Merge branch 'development' into pre-release-9.1.0
This commit is contained in:
commit
e217ab49d9
@ -119,6 +119,8 @@
|
||||
| USE_CHIRP | - | - | - | - | - | - | - |
|
||||
| USE_PAJ7620 | - | - | - | - | - | - | - |
|
||||
| USE_PCF8574 | - | - | - | - | - | - | - |
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
| USE_HIH6 | - | - | - | - | x | - | - |
|
||||
| USE_DHT12 | - | - | - | - | x | - | - |
|
||||
| USE_DS1624 | - | - | - | - | x | - | - |
|
||||
@ -133,9 +135,12 @@
|
||||
| USE_HP303B | - | - | - | - | - | - | - |
|
||||
| USE_EZOCO2 | - | - | - | - | - | - | - |
|
||||
| USE_EZOEC | - | - | - | - | - | - | - |
|
||||
| USE_EZOFLO | - | - | - | - | - | - | - |
|
||||
| USE_EZOHUM | - | - | - | - | - | - | - |
|
||||
| USE_EZOO2 | - | - | - | - | - | - | - |
|
||||
| USE_EZOORP | - | - | - | - | - | - | - |
|
||||
| USE_EZOPH | - | - | - | - | - | - | - |
|
||||
| USE_EZOPRS | - | - | - | - | - | - | - |
|
||||
| USE_EZORTD | - | - | - | - | - | - | - |
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
|
||||
14
CHANGELOG.md
14
CHANGELOG.md
@ -11,10 +11,20 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [9.0.0.3]
|
||||
### Added
|
||||
- TLS in binary tasmota-zbbridge (#9620)
|
||||
- TLS in binary tasmota-zbbridge (#9635)
|
||||
- Support for EZO O2 sensors by Christopher Tremblay (#9619)
|
||||
- Support for EZO PRS sensors by Christopher Tremblay (#9659)
|
||||
- Support for EZO FLO sensors by Christopher Tremblay (#9697)
|
||||
- Zigbee reduce battery drain (#9642)
|
||||
- Zigbee command ``ZbMap`` to describe Zigbee topology (#9651)
|
||||
- Zigbee command ``ZbOccupancy`` to configure the time-out for PIR
|
||||
- Command ``Gpios 255`` to show all possible GPIO configurations
|
||||
- Command ``SwitchText`` to change JSON switch names by barbudor (#9691)
|
||||
|
||||
### Changed
|
||||
- PlatformIO library structure redesigned for compilation speed by Jason2866
|
||||
- Zigbee flash storage refactor adding commands ``ZbProbe``, ``ZbStatus2`` and ``ZbRestore`` (#9641)
|
||||
- Default otaurl in my_user_config.h to http://ota.tasmota.com/tasmota/release/tasmota.bin.gz
|
||||
|
||||
### Fixed
|
||||
- Rule Break not working as expected when ONCE is enabled (#9245)
|
||||
@ -164,7 +174,7 @@ All notable changes to this project will be documented in this file.
|
||||
### Added
|
||||
- Zigbee better support for IKEA Motion Sensor
|
||||
- ESP32 Analog input support for GPIO32 to GPIO39
|
||||
- Zigbee options to ``ZbSend`` ``Config`` and ``ReadCondig``
|
||||
- Zigbee options to ``ZbSend`` ``Config`` and ``ReadConfig``
|
||||
- Command ``Restart 2`` to halt system. Needs hardware reset or power cycle to restart (#9046)
|
||||
- Command ``SetOption102 0/1`` to switch between Teleinfo French Metering mode, legacy 1200 bps (0) or Linky standard 9600 bps (1)
|
||||
|
||||
|
||||
@ -83,3 +83,6 @@ Index | Define | Driver | Device | Address(es) | Description
|
||||
55 | USE_EZOHUM | xsns_78 | EZOHUM | 0x61 - 0x70 | Humidity sensor
|
||||
55 | USE_EZOEC | xsns_78 | EZOEC | 0x61 - 0x70 | Electric conductivity sensor
|
||||
55 | USE_EZOCO2 | xsns_78 | EZOCO2 | 0x61 - 0x70 | CO2 sensor
|
||||
55 | USE_EZOO2 | xsns_78 | EZOO2 | 0x61 - 0x70 | O2 sensor
|
||||
55 | USE_EZOPRS | xsns_78 | EZOPRS | 0x61 - 0x70 | Pressure sensor
|
||||
55 | USE_EZOFLO | xsns_78 | EZOFLO | 0x61 - 0x70 | Flow meter sensor
|
||||
|
||||
@ -80,4 +80,4 @@ Module | LCode | Description
|
||||
74 Sonoff D1 | x | Sonoff D1 Wifi and RF Dimmer
|
||||
75 Sonoff ZbBridge | x | Sonoff Zigbee bridge
|
||||
|
||||
Over 1600 additional devices are supported using [templates](TEMPLATES.md).
|
||||
Over 1650 additional devices are supported using [templates](TEMPLATES.md).
|
||||
|
||||
@ -51,7 +51,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
||||
- **tasmota-zbbridge.bin** = The dedicated Sonoff Zigbee Bridge version.
|
||||
- **tasmota-minimal.bin** = The Minimal version allows intermediate OTA uploads to support larger versions and does NOT change any persistent parameter. This version **should NOT be used for initial installation**.
|
||||
|
||||
The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota/release for ESP8266 or http://ota.tasmota.com/tasmota32/release for ESP32. The links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin``
|
||||
The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota/release for ESP8266 or http://ota.tasmota.com/tasmota32/release for ESP32. The links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
|
||||
|
||||
[List](MODULES.md) of embedded modules.
|
||||
|
||||
@ -59,11 +59,14 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
||||
|
||||
## Changelog v9.1.0 Imogen
|
||||
### Added
|
||||
- Command ``Gpios 255`` to show all possible GPIO configurations
|
||||
- Command ``NoDelay`` for immediate backlog command execution by Erik Montnemery (#9544)
|
||||
- Command ``SwitchMode 15`` sending only MQTT message on switch change (#9593)
|
||||
- Command ``ShutterChange`` to increment change position (#9594)
|
||||
- Command ``SetOption113 1`` to set dimmer low on rotary dial after power off
|
||||
- Command ``SwitchText`` to change JSON switch names by barbudor (#9691)
|
||||
- Zigbee command ``ZbData`` for better support of device specific data
|
||||
- Zigbee command ``ZbOccupancy`` to configure the time-out for PIR
|
||||
- Optional support for Mitsubishi Electric HVAC by David Gwynne (#9237)
|
||||
- Optional support for Orno WE517-Modbus energy meter by Maxime Vincent (#9353)
|
||||
- SDM630 three phase ImportActive Energy display when ``#define SDM630_IMPORT`` is enabled by Janusz Kostorz (#9124)
|
||||
@ -73,9 +76,10 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
||||
- Support for analog buttons indexed within standard button range
|
||||
- Support for Vietnamese language translations by Tâm.NT
|
||||
- Support for timers in case of no-sunset permanent day by cybermaus (#9543)
|
||||
- Support for EZO CO2, EC, HUM, ORP, Ph and RTD sensors by Christopher Tremblay
|
||||
- Support for EZO sensors by Christopher Tremblay
|
||||
- Support for fixed output Hi or Lo GPIO selection
|
||||
- TLS in binary tasmota-zbbridge (#9620)
|
||||
- Zigbee reduce battery drain (#9642)
|
||||
- ESP32 support for Wireless-Tag WT32-ETH01 (#9496)
|
||||
- ESP32 MI32 Beacon support, RSSI at TELEPERIOD, refactoring (#9609)
|
||||
|
||||
@ -98,6 +102,8 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
||||
- Tasmota Arduino Core v2.7.4.5 allowing webpassword over 47 characters (#9687)
|
||||
- Webserver code optimizations (#9580, #9590)
|
||||
- PlatformIO library structure redesigned for compilation speed by Jason2866
|
||||
- Zigbee flash storage refactor adding commands ``ZbProbe``, ``ZbStatus2`` and ``ZbRestore`` (#9641)
|
||||
- Default otaurl in my_user_config.h to http://ota.tasmota.com/tasmota/release/tasmota.bin.gz
|
||||
|
||||
### Fixed
|
||||
- Ledlink blink when no network connected regression from v8.3.1.4 (#9292)
|
||||
|
||||
152
TEMPLATES.md
152
TEMPLATES.md
@ -2,7 +2,7 @@
|
||||
|
||||
# Templates
|
||||
|
||||
Find below the available templates as of October 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 November 2020. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)
|
||||
|
||||
## Aromatherapy Diffuser
|
||||
```
|
||||
@ -24,6 +24,7 @@ Arlec Smart Home Hub {"NAME":"Arlec Hub","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0
|
||||
|
||||
## Bulb Socket
|
||||
```
|
||||
Blitzwolf E27 {"NAME":"Blitzwolf BW-LT30","GPIO":[17,0,0,0,21,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
Elegant Choice E27/E26 {"NAME":"name","GPIO":[0,0,0,0,0,0,0,0,0,0,0,21,0],"FLAG":0,"BASE":18}
|
||||
Slampher {"NAME":"Slampher","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":9}
|
||||
SmartBase E0260 {"NAME":"SmartBaseE0260","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
@ -62,11 +63,13 @@ Globe A19 10W 800lm {"NAME":"GlobeCCT","GPIO":[0,0,0,0,38,37,0,0,0,0,0,0,0]
|
||||
Globe G25 Edison 500lm {"NAME":"Globe 34920","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18}
|
||||
Globe 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}
|
||||
Hama 4.5W 300lm {"NAME":"Hama LED-Bulb GU10","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
Hama 4.5W 350lm {"NAME":"Hama LED-Bulb","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}
|
||||
iView 10W 1050lm {"NAME":"iView ISB1000-D","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
Kogan 10W Cool & Warm White 1050lm {"NAME":"Kogan 10W CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48}
|
||||
Kogan 4.5W 330lm 110C {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
Kogan 4.5W 330lm 110 {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
Kogan 5W {"NAME":"Kogan Co/Wa","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
Laser 10W 1000lm {"NAME":"Laser 10W CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48}
|
||||
Laser 10W 1000lm {"NAME":"Laster 10W CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
@ -76,12 +79,12 @@ ledscom.de 4.5W 430lm {"NAME":"GX53","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FL
|
||||
Lenovo 800lm {"NAME":"LenovoLB","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
Lohas ZN051 5W 420lm {"NAME":"Lohas ZN051","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18}
|
||||
Lohas ZN070 720lm {"NAME":"Lohas ZN070","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18}
|
||||
LSC A55 14W 1400lm {"NAME":"LSC CT E27","GPIO":[0,0,0,0,37,47,0,0,0,0,0,0,0],"FLAG":0,"BASE":48}
|
||||
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}
|
||||
LVWIT E14 Smart Wifi LED Bulb, 470Lm, 4.5W {"NAME":"LVWIT 4.5w CCT","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 A21 10.5W 1050lm {"NAME":"Mimoodz","GPIO":[0,0,0,0,21,22,0,0,23,24,25,26,27],"FLAG":0,"BASE":18}
|
||||
Mimoodz A21 10.5W 1050lm {"NAME":"Mimoodz","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
Mirabella Genio 6W 500lm {"NAME":"GenioGU10","GPIO":[0,0,0,0,0,0,0,0,38,0,37,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}
|
||||
@ -93,15 +96,19 @@ Nedis A60 800lm {"NAME":"WIFILW10WTE27","GPIO":[0,0,0,0,0,37,0,0,38,0,0
|
||||
Nedis C10 350lm {"NAME":"WIFILW10WTE14","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
Nedis G125 5.5W 350lm Twisted Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,38,0,37,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 110C {"NAME":"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}
|
||||
Polux ST64 5.5W 470lm {"NAME":"basic","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18}
|
||||
Prokord 10W 1050lm {"NAME":"PSH-E2745-CCT","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":1,"BASE":18}
|
||||
Prokord 5W 1050lm {"NAME":"Prokord-PSH-GU1045-CCT","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18}
|
||||
Shelly DUO 800lm {"NAME":"Shelly DUO","GPIO":[0,0,0,0,38,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
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}
|
||||
Solimo 12W 1080lm {"NAME":"Solimo WCCT 12","GPIO":[0,0,0,0,9,37,0,0,10,38,11,0,0],"FLAG":0,"BASE":18}
|
||||
Spectrum Smart 5W 410lm Candle {"NAME":"lightbulb","GPIO":[0,0,0,0,0,0,0,0,38,0,37,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}
|
||||
V-Tac PAR16 4.5W 300lm 110C {"NAME":"V-TAC VT-5174","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18}
|
||||
Treatlife A19 9W 800lm {"NAME":"Treatlife SL20","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
V-Tac PAR16 4.5W 300lm 110 {"NAME":"V-TAC VT-5174","GPIO":[0,0,0,0,0,0,0,0,38,0,37,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,0,0,0,37,0,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}
|
||||
@ -149,7 +156,7 @@ Konesky {"NAME":"KingArt","GPIO":[157,0,53,11,23,17,0,0,18,22,5
|
||||
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 SC500W Roller Shutter {"NAME":"SC500W","GPIO":[0,0,0,158,9,10,0,0,21,17,22,0,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}
|
||||
LoraTap SC511WSC Roller Shutter {"NAME":"SC511WSC","GPIO":[0,255,0,56,17,19,0,0,21,18,23,22,0],"FLAG":0,"BASE":18}
|
||||
Maxcio WF-CS01 {"NAME":"Maxcio","GPIO":[157,0,53,11,23,18,0,0,17,21,54,22,52],"FLAG":0,"BASE":18}
|
||||
SCS86-03AJAI {"NAME":"ESE86-03AJAI","GPIO":[157,0,58,18,22,19,0,0,17,21,57,23,56],"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}
|
||||
@ -190,6 +197,7 @@ Feit Electric 800lm {"NAME":" Feit P_A800_2","GPIO":[0,0,0,0,0,37,0,0,0,0,0
|
||||
Feit Electric 8.8W 800lm Vintage {"NAME":"FEIT A1960CL","GPIO":[0,0,0,0,0,0,0,0,0,0,37,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 800 {"NAME":"Geeni GN-BW902-999","GPIO":[0,0,0,0,37,0,0,0,0,9,0,0,0],"FLAG":0,"BASE":18}
|
||||
Geeni LUX 800 {"NAME":"Geeni-LUX-800","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 A19 10W 800lm {"NAME":"Globe WW 800lm","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
@ -213,6 +221,7 @@ Luminea ZX-2880 A60 800lm {"NAME":"LAV-110.w","GPIO":[0,0,0,0,37,40,0,0,38,41,3
|
||||
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}
|
||||
MagicHome 7.5W Warm White {"NAME":"ZJ-8C2B-CCT-AV1.1","GPIO":[0,0,0,0,0,0,0,0,37,0,0,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 BR30 750lm {"NAME":"MI-BW905-999W","GPIO":[0,0,0,0,0,37,0,0,38,0,0,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}
|
||||
@ -231,6 +240,7 @@ Nedis PAR16 330lm {"NAME":"Nedis WIFILW31","GPIO":[0,0,0,0,0,37,0,0,0,0,0
|
||||
NiteBird 8W 800lm 2700k {"NAME":"Nitebird-smart28k","GPIO":[0,0,0,0,37,0,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}
|
||||
SmartDGM 9W 806lm {"NAME":"L-WB9W1","GPIO":[0,0,0,0,0,37,0,0,9,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
Smitch 10W 6500K {"NAME":"Smitch Ambience SB-0110","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}
|
||||
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}
|
||||
@ -250,10 +260,11 @@ CNSKOU Touch {"NAME":"CNSKOU Dimmer Switch","GPIO":[0,0,0,0,0,0,0,0,
|
||||
Eva Logik {"NAME":"WF31 Dimmer","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54}
|
||||
Eva Logik 3 Way {"NAME":"EL WF31T","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}
|
||||
Feit Electric Smart {"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}
|
||||
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 SD01 {"NAME":"MJ-SD02","GPIO":[19,18,0,59,158,58,0,0,57,37,56,122,29],"FLAG":0,"BASE":73}
|
||||
Martin Jerry Single Pole {"NAME":"MJ-KN01 Dimmer","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||
Minoston 3-Way {"NAME":"MS10W","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54}
|
||||
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}
|
||||
@ -274,7 +285,23 @@ Zemismart KS-7011 {"NAME":"KS-7011 Dimmer","GPIO":[255,107,255,108,255,25
|
||||
|
||||
## Downlight
|
||||
```
|
||||
Philips 5/6 in. RGBCCT Downlight {"NAME":"Philips","GPIO":[0,0,0,0,40,0,0,0,37,41,39,38,0],"FLAG":0,"BASE":48}
|
||||
BrilliantSmart Prism 10W RGBCCT {"NAME":"Prism","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
BrilliantSmart Trilogy 9W CCT {"NAME":"SmartCCTDwnLgt","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48}
|
||||
Connect SmartHome RGB {"NAME":"CSH-240RGB10W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
Deta 10W RGBCCT {"NAME":"Deta DownLight","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
Feit Electric 6in. RGBW Recessed {"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" {"NAME":"HyperikonDL6","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
iHomma 6W RGBCCT {"NAME":"iHomma RGBWW","GPIO":[0,0,0,0,41,40,0,0,37,38,39,0,0],"FLAG":0,"BASE":18}
|
||||
iHomma RGB BT+IR 12W {"NAME":"iHommaLEDDownl","GPIO":[0,0,0,0,0,40,0,0,37,38,39,0,0],"FLAG":0,"BASE":18}
|
||||
Kogan 9W RGBCCT {"NAME":"Kogan_SMARTLED","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
Mirabella Genio 9W CCT {"NAME":"GenioDLightCCT","GPIO":[0,0,0,0,0,0,0,0,47,0,37,0,0],"FLAG":0,"BASE":48}
|
||||
Mirabella Genio 9W RGBCCT {"NAME":"GenioDLightRGB","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
Moes 7W RGBCCT {"NAME":"Moes Downlight","GPIO":[0,0,0,0,40,41,0,0,37,38,39,0,0],"FLAG":0,"BASE":18}
|
||||
Philips 5/6 in. RGBCCT {"NAME":"Philips","GPIO":[0,0,0,0,40,0,0,0,37,41,39,38,0],"FLAG":0,"BASE":48}
|
||||
Zemismart 4" 10W RGBCCT {"NAME":"ZemiDownLight4","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
Zemismart 4" 10W RGBW {"NAME":"ZemiDownLight","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27}
|
||||
Zemismart 6" 14W RGBCCT {"NAME":"ZemiDownLight6","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
```
|
||||
|
||||
## Energy Meter
|
||||
@ -341,6 +368,7 @@ Arilux AL-LC06 {"NAME":"Arilux LC06","GPIO":[17,0,0,0,0,0,0,0,38,39,37
|
||||
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}
|
||||
Bakeey RGB {"NAME":"Bakeey Strip Controller","GPIO":[17,0,0,0,37,41,0,0,39,0,38,40,0],"FLAG":0,"BASE":18}
|
||||
CIN-03 96W RGB {"NAME":"CIN03-03 Strip","GPIO":[0,0,0,0,38,0,0,0,37,0,39,0,0],"FLAG":0,"BASE":18}
|
||||
DD001-MINI(G)-IR-V03 {"NAME":"WIFI-RGB","GPIO":[17,0,0,0,0,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":40}
|
||||
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}
|
||||
@ -354,6 +382,7 @@ Luminea ZX-2844 {"NAME":"Luminea ZX-284","GPIO":[40,0,0,0,0,39,0,0,38,1
|
||||
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 {"NAME":"Magic Home RGB","GPIO":[0,0,0,0,147,37,0,0,39,0,38,0,159],"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 {"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 RF {"NAME":"MagicHome RGBW RF","GPIO":[0,0,56,0,147,38,0,0,39,40,37,159,0],"FLAG":0,"BASE":18}
|
||||
@ -371,7 +400,7 @@ 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 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}
|
||||
B.K. Licht 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}
|
||||
@ -401,10 +430,12 @@ Maxonar Lightstrip Pro XS-SLD001 {"NAME":"Maxonar LED","GPIO":[0,0,0,0,0,37,0,0
|
||||
Merkury Innovations MI-EW003-999W {"NAME":"MI-EW003-999W ","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
Mirabella Genio RGB+CW {"NAME":"MirabellaStrip","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18}
|
||||
Monster Smart IlluminEssence {"NAME":"MI-EW003-999W ","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
NiteBird 9.2ft RGB TV Backlight {"NAME":"NiteBird Smart LED Light Strip","GPIO":[17,0,0,0,0,0,0,0,37,39,38,0,0],"FLAG":0,"BASE":18}
|
||||
Polux RGB+NW 2m {"NAME":"Polux Wi-Fi SM","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":37}
|
||||
Powertech 5m RGBW {"NAME":"Jaycar ST3992 LED Strip","GPIO":[122,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18}
|
||||
Reafoo RGBW 5m {"NAME":"REAFOO RGBW LS","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18}
|
||||
Sonoff L1 {"NAME":"SonoffL1","GPIO":[0,148,0,149,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":70}
|
||||
Techvilla TE001 {"NAME":"TE-TE001","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||
Teckin SL02 {"NAME":"Teckin SL02","GPIO":[51,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":52}
|
||||
Teckin SL07 32.8ft RGB {"NAME":"WIFI RGB","GPIO":[51,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18}
|
||||
TORCHSTAR CCT 30W Lighting Kit {"NAME":"Torchstar CCT ","GPIO":[0,0,0,0,52,38,0,0,0,17,0,37,53],"FLAG":0,"BASE":18}
|
||||
@ -422,40 +453,26 @@ Arlec Smart 40W 4000lm LED Batten {"NAME":"Arlec Batten","GPIO":[0,0,0,0,0,37,0
|
||||
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}
|
||||
Arlec Smart Up & Down LED Wall {"NAME":"Arlec Up Down CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
BAZZ 4 in. RGB Recessed Fixture {"NAME":"SLMR4RGBWWFW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
BAZZ 6 in. CCT Recessed Fixture {"NAME":"SLDSK6TNWWF","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
Brelong USB Charging Night {"NAME":"Brelong Smart USB Charging Lamp","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,40],"FLAG":0,"BASE":18}
|
||||
Brilex Nightstand Lamp {"NAME":"Smart Table Lamp","GPIO":[0,0,18,0,37,157,0,0,38,17,39,0,40],"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}
|
||||
BrilliantSmart RGB Garden Kit {"NAME":"Brilliant Gard","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18}
|
||||
Connect SmartHome CSH-240RGB10W {"NAME":"CSH-240RGB10W","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}
|
||||
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}
|
||||
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}
|
||||
Hugoai Table Lamp {"NAME":"HG02","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54}
|
||||
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}
|
||||
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}
|
||||
Iwoole Table Lamp {"NAME":"GLOBELAMP","GPIO":[0,0,0,0,0,0,0,0,38,39,37,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}
|
||||
Mi LED Desk Lamp {"NAME":"Mi Desk Lamp","GPIO":[0,0,17,0,37,38,0,0,150,151,0,0,0],"FLAG":0,"BASE":66}
|
||||
Mirabella Genio 10 LED Filament Festoon {"NAME":"GenioFestoon","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18}
|
||||
Mirabella Genio 4 Black LED Garden Path {"NAME":"GenioGardenStr","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18}
|
||||
Mirabella Genio 9W CCT Downlight {"NAME":"GenioDLightCCT","GPIO":[0,0,0,0,0,0,0,0,47,0,37,0,0],"FLAG":0,"BASE":48}
|
||||
Mirabella Genio 9W RGBCCT Downlight {"NAME":"GenioDLightRGB","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
Mirabella Genio CCT 6 LED 30mm Stainless Steel Deck {"NAME":"Mirabella Deck CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18}
|
||||
MiraBella Genio Colour 6 LED 30mm Stainless Steel Deck {"NAME":"Genio RGB Deck Lights","GPIO":[0,0,0,0,37,0,0,0,38,0,39,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}
|
||||
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,37,0,0],"FLAG":0,"BASE":18}
|
||||
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}
|
||||
Zemismart 4" 10W RGBW {"NAME":"ZemiDownLight","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27}
|
||||
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
|
||||
@ -468,6 +485,7 @@ Kogan 1500w Panel Heater {"NAME":"Kogan Panel Heater","GPIO":[0,0,0,0,0,0,0,0,0
|
||||
Kogan 4.1kW Portable Air Conditioner (Reverse Cycle) {"NAME":"Kogan Panel Heater","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54}
|
||||
LED Starry Sky Projector Light {"NAME":"STAR PROJECTOR","GPIO":[0,0,0,0,37,0,0,0,38,0,39,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}
|
||||
NEO Coolcam Mouse Trap {"NAME":"Neo Mouse Trap","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54}
|
||||
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"}
|
||||
```
|
||||
@ -496,7 +514,7 @@ Sonoff SC {"NAME":"Sonoff SC","GPIO":[17,148,255,149,0,0,0,0,0,56
|
||||
## 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}
|
||||
Aicliv SOP03-US {"NAME":"AICLIV SOP03US","GPIO":[0,0,0,23,57,0,0,0,21,18,22,0,0],"FLAG":15,"BASE":18}
|
||||
Aicliv 3 Outlet {"NAME":"AICLIV SOP03US","GPIO":[0,0,0,23,57,0,0,0,21,18,22,0,0],"FLAG":0,"BASE":18}
|
||||
Albohes PC-1606 {"NAME":"Albohes PC1606","GPIO":[17,0,0,0,0,22,18,0,21,0,0,0,0],"FLAG":1,"BASE":39}
|
||||
Albohes PS-1602 {"NAME":"Albohes PC1606","GPIO":[17,0,0,0,0,22,18,0,21,0,0,0,0],"FLAG":1,"BASE":39}
|
||||
Amzdest IP55 {"NAME":"C168 Outdoor","GPIO":[0,0,0,130,134,132,0,0,21,56,22,23,17],"FLAG":0,"BASE":18}
|
||||
@ -508,12 +526,15 @@ C137 IP55 {"NAME":"C137 Outdoor","GPIO":[0,17,0,56,134,132,0,0,21
|
||||
C168 IP64 {"NAME":"C188","GPIO":[56,0,57,0,18,0,0,0,21,17,157,22,0],"FLAG":0,"BASE":18}
|
||||
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}
|
||||
Edimax 2AC {"NAME":"EDI SP-1122WTO","GPIO":[0,0,0,0,22,158,0,0,21,0,17,0,0],"FLAG":0,"BASE":18}
|
||||
Etekcity {"NAME":"ES015-TB","GPIO":[0,0,0,0,21,22,0,0,132,133,17,130,56],"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}
|
||||
Globe 2-Outlet {"NAME":"Globe SK509W2S","GPIO":[0,0,0,0,22,0,0,0,17,21,56,0,0],"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}
|
||||
HBN 6 Outlet Yard Stake {"NAME":"BNC-60/U13WT","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
HBN Heavy Duty {"NAME":"HBN U151T","GPIO":[0,0,0,0,52,53,0,0,21,17,0,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}
|
||||
Jackyled IP55 3AC {"NAME":"JackyLed 3","GPIO":[0,0,56,0,0,23,0,0,22,57,17,0,21],"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}
|
||||
@ -532,6 +553,7 @@ Oittm Outdoor {"NAME":"Oittm Outdoor","GPIO":[17,0,0,0,0,0,0,0,0,0,56
|
||||
Peteme PS-1602 {"NAME":"Peteme Outdoor","GPIO":[17,0,0,0,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":18}
|
||||
Poweradd {"NAME":"POWERADD","GPIO":[0,0,0,0,56,57,0,0,21,17,22,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}
|
||||
Prime Smart Outlet {"NAME":"Prime CCWFIO232PK","GPIO":[0,0,0,57,22,0,0,0,17,21,52,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}
|
||||
@ -575,11 +597,11 @@ Anoopsyche SP-G01 {"NAME":"SP-G01","GPIO":[0,145,0,146,0,0,0,0,17,56,21,0
|
||||
Anoopsyche SP15 {"NAME":"Anoop SP15","GPIO":[0,0,0,0,56,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
Anoopsyche UK1D {"NAME":"UK1D","GPIO":[0,17,0,0,133,132,0,0,130,52,21,0,0],"FLAG":0,"BASE":6}
|
||||
AOFO 10A {"NAME":"AOFO Smart Plug Wifi","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
Aoycocr {"NAME":"Aoycocr X10S","GPIO":[56,0,57,0,21,134,0,0,131,17,132,0,0],"FLAG":0,"BASE":45}
|
||||
Aoycocr EU5 16A {"NAME":"Aoycocr","GPIO":[255,0,56,0,0,0,0,0,255,17,0,21,0],"FLAG":0,"BASE":17}
|
||||
Aoycocr EU6S {"NAME":"Aoycocr EU6S","GPIO":[255,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":17}
|
||||
Aoycocr U2S {"NAME":"Aoycocr U2S","GPIO":[56,0,57,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
Aoycocr U3S {"NAME":"Aoycocr U3S","GPIO":[56,255,57,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
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}
|
||||
Aquiv S1 {"NAME":"Aquiv S1","GPIO":[0,0,157,0,56,0,0,0,21,17,0,0,0],"FLAG":15,"BASE":18}
|
||||
@ -588,7 +610,7 @@ Arlec Heavy Duty 20m Extension Lead {"NAME":"Arlec Ext Cord","GPIO":[0,17,0,0,0
|
||||
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,56,0,0,0,21,158,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 Smart PC399HA Plug {"NAME":"PC399HA","GPIO":[0,0,0,17,134,132,0,0,131,56,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}
|
||||
Athom 16A {"NAME":"Athom PG01EU16A","GPIO":[0,0,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":1}
|
||||
Atomi AT1217 {"NAME":"AT1217","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
@ -597,6 +619,7 @@ Aukey SH-PA2 {"NAME":"AUKEY SH-PA2","GPIO":[0,0,0,0,158,0,0,0,21,0,1
|
||||
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 {"NAME":"Avatar UK 10A","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
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}
|
||||
@ -604,7 +627,6 @@ Avatar AWP04L {"NAME":"AWP04L","GPIO":[57,255,255,131,255,134,0,0,21,
|
||||
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":"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}
|
||||
@ -618,18 +640,20 @@ Bardi 16A {"NAME":"BARDI","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57
|
||||
Bauhn ASPU-1019 {"NAME":"Bauhn 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 1200W Dual {"NAME":"BlitzWolf SHP3","GPIO":[56,0,57,0,22,134,0,0,131,18,132,21,17],"FLAG":0,"BASE":45}
|
||||
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-SHP10-P {"NAME":"BW-SHP10 PM","GPIO":[0,148,0,207,158,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}
|
||||
BlitzWolf BW-SHP4 {"NAME":"BlitzWolf SHP","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
BlitzWolf BW-SHP5 {"NAME":"SHP5","GPIO":[57,145,56,146,0,22,0,0,0,0,21,0,17],"FLAG":0,"BASE":18}
|
||||
BlitzWolf BW-SHP6 10A {"NAME":"BW-SHP6 10A","GPIO":[158,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
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}
|
||||
BlitzWolf SHP1 {"NAME":"BlitzWolf-SHP1","GPIO":[56,0,57,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18}
|
||||
BN-Link {"NAME":"BNC-60/U133TJ","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":18}
|
||||
BNETA IO-WIFI-PlugSA {"NAME":"BNETA WifiPlug","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18}
|
||||
Bontec SPEU {"NAME":"Bontec SPEU","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18}
|
||||
Brennenstuhl WA 3000 {"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 {"NAME":"HK17654S05","GPIO":[17,255,255,255,133,132,255,255,131,56,21,255,255],"FLAG":0,"BASE":18}
|
||||
@ -653,6 +677,7 @@ CE Smart Home LA-WF3 {"NAME":"CE LA-WF3","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0
|
||||
Cloudfree Runs Tasmota {"NAME":"CloudFree 1","GPIO":[255,255,56,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18}
|
||||
Conico SM-PW70 {"NAME":"Conico SM-PW70","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":1,"BASE":18}
|
||||
Connex CC-P1000 {"NAME":"Connex Smart T","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18}
|
||||
Connex Type F {"NAME":"Connex CC-P1001","GPIO":[0,0,56,0,0,133,0,0,131,17,132,21,0],"FLAG":0,"BASE":18}
|
||||
Coosa {"NAME":"COOSA","GPIO":[0,0,0,0,57,52,0,0,21,17,255,0,0],"FLAG":0,"BASE":1}
|
||||
Coosa SP1 {"NAME":"COOSA SP1","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
CrazyLynX WiFi {"NAME":"CrazyLynX","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":1,"BASE":18}
|
||||
@ -660,6 +685,7 @@ CYYLTF BIFANS J23 {"NAME":"CYYLTD BIFANS J23","GPIO":[56,0,0,0,0,0,0,0,21
|
||||
D3D Smart Plug with USB & Power Monitor {"NAME":"D3D FLHS-ZN04","GPIO":[57,255,56,131,255,133,255,255,255,17,132,21,255],"FLAG":15,"BASE":18}
|
||||
DE-1 16A {"NAME":"DE-1","GPIO":[0,17,0,0,133,0,0,0,0,52,21,0,0],"FLAG":1,"BASE":18}
|
||||
DeLock Power Socket Switch MQTT {"NAME":"DeLock 11826","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":1}
|
||||
Delock Power Socket Switch MQTT {"NAME":"Delock 11827","GPIO":[0,0,0,17,133,132,0,0,131,158,21,0,0],"FLAG":0,"BASE":53}
|
||||
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}
|
||||
@ -704,7 +730,8 @@ Frankever USB {"NAME":"FK-PW301U","GPIO":[0,0,255,0,158,0,0,0,21,17,0
|
||||
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 OUTDOOR {"NAME":"Geeni Outdoor","GPIO":[17,0,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18}
|
||||
Geeni Spot {"NAME":"Geeni Spot","GPIO":[158,0,0,0,56,0,0,0,0,17,0,21,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}
|
||||
Geeni Switch Duo {"NAME":"Geeni Duo","GPIO":[0,0,0,0,18,22,0,0,17,52,21,0,53],"FLAG":0,"BASE":18}
|
||||
@ -713,6 +740,7 @@ Globe 2 Outlet {"NAME":"Globe 50020","GPIO":[0,158,0,57,18,17,0,0,21,5
|
||||
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 {"NAME":"Gosund EP2","GPIO":[56,255,158,255,132,134,0,0,131,17,0,21,0],"FLAG":0,"BASE":45}
|
||||
Gosund 2 in 1 {"NAME":"Gosund WP212","GPIO":[57,52,157,0,21,134,0,0,131,17,132,22,18],"FLAG":0,"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}
|
||||
@ -726,7 +754,7 @@ Gosund UP111 {"NAME":"Gosund UP111","GPIO":[0,52,0,17,134,132,0,0,13
|
||||
Gosund WP1 {"NAME":"Gosund WP1-1","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
Gosund WP2 {"NAME":"Gosund WP2","GPIO":[17,158,57,0,18,0,0,0,22,56,21,0,0],"FLAG":0,"BASE":18}
|
||||
Gosund WP211 {"NAME":"Gosund wp211","GPIO":[0,0,0,0,21,0,0,0,0,17,0,22,18],"FLAG":0,"BASE":18}
|
||||
Gosund WP212 {"NAME":"Gosund_WP212","GPIO":[17,0,0,0,18,0,0,0,22,0,21,0,0],"FLAG":0,"BASE":18}
|
||||
Gosund WP212 {"NAME":"Gosund_WP212","GPIO":[17,157,57,0,18,0,0,0,22,56,21,0,0],"FLAG":0,"BASE":18}
|
||||
Gosund WP3 {"NAME":"Gosund WP3","GPIO":[0,0,0,0,17,0,0,0,56,57,21,0,0],"FLAG":0,"BASE":18}
|
||||
Gosund WP5 {"NAME":"Gosund-WP5","GPIO":[0,0,0,0,17,0,0,0,56,57,21,0,0],"FLAG":0,"BASE":18}
|
||||
Gosund WP6 {"NAME":"Gosund WP6","GPIO":[0,0,0,17,0,0,0,0,56,57,21,0,0],"FLAG":0,"BASE":18}
|
||||
@ -758,7 +786,7 @@ Hyleton 317 {"NAME":"hyleton-317","GPIO":[56,0,57,0,58,0,0,0,0,90,0
|
||||
Hyleton HLT-311 {"NAME":"HLT-311","GPIO":[56,0,0,0,0,0,0,0,0,17,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}
|
||||
iDIGITAL {"NAME":"Brilliant","GPIO":[0,0,0,0,52,0,0,0,21,90,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}
|
||||
Ihommate 16A {"NAME":"ZCH-02","GPIO":[0,0,0,17,133,132,0,0,130,56,21,0,0],"FLAG":1,"BASE":18}
|
||||
Infray 16A {"NAME":"AWP08L","GPIO":[17,0,52,0,0,0,0,0,0,0,0,21,0],"FLAG":1,"BASE":18}
|
||||
Insmart WP5 {"NAME":"INSMART","GPIO":[0,0,46,0,0,0,0,0,0,9,0,21,0],"FLAG":0,"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}
|
||||
@ -810,7 +838,6 @@ Luminea ZX-2858 {"NAME":"Luminea SF-200","GPIO":[0,0,0,17,0,0,0,0,0,56,
|
||||
Lunvon {"NAME":"Lunvon Smart Plug","GPIO":[17,0,0,0,0,0,52,21,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
Martin Jerry V01 {"NAME":"MJ V01","GPIO":[0,0,0,0,56,0,0,0,21,17,0,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}
|
||||
Maxcio W-UK007S {"NAME":"Maxcio","GPIO":[56,0,255,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
Maxcio W-US002S {"NAME":"W-US002S","GPIO":[57,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45}
|
||||
Maxcio W-US003 {"NAME":"W-US003","GPIO":[255,17,255,255,255,255,0,0,255,22,21,255,255],"FLAG":0,"BASE":18}
|
||||
@ -844,6 +871,7 @@ Nightlight and AC Outlet {"NAME":"SWN03","GPIO":[17,0,0,0,0,0,255,255,37,0,0,21
|
||||
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}
|
||||
NX-SM210 {"NAME":"NX-SM210","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18}
|
||||
NX-SM223 {"NAME":"Smart Thurmm","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"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}
|
||||
@ -880,7 +908,9 @@ Robaxo {"NAME":"Robaxo RSP-025","GPIO":[17,0,0,0,134,132,0,0,1
|
||||
RSH-WS005 {"NAME":"RSH-WS005 Energy Monitor","GPIO":[56,0,158,0,0,134,0,0,131,17,132,21,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}
|
||||
S126 {"NAME":"tuya-plug","GPIO":[0,0,0,0,0,0,0,0,21,20,0,0,0],"FLAG":0,"BASE":8}
|
||||
SA-001 {"NAME":"SA-001","GPIO":[17,145,0,146,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":41}
|
||||
SA-P202C 16A {"NAME":"Elivco 202C-G","GPIO":[0,0,0,17,134,132,0,0,130,56,21,0,0],"FLAG":0,"BASE":18}
|
||||
SA-P302A {"NAME":"KinCam SA-P302A","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
Sansui {"NAME":"Sansui YSP-1","GPIO":[52,0,53,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18}
|
||||
Shelly Plug S {"NAME":"Shelly Plug S","GPIO":[56,255,158,255,255,134,0,0,131,17,132,21,255],"FLAG":2,"BASE":45}
|
||||
Shelly Plug US {"NAME":"Shelly Plug US","GPIO":[52,0,57,0,21,134,0,0,131,17,132,157,0],"FLAG":0,"BASE":45}
|
||||
@ -957,6 +987,7 @@ Vivanco 39625 Smart Home Power Adapter {"NAME":"Vivianco","GPIO":[0,0,0,17,133,
|
||||
Vivitar {"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}
|
||||
W-DE004 {"NAME":"W-DE004","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":1,"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}
|
||||
WAZA 10A {"NAME":"WAZA","GPIO":[0,0,0,0,21,17,0,0,56,0,0,0,0],"FLAG":1,"BASE":18}
|
||||
WAZA JH-G01B {"NAME":"Teckin SP27","GPIO":[255,255,255,255,53,255,0,0,21,17,255,255,255],"FLAG":0,"BASE":18}
|
||||
@ -1019,6 +1050,7 @@ Arlec Smart PB88UHA {"NAME":"Arlec PB88UHA","GPIO":[0,56,0,17,22,21,0,0,24,
|
||||
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}
|
||||
Brennenstuhl Connect Eco-Line {"NAME":"WS EL01 DE","GPIO":[19,18,0,17,21,22,0,0,52,0,0,53,158],"FLAG":0,"BASE":18}
|
||||
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}
|
||||
CE Smart Home {"NAME":"CE Power Strip","GPIO":[52,0,0,0,22,21,0,0,24,23,25,26,17],"FLAG":0,"BASE":18}
|
||||
CE Smart Home Garden Stake {"NAME":"CE Power Stake","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
@ -1027,6 +1059,7 @@ Deltaco SH-P03USB {"NAME":"Deltaco SH-P03","GPIO":[56,0,0,0,0,23,0,0,21,1
|
||||
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}
|
||||
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 + Charge 2 USB {"NAME":"Geeni GN-SW023","GPIO":[52,0,0,0,22,21,0,0,23,24,25,0,17],"FLAG":0,"BASE":18}
|
||||
Geeni SURGE 6-Outlet Surge Protector {"NAME":"Geeni 6 Strip","GPIO":[56,0,0,0,22,21,0,0,24,25,23,26,0],"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}
|
||||
Globe 4 Outlet 2 USB {"NAME":"PowerBar","GPIO":[56,0,0,0,24,17,0,0,22,23,21,0,0],"FLAG":15,"BASE":18}
|
||||
@ -1049,6 +1082,7 @@ KMC 5AC 3USB QC {"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}
|
||||
Konesky Type 1 {"NAME":"Konesky","GPIO":[0,0,0,0,25,22,0,0,24,17,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}
|
||||
Larkkey 4AC 4USB {"NAME":"LARKKEY Strip","GPIO":[0,157,0,17,22,21,0,0,23,24,25,0,0],"FLAG":0,"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}
|
||||
@ -1080,6 +1114,7 @@ WP40 {"NAME":"WP40","GPIO":[33,0,0,0,56,0,0,0,21,17,22,23,32
|
||||
Xenon SM-S0301 {"NAME":"SM-SO301","GPIO":[52,255,255,57,29,17,0,0,31,30,32,255,25],"FLAG":0,"BASE":18}
|
||||
Xenon SM-S0301-U {"NAME":"SM-SO301-U","GPIO":[52,255,255,57,29,17,0,0,31,30,32,255,25],"FLAG":0,"BASE":18}
|
||||
Xenon SM-SO301 v2 {"NAME":"SM-SO301","GPIO":[56,0,0,0,30,17,0,0,32,31,33,0,21],"FLAG":0,"BASE":18}
|
||||
Xenta 3 AC 6 USB {"NAME":"Xenta-3-Gang","GPIO":[52,0,0,57,29,17,0,0,31,30,0,0,24],"FLAG":0,"BASE":18}
|
||||
XS-A25 {"NAME":"XS-A25","GPIO":[52,0,53,0,25,22,0,0,24,17,23,21,0],"FLAG":0,"BASE":18}
|
||||
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}
|
||||
@ -1088,6 +1123,7 @@ Yagala SWB3 {"NAME":"YAGALA SWB3","GPIO":[157,0,53,0,0,23,0,0,21,17
|
||||
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 4AC 2USB {"NAME":"Zeoota WP30","GPIO":[0,17,0,24,0,0,0,0,0,22,21,23,0],"FLAG":7,"BASE":18}
|
||||
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}
|
||||
@ -1125,9 +1161,10 @@ Athom 7W 600lm {"NAME":"Athom LB017W","GPIO":[0,0,0,0,37,40,0,0,38,41,
|
||||
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}
|
||||
B.K. Licht 5.5W 350lm {"NAME":"BKL1262","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
B.K. Licht 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}
|
||||
BAZZ BR30 650lm {"NAME":"BAZZrgb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
BlitzWolf 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 8.5W 800lm {"NAME":"BNETA IO-WIFI60-E27P","GPIO":[0,0,0,0,37,40,0,0,38,50,39,0,0],"FLAG":0,"BASE":18}
|
||||
BNETA 8.5W 800lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18}
|
||||
@ -1138,6 +1175,7 @@ Calex 5W 350lm Reflector {"NAME":"Calex RGBW","GPIO":[0,0,0,0,0,0,0,0,181,0,180
|
||||
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}
|
||||
Connect SmartHome 5W GU5.3 {"NAME":"CSH-GU53RGB5W","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18}
|
||||
Diolamp E27 9W 800lm {"NAME":"Diolamp A609WIFI","GPIO":[0,0,0,0,180,0,0,0,0,0,181,0,0],"FLAG":0,"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}
|
||||
@ -1162,6 +1200,7 @@ Helloify BR30 9W 600lm {"NAME":"Helloify","GPIO":[255,255,255,255,37,40,255,25
|
||||
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}
|
||||
HIPER IoT C1 {"NAME":"Hiper IoT C1 RGB","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
|
||||
Holdpeak BR40 12W 1100lm {"NAME":"HP-BR40-12W","GPIO":[0,0,0,0,140,37,0,0,38,0,141,0,0],"FLAG":0,"BASE":18}
|
||||
Hombli 9W 800lm {"NAME":"HBEB-0124","GPIO":[0,0,0,0,39,38,0,0,40,37,41,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}
|
||||
@ -1189,6 +1228,7 @@ Lohas ZN036 900 lm {"NAME":"Lohas RGBCCT","GPIO":[0,0,0,0,38,37,0,0,41,39,
|
||||
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 ZN038 BR20 8W 750lm {"NAME":"Lohas LH-ZN038","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
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}
|
||||
Lohas ZN041 BR30 12W 1080lm {"NAME":"Lohas ZN041","GPIO":[0,0,0,0,39,37,0,0,41,38,40,0,0],"FLAG":0,"BASE":18}
|
||||
Longlifelamps A60 9W {"NAME":"longlifelamps A60 RGBWW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,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}
|
||||
Luminea 5.5W 470lm {"NAME":"Luminea ZX-2983","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
|
||||
@ -1203,7 +1243,7 @@ Nishica JBT 9W 806lm {"NAME":"Nishica","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,
|
||||
Novostella 7W 600lm {"NAME":"Novostella E27","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
Novostella 7W 600lm {"NAME":"Novostella B22","GPIO":[0,0,0,0,37,41,0,0,38,40,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 NTB10 9W 900lm {"NAME":"NTB10","GPIO":[0,0,0,0,41,38,0,0,39,51,40,37,0],"FLAG":0,"BASE":18}
|
||||
Novostella UT55507 9W 900lm {"NAME":"Novostella UT55507","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
Novostella UT55507 9W 900lm {"NAME":"Novostella UT55507","GPIO":[0,0,0,0,37,40,0,0,38,41,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}
|
||||
@ -1223,6 +1263,7 @@ RYE 5W 450LM Candle {"NAME":"RYE Candlebra","GPIO":[0,0,0,0,37,40,0,0,38,41
|
||||
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}
|
||||
Smart 9W 800lm {"NAME":"SmartLED ","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,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}
|
||||
@ -1233,7 +1274,8 @@ Techlux A19 9W 806lm {"NAME":"TECHLUX A19 RGBCW 806lm 9w","GPIO":[0,0,0,0,37
|
||||
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}
|
||||
Treatlife A19 8W 650lm {"NAME":"Treatlife RGBW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18}
|
||||
V-Tac PAR16 4.5W 400lm 100C {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
|
||||
V-TAC 10W 806lm {"NAME":"V-TAC VT-5119","GPIO":[0,0,0,0,180,0,0,0,0,0,181,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}
|
||||
@ -1259,7 +1301,7 @@ Avatar Controls A19 10W 900lm {"NAME":"Avatar E26 10W","GPIO":[0,0,0,0,0,39,0,0
|
||||
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 900lm {"NAME":"BlitzWolf LT21","GPIO":[0,0,0,0,41,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18}
|
||||
BlitzWolf 900lm {"NAME":"BlitzWolf LT21","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18}
|
||||
BNeta 4.5W 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 350lm Candle {"NAME":"HK17653S72","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18}
|
||||
@ -1309,7 +1351,7 @@ Kainsy 600lm {"NAME":"KAINSY","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0
|
||||
Kkmoon 9W 800lm {"NAME":"KKMOON V21","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18}
|
||||
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 4.5W 330lm 110C {"NAME":"Kogan_GU10","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":0,"BASE":18}
|
||||
Kogan 4.5W 330lm 110 {"NAME":"Kogan_GU10","GPIO":[0,0,0,0,39,40,0,0,37,0,38,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}
|
||||
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}
|
||||
@ -1371,6 +1413,7 @@ Saudio 7W 700lm {"NAME":"X002BU0DOL","GPIO":[0,0,0,0,37,40,0,0,38,41,39
|
||||
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}
|
||||
Smitch 7W {"NAME":"Smitch RGB 7W SB-1602","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
|
||||
Solimo 12W {"NAME":"Solimo RGBCCT 12","GPIO":[0,0,0,0,37,41,0,0,38,40,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}
|
||||
@ -1401,7 +1444,7 @@ Zilotek A19 800lm {"NAME":"Zilotek RGBW","GPIO":[0,0,0,0,140,37,0,0,38,14
|
||||
## Relay
|
||||
```
|
||||
Anmbest 2 Channel Inching Self-locking Switch Module {"NAME":"Generic","GPIO":[17,255,255,255,255,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":1}
|
||||
Athom 16A {"NAME":"Athom CB0110A","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1}
|
||||
Athom 10A {"NAME":"Athom CB0110A","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1}
|
||||
BH OnOfre Dual Rev5 Silent Edition {"NAME":"bhonofre","GPIO":[0,0,0,0,22,21,0,0,9,10,0,0,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}
|
||||
@ -1422,6 +1465,7 @@ LC Technology DC8V-80V/5V 1 Channel ESP-12F Dev Board {"NAME":"LC Relay-ESP12-1
|
||||
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}
|
||||
LoveAnna AC85-250V 10A {"NAME":"2xSwitch No RF LoveAnna","GPIO":[17,0,0,0,0,22,18,0,21,56,0,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}
|
||||
Sinilink DC6V-36V Module {"NAME":"Sinilink XY-WF5V","GPIO":[0,0,0,0,21,255,0,0,17,52,0,0,255],"FLAG":0,"BASE":18}
|
||||
Sinilink MOS {"NAME":"Sinilink MOS","GPIO":[0,0,0,0,21,255,0,0,17,52,0,0,255],"FLAG":0,"BASE":18}
|
||||
@ -1438,10 +1482,11 @@ Smoke Alarm {"NAME":"YG400A","GPIO":[255,107,255,108,255,255,0,0,25
|
||||
|
||||
## Switch
|
||||
```
|
||||
3 Way Smart Light {"NAME":"Nexete KS-602F 3-Way","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54}
|
||||
3A Smart Home {"NAME":"3A Smart Home ","GPIO":[52,0,55,18,22,19,0,0,17,21,54,23,53],"FLAG":0,"BASE":18}
|
||||
AGL 2 Gang {"NAME":"AGL WiFi 02","GPIO":[0,0,157,0,0,18,0,0,22,21,0,0,17],"FLAG":0,"BASE":18}
|
||||
AGL 3 Gang {"NAME":"AGL WiFi 03","GPIO":[0,0,157,0,19,18,0,0,22,21,23,0,17],"FLAG":0,"BASE":18}
|
||||
AGL Modulo Relay 01 Canal {"NAME":"AGL-Basic","GPIO":[0,255,0,0,21,17,0,0,0,0,56,0,0],"FLAG":0,"BASE":18}
|
||||
AGL Modulo Rel 01 Canal {"NAME":"AGL-Basic","GPIO":[0,255,0,0,21,17,0,0,0,0,56,0,0],"FLAG":0,"BASE":18}
|
||||
Albohes 2 Channel {"NAME":"Albohes SH-08","GPIO":[0,148,18,149,57,56,0,0,21,157,17,0,22],"FLAG":15,"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}
|
||||
Athom 1 Gang {"NAME":"Athom SW011EU","GPIO":[158,0,0,17,0,0,0,0,0,21,52,0,0],"FLAG":0,"BASE":1}
|
||||
@ -1466,6 +1511,7 @@ BlitzWolf BW-SS3 3 Gang {"NAME":"BlitzWolf SS3","GPIO":[158,0,0,10,22,11,0,0,9,
|
||||
BlitzWolf BW-SS5 1 Gang {"NAME":"BlitzWolf SS5 1 Gang","GPIO":[0,0,0,0,0,0,0,0,9,21,0,0,0],"FLAG":0,"BASE":18}
|
||||
BlitzWolf BW-SS5 2 Gang {"NAME":"BlitzWolf SS5 2 Gang","GPIO":[0,0,17,0,160,0,0,0,10,9,21,22,0],"FLAG":0,"BASE":18}
|
||||
BlitzWolf SS4 {"NAME":"BlitzWolf SS4 Two Gang","GPIO":[0,0,0,0,56,21,0,0,22,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
BSEED 2 Gang 1 Way {"NAME":"BSEED Switch 2Ch","GPIO":[0,0,0,18,22,0,0,0,17,21,0,52,53],"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}
|
||||
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}
|
||||
Century Aoke Smart Switch {"NAME":"CenturyAoke","GPIO":[0,255,0,255,21,0,0,0,17,56,255,0,0],"FLAG":0,"BASE":18}
|
||||
@ -1478,9 +1524,12 @@ Deta 6000HA Smart Inline Switch {"NAME":"DETA-6000HA","GPIO":[0,17,0,0,0,0,0,0,
|
||||
Deta Fan Speed Controller with Light {"NAME":"Deta Fan Speed and Light Controller","GPIO":[18,0,0,157,23,19,0,0,0,22,21,24,17],"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}
|
||||
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}
|
||||
DS-102 1 Gang {"NAME":"DS-102 1 Gang","GPIO":[57,0,0,17,0,0,0,0,0,21,56,0,0],"FLAG":1,"BASE":18}
|
||||
DS-101 1 Gang {"NAME":"Smart Life Switch","GPIO":[0,0,0,0,0,17,0,0,0,0,0,21,52],"FLAG":0,"BASE":18}
|
||||
DS-102 1 Gang {"NAME":"DS-102 1 Gang","GPIO":[158,0,0,17,0,0,0,0,0,21,52,0,0],"FLAG":0,"BASE":18}
|
||||
DS-102 2 Gang {"NAME":"DS-102 2 Gang","GPIO":[158,57,0,17,22,18,0,0,0,21,56,255,0],"FLAG":0,"BASE":18}
|
||||
DS-102 3 Gang {"NAME":"DS-102 3 Gang","GPIO":[158,58,0,18,22,19,0,0,17,21,57,23,56],"FLAG":0,"BASE":18}
|
||||
DS-121 2 Gang No Neutral {"NAME":"2 Gang Switch","GPIO":[0,57,0,17,22,18,0,0,0,21,56,0,0],"FLAG":0,"BASE":18}
|
||||
DS-121 4 Gang No Neutral {"NAME":"4 Gang Switch","GPIO":[52,255,255,18,22,19,0,0,17,21,24,23,20],"FLAG":0,"BASE":18}
|
||||
Eachen CD303 3 Gang {"NAME":"ID Components","GPIO":[157,53,0,11,21,10,0,0,9,22,54,23,52],"FLAG":15,"BASE":18}
|
||||
Eachen SWT-2Gang {"NAME":"ID Components","GPIO":[157,255,255,255,255,10,255,255,9,21,53,22,52],"FLAG":15,"BASE":18}
|
||||
eMylo 2 Channel {"NAME":"eMylo XL9252WI","GPIO":[0,255,0,0,56,22,0,0,21,0,12,0,0],"FLAG":0,"BASE":18}
|
||||
@ -1537,7 +1586,7 @@ L-5A01 {"NAME":"L-5A01","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0
|
||||
Laghten SS02S {"NAME":"Laghten SS02S","GPIO":[0,0,0,0,52,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
LCARE Modular 2 Gang {"NAME":"2SW1-In","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":29}
|
||||
LerLink X801A-L No Neutral {"NAME":"LerLink X801-L","GPIO":[0,0,0,0,17,0,0,0,21,56,0,0,0],"FLAG":15,"BASE":18}
|
||||
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 2 Gang {"NAME":"Lerlink X802A","GPIO":[0,0,0,18,17,0,0,0,21,52,22,0,0],"FLAG":0,"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":0,"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}
|
||||
@ -1660,8 +1709,8 @@ STITCH by Monoprice 35557 {"NAME":"Tuya WF15S ","GPIO":[255,255,0,0,255,255,0,0
|
||||
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}
|
||||
SW-R03 {"NAME":"SW-R03","GPIO":[0,0,0,0,0,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
TCP Smart 1 Gang {"NAME":"TCP 1 Gang 1 Way","GPIO":[157,0,0,17,21,0,0,0,0,0,56,0,0],"FLAG":0,"BASE":18}
|
||||
Teckin 2 Gang {"NAME":"Teckin SR43","GPIO":[0,0,52,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18}
|
||||
Teckin SR-41 Single Pole {"NAME":"Teckin SR-41","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":18}
|
||||
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}
|
||||
@ -1675,10 +1724,11 @@ TreatLife SS02 3-Way {"NAME":"TreatLife 3Way","GPIO":[0,0,0,0,53,29,0,0,30,1
|
||||
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}
|
||||
Unbranded 2 Gang {"NAME":"Smart Life Switch 2","GPIO":[157,57,0,17,21,18,0,0,0,22,56,0,0],"FLAG":0,"BASE":18}
|
||||
Useelink 1 Gang {"NAME":"USEELINK-SW-1G","GPIO":[52,0,0,0,0,0,0,0,17,21,0,0,0],"FLAG":0,"BASE":18}
|
||||
Useelink 2 Gang {"NAME":"SM-SW101-2","GPIO":[158,52,0,18,22,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18}
|
||||
Useelink 3 Gang {"NAME":"Useelink 3 Gang Wall Switch","GPIO":[158,52,0,18,22,17,0,0,19,23,53,21,52],"FLAG":0,"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 1 Gang Switch {"NAME":"VH-TW-CL-01","GPIO":[0,0,0,0,0,17,0,0,0,0,0,21,157],"FLAG":15,"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}
|
||||
@ -1728,7 +1778,7 @@ Owfeel EN71 {"NAME":"SmartValve","GPIO":[21,0,0,0,0,0,0,0,17,52,0,0
|
||||
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}
|
||||
BSEED Smart Socket {"NAME":"BSEED Socket","GPIO":[0,0,0,0,157,52,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
CE Smart Home {"NAME":"CE Smart Wall","GPIO":[255,255,255,255,157,17,0,0,21,255,255,255,255],"FLAG":15,"BASE":18}
|
||||
CE Smart Home LQ-2-W3 {"NAME":"LITESUN","GPIO":[0,0,0,0,157,17,0,0,21,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
Deta 6922HA {"NAME":"DETA 2G GPO","GPIO":[0,0,0,0,157,0,0,0,91,21,22,0,90],"FLAG":0,"BASE":18}
|
||||
@ -1742,6 +1792,7 @@ Makegood MG-AUWF01 {"NAME":"MG-AUWF01","GPIO":[56,10,157,59,134,132,0,0,13
|
||||
Makegood MG-UKWSG01 {"NAME":"Aseer 2-Gang","GPIO":[57,9,157,59,134,132,0,0,131,21,56,22,10],"FLAG":0,"BASE":18}
|
||||
Makegood MG-UKWSW/B {"NAME":"Aseer 1-Gang","GPIO":[56,0,157,57,134,132,0,0,131,0,0,21,9],"FLAG":0,"BASE":18}
|
||||
Moes WWK Glass Panel {"NAME":"Smart Socket","GPIO":[0,0,0,0,52,53,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
Oittm 120 {"NAME":"Oittm WS01","GPIO":[17,0,0,0,0,130,0,0,21,132,133,52,0],"FLAG":0,"BASE":18}
|
||||
PS-1607 {"NAME":"PS-1607","GPIO":[17,0,0,0,0,22,18,0,21,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
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}
|
||||
@ -1756,6 +1807,7 @@ Vigica VGSPK00815 {"NAME":"VIGICA outlet","GPIO":[17,255,255,255,255,22,1
|
||||
## Water Sensor
|
||||
```
|
||||
W06 {"NAME":"W06 Water Sensor","GPIO":[0,148,0,149,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||
Y09 {"NAME":"Y09","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||
```
|
||||
|
||||
## Zigbee Bridge
|
||||
|
||||
@ -30,6 +30,8 @@ lib_ignore =
|
||||
EspSoftwareSerial
|
||||
SPISlave
|
||||
Hash
|
||||
; Disable next if you want to use ArduinoOTA in Tasmota (default disabled)
|
||||
ArduinoOTA
|
||||
|
||||
[env:tasmota]
|
||||
|
||||
|
||||
@ -21,12 +21,14 @@ lib_ignore =
|
||||
ESP32 Azure IoT Arduino
|
||||
ESP32 Async UDP
|
||||
ESP32 BLE Arduino
|
||||
SimpleBLE
|
||||
; SimpleBLE
|
||||
NetBIOS
|
||||
ESP32
|
||||
Preferences
|
||||
BluetoothSerial
|
||||
|
||||
; Disable next if you want to use ArduinoOTA in Tasmota32 (default disabled)
|
||||
ArduinoOTA
|
||||
|
||||
[env:tasmota32-webcam]
|
||||
extends = env:tasmota32
|
||||
board = esp32cam
|
||||
|
||||
@ -113,6 +113,7 @@
|
||||
#define D_JSON_NONE "None"
|
||||
#define D_JSON_OR "or"
|
||||
#define D_JSON_ORP "ORP"
|
||||
#define D_JSON_O2 "Oxygen"
|
||||
#define D_JSON_PERIOD "Period"
|
||||
#define D_JSON_PH "pH"
|
||||
#define D_JSON_PHASE_ANGLE "PhaseAngle"
|
||||
@ -181,6 +182,7 @@
|
||||
#define D_JSON_VCC "Vcc"
|
||||
#define D_JSON_VERSION "Version"
|
||||
#define D_JSON_VOLTAGE "Voltage"
|
||||
#define D_JSON_VOLUME "Volume"
|
||||
#define D_JSON_WEIGHT "Weight"
|
||||
#define D_JSON_WIFI "Wifi"
|
||||
#define D_JSON_WRONG "Wrong"
|
||||
@ -263,6 +265,7 @@
|
||||
#define D_CMND_PWMRANGE "PWMRange"
|
||||
#define D_CMND_BUTTONDEBOUNCE "ButtonDebounce"
|
||||
#define D_CMND_SWITCHDEBOUNCE "SwitchDebounce"
|
||||
#define D_CMND_SWITCHTEXT "SwitchText"
|
||||
#define D_CMND_SLEEP "Sleep"
|
||||
#define D_CMND_UPLOAD "Upload"
|
||||
#define D_CMND_UPGRADE "Upgrade"
|
||||
@ -564,6 +567,8 @@
|
||||
#define D_JSON_ZIGBEE_UNBIND "ZbUnbind"
|
||||
#define D_CMND_ZIGBEE_BIND_STATE "BindState"
|
||||
#define D_JSON_ZIGBEE_BIND_STATE "ZbBindState"
|
||||
#define D_CMND_ZIGBEE_MAP "Map"
|
||||
#define D_JSON_ZIGBEE_MAP "ZbMap"
|
||||
#define D_JSON_ZIGBEE_PARENT "ZbParent"
|
||||
#define D_CMND_ZIGBEE_PING "Ping"
|
||||
#define D_JSON_ZIGBEE_PING "ZbPing"
|
||||
@ -574,6 +579,8 @@
|
||||
#define D_JSON_ZIGBEE_STATUS_MSG "StatusMessage"
|
||||
#define D_CMND_ZIGBEE_LIGHT "Light"
|
||||
#define D_JSON_ZIGBEE_LIGHT "Light"
|
||||
#define D_CMND_ZIGBEE_OCCUPANCY "Occupancy"
|
||||
#define D_JSON_ZIGBEE_OCCUPANCY "Occupancy"
|
||||
#define D_CMND_ZIGBEE_RESTORE "Restore"
|
||||
#define D_CMND_ZIGBEE_CONFIG "Config"
|
||||
#define D_JSON_ZIGBEE_CONFIG "Config"
|
||||
@ -775,6 +782,9 @@ const char HTTP_SNS_ENERGY_TOTAL[] PROGMEM = "{s}" D_ENERGY_TOTAL "{
|
||||
const char HTTP_SNS_PH[] PROGMEM = "{s}%s " D_PH "{m}%s " "{e}";
|
||||
const char HTTP_SNS_ORP[] PROGMEM = "{s}%s " D_ORP "{m}%s " D_UNIT_MILLIVOLT "{e}";
|
||||
const char HTTP_SNS_EC[] PROGMEM = "{s}%s " D_EC "{m}%s " D_UNIT_MICROSIEMENS_PER_CM "{e}";
|
||||
const char HTTP_SNS_O2[] PROGMEM = "{s}%s " D_O2 "{m}%s " D_UNIT_PERCENT "{e}";
|
||||
const char HTTP_SNS_LITERS[] PROGMEM = "{s}%s " D_VOLUME "{m}%s " D_UNIT_LITERS "{e}";
|
||||
const char HTTP_SNS_LPM[] PROGMEM = "{s}%s " D_FLOW_RATE "{m}%s " D_UNIT_LITERS_PER_MIN "{e}";
|
||||
|
||||
const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
|
||||
const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION;
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "неколкократно натискане"
|
||||
#define D_NOISE "Шум"
|
||||
#define D_NONE "Няма"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Изкл."
|
||||
#define D_OFFLINE "Офлайн"
|
||||
#define D_OK "Ок"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV мощност"
|
||||
#define D_VERSION "Версия"
|
||||
#define D_VOLTAGE "Напрежение"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Тегло"
|
||||
#define D_WARMLIGHT "Топла"
|
||||
#define D_WEB_SERVER "Уеб сървър"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "několikeré-stisknutí"
|
||||
#define D_NOISE "Hluk"
|
||||
#define D_NONE "Žádný"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Vyp."
|
||||
#define D_OFFLINE "Offline" // Don't translate, LWT message! Nepředkládat, LWT zpráva!
|
||||
#define D_OK "OK"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_VERSION "Verze"
|
||||
#define D_VOLTAGE "Napětí"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Hmotnost"
|
||||
#define D_WARMLIGHT "Teplé světlo"
|
||||
#define D_WEB_SERVER "Web Server"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -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.4.0.3
|
||||
* Updated until v9.0.0.3
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "Mehrfachdruck"
|
||||
#define D_NOISE "Lautstärke"
|
||||
#define D_NONE "keine"
|
||||
#define D_O2 "Sauerstoff"
|
||||
#define D_OFF "aus"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "OK"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Intensität"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VOLTAGE "Spannung"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Gewicht"
|
||||
#define D_WARMLIGHT "warm"
|
||||
#define D_WEB_SERVER "Web-Server"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "ανίχνευση για πολλαπλά πατήματα"
|
||||
#define D_NOISE "Θόρυβος"
|
||||
#define D_NONE "Κανένα"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Off"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "Ένταση UV"
|
||||
#define D_VERSION "Έκδοση"
|
||||
#define D_VOLTAGE "Τάση"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Βάρος"
|
||||
#define D_WARMLIGHT "Θερμό"
|
||||
#define D_WEB_SERVER "Διακομιστής Web"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "multi-press"
|
||||
#define D_NOISE "Noise"
|
||||
#define D_NONE "None"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Off"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VOLTAGE "Voltage"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Weight"
|
||||
#define D_WARMLIGHT "Warm"
|
||||
#define D_WEB_SERVER "Web Server"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "multi-press"
|
||||
#define D_NOISE "Ruido"
|
||||
#define D_NONE "Ninguno"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Apagado"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_VERSION "Versión"
|
||||
#define D_VOLTAGE "Tensión"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Peso"
|
||||
#define D_WARMLIGHT "Cálida"
|
||||
#define D_WEB_SERVER "Servidor Web"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -121,6 +121,7 @@
|
||||
#define D_MULTI_PRESS "multi-pression"
|
||||
#define D_NOISE "Bruit"
|
||||
#define D_NONE "Aucun"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Arrêt"
|
||||
#define D_OFFLINE "Déconnecté"
|
||||
#define D_OK "Ok"
|
||||
@ -186,6 +187,7 @@
|
||||
#define D_UV_POWER "Puissance UV"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VOLTAGE "Tension"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Poids"
|
||||
#define D_WARMLIGHT "Chaud"
|
||||
#define D_WEB_SERVER "Serveur web"
|
||||
@ -740,6 +742,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "לחיצה מרובה"
|
||||
#define D_NOISE "רעש"
|
||||
#define D_NONE "כלום"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "כבוי"
|
||||
#define D_OFFLINE "מנותק"
|
||||
#define D_OK "אוקיי"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_VERSION "גרסה"
|
||||
#define D_VOLTAGE "מתח"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "משקל"
|
||||
#define D_WARMLIGHT "חום"
|
||||
#define D_WEB_SERVER "Web שרת"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "több lenyomás"
|
||||
#define D_NOISE "Zaj"
|
||||
#define D_NONE "nincs"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Ki"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "OK"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV teljesítmény"
|
||||
#define D_VERSION "Verzió"
|
||||
#define D_VOLTAGE "Feszültség"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Tömeg"
|
||||
#define D_WARMLIGHT "Meleg fény"
|
||||
#define D_WEB_SERVER "Webszerver"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
it-IT.h - localization for Italian - Italy for Tasmota
|
||||
|
||||
Copyright (C) 2020 Gennaro Tortone - some mods by Antonio Fragola - Updated by bovirus - rev. 03.10.2020
|
||||
Copyright (C) 2020 Gennaro Tortone - some mods by Antonio Fragola - Updated by bovirus - rev. 30.10.2020
|
||||
|
||||
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
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "multi-pressione"
|
||||
#define D_NOISE "Rumore"
|
||||
#define D_NONE "Nessuno"
|
||||
#define D_O2 "Ossigeno"
|
||||
#define D_OFF "OFF"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "OK"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "Intensità UV"
|
||||
#define D_VERSION "Versione"
|
||||
#define D_VOLTAGE "Tensione"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Peso"
|
||||
#define D_WARMLIGHT "Calda"
|
||||
#define D_WEB_SERVER "Server web"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "multi-press"
|
||||
#define D_NOISE "소음"
|
||||
#define D_NONE "없음"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "꺼짐"
|
||||
#define D_OFFLINE "오프라인"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV 파워"
|
||||
#define D_VERSION "버전"
|
||||
#define D_VOLTAGE "전압"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "무게"
|
||||
#define D_WARMLIGHT "따뜻하게"
|
||||
#define D_WEB_SERVER "웹 서버"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "마이크로미터"
|
||||
|
||||
@ -120,11 +120,12 @@
|
||||
#define D_LWT "LWT"
|
||||
#define D_LQI "LQI" // Zigbee Link Quality Index
|
||||
#define D_MODULE "Module"
|
||||
#define D_MOISTURE "Moisture"
|
||||
#define D_MOISTURE "Vochtigheid"
|
||||
#define D_MQTT "MQTT"
|
||||
#define D_MULTI_PRESS "meervoudig"
|
||||
#define D_NOISE "Lawaai"
|
||||
#define D_NONE "Geen"
|
||||
#define D_O2 "Zuurstof"
|
||||
#define D_OFF "Uit"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV intensiteit"
|
||||
#define D_VERSION "Versie"
|
||||
#define D_VOLTAGE "Spanning"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Gewicht"
|
||||
#define D_WARMLIGHT "Warm"
|
||||
#define D_WEB_SERVER "Webserver"
|
||||
@ -497,12 +499,12 @@
|
||||
#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_GESTURE "Gebaar"
|
||||
#define D_COLOR_RED "Rood"
|
||||
#define D_COLOR_GREEN "Groen"
|
||||
#define D_COLOR_BLUE "Blauw"
|
||||
#define D_CCT "CCT"
|
||||
#define D_PROXIMITY "Proximity"
|
||||
#define D_PROXIMITY "Nabijheid"
|
||||
|
||||
// xsns_32_mpu6050.ino
|
||||
#define D_AX_AXIS "Versn. X-as"
|
||||
@ -536,23 +538,23 @@
|
||||
#define D_TX20_WEST "W"
|
||||
|
||||
// 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_TPWRIN "Totaal energie-In"
|
||||
#define D_TPWROUT "Totaal energie-Uit"
|
||||
#define D_TPWRCURR "Werkelijk vermogen-In/Uit"
|
||||
#define D_TPWRCURR1 "Werkelijk vermogen-In p1"
|
||||
#define D_TPWRCURR2 "Werkelijk vermogen-In p2"
|
||||
#define D_TPWRCURR3 "Werkelijk vermogen-In p3"
|
||||
#define D_Strom_L1 "Stroom L1"
|
||||
#define D_Strom_L2 "Stroom L2"
|
||||
#define D_Strom_L3 "Stroom 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_METERNR "Meter_nummer"
|
||||
#define D_METERSID "Service ID"
|
||||
#define D_GasIN "Counter"
|
||||
#define D_H2oIN "Counter"
|
||||
#define D_StL1L2L3 "Current L1+L2+L3"
|
||||
#define D_GasIN "Teller"
|
||||
#define D_H2oIN "Teller"
|
||||
#define D_StL1L2L3 "Stroom L1+L2+L3"
|
||||
#define D_SpL1L2L3 "Voltage L1+L2+L3/3"
|
||||
|
||||
// tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||
@ -678,9 +680,9 @@
|
||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client 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"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
@ -778,7 +782,7 @@
|
||||
#define D_TOTAL_REACTIVE "Totaal blind"
|
||||
#define D_UNIT_KWARH "kVArh"
|
||||
#define D_UNIT_ANGLE "Deg"
|
||||
#define D_TOTAL_ACTIVE "Total Active"
|
||||
#define D_TOTAL_ACTIVE "Totaal werkelijk"
|
||||
|
||||
//SOLAXX1
|
||||
#define D_PV1_VOLTAGE "PV1 spanning"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "Wielokrotne naciśnięcie"
|
||||
#define D_NOISE "Szum"
|
||||
#define D_NONE "Brak"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Wyłączony"
|
||||
#define D_OFFLINE "Nieaktywny"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "Moc UV"
|
||||
#define D_VERSION "Wersja"
|
||||
#define D_VOLTAGE "Napięcie"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Waga"
|
||||
#define D_WARMLIGHT "Temperatura światła"
|
||||
#define D_WEB_SERVER "Serwer Web"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "multi-pressão"
|
||||
#define D_NOISE "Ruído"
|
||||
#define D_NONE "Nenhum"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Desligado"
|
||||
#define D_OFFLINE "Desconectado"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_VERSION "Versão"
|
||||
#define D_VOLTAGE "Voltagem"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Peso"
|
||||
#define D_WARMLIGHT "Luz quente"
|
||||
#define D_WEB_SERVER "Servidor WEB"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "multi-pressão"
|
||||
#define D_NOISE "Ruído"
|
||||
#define D_NONE "Nenhum"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Off"
|
||||
#define D_OFFLINE "Desconetado"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "Poder UV"
|
||||
#define D_VERSION "Versão"
|
||||
#define D_VOLTAGE "Voltagem"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Peso"
|
||||
#define D_WARMLIGHT "Luz Quente"
|
||||
#define D_WEB_SERVER "Servidor WEB"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "selectare multiplă"
|
||||
#define D_NOISE "Zgomot"
|
||||
#define D_NONE "Lipsă"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Închis"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "Putere UV"
|
||||
#define D_VERSION "Versiune"
|
||||
#define D_VOLTAGE "Voltaj"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Greutate"
|
||||
#define D_WARMLIGHT "Cald"
|
||||
#define D_WEB_SERVER "Server Web"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "многократное нажатие"
|
||||
#define D_NOISE "Шум"
|
||||
#define D_NONE "Нет"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Выкл"
|
||||
#define D_OFFLINE "Офф-лайн"
|
||||
#define D_OK "Ок"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_VERSION "Версия"
|
||||
#define D_VOLTAGE "Напряжение"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Weight"
|
||||
#define D_WARMLIGHT "Тепло"
|
||||
#define D_WEB_SERVER "Web сервер"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "кОм"
|
||||
#define D_UNIT_KILOWATTHOUR "кВт"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "лк"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "мкг/м³"
|
||||
#define D_UNIT_MICROMETER "мкм"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "multi-stlačenie"
|
||||
#define D_NOISE "Hluk"
|
||||
#define D_NONE "Žiadny"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Vyp."
|
||||
#define D_OFFLINE "Neaktívny"
|
||||
#define D_OK "OK"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_VERSION "Verzia"
|
||||
#define D_VOLTAGE "Napätie"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Hmotnosť"
|
||||
#define D_WARMLIGHT "Teplé svetlo"
|
||||
#define D_WEB_SERVER "Web Server"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "fler tryck"
|
||||
#define D_NOISE "Oväsen"
|
||||
#define D_NONE "Ingen"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Av"
|
||||
#define D_OFFLINE "Off-line"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV kraft"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VOLTAGE "Volttal"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Vikt"
|
||||
#define D_WARMLIGHT "Varm"
|
||||
#define D_WEB_SERVER "Webbserver"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "multi-press"
|
||||
#define D_NOISE "Noise"
|
||||
#define D_NONE "None"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Off"
|
||||
#define D_OFFLINE "Çevirimdışı"
|
||||
#define D_OK "Tamam"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_VERSION "Versiyon"
|
||||
#define D_VOLTAGE "Voltaj"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Weight"
|
||||
#define D_WARMLIGHT "Sıcak"
|
||||
#define D_WEB_SERVER "Web Sunucusu"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "Багаторазове натискання"
|
||||
#define D_NOISE "Шум"
|
||||
#define D_NONE "Нічого"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Вимкнено"
|
||||
#define D_OFFLINE "Неактивний"
|
||||
#define D_OK "Ок"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "Потужність УФ"
|
||||
#define D_VERSION "Версія"
|
||||
#define D_VOLTAGE "Напруга"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Вага"
|
||||
#define D_WARMLIGHT "Тепло"
|
||||
#define D_WEB_SERVER "Web сервер"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "км/г" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "㏀"
|
||||
#define D_UNIT_KILOWATTHOUR "кВт/г"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "лк"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µг/м³"
|
||||
#define D_UNIT_MICROMETER "µм"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "bấm nhiều lần"
|
||||
#define D_NOISE "Nhiễu"
|
||||
#define D_NONE "Không"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "Tắt"
|
||||
#define D_OFFLINE "Ngoại tuyến"
|
||||
#define D_OK "Ok"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "Công suất UV"
|
||||
#define D_VERSION "Phiên bản"
|
||||
#define D_VOLTAGE "Điện áp"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "Cân nặng"
|
||||
#define D_WARMLIGHT "Ấm"
|
||||
#define D_WEB_SERVER "Máy chủ Web"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "多次按键"
|
||||
#define D_NOISE "嘈杂"
|
||||
#define D_NONE "无"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "关"
|
||||
#define D_OFFLINE "离线"
|
||||
#define D_OK "好"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "紫外线功率 "
|
||||
#define D_VERSION "版本"
|
||||
#define D_VOLTAGE "电压"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "重量"
|
||||
#define D_WARMLIGHT "暖"
|
||||
#define D_WEB_SERVER "Web Server"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "公里/时" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "千欧"
|
||||
#define D_UNIT_KILOWATTHOUR "千瓦时"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "勒克斯"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "微克/立方米"
|
||||
#define D_UNIT_MICROMETER "微米"
|
||||
|
||||
@ -125,6 +125,7 @@
|
||||
#define D_MULTI_PRESS "多重點擊"
|
||||
#define D_NOISE "雜訊"
|
||||
#define D_NONE "無"
|
||||
#define D_O2 "Oxygen"
|
||||
#define D_OFF "關閉"
|
||||
#define D_OFFLINE "離線"
|
||||
#define D_OK "好"
|
||||
@ -190,6 +191,7 @@
|
||||
#define D_UV_POWER "紫外線能量"
|
||||
#define D_VERSION "版本"
|
||||
#define D_VOLTAGE "電壓"
|
||||
#define D_VOLUME "Volume"
|
||||
#define D_WEIGHT "重量"
|
||||
#define D_WARMLIGHT "暖光"
|
||||
#define D_WEB_SERVER "網頁伺服器"
|
||||
@ -744,6 +746,8 @@
|
||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||
#define D_UNIT_KILOOHM "千歐姆"
|
||||
#define D_UNIT_KILOWATTHOUR "千瓦小時"
|
||||
#define D_UNIT_LITERS "L"
|
||||
#define D_UNIT_LITERS_PER_MIN "L/m"
|
||||
#define D_UNIT_LUX "lux"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "微克/立方公尺"
|
||||
#define D_UNIT_MICROMETER "微米"
|
||||
|
||||
@ -90,7 +90,7 @@
|
||||
#define MQTT_LOG_LEVEL LOG_LEVEL_NONE // [MqttLog] (LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE)
|
||||
|
||||
// -- Ota -----------------------------------------
|
||||
#define OTA_URL "http://ota.tasmota.com/tasmota/release/tasmota.bin" // [OtaUrl]
|
||||
#define OTA_URL "http://ota.tasmota.com/tasmota/release/tasmota.bin.gz" // [OtaUrl]
|
||||
#define OTA_COMPATIBILITY false // [SetOption78] Disable OTA compatibility check
|
||||
|
||||
// -- MQTT ----------------------------------------
|
||||
@ -568,6 +568,9 @@
|
||||
// #define USE_EZOHUM // [I2cDriver55] Enable support for EZO's HUM sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
// #define USE_EZOEC // [I2cDriver55] Enable support for EZO's EC sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
// #define USE_EZOCO2 // [I2cDriver55] Enable support for EZO's CO2 sensor (+0k2 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
// #define USE_EZOO2 // [I2cDriver55] Enable support for EZO's O2 sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
// #define USE_EZOPRS // [I2cDriver55] Enable support for EZO's PRS sensor (+0k7 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
// #define USE_EZOFLO // [I2cDriver55] Enable support for EZO's FLO sensor (+0k4 code) - Shared EZO code required for any EZO device (+1k2 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
|
||||
@ -719,6 +722,7 @@
|
||||
#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)
|
||||
#define USE_ZBBRIDGE_TLS // TLS support for zbbridge
|
||||
|
||||
// -- Other sensors/drivers -----------------------
|
||||
|
||||
|
||||
@ -321,7 +321,7 @@ uint32_t GetSettingsCrc32(void)
|
||||
void SettingsSaveAll(void)
|
||||
{
|
||||
if (Settings.flag.save_state) {
|
||||
Settings.power = power;
|
||||
Settings.power = TasmotaGlobal.power;
|
||||
} else {
|
||||
Settings.power = 0;
|
||||
}
|
||||
@ -526,12 +526,12 @@ void SettingsSave(uint8_t rotate)
|
||||
UpdateBackwardCompatibility();
|
||||
if ((GetSettingsCrc32() != settings_crc32) || rotate) {
|
||||
if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade)
|
||||
stop_flash_rotate = 1;
|
||||
TasmotaGlobal.stop_flash_rotate = 1;
|
||||
}
|
||||
if (2 == rotate) { // Use eeprom flash slot and erase next flash slots if stop_flash_rotate is off (default)
|
||||
settings_location = SETTINGS_LOCATION +1;
|
||||
}
|
||||
if (stop_flash_rotate) {
|
||||
if (TasmotaGlobal.stop_flash_rotate) {
|
||||
settings_location = SETTINGS_LOCATION;
|
||||
} else {
|
||||
settings_location--;
|
||||
@ -555,7 +555,7 @@ void SettingsSave(uint8_t rotate)
|
||||
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
|
||||
}
|
||||
|
||||
if (!stop_flash_rotate && rotate) {
|
||||
if (!TasmotaGlobal.stop_flash_rotate && rotate) {
|
||||
for (uint32_t i = 1; i < CFG_ROTATES; i++) {
|
||||
ESP.flashEraseSector(settings_location -i); // Delete previous configurations by resetting to 0xFF
|
||||
delay(1);
|
||||
@ -615,7 +615,7 @@ void SettingsLoad(void) {
|
||||
|
||||
void EspErase(uint32_t start_sector, uint32_t end_sector)
|
||||
{
|
||||
bool serial_output = (LOG_LEVEL_DEBUG_MORE <= seriallog_level);
|
||||
bool serial_output = (LOG_LEVEL_DEBUG_MORE <= TasmotaGlobal.seriallog_level);
|
||||
for (uint32_t sector = start_sector; sector < end_sector; sector++) {
|
||||
|
||||
bool result = ESP.flashEraseSector(sector); // Arduino core - erases flash as seen by SDK
|
||||
|
||||
@ -607,7 +607,7 @@ bool NewerVersion(char* version_str)
|
||||
char* GetPowerDevice(char* dest, uint32_t idx, size_t size, uint32_t option)
|
||||
{
|
||||
strncpy_P(dest, S_RSLT_POWER, size); // POWER
|
||||
if ((devices_present + option) > 1) {
|
||||
if ((TasmotaGlobal.devices_present + option) > 1) {
|
||||
char sidx[8];
|
||||
snprintf_P(sidx, sizeof(sidx), PSTR("%d"), idx); // x
|
||||
strncat(dest, sidx, size - strlen(dest) -1); // POWERx
|
||||
@ -629,12 +629,12 @@ void GetEspHardwareType(void)
|
||||
// uint32_t efuse3 = *(uint32_t*)(0x3FF00058);
|
||||
// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C);
|
||||
|
||||
is_8285 = ( (efuse1 & (1 << 4)) || (efuse2 & (1 << 16)) );
|
||||
if (is_8285 && (ESP.getFlashChipRealSize() > 1048576)) {
|
||||
is_8285 = false; // ESP8285 can only have 1M flash
|
||||
TasmotaGlobal.is_8285 = ( (efuse1 & (1 << 4)) || (efuse2 & (1 << 16)) );
|
||||
if (TasmotaGlobal.is_8285 && (ESP.getFlashChipRealSize() > 1048576)) {
|
||||
TasmotaGlobal.is_8285 = false; // ESP8285 can only have 1M flash
|
||||
}
|
||||
#else
|
||||
is_8285 = false; // ESP8285 can only have 1M flash
|
||||
TasmotaGlobal.is_8285 = false; // ESP8285 can only have 1M flash
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -642,7 +642,7 @@ String GetDeviceHardware(void)
|
||||
{
|
||||
char buff[10];
|
||||
#ifdef ESP8266
|
||||
if (is_8285) {
|
||||
if (TasmotaGlobal.is_8285) {
|
||||
strcpy_P(buff, PSTR("ESP8285"));
|
||||
} else {
|
||||
strcpy_P(buff, PSTR("ESP8266EX"));
|
||||
@ -657,8 +657,8 @@ float ConvertTemp(float c)
|
||||
{
|
||||
float result = c;
|
||||
|
||||
global_update = uptime;
|
||||
global_temperature_celsius = c;
|
||||
TasmotaGlobal.global_update = TasmotaGlobal.uptime;
|
||||
TasmotaGlobal.temperature_celsius = c;
|
||||
|
||||
if (!isnan(c) && Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit
|
||||
result = c * 1.8 + 32; // Fahrenheit
|
||||
@ -688,8 +688,8 @@ float ConvertHumidity(float h)
|
||||
{
|
||||
float result = h;
|
||||
|
||||
global_update = uptime;
|
||||
global_humidity = h;
|
||||
TasmotaGlobal.global_update = TasmotaGlobal.uptime;
|
||||
TasmotaGlobal.humidity = h;
|
||||
|
||||
result = result + (0.1 * Settings.hum_comp);
|
||||
|
||||
@ -717,8 +717,8 @@ float ConvertPressure(float p)
|
||||
{
|
||||
float result = p;
|
||||
|
||||
global_update = uptime;
|
||||
global_pressure_hpa = p;
|
||||
TasmotaGlobal.global_update = TasmotaGlobal.uptime;
|
||||
TasmotaGlobal.pressure_hpa = p;
|
||||
|
||||
if (!isnan(p) && Settings.flag.pressure_conversion) { // SetOption24 - Switch between hPa or mmHg pressure unit
|
||||
result = p * 0.75006375541921; // mmHg
|
||||
@ -726,6 +726,14 @@ float ConvertPressure(float p)
|
||||
return result;
|
||||
}
|
||||
|
||||
float ConvertPressureForSeaLevel(float pressure)
|
||||
{
|
||||
if (pressure == 0.0f)
|
||||
return pressure;
|
||||
|
||||
return ConvertPressure((pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0f), 5.255f)) - 21.6f);
|
||||
}
|
||||
|
||||
String PressureUnit(void)
|
||||
{
|
||||
return (Settings.flag.pressure_conversion) ? String(D_UNIT_MILLIMETER_MERCURY) : String(D_UNIT_PRESSURE);
|
||||
@ -745,11 +753,11 @@ String SpeedUnit(void)
|
||||
|
||||
void ResetGlobalValues(void)
|
||||
{
|
||||
if ((uptime - global_update) > GLOBAL_VALUES_VALID) { // Reset after 5 minutes
|
||||
global_update = 0;
|
||||
global_temperature_celsius = NAN;
|
||||
global_humidity = 0.0f;
|
||||
global_pressure_hpa = 0.0f;
|
||||
if ((TasmotaGlobal.uptime - TasmotaGlobal.global_update) > GLOBAL_VALUES_VALID) { // Reset after 5 minutes
|
||||
TasmotaGlobal.global_update = 0;
|
||||
TasmotaGlobal.temperature_celsius = NAN;
|
||||
TasmotaGlobal.humidity = 0.0f;
|
||||
TasmotaGlobal.pressure_hpa = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,10 +910,18 @@ String GetSerialConfig(void) {
|
||||
}
|
||||
|
||||
void SetSerialBegin(void) {
|
||||
baudrate = Settings.baudrate * 300;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_SERIAL "Set to %s %d bit/s"), GetSerialConfig().c_str(), baudrate);
|
||||
TasmotaGlobal.baudrate = Settings.baudrate * 300;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_SERIAL "Set to %s %d bit/s"), GetSerialConfig().c_str(), TasmotaGlobal.baudrate);
|
||||
Serial.flush();
|
||||
Serial.begin(baudrate, (SerialConfig)pgm_read_byte(kTasmotaSerialConfig + Settings.serial_config));
|
||||
#ifdef ESP8266
|
||||
Serial.begin(TasmotaGlobal.baudrate, (SerialConfig)pgm_read_byte(kTasmotaSerialConfig + Settings.serial_config));
|
||||
#else // ESP32
|
||||
delay(10); // Allow time to cleanup queues - if not used hangs ESP32
|
||||
Serial.end();
|
||||
delay(10); // Allow time to cleanup queues - if not used hangs ESP32
|
||||
uint32_t config = pgm_read_dword(kTasmotaSerialConfig + Settings.serial_config);
|
||||
Serial.begin(TasmotaGlobal.baudrate, config);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetSerialConfig(uint32_t serial_config) {
|
||||
@ -918,29 +934,29 @@ void SetSerialConfig(uint32_t serial_config) {
|
||||
}
|
||||
}
|
||||
|
||||
void SetSerialBaudrate(uint32_t ubaudrate) {
|
||||
baudrate = ubaudrate;
|
||||
Settings.baudrate = baudrate / 300;
|
||||
if (Serial.baudRate() != baudrate) {
|
||||
void SetSerialBaudrate(uint32_t baudrate) {
|
||||
TasmotaGlobal.baudrate = baudrate;
|
||||
Settings.baudrate = TasmotaGlobal.baudrate / 300;
|
||||
if (Serial.baudRate() != TasmotaGlobal.baudrate) {
|
||||
SetSerialBegin();
|
||||
}
|
||||
}
|
||||
|
||||
void SetSerial(uint32_t ubaudrate, uint32_t serial_config) {
|
||||
void SetSerial(uint32_t baudrate, uint32_t serial_config) {
|
||||
Settings.flag.mqtt_serial = 0; // CMND_SERIALSEND and CMND_SERIALLOG
|
||||
Settings.serial_config = serial_config;
|
||||
baudrate = ubaudrate;
|
||||
Settings.baudrate = baudrate / 300;
|
||||
TasmotaGlobal.baudrate = baudrate;
|
||||
Settings.baudrate = TasmotaGlobal.baudrate / 300;
|
||||
SetSeriallog(LOG_LEVEL_NONE);
|
||||
SetSerialBegin();
|
||||
}
|
||||
|
||||
void ClaimSerial(void) {
|
||||
serial_local = true;
|
||||
TasmotaGlobal.serial_local = true;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("SNS: Hardware Serial"));
|
||||
SetSeriallog(LOG_LEVEL_NONE);
|
||||
baudrate = Serial.baudRate();
|
||||
Settings.baudrate = baudrate / 300;
|
||||
TasmotaGlobal.baudrate = Serial.baudRate();
|
||||
Settings.baudrate = TasmotaGlobal.baudrate / 300;
|
||||
}
|
||||
|
||||
void SerialSendRaw(char *codes)
|
||||
@ -1073,12 +1089,16 @@ char* ResponseGetTime(uint32_t format, char* time_str)
|
||||
return time_str;
|
||||
}
|
||||
|
||||
void ResponseClear(void) {
|
||||
TasmotaGlobal.mqtt_data[0] = '\0';
|
||||
}
|
||||
|
||||
int Response_P(const char* format, ...) // Content send snprintf_P char data
|
||||
{
|
||||
// This uses char strings. Be aware of sending %% if % is needed
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int len = vsnprintf_P(mqtt_data, sizeof(mqtt_data), format, args);
|
||||
int len = vsnprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), format, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
@ -1089,10 +1109,10 @@ int ResponseTime_P(const char* format, ...) // Content send snprintf_P char d
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
ResponseGetTime(Settings.flag2.time_format, mqtt_data);
|
||||
ResponseGetTime(Settings.flag2.time_format, TasmotaGlobal.mqtt_data);
|
||||
|
||||
int mlen = strlen(mqtt_data);
|
||||
int len = vsnprintf_P(mqtt_data + mlen, sizeof(mqtt_data) - mlen, format, args);
|
||||
int mlen = strlen(TasmotaGlobal.mqtt_data);
|
||||
int len = vsnprintf_P(TasmotaGlobal.mqtt_data + mlen, sizeof(TasmotaGlobal.mqtt_data) - mlen, format, args);
|
||||
va_end(args);
|
||||
return len + mlen;
|
||||
}
|
||||
@ -1102,8 +1122,8 @@ int ResponseAppend_P(const char* format, ...) // Content send snprintf_P char d
|
||||
// This uses char strings. Be aware of sending %% if % is needed
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int mlen = strlen(mqtt_data);
|
||||
int len = vsnprintf_P(mqtt_data + mlen, sizeof(mqtt_data) - mlen, format, args);
|
||||
int mlen = strlen(TasmotaGlobal.mqtt_data);
|
||||
int len = vsnprintf_P(TasmotaGlobal.mqtt_data + mlen, sizeof(TasmotaGlobal.mqtt_data) - mlen, format, args);
|
||||
va_end(args);
|
||||
return len + mlen;
|
||||
}
|
||||
@ -1225,7 +1245,7 @@ void DumpConvertTable(void) {
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
*/
|
||||
#endif // ESP8266
|
||||
@ -1238,8 +1258,8 @@ uint32_t ICACHE_RAM_ATTR Pin(uint32_t gpio, uint32_t index) {
|
||||
real_gpio += index;
|
||||
mask = 0xFFFF;
|
||||
}
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(gpio_pin); i++) {
|
||||
if ((gpio_pin[i] & mask) == real_gpio) {
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(TasmotaGlobal.gpio_pin); i++) {
|
||||
if ((TasmotaGlobal.gpio_pin[i] & mask) == real_gpio) {
|
||||
return i; // Pin number configured for gpio
|
||||
}
|
||||
}
|
||||
@ -1252,15 +1272,15 @@ bool PinUsed(uint32_t gpio, uint32_t index) {
|
||||
}
|
||||
|
||||
uint32_t GetPin(uint32_t lpin) {
|
||||
if (lpin < ARRAY_SIZE(gpio_pin)) {
|
||||
return gpio_pin[lpin];
|
||||
if (lpin < ARRAY_SIZE(TasmotaGlobal.gpio_pin)) {
|
||||
return TasmotaGlobal.gpio_pin[lpin];
|
||||
} else {
|
||||
return GPIO_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void SetPin(uint32_t lpin, uint32_t gpio) {
|
||||
gpio_pin[lpin] = gpio;
|
||||
TasmotaGlobal.gpio_pin[lpin] = gpio;
|
||||
}
|
||||
|
||||
void DigitalWrite(uint32_t gpio_pin, uint32_t index, uint32_t state)
|
||||
@ -1422,7 +1442,7 @@ void ModuleDefault(uint32_t module)
|
||||
|
||||
void SetModuleType(void)
|
||||
{
|
||||
my_module_type = (USER_MODULE == Settings.module) ? Settings.user_template_base : Settings.module;
|
||||
TasmotaGlobal.module_type = (USER_MODULE == Settings.module) ? Settings.user_template_base : Settings.module;
|
||||
}
|
||||
|
||||
bool FlashPin(uint32_t pin)
|
||||
@ -1436,7 +1456,7 @@ uint32_t ValidPin(uint32_t pin, uint32_t gpio)
|
||||
return GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11
|
||||
}
|
||||
|
||||
// if (!is_8285 && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
|
||||
// if (!TasmotaGlobal.is_8285 && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
|
||||
if ((WEMOS == Settings.module) && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
|
||||
if ((9 == pin) || (10 == pin)) {
|
||||
return GPIO_NONE; // Disable possible flash GPIO9 and GPIO10
|
||||
@ -1632,7 +1652,7 @@ bool TimeReached(uint32_t timer)
|
||||
return (passed >= 0);
|
||||
}
|
||||
|
||||
void SetNextTimeInterval(unsigned long& timer, const unsigned long step)
|
||||
void SetNextTimeInterval(uint32_t& timer, const uint32_t step)
|
||||
{
|
||||
timer += step;
|
||||
const long passed = TimePassedSince(timer);
|
||||
@ -1919,15 +1939,15 @@ bool I2cSetDevice(uint32_t addr)
|
||||
void SetSeriallog(uint32_t loglevel)
|
||||
{
|
||||
Settings.seriallog_level = loglevel;
|
||||
seriallog_level = loglevel;
|
||||
seriallog_timer = 0;
|
||||
TasmotaGlobal.seriallog_level = loglevel;
|
||||
TasmotaGlobal.seriallog_timer = 0;
|
||||
}
|
||||
|
||||
void SetSyslog(uint32_t loglevel)
|
||||
{
|
||||
Settings.syslog_level = loglevel;
|
||||
syslog_level = loglevel;
|
||||
syslog_timer = 0;
|
||||
TasmotaGlobal.syslog_level = loglevel;
|
||||
TasmotaGlobal.syslog_timer = 0;
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
@ -1937,7 +1957,7 @@ void GetLog(uint32_t idx, char** entry_pp, size_t* len_p)
|
||||
size_t len = 0;
|
||||
|
||||
if (idx) {
|
||||
char* it = web_log;
|
||||
char* it = TasmotaGlobal.web_log;
|
||||
do {
|
||||
uint32_t cur_idx = *it;
|
||||
it++;
|
||||
@ -1949,7 +1969,7 @@ void GetLog(uint32_t idx, char** entry_pp, size_t* len_p)
|
||||
break;
|
||||
}
|
||||
it += tmp;
|
||||
} while (it < web_log + WEB_LOG_SIZE && *it != '\0');
|
||||
} while (it < TasmotaGlobal.web_log + WEB_LOG_SIZE && *it != '\0');
|
||||
}
|
||||
*entry_pp = entry_p;
|
||||
*len_p = len;
|
||||
@ -1958,7 +1978,7 @@ void GetLog(uint32_t idx, char** entry_pp, size_t* len_p)
|
||||
|
||||
void Syslog(void)
|
||||
{
|
||||
// Destroys log_data
|
||||
// Destroys TasmotaGlobal.log_data
|
||||
|
||||
uint32_t current_hash = GetHash(SettingsText(SET_SYSLOG_HOST), strlen(SettingsText(SET_SYSLOG_HOST)));
|
||||
if (syslog_host_hash != current_hash) {
|
||||
@ -1968,15 +1988,15 @@ 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-"), 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));
|
||||
memmove(TasmotaGlobal.log_data + strlen(syslog_preamble), TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data) - strlen(syslog_preamble));
|
||||
TasmotaGlobal.log_data[sizeof(TasmotaGlobal.log_data) -1] = '\0';
|
||||
memcpy(TasmotaGlobal.log_data, syslog_preamble, strlen(syslog_preamble));
|
||||
PortUdp_write(TasmotaGlobal.log_data, strlen(TasmotaGlobal.log_data));
|
||||
PortUdp.endPacket();
|
||||
delay(1); // Add time for UDP handling (#5512)
|
||||
} else {
|
||||
syslog_level = 0;
|
||||
syslog_timer = SYSLOG_TIMER;
|
||||
TasmotaGlobal.syslog_level = 0;
|
||||
TasmotaGlobal.syslog_timer = SYSLOG_TIMER;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SYSLOG_HOST_NOT_FOUND ". " D_RETRY_IN " %d " D_UNIT_SECOND), SYSLOG_TIMER);
|
||||
}
|
||||
}
|
||||
@ -1986,57 +2006,61 @@ void AddLog(uint32_t loglevel)
|
||||
char mxtime[10]; // "13:45:21 "
|
||||
snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d "), RtcTime.hour, RtcTime.minute, RtcTime.second);
|
||||
|
||||
if ((loglevel <= seriallog_level) &&
|
||||
(masterlog_level <= seriallog_level)) {
|
||||
Serial.printf("%s%s\r\n", mxtime, log_data);
|
||||
if ((loglevel <= TasmotaGlobal.seriallog_level) &&
|
||||
(TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) {
|
||||
Serial.printf("%s%s\r\n", mxtime, TasmotaGlobal.log_data);
|
||||
}
|
||||
#ifdef USE_WEBSERVER
|
||||
if (Settings.webserver &&
|
||||
(loglevel <= Settings.weblog_level) &&
|
||||
(masterlog_level <= Settings.weblog_level)) {
|
||||
(TasmotaGlobal.masterlog_level <= Settings.weblog_level)) {
|
||||
// Delimited, zero-terminated buffer of log lines.
|
||||
// Each entry has this format: [index][log data]['\1']
|
||||
web_log_index &= 0xFF;
|
||||
if (!web_log_index) web_log_index++; // Index 0 is not allowed as it is the end of char string
|
||||
while (web_log_index == web_log[0] || // If log already holds the next index, remove it
|
||||
strlen(web_log) + strlen(log_data) + 13 > WEB_LOG_SIZE) // 13 = web_log_index + mxtime + '\1' + '\0'
|
||||
TasmotaGlobal.web_log_index &= 0xFF;
|
||||
if (!TasmotaGlobal.web_log_index) {
|
||||
TasmotaGlobal.web_log_index++; // Index 0 is not allowed as it is the end of char string
|
||||
}
|
||||
while (TasmotaGlobal.web_log_index == TasmotaGlobal.web_log[0] || // If log already holds the next index, remove it
|
||||
strlen(TasmotaGlobal.web_log) + strlen(TasmotaGlobal.log_data) + 13 > WEB_LOG_SIZE) // 13 = web_log_index + mxtime + '\1' + '\0'
|
||||
{
|
||||
char* it = web_log;
|
||||
char* it = TasmotaGlobal.web_log;
|
||||
it++; // Skip web_log_index
|
||||
it += strchrspn(it, '\1'); // Skip log line
|
||||
it++; // Skip delimiting "\1"
|
||||
memmove(web_log, it, WEB_LOG_SIZE -(it-web_log)); // Move buffer forward to remove oldest log line
|
||||
memmove(TasmotaGlobal.web_log, it, WEB_LOG_SIZE -(it-TasmotaGlobal.web_log)); // Move buffer forward to remove oldest log line
|
||||
}
|
||||
snprintf_P(TasmotaGlobal.web_log, sizeof(TasmotaGlobal.web_log), PSTR("%s%c%s%s\1"), TasmotaGlobal.web_log, TasmotaGlobal.web_log_index++, mxtime, TasmotaGlobal.log_data);
|
||||
TasmotaGlobal.web_log_index &= 0xFF;
|
||||
if (!TasmotaGlobal.web_log_index) {
|
||||
TasmotaGlobal.web_log_index++; // Index 0 is not allowed as it is the end of char string
|
||||
}
|
||||
snprintf_P(web_log, sizeof(web_log), PSTR("%s%c%s%s\1"), web_log, web_log_index++, mxtime, log_data);
|
||||
web_log_index &= 0xFF;
|
||||
if (!web_log_index) web_log_index++; // Index 0 is not allowed as it is the end of char string
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
if (Settings.flag.mqtt_enabled && // SetOption3 - Enable MQTT
|
||||
!global_state.mqtt_down &&
|
||||
!TasmotaGlobal.global_state.mqtt_down &&
|
||||
(loglevel <= Settings.mqttlog_level) &&
|
||||
(masterlog_level <= Settings.mqttlog_level)) { MqttPublishLogging(mxtime); }
|
||||
(TasmotaGlobal.masterlog_level <= Settings.mqttlog_level)) { MqttPublishLogging(mxtime); }
|
||||
|
||||
if (!global_state.network_down &&
|
||||
(loglevel <= syslog_level) &&
|
||||
(masterlog_level <= syslog_level)) { Syslog(); }
|
||||
if (!TasmotaGlobal.global_state.network_down &&
|
||||
(loglevel <= TasmotaGlobal.syslog_level) &&
|
||||
(TasmotaGlobal.masterlog_level <= TasmotaGlobal.syslog_level)) { Syslog(); }
|
||||
|
||||
prepped_loglevel = 0;
|
||||
TasmotaGlobal.prepped_loglevel = 0;
|
||||
}
|
||||
|
||||
void AddLog_P(uint32_t loglevel, const char *formatP)
|
||||
{
|
||||
snprintf_P(log_data, sizeof(log_data), formatP);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), formatP);
|
||||
AddLog(loglevel);
|
||||
}
|
||||
|
||||
void AddLog_P(uint32_t loglevel, const char *formatP, const char *formatP2)
|
||||
{
|
||||
char message[sizeof(log_data)];
|
||||
char message[sizeof(TasmotaGlobal.log_data)];
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), formatP);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), formatP);
|
||||
snprintf_P(message, sizeof(message), formatP2);
|
||||
strncat(log_data, message, sizeof(log_data) - strlen(log_data) -1);
|
||||
strncat(TasmotaGlobal.log_data, message, sizeof(TasmotaGlobal.log_data) - strlen(TasmotaGlobal.log_data) -1);
|
||||
AddLog(loglevel);
|
||||
}
|
||||
|
||||
@ -2044,17 +2068,17 @@ void PrepLog_P2(uint32_t loglevel, PGM_P formatP, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
vsnprintf_P(log_data, sizeof(log_data), formatP, arg);
|
||||
vsnprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
prepped_loglevel = loglevel;
|
||||
TasmotaGlobal.prepped_loglevel = loglevel;
|
||||
}
|
||||
|
||||
void AddLog_P2(uint32_t loglevel, PGM_P formatP, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
vsnprintf_P(log_data, sizeof(log_data), formatP, arg);
|
||||
vsnprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
AddLog(loglevel);
|
||||
@ -2064,7 +2088,7 @@ void AddLog_Debug(PGM_P formatP, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
vsnprintf_P(log_data, sizeof(log_data), formatP, arg);
|
||||
vsnprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
@ -2073,15 +2097,15 @@ void AddLog_Debug(PGM_P formatP, ...)
|
||||
void AddLogBuffer(uint32_t loglevel, uint8_t *buffer, uint32_t count)
|
||||
{
|
||||
/*
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("DMP:"));
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("DMP:"));
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X"), log_data, *(buffer++));
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s %02X"), TasmotaGlobal.log_data, *(buffer++));
|
||||
}
|
||||
AddLog(loglevel);
|
||||
*/
|
||||
/*
|
||||
strcpy_P(log_data, PSTR("DMP: "));
|
||||
ToHex_P(buffer, count, log_data + strlen(log_data), sizeof(log_data) - strlen(log_data), ' ');
|
||||
strcpy_P(TasmotaGlobal.log_data, PSTR("DMP: "));
|
||||
ToHex_P(buffer, count, TasmotaGlobal.log_data + strlen(TasmotaGlobal.log_data), sizeof(TasmotaGlobal.log_data) - strlen(TasmotaGlobal.log_data), ' ');
|
||||
AddLog(loglevel);
|
||||
*/
|
||||
char hex_char[(count * 3) + 2];
|
||||
@ -2090,7 +2114,7 @@ void AddLogBuffer(uint32_t loglevel, uint8_t *buffer, uint32_t count)
|
||||
|
||||
void AddLogSerial(uint32_t loglevel)
|
||||
{
|
||||
AddLogBuffer(loglevel, (uint8_t*)serial_in_buffer, serial_in_byte_counter);
|
||||
AddLogBuffer(loglevel, (uint8_t*)TasmotaGlobal.serial_in_buffer, TasmotaGlobal.serial_in_byte_counter);
|
||||
}
|
||||
|
||||
void AddLogMissed(const char *sensor, uint32_t misses)
|
||||
@ -2099,12 +2123,12 @@ void AddLogMissed(const char *sensor, uint32_t misses)
|
||||
}
|
||||
|
||||
void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32_t size) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("DMP:"));
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.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));
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s %02X"), TasmotaGlobal.log_data, *(buffer));
|
||||
} else { // uint16_t
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X%02X"), log_data, *(buffer +1), *(buffer));
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s %02X%02X"), TasmotaGlobal.log_data, *(buffer +1), *(buffer));
|
||||
}
|
||||
buffer += size;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ const char kMultiPress[] PROGMEM =
|
||||
"|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|";
|
||||
|
||||
struct BUTTON {
|
||||
unsigned long debounce = 0; // Button debounce timer
|
||||
uint32_t debounce = 0; // Button debounce timer
|
||||
uint16_t hold_timer[MAX_KEYS] = { 0 }; // Timer for button hold
|
||||
uint16_t dual_code = 0; // Sonoff dual received code
|
||||
|
||||
@ -80,7 +80,7 @@ void ButtonInit(void)
|
||||
{
|
||||
Button.present = 0;
|
||||
#ifdef ESP8266
|
||||
if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) {
|
||||
if ((SONOFF_DUAL == TasmotaGlobal.module_type) || (CH4 == TasmotaGlobal.module_type)) {
|
||||
Button.present++;
|
||||
}
|
||||
#endif // ESP8266
|
||||
@ -135,7 +135,7 @@ uint8_t ButtonSerial(uint8_t serial_in_byte)
|
||||
|
||||
void ButtonHandler(void)
|
||||
{
|
||||
if (uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit
|
||||
if (TasmotaGlobal.uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit
|
||||
|
||||
uint8_t hold_time_extent = IMMINENT_RESET_FACTOR; // Extent hold time factor in case of iminnent Reset command
|
||||
uint16_t loops_per_second = 1000 / Settings.button_debounce; // ButtonDebounce (50)
|
||||
@ -146,7 +146,7 @@ void ButtonHandler(void)
|
||||
uint8_t button_present = 0;
|
||||
|
||||
#ifdef ESP8266
|
||||
if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type))) {
|
||||
if (!button_index && ((SONOFF_DUAL == TasmotaGlobal.module_type) || (CH4 == TasmotaGlobal.module_type))) {
|
||||
button_present = 1;
|
||||
if (Button.dual_code) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON " " D_CODE " %04X"), Button.dual_code);
|
||||
@ -204,7 +204,7 @@ void ButtonHandler(void)
|
||||
// Serviced
|
||||
}
|
||||
#ifdef ESP8266
|
||||
else if (SONOFF_4CHPRO == my_module_type) {
|
||||
else if (SONOFF_4CHPRO == TasmotaGlobal.module_type) {
|
||||
if (Button.hold_timer[button_index]) { Button.hold_timer[button_index]--; }
|
||||
|
||||
bool button_pressed = false;
|
||||
@ -245,7 +245,7 @@ void ButtonHandler(void)
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_MULTI_PRESS " %d"), button_index +1, Button.press_counter[button_index]);
|
||||
Button.window_timer[button_index] = loops_per_second / 2; // 0.5 second multi press window
|
||||
}
|
||||
blinks = 201;
|
||||
TasmotaGlobal.blinks = 201;
|
||||
}
|
||||
|
||||
if (NOT_PRESSED == button) {
|
||||
@ -281,18 +281,18 @@ void ButtonHandler(void)
|
||||
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] < 7)) {
|
||||
if (!TasmotaGlobal.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
|
||||
#ifdef ESP8266
|
||||
if ((SONOFF_DUAL_R2 == my_module_type) || (SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) {
|
||||
if ((SONOFF_DUAL_R2 == TasmotaGlobal.module_type) || (SONOFF_DUAL == TasmotaGlobal.module_type) || (CH4 == TasmotaGlobal.module_type)) {
|
||||
single_press = true;
|
||||
} 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 ((1 == Button.present) && (2 == TasmotaGlobal.devices_present)) { // Single Button with two devices only
|
||||
if (Settings.flag.button_swap) { // SetOption11 (0)
|
||||
Button.press_counter[button_index] = (single_press) ? 1 : 2;
|
||||
}
|
||||
@ -307,7 +307,7 @@ void ButtonHandler(void)
|
||||
} else {
|
||||
if (Button.press_counter[button_index] < 6) { // Single to Penta press
|
||||
if (WifiState() > WIFI_RESTART) { // Wifimanager active
|
||||
restart_flag = 1;
|
||||
TasmotaGlobal.restart_flag = 1;
|
||||
}
|
||||
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)
|
||||
@ -317,8 +317,8 @@ void ButtonHandler(void)
|
||||
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);
|
||||
if ((SONOFF_DUAL == TasmotaGlobal.module_type) || (CH4 == TasmotaGlobal.module_type)) {
|
||||
valid_relay = (Button.press_counter[button_index] <= TasmotaGlobal.devices_present);
|
||||
}
|
||||
#endif // ESP8266
|
||||
if ((Button.press_counter[button_index] > 1) && valid_relay && (Button.press_counter[button_index] <= MAX_RELAY_BUTTON1)) {
|
||||
@ -366,7 +366,7 @@ void MqttButtonTopic(uint8_t button_id, uint8_t action, uint8_t hold)
|
||||
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);
|
||||
GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, scommand);
|
||||
Response_P(S_JSON_COMMAND_SVALUE, "ACTION", (hold) ? SettingsText(SET_STATE_TXT4) : mqttstate);
|
||||
MqttPublish(stopic);
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
|
||||
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_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 "|"
|
||||
D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_WIFI "|" D_CMND_SWITCHTEXT "|"
|
||||
#ifdef USE_I2C
|
||||
D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|"
|
||||
#endif
|
||||
@ -54,7 +54,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
|
||||
&CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig,
|
||||
&CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd,
|
||||
&CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode,
|
||||
&CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndWifi,
|
||||
&CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndWifi, &CmndSwitchText,
|
||||
#ifdef USE_I2C
|
||||
&CmndI2cScan, CmndI2cDriver,
|
||||
#endif
|
||||
@ -121,7 +121,7 @@ void ResponseCmndIdxChar(const char* value)
|
||||
void ResponseCmndAll(uint32_t text_index, uint32_t count)
|
||||
{
|
||||
uint32_t real_index = text_index;
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
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, EscapeJSONString(SettingsText(real_index +i)).c_str());
|
||||
@ -200,7 +200,7 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len)
|
||||
|
||||
char stemp1[TOPSZ];
|
||||
GetFallbackTopic_P(stemp1, ""); // Full Fallback topic = cmnd/DVES_xxxxxxxx_fb/
|
||||
fallback_topic_flag = (!strncmp(topicBuf, stemp1, strlen(stemp1)));
|
||||
TasmotaGlobal.fallback_topic_flag = (!strncmp(topicBuf, stemp1, strlen(stemp1)));
|
||||
|
||||
char *type = strrchr(topicBuf, '/'); // Last part of received topic is always the command (type)
|
||||
|
||||
@ -232,7 +232,7 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len)
|
||||
if (type != nullptr) {
|
||||
Response_P(PSTR("{\"" D_JSON_COMMAND "\":\"" D_JSON_ERROR "\"}"));
|
||||
|
||||
if (Settings.ledstate &0x02) { blinks++; }
|
||||
if (Settings.ledstate &0x02) { TasmotaGlobal.blinks++; }
|
||||
|
||||
if (!strcmp(dataBuf,"?")) { data_len = 0; }
|
||||
|
||||
@ -244,8 +244,8 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len)
|
||||
|
||||
DEBUG_CORE_LOG(PSTR("CMD: Payload %d"), payload);
|
||||
|
||||
// backlog_delay = millis() + (100 * MIN_BACKLOG_DELAY);
|
||||
backlog_delay = millis() + Settings.param[P_BACKLOG_DELAY];
|
||||
// TasmotaGlobal.backlog_delay = millis() + (100 * MIN_BACKLOG_DELAY);
|
||||
TasmotaGlobal.backlog_delay = millis() + Settings.param[P_BACKLOG_DELAY];
|
||||
|
||||
char command[CMDSZ] = { 0 };
|
||||
XdrvMailbox.command = command;
|
||||
@ -281,28 +281,28 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len)
|
||||
}
|
||||
|
||||
if (type == nullptr) {
|
||||
blinks = 201;
|
||||
TasmotaGlobal.blinks = 201;
|
||||
snprintf_P(stemp1, sizeof(stemp1), PSTR(D_JSON_COMMAND));
|
||||
Response_P(PSTR("{\"" D_JSON_COMMAND "\":\"" D_JSON_UNKNOWN "\"}"));
|
||||
type = (char*)stemp1;
|
||||
}
|
||||
|
||||
if (mqtt_data[0] != '\0') {
|
||||
if (TasmotaGlobal.mqtt_data[0] != '\0') {
|
||||
/*
|
||||
// Add "Command":"POWERONSTATE", like:
|
||||
// 12:15:37 MQT: stat/wemos4/RESULT = {"Command":"POWERONSTATE","PowerOnState":3}
|
||||
char json_command[TOPSZ];
|
||||
snprintf_P(json_command, sizeof(json_command), PSTR("{\"" D_JSON_COMMAND "\":\"%s\","), type);
|
||||
uint32_t jc_len = strlen(json_command);
|
||||
uint32_t mq_len = strlen(mqtt_data) +1;
|
||||
if (mq_len < sizeof(mqtt_data) - jc_len) {
|
||||
memmove(mqtt_data +jc_len -1, mqtt_data, mq_len);
|
||||
memmove(mqtt_data, json_command, jc_len);
|
||||
uint32_t mq_len = strlen(TasmotaGlobal.mqtt_data) +1;
|
||||
if (mq_len < sizeof(TasmotaGlobal.mqtt_data) - jc_len) {
|
||||
memmove(TasmotaGlobal.mqtt_data +jc_len -1, TasmotaGlobal.mqtt_data, mq_len);
|
||||
memmove(TasmotaGlobal.mqtt_data, json_command, jc_len);
|
||||
}
|
||||
*/
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, type);
|
||||
}
|
||||
fallback_topic_flag = false;
|
||||
TasmotaGlobal.fallback_topic_flag = false;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
@ -315,10 +315,10 @@ void CmndBacklog(void)
|
||||
char *blcommand = strtok(XdrvMailbox.data, ";");
|
||||
while ((blcommand != nullptr) && (backlog.size() < MAX_BACKLOG))
|
||||
#else
|
||||
uint32_t bl_pointer = (!backlog_pointer) ? MAX_BACKLOG -1 : backlog_pointer;
|
||||
uint32_t bl_pointer = (!TasmotaGlobal.backlog_pointer) ? MAX_BACKLOG -1 : TasmotaGlobal.backlog_pointer;
|
||||
bl_pointer--;
|
||||
char *blcommand = strtok(XdrvMailbox.data, ";");
|
||||
while ((blcommand != nullptr) && (backlog_index != bl_pointer))
|
||||
while ((blcommand != nullptr) && (TasmotaGlobal.backlog_index != bl_pointer))
|
||||
#endif
|
||||
{
|
||||
while(true) {
|
||||
@ -335,22 +335,22 @@ void CmndBacklog(void)
|
||||
backlog.add(blcommand);
|
||||
}
|
||||
#else
|
||||
backlog[backlog_index] = blcommand;
|
||||
backlog_index++;
|
||||
if (backlog_index >= MAX_BACKLOG) backlog_index = 0;
|
||||
TasmotaGlobal.backlog[TasmotaGlobal.backlog_index] = blcommand;
|
||||
TasmotaGlobal.backlog_index++;
|
||||
if (TasmotaGlobal.backlog_index >= MAX_BACKLOG) TasmotaGlobal.backlog_index = 0;
|
||||
#endif
|
||||
}
|
||||
blcommand = strtok(nullptr, ";");
|
||||
}
|
||||
// ResponseCmndChar(D_JSON_APPENDED);
|
||||
mqtt_data[0] = '\0';
|
||||
backlog_delay = 0;
|
||||
ResponseClear();
|
||||
TasmotaGlobal.backlog_delay = 0;
|
||||
} else {
|
||||
bool blflag = BACKLOG_EMPTY;
|
||||
#ifdef SUPPORT_IF_STATEMENT
|
||||
backlog.clear();
|
||||
#else
|
||||
backlog_pointer = backlog_index;
|
||||
TasmotaGlobal.backlog_pointer = TasmotaGlobal.backlog_index;
|
||||
#endif
|
||||
ResponseCmndChar(blflag ? D_JSON_EMPTY : D_JSON_ABORTED);
|
||||
}
|
||||
@ -359,23 +359,23 @@ void CmndBacklog(void)
|
||||
void CmndDelay(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= (MIN_BACKLOG_DELAY / 100)) && (XdrvMailbox.payload <= 3600)) {
|
||||
backlog_delay = millis() + (100 * XdrvMailbox.payload);
|
||||
TasmotaGlobal.backlog_delay = millis() + (100 * XdrvMailbox.payload);
|
||||
}
|
||||
uint32_t bl_delay = 0;
|
||||
long bl_delta = TimePassedSince(backlog_delay);
|
||||
long bl_delta = TimePassedSince(TasmotaGlobal.backlog_delay);
|
||||
if (bl_delta < 0) { bl_delay = (bl_delta *-1) / 100; }
|
||||
ResponseCmndNumber(bl_delay);
|
||||
}
|
||||
|
||||
void CmndPower(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= devices_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.devices_present)) {
|
||||
if ((XdrvMailbox.payload < POWER_OFF) || (XdrvMailbox.payload > POWER_BLINK_STOP)) {
|
||||
XdrvMailbox.payload = POWER_SHOW_STATE;
|
||||
}
|
||||
// Settings.flag.device_index_enable = XdrvMailbox.usridx; // SetOption26 - Switch between POWER or POWER1
|
||||
ExecuteCommandPower(XdrvMailbox.index, XdrvMailbox.payload, SRC_IGNORE);
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
else if (0 == XdrvMailbox.index) {
|
||||
if ((XdrvMailbox.payload < POWER_OFF) || (XdrvMailbox.payload > POWER_TOGGLE)) {
|
||||
@ -385,7 +385,7 @@ void CmndPower(void)
|
||||
if (Settings.flag3.hass_tele_on_power) { // SetOption59 - Send tele/%topic%/STATE in addition to stat/%topic%/RESULT
|
||||
MqttPublishTeleState();
|
||||
}
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,7 +395,7 @@ void CmndStatus(void)
|
||||
|
||||
if (payload > MAX_STATUS) { return; } // {"Command":"Error"}
|
||||
if (!Settings.flag.mqtt_enabled && (6 == payload)) { return; } // SetOption3 - Enable MQTT
|
||||
if (!energy_flg && (9 == payload)) { return; }
|
||||
if (!TasmotaGlobal.energy_driver && (9 == payload)) { return; }
|
||||
if (!CrashFlag() && (12 == payload)) { return; }
|
||||
if (!Settings.flag3.shutter_mode && (13 == payload)) { return; }
|
||||
|
||||
@ -403,7 +403,7 @@ void CmndStatus(void)
|
||||
char stemp2[TOPSZ];
|
||||
|
||||
if (0 == payload) {
|
||||
uint32_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!devices_present) ? 1 : devices_present;
|
||||
uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!TasmotaGlobal.devices_present) ? 1 : TasmotaGlobal.devices_present;
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
if (IsModuleIfan()) { maxfn = 1; }
|
||||
#endif // USE_SONOFF_IFAN
|
||||
@ -419,8 +419,8 @@ void CmndStatus(void)
|
||||
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(), EscapeJSONString(SettingsText(SET_DEVICENAME)).c_str(), stemp, mqtt_topic,
|
||||
SettingsText(SET_MQTT_BUTTON_TOPIC), power, Settings.poweronstate, Settings.ledstate,
|
||||
ModuleNr(), EscapeJSONString(SettingsText(SET_DEVICENAME)).c_str(), stemp, TasmotaGlobal.mqtt_topic,
|
||||
SettingsText(SET_MQTT_BUTTON_TOPIC), TasmotaGlobal.power, Settings.poweronstate, Settings.ledstate,
|
||||
Settings.ledmask, Settings.save_data,
|
||||
Settings.flag.save_state, // SetOption0 - Save power state and use after restart
|
||||
SettingsText(SET_MQTT_SWITCH_TOPIC),
|
||||
@ -440,7 +440,7 @@ void CmndStatus(void)
|
||||
",\"" D_JSON_SAVEADDRESS "\":\"%X\""
|
||||
#endif
|
||||
"}}"),
|
||||
baudrate, GetSerialConfig().c_str(), SettingsText(SET_MQTT_GRP_TOPIC), SettingsText(SET_OTAURL),
|
||||
TasmotaGlobal.baudrate, 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
|
||||
#ifdef ESP8266
|
||||
@ -458,7 +458,7 @@ void CmndStatus(void)
|
||||
",\"" D_JSON_COREVERSION "\":\"" ARDUINO_CORE_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\","
|
||||
"\"CpuFrequency\":%d,\"Hardware\":\"%s\""
|
||||
"%s}}"),
|
||||
my_version, my_image, GetBuildDateAndTime().c_str()
|
||||
TasmotaGlobal.version, TasmotaGlobal.image_name, GetBuildDateAndTime().c_str()
|
||||
#ifdef ESP8266
|
||||
, ESP.getBootVersion()
|
||||
#endif
|
||||
@ -488,8 +488,7 @@ void CmndStatus(void)
|
||||
#ifdef ESP8266
|
||||
",\"" D_JSON_FLASHCHIPID "\":\"%06X\""
|
||||
#endif
|
||||
",\"FlashFrequency\":%d,\"" D_JSON_FLASHMODE "\":%d,\""
|
||||
D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"),
|
||||
",\"FlashFrequency\":%d,\"" D_JSON_FLASHMODE "\":%d"),
|
||||
ESP_getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP_getFreeHeap()/1024,
|
||||
#ifdef ESP32
|
||||
ESP.getPsramSize()/1024, ESP.getFreePsram()/1024,
|
||||
@ -498,8 +497,8 @@ void CmndStatus(void)
|
||||
#ifdef ESP8266
|
||||
, ESP.getFlashChipId()
|
||||
#endif
|
||||
, ESP.getFlashChipSpeed()/1000000, ESP.getFlashChipMode(),
|
||||
LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5, feature6, feature7);
|
||||
, ESP.getFlashChipSpeed()/1000000, ESP.getFlashChipMode());
|
||||
ResponseAppendFeatures();
|
||||
XsnsDriverState();
|
||||
ResponseAppend_P(PSTR(",\"Sensors\":"));
|
||||
XsnsSensorState();
|
||||
@ -521,7 +520,7 @@ void CmndStatus(void)
|
||||
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, EscapeJSONString(SettingsText(SET_MQTT_CLIENT)).c_str(),
|
||||
mqtt_client, EscapeJSONString(SettingsText(SET_MQTT_USER)).c_str(), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE);
|
||||
TasmotaGlobal.mqtt_client, EscapeJSONString(SettingsText(SET_MQTT_USER)).c_str(), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE);
|
||||
MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS "6"));
|
||||
}
|
||||
|
||||
@ -546,7 +545,7 @@ void CmndStatus(void)
|
||||
}
|
||||
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_MARGIN_DETECTION)
|
||||
if (energy_flg) {
|
||||
if (TasmotaGlobal.energy_driver) {
|
||||
if ((0 == payload) || (9 == payload)) {
|
||||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS9_MARGIN "\":{\"" D_CMND_POWERDELTA "\":[%d,%d,%d],\"" D_CMND_POWERLOW "\":%d,\"" D_CMND_POWERHIGH "\":%d,\""
|
||||
D_CMND_VOLTAGELOW "\":%d,\"" D_CMND_VOLTAGEHIGH "\":%d,\"" D_CMND_CURRENTLOW "\":%d,\"" D_CMND_CURRENTHIGH "\":%d}}"),
|
||||
@ -607,19 +606,19 @@ void CmndStatus(void)
|
||||
#endif
|
||||
|
||||
#ifdef USE_SCRIPT_STATUS
|
||||
if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">U",2,mqtt_data);
|
||||
if (bitRead(Settings.rule_enabled, 0)) { Run_Scripter(">U", 2, TasmotaGlobal.mqtt_data); }
|
||||
#endif
|
||||
|
||||
if (payload) {
|
||||
XdrvRulesProcess(); // Allow rule processing on single Status command only
|
||||
}
|
||||
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
|
||||
void CmndState(void)
|
||||
{
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
MqttShowState();
|
||||
if (Settings.flag3.hass_tele_on_power) { // SetOption59 - Send tele/%topic%/STATE in addition to stat/%topic%/RESULT
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN);
|
||||
@ -662,10 +661,10 @@ void CmndGlobalTemp(void)
|
||||
}
|
||||
if ((temperature >= -50.0f) && (temperature <= 100.0f)) {
|
||||
ConvertTemp(temperature);
|
||||
global_update = 1; // Keep global values just entered valid
|
||||
TasmotaGlobal.global_update = 1; // Keep global values just entered valid
|
||||
}
|
||||
}
|
||||
ResponseCmndFloat(global_temperature_celsius, 1);
|
||||
ResponseCmndFloat(TasmotaGlobal.temperature_celsius, 1);
|
||||
}
|
||||
|
||||
void CmndGlobalHum(void)
|
||||
@ -674,20 +673,20 @@ void CmndGlobalHum(void)
|
||||
float humidity = CharToFloat(XdrvMailbox.data);
|
||||
if ((humidity >= 0.0) && (humidity <= 100.0)) {
|
||||
ConvertHumidity(humidity);
|
||||
global_update = 1; // Keep global values just entered valid
|
||||
TasmotaGlobal.global_update = 1; // Keep global values just entered valid
|
||||
}
|
||||
}
|
||||
ResponseCmndFloat(global_humidity, 1);
|
||||
ResponseCmndFloat(TasmotaGlobal.humidity, 1);
|
||||
}
|
||||
|
||||
void CmndSleep(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 251)) {
|
||||
Settings.sleep = XdrvMailbox.payload;
|
||||
ssleep = XdrvMailbox.payload;
|
||||
TasmotaGlobal.sleep = XdrvMailbox.payload;
|
||||
WiFiSetSleepMode();
|
||||
}
|
||||
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.sleep, ssleep);
|
||||
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.sleep, TasmotaGlobal.sleep);
|
||||
|
||||
}
|
||||
|
||||
@ -698,11 +697,11 @@ void CmndUpgrade(void)
|
||||
// Check if the version we have been asked to upgrade to is higher than our current version.
|
||||
// We also need at least 3 chars to make a valid version number string.
|
||||
if (((1 == XdrvMailbox.data_len) && (1 == XdrvMailbox.payload)) || ((XdrvMailbox.data_len >= 3) && NewerVersion(XdrvMailbox.data))) {
|
||||
ota_state_flag = 3;
|
||||
TasmotaGlobal.ota_state_flag = 3;
|
||||
char stemp1[TOPSZ];
|
||||
Response_P(PSTR("{\"%s\":\"" D_JSON_VERSION " %s " D_JSON_FROM " %s\"}"), XdrvMailbox.command, my_version, GetOtaUrl(stemp1, sizeof(stemp1)));
|
||||
Response_P(PSTR("{\"%s\":\"" D_JSON_VERSION " %s " D_JSON_FROM " %s\"}"), XdrvMailbox.command, TasmotaGlobal.version, GetOtaUrl(stemp1, sizeof(stemp1)));
|
||||
} else {
|
||||
Response_P(PSTR("{\"%s\":\"" D_JSON_ONE_OR_GT "\"}"), XdrvMailbox.command, my_version);
|
||||
Response_P(PSTR("{\"%s\":\"" D_JSON_ONE_OR_GT "\"}"), XdrvMailbox.command, TasmotaGlobal.version);
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,19 +719,19 @@ void CmndSeriallog(void)
|
||||
Settings.flag.mqtt_serial = 0; // CMND_SERIALSEND and CMND_SERIALLOG
|
||||
SetSeriallog(XdrvMailbox.payload);
|
||||
}
|
||||
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.seriallog_level, seriallog_level);
|
||||
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.seriallog_level, TasmotaGlobal.seriallog_level);
|
||||
}
|
||||
|
||||
void CmndRestart(void)
|
||||
{
|
||||
switch (XdrvMailbox.payload) {
|
||||
case 1:
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
ResponseCmndChar(D_JSON_RESTARTING);
|
||||
break;
|
||||
case 2:
|
||||
restart_flag = 2;
|
||||
restart_halt = true;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
TasmotaGlobal.restart_halt = true;
|
||||
ResponseCmndChar(D_JSON_HALTING);
|
||||
break;
|
||||
case -1:
|
||||
@ -756,7 +755,7 @@ void CmndRestart(void)
|
||||
void CmndPowerOnState(void)
|
||||
{
|
||||
#ifdef ESP8266
|
||||
if (my_module_type != MOTOR)
|
||||
if (TasmotaGlobal.module_type != MOTOR)
|
||||
#endif // ESP8266
|
||||
{
|
||||
/* 0 = Keep relays off after power on
|
||||
@ -769,7 +768,7 @@ void CmndPowerOnState(void)
|
||||
if ((XdrvMailbox.payload >= POWER_ALL_OFF) && (XdrvMailbox.payload <= POWER_ALL_OFF_PULSETIME_ON)) {
|
||||
Settings.poweronstate = XdrvMailbox.payload;
|
||||
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) {
|
||||
for (uint32_t i = 1; i <= devices_present; i++) {
|
||||
for (uint32_t i = 1; i <= TasmotaGlobal.devices_present; i++) {
|
||||
ExecuteCommandPower(i, POWER_ON, SRC_IGNORE);
|
||||
}
|
||||
}
|
||||
@ -790,7 +789,7 @@ void CmndPulsetime(void)
|
||||
SetPulseTimer(XdrvMailbox.index -1, XdrvMailbox.payload);
|
||||
}
|
||||
}
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
for (uint32_t i = 0; i < items; i++) {
|
||||
uint32_t index = (1 == items) ? XdrvMailbox.index : i +1;
|
||||
ResponseAppend_P(PSTR("%c\"%s%d\":{\"" D_JSON_SET "\":%d,\"" D_JSON_REMAINING "\":%d}"),
|
||||
@ -806,7 +805,9 @@ void CmndBlinktime(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload > 1) && (XdrvMailbox.payload <= 3600)) {
|
||||
Settings.blinktime = XdrvMailbox.payload;
|
||||
if (blink_timer > 0) { blink_timer = millis() + (100 * XdrvMailbox.payload); }
|
||||
if (TasmotaGlobal.blink_timer > 0) {
|
||||
TasmotaGlobal.blink_timer = millis() + (100 * XdrvMailbox.payload);
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber(Settings.blinktime);
|
||||
}
|
||||
@ -815,7 +816,7 @@ void CmndBlinkcount(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 65536)) {
|
||||
Settings.blinkcount = XdrvMailbox.payload; // 0 - 65535
|
||||
if (blink_counter) { blink_counter = Settings.blinkcount *2; }
|
||||
if (TasmotaGlobal.blink_counter) { TasmotaGlobal.blink_counter = Settings.blinkcount *2; }
|
||||
}
|
||||
ResponseCmndNumber(Settings.blinkcount);
|
||||
}
|
||||
@ -824,7 +825,7 @@ void CmndSavedata(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3600)) {
|
||||
Settings.save_data = XdrvMailbox.payload;
|
||||
save_data_counter = Settings.save_data;
|
||||
TasmotaGlobal.save_data_counter = Settings.save_data;
|
||||
}
|
||||
SettingsSaveAll();
|
||||
char stemp1[TOPSZ];
|
||||
@ -878,7 +879,7 @@ void CmndSetoption(void)
|
||||
#ifdef USE_LIGHT
|
||||
if (P_RGB_REMAP == pindex) {
|
||||
LightUpdateColorMapping();
|
||||
restart_flag = 2; // SetOption37 needs a reboot in most cases
|
||||
TasmotaGlobal.restart_flag = 2; // SetOption37 needs a reboot in most cases
|
||||
}
|
||||
#endif
|
||||
#if (defined(USE_IR_REMOTE) && defined(USE_IR_RECEIVE)) || defined(USE_IR_REMOTE_FULL)
|
||||
@ -906,12 +907,12 @@ void CmndSetoption(void)
|
||||
break; // Ignore command SetOption
|
||||
case 3: // mqtt
|
||||
case 15: // pwm_control
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
default:
|
||||
bitWrite(Settings.flag.data, pindex, XdrvMailbox.payload);
|
||||
}
|
||||
if (12 == pindex) { // stop_flash_rotate
|
||||
stop_flash_rotate = XdrvMailbox.payload;
|
||||
TasmotaGlobal.stop_flash_rotate = XdrvMailbox.payload;
|
||||
SettingsSave(2);
|
||||
}
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
@ -925,7 +926,7 @@ void CmndSetoption(void)
|
||||
switch (pindex) {
|
||||
case 5: // SetOption55
|
||||
if (0 == XdrvMailbox.payload) {
|
||||
restart_flag = 2; // Disable mDNS needs restart
|
||||
TasmotaGlobal.restart_flag = 2; // Disable mDNS needs restart
|
||||
}
|
||||
break;
|
||||
case 10: // SetOption60 enable or disable traditional sleep
|
||||
@ -933,7 +934,7 @@ void CmndSetoption(void)
|
||||
break;
|
||||
case 18: // SetOption68 for multi-channel PWM, requires a reboot
|
||||
case 25: // SetOption75 grouptopic change
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -948,7 +949,7 @@ void CmndSetoption(void)
|
||||
case 22: // SetOption104 - No Retain - disable all MQTT retained messages, some brokers don't support it: AWS IoT, Losant
|
||||
case 24: // SetOption106 - Virtual CT - Creates a virtual White ColorTemp for RGBW lights
|
||||
case 25: // SetOption107 - Virtual CT Channel - signals whether the hardware white is cold CW (true) or warm WW (false)
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1084,7 +1085,7 @@ void CmndModule(void)
|
||||
Settings.my_gp.io[i] = GPIO_NONE;
|
||||
}
|
||||
}
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1119,7 +1120,7 @@ void CmndModules(void)
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
|
||||
void CmndGpio(void)
|
||||
@ -1143,7 +1144,7 @@ void CmndGpio(void)
|
||||
}
|
||||
}
|
||||
Settings.my_gp.io[XdrvMailbox.index] = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
}
|
||||
Response_P(PSTR("{"));
|
||||
@ -1188,13 +1189,20 @@ void CmndGpio(void)
|
||||
}
|
||||
|
||||
void ShowGpios(const uint16_t *NiceList, uint32_t size, uint32_t offset, uint32_t &lines) {
|
||||
uint32_t ridx;
|
||||
uint32_t midx;
|
||||
myio cmodule;
|
||||
ModuleGpios(&cmodule);
|
||||
bool jsflg = false;
|
||||
for (uint32_t i = offset; i < size; i++) { // Skip ADC_NONE
|
||||
uint32_t ridx = pgm_read_word(NiceList + i) & 0xFFE0;
|
||||
uint32_t midx = BGPIO(ridx);
|
||||
if ((XdrvMailbox.payload != 255) && GetUsedInModule(midx, cmodule.io)) { continue; }
|
||||
if (NiceList == nullptr) {
|
||||
ridx = AGPIO(i);
|
||||
midx = i;
|
||||
} else {
|
||||
ridx = pgm_read_word(NiceList + i) & 0xFFE0;
|
||||
midx = BGPIO(ridx);
|
||||
if ((XdrvMailbox.payload != 255) && GetUsedInModule(midx, cmodule.io)) { continue; }
|
||||
}
|
||||
if (!jsflg) {
|
||||
Response_P(PSTR("{\"" D_CMND_GPIOS "%d\":{"), lines);
|
||||
} else {
|
||||
@ -1213,20 +1221,19 @@ void ShowGpios(const uint16_t *NiceList, uint32_t size, uint32_t offset, uint32_
|
||||
|
||||
void CmndGpios(void)
|
||||
{
|
||||
/*
|
||||
if (XdrvMailbox.payload == 17) {
|
||||
DumpConvertTable();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
uint32_t lines = 1;
|
||||
ShowGpios(kGpioNiceList, ARRAY_SIZE(kGpioNiceList), 0, lines);
|
||||
if (XdrvMailbox.payload == 255) {
|
||||
// DumpConvertTable();
|
||||
ShowGpios(nullptr, GPIO_SENSOR_END, 0, lines);
|
||||
} else {
|
||||
ShowGpios(kGpioNiceList, ARRAY_SIZE(kGpioNiceList), 0, lines);
|
||||
#ifdef ESP8266
|
||||
#ifndef USE_ADC_VCC
|
||||
ShowGpios(kAdcNiceList, ARRAY_SIZE(kAdcNiceList), 1, lines);
|
||||
ShowGpios(kAdcNiceList, ARRAY_SIZE(kAdcNiceList), 1, lines);
|
||||
#endif // USE_ADC_VCC
|
||||
#endif // ESP8266
|
||||
mqtt_data[0] = '\0';
|
||||
}
|
||||
ResponseClear();
|
||||
}
|
||||
|
||||
void CmndTemplate(void)
|
||||
@ -1240,7 +1247,7 @@ void CmndTemplate(void)
|
||||
XdrvMailbox.payload--;
|
||||
if (ValidTemplateModule(XdrvMailbox.payload)) {
|
||||
ModuleDefault(XdrvMailbox.payload); // Copy template module
|
||||
if (USER_MODULE == Settings.module) { restart_flag = 2; }
|
||||
if (USER_MODULE == Settings.module) { TasmotaGlobal.restart_flag = 2; }
|
||||
}
|
||||
}
|
||||
else if (0 == XdrvMailbox.payload) { // Copy current template to user template
|
||||
@ -1257,8 +1264,8 @@ void CmndTemplate(void)
|
||||
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) {
|
||||
Settings.user_template.gp.io[i] = my_module.io[j];
|
||||
if (TasmotaGlobal.my_module.io[j] > GPIO_NONE) {
|
||||
Settings.user_template.gp.io[i] = TasmotaGlobal.my_module.io[j];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
@ -1266,7 +1273,7 @@ void CmndTemplate(void)
|
||||
}
|
||||
else {
|
||||
if (JsonTemplate(XdrvMailbox.data)) { // Free 336 bytes StaticJsonBuffer stack space by moving code to function
|
||||
if (USER_MODULE == Settings.module) { restart_flag = 2; }
|
||||
if (USER_MODULE == Settings.module) { TasmotaGlobal.restart_flag = 2; }
|
||||
} else {
|
||||
ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON));
|
||||
error = true;
|
||||
@ -1277,10 +1284,10 @@ void CmndTemplate(void)
|
||||
|
||||
void CmndPwm(void)
|
||||
{
|
||||
if (pwm_present && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_PWMS)) {
|
||||
if (TasmotaGlobal.pwm_present && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_PWMS)) {
|
||||
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(TasmotaGlobal.pwm_inverted, XdrvMailbox.index -1) ? Settings.pwm_range - XdrvMailbox.payload : XdrvMailbox.payload);
|
||||
}
|
||||
Response_P(PSTR("{"));
|
||||
MqttShowPWMState(); // Render the PWM status to MQTT
|
||||
@ -1341,10 +1348,10 @@ void CmndBaudrate(void)
|
||||
{
|
||||
if (XdrvMailbox.payload >= 300) {
|
||||
XdrvMailbox.payload /= 300; // Make it a valid baudrate
|
||||
baudrate = (XdrvMailbox.payload & 0xFFFF) * 300;
|
||||
SetSerialBaudrate(baudrate);
|
||||
TasmotaGlobal.baudrate = (XdrvMailbox.payload & 0xFFFF) * 300;
|
||||
SetSerialBaudrate(TasmotaGlobal.baudrate);
|
||||
}
|
||||
ResponseCmndNumber(baudrate);
|
||||
ResponseCmndNumber(TasmotaGlobal.baudrate);
|
||||
}
|
||||
|
||||
void CmndSerialConfig(void)
|
||||
@ -1438,7 +1445,7 @@ void CmndSyslog(void)
|
||||
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) {
|
||||
SetSyslog(XdrvMailbox.payload);
|
||||
}
|
||||
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.syslog_level, syslog_level);
|
||||
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.syslog_level, TasmotaGlobal.syslog_level);
|
||||
}
|
||||
|
||||
void CmndLoghost(void)
|
||||
@ -1463,7 +1470,7 @@ void CmndIpAddress(void)
|
||||
uint32_t address;
|
||||
if (ParseIp(&address, XdrvMailbox.data)) {
|
||||
Settings.ip_address[XdrvMailbox.index -1] = address;
|
||||
// restart_flag = 2;
|
||||
// TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
char stemp1[TOPSZ];
|
||||
snprintf_P(stemp1, sizeof(stemp1), PSTR(" (%s)"), WiFi.localIP().toString().c_str());
|
||||
@ -1482,8 +1489,8 @@ void CmndNtpServer(void)
|
||||
SettingsUpdateText(ntp_server,
|
||||
(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;
|
||||
// TasmotaGlobal.restart_flag = 2; // Issue #3890
|
||||
TasmotaGlobal.ntp_force_sync = true;
|
||||
}
|
||||
ResponseCmndIdxChar(SettingsText(ntp_server));
|
||||
}
|
||||
@ -1502,7 +1509,7 @@ void CmndAp(void)
|
||||
Settings.sta_active = XdrvMailbox.payload -1;
|
||||
}
|
||||
Settings.wifi_channel = 0; // Disable stored AP
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_active +1, EscapeJSONString(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str());
|
||||
}
|
||||
@ -1517,7 +1524,7 @@ void CmndSsid(void)
|
||||
SettingsUpdateText(SET_STASSID1 + XdrvMailbox.index -1,
|
||||
(SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? STA_SSID1 : STA_SSID2 : XdrvMailbox.data);
|
||||
Settings.sta_active = XdrvMailbox.index -1;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndIdxChar(SettingsText(SET_STASSID1 + XdrvMailbox.index -1));
|
||||
}
|
||||
@ -1531,7 +1538,7 @@ void CmndPassword(void)
|
||||
SettingsUpdateText(SET_STAPWD1 + XdrvMailbox.index -1,
|
||||
(SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? STA_PASS1 : STA_PASS2 : XdrvMailbox.data);
|
||||
Settings.sta_active = XdrvMailbox.index -1;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
ResponseCmndIdxChar(SettingsText(SET_STAPWD1 + XdrvMailbox.index -1));
|
||||
} else {
|
||||
Response_P(S_JSON_COMMAND_INDEX_ASTERISK, XdrvMailbox.command, XdrvMailbox.index);
|
||||
@ -1546,7 +1553,7 @@ void CmndHostname(void)
|
||||
if (strstr(SettingsText(SET_HOSTNAME), "%") != nullptr) {
|
||||
SettingsUpdateText(SET_HOSTNAME, WIFI_HOSTNAME);
|
||||
}
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndChar(SettingsText(SET_HOSTNAME));
|
||||
}
|
||||
@ -1558,9 +1565,9 @@ void CmndWifiConfig(void)
|
||||
XdrvMailbox.payload = WIFI_MANAGER;
|
||||
}
|
||||
Settings.sta_config = XdrvMailbox.payload;
|
||||
wifi_state_flag = Settings.sta_config;
|
||||
TasmotaGlobal.wifi_state_flag = Settings.sta_config;
|
||||
if (WifiState() > WIFI_RESTART) {
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
}
|
||||
char stemp1[TOPSZ];
|
||||
@ -1571,7 +1578,7 @@ void CmndWifi(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
|
||||
Settings.flag4.network_wifi = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndStateText(Settings.flag4.network_wifi);
|
||||
}
|
||||
@ -1604,6 +1611,20 @@ void CmndFriendlyname(void)
|
||||
}
|
||||
}
|
||||
|
||||
void CmndSwitchText(void) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_SWITCHES)) {
|
||||
if (!XdrvMailbox.usridx && !XdrvMailbox.data_len) {
|
||||
ResponseCmndAll(SET_SWITCH_TXT1, MAX_SWITCHES);
|
||||
} else {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
RemoveSpace(XdrvMailbox.data);
|
||||
SettingsUpdateText(SET_SWITCH_TXT1 + XdrvMailbox.index -1, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data);
|
||||
}
|
||||
ResponseCmndIdxChar(SettingsText(SET_SWITCH_TXT1 + XdrvMailbox.index -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CmndSwitchMode(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_SWITCHES)) {
|
||||
@ -1617,8 +1638,8 @@ void CmndSwitchMode(void)
|
||||
void CmndInterlock(void)
|
||||
{
|
||||
// Interlock 0 - Off, Interlock 1 - On, Interlock 1,2 3,4 5,6,7
|
||||
uint32_t max_relays = devices_present;
|
||||
if (light_type) { max_relays--; }
|
||||
uint32_t max_relays = TasmotaGlobal.devices_present;
|
||||
if (TasmotaGlobal.light_type) { max_relays--; }
|
||||
if (max_relays > sizeof(Settings.interlock[0]) * 8) { max_relays = sizeof(Settings.interlock[0]) * 8; }
|
||||
if (max_relays > 1) { // Only interlock with more than 1 relay
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
@ -1653,7 +1674,7 @@ void CmndInterlock(void)
|
||||
} else {
|
||||
Settings.flag.interlock = XdrvMailbox.payload &1; // CMND_INTERLOCK - Enable/disable interlock
|
||||
if (Settings.flag.interlock) {
|
||||
SetDevicePower(power, SRC_IGNORE); // Remove multiple relays if set
|
||||
SetDevicePower(TasmotaGlobal.power, SRC_IGNORE); // Remove multiple relays if set
|
||||
}
|
||||
}
|
||||
#ifdef USE_SHUTTER
|
||||
@ -1697,9 +1718,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;
|
||||
// TasmotaGlobal.tele_period = Settings.tele_period;
|
||||
}
|
||||
tele_period = Settings.tele_period; // Show teleperiod data also on empty command
|
||||
TasmotaGlobal.tele_period = Settings.tele_period; // Show teleperiod data also on empty command
|
||||
ResponseCmndNumber(Settings.tele_period);
|
||||
}
|
||||
|
||||
@ -1707,11 +1728,11 @@ void CmndReset(void)
|
||||
{
|
||||
switch (XdrvMailbox.payload) {
|
||||
case 1:
|
||||
restart_flag = 211;
|
||||
TasmotaGlobal.restart_flag = 211;
|
||||
ResponseCmndChar(PSTR(D_JSON_RESET_AND_RESTARTING));
|
||||
break;
|
||||
case 2 ... 6:
|
||||
restart_flag = 210 + XdrvMailbox.payload;
|
||||
TasmotaGlobal.restart_flag = 210 + XdrvMailbox.payload;
|
||||
Response_P(PSTR("{\"" D_CMND_RESET "\":\"" D_JSON_ERASE ", " D_JSON_RESET_AND_RESTARTING "\"}"));
|
||||
break;
|
||||
case 99:
|
||||
@ -1743,7 +1764,7 @@ void CmndTime(void)
|
||||
RtcSetTime(XdrvMailbox.payload);
|
||||
}
|
||||
}
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
ResponseAppendTimeFormat(format);
|
||||
ResponseJsonEnd();
|
||||
}
|
||||
@ -1765,7 +1786,7 @@ void CmndTimezone(void)
|
||||
} else {
|
||||
Settings.timezone = 99;
|
||||
}
|
||||
ntp_force_sync = true;
|
||||
TasmotaGlobal.ntp_force_sync = true;
|
||||
}
|
||||
if (99 == Settings.timezone) {
|
||||
ResponseCmndNumber(Settings.timezone);
|
||||
@ -1801,7 +1822,7 @@ void CmndTimeStdDst(uint32_t ts)
|
||||
value = strtol(p, &p, 10);
|
||||
tpos++; // Next parameter
|
||||
}
|
||||
ntp_force_sync = true;
|
||||
TasmotaGlobal.ntp_force_sync = true;
|
||||
} else {
|
||||
if (0 == XdrvMailbox.payload) {
|
||||
if (0 == ts) {
|
||||
@ -1810,7 +1831,7 @@ void CmndTimeStdDst(uint32_t ts)
|
||||
SettingsResetDst();
|
||||
}
|
||||
}
|
||||
ntp_force_sync = true;
|
||||
TasmotaGlobal.ntp_force_sync = true;
|
||||
}
|
||||
}
|
||||
Response_P(PSTR("{\"%s\":{\"Hemisphere\":%d,\"Week\":%d,\"Month\":%d,\"Day\":%d,\"Hour\":%d,\"Offset\":%d}}"),
|
||||
@ -1836,7 +1857,7 @@ void CmndAltitude(void)
|
||||
}
|
||||
|
||||
void CmndLedPower(void) {
|
||||
// If GPIO_LEDLINK (used for network status) then allow up to 4 GPIO_LEDx control using led_power
|
||||
// If GPIO_LEDLINK (used for network status) then allow up to 4 GPIO_LEDx control using TasmotaGlobal.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 (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; }
|
||||
@ -1845,26 +1866,26 @@ void CmndLedPower(void) {
|
||||
uint32_t mask = 1 << (XdrvMailbox.index -1); // Led to control
|
||||
switch (XdrvMailbox.payload) {
|
||||
case 0: // Off
|
||||
led_power &= (0xFF ^ mask);
|
||||
TasmotaGlobal.led_power &= (0xFF ^ mask);
|
||||
Settings.ledstate = 0;
|
||||
break;
|
||||
case 1: // On
|
||||
led_power |= mask;
|
||||
TasmotaGlobal.led_power |= mask;
|
||||
Settings.ledstate = 8;
|
||||
break;
|
||||
case 2: // Toggle
|
||||
led_power ^= mask;
|
||||
TasmotaGlobal.led_power ^= mask;
|
||||
Settings.ledstate ^= 8;
|
||||
break;
|
||||
}
|
||||
blinks = 0;
|
||||
TasmotaGlobal.blinks = 0;
|
||||
if (!PinUsed(GPIO_LEDLNK)) {
|
||||
SetLedPower(Settings.ledstate &8);
|
||||
} else {
|
||||
SetLedPowerIdx(XdrvMailbox.index -1, (led_power & mask));
|
||||
SetLedPowerIdx(XdrvMailbox.index -1, (TasmotaGlobal.led_power & mask));
|
||||
}
|
||||
}
|
||||
bool state = bitRead(led_power, XdrvMailbox.index -1);
|
||||
bool state = bitRead(TasmotaGlobal.led_power, XdrvMailbox.index -1);
|
||||
if (!PinUsed(GPIO_LEDLNK)) {
|
||||
state = bitRead(Settings.ledstate, 3);
|
||||
}
|
||||
@ -1966,8 +1987,8 @@ void CmndWifiPower(void)
|
||||
#ifdef USE_I2C
|
||||
void CmndI2cScan(void)
|
||||
{
|
||||
if (i2c_flg) {
|
||||
I2cScan(mqtt_data, sizeof(mqtt_data));
|
||||
if (TasmotaGlobal.i2c_enabled) {
|
||||
I2cScan(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1976,7 +1997,7 @@ void CmndI2cDriver(void)
|
||||
if (XdrvMailbox.index < MAX_I2C_DRIVERS) {
|
||||
if (XdrvMailbox.payload >= 0) {
|
||||
bitWrite(Settings.i2c_drivers[XdrvMailbox.index / 32], XdrvMailbox.index % 32, XdrvMailbox.payload &1);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
}
|
||||
Response_P(PSTR("{\"" D_CMND_I2CDRIVER "\":"));
|
||||
@ -1995,7 +2016,7 @@ void CmndDevGroupName(void)
|
||||
else if (1 == XdrvMailbox.data_len && ('"' == XdrvMailbox.data[0] || '0' == XdrvMailbox.data[0]))
|
||||
XdrvMailbox.data[0] = 0;
|
||||
SettingsUpdateText(SET_DEV_GROUP_NAME1 + XdrvMailbox.index - 1, XdrvMailbox.data);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndAll(SET_DEV_GROUP_NAME1, MAX_DEV_GROUP_NAMES);
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ void DeviceGroupsInit(void)
|
||||
|
||||
void DeviceGroupsStart()
|
||||
{
|
||||
if (Settings.flag4.device_groups_enabled && !device_groups_up && !restart_flag) {
|
||||
if (Settings.flag4.device_groups_enabled && !device_groups_up && !TasmotaGlobal.restart_flag) {
|
||||
|
||||
// If we haven't successfuly initialized device groups yet, attempt to do it now.
|
||||
if (!device_groups_initialized) {
|
||||
@ -295,7 +295,7 @@ void SendReceiveDeviceGroupMessage(struct device_group * device_group, struct de
|
||||
XdrvMailbox.index = flags | message_sequence << 16;
|
||||
if (device_group_index == 0 && first_device_group_is_local) XdrvMailbox.index |= DGR_FLAG_LOCAL;
|
||||
XdrvMailbox.topic = (char *)&device_group_index;
|
||||
if (flags & (DGR_FLAG_MORE_TO_COME | DGR_FLAG_DIRECT)) skip_light_fade = true;
|
||||
if (flags & (DGR_FLAG_MORE_TO_COME | DGR_FLAG_DIRECT)) TasmotaGlobal.skip_light_fade = true;
|
||||
|
||||
// Set the flag to ignore device group send message request so callbacks from the drivers do not
|
||||
// send updates.
|
||||
@ -386,18 +386,18 @@ void SendReceiveDeviceGroupMessage(struct device_group * device_group, struct de
|
||||
switch (item) {
|
||||
case DGR_ITEM_POWER:
|
||||
if (Settings.flag4.multiple_device_groups) { // SetOption88 - Enable relays in separate device groups
|
||||
if (device_group_index < devices_present) {
|
||||
if (device_group_index < TasmotaGlobal.devices_present) {
|
||||
bool on = (value & 1);
|
||||
if (on != (power & (1 << device_group_index))) ExecuteCommandPower(device_group_index + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE);
|
||||
if (on != (TasmotaGlobal.power & (1 << device_group_index))) ExecuteCommandPower(device_group_index + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE);
|
||||
}
|
||||
}
|
||||
else if (XdrvMailbox.index & DGR_FLAG_LOCAL) {
|
||||
uint8_t mask_devices = value >> 24;
|
||||
if (mask_devices > devices_present) mask_devices = devices_present;
|
||||
if (mask_devices > TasmotaGlobal.devices_present) mask_devices = TasmotaGlobal.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);
|
||||
if (on != (TasmotaGlobal.power & mask)) ExecuteCommandPower(i + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -455,7 +455,7 @@ badmsg:
|
||||
|
||||
cleanup:
|
||||
if (received) {
|
||||
skip_light_fade = false;
|
||||
TasmotaGlobal.skip_light_fade = false;
|
||||
ignore_dgr_sends = false;
|
||||
}
|
||||
}
|
||||
@ -505,7 +505,7 @@ bool _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
building_status_message = true;
|
||||
|
||||
// Call the drivers to build the status update.
|
||||
SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_POWER, power);
|
||||
SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_POWER, TasmotaGlobal.power);
|
||||
XdrvMailbox.index = 0;
|
||||
if (device_group_index == 0 && first_device_group_is_local) XdrvMailbox.index = DGR_FLAG_LOCAL;
|
||||
XdrvMailbox.command_code = DGR_ITEM_STATUS;
|
||||
@ -679,7 +679,7 @@ bool _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
*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 && first_device_group_is_local ? devices_present : 1);
|
||||
if (item == DGR_ITEM_POWER && !value) value = (device_group_index == 0 && first_device_group_is_local ? TasmotaGlobal.devices_present : 1);
|
||||
*message_ptr++ = value;
|
||||
}
|
||||
}
|
||||
@ -806,7 +806,7 @@ void DeviceGroupStatus(uint8_t device_group_index)
|
||||
|
||||
void DeviceGroupsLoop(void)
|
||||
{
|
||||
if (!device_groups_up || restart_flag) return;
|
||||
if (!device_groups_up || TasmotaGlobal.restart_flag) return;
|
||||
|
||||
while (device_groups_udp.parsePacket()) {
|
||||
uint8_t packet_buffer[512];
|
||||
|
||||
@ -39,7 +39,7 @@ void eeprom_readBytes(uint32_t addr, uint32_t len, uint8_t *buff) {
|
||||
}
|
||||
|
||||
uint32_t eeprom_init(uint32_t size) {
|
||||
if (i2c_flg) {
|
||||
if (TasmotaGlobal.i2c_enabled) {
|
||||
if (I2cActive(EEPROM_ADDRESS) || I2cSetDevice(EEPROM_ADDRESS)) {
|
||||
// eeprom is present
|
||||
I2cSetActiveFound(EEPROM_ADDRESS, "24C256");
|
||||
|
||||
@ -168,13 +168,13 @@ void SntpInit() {
|
||||
|
||||
uint32_t SntpGetCurrentTimestamp(void) {
|
||||
time_t now = 0;
|
||||
if (bNetIsTimeSync || ntp_force_sync)
|
||||
if (bNetIsTimeSync || TasmotaGlobal.ntp_force_sync)
|
||||
{
|
||||
//Serial_DebugX(("timesync configTime %d\n", ntp_force_sync, bNetIsTimeSync));
|
||||
//Serial_DebugX(("timesync configTime %d\n", TasmotaGlobal.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;
|
||||
TasmotaGlobal.ntp_force_sync = false;
|
||||
}
|
||||
time(&now);
|
||||
return now;
|
||||
|
||||
@ -21,663 +21,668 @@
|
||||
* Fill feature list
|
||||
\*********************************************************************************************/
|
||||
|
||||
void GetFeatures(void)
|
||||
void ResponseAppendFeatures(void)
|
||||
{
|
||||
feature_drv1 = 0x00000000;
|
||||
|
||||
static uint32_t feature1 = 0x00000000;
|
||||
if (!feature1) { // Only fill this once
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_MARGIN_DETECTION)
|
||||
feature_drv1 |= 0x00000001; // xdrv_03_energy.ino
|
||||
feature1 |= 0x00000001; // xdrv_03_energy.ino
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
feature_drv1 |= 0x00000002; // tasmota.ino, xdrv_04_light.ino
|
||||
feature1 |= 0x00000002; // tasmota.ino, xdrv_04_light.ino
|
||||
#endif
|
||||
#ifdef USE_I2C
|
||||
feature_drv1 |= 0x00000004; // tasmota.ino
|
||||
feature1 |= 0x00000004; // tasmota.ino
|
||||
#endif
|
||||
#ifdef USE_SPI
|
||||
feature_drv1 |= 0x00000008; // tasmota.ino
|
||||
feature1 |= 0x00000008; // tasmota.ino
|
||||
#endif
|
||||
#ifdef USE_DISCOVERY
|
||||
feature_drv1 |= 0x00000010; // tasmota.ino
|
||||
feature1 |= 0x00000010; // tasmota.ino
|
||||
#endif
|
||||
#ifdef USE_ARDUINO_OTA
|
||||
feature_drv1 |= 0x00000020; // tasmota.ino
|
||||
feature1 |= 0x00000020; // tasmota.ino
|
||||
#endif
|
||||
#ifdef USE_MQTT_TLS
|
||||
feature_drv1 |= 0x00000040; // xdrv_02_mqtt.ino
|
||||
feature1 |= 0x00000040; // xdrv_02_mqtt.ino
|
||||
#endif
|
||||
#ifdef USE_WEBSERVER
|
||||
feature_drv1 |= 0x00000080; // xdrv_01_webserver.ino
|
||||
feature1 |= 0x00000080; // xdrv_01_webserver.ino
|
||||
#endif
|
||||
#if defined(USE_WEBSERVER) && defined(WEBSERVER_ADVERTISE)
|
||||
feature_drv1 |= 0x00000100; // xdrv_01_webserver.ino
|
||||
feature1 |= 0x00000100; // xdrv_01_webserver.ino
|
||||
#endif
|
||||
#if defined(USE_WEBSERVER) && defined(USE_EMULATION_HUE)
|
||||
feature_drv1 |= 0x00000200; // xdrv_20_hue.ino
|
||||
feature1 |= 0x00000200; // xdrv_20_hue.ino
|
||||
#endif
|
||||
//#if (MQTT_LIBRARY_TYPE == MQTT_PUBSUBCLIENT)
|
||||
feature_drv1 |= 0x00000400; // xdrv_02_mqtt.ino
|
||||
feature1 |= 0x00000400; // xdrv_02_mqtt.ino
|
||||
//#endif
|
||||
//#if (MQTT_LIBRARY_TYPE == MQTT_TASMOTAMQTT)
|
||||
// feature_drv1 |= 0x00000800; // xdrv_02_mqtt.ino
|
||||
// feature1 |= 0x00000800; // xdrv_02_mqtt.ino
|
||||
//#endif
|
||||
//#if (MQTT_LIBRARY_TYPE == MQTT_ESPMQTTARDUINO) // Obsolete since 6.2.1.11
|
||||
// feature_drv1 |= 0x00001000; // xdrv_02_mqtt.ino
|
||||
// feature1 |= 0x00001000; // xdrv_02_mqtt.ino
|
||||
//#endif
|
||||
#if defined(USE_DISCOVERY) && defined(MQTT_HOST_DISCOVERY)
|
||||
feature_drv1 |= 0x00002000; // xdrv_02_mqtt.ino
|
||||
feature1 |= 0x00002000; // xdrv_02_mqtt.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_ARILUX_RF)
|
||||
feature_drv1 |= 0x00004000; // xdrv_04_light.ino
|
||||
feature1 |= 0x00004000; // xdrv_04_light.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_WS2812)
|
||||
feature_drv1 |= 0x00008000; // xdrv_04_light.ino
|
||||
feature1 |= 0x00008000; // xdrv_04_light.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_WS2812) && defined(USE_WS2812_DMA)
|
||||
feature_drv1 |= 0x00010000; // xdrv_04_light.ino
|
||||
feature1 |= 0x00010000; // xdrv_04_light.ino
|
||||
#endif
|
||||
#if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL)
|
||||
feature_drv1 |= 0x00020000; // xdrv_05_irremote.ino
|
||||
feature1 |= 0x00020000; // xdrv_05_irremote.ino
|
||||
#endif
|
||||
#ifdef USE_IR_HVAC
|
||||
feature_drv1 |= 0x00040000; // xdrv_05_irremote.ino
|
||||
feature1 |= 0x00040000; // xdrv_05_irremote.ino
|
||||
#endif
|
||||
#if defined(USE_IR_REMOTE) && defined(USE_IR_RECEIVE)
|
||||
feature_drv1 |= 0x00080000; // xdrv_05_irremote.ino
|
||||
feature1 |= 0x00080000; // xdrv_05_irremote.ino
|
||||
#endif
|
||||
#ifdef USE_DOMOTICZ
|
||||
feature_drv1 |= 0x00100000; // xdrv_07_domoticz.ino
|
||||
feature1 |= 0x00100000; // xdrv_07_domoticz.ino
|
||||
#endif
|
||||
#ifdef USE_DISPLAY
|
||||
feature_drv1 |= 0x00200000; // xdrv_13_display.ino
|
||||
feature1 |= 0x00200000; // xdrv_13_display.ino
|
||||
#endif
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
feature_drv1 |= 0x00400000; // xdrv_12_home_assistant.ino
|
||||
feature1 |= 0x00400000; // xdrv_12_home_assistant.ino
|
||||
#endif
|
||||
#ifdef USE_SERIAL_BRIDGE
|
||||
feature_drv1 |= 0x00800000; // xdrv_08_serial_bridge.ino
|
||||
feature1 |= 0x00800000; // xdrv_08_serial_bridge.ino
|
||||
#endif
|
||||
#ifdef USE_TIMERS
|
||||
feature_drv1 |= 0x01000000; // xdrv_09_timers.ino
|
||||
feature1 |= 0x01000000; // xdrv_09_timers.ino
|
||||
#endif
|
||||
#if defined(USE_TIMERS) && defined(USE_SUNRISE)
|
||||
feature_drv1 |= 0x02000000; // xdrv_09_timers.ino
|
||||
feature1 |= 0x02000000; // xdrv_09_timers.ino
|
||||
#endif
|
||||
#if defined(USE_TIMERS) && defined(USE_TIMERS_WEB)
|
||||
feature_drv1 |= 0x04000000; // xdrv_09_timers.ino
|
||||
feature1 |= 0x04000000; // xdrv_09_timers.ino
|
||||
#endif
|
||||
#ifdef USE_RULES
|
||||
feature_drv1 |= 0x08000000; // xdrv_10_rules.ino
|
||||
feature1 |= 0x08000000; // xdrv_10_rules.ino
|
||||
#endif
|
||||
#ifdef USE_KNX
|
||||
feature_drv1 |= 0x10000000; // xdrv_11_knx.ino
|
||||
feature1 |= 0x10000000; // xdrv_11_knx.ino
|
||||
#endif
|
||||
#ifdef USE_WPS
|
||||
feature_drv1 |= 0x20000000; // support.ino - removed with version 6.6.0.21
|
||||
feature1 |= 0x20000000; // support.ino - removed with version 6.6.0.21
|
||||
#endif
|
||||
#ifdef USE_SMARTCONFIG
|
||||
feature_drv1 |= 0x40000000; // support.ino - removed with version 6.6.0.21
|
||||
feature1 |= 0x40000000; // support.ino - removed with version 6.6.0.21
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_POWER_LIMIT)
|
||||
feature_drv1 |= 0x80000000; // xdrv_03_energy.ino
|
||||
feature1 |= 0x80000000; // xdrv_03_energy.ino
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
feature_drv2 = 0x00000000;
|
||||
|
||||
static uint32_t feature2 = 0x00000000;
|
||||
if (!feature2) { // Only fill this once
|
||||
#ifdef USE_CONFIG_OVERRIDE
|
||||
feature_drv2 |= 0x00000001; // user_config(_override).h
|
||||
feature2 |= 0x00000001; // user_config(_override).h
|
||||
#endif
|
||||
#ifdef FIRMWARE_MINIMAL
|
||||
feature_drv2 |= 0x00000002; // user_config(_override).h
|
||||
feature2 |= 0x00000002; // user_config(_override).h
|
||||
#endif
|
||||
#ifdef FIRMWARE_SENSORS
|
||||
feature_drv2 |= 0x00000004; // user_config(_override).h
|
||||
feature2 |= 0x00000004; // user_config(_override).h
|
||||
#endif
|
||||
#ifdef FIRMWARE_CLASSIC
|
||||
feature_drv2 |= 0x00000008; // user_config(_override).h
|
||||
feature2 |= 0x00000008; // user_config(_override).h
|
||||
#endif
|
||||
#ifdef FIRMWARE_KNX_NO_EMULATION
|
||||
feature_drv2 |= 0x00000010; // user_config(_override).h
|
||||
feature2 |= 0x00000010; // user_config(_override).h
|
||||
#endif
|
||||
#if defined(USE_DISPLAY) && defined(USE_DISPLAY_MODES1TO5)
|
||||
feature_drv2 |= 0x00000020; // xdrv_13_display.ino
|
||||
feature2 |= 0x00000020; // xdrv_13_display.ino
|
||||
#endif
|
||||
#if defined(USE_DISPLAY) && defined(USE_DISPLAY_GRAPH)
|
||||
feature_drv2 |= 0x00000040; // xdrv_13_display.ino
|
||||
feature2 |= 0x00000040; // xdrv_13_display.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_LCD)
|
||||
feature_drv2 |= 0x00000080; // xdsp_01_lcd.ino
|
||||
feature2 |= 0x00000080; // xdsp_01_lcd.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SSD1306)
|
||||
feature_drv2 |= 0x00000100; // xdsp_02_ssd1306.ino
|
||||
feature2 |= 0x00000100; // xdsp_02_ssd1306.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_MATRIX)
|
||||
feature_drv2 |= 0x00000200; // xdsp_03_matrix.ino
|
||||
feature2 |= 0x00000200; // xdsp_03_matrix.ino
|
||||
#endif
|
||||
#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_ILI9341)
|
||||
feature_drv2 |= 0x00000400; // xdsp_04_ili9341.ino
|
||||
feature2 |= 0x00000400; // xdsp_04_ili9341.ino
|
||||
#endif
|
||||
#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_EPAPER_29)
|
||||
feature_drv2 |= 0x00000800; // xdsp_05_epaper.ino
|
||||
feature2 |= 0x00000800; // xdsp_05_epaper.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SH1106)
|
||||
feature_drv2 |= 0x00001000; // xdsp_06_sh1106.ino
|
||||
feature2 |= 0x00001000; // xdsp_06_sh1106.ino
|
||||
#endif
|
||||
#ifdef USE_MP3_PLAYER
|
||||
feature_drv2 |= 0x00002000; // xdrv_14_mp3.ino
|
||||
feature2 |= 0x00002000; // xdrv_14_mp3.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_PCA9685)
|
||||
feature_drv2 |= 0x00004000; // xdrv_15_pca9685.ino
|
||||
feature2 |= 0x00004000; // xdrv_15_pca9685.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_TUYA_MCU)
|
||||
feature_drv2 |= 0x00008000; // xdrv_16_tuyadimmer.ino
|
||||
feature2 |= 0x00008000; // xdrv_16_tuyadimmer.ino
|
||||
#endif
|
||||
#ifdef USE_RC_SWITCH
|
||||
feature_drv2 |= 0x00010000; // xdrv_17_rcswitch.ino
|
||||
feature2 |= 0x00010000; // xdrv_17_rcswitch.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_ARMTRONIX_DIMMERS)
|
||||
feature_drv2 |= 0x00020000; // xdrv_18_armtronixdimmer.ino
|
||||
feature2 |= 0x00020000; // xdrv_18_armtronixdimmer.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_SM16716)
|
||||
feature_drv2 |= 0x00040000; // xdrv_04_light.ino
|
||||
feature2 |= 0x00040000; // xdrv_04_light.ino
|
||||
#endif
|
||||
#ifdef USE_SCRIPT
|
||||
feature_drv2 |= 0x00080000; // xdrv_10_scripter.ino
|
||||
feature2 |= 0x00080000; // xdrv_10_scripter.ino
|
||||
#endif
|
||||
#if defined(USE_WEBSERVER) && defined(USE_EMULATION_WEMO)
|
||||
feature_drv2 |= 0x00100000; // xdrv_21_wemo.ino
|
||||
feature2 |= 0x00100000; // xdrv_21_wemo.ino
|
||||
#endif
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
feature_drv2 |= 0x00200000; // xdrv_22_sonoff_ifan.ino
|
||||
feature2 |= 0x00200000; // xdrv_22_sonoff_ifan.ino
|
||||
#endif
|
||||
#ifdef USE_ZIGBEE
|
||||
feature_drv2 |= 0x00400000; // xdrv_23_zigbee.ino
|
||||
feature2 |= 0x00400000; // xdrv_23_zigbee.ino
|
||||
#endif
|
||||
#ifdef NO_EXTRA_4K_HEAP
|
||||
feature_drv2 |= 0x00800000; // sonoff_post.h
|
||||
feature2 |= 0x00800000; // sonoff_post.h
|
||||
#endif
|
||||
#ifdef VTABLES_IN_IRAM
|
||||
feature_drv2 |= 0x01000000; // platformio.ini
|
||||
feature2 |= 0x01000000; // platformio.ini
|
||||
#endif
|
||||
#ifdef VTABLES_IN_DRAM
|
||||
feature_drv2 |= 0x02000000; // platformio.ini
|
||||
feature2 |= 0x02000000; // platformio.ini
|
||||
#endif
|
||||
#ifdef VTABLES_IN_FLASH
|
||||
feature_drv2 |= 0x04000000; // platformio.ini
|
||||
feature2 |= 0x04000000; // platformio.ini
|
||||
#endif
|
||||
#ifdef PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
|
||||
feature_drv2 |= 0x08000000; // platformio.ini
|
||||
feature2 |= 0x08000000; // platformio.ini
|
||||
#endif
|
||||
#ifdef PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
|
||||
feature_drv2 |= 0x10000000; // platformio.ini
|
||||
feature2 |= 0x10000000; // platformio.ini
|
||||
#endif
|
||||
#ifdef PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||
feature_drv2 |= 0x20000000; // platformio.ini
|
||||
feature2 |= 0x20000000; // platformio.ini
|
||||
#endif
|
||||
#ifdef DEBUG_THEO
|
||||
feature_drv2 |= 0x40000000; // xdrv_99_debug.ino
|
||||
feature2 |= 0x40000000; // xdrv_99_debug.ino
|
||||
#endif
|
||||
#ifdef USE_DEBUG_DRIVER
|
||||
feature_drv2 |= 0x80000000; // xdrv_99_debug.ino
|
||||
feature2 |= 0x80000000; // xdrv_99_debug.ino
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
feature_sns1 = 0x00000000;
|
||||
|
||||
static uint32_t feature3 = 0x00000000;
|
||||
if (!feature3) { // Only fill this once
|
||||
#ifdef USE_COUNTER
|
||||
feature_sns1 |= 0x00000001; // xsns_01_counter.ino
|
||||
feature3 |= 0x00000001; // xsns_01_counter.ino
|
||||
#endif
|
||||
#if defined(USE_ADC_VCC) || defined(USE_ADC)
|
||||
feature_sns1 |= 0x00000002; // xsns_02_analog.ino
|
||||
feature3 |= 0x00000002; // xsns_02_analog.ino
|
||||
#endif
|
||||
#ifdef USE_ENERGY_SENSOR
|
||||
feature_sns1 |= 0x00000004; // xdrv_03_energy.ino
|
||||
feature3 |= 0x00000004; // xdrv_03_energy.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM004T)
|
||||
feature_sns1 |= 0x00000008; // xnrg_03_pzem004t.ino
|
||||
feature3 |= 0x00000008; // xnrg_03_pzem004t.ino
|
||||
#endif
|
||||
#ifdef USE_DS18B20
|
||||
feature_sns1 |= 0x00000010; // xsns_05_ds18b20.ino - no more support since 6.6.0.18
|
||||
feature3 |= 0x00000010; // xsns_05_ds18b20.ino - no more support since 6.6.0.18
|
||||
#endif
|
||||
#ifdef USE_DS18x20_LEGACY
|
||||
feature_sns1 |= 0x00000020; // xsns_05_ds18x20_legacy.ino - no more support since 6.6.0.14
|
||||
feature3 |= 0x00000020; // xsns_05_ds18x20_legacy.ino - no more support since 6.6.0.14
|
||||
#endif
|
||||
#ifdef USE_DS18x20
|
||||
feature_sns1 |= 0x00000040; // xsns_05_ds18x20.ino
|
||||
feature3 |= 0x00000040; // xsns_05_ds18x20.ino
|
||||
#endif
|
||||
#ifdef USE_DHT
|
||||
feature_sns1 |= 0x00000080; // xsns_06_dht.ino
|
||||
feature3 |= 0x00000080; // xsns_06_dht.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_SHT)
|
||||
feature_sns1 |= 0x00000100; // xsns_07_sht1x.ino
|
||||
feature3 |= 0x00000100; // xsns_07_sht1x.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_HTU)
|
||||
feature_sns1 |= 0x00000200; // xsns_08_htu21.ino
|
||||
feature3 |= 0x00000200; // xsns_08_htu21.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_BMP)
|
||||
feature_sns1 |= 0x00000400; // xsns_09_bmp.ino
|
||||
feature3 |= 0x00000400; // xsns_09_bmp.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_BMP) && defined(USE_BME680)
|
||||
feature_sns1 |= 0x00000800; // xsns_09_bmp.ino - BME680
|
||||
feature3 |= 0x00000800; // xsns_09_bmp.ino - BME680
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_BH1750)
|
||||
feature_sns1 |= 0x00001000; // xsns_10_bh1750.ino
|
||||
feature3 |= 0x00001000; // xsns_10_bh1750.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_VEML6070)
|
||||
feature_sns1 |= 0x00002000; // xsns_11_veml6070.ino
|
||||
feature3 |= 0x00002000; // xsns_11_veml6070.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_ADS1115_I2CDEV)
|
||||
feature_sns1 |= 0x00004000; // xsns_12_ads1115_i2cdev.ino
|
||||
feature3 |= 0x00004000; // xsns_12_ads1115_i2cdev.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_ADS1115)
|
||||
feature_sns1 |= 0x00008000; // xsns_12_ads1115.ino
|
||||
feature3 |= 0x00008000; // xsns_12_ads1115.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_INA219)
|
||||
feature_sns1 |= 0x00010000; // xsns_13_ina219.ino
|
||||
feature3 |= 0x00010000; // xsns_13_ina219.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_SHT3X)
|
||||
feature_sns1 |= 0x00020000; // xsns_14_sht3x.ino
|
||||
feature3 |= 0x00020000; // xsns_14_sht3x.ino
|
||||
#endif
|
||||
#ifdef USE_MHZ19
|
||||
feature_sns1 |= 0x00040000; // xsns_15_mhz19.ino
|
||||
feature3 |= 0x00040000; // xsns_15_mhz19.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_TSL2561)
|
||||
feature_sns1 |= 0x00080000; // xsns_16_tsl2561.ino
|
||||
feature3 |= 0x00080000; // xsns_16_tsl2561.ino
|
||||
#endif
|
||||
#ifdef USE_SENSEAIR
|
||||
feature_sns1 |= 0x00100000; // xsns_17_senseair.ino
|
||||
feature3 |= 0x00100000; // xsns_17_senseair.ino
|
||||
#endif
|
||||
#ifdef USE_PMS5003
|
||||
feature_sns1 |= 0x00200000; // xsns_18_pms5003.ino
|
||||
feature3 |= 0x00200000; // xsns_18_pms5003.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MGS)
|
||||
feature_sns1 |= 0x00400000; // xsns_19_mgs.ino
|
||||
feature3 |= 0x00400000; // xsns_19_mgs.ino
|
||||
#endif
|
||||
#ifdef USE_NOVA_SDS
|
||||
feature_sns1 |= 0x00800000; // xsns_20_novasds.ino
|
||||
feature3 |= 0x00800000; // xsns_20_novasds.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_SGP30)
|
||||
feature_sns1 |= 0x01000000; // xsns_21_sgp30.ino
|
||||
feature3 |= 0x01000000; // xsns_21_sgp30.ino
|
||||
#endif
|
||||
#ifdef USE_SR04
|
||||
feature_sns1 |= 0x02000000; // xsns_22_sr04.ino
|
||||
feature3 |= 0x02000000; // xsns_22_sr04.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_SDM120)
|
||||
feature_sns1 |= 0x04000000; // xnrg_08_sdm120.ino
|
||||
feature3 |= 0x04000000; // xnrg_08_sdm120.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_SI1145)
|
||||
feature_sns1 |= 0x08000000; // xsns_24_si1145.ino
|
||||
feature3 |= 0x08000000; // xsns_24_si1145.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_SDM630)
|
||||
feature_sns1 |= 0x10000000; // xnrg_10_sdm630.ino
|
||||
feature3 |= 0x10000000; // xnrg_10_sdm630.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_LM75AD)
|
||||
feature_sns1 |= 0x20000000; // xsns_26_lm75ad.ino
|
||||
feature3 |= 0x20000000; // xsns_26_lm75ad.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_APDS9960)
|
||||
feature_sns1 |= 0x40000000; // xsns_27_apds9960.ino
|
||||
feature3 |= 0x40000000; // xsns_27_apds9960.ino
|
||||
#endif
|
||||
#ifdef USE_TM1638
|
||||
feature_sns1 |= 0x80000000; // xsns_28_tm1638.ino
|
||||
feature3 |= 0x80000000; // xsns_28_tm1638.ino
|
||||
#endif
|
||||
/*********************************************************************************************/
|
||||
|
||||
feature_sns2 = 0x00000000;
|
||||
}
|
||||
|
||||
static uint32_t feature4 = 0x00000000;
|
||||
if (!feature4) { // Only fill this once
|
||||
#if defined(USE_I2C) && defined(USE_MCP230xx)
|
||||
feature_sns2 |= 0x00000001; // xsns_29_mcp230xx.ino
|
||||
feature4 |= 0x00000001; // xsns_29_mcp230xx.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MPR121)
|
||||
feature_sns2 |= 0x00000002; // xsns_30_mpr121.ino
|
||||
feature4 |= 0x00000002; // xsns_30_mpr121.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_CCS811)
|
||||
feature_sns2 |= 0x00000004; // xsns_31_ccs811.ino
|
||||
feature4 |= 0x00000004; // xsns_31_ccs811.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MPU6050)
|
||||
feature_sns2 |= 0x00000008; // xsns_32_mpu6050.ino
|
||||
feature4 |= 0x00000008; // xsns_32_mpu6050.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_OUTPUT)
|
||||
feature_sns2 |= 0x00000010; // xsns_29_mcp230xx.ino
|
||||
feature4 |= 0x00000010; // xsns_29_mcp230xx.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_DISPLAYOUTPUT)
|
||||
feature_sns2 |= 0x00000020; // xsns_29_mcp230xx.ino
|
||||
feature4 |= 0x00000020; // xsns_29_mcp230xx.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_HLW8012)
|
||||
feature_sns2 |= 0x00000040; // xnrg_01_hlw8012.ino
|
||||
feature4 |= 0x00000040; // xnrg_01_hlw8012.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_CSE7766)
|
||||
feature_sns2 |= 0x00000080; // xnrg_02_cse7766.ino
|
||||
feature4 |= 0x00000080; // xnrg_02_cse7766.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_MCP39F501)
|
||||
feature_sns2 |= 0x00000100; // xnrg_04_mcp39f501.ino
|
||||
feature4 |= 0x00000100; // xnrg_04_mcp39f501.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM_AC)
|
||||
feature_sns2 |= 0x00000200; // xnrg_05_pzem_ac.ino
|
||||
feature4 |= 0x00000200; // xnrg_05_pzem_ac.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_DS3231)
|
||||
feature_sns2 |= 0x00000400; // xsns_33_ds3231.ino
|
||||
feature4 |= 0x00000400; // xsns_33_ds3231.ino
|
||||
#endif
|
||||
#ifdef USE_HX711
|
||||
feature_sns2 |= 0x00000800; // xsns_34_hx711.ino
|
||||
feature4 |= 0x00000800; // xsns_34_hx711.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM_DC)
|
||||
feature_sns2 |= 0x00001000; // xnrg_06_pzem_dc.ino
|
||||
feature4 |= 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
|
||||
feature4 |= 0x00002000; // xsns_35_tx20.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MGC3130)
|
||||
feature_sns2 |= 0x00004000; // xsns_36_mgc3130.ino
|
||||
feature4 |= 0x00004000; // xsns_36_mgc3130.ino
|
||||
#endif
|
||||
#ifdef USE_RF_SENSOR
|
||||
feature_sns2 |= 0x00008000; // xsns_37_rfsensor.ino
|
||||
feature4 |= 0x00008000; // xsns_37_rfsensor.ino
|
||||
#endif
|
||||
#if defined(USE_RF_SENSOR) && defined(USE_THEO_V2)
|
||||
feature_sns2 |= 0x00010000; // xsns_37_rfsensor.ino
|
||||
feature4 |= 0x00010000; // xsns_37_rfsensor.ino
|
||||
#endif
|
||||
#if defined(USE_RF_SENSOR) && defined(USE_ALECTO_V2)
|
||||
feature_sns2 |= 0x00020000; // xsns_37_rfsensor.ino
|
||||
feature4 |= 0x00020000; // xsns_37_rfsensor.ino
|
||||
#endif
|
||||
#ifdef USE_AZ7798
|
||||
feature_sns2 |= 0x00040000; // xsns_38_az7798.ino
|
||||
feature4 |= 0x00040000; // xsns_38_az7798.ino
|
||||
#endif
|
||||
#ifdef USE_MAX31855
|
||||
feature_sns2 |= 0x00080000; // xsns_39_max31855.ino
|
||||
feature4 |= 0x00080000; // xsns_39_max31855.ino
|
||||
#endif
|
||||
#ifdef USE_PN532_HSU
|
||||
feature_sns2 |= 0x00100000; // xsns_40_pn532.ino
|
||||
feature4 |= 0x00100000; // xsns_40_pn532.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MAX44009)
|
||||
feature_sns2 |= 0x00200000; // xsns_41_max44009.ino
|
||||
feature4 |= 0x00200000; // xsns_41_max44009.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_SCD30)
|
||||
feature_sns2 |= 0x00400000; // xsns_42_scd30.ino
|
||||
feature4 |= 0x00400000; // xsns_42_scd30.ino
|
||||
#endif
|
||||
#ifdef USE_HRE
|
||||
feature_sns2 |= 0x00800000; // xsns_43_hre.ino
|
||||
feature4 |= 0x00800000; // xsns_43_hre.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_ADE7953)
|
||||
feature_sns2 |= 0x01000000; // xnrg_07_ade7953.ino
|
||||
feature4 |= 0x01000000; // xnrg_07_ade7953.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_SPS30)
|
||||
feature_sns2 |= 0x02000000; // xsns_44_sps30.ino
|
||||
feature4 |= 0x02000000; // xsns_44_sps30.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_VL53L0X)
|
||||
feature_sns2 |= 0x04000000; // xsns_45_vl53l0x.ino
|
||||
feature4 |= 0x04000000; // xsns_45_vl53l0x.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MLX90614)
|
||||
feature_sns2 |= 0x08000000; // xsns_46_MLX90614.ino
|
||||
feature4 |= 0x08000000; // xsns_46_MLX90614.ino
|
||||
#endif
|
||||
#ifdef USE_MAX31865
|
||||
feature_sns2 |= 0x10000000; // xsns_47-max31865.ino
|
||||
feature4 |= 0x10000000; // xsns_47-max31865.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_CHIRP)
|
||||
feature_sns2 |= 0x20000000; // xsns_48_chirp.ino
|
||||
feature4 |= 0x20000000; // xsns_48_chirp.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_SOLAX_X1)
|
||||
feature_sns2 |= 0x40000000; // xnrg_12_solaxX1.ino
|
||||
feature4 |= 0x40000000; // xnrg_12_solaxX1.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_PAJ7620)
|
||||
feature_sns2 |= 0x80000000; // xsns_50_paj7620.ino
|
||||
feature4 |= 0x80000000; // xsns_50_paj7620.ino
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
feature5 = 0x00000000;
|
||||
|
||||
static uint32_t feature5 = 0x00000000;
|
||||
if (!feature5) { // Only fill this once
|
||||
#ifdef USE_BUZZER
|
||||
feature5 |= 0x00000001; // xdrv_24_buzzer.ino
|
||||
feature5 |= 0x00000001; // xdrv_24_buzzer.ino
|
||||
#endif
|
||||
#ifdef USE_RDM6300
|
||||
feature5 |= 0x00000002; // xsns_51_rdm6300.ino
|
||||
feature5 |= 0x00000002; // xsns_51_rdm6300.ino
|
||||
#endif
|
||||
#ifdef USE_IBEACON
|
||||
feature5 |= 0x00000004; // xsns_52_ibeacon.ino
|
||||
feature5 |= 0x00000004; // xsns_52_ibeacon.ino
|
||||
#endif
|
||||
#ifdef USE_SML_M
|
||||
feature5 |= 0x00000008; // xsns_53_sml.ino
|
||||
feature5 |= 0x00000008; // xsns_53_sml.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_INA226)
|
||||
feature5 |= 0x00000010; // xsns_54_ina226.ino
|
||||
feature5 |= 0x00000010; // xsns_54_ina226.ino
|
||||
#endif
|
||||
#ifdef USE_A4988_STEPPER
|
||||
feature5 |= 0x00000020; // xdrv_25_A4988.ino
|
||||
feature5 |= 0x00000020; // xdrv_25_A4988.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_DDS2382)
|
||||
feature5 |= 0x00000040; // xnrg_09_dds2382.ino
|
||||
feature5 |= 0x00000040; // xnrg_09_dds2382.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_SM2135)
|
||||
feature5 |= 0x00000080; // xdrv_026_sm2135.ino
|
||||
feature5 |= 0x00000080; // xdrv_026_sm2135.ino
|
||||
#endif
|
||||
#ifdef USE_SHUTTER
|
||||
feature5 |= 0x00000100; // xdrv_027_shutter.ino
|
||||
feature5 |= 0x00000100; // xdrv_027_shutter.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_PCF8574)
|
||||
feature5 |= 0x00000200; // xdrv_028_pcf8574.ino
|
||||
feature5 |= 0x00000200; // xdrv_028_pcf8574.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_DDSU666)
|
||||
feature5 |= 0x00000400; // xnrg_11_ddsu666.ino
|
||||
feature5 |= 0x00000400; // xnrg_11_ddsu666.ino
|
||||
#endif
|
||||
#ifdef USE_DEEPSLEEP
|
||||
feature5 |= 0x00000800; // xdrv_029_deepsleep.ino
|
||||
feature5 |= 0x00000800; // xdrv_029_deepsleep.ino
|
||||
#endif
|
||||
#ifdef USE_SONOFF_SC
|
||||
feature5 |= 0x00001000; // xsns_04_snfsc.ino
|
||||
feature5 |= 0x00001000; // xsns_04_snfsc.ino
|
||||
#endif
|
||||
#ifdef USE_SONOFF_RF
|
||||
feature5 |= 0x00002000; // xdrv_06_snfbridge.ino
|
||||
feature5 |= 0x00002000; // xdrv_06_snfbridge.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_SONOFF_L1)
|
||||
feature5 |= 0x00004000; // xlgt_05_sonoff_l1.ino
|
||||
feature5 |= 0x00004000; // xlgt_05_sonoff_l1.ino
|
||||
#endif
|
||||
#if defined(USE_LIGHT) && defined(USE_EXS_DIMMER)
|
||||
feature5 |= 0x00008000; // xdrv_30_exs_dimmer.ino
|
||||
feature5 |= 0x00008000; // xdrv_30_exs_dimmer.ino
|
||||
#endif
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
feature5 |= 0x00010000; // xdrv_31_tasmota_client.ino
|
||||
feature5 |= 0x00010000; // xdrv_31_tasmota_client.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_HIH6)
|
||||
feature5 |= 0x00020000; // xsns_55_hih_series.ino
|
||||
feature5 |= 0x00020000; // xsns_55_hih_series.ino
|
||||
#endif
|
||||
#ifdef USE_HPMA
|
||||
feature5 |= 0x00040000; // xsns_56_hpma.ino
|
||||
feature5 |= 0x00040000; // xsns_56_hpma.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_TSL2591)
|
||||
feature5 |= 0x00080000; // xsns_57_tsl2591.ino
|
||||
feature5 |= 0x00080000; // xsns_57_tsl2591.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_DHT12)
|
||||
feature5 |= 0x00100000; // xsns_58_dht12.ino
|
||||
feature5 |= 0x00100000; // xsns_58_dht12.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_DS1624)
|
||||
feature5 |= 0x00200000; // xsns_59_ds1624.ino
|
||||
feature5 |= 0x00200000; // xsns_59_ds1624.ino
|
||||
#endif
|
||||
#ifdef USE_GPS
|
||||
feature5 |= 0x00400000; // xsns_60_GPS.ino
|
||||
feature5 |= 0x00400000; // xsns_60_GPS.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_HOTPLUG)
|
||||
feature5 |= 0x00800000; // xdrv_32_hotplug.ino
|
||||
feature5 |= 0x00800000; // xdrv_32_hotplug.ino
|
||||
#endif
|
||||
#ifdef USE_NRF24
|
||||
feature5 |= 0x01000000; // xsns_33_nrf24l01.ino
|
||||
feature5 |= 0x01000000; // xsns_33_nrf24l01.ino
|
||||
#endif
|
||||
#ifdef USE_MIBLE
|
||||
feature5 |= 0x02000000; // xsns_61_MI_BLE.ino
|
||||
feature5 |= 0x02000000; // xsns_61_MI_BLE.ino
|
||||
#endif
|
||||
#ifdef USE_HM10
|
||||
feature5 |= 0x04000000; // xsns_62_MI_HM10.ino
|
||||
feature5 |= 0x04000000; // xsns_62_MI_HM10.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_LE01MR)
|
||||
feature5 |= 0x08000000; // xnrg_13_fif_le01mr.ino
|
||||
feature5 |= 0x08000000; // xnrg_13_fif_le01mr.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_AHT1x)
|
||||
feature5 |= 0x10000000; // xsns_63_aht1x.ino
|
||||
feature5 |= 0x10000000; // xsns_63_aht1x.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_WEMOS_MOTOR_V1)
|
||||
feature5 |= 0x20000000; // xdrv_34_wemos_motor_v1.ino
|
||||
feature5 |= 0x20000000; // xdrv_34_wemos_motor_v1.ino
|
||||
#endif
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
feature5 |= 0x40000000; // support_device_groups.ino
|
||||
feature5 |= 0x40000000; // support_device_groups.ino
|
||||
#endif
|
||||
#ifdef USE_PWM_DIMMER
|
||||
feature5 |= 0x80000000; // xdrv_35_pwm_dimmer
|
||||
feature5 |= 0x80000000; // xdrv_35_pwm_dimmer
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
feature6 = 0x00000000;
|
||||
|
||||
static uint32_t feature6 = 0x00000000;
|
||||
if (!feature6) { // Only fill this once
|
||||
#ifdef USE_KEELOQ
|
||||
feature6 |= 0x00000001; // xdrv_36_keeloq.ino
|
||||
feature6 |= 0x00000001; // xdrv_36_keeloq.ino
|
||||
#endif
|
||||
#ifdef USE_HRXL
|
||||
feature6 |= 0x00000002; // xsns_64_hrxl.ino
|
||||
feature6 |= 0x00000002; // xsns_64_hrxl.ino
|
||||
#endif
|
||||
#ifdef USE_SONOFF_D1
|
||||
feature6 |= 0x00000004; // xdrv_37_sonoff_d1.ino
|
||||
feature6 |= 0x00000004; // xdrv_37_sonoff_d1.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_HDC1080)
|
||||
feature6 |= 0x00000008; // xsns_65_hdc1080.ino
|
||||
feature6 |= 0x00000008; // xsns_65_hdc1080.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_IAQ)
|
||||
feature6 |= 0x00000010; // xsns_66_iAQ.ino
|
||||
feature6 |= 0x00000010; // xsns_66_iAQ.ino
|
||||
#endif
|
||||
#if defined(USE_DISPLAY) && defined(USE_DISPLAY_SEVENSEG)
|
||||
feature6 |= 0x00000020; // xdsp_11_sevenseg.ino
|
||||
feature6 |= 0x00000020; // xdsp_11_sevenseg.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_AS3935)
|
||||
feature6 |= 0x00000040; // xsns_67_as3935.ino
|
||||
feature6 |= 0x00000040; // xsns_67_as3935.ino
|
||||
#endif
|
||||
#ifdef USE_PING
|
||||
feature6 |= 0x00000080; // xdrv_38_ping.ino
|
||||
feature6 |= 0x00000080; // xdrv_38_ping.ino
|
||||
#endif
|
||||
#ifdef USE_WINDMETER
|
||||
feature6 |= 0x00000100; // xsns_68_windmeter.ino
|
||||
feature6 |= 0x00000100; // xsns_68_windmeter.ino
|
||||
#endif
|
||||
#ifdef USE_OPENTHERM
|
||||
feature6 |= 0x00000200; // xsns_69_opentherm.ino
|
||||
feature6 |= 0x00000200; // xsns_69_opentherm.ino
|
||||
#endif
|
||||
#ifdef USE_THERMOSTAT
|
||||
feature6 |= 0x00000400; // xdrv_39_heating.ino
|
||||
feature6 |= 0x00000400; // xdrv_39_heating.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_VEML6075)
|
||||
feature6 |= 0x00000800; // xsns_70_veml6075.ino
|
||||
feature6 |= 0x00000800; // xsns_70_veml6075.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_VEML7700)
|
||||
feature6 |= 0x00001000; // xsns_71_veml7700.ino
|
||||
feature6 |= 0x00001000; // xsns_71_veml7700.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_MCP9808)
|
||||
feature6 |= 0x00002000; // xsns_72_mcp9808.ino
|
||||
feature6 |= 0x00002000; // xsns_72_mcp9808.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_BL0940)
|
||||
feature6 |= 0x00004000; // xnrg_14_bl0940.ino
|
||||
feature6 |= 0x00004000; // xnrg_14_bl0940.ino
|
||||
#endif
|
||||
#ifdef USE_TELEGRAM
|
||||
feature6 |= 0x00008000; // xdrv_40_telegram.ino
|
||||
feature6 |= 0x00008000; // xdrv_40_telegram.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_HP303B)
|
||||
feature6 |= 0x00010000; // xsns_73_hp303b.ino
|
||||
feature6 |= 0x00010000; // xsns_73_hp303b.ino
|
||||
#endif
|
||||
#ifdef USE_TCP_BRIDGE
|
||||
feature6 |= 0x00020000; // xdrv_41_tcp_bridge.ino
|
||||
feature6 |= 0x00020000; // xdrv_41_tcp_bridge.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_TELEINFO)
|
||||
feature6 |= 0x00040000; // xnrg_15_teleinfo.ino
|
||||
feature6 |= 0x00040000; // xnrg_15_teleinfo.ino
|
||||
#endif
|
||||
#ifdef USE_LMT01
|
||||
feature6 |= 0x00080000; // xsns_74_lmt01.ino
|
||||
feature6 |= 0x00080000; // xsns_74_lmt01.ino
|
||||
#endif
|
||||
#ifdef USE_PROMETHEUS
|
||||
feature6 |= 0x00100000; // xsns_75_prometheus.ino
|
||||
feature6 |= 0x00100000; // xsns_75_prometheus.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_IEM3000)
|
||||
feature6 |= 0x00200000; // xnrg_16_iem3000.ino
|
||||
feature6 |= 0x00200000; // xnrg_16_iem3000.ino
|
||||
#endif
|
||||
#ifdef USE_DYP
|
||||
feature6 |= 0x00400000; // xsns_76_dyp.ino
|
||||
feature6 |= 0x00400000; // xsns_76_dyp.ino
|
||||
#endif
|
||||
#ifdef USE_I2S_AUDIO
|
||||
feature6 |= 0x00800000; // xdrv_42_i2s_audio.ino
|
||||
feature6 |= 0x00800000; // xdrv_42_i2s_audio.ino
|
||||
#endif
|
||||
#ifdef USE_MLX90640
|
||||
feature6 |= 0x01000000; // xdrv_43_mlx90640.ino
|
||||
feature6 |= 0x01000000; // xdrv_43_mlx90640.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_VL53L1X)
|
||||
feature6 |= 0x02000000; // xsns_77_vl53l1x.ino
|
||||
feature6 |= 0x02000000; // xsns_77_vl53l1x.ino
|
||||
#endif
|
||||
#ifdef USE_MIEL_HVAC
|
||||
feature6 |= 0x04000000; // xdrv_44_miel_hvac.ino
|
||||
feature6 |= 0x04000000; // xdrv_44_miel_hvac.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_WE517)
|
||||
feature6 |= 0x08000000; // xnrg_17_ornowe517.ino
|
||||
feature6 |= 0x08000000; // xnrg_17_ornowe517.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOPH)
|
||||
feature6 |= 0x10000000; // xsns_78_ezoph.ino
|
||||
feature6 |= 0x10000000; // xsns_78_ezoph.ino
|
||||
#endif
|
||||
#if defined(ESP32) && defined(USE_TTGO_WATCH)
|
||||
feature6 |= 0x20000000; // xdrv_83_esp32watch.ino
|
||||
feature6 |= 0x20000000; // xdrv_83_esp32watch.ino
|
||||
#endif
|
||||
#if defined(ESP32) && defined(USE_ETHERNET)
|
||||
feature6 |= 0x40000000; // xdrv_82_ethernet.ino
|
||||
feature6 |= 0x40000000; // xdrv_82_ethernet.ino
|
||||
#endif
|
||||
#if defined(ESP32) && defined(USE_WEBCAM)
|
||||
feature6 |= 0x80000000; // xdrv_81_webcam.ino
|
||||
feature6 |= 0x80000000; // xdrv_81_webcam.ino
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t feature7 = 0x00000000;
|
||||
if (!feature7) { // Only fill this once
|
||||
#if defined(USE_I2C) && defined(USE_EZOORP)
|
||||
feature7 |= 0x00000001; // xsns_78_ezoorp.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZORTD)
|
||||
feature7 |= 0x00000002; // xsns_78_ezortd.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOHUM)
|
||||
feature7 |= 0x00000004; // xsns_78_ezohum.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOEC)
|
||||
feature7 |= 0x00000008; // xsns_78_ezoec.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOCO2)
|
||||
feature7 |= 0x00000010; // xsns_78_ezoco2.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOO2)
|
||||
feature7 |= 0x00000020; // xsns_78_ezoo2.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOPRS)
|
||||
feature7 |= 0x00000040; // xsns_78_ezoprs.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOFLO)
|
||||
feature7 |= 0x00000080;
|
||||
#endif
|
||||
|
||||
// feature7 |= 0x00000100;
|
||||
// feature7 |= 0x00000200;
|
||||
// feature7 |= 0x00000400;
|
||||
// feature7 |= 0x00000800;
|
||||
|
||||
// feature7 |= 0x00001000;
|
||||
// feature7 |= 0x00002000;
|
||||
// feature7 |= 0x00004000;
|
||||
// feature7 |= 0x00008000;
|
||||
|
||||
// feature7 |= 0x00010000;
|
||||
// feature7 |= 0x00020000;
|
||||
// feature7 |= 0x00040000;
|
||||
// feature7 |= 0x00080000;
|
||||
|
||||
// feature7 |= 0x00100000;
|
||||
// feature7 |= 0x00200000;
|
||||
// feature7 |= 0x00400000;
|
||||
// feature7 |= 0x00800000;
|
||||
|
||||
// feature7 |= 0x01000000;
|
||||
// feature7 |= 0x02000000;
|
||||
// feature7 |= 0x04000000;
|
||||
// feature7 |= 0x08000000;
|
||||
|
||||
// feature7 |= 0x10000000;
|
||||
// feature7 |= 0x20000000;
|
||||
// feature7 |= 0x40000000;
|
||||
// feature7 |= 0x80000000;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
feature7 = 0x00000000;
|
||||
|
||||
#if defined(USE_I2C) && defined(USE_EZOORP)
|
||||
feature7 |= 0x00000001; // xsns_78_ezoorp.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZORTD)
|
||||
feature7 |= 0x00000002; // xsns_78_ezortd.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOHUM)
|
||||
feature7 |= 0x00000004; // xsns_78_ezohum.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOEC)
|
||||
feature7 |= 0x00000008; // xsns_78_ezoec.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_EZOCO2)
|
||||
feature7 |= 0x00000010;
|
||||
#endif
|
||||
// feature7 |= 0x00000020;
|
||||
// feature7 |= 0x00000040;
|
||||
// feature7 |= 0x00000080;
|
||||
|
||||
// feature7 |= 0x00000100;
|
||||
// feature7 |= 0x00000200;
|
||||
// feature7 |= 0x00000400;
|
||||
// feature7 |= 0x00000800;
|
||||
|
||||
// feature7 |= 0x00001000;
|
||||
// feature7 |= 0x00002000;
|
||||
// feature7 |= 0x00004000;
|
||||
// feature7 |= 0x00008000;
|
||||
|
||||
// feature7 |= 0x00010000;
|
||||
// feature7 |= 0x00020000;
|
||||
// feature7 |= 0x00040000;
|
||||
// feature7 |= 0x00080000;
|
||||
|
||||
// feature7 |= 0x00100000;
|
||||
// feature7 |= 0x00200000;
|
||||
// feature7 |= 0x00400000;
|
||||
// feature7 |= 0x00800000;
|
||||
|
||||
// feature7 |= 0x01000000;
|
||||
// feature7 |= 0x02000000;
|
||||
// feature7 |= 0x04000000;
|
||||
// feature7 |= 0x08000000;
|
||||
|
||||
// feature7 |= 0x10000000;
|
||||
// feature7 |= 0x20000000;
|
||||
// feature7 |= 0x40000000;
|
||||
// feature7 |= 0x80000000;
|
||||
|
||||
|
||||
} // GetFeatures
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"),
|
||||
LANGUAGE_LCID, feature1, feature2, feature3, feature4, feature5, feature6, feature7);
|
||||
}
|
||||
|
||||
@ -397,7 +397,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(ssleep);
|
||||
delay(TasmotaGlobal.sleep);
|
||||
}
|
||||
k+=size;
|
||||
if(bytes_left>7){
|
||||
@ -416,7 +416,7 @@ void FLOG::stopRecording(void){
|
||||
_readSector(next_sector);
|
||||
bytes_left = sector.header.buf_pointer - sizeof(sector.header);
|
||||
OsWatchLoop();
|
||||
delay(ssleep);
|
||||
delay(TasmotaGlobal.sleep);
|
||||
}
|
||||
running_download = false;
|
||||
// Callback 3: create a footer or simply finish the download with an empty payload
|
||||
|
||||
@ -27,16 +27,18 @@ struct {
|
||||
|
||||
#ifdef USE_DISCOVERY
|
||||
void StartMdns(void) {
|
||||
// static uint8_t mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
|
||||
|
||||
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);
|
||||
// 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(TasmotaGlobal.hostname);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Mdns.begun) ? D_INITIALIZED : D_FAILED);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -92,18 +94,18 @@ void MdnsUpdate(void) {
|
||||
char* NetworkHostname(void) {
|
||||
#ifdef ESP32
|
||||
#ifdef USE_ETHERNET
|
||||
if (!global_state.eth_down) {
|
||||
if (!TasmotaGlobal.global_state.eth_down) {
|
||||
return EthernetHostname();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return my_hostname;
|
||||
return TasmotaGlobal.hostname;
|
||||
}
|
||||
|
||||
IPAddress NetworkAddress(void) {
|
||||
#ifdef ESP32
|
||||
#ifdef USE_ETHERNET
|
||||
if (!global_state.eth_down) {
|
||||
if (!TasmotaGlobal.global_state.eth_down) {
|
||||
return EthernetLocalIP();
|
||||
}
|
||||
#endif
|
||||
@ -114,7 +116,7 @@ IPAddress NetworkAddress(void) {
|
||||
String NetworkMacAddress(void) {
|
||||
#ifdef ESP32
|
||||
#ifdef USE_ETHERNET
|
||||
if (!global_state.eth_down) {
|
||||
if (!TasmotaGlobal.global_state.eth_down) {
|
||||
return EthernetMacAddress();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -81,7 +81,7 @@ bool RotaryButtonPressed(uint32_t button_index) {
|
||||
if (-1 == Encoder[index].pinb) { continue; }
|
||||
if (index != button_index) { continue; }
|
||||
|
||||
bool powered_on = (power);
|
||||
bool powered_on = (TasmotaGlobal.power);
|
||||
#ifdef USE_LIGHT
|
||||
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||
powered_on = LightPower();
|
||||
@ -126,7 +126,7 @@ void RotaryInit(void) {
|
||||
Rotary.present = false;
|
||||
Rotary.model = 1;
|
||||
#ifdef ESP8266
|
||||
if (MI_DESK_LAMP == my_module_type) {
|
||||
if (MI_DESK_LAMP == TasmotaGlobal.module_type) {
|
||||
Rotary.model = 0;
|
||||
}
|
||||
#endif // ESP8266
|
||||
@ -180,8 +180,8 @@ void RotaryHandler(void) {
|
||||
Encoder[index].position = rotary_offset;
|
||||
interrupts();
|
||||
|
||||
if (Settings.save_data && (save_data_counter < 2)) {
|
||||
save_data_counter = 3; // Postpone flash writes while rotary is turned
|
||||
if (Settings.save_data && (TasmotaGlobal.save_data_counter < 2)) {
|
||||
TasmotaGlobal.save_data_counter = 3; // Postpone flash writes while rotary is turned
|
||||
}
|
||||
|
||||
bool button_pressed = (Button.hold_timer[index]); // Button is pressed: set color temperature
|
||||
@ -202,7 +202,7 @@ void RotaryHandler(void) {
|
||||
}
|
||||
} else { // Dimmer RGBCW or RGB only if second rotary
|
||||
uint32_t dimmer_index = second_rotary ? 1 : 0;
|
||||
if (!Settings.flag4.rotary_poweron_dimlow || power) { // SetOption113 - On rotary dial after power off set dimmer low
|
||||
if (!Settings.flag4.rotary_poweron_dimlow || TasmotaGlobal.power) { // SetOption113 - On rotary dial after power off set dimmer low
|
||||
LightDimmerOffset(dimmer_index, rotary_position * rotary_dimmer_increment[Rotary.model]);
|
||||
} else {
|
||||
if (rotary_position > 0) { // Only power on if rotary increase
|
||||
|
||||
@ -225,7 +225,7 @@ uint32_t UpTime(void)
|
||||
if (Rtc.restart_time) {
|
||||
return Rtc.utc_time - Rtc.restart_time;
|
||||
} else {
|
||||
return uptime;
|
||||
return TasmotaGlobal.uptime;
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,23 +379,23 @@ void RtcSecond(void)
|
||||
Rtc.millis = millis();
|
||||
|
||||
if (!Rtc.user_time_entry) {
|
||||
if (!global_state.network_down) {
|
||||
uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59
|
||||
if (!TasmotaGlobal.global_state.network_down) {
|
||||
uint8_t uptime_minute = (TasmotaGlobal.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
|
||||
uint8_t offset = (TasmotaGlobal.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
|
||||
TasmotaGlobal.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;
|
||||
TasmotaGlobal.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
|
||||
Rtc.restart_time = Rtc.utc_time - TasmotaGlobal.uptime; // save first ntp time as restart time
|
||||
}
|
||||
BreakTime(Rtc.utc_time, tmpTime);
|
||||
RtcTime.year = tmpTime.year + 1970;
|
||||
@ -407,9 +407,9 @@ void RtcSecond(void)
|
||||
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;
|
||||
TasmotaGlobal.rules_flag.time_init = 1;
|
||||
} else {
|
||||
rules_flag.time_set = 1;
|
||||
TasmotaGlobal.rules_flag.time_set = 1;
|
||||
}
|
||||
} else {
|
||||
Rtc.ntp_sync_minute++; // Try again in next minute
|
||||
@ -476,7 +476,7 @@ void RtcSetTime(uint32_t epoch)
|
||||
{
|
||||
if (epoch < START_VALID_TIME) { // 2016-01-01
|
||||
Rtc.user_time_entry = false;
|
||||
ntp_force_sync = true;
|
||||
TasmotaGlobal.ntp_force_sync = true;
|
||||
sntp_init();
|
||||
} else {
|
||||
sntp_stop();
|
||||
|
||||
@ -194,14 +194,10 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if no NULL is found, returns length until the end of the buffer
|
||||
inline size_t strlen(const size_t offset) const {
|
||||
return strnlen((const char*) &_buf->buf[offset], len() - offset);
|
||||
}
|
||||
|
||||
size_t strlen_s(const size_t offset) const {
|
||||
size_t slen = this->strlen(offset);
|
||||
if (slen == len() - offset) {
|
||||
size_t strlen(const size_t offset) const {
|
||||
if (offset >= len()) { return 0; }
|
||||
size_t slen = strnlen((const char*) &_buf->buf[offset], len() - offset);
|
||||
if (slen == (len() - offset)) {
|
||||
return 0; // we didn't find a NULL char
|
||||
} else {
|
||||
return slen;
|
||||
|
||||
@ -40,7 +40,7 @@ const uint8_t AC_PERIOD = (20 + SWITCH_FAST_PROBE_INTERVAL - 1) / SWITCH_FAST_PR
|
||||
Ticker TickerSwitch;
|
||||
|
||||
struct SWITCH {
|
||||
unsigned long debounce = 0; // Switch debounce timer
|
||||
uint32_t debounce = 0; // Switch debounce timer
|
||||
uint16_t no_pullup_mask = 0; // Switch pull-up bitmask flags
|
||||
uint8_t state[MAX_SWITCHES] = { 0 };
|
||||
uint8_t last_state[MAX_SWITCHES]; // Last wall switch states
|
||||
@ -88,7 +88,7 @@ bool SwitchState(uint32_t index)
|
||||
|
||||
void SwitchProbe(void)
|
||||
{
|
||||
if (uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit
|
||||
if (TasmotaGlobal.uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit
|
||||
|
||||
uint8_t state_filter;
|
||||
uint8_t debounce_flags = Settings.switch_debounce % 10;
|
||||
@ -232,7 +232,7 @@ void SwitchInit(void)
|
||||
|
||||
void SwitchHandler(uint8_t mode)
|
||||
{
|
||||
if (uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit
|
||||
if (TasmotaGlobal.uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit
|
||||
|
||||
uint16_t loops_per_second = 1000 / Settings.switch_debounce;
|
||||
|
||||
@ -401,7 +401,7 @@ void SwitchHandler(uint8_t mode)
|
||||
}
|
||||
if (switchflag <= POWER_TOGGLE) {
|
||||
if (!SendKey(KEY_SWITCH, i +1, switchflag)) { // Execute command via MQTT
|
||||
ExecuteCommandPower(i +1, switchflag, SRC_SWITCH); // Execute command internally (if i < devices_present)
|
||||
ExecuteCommandPower(i +1, switchflag, SRC_SWITCH); // Execute command internally (if i < TasmotaGlobal.devices_present)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -79,7 +79,7 @@ bool UdpDisconnect(void)
|
||||
|
||||
bool UdpConnect(void)
|
||||
{
|
||||
if (!udp_connected && !restart_flag) {
|
||||
if (!udp_connected && !TasmotaGlobal.restart_flag) {
|
||||
// Simple Service Discovery Protocol (SSDP)
|
||||
#ifdef ESP8266
|
||||
UdpCtx.reset();
|
||||
@ -133,7 +133,7 @@ void PollUdp(void)
|
||||
#if defined(USE_SCRIPT_HUE) || defined(USE_ZIGBEE)
|
||||
if (!udp_response_mutex && (strstr_P(packet_buffer, PSTR("M-SEARCH")) != nullptr)) {
|
||||
#else
|
||||
if (devices_present && !udp_response_mutex && (strstr_P(packet_buffer, PSTR("M-SEARCH")) != nullptr)) {
|
||||
if (TasmotaGlobal.devices_present && !udp_response_mutex && (strstr_P(packet_buffer, PSTR("M-SEARCH")) != nullptr)) {
|
||||
#endif
|
||||
udp_response_mutex = true;
|
||||
|
||||
|
||||
@ -97,9 +97,9 @@ void WifiConfig(uint8_t type)
|
||||
|
||||
Wifi.config_counter = WIFI_CONFIG_SEC; // Allow up to WIFI_CONFIG_SECS seconds for phone to provide ssid/pswd
|
||||
Wifi.counter = Wifi.config_counter +5;
|
||||
blinks = 1999;
|
||||
TasmotaGlobal.blinks = 255;
|
||||
if (WIFI_RESTART == Wifi.config_type) {
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
else if (WIFI_SERIAL == Wifi.config_type) {
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_6_SERIAL " " D_ACTIVE_FOR_3_MINUTES));
|
||||
@ -153,7 +153,7 @@ void WiFiSetSleepMode(void)
|
||||
*/
|
||||
|
||||
// Sleep explanation: https://github.com/esp8266/Arduino/blob/3f0c601cfe81439ce17e9bd5d28994a7ed144482/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L255
|
||||
if (ssleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
|
||||
if (TasmotaGlobal.sleep && 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)
|
||||
@ -193,7 +193,7 @@ void WifiBegin(uint8_t flag, uint8_t channel)
|
||||
if (Settings.ip_address[0]) {
|
||||
WiFi.config(Settings.ip_address[0], Settings.ip_address[1], Settings.ip_address[2], Settings.ip_address[3]); // Set static IP
|
||||
}
|
||||
WiFi.hostname(my_hostname);
|
||||
WiFi.hostname(TasmotaGlobal.hostname);
|
||||
|
||||
char stemp[40] = { 0 };
|
||||
if (channel) {
|
||||
@ -205,7 +205,7 @@ void WifiBegin(uint8_t flag, uint8_t channel)
|
||||
WiFi.begin(SettingsText(SET_STASSID1 + Settings.sta_active), SettingsText(SET_STAPWD1 + Settings.sta_active));
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECTING_TO_AP "%d %s%s " D_IN_MODE " 11%c " D_AS " %s..."),
|
||||
Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), stemp, kWifiPhyMode[WiFi.getPhyMode() & 0x3], my_hostname);
|
||||
Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), stemp, kWifiPhyMode[WiFi.getPhyMode() & 0x3], TasmotaGlobal.hostname);
|
||||
|
||||
#if LWIP_IPV6
|
||||
for (bool configured = false; !configured;) {
|
||||
@ -331,19 +331,19 @@ String WifiDowntime(void)
|
||||
|
||||
void WifiSetState(uint8_t state)
|
||||
{
|
||||
if (state == global_state.wifi_down) {
|
||||
if (state == TasmotaGlobal.global_state.wifi_down) {
|
||||
if (state) {
|
||||
rules_flag.wifi_connected = 1;
|
||||
TasmotaGlobal.rules_flag.wifi_connected = 1;
|
||||
Wifi.link_count++;
|
||||
Wifi.downtime += UpTime() - Wifi.last_event;
|
||||
} else {
|
||||
rules_flag.wifi_disconnected = 1;
|
||||
TasmotaGlobal.rules_flag.wifi_disconnected = 1;
|
||||
Wifi.last_event = UpTime();
|
||||
}
|
||||
}
|
||||
global_state.wifi_down = state ^1;
|
||||
if (!global_state.wifi_down) {
|
||||
global_state.network_down = 0;
|
||||
TasmotaGlobal.global_state.wifi_down = state ^1;
|
||||
if (!TasmotaGlobal.global_state.wifi_down) {
|
||||
TasmotaGlobal.global_state.network_down = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,7 +503,7 @@ void WifiCheck(uint8_t param)
|
||||
}
|
||||
if (!Wifi.config_counter) {
|
||||
// SettingsSdkErase(); // Disabled v6.1.0b due to possible bad wifi connects
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
} else {
|
||||
if (Wifi.scan_state) { WifiBeginAfterScan(); }
|
||||
@ -520,7 +520,7 @@ void WifiCheck(uint8_t param)
|
||||
#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))) {
|
||||
if (!(TasmotaGlobal.uptime % (60 * WIFI_RESCAN_MINUTES))) {
|
||||
Wifi.scan_state = 2;
|
||||
}
|
||||
}
|
||||
@ -536,7 +536,7 @@ int WifiState(void)
|
||||
{
|
||||
int state = -1;
|
||||
|
||||
if (!global_state.wifi_down) { state = WIFI_RESTART; }
|
||||
if (!TasmotaGlobal.global_state.wifi_down) { state = WIFI_RESTART; }
|
||||
if (Wifi.config_type) { state = Wifi.config_type; }
|
||||
return state;
|
||||
}
|
||||
@ -641,7 +641,7 @@ void EspRestart(void)
|
||||
WifiShutdown(true);
|
||||
CrashDumpClear(); // Clear the stack dump in RTC
|
||||
|
||||
if (restart_halt) {
|
||||
if (TasmotaGlobal.restart_halt) {
|
||||
while (1) {
|
||||
OsWatchLoop(); // Feed OsWatch timer to prevent restart
|
||||
SetLedLink(1); // Wifi led on
|
||||
@ -666,8 +666,6 @@ extern "C" {
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long wifiTimer = 0;
|
||||
|
||||
void stationKeepAliveNow(void) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_WIFI "Sending Gratuitous ARP"));
|
||||
for (netif* interface = netif_list; interface != nullptr; interface = interface->next)
|
||||
@ -689,15 +687,17 @@ void stationKeepAliveNow(void) {
|
||||
}
|
||||
|
||||
void wifiKeepAlive(void) {
|
||||
uint32_t wifiTimerSec = Settings.param[P_ARP_GRATUITOUS]; // 8-bits number of seconds, or minutes if > 100
|
||||
static uint32_t wifi_timer = 0; // Wifi keepalive timer
|
||||
|
||||
uint32_t wifiTimerSec = Settings.param[P_ARP_GRATUITOUS]; // 8-bits number of seconds, or minutes if > 100
|
||||
|
||||
if ((WL_CONNECTED != Wifi.status) || (0 == wifiTimerSec)) { return; } // quick exit if wifi not connected or feature disabled
|
||||
|
||||
if (TimeReached(wifiTimer)) {
|
||||
if (TimeReached(wifi_timer)) {
|
||||
stationKeepAliveNow();
|
||||
if (wifiTimerSec > 100) {
|
||||
wifiTimerSec = (wifiTimerSec - 100) * 60; // convert >100 as minutes, ex: 105 = 5 minutes, 110 = 10 minutes
|
||||
wifiTimerSec = (wifiTimerSec - 100) * 60; // convert >100 as minutes, ex: 105 = 5 minutes, 110 = 10 minutes
|
||||
}
|
||||
SetNextTimeInterval(wifiTimer, wifiTimerSec * 1000);
|
||||
SetNextTimeInterval(wifi_timer, wifiTimerSec * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,6 +306,7 @@ enum SettingsTextIndex { SET_OTAURL,
|
||||
#else // ESP32
|
||||
SET_ADC_PARAM1, SET_ADC_PARAM2, SET_ADC_PARAM3, SET_ADC_PARAM4, SET_ADC_PARAM5, SET_ADC_PARAM6, SET_ADC_PARAM7, SET_ADC_PARAM8, // MAX_ADCS
|
||||
#endif
|
||||
SET_SWITCH_TXT1, SET_SWITCH_TXT2, SET_SWITCH_TXT3, SET_SWITCH_TXT4, SET_SWITCH_TXT5, SET_SWITCH_TXT6, SET_SWITCH_TXT7, SET_SWITCH_TXT8, // MAX_SWITCHES
|
||||
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, DGR_MSGTYPFLAG_WITH_LOCAL = 128 };
|
||||
@ -348,6 +349,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 };
|
||||
|
||||
#ifdef ESP8266
|
||||
const SerConfu8 kTasmotaSerialConfig[] PROGMEM = {
|
||||
SERIAL_5N1, SERIAL_6N1, SERIAL_7N1, SERIAL_8N1,
|
||||
SERIAL_5N2, SERIAL_6N2, SERIAL_7N2, SERIAL_8N2,
|
||||
@ -356,6 +358,16 @@ const SerConfu8 kTasmotaSerialConfig[] PROGMEM = {
|
||||
SERIAL_5O1, SERIAL_6O1, SERIAL_7O1, SERIAL_8O1,
|
||||
SERIAL_5O2, SERIAL_6O2, SERIAL_7O2, SERIAL_8O2
|
||||
};
|
||||
#else // ESP32
|
||||
const uint32_t 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,
|
||||
SERIAL_5E2, SERIAL_6E2, SERIAL_7E2, SERIAL_8E2,
|
||||
SERIAL_5O1, SERIAL_6O1, SERIAL_7O1, SERIAL_8O1,
|
||||
SERIAL_5O2, SERIAL_6O2, SERIAL_7O2, SERIAL_8O2
|
||||
};
|
||||
#endif
|
||||
|
||||
enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE,
|
||||
TUYA_MCU_FUNC_SWT1 = 1, TUYA_MCU_FUNC_SWT2, TUYA_MCU_FUNC_SWT3, TUYA_MCU_FUNC_SWT4,
|
||||
|
||||
@ -77,111 +77,105 @@
|
||||
|
||||
WiFiUDP PortUdp; // UDP Syslog and Alexa
|
||||
|
||||
unsigned long feature_drv1; // Compiled driver feature map
|
||||
unsigned long feature_drv2; // Compiled driver feature map
|
||||
unsigned long feature_sns1; // Compiled sensor feature map
|
||||
unsigned long feature_sns2; // Compiled sensor feature map
|
||||
unsigned long feature5; // Compiled feature map
|
||||
unsigned long feature6; // Compiled feature map
|
||||
unsigned long feature7; // Compiled feature map
|
||||
unsigned long serial_polling_window = 0; // Serial polling window
|
||||
unsigned long state_second = 0; // State second timer
|
||||
unsigned long state_50msecond = 0; // State 50msecond timer
|
||||
unsigned long state_100msecond = 0; // State 100msecond timer
|
||||
unsigned long state_250msecond = 0; // State 250msecond timer
|
||||
unsigned long pulse_timer[MAX_PULSETIMERS] = { 0 }; // Power off timer
|
||||
unsigned long blink_timer = 0; // Power cycle timer
|
||||
unsigned long backlog_delay = 0; // Command backlog delay
|
||||
power_t power = 0; // Current copy of Settings.power
|
||||
power_t last_power = 0; // Last power set state
|
||||
power_t blink_power; // Blink power state
|
||||
power_t blink_mask = 0; // Blink relay active mask
|
||||
power_t blink_powersave; // Blink start power save state
|
||||
power_t latching_power = 0; // Power state at latching start
|
||||
power_t rel_inverted = 0; // Relay inverted flag (1 = (0 = On, 1 = Off))
|
||||
int serial_in_byte_counter = 0; // Index in receive buffer
|
||||
int ota_state_flag = 0; // OTA state flag
|
||||
int ota_result = 0; // OTA result
|
||||
int restart_flag = 0; // Tasmota restart flag
|
||||
int wifi_state_flag = WIFI_RESTART; // Wifi state flag
|
||||
int blinks = 201; // Number of LED blinks
|
||||
uint32_t uptime = 0; // Counting every second until 4294967295 = 130 year
|
||||
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)
|
||||
uint32_t baudrate = APP_BAUDRATE; // Current Serial baudrate
|
||||
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
|
||||
uint16_t gpio_pin[MAX_GPIO_PIN] = { 0 }; // GPIO functions indexed by pin number
|
||||
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 ssleep; // Current copy of Settings.sleep
|
||||
uint8_t blinkspeed = 1; // LED blink rate
|
||||
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))
|
||||
uint8_t led_power = 0; // LED power state
|
||||
uint8_t ledlnk_inverted = 0; // Link LED inverted flag (1 = (0 = On, 1 = Off))
|
||||
uint8_t pwm_inverted = 0; // PWM inverted flag (1 = inverted)
|
||||
uint8_t energy_flg = 0; // Energy monitor configured
|
||||
uint8_t light_flg = 0; // Light module configured
|
||||
uint8_t light_type = 0; // Light types
|
||||
uint8_t serial_in_byte; // Received byte
|
||||
uint8_t ota_retry_counter = OTA_ATTEMPTS; // OTA retry counter
|
||||
uint8_t devices_present = 0; // Max number of devices supported
|
||||
uint8_t masterlog_level = 0; // Master log level used to override set log level
|
||||
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 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_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
|
||||
bool stop_flash_rotate = false; // Allow flash configuration rotation
|
||||
bool blinkstate = false; // LED state
|
||||
//bool latest_uptime_flag = true; // Signal latest uptime
|
||||
bool pwm_present = false; // Any PWM channel configured with SetOption15 0
|
||||
bool i2c_flg = false; // I2C configured
|
||||
bool spi_flg = false; // SPI configured
|
||||
bool soft_spi_flg = false; // Software SPI configured
|
||||
bool ntp_force_sync = false; // Force NTP sync
|
||||
bool is_8285 = false; // Hardware device ESP8266EX (0) or ESP8285 (1)
|
||||
bool skip_light_fade; // Temporarily skip light fading
|
||||
bool restart_halt = false; // Do not restart but stay in wait loop
|
||||
myio my_module; // Active copy of Module GPIOs (17 x 8 bits)
|
||||
StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits)
|
||||
char my_version[33]; // Composed version string
|
||||
char my_image[33]; // Code image and/or commit
|
||||
char my_hostname[33]; // Composed Wifi hostname
|
||||
char mqtt_client[TOPSZ]; // Composed MQTT Clientname
|
||||
char mqtt_topic[TOPSZ]; // Composed MQTT topic
|
||||
char serial_in_buffer[INPUT_BUFFER_SIZE]; // Receive buffer
|
||||
char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer
|
||||
char log_data[LOGSZ]; // Logging
|
||||
char web_log[WEB_LOG_SIZE] = {'\0'}; // Web log buffer
|
||||
struct {
|
||||
uint32_t global_update; // Timestamp of last global temperature and humidity update
|
||||
uint32_t baudrate; // Current Serial baudrate
|
||||
uint32_t pulse_timer[MAX_PULSETIMERS]; // Power off timer
|
||||
uint32_t blink_timer; // Power cycle timer
|
||||
uint32_t backlog_delay; // Command backlog delay
|
||||
uint32_t loop_load_avg; // Indicative loop load average
|
||||
uint32_t web_log_index; // Index in Web log buffer
|
||||
uint32_t uptime; // Counting every second until 4294967295 = 130 year
|
||||
|
||||
power_t power; // Current copy of Settings.power
|
||||
power_t rel_inverted; // Relay inverted flag (1 = (0 = On, 1 = Off))
|
||||
power_t last_power; // Last power set state
|
||||
power_t blink_power; // Blink power state
|
||||
power_t blink_powersave; // Blink start power save state
|
||||
power_t blink_mask; // Blink relay active mask
|
||||
|
||||
int serial_in_byte_counter; // Index in receive buffer
|
||||
|
||||
float temperature_celsius; // Provide a global temperature to be used by some sensors
|
||||
float humidity; // Provide a global humidity to be used by some sensors
|
||||
float pressure_hpa; // Provide a global pressure to be used by some sensors
|
||||
|
||||
uint16_t gpio_pin[MAX_GPIO_PIN]; // GPIO functions indexed by pin number
|
||||
myio my_module; // Active copy of Module GPIOs (17 x 16 bits)
|
||||
uint16_t blink_counter; // Number of blink cycles
|
||||
uint16_t seriallog_timer; // Timer to disable Seriallog
|
||||
uint16_t syslog_timer; // Timer to re-enable syslog_level
|
||||
uint16_t tele_period; // Tele period timer
|
||||
int16_t save_data_counter; // Counter and flag for config save to Flash
|
||||
RulesBitfield rules_flag; // Rule state flags (16 bits)
|
||||
|
||||
bool serial_local; // Handle serial locally
|
||||
bool fallback_topic_flag; // Use Topic or FallbackTopic
|
||||
bool backlog_mutex; // Command backlog pending
|
||||
bool stop_flash_rotate; // Allow flash configuration rotation
|
||||
bool blinkstate; // LED state
|
||||
bool pwm_present; // Any PWM channel configured with SetOption15 0
|
||||
bool i2c_enabled; // I2C configured
|
||||
bool spi_enabled; // SPI configured
|
||||
bool soft_spi_enabled; // Software SPI configured
|
||||
bool ntp_force_sync; // Force NTP sync
|
||||
bool is_8285; // Hardware device ESP8266EX (0) or ESP8285 (1)
|
||||
bool skip_light_fade; // Temporarily skip light fading
|
||||
bool restart_halt; // Do not restart but stay in wait loop
|
||||
bool module_changed; // Indicate module changed since last restart
|
||||
|
||||
StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits)
|
||||
uint8_t blinks; // Number of LED blinks
|
||||
uint8_t restart_flag; // Tasmota restart flag
|
||||
uint8_t ota_state_flag; // OTA state flag
|
||||
uint8_t wifi_state_flag; // Wifi state flag
|
||||
uint8_t mqtt_cmnd_blocked; // Ignore flag for publish command
|
||||
uint8_t mqtt_cmnd_blocked_reset; // Count down to reset if needed
|
||||
uint8_t state_250mS; // State 250msecond per second flag
|
||||
uint8_t latching_relay_pulse; // Latching relay pulse timer
|
||||
uint8_t active_device; // Active device in ExecuteCommandPower
|
||||
uint8_t sleep; // Current copy of Settings.sleep
|
||||
uint8_t leds_present; // Max number of LED supported
|
||||
uint8_t led_inverted; // LED inverted flag (1 = (0 = On, 1 = Off))
|
||||
uint8_t led_power; // LED power state
|
||||
uint8_t ledlnk_inverted; // Link LED inverted flag (1 = (0 = On, 1 = Off))
|
||||
uint8_t pwm_inverted; // PWM inverted flag (1 = inverted)
|
||||
uint8_t energy_driver; // Energy monitor configured
|
||||
uint8_t light_driver; // Light module configured
|
||||
uint8_t light_type; // Light types
|
||||
uint8_t serial_in_byte; // Received byte
|
||||
uint8_t devices_present; // Max number of devices supported
|
||||
uint8_t masterlog_level; // Master log level used to override set log level
|
||||
uint8_t seriallog_level; // Current copy of Settings.seriallog_level
|
||||
uint8_t syslog_level; // Current copy of Settings.syslog_level
|
||||
uint8_t module_type; // Current copy of Settings.module or user template type
|
||||
uint8_t last_source; // Last command source
|
||||
uint8_t shutters_present; // Number of actual define shutters
|
||||
uint8_t prepped_loglevel; // Delayed log level message
|
||||
|
||||
#ifndef SUPPORT_IF_STATEMENT
|
||||
uint8_t backlog_index; // Command backlog index
|
||||
uint8_t backlog_pointer; // Command backlog pointer
|
||||
String backlog[MAX_BACKLOG]; // Command backlog buffer
|
||||
#endif
|
||||
|
||||
char version[16]; // Composed version string like 255.255.255.255
|
||||
char image_name[33]; // Code image and/or commit
|
||||
char hostname[33]; // Composed Wifi hostname
|
||||
char serial_in_buffer[INPUT_BUFFER_SIZE]; // Receive buffer
|
||||
char mqtt_client[99]; // Composed MQTT Clientname
|
||||
char mqtt_topic[TOPSZ]; // Composed MQTT topic
|
||||
char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer
|
||||
char log_data[LOGSZ]; // Logging
|
||||
char web_log[WEB_LOG_SIZE]; // Web log buffer
|
||||
} TasmotaGlobal;
|
||||
|
||||
#ifdef SUPPORT_IF_STATEMENT
|
||||
#include <LinkedList.h>
|
||||
LinkedList<String> backlog; // Command backlog implemented with LinkedList
|
||||
#define BACKLOG_EMPTY (backlog.size() == 0)
|
||||
#else
|
||||
uint8_t backlog_index = 0; // Command backlog index
|
||||
uint8_t backlog_pointer = 0; // Command backlog pointer
|
||||
String backlog[MAX_BACKLOG]; // Command backlog buffer
|
||||
#define BACKLOG_EMPTY (backlog_pointer == backlog_index)
|
||||
#define BACKLOG_EMPTY (TasmotaGlobal.backlog_pointer == TasmotaGlobal.backlog_index)
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -195,7 +189,14 @@ void setup(void) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues
|
||||
memset(&TasmotaGlobal, 0, sizeof(TasmotaGlobal));
|
||||
TasmotaGlobal.baudrate = APP_BAUDRATE;
|
||||
TasmotaGlobal.temperature_celsius = NAN;
|
||||
TasmotaGlobal.blinks = 201;
|
||||
TasmotaGlobal.wifi_state_flag = WIFI_RESTART;
|
||||
TasmotaGlobal.tele_period = 9999;
|
||||
TasmotaGlobal.active_device = 1;
|
||||
TasmotaGlobal.global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues
|
||||
|
||||
RtcRebootLoad();
|
||||
if (!RtcRebootValid()) {
|
||||
@ -208,36 +209,33 @@ void setup(void) {
|
||||
#endif
|
||||
RtcRebootSave();
|
||||
|
||||
Serial.begin(baudrate);
|
||||
Serial.begin(TasmotaGlobal.baudrate);
|
||||
// Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars
|
||||
seriallog_level = LOG_LEVEL_INFO; // Allow specific serial messages until config loaded
|
||||
TasmotaGlobal.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
|
||||
snprintf_P(TasmotaGlobal.version, sizeof(TasmotaGlobal.version), PSTR("%d.%d.%d"), VERSION >> 24 & 0xff, VERSION >> 16 & 0xff, VERSION >> 8 & 0xff); // Release version 6.3.0
|
||||
if (VERSION & 0xff) { // Development or patched version 6.3.0.10
|
||||
snprintf_P(my_version, sizeof(my_version), PSTR("%s.%d"), my_version, VERSION & 0xff);
|
||||
snprintf_P(TasmotaGlobal.version, sizeof(TasmotaGlobal.version), PSTR("%s.%d"), TasmotaGlobal.version, VERSION & 0xff);
|
||||
}
|
||||
// Thehackbox inserts "release" or "commit number" before compiling using sed -i -e 's/PSTR("(%s)")/PSTR("(85cff52-%s)")/g' tasmota.ino
|
||||
snprintf_P(my_image, sizeof(my_image), PSTR("(%s)"), CODE_IMAGE_STR); // Results in (85cff52-tasmota) or (release-tasmota)
|
||||
snprintf_P(TasmotaGlobal.image_name, sizeof(TasmotaGlobal.image_name), PSTR("(%s)"), CODE_IMAGE_STR); // Results in (85cff52-tasmota) or (release-tasmota)
|
||||
|
||||
SettingsLoad();
|
||||
SettingsDelta();
|
||||
|
||||
OsWatchInit();
|
||||
|
||||
GetFeatures();
|
||||
|
||||
if (1 == RtcReboot.fast_reboot_count) { // Allow setting override only when all is well
|
||||
UpdateQuickPowerCycle(true);
|
||||
XdrvCall(FUNC_SETTINGS_OVERRIDE);
|
||||
}
|
||||
|
||||
// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
|
||||
seriallog_level = Settings.seriallog_level;
|
||||
seriallog_timer = SERIALLOG_TIMER;
|
||||
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;
|
||||
ssleep = Settings.sleep;
|
||||
TasmotaGlobal.seriallog_level = Settings.seriallog_level;
|
||||
TasmotaGlobal.seriallog_timer = SERIALLOG_TIMER;
|
||||
TasmotaGlobal.syslog_level = Settings.syslog_level;
|
||||
TasmotaGlobal.stop_flash_rotate = Settings.flag.stop_flash_rotate; // SetOption12 - Switch between dynamic or fixed slot flash save location
|
||||
TasmotaGlobal.save_data_counter = Settings.save_data;
|
||||
TasmotaGlobal.sleep = Settings.sleep;
|
||||
#ifndef USE_EMULATION
|
||||
Settings.flag2.emulation = 0;
|
||||
#else
|
||||
@ -249,6 +247,8 @@ void setup(void) {
|
||||
#endif
|
||||
#endif // USE_EMULATION
|
||||
|
||||
// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)&TasmotaGlobal, sizeof(TasmotaGlobal));
|
||||
|
||||
if (Settings.param[P_BOOT_LOOP_OFFSET]) { // SetOption36
|
||||
// Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts)
|
||||
if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET]) { // Restart twice
|
||||
@ -276,13 +276,13 @@ void setup(void) {
|
||||
}
|
||||
}
|
||||
|
||||
Format(mqtt_client, SettingsText(SET_MQTT_CLIENT), sizeof(mqtt_client));
|
||||
Format(mqtt_topic, SettingsText(SET_MQTT_TOPIC), sizeof(mqtt_topic));
|
||||
Format(TasmotaGlobal.mqtt_client, SettingsText(SET_MQTT_CLIENT), sizeof(TasmotaGlobal.mqtt_client));
|
||||
Format(TasmotaGlobal.mqtt_topic, SettingsText(SET_MQTT_TOPIC), sizeof(TasmotaGlobal.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(TasmotaGlobal.hostname, sizeof(TasmotaGlobal.hostname)-1, SettingsText(SET_HOSTNAME), TasmotaGlobal.mqtt_topic, ESP_getChipId() & 0x1FFF);
|
||||
} else {
|
||||
snprintf_P(my_hostname, sizeof(my_hostname)-1, SettingsText(SET_HOSTNAME));
|
||||
snprintf_P(TasmotaGlobal.hostname, sizeof(TasmotaGlobal.hostname)-1, SettingsText(SET_HOSTNAME));
|
||||
}
|
||||
|
||||
GetEspHardwareType();
|
||||
@ -294,12 +294,12 @@ void setup(void) {
|
||||
|
||||
SetPowerOnState();
|
||||
|
||||
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);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_PROJECT " %s %s " D_VERSION " %s%s-" ARDUINO_CORE_RELEASE), PROJECT, SettingsText(SET_DEVICENAME), TasmotaGlobal.version, TasmotaGlobal.image_name);
|
||||
#ifdef FIRMWARE_MINIMAL
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_WARNING_MINIMAL_VERSION));
|
||||
#endif // FIRMWARE_MINIMAL
|
||||
|
||||
memcpy_P(log_data, VERSION_MARKER, 1); // Dummy for compiler saving VERSION_MARKER
|
||||
memcpy_P(TasmotaGlobal.log_data, VERSION_MARKER, 1); // Dummy for compiler saving VERSION_MARKER
|
||||
|
||||
RtcInit();
|
||||
|
||||
@ -313,13 +313,13 @@ void setup(void) {
|
||||
if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">BS",3,0);
|
||||
#endif
|
||||
|
||||
rules_flag.system_init = 1;
|
||||
TasmotaGlobal.rules_flag.system_init = 1;
|
||||
}
|
||||
|
||||
void BacklogLoop(void) {
|
||||
if (TimeReached(backlog_delay)) {
|
||||
if (!BACKLOG_EMPTY && !backlog_mutex) {
|
||||
backlog_mutex = true;
|
||||
if (TimeReached(TasmotaGlobal.backlog_delay)) {
|
||||
if (!BACKLOG_EMPTY && !TasmotaGlobal.backlog_mutex) {
|
||||
TasmotaGlobal.backlog_mutex = true;
|
||||
bool nodelay = false;
|
||||
bool nodelay_detected = false;
|
||||
String cmd;
|
||||
@ -327,17 +327,21 @@ void BacklogLoop(void) {
|
||||
#ifdef SUPPORT_IF_STATEMENT
|
||||
cmd = backlog.shift();
|
||||
#else
|
||||
cmd = backlog[backlog_pointer];
|
||||
backlog[backlog_pointer] = (const char*) nullptr; // Force deallocation of the String internal memory
|
||||
backlog_pointer++;
|
||||
if (backlog_pointer >= MAX_BACKLOG) { backlog_pointer = 0; }
|
||||
cmd = TasmotaGlobal.backlog[TasmotaGlobal.backlog_pointer];
|
||||
TasmotaGlobal.backlog[TasmotaGlobal.backlog_pointer] = (const char*) nullptr; // Force deallocation of the String internal memory
|
||||
TasmotaGlobal.backlog_pointer++;
|
||||
if (TasmotaGlobal.backlog_pointer >= MAX_BACKLOG) { TasmotaGlobal.backlog_pointer = 0; }
|
||||
#endif
|
||||
nodelay_detected = !strncasecmp_P(cmd.c_str(), PSTR(D_CMND_NODELAY), strlen(D_CMND_NODELAY));
|
||||
if (nodelay_detected) { nodelay = true; }
|
||||
} while (!BACKLOG_EMPTY && nodelay_detected);
|
||||
if (!nodelay_detected) { ExecuteCommand((char*)cmd.c_str(), SRC_BACKLOG); }
|
||||
if (nodelay) { backlog_delay = 0; } // Reset backlog_delay which has been set by ExecuteCommand (CommandHandler)
|
||||
backlog_mutex = false;
|
||||
if (!nodelay_detected) {
|
||||
ExecuteCommand((char*)cmd.c_str(), SRC_BACKLOG);
|
||||
}
|
||||
if (nodelay) {
|
||||
TasmotaGlobal.backlog_delay = 0; // Reset backlog_delay which has been set by ExecuteCommand (CommandHandler)
|
||||
}
|
||||
TasmotaGlobal.backlog_mutex = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,6 +372,7 @@ void loop(void) {
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
BacklogLoop();
|
||||
|
||||
static uint32_t state_50msecond = 0; // State 50msecond timer
|
||||
if (TimeReached(state_50msecond)) {
|
||||
SetNextTimeInterval(state_50msecond, 50);
|
||||
#ifdef ROTARY_V1
|
||||
@ -376,18 +381,24 @@ void loop(void) {
|
||||
XdrvCall(FUNC_EVERY_50_MSECOND);
|
||||
XsnsCall(FUNC_EVERY_50_MSECOND);
|
||||
}
|
||||
|
||||
static uint32_t state_100msecond = 0; // State 100msecond timer
|
||||
if (TimeReached(state_100msecond)) {
|
||||
SetNextTimeInterval(state_100msecond, 100);
|
||||
Every100mSeconds();
|
||||
XdrvCall(FUNC_EVERY_100_MSECOND);
|
||||
XsnsCall(FUNC_EVERY_100_MSECOND);
|
||||
}
|
||||
|
||||
static uint32_t state_250msecond = 0; // State 250msecond timer
|
||||
if (TimeReached(state_250msecond)) {
|
||||
SetNextTimeInterval(state_250msecond, 250);
|
||||
Every250mSeconds();
|
||||
XdrvCall(FUNC_EVERY_250_MSECOND);
|
||||
XsnsCall(FUNC_EVERY_250_MSECOND);
|
||||
}
|
||||
|
||||
static uint32_t state_second = 0; // State second timer
|
||||
if (TimeReached(state_second)) {
|
||||
SetNextTimeInterval(state_second, 1000);
|
||||
PerformEverySecond();
|
||||
@ -395,7 +406,7 @@ void loop(void) {
|
||||
XsnsCall(FUNC_EVERY_SECOND);
|
||||
}
|
||||
|
||||
if (!serial_local) { SerialInput(); }
|
||||
if (!TasmotaGlobal.serial_local) { SerialInput(); }
|
||||
|
||||
#ifdef USE_ARDUINO_OTA
|
||||
ArduinoOtaLoop();
|
||||
@ -405,21 +416,21 @@ void loop(void) {
|
||||
|
||||
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
|
||||
SleepDelay(TasmotaGlobal.sleep); // https://github.com/esp8266/Arduino/issues/2021
|
||||
} else {
|
||||
if (my_activity < (uint32_t)ssleep) {
|
||||
SleepDelay((uint32_t)ssleep - my_activity); // Provide time for background tasks like wifi
|
||||
if (my_activity < (uint32_t)TasmotaGlobal.sleep) {
|
||||
SleepDelay((uint32_t)TasmotaGlobal.sleep - my_activity); // Provide time for background tasks like wifi
|
||||
} else {
|
||||
if (global_state.network_down) {
|
||||
if (TasmotaGlobal.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 = ssleep;
|
||||
uint32_t loop_delay = TasmotaGlobal.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
|
||||
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
|
||||
TasmotaGlobal.loop_load_avg = TasmotaGlobal.loop_load_avg - (TasmotaGlobal.loop_load_avg / loops_per_second) + (this_cycle_ratio / loops_per_second); // Take away one loop average away and add the new one
|
||||
}
|
||||
|
||||
@ -133,6 +133,9 @@
|
||||
//#define USE_EZOHUM // [I2cDriver55] Enable support for EZO's HUM sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
//#define USE_EZOEC // [I2cDriver55] Enable support for EZO's EC sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
//#define USE_EZOCO2 // [I2cDriver55] Enable support for EZO's CO2 sensor (+0k2 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
//#define USE_EZOO2 // [I2cDriver55] Enable support for EZO's O2 sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
//#define USE_EZOPRS // [I2cDriver55] Enable support for EZO's PRS sensor (+0k7 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
//#define USE_EZOFLO // [I2cDriver55] Enable support for EZO's FLO sensor (+0k4 code) - Shared EZO code required for any EZO device (+1k2 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)
|
||||
@ -443,12 +446,14 @@
|
||||
#undef USE_HOME_ASSISTANT // Disable Home Assistant
|
||||
|
||||
// -- MQTT - TLS - AWS IoT ------------------------
|
||||
#define USE_MQTT_TLS // Use TLS for MQTT connection (+34.5k code, +7.0k mem and +4.8k additional during connection handshake)
|
||||
#define USE_MQTT_TLS_CA_CERT // Force full CA validation instead of fingerprints, slower, but simpler to use. (+2.2k code, +1.9k mem during connection handshake)
|
||||
// This includes the LetsEncrypt CA in tasmota_ca.ino for verifying server certificates
|
||||
#define USE_MQTT_TLS_FORCE_EC_CIPHER // Force Elliptic Curve cipher (higher security) required by some servers (automatically enabled with USE_MQTT_AWS_IOT) (+11.4k code, +0.4k mem)
|
||||
#define USE_MQTT_AWS_IOT_LIGHT // Enable MQTT for AWS IoT in light mode, with user/password instead of private certificate
|
||||
#define USE_TLS // flag indicates we need to include TLS code
|
||||
#ifdef USE_ZBBRIDGE_TLS // Enable TLS for ZbBridge
|
||||
#define USE_MQTT_TLS // Use TLS for MQTT connection (+34.5k code, +7.0k mem and +4.8k additional during connection handshake)
|
||||
#define USE_MQTT_TLS_CA_CERT // Force full CA validation instead of fingerprints, slower, but simpler to use. (+2.2k code, +1.9k mem during connection handshake)
|
||||
// This includes the LetsEncrypt CA in tasmota_ca.ino for verifying server certificates
|
||||
#define USE_MQTT_TLS_FORCE_EC_CIPHER // Force Elliptic Curve cipher (higher security) required by some servers (automatically enabled with USE_MQTT_AWS_IOT) (+11.4k code, +0.4k mem)
|
||||
#define USE_MQTT_AWS_IOT_LIGHT // Enable MQTT for AWS IoT in light mode, with user/password instead of private certificate
|
||||
#define USE_TLS // flag indicates we need to include TLS code
|
||||
#endif // USE_ZBBRIDGE_TLS
|
||||
|
||||
#undef USE_KNX // Disable KNX IP Protocol Support
|
||||
//#undef USE_WEBSERVER // Disable Webserver
|
||||
|
||||
@ -840,7 +840,7 @@ void ShowWebSource(uint32_t source)
|
||||
void ExecuteWebCommand(char* svalue, uint32_t source)
|
||||
{
|
||||
ShowWebSource(source);
|
||||
last_source = source;
|
||||
TasmotaGlobal.last_source = source;
|
||||
ExecuteCommand(svalue, SRC_IGNORE);
|
||||
}
|
||||
|
||||
@ -875,7 +875,11 @@ const WebServerDispatch_t WebServerDispatch[] PROGMEM = {
|
||||
};
|
||||
|
||||
void WebServer_on(const char * prefix, void (*func)(void), uint8_t method = HTTP_ANY) {
|
||||
#ifdef ESP8266
|
||||
Webserver->on((const __FlashStringHelper *) prefix, (HTTPMethod) method, func);
|
||||
#else
|
||||
Webserver->on(prefix, (HTTPMethod) method, func);
|
||||
#endif
|
||||
}
|
||||
|
||||
void StartWebserver(int type, IPAddress ipweb)
|
||||
@ -921,7 +925,7 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"),
|
||||
NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str());
|
||||
#endif // LWIP_IPV6 = 1
|
||||
rules_flag.http_init = 1;
|
||||
TasmotaGlobal.rules_flag.http_init = 1;
|
||||
}
|
||||
if (type) { Web.state = type; }
|
||||
}
|
||||
@ -938,7 +942,7 @@ void StopWebserver(void)
|
||||
void WifiManagerBegin(bool reset_only)
|
||||
{
|
||||
// setup AP
|
||||
if (!global_state.wifi_down) {
|
||||
if (!TasmotaGlobal.global_state.wifi_down) {
|
||||
// WiFi.mode(WIFI_AP_STA);
|
||||
WifiSetMode(WIFI_AP_STA);
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION));
|
||||
@ -956,7 +960,7 @@ void WifiManagerBegin(bool reset_only)
|
||||
if ((channel < 1) || (channel > 13)) { channel = 1; }
|
||||
|
||||
// bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4);
|
||||
WiFi.softAP(my_hostname, WIFI_AP_PASSPHRASE, channel, 0, 1);
|
||||
WiFi.softAP(TasmotaGlobal.hostname, WIFI_AP_PASSPHRASE, channel, 0, 1);
|
||||
delay(500); // Without delay I've seen the IP address blank
|
||||
/* Setup the DNS server redirecting all the domains to the apIP */
|
||||
DnsServer->setErrorReplyCode(DNSReplyCode::NoError);
|
||||
@ -1041,7 +1045,7 @@ void _WSContentSend(const String& content) // Low level sendContent for a
|
||||
#ifdef USE_DEBUG_DRIVER
|
||||
ShowFreeMem(PSTR("WSContentSend"));
|
||||
#endif
|
||||
DEBUG_CORE_LOG(PSTR("WEB: Chunk size %d/%d"), len, sizeof(mqtt_data));
|
||||
DEBUG_CORE_LOG(PSTR("WEB: Chunk size %d/%d"), len, sizeof(TasmotaGlobal.mqtt_data));
|
||||
}
|
||||
|
||||
void WSContentFlush(void)
|
||||
@ -1054,24 +1058,24 @@ void WSContentFlush(void)
|
||||
|
||||
void _WSContentSendBuffer(void)
|
||||
{
|
||||
int len = strlen(mqtt_data);
|
||||
int len = strlen(TasmotaGlobal.mqtt_data);
|
||||
|
||||
if (0 == len) { // No content
|
||||
return;
|
||||
}
|
||||
else if (len == sizeof(mqtt_data)) {
|
||||
else if (len == sizeof(TasmotaGlobal.mqtt_data)) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: Content too large"));
|
||||
}
|
||||
else if (len < CHUNKED_BUFFER_SIZE) { // Append chunk buffer with small content
|
||||
Web.chunk_buffer += mqtt_data;
|
||||
Web.chunk_buffer += TasmotaGlobal.mqtt_data;
|
||||
len = Web.chunk_buffer.length();
|
||||
}
|
||||
|
||||
if (len >= CHUNKED_BUFFER_SIZE) { // Either content or chunk buffer is oversize
|
||||
WSContentFlush(); // Send chunk buffer before possible content oversize
|
||||
}
|
||||
if (strlen(mqtt_data) >= CHUNKED_BUFFER_SIZE) { // Content is oversize
|
||||
_WSContentSend(mqtt_data); // Send content
|
||||
if (strlen(TasmotaGlobal.mqtt_data) >= CHUNKED_BUFFER_SIZE) { // Content is oversize
|
||||
_WSContentSend(TasmotaGlobal.mqtt_data); // Send content
|
||||
}
|
||||
}
|
||||
|
||||
@ -1080,13 +1084,13 @@ void WSContentSend_P(const char* formatP, ...) // Content send snprintf_P ch
|
||||
// This uses char strings. Be aware of sending %% if % is needed
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
int len = vsnprintf_P(mqtt_data, sizeof(mqtt_data), formatP, arg);
|
||||
int len = vsnprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
#ifdef DEBUG_TASMOTA_CORE
|
||||
if (len > (sizeof(mqtt_data) -1)) {
|
||||
mqtt_data[33] = '\0';
|
||||
DEBUG_CORE_LOG(PSTR("ERROR: WSContentSend_P size %d > mqtt_data size %d. Start of data [%s...]"), len, sizeof(mqtt_data), mqtt_data);
|
||||
if (len > (sizeof(TasmotaGlobal.mqtt_data) -1)) {
|
||||
TasmotaGlobal.mqtt_data[33] = '\0';
|
||||
DEBUG_CORE_LOG(PSTR("ERROR: WSContentSend_P size %d > mqtt_data size %d. Start of data [%s...]"), len, sizeof(TasmotaGlobal.mqtt_data), TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1098,20 +1102,20 @@ void WSContentSend_PD(const char* formatP, ...) // Content send snprintf_P ch
|
||||
// This uses char strings. Be aware of sending %% if % is needed
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
int len = vsnprintf_P(mqtt_data, sizeof(mqtt_data), formatP, arg);
|
||||
int len = vsnprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
#ifdef DEBUG_TASMOTA_CORE
|
||||
if (len > (sizeof(mqtt_data) -1)) {
|
||||
mqtt_data[33] = '\0';
|
||||
DEBUG_CORE_LOG(PSTR("ERROR: WSContentSend_PD size %d > mqtt_data size %d. Start of data [%s...]"), len, sizeof(mqtt_data), mqtt_data);
|
||||
if (len > (sizeof(TasmotaGlobal.mqtt_data) -1)) {
|
||||
TasmotaGlobal.mqtt_data[33] = '\0';
|
||||
DEBUG_CORE_LOG(PSTR("ERROR: WSContentSend_PD size %d > mqtt_data size %d. Start of data [%s...]"), len, sizeof(TasmotaGlobal.mqtt_data), TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (D_DECIMAL_SEPARATOR[0] != '.') {
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
if ('.' == mqtt_data[i]) {
|
||||
mqtt_data[i] = D_DECIMAL_SEPARATOR[0];
|
||||
if ('.' == TasmotaGlobal.mqtt_data[i]) {
|
||||
TasmotaGlobal.mqtt_data[i] = D_DECIMAL_SEPARATOR[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1162,13 +1166,13 @@ void WSContentSendStyle_P(const char* formatP, ...)
|
||||
// This uses char strings. Be aware of sending %% if % is needed
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
int len = vsnprintf_P(mqtt_data, sizeof(mqtt_data), formatP, arg);
|
||||
int len = vsnprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
#ifdef DEBUG_TASMOTA_CORE
|
||||
if (len > (sizeof(mqtt_data) -1)) {
|
||||
mqtt_data[33] = '\0';
|
||||
DEBUG_CORE_LOG(PSTR("ERROR: WSContentSendStyle_P size %d > mqtt_data size %d. Start of data [%s...]"), len, sizeof(mqtt_data), mqtt_data);
|
||||
if (len > (sizeof(TasmotaGlobal.mqtt_data) -1)) {
|
||||
TasmotaGlobal.mqtt_data[33] = '\0';
|
||||
DEBUG_CORE_LOG(PSTR("ERROR: WSContentSendStyle_P size %d > mqtt_data size %d. Start of data [%s...]"), len, sizeof(TasmotaGlobal.mqtt_data), TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1248,7 +1252,7 @@ void WSContentStop(void)
|
||||
WSContentSend_P(HTTP_COUNTER);
|
||||
}
|
||||
}
|
||||
WSContentSend_P(HTTP_END, my_version);
|
||||
WSContentSend_P(HTTP_END, TasmotaGlobal.version);
|
||||
WSContentEnd();
|
||||
}
|
||||
|
||||
@ -1282,7 +1286,7 @@ void WebRestart(uint32_t type)
|
||||
WSContentStop();
|
||||
|
||||
ShowWebSource(SRC_WEBGUI);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
@ -1360,12 +1364,12 @@ void HandleRoot(void)
|
||||
WSContentSendStyle();
|
||||
|
||||
WSContentSend_P(PSTR("<div id='l1' name='l1'></div>"));
|
||||
if (devices_present) {
|
||||
if (TasmotaGlobal.devices_present) {
|
||||
#ifdef USE_LIGHT
|
||||
if (light_type) {
|
||||
uint8_t light_subtype = light_type &7;
|
||||
if (TasmotaGlobal.light_type) {
|
||||
uint8_t light_subtype = TasmotaGlobal.light_type &7;
|
||||
if (!Settings.flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM
|
||||
bool split_white = ((LST_RGBW <= light_subtype) && (devices_present > 1)); // Only on RGBW or RGBCW and SetOption37 128
|
||||
bool split_white = ((LST_RGBW <= light_subtype) && (TasmotaGlobal.devices_present > 1)); // Only on RGBW or RGBCW and SetOption37 128
|
||||
|
||||
if ((LST_COLDWARM == light_subtype) || ((LST_RGBCW == light_subtype) && !split_white)) {
|
||||
WebSliderColdWarm();
|
||||
@ -1439,7 +1443,7 @@ void HandleRoot(void)
|
||||
#endif // USE_LIGHT
|
||||
#ifdef USE_SHUTTER
|
||||
if (Settings.flag3.shutter_mode) { // SetOption80 - Enable shutter support
|
||||
for (uint32_t i = 0; i < shutters_present; i++) {
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
WSContentSend_P(HTTP_MSG_SLIDER_SHUTTER, Settings.shutter_position[i], i+1);
|
||||
}
|
||||
}
|
||||
@ -1459,21 +1463,21 @@ void HandleRoot(void)
|
||||
}
|
||||
} else {
|
||||
#endif // USE_SONOFF_IFAN
|
||||
for (uint32_t idx = 1; idx <= devices_present; idx++) {
|
||||
for (uint32_t idx = 1; idx <= TasmotaGlobal.devices_present; idx++) {
|
||||
bool set_button = ((idx <= MAX_BUTTON_TEXT) && strlen(SettingsText(SET_BUTTON1 + idx -1)));
|
||||
#ifdef USE_SHUTTER
|
||||
int32_t ShutterWebButton;
|
||||
if (ShutterWebButton = IsShutterWebButton(idx)) {
|
||||
WSContentSend_P(HTTP_DEVICE_CONTROL, 100 / devices_present, idx,
|
||||
WSContentSend_P(HTTP_DEVICE_CONTROL, 100 / TasmotaGlobal.devices_present, idx,
|
||||
(set_button) ? SettingsText(SET_BUTTON1 + idx -1) : ((Settings.shutter_options[abs(ShutterWebButton)-1] & 2) /* is locked */ ? "-" : ((Settings.shutter_options[abs(ShutterWebButton)-1] & 8) /* invert web buttons */ ? ((ShutterWebButton>0) ? "▼" : "▲") : ((ShutterWebButton>0) ? "▲" : "▼"))),
|
||||
"");
|
||||
continue;
|
||||
}
|
||||
#endif // USE_SHUTTER
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), idx);
|
||||
WSContentSend_P(HTTP_DEVICE_CONTROL, 100 / devices_present, idx,
|
||||
(set_button) ? SettingsText(SET_BUTTON1 + idx -1) : (devices_present < 5) ? D_BUTTON_TOGGLE : "",
|
||||
(set_button) ? "" : (devices_present > 1) ? stemp : "");
|
||||
WSContentSend_P(HTTP_DEVICE_CONTROL, 100 / TasmotaGlobal.devices_present, idx,
|
||||
(set_button) ? SettingsText(SET_BUTTON1 + idx -1) : (TasmotaGlobal.devices_present < 5) ? D_BUTTON_TOGGLE : "",
|
||||
(set_button) ? "" : (TasmotaGlobal.devices_present > 1) ? stemp : "");
|
||||
}
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
}
|
||||
@ -1487,13 +1491,13 @@ void HandleRoot(void)
|
||||
WSContentSend_P(HTTP_TABLE100);
|
||||
WSContentSend_P(PSTR("<tr><div></div>"));
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("" D_JSON_IRHVAC_MODE ""));
|
||||
WSContentSend_P(HTTP_DEVICE_CONTROL, 26, devices_present + 1,
|
||||
(strlen(SettingsText(SET_BUTTON1 + devices_present))) ? SettingsText(SET_BUTTON1 + devices_present) : stemp, "");
|
||||
WSContentSend_P(HTTP_DEVICE_CONTROL, 26, TasmotaGlobal.devices_present + 1,
|
||||
(strlen(SettingsText(SET_BUTTON1 + TasmotaGlobal.devices_present))) ? SettingsText(SET_BUTTON1 + TasmotaGlobal.devices_present) : stemp, "");
|
||||
WSContentSend_P(PSTR("</tr></table>"));
|
||||
modeset = 1;
|
||||
}
|
||||
if (IsTuyaFanCtrl()) {
|
||||
uint8_t device = devices_present + modeset;
|
||||
uint8_t device = TasmotaGlobal.devices_present + modeset;
|
||||
WSContentSend_P(HTTP_TABLE100);
|
||||
WSContentSend_P(PSTR("<tr><div></div>"));
|
||||
for (uint32_t i = device + 1; i <= (TuyaFanSpeeds() + device) + 1; i++) {
|
||||
@ -1506,7 +1510,7 @@ void HandleRoot(void)
|
||||
}
|
||||
#endif // USE_TUYA_MCU
|
||||
#ifdef USE_SONOFF_RF
|
||||
if (SONOFF_BRIDGE == my_module_type) {
|
||||
if (SONOFF_BRIDGE == TasmotaGlobal.module_type) {
|
||||
WSContentSend_P(HTTP_TABLE100);
|
||||
WSContentSend_P(PSTR("<tr>"));
|
||||
uint32_t idx = 0;
|
||||
@ -1578,10 +1582,10 @@ bool HandleRootStatusRefresh(void)
|
||||
#ifdef USE_TUYA_MCU
|
||||
if (IsModuleTuya()) {
|
||||
uint8_t FuncIdx = 0;
|
||||
if (device <= devices_present) {
|
||||
if (device <= TasmotaGlobal.devices_present) {
|
||||
ExecuteCommandPower(device, POWER_TOGGLE, SRC_IGNORE);
|
||||
} else {
|
||||
if (AsModuleTuyaMS() && device == devices_present + 1) {
|
||||
if (AsModuleTuyaMS() && device == TasmotaGlobal.devices_present + 1) {
|
||||
uint8_t dpId = TuyaGetDpId(TUYA_MCU_FUNC_MODESET);
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("Tuyasend4 %d,%d"), dpId, !TuyaModeSet());
|
||||
ExecuteCommand(svalue, SRC_WEBGUI);
|
||||
@ -1593,9 +1597,9 @@ bool HandleRootStatusRefresh(void)
|
||||
dpId = TuyaGetDpId(TUYA_MCU_FUNC_FAN3 + i);
|
||||
}
|
||||
}
|
||||
if ((AsModuleTuyaMS() && device != devices_present + 1) || !AsModuleTuyaMS()) {
|
||||
if ((AsModuleTuyaMS() && device != TasmotaGlobal.devices_present + 1) || !AsModuleTuyaMS()) {
|
||||
if (AsModuleTuyaMS()) {FuncIdx = 1;}
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("Tuyasend2 %d,%d"), dpId, (device - (devices_present + FuncIdx) - 1));
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("Tuyasend2 %d,%d"), dpId, (device - (TasmotaGlobal.devices_present + FuncIdx) - 1));
|
||||
ExecuteCommand(svalue, SRC_WEBGUI);
|
||||
}
|
||||
}
|
||||
@ -1632,7 +1636,7 @@ bool HandleRootStatusRefresh(void)
|
||||
ExecuteWebCommand(svalue, SRC_WEBGUI);
|
||||
}
|
||||
uint32_t light_device = LightDevice(); // Channel number offset
|
||||
uint32_t pwm_channels = (light_type & 7) > LST_MAX ? LST_MAX : (light_type & 7);
|
||||
uint32_t pwm_channels = (TasmotaGlobal.light_type & 7) > LST_MAX ? LST_MAX : (TasmotaGlobal.light_type & 7);
|
||||
for (uint32_t j = 0; j < pwm_channels; j++) {
|
||||
snprintf_P(webindex, sizeof(webindex), PSTR("e%d"), j +1);
|
||||
WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent
|
||||
@ -1658,7 +1662,7 @@ bool HandleRootStatusRefresh(void)
|
||||
}
|
||||
#endif // USE_LIGHT
|
||||
#ifdef USE_SHUTTER
|
||||
for (uint32_t j = 1; j <= shutters_present; j++) {
|
||||
for (uint32_t j = 1; j <= TasmotaGlobal.shutters_present; j++) {
|
||||
snprintf_P(webindex, sizeof(webindex), PSTR("u%d"), j);
|
||||
WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent
|
||||
if (strlen(tmp)) {
|
||||
@ -1681,20 +1685,20 @@ bool HandleRootStatusRefresh(void)
|
||||
|
||||
WSContentSend_P(PSTR("</table>"));
|
||||
|
||||
if (devices_present) {
|
||||
if (TasmotaGlobal.devices_present) {
|
||||
WSContentSend_P(PSTR("{t}<tr>"));
|
||||
uint32_t fsize = (devices_present < 5) ? 70 - (devices_present * 8) : 32;
|
||||
uint32_t fsize = (TasmotaGlobal.devices_present < 5) ? 70 - (TasmotaGlobal.devices_present * 8) : 32;
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
if (IsModuleIfan()) {
|
||||
WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(power, 0)) ? "bold" : "normal", 54, GetStateText(bitRead(power, 0)));
|
||||
WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(TasmotaGlobal.power, 0)) ? "bold" : "normal", 54, GetStateText(bitRead(TasmotaGlobal.power, 0)));
|
||||
uint32_t fanspeed = GetFanspeed();
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fanspeed);
|
||||
WSContentSend_P(HTTP_DEVICE_STATE, 64, (fanspeed) ? "bold" : "normal", 54, (fanspeed) ? svalue : GetStateText(0));
|
||||
} else {
|
||||
#endif // USE_SONOFF_IFAN
|
||||
for (uint32_t idx = 1; idx <= devices_present; idx++) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(power, idx -1));
|
||||
WSContentSend_P(HTTP_DEVICE_STATE, 100 / devices_present, (bitRead(power, idx -1)) ? "bold" : "normal", fsize, (devices_present < 5) ? GetStateText(bitRead(power, idx -1)) : svalue);
|
||||
for (uint32_t idx = 1; idx <= TasmotaGlobal.devices_present; idx++) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(TasmotaGlobal.power, idx -1));
|
||||
WSContentSend_P(HTTP_DEVICE_STATE, 100 / TasmotaGlobal.devices_present, (bitRead(TasmotaGlobal.power, idx -1)) ? "bold" : "normal", fsize, (TasmotaGlobal.devices_present < 5) ? GetStateText(bitRead(TasmotaGlobal.power, idx -1)) : svalue);
|
||||
}
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
}
|
||||
@ -1997,7 +2001,7 @@ void HandleModuleConfiguration(void)
|
||||
|
||||
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 - g17
|
||||
WSContentSend_P(PSTR("sk(%d,%d);"), TasmotaGlobal.my_module.io[i], i); // g0 - g17
|
||||
}
|
||||
}
|
||||
|
||||
@ -2016,7 +2020,7 @@ void HandleModuleConfiguration(void)
|
||||
if (ValidGPIO(i, cmodule.io[i])) {
|
||||
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
||||
WSContentSend_P(PSTR("<tr><td style='width:116px'>%s <b>" D_GPIO "%d</b></td><td style='width:150px'><select id='g%d' onchange='ot(%d,this.value)'></select></td>"),
|
||||
(WEMOS==my_module_type)?stemp:"", i, i, i);
|
||||
(WEMOS==TasmotaGlobal.module_type)?stemp:"", i, i, i);
|
||||
WSContentSend_P(PSTR("<td style='width:50px'><select id='h%d'></select></td></tr>"), i);
|
||||
}
|
||||
}
|
||||
@ -2281,13 +2285,13 @@ void HandleOtherConfiguration(void)
|
||||
WSContentSendStyle();
|
||||
|
||||
TemplateJson();
|
||||
char stemp[strlen(mqtt_data) +1];
|
||||
strlcpy(stemp, mqtt_data, sizeof(stemp)); // Get JSON template
|
||||
char stemp[strlen(TasmotaGlobal.mqtt_data) +1];
|
||||
strlcpy(stemp, TasmotaGlobal.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
|
||||
SettingsText(SET_FRIENDLYNAME1), SettingsText(SET_DEVICENAME));
|
||||
|
||||
uint32_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!devices_present) ? 1 : devices_present;
|
||||
uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!TasmotaGlobal.devices_present) ? 1 : TasmotaGlobal.devices_present;
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
if (IsModuleIfan()) { maxfn = 1; }
|
||||
#endif // USE_SONOFF_IFAN
|
||||
@ -2382,10 +2386,10 @@ void HandleBackupConfiguration(void)
|
||||
char attachment[TOPSZ];
|
||||
|
||||
// char friendlyname[TOPSZ];
|
||||
// snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(friendlyname, SettingsText(SET_FRIENDLYNAME1)), my_version);
|
||||
// snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(friendlyname, SettingsText(SET_FRIENDLYNAME1)), TasmotaGlobal.version);
|
||||
|
||||
char hostname[sizeof(my_hostname)];
|
||||
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(hostname, my_hostname), my_version);
|
||||
char hostname[sizeof(TasmotaGlobal.hostname)];
|
||||
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(hostname, TasmotaGlobal.hostname), TasmotaGlobal.version);
|
||||
|
||||
Webserver->sendHeader(F("Content-Disposition"), attachment);
|
||||
|
||||
@ -2467,7 +2471,7 @@ void HandleInformation(void)
|
||||
// }2 = </th><td>
|
||||
WSContentSend_P(HTTP_SCRIPT_INFO_BEGIN);
|
||||
WSContentSend_P(PSTR("<table style='width:100%%'><tr><th>"));
|
||||
WSContentSend_P(PSTR(D_PROGRAM_VERSION "}2%s%s"), my_version, my_image);
|
||||
WSContentSend_P(PSTR(D_PROGRAM_VERSION "}2%s%s"), TasmotaGlobal.version, TasmotaGlobal.image_name);
|
||||
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_CORE_RELEASE "/%s"), ESP.getSdkVersion());
|
||||
WSContentSend_P(PSTR("}1" D_UPTIME "}2%s"), GetUptime().c_str());
|
||||
@ -2478,7 +2482,7 @@ void HandleInformation(void)
|
||||
#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;
|
||||
uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : TasmotaGlobal.devices_present;
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
if (IsModuleIfan()) { maxfn = 1; }
|
||||
#endif // USE_SONOFF_IFAN
|
||||
@ -2499,7 +2503,7 @@ void HandleInformation(void)
|
||||
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" : "");
|
||||
WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), TasmotaGlobal.hostname, (Mdns.begun) ? ".local" : "");
|
||||
#if LWIP_IPV6
|
||||
String ipv6_addr = WifiGetIPv6();
|
||||
if (ipv6_addr != "") {
|
||||
@ -2512,7 +2516,7 @@ void HandleInformation(void)
|
||||
WSContentSend_P(PSTR("}1<hr/>}2<hr/>"));
|
||||
}
|
||||
}
|
||||
if (!global_state.network_down) {
|
||||
if (!TasmotaGlobal.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());
|
||||
@ -2531,7 +2535,7 @@ void HandleInformation(void)
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_TLS_ENABLE "}2%s"), Settings.flag4.mqtt_tls ? PSTR(D_ENABLED) : PSTR(D_DISABLED));
|
||||
#endif // USE_MQTT_TLS
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_USER "}2%s"), SettingsText(SET_MQTT_USER));
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_CLIENT "}2%s"), mqtt_client);
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_CLIENT "}2%s"), TasmotaGlobal.mqtt_client);
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_TOPIC "}2%s"), SettingsText(SET_MQTT_TOPIC));
|
||||
uint32_t real_index = SET_MQTT_GRP_TOPIC;
|
||||
for (uint32_t i = 0; i < MAX_GROUP_TOPICS; i++) {
|
||||
@ -2540,7 +2544,7 @@ void HandleInformation(void)
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_GROUP_TOPIC " %d}2%s"), 1 +i, GetGroupTopic_P(stopic, "", real_index +i));
|
||||
}
|
||||
}
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_FULL_TOPIC "}2%s"), GetTopic_P(stopic, CMND, mqtt_topic, ""));
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_FULL_TOPIC "}2%s"), GetTopic_P(stopic, CMND, TasmotaGlobal.mqtt_topic, ""));
|
||||
WSContentSend_P(PSTR("}1" D_MQTT " " D_FALLBACK_TOPIC "}2%s"), GetFallbackTopic_P(stopic, ""));
|
||||
WSContentSend_P(PSTR("}1" D_MQTT_NO_RETAIN "}2%s"), Settings.flag4.mqtt_no_retain ? PSTR(D_ENABLED) : PSTR(D_DISABLED));
|
||||
} else {
|
||||
@ -2662,7 +2666,7 @@ void HandleUploadDone(void)
|
||||
char error[100];
|
||||
|
||||
WifiConfigCounter();
|
||||
restart_flag = 0;
|
||||
TasmotaGlobal.restart_flag = 0;
|
||||
MqttRetryCounter(0);
|
||||
#ifdef USE_COUNTER
|
||||
CounterInterruptDisable(false);
|
||||
@ -2694,17 +2698,17 @@ void HandleUploadDone(void)
|
||||
}
|
||||
WSContentSend_P(error);
|
||||
DEBUG_CORE_LOG(PSTR("UPL: %s"), error);
|
||||
stop_flash_rotate = Settings.flag.stop_flash_rotate; // SetOption12 - Switch between dynamic or fixed slot flash save location
|
||||
TasmotaGlobal.stop_flash_rotate = Settings.flag.stop_flash_rotate; // SetOption12 - Switch between dynamic or fixed slot flash save location
|
||||
} else {
|
||||
WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "</font></b><br>"), WebColor(COL_TEXT_SUCCESS));
|
||||
restart_flag = 2; // Always restart to re-enable disabled features during update
|
||||
TasmotaGlobal.restart_flag = 2; // Always restart to re-enable disabled features during update
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
if (TasmotaClient_GetFlagFlashing()) {
|
||||
WSContentSend_P(PSTR("<br><div style='text-align:center;'><b>" D_TRANSFER_STARTED " ...</b></div>"));
|
||||
restart_flag = 0; // Hold restart as code still needs to be transferred to Atmega
|
||||
TasmotaGlobal.restart_flag = 0; // Hold restart as code still needs to be transferred to Atmega
|
||||
}
|
||||
#endif // USE_TASMOTA_CLIENT
|
||||
if (restart_flag) {
|
||||
if (TasmotaGlobal.restart_flag) {
|
||||
WSContentSend_P(HTTP_MSG_RSTRT);
|
||||
ShowWebSource(SRC_WEBGUI);
|
||||
}
|
||||
@ -2724,7 +2728,7 @@ void HandleUploadDone(void)
|
||||
void HandleUploadLoop(void)
|
||||
{
|
||||
// Based on ESP8266HTTPUpdateServer.cpp uses ESP8266WebServer Parsing.cpp and Cores Updater.cpp (Update)
|
||||
bool _serialoutput = (LOG_LEVEL_DEBUG <= seriallog_level);
|
||||
bool _serialoutput = (LOG_LEVEL_DEBUG <= TasmotaGlobal.seriallog_level);
|
||||
|
||||
if (HTTP_USER == Web.state) { return; }
|
||||
if (Web.upload_error) {
|
||||
@ -2736,7 +2740,7 @@ void HandleUploadLoop(void)
|
||||
|
||||
// ***** Step1: Start upload file
|
||||
if (UPLOAD_FILE_START == upload.status) {
|
||||
restart_flag = 60;
|
||||
TasmotaGlobal.restart_flag = 60;
|
||||
if (0 == upload.filename.c_str()[0]) {
|
||||
Web.upload_error = 1; // No file selected
|
||||
return;
|
||||
@ -2786,7 +2790,7 @@ void HandleUploadLoop(void)
|
||||
else {
|
||||
#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP)
|
||||
#ifdef ESP8266
|
||||
if ((SONOFF_ZB_BRIDGE == my_module_type) && (upload.buf[0] == 0xEB)) { // Check if this is a Zigbee bridge FW file
|
||||
if ((SONOFF_ZB_BRIDGE == TasmotaGlobal.module_type) && (upload.buf[0] == 0xEB)) { // Check if this is a Zigbee bridge FW file
|
||||
#else // ESP32
|
||||
if (PinUsed(GPIO_ZIGBEE_RX) && PinUsed(GPIO_ZIGBEE_TX) && (upload.buf[0] == 0xEB)) { // Check if this is a Zigbee bridge FW file
|
||||
#endif // ESP8266 or ESP32
|
||||
@ -2798,7 +2802,7 @@ void HandleUploadLoop(void)
|
||||
} else
|
||||
#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP
|
||||
#ifdef USE_RF_FLASH
|
||||
if ((SONOFF_BRIDGE == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a RF bridge FW file
|
||||
if ((SONOFF_BRIDGE == TasmotaGlobal.module_type) && (upload.buf[0] == ':')) { // Check if this is a RF bridge FW file
|
||||
Update.end(); // End esp8266 update session
|
||||
Web.upload_file_type = UPL_EFM8BB1;
|
||||
|
||||
@ -2986,7 +2990,7 @@ void HandleUploadLoop(void)
|
||||
|
||||
// ***** Step4: Abort upload file
|
||||
else if (UPLOAD_FILE_ABORTED == upload.status) {
|
||||
restart_flag = 0;
|
||||
TasmotaGlobal.restart_flag = 0;
|
||||
MqttRetryCounter(0);
|
||||
#ifdef USE_COUNTER
|
||||
CounterInterruptDisable(false);
|
||||
@ -3029,11 +3033,11 @@ void HandleHttpCommand(void)
|
||||
}
|
||||
|
||||
WSContentBegin(200, CT_JSON);
|
||||
uint32_t curridx = web_log_index;
|
||||
uint32_t curridx = TasmotaGlobal.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) {
|
||||
if (TasmotaGlobal.web_log_index != curridx) {
|
||||
uint32_t counter = curridx;
|
||||
WSContentSend_P(PSTR("{"));
|
||||
bool cflg = false;
|
||||
@ -3046,7 +3050,7 @@ void HandleHttpCommand(void)
|
||||
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); }
|
||||
if (JSONlen > sizeof(TasmotaGlobal.mqtt_data)) { JSONlen = sizeof(TasmotaGlobal.mqtt_data); }
|
||||
char stemp[JSONlen];
|
||||
strlcpy(stemp, JSON +1, JSONlen -2);
|
||||
WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp);
|
||||
@ -3056,7 +3060,7 @@ void HandleHttpCommand(void)
|
||||
counter++;
|
||||
counter &= 0xFF;
|
||||
if (!counter) counter++; // Skip 0 as it is not allowed
|
||||
} while (counter != web_log_index);
|
||||
} while (counter != TasmotaGlobal.web_log_index);
|
||||
WSContentSend_P(PSTR("}"));
|
||||
} else {
|
||||
WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}"));
|
||||
@ -3104,14 +3108,14 @@ void HandleConsoleRefresh(void)
|
||||
if (strlen(stmp)) { counter = atoi(stmp); }
|
||||
|
||||
WSContentBegin(200, CT_PLAIN);
|
||||
WSContentSend_P(PSTR("%d}1%d}1"), web_log_index, Web.reset_web_log_flag);
|
||||
WSContentSend_P(PSTR("%d}1%d}1"), TasmotaGlobal.web_log_index, Web.reset_web_log_flag);
|
||||
if (!Web.reset_web_log_flag) {
|
||||
counter = 0;
|
||||
Web.reset_web_log_flag = true;
|
||||
}
|
||||
if (counter != web_log_index) {
|
||||
if (counter != TasmotaGlobal.web_log_index) {
|
||||
if (!counter) {
|
||||
counter = web_log_index;
|
||||
counter = TasmotaGlobal.web_log_index;
|
||||
cflg = false;
|
||||
}
|
||||
do {
|
||||
@ -3119,7 +3123,7 @@ void HandleConsoleRefresh(void)
|
||||
size_t len;
|
||||
GetLog(counter, &tmp, &len);
|
||||
if (len) {
|
||||
if (len > sizeof(mqtt_data) -2) { len = sizeof(mqtt_data); }
|
||||
if (len > sizeof(TasmotaGlobal.mqtt_data) -2) { len = sizeof(TasmotaGlobal.mqtt_data); }
|
||||
char stemp[len +1];
|
||||
strlcpy(stemp, tmp, len);
|
||||
WSContentSend_P(PSTR("%s%s"), (cflg) ? "\n" : "", stemp);
|
||||
@ -3128,7 +3132,7 @@ void HandleConsoleRefresh(void)
|
||||
counter++;
|
||||
counter &= 0xFF;
|
||||
if (!counter) { counter++; } // Skip log index 0 as it is not allowed
|
||||
} while (counter != web_log_index);
|
||||
} while (counter != TasmotaGlobal.web_log_index);
|
||||
}
|
||||
WSContentSend_P(PSTR("}1"));
|
||||
WSContentEnd();
|
||||
@ -3264,11 +3268,11 @@ int WebSend(char *buffer)
|
||||
while (text != '\0') {
|
||||
text = *read++;
|
||||
if (text > 31) { // Remove control characters like linefeed
|
||||
mqtt_data[j++] = text;
|
||||
if (j == sizeof(mqtt_data) -2) { break; }
|
||||
TasmotaGlobal.mqtt_data[j++] = text;
|
||||
if (j == sizeof(TasmotaGlobal.mqtt_data) -2) { break; }
|
||||
}
|
||||
}
|
||||
mqtt_data[j] = '\0';
|
||||
TasmotaGlobal.mqtt_data[j] = '\0';
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_WEBSEND));
|
||||
#ifdef USE_SCRIPT
|
||||
extern uint8_t tasm_cmd_activ;
|
||||
@ -3355,7 +3359,7 @@ void CmndEmulation(void)
|
||||
#endif
|
||||
#endif
|
||||
Settings.flag2.emulation = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
#endif
|
||||
ResponseCmndNumber(Settings.flag2.emulation);
|
||||
|
||||
@ -210,12 +210,12 @@ bool MqttPublishLib(const char* topic, bool retained)
|
||||
if (!strcmp(SettingsText(SET_MQTTPREFIX1), SettingsText(SET_MQTTPREFIX2))) {
|
||||
char *str = strstr(topic, SettingsText(SET_MQTTPREFIX1));
|
||||
if (str == topic) {
|
||||
mqtt_cmnd_blocked_reset = 4; // Allow up to four seconds before resetting residual cmnd blocks
|
||||
mqtt_cmnd_blocked++;
|
||||
TasmotaGlobal.mqtt_cmnd_blocked_reset = 4; // Allow up to four seconds before resetting residual cmnd blocks
|
||||
TasmotaGlobal.mqtt_cmnd_blocked++;
|
||||
}
|
||||
}
|
||||
|
||||
bool result = MqttClient.publish(topic, mqtt_data, retained);
|
||||
bool result = MqttClient.publish(topic, TasmotaGlobal.mqtt_data, retained);
|
||||
yield(); // #3313
|
||||
return result;
|
||||
}
|
||||
@ -238,8 +238,8 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len
|
||||
// Do not execute multiple times if Prefix1 equals Prefix2
|
||||
if (!strcmp(SettingsText(SET_MQTTPREFIX1), SettingsText(SET_MQTTPREFIX2))) {
|
||||
char *str = strstr(mqtt_topic, SettingsText(SET_MQTTPREFIX1));
|
||||
if ((str == mqtt_topic) && mqtt_cmnd_blocked) {
|
||||
mqtt_cmnd_blocked--;
|
||||
if ((str == mqtt_topic) && TasmotaGlobal.mqtt_cmnd_blocked) {
|
||||
TasmotaGlobal.mqtt_cmnd_blocked--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -252,7 +252,7 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len
|
||||
memcpy(data, mqtt_data, sizeof(data));
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_MQTT D_DATA_SIZE " %d, \"%s %s\""), data_len, topic, data);
|
||||
// if (LOG_LEVEL_DEBUG_MORE <= seriallog_level) { Serial.println(data); }
|
||||
// if (LOG_LEVEL_DEBUG_MORE <= TasmotaGlobal.seriallog_level) { Serial.println(data); }
|
||||
MqttDumpData(topic, data, data_len); // Use a function to save stack space used by dump_data
|
||||
|
||||
// MQTT pre-processing
|
||||
@ -288,16 +288,16 @@ void MqttUnsubscribe(const char *topic)
|
||||
|
||||
void MqttPublishLogging(const char *mxtime)
|
||||
{
|
||||
char saved_mqtt_data[strlen(mqtt_data) +1];
|
||||
memcpy(saved_mqtt_data, mqtt_data, sizeof(saved_mqtt_data));
|
||||
char saved_mqtt_data[strlen(TasmotaGlobal.mqtt_data) +1];
|
||||
memcpy(saved_mqtt_data, TasmotaGlobal.mqtt_data, sizeof(saved_mqtt_data));
|
||||
|
||||
// ResponseTime_P(PSTR(",\"Log\":{\"%s\"}}"), log_data); // Will fail as some messages contain JSON
|
||||
Response_P(PSTR("%s%s"), mxtime, log_data); // No JSON and ugly!!
|
||||
// ResponseTime_P(PSTR(",\"Log\":{\"%s\"}}"), TasmotaGlobal.log_data); // Will fail as some messages contain JSON
|
||||
Response_P(PSTR("%s%s"), mxtime, TasmotaGlobal.log_data); // No JSON and ugly!!
|
||||
char stopic[TOPSZ];
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, PSTR("LOGGING"));
|
||||
GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, PSTR("LOGGING"));
|
||||
MqttPublishLib(stopic, false);
|
||||
|
||||
memcpy(mqtt_data, saved_mqtt_data, sizeof(saved_mqtt_data));
|
||||
memcpy(TasmotaGlobal.mqtt_data, saved_mqtt_data, sizeof(saved_mqtt_data));
|
||||
}
|
||||
|
||||
void MqttPublish(const char* topic, bool retained)
|
||||
@ -324,16 +324,16 @@ void MqttPublish(const char* topic, bool retained)
|
||||
}
|
||||
}
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%s = %s"), slog_type, (Settings.flag.mqtt_enabled) ? topic : strrchr(topic,'/')+1, mqtt_data); // SetOption3 - Enable MQTT
|
||||
if (strlen(log_data) >= (sizeof(log_data) - strlen(sretained) -1)) {
|
||||
log_data[sizeof(log_data) - strlen(sretained) -5] = '\0';
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s ..."), log_data);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s%s = %s"), slog_type, (Settings.flag.mqtt_enabled) ? topic : strrchr(topic,'/')+1, TasmotaGlobal.mqtt_data); // SetOption3 - Enable MQTT
|
||||
if (strlen(TasmotaGlobal.log_data) >= (sizeof(TasmotaGlobal.log_data) - strlen(sretained) -1)) {
|
||||
TasmotaGlobal.log_data[sizeof(TasmotaGlobal.log_data) - strlen(sretained) -5] = '\0';
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s ..."), TasmotaGlobal.log_data);
|
||||
}
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%s"), log_data, sretained);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s%s"), TasmotaGlobal.log_data, sretained);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
|
||||
if (Settings.ledstate &0x04) {
|
||||
blinks++;
|
||||
TasmotaGlobal.blinks++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retain
|
||||
romram[i] = toupper(romram[i]);
|
||||
}
|
||||
prefix &= 3;
|
||||
GetTopic_P(stopic, prefix, mqtt_topic, romram);
|
||||
GetTopic_P(stopic, prefix, TasmotaGlobal.mqtt_topic, romram);
|
||||
MqttPublish(stopic, retained);
|
||||
|
||||
#if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_AWS_IOT_LIGHT)
|
||||
@ -380,13 +380,13 @@ void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retain
|
||||
snprintf_P(romram, sizeof(romram), PSTR("$aws/things/%s/shadow/update"), topic2);
|
||||
|
||||
// copy buffer
|
||||
char *mqtt_save = (char*) malloc(strlen(mqtt_data)+1);
|
||||
char *mqtt_save = (char*) malloc(strlen(TasmotaGlobal.mqtt_data)+1);
|
||||
if (!mqtt_save) { return; } // abort
|
||||
strcpy(mqtt_save, mqtt_data);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"state\":{\"reported\":%s}}"), mqtt_save);
|
||||
strcpy(mqtt_save, TasmotaGlobal.mqtt_data);
|
||||
snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"state\":{\"reported\":%s}}"), mqtt_save);
|
||||
free(mqtt_save);
|
||||
|
||||
bool result = MqttClient.publish(romram, mqtt_data, false);
|
||||
bool result = MqttClient.publish(romram, TasmotaGlobal.mqtt_data, false);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "Updated shadow: %s"), romram);
|
||||
yield(); // #3313
|
||||
}
|
||||
@ -419,7 +419,7 @@ void MqttPublishPowerState(uint32_t device)
|
||||
char stopic[TOPSZ];
|
||||
char scommand[33];
|
||||
|
||||
if ((device < 1) || (device > devices_present)) { device = 1; }
|
||||
if ((device < 1) || (device > TasmotaGlobal.devices_present)) { device = 1; }
|
||||
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
if (IsModuleIfan() && (device > 1)) {
|
||||
@ -428,20 +428,20 @@ void MqttPublishPowerState(uint32_t device)
|
||||
DomoticzUpdateFanState(); // RC Button feedback
|
||||
#endif // USE_DOMOTICZ
|
||||
snprintf_P(scommand, sizeof(scommand), PSTR(D_CMND_FANSPEED));
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); // SetOption4 - Switch between MQTT RESULT or COMMAND
|
||||
GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); // SetOption4 - Switch between MQTT RESULT or COMMAND
|
||||
Response_P(S_JSON_COMMAND_NVALUE, scommand, GetFanspeed());
|
||||
MqttPublish(stopic);
|
||||
}
|
||||
} else {
|
||||
#endif // USE_SONOFF_IFAN
|
||||
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable); // SetOption26 - Switch between POWER or POWER1
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); // SetOption4 - Switch between MQTT RESULT or COMMAND
|
||||
Response_P(S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(power, device -1)));
|
||||
GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); // SetOption4 - Switch between MQTT RESULT or COMMAND
|
||||
Response_P(S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(TasmotaGlobal.power, device -1)));
|
||||
MqttPublish(stopic);
|
||||
|
||||
if (!Settings.flag4.only_json_message) { // SetOption90 - Disable non-json MQTT response
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
|
||||
Response_P(GetStateText(bitRead(power, device -1)));
|
||||
GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, scommand);
|
||||
Response_P(GetStateText(bitRead(TasmotaGlobal.power, device -1)));
|
||||
MqttPublish(stopic, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN
|
||||
}
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
@ -451,7 +451,7 @@ void MqttPublishPowerState(uint32_t device)
|
||||
|
||||
void MqttPublishAllPowerState(void)
|
||||
{
|
||||
for (uint32_t i = 1; i <= devices_present; i++) {
|
||||
for (uint32_t i = 1; i <= TasmotaGlobal.devices_present; i++) {
|
||||
MqttPublishPowerState(i);
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
if (IsModuleIfan()) { break; } // Report status of light relay only
|
||||
@ -463,11 +463,11 @@ void MqttPublishPowerBlinkState(uint32_t device)
|
||||
{
|
||||
char scommand[33];
|
||||
|
||||
if ((device < 1) || (device > devices_present)) {
|
||||
if ((device < 1) || (device > TasmotaGlobal.devices_present)) {
|
||||
device = 1;
|
||||
}
|
||||
Response_P(PSTR("{\"%s\":\"" D_JSON_BLINK " %s\"}"),
|
||||
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable), GetStateText(bitRead(blink_mask, device -1))); // SetOption26 - Switch between POWER or POWER1
|
||||
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable), GetStateText(bitRead(TasmotaGlobal.blink_mask, device -1))); // SetOption26 - Switch between POWER or POWER1
|
||||
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, S_RSLT_POWER);
|
||||
}
|
||||
@ -487,7 +487,7 @@ void MqttDisconnected(int state)
|
||||
MqttClient.disconnect();
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND), SettingsText(SET_MQTT_HOST), Settings.mqtt_port, state, Mqtt.retry_counter);
|
||||
rules_flag.mqtt_disconnected = 1;
|
||||
TasmotaGlobal.rules_flag.mqtt_disconnected = 1;
|
||||
}
|
||||
|
||||
void MqttConnected(void)
|
||||
@ -500,17 +500,17 @@ void MqttConnected(void)
|
||||
Mqtt.retry_counter = 0;
|
||||
Mqtt.connect_count++;
|
||||
|
||||
GetTopic_P(stopic, TELE, mqtt_topic, S_LWT);
|
||||
GetTopic_P(stopic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
Response_P(PSTR(MQTT_LWT_ONLINE));
|
||||
MqttPublish(stopic, true);
|
||||
|
||||
if (!Settings.flag4.only_json_message) { // SetOption90 - Disable non-json MQTT response
|
||||
// Satisfy iobroker (#299)
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
MqttPublishPrefixTopic_P(CMND, S_RSLT_POWER);
|
||||
}
|
||||
|
||||
GetTopic_P(stopic, CMND, mqtt_topic, PSTR("#"));
|
||||
GetTopic_P(stopic, CMND, TasmotaGlobal.mqtt_topic, PSTR("#"));
|
||||
MqttSubscribe(stopic);
|
||||
if (strstr_P(SettingsText(SET_MQTT_FULLTOPIC), MQTT_TOKEN_TOPIC) != nullptr) {
|
||||
uint32_t real_index = SET_MQTT_GRP_TOPIC;
|
||||
@ -532,7 +532,7 @@ void MqttConnected(void)
|
||||
if (ResetReason() != REASON_DEEP_SLEEP_AWAKE) {
|
||||
char stopic2[TOPSZ];
|
||||
Response_P(PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"),
|
||||
ModuleName().c_str(), my_version, my_image, GetFallbackTopic_P(stopic, ""), GetGroupTopic_P(stopic2, "", SET_MQTT_GRP_TOPIC));
|
||||
ModuleName().c_str(), TasmotaGlobal.version, TasmotaGlobal.image_name, GetFallbackTopic_P(stopic, ""), GetGroupTopic_P(stopic2, "", SET_MQTT_GRP_TOPIC));
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "1"));
|
||||
#ifdef USE_WEBSERVER
|
||||
if (Settings.webserver) {
|
||||
@ -558,16 +558,16 @@ void MqttConnected(void)
|
||||
|
||||
MqttPublishAllPowerState();
|
||||
if (Settings.tele_period) {
|
||||
tele_period = Settings.tele_period -5; // Enable TelePeriod in 5 seconds
|
||||
TasmotaGlobal.tele_period = Settings.tele_period -5; // Enable TelePeriod in 5 seconds
|
||||
}
|
||||
rules_flag.system_boot = 1;
|
||||
TasmotaGlobal.rules_flag.system_boot = 1;
|
||||
XdrvCall(FUNC_MQTT_INIT);
|
||||
}
|
||||
Mqtt.initial_connection_state = 0;
|
||||
|
||||
global_state.mqtt_down = 0;
|
||||
TasmotaGlobal.global_state.mqtt_down = 0;
|
||||
if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT
|
||||
rules_flag.mqtt_connected = 1;
|
||||
TasmotaGlobal.rules_flag.mqtt_connected = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -603,11 +603,20 @@ void MqttReconnect(void)
|
||||
UdpDisconnect();
|
||||
#endif // USE_EMULATION
|
||||
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_ATTEMPTING_CONNECTION));
|
||||
|
||||
Mqtt.connected = false;
|
||||
Mqtt.retry_counter = Settings.mqtt_retry;
|
||||
global_state.mqtt_down = 1;
|
||||
TasmotaGlobal.global_state.mqtt_down = 1;
|
||||
|
||||
#ifdef FIRMWARE_MINIMAL
|
||||
#ifndef USE_MQTT_TLS
|
||||
// Don't try to connect if MQTT requires TLS but TLS is not supported
|
||||
if (Settings.flag4.mqtt_tls) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_ATTEMPTING_CONNECTION));
|
||||
|
||||
char *mqtt_user = nullptr;
|
||||
char *mqtt_pwd = nullptr;
|
||||
@ -618,7 +627,7 @@ void MqttReconnect(void)
|
||||
mqtt_pwd = SettingsText(SET_MQTT_PWD);
|
||||
}
|
||||
|
||||
GetTopic_P(stopic, TELE, mqtt_topic, S_LWT);
|
||||
GetTopic_P(stopic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
Response_P(S_LWT_OFFLINE);
|
||||
|
||||
if (MqttClient.connected()) { MqttClient.disconnect(); }
|
||||
@ -678,7 +687,7 @@ void MqttReconnect(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (MqttClient.connect(mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, lwt_retain, mqtt_data, MQTT_CLEAN_SESSION)) {
|
||||
if (MqttClient.connect(TasmotaGlobal.mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, lwt_retain, TasmotaGlobal.mqtt_data, MQTT_CLEAN_SESSION)) {
|
||||
#ifdef USE_MQTT_TLS
|
||||
if (Mqtt.mqtt_tls) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connected in %d ms, max ThunkStack used %d"),
|
||||
@ -764,17 +773,17 @@ void MqttCheck(void)
|
||||
{
|
||||
if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT
|
||||
if (!MqttIsConnected()) {
|
||||
global_state.mqtt_down = 1;
|
||||
TasmotaGlobal.global_state.mqtt_down = 1;
|
||||
if (!Mqtt.retry_counter) {
|
||||
MqttReconnect();
|
||||
} else {
|
||||
Mqtt.retry_counter--;
|
||||
}
|
||||
} else {
|
||||
global_state.mqtt_down = 0;
|
||||
TasmotaGlobal.global_state.mqtt_down = 0;
|
||||
}
|
||||
} else {
|
||||
global_state.mqtt_down = 0;
|
||||
TasmotaGlobal.global_state.mqtt_down = 0;
|
||||
if (Mqtt.initial_connection_state) {
|
||||
MqttReconnect();
|
||||
}
|
||||
@ -810,7 +819,7 @@ void CmndMqttFingerprint(void)
|
||||
Settings.mqtt_fingerprint[XdrvMailbox.index -1][i] = strtol(p, &p, 16);
|
||||
}
|
||||
}
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndIdxChar(ToHex_P((unsigned char *)Settings.mqtt_fingerprint[XdrvMailbox.index -1], 20, fingerprint, sizeof(fingerprint), ' '));
|
||||
}
|
||||
@ -821,7 +830,7 @@ void CmndMqttUser(void)
|
||||
{
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
SettingsUpdateText(SET_MQTT_USER, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_USER : XdrvMailbox.data);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndChar(SettingsText(SET_MQTT_USER));
|
||||
}
|
||||
@ -831,7 +840,7 @@ void CmndMqttPassword(void)
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
SettingsUpdateText(SET_MQTT_PWD, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_PASS : XdrvMailbox.data);
|
||||
ResponseCmndChar(SettingsText(SET_MQTT_PWD));
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
} else {
|
||||
Response_P(S_JSON_COMMAND_ASTERISK, XdrvMailbox.command);
|
||||
}
|
||||
@ -849,7 +858,7 @@ void CmndMqttHost(void)
|
||||
{
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
SettingsUpdateText(SET_MQTT_HOST, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_HOST : XdrvMailbox.data);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndChar(SettingsText(SET_MQTT_HOST));
|
||||
}
|
||||
@ -858,7 +867,7 @@ void CmndMqttPort(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 65536)) {
|
||||
Settings.mqtt_port = (1 == XdrvMailbox.payload) ? MQTT_PORT : XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndNumber(Settings.mqtt_port);
|
||||
}
|
||||
@ -893,7 +902,7 @@ void CmndMqttClient(void)
|
||||
{
|
||||
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) {
|
||||
SettingsUpdateText(SET_MQTT_CLIENT, (SC_DEFAULT == Shortcut()) ? MQTT_CLIENT_ID : XdrvMailbox.data);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndChar(SettingsText(SET_MQTT_CLIENT));
|
||||
}
|
||||
@ -902,14 +911,14 @@ void CmndFullTopic(void)
|
||||
{
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
MakeValidMqtt(1, XdrvMailbox.data);
|
||||
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
|
||||
if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); }
|
||||
char stemp1[TOPSZ];
|
||||
strlcpy(stemp1, (SC_DEFAULT == Shortcut()) ? MQTT_FULLTOPIC : XdrvMailbox.data, sizeof(stemp1));
|
||||
if (strcmp(stemp1, SettingsText(SET_MQTT_FULLTOPIC))) {
|
||||
Response_P((Settings.flag.mqtt_offline) ? S_LWT_OFFLINE : ""); // SetOption10 - Control MQTT LWT message format
|
||||
MqttPublishPrefixTopic_P(TELE, S_LWT, true); // Offline or remove previous retained topic
|
||||
SettingsUpdateText(SET_MQTT_FULLTOPIC, stemp1);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
}
|
||||
ResponseCmndChar(SettingsText(SET_MQTT_FULLTOPIC));
|
||||
@ -925,7 +934,7 @@ void CmndPrefix(void)
|
||||
MakeValidMqtt(0, XdrvMailbox.data);
|
||||
SettingsUpdateText(SET_MQTTPREFIX1 + XdrvMailbox.index -1,
|
||||
(SC_DEFAULT == Shortcut()) ? (1==XdrvMailbox.index) ? SUB_PREFIX : (2==XdrvMailbox.index) ? PUB_PREFIX : PUB_PREFIX2 : XdrvMailbox.data);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndIdxChar(SettingsText(SET_MQTTPREFIX1 + XdrvMailbox.index -1));
|
||||
}
|
||||
@ -941,13 +950,13 @@ void CmndPublish(void)
|
||||
char stemp1[TOPSZ];
|
||||
strlcpy(stemp1, mqtt_part, sizeof(stemp1));
|
||||
if ((payload_part != nullptr) && strlen(payload_part)) {
|
||||
strlcpy(mqtt_data, payload_part, sizeof(mqtt_data));
|
||||
strlcpy(TasmotaGlobal.mqtt_data, payload_part, sizeof(TasmotaGlobal.mqtt_data));
|
||||
} else {
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
MqttPublish(stemp1, (XdrvMailbox.index == 2));
|
||||
// ResponseCmndDone();
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -958,7 +967,7 @@ void CmndGroupTopic(void)
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
uint32_t settings_text_index = (1 == XdrvMailbox.index) ? SET_MQTT_GRP_TOPIC : SET_MQTT_GRP_TOPIC2 + XdrvMailbox.index - 2;
|
||||
MakeValidMqtt(0, XdrvMailbox.data);
|
||||
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
|
||||
if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); }
|
||||
SettingsUpdateText(settings_text_index, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_GRPTOPIC : XdrvMailbox.data);
|
||||
|
||||
// Eliminate duplicates, have at least one and fill from index 1
|
||||
@ -996,7 +1005,7 @@ void CmndGroupTopic(void)
|
||||
}
|
||||
}
|
||||
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndAll(SET_MQTT_GRP_TOPIC, MAX_GROUP_TOPICS);
|
||||
}
|
||||
@ -1006,14 +1015,14 @@ void CmndTopic(void)
|
||||
{
|
||||
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) {
|
||||
MakeValidMqtt(0, XdrvMailbox.data);
|
||||
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
|
||||
if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); }
|
||||
char stemp1[TOPSZ];
|
||||
strlcpy(stemp1, (SC_DEFAULT == Shortcut()) ? MQTT_TOPIC : XdrvMailbox.data, sizeof(stemp1));
|
||||
if (strcmp(stemp1, SettingsText(SET_MQTT_TOPIC))) {
|
||||
Response_P((Settings.flag.mqtt_offline) ? S_LWT_OFFLINE : ""); // SetOption10 - Control MQTT LWT message format
|
||||
MqttPublishPrefixTopic_P(TELE, S_LWT, true); // Offline or remove previous retained topic
|
||||
SettingsUpdateText(SET_MQTT_TOPIC, stemp1);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
}
|
||||
ResponseCmndChar(SettingsText(SET_MQTT_TOPIC));
|
||||
@ -1023,10 +1032,10 @@ void CmndButtonTopic(void)
|
||||
{
|
||||
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) {
|
||||
MakeValidMqtt(0, XdrvMailbox.data);
|
||||
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
|
||||
if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); }
|
||||
switch (Shortcut()) {
|
||||
case SC_CLEAR: SettingsUpdateText(SET_MQTT_BUTTON_TOPIC, ""); break;
|
||||
case SC_DEFAULT: SettingsUpdateText(SET_MQTT_BUTTON_TOPIC, mqtt_topic); break;
|
||||
case SC_DEFAULT: SettingsUpdateText(SET_MQTT_BUTTON_TOPIC, TasmotaGlobal.mqtt_topic); break;
|
||||
case SC_USER: SettingsUpdateText(SET_MQTT_BUTTON_TOPIC, MQTT_BUTTON_TOPIC); break;
|
||||
default: SettingsUpdateText(SET_MQTT_BUTTON_TOPIC, XdrvMailbox.data);
|
||||
}
|
||||
@ -1038,10 +1047,10 @@ void CmndSwitchTopic(void)
|
||||
{
|
||||
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) {
|
||||
MakeValidMqtt(0, XdrvMailbox.data);
|
||||
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
|
||||
if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); }
|
||||
switch (Shortcut()) {
|
||||
case SC_CLEAR: SettingsUpdateText(SET_MQTT_SWITCH_TOPIC, ""); break;
|
||||
case SC_DEFAULT: SettingsUpdateText(SET_MQTT_SWITCH_TOPIC, mqtt_topic); break;
|
||||
case SC_DEFAULT: SettingsUpdateText(SET_MQTT_SWITCH_TOPIC, TasmotaGlobal.mqtt_topic); break;
|
||||
case SC_USER: SettingsUpdateText(SET_MQTT_SWITCH_TOPIC, MQTT_SWITCH_TOPIC); break;
|
||||
default: SettingsUpdateText(SET_MQTT_SWITCH_TOPIC, XdrvMailbox.data);
|
||||
}
|
||||
@ -1081,9 +1090,9 @@ void CmndPowerRetain(void)
|
||||
if (!XdrvMailbox.payload) {
|
||||
char stemp1[TOPSZ];
|
||||
char scommand[CMDSZ];
|
||||
for (uint32_t i = 1; i <= devices_present; i++) { // Clear MQTT retain in broker
|
||||
GetTopic_P(stemp1, STAT, mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand), Settings.flag.device_index_enable)); // SetOption26 - Switch between POWER or POWER1
|
||||
mqtt_data[0] = '\0';
|
||||
for (uint32_t i = 1; i <= TasmotaGlobal.devices_present; i++) { // Clear MQTT retain in broker
|
||||
GetTopic_P(stemp1, STAT, TasmotaGlobal.mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand), Settings.flag.device_index_enable)); // SetOption26 - Switch between POWER or POWER1
|
||||
ResponseClear();
|
||||
MqttPublish(stemp1, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN
|
||||
}
|
||||
}
|
||||
@ -1099,7 +1108,7 @@ void CmndSensorRetain(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
|
||||
if (!XdrvMailbox.payload) {
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); // CMND_SENSORRETAIN
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain); // CMND_SENSORRETAIN
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ void EnergyUpdateTotal(float value, bool kwh)
|
||||
|
||||
void Energy200ms(void)
|
||||
{
|
||||
Energy.power_on = (power != 0) | Settings.flag.no_power_on_check; // SetOption21 - Show voltage even if powered off
|
||||
Energy.power_on = (TasmotaGlobal.power != 0) | Settings.flag.no_power_on_check; // SetOption21 - Show voltage even if powered off
|
||||
|
||||
Energy.fifth_second++;
|
||||
if (5 == Energy.fifth_second) {
|
||||
@ -338,6 +338,8 @@ void EnergyMarginCheck(void)
|
||||
for (uint32_t phase = 0; phase < Energy.phase_count; phase++) {
|
||||
uint16_t active_power = (uint16_t)(Energy.active_power[phase]);
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("NRG: APower %d, HPower0 %d, HPower1 %d, HPower2 %d"), active_power, Energy.power_history[phase][0], Energy.power_history[phase][1], Energy.power_history[phase][2]);
|
||||
|
||||
if (Settings.energy_power_delta[phase]) {
|
||||
power_diff[phase] = active_power - Energy.power_history[phase][0];
|
||||
uint16_t delta = abs(power_diff[phase]);
|
||||
@ -437,12 +439,12 @@ void EnergyMarginCheck(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (power && (energy_power_u <= Settings.energy_max_power_limit)) {
|
||||
else if (TasmotaGlobal.power && (energy_power_u <= Settings.energy_max_power_limit)) {
|
||||
Energy.mplh_counter = 0;
|
||||
Energy.mplr_counter = 0;
|
||||
Energy.mplw_counter = 0;
|
||||
}
|
||||
if (!power) {
|
||||
if (!TasmotaGlobal.power) {
|
||||
if (Energy.mplw_counter) {
|
||||
Energy.mplw_counter--;
|
||||
} else {
|
||||
@ -488,12 +490,12 @@ void EnergyMarginCheck(void)
|
||||
void EnergyMqttShow(void)
|
||||
{
|
||||
// {"Time":"2017-12-16T11:48:55","ENERGY":{"Total":0.212,"Yesterday":0.000,"Today":0.014,"Period":2.0,"Power":22.0,"Factor":1.00,"Voltage":213.6,"Current":0.100}}
|
||||
int tele_period_save = tele_period;
|
||||
tele_period = 2;
|
||||
mqtt_data[0] = '\0';
|
||||
int tele_period_save = TasmotaGlobal.tele_period;
|
||||
TasmotaGlobal.tele_period = 2;
|
||||
ResponseClear();
|
||||
ResponseAppendTime();
|
||||
EnergyShow(true);
|
||||
tele_period = tele_period_save;
|
||||
TasmotaGlobal.tele_period = tele_period_save;
|
||||
ResponseJsonEnd();
|
||||
MqttPublishTeleSensor();
|
||||
}
|
||||
@ -502,11 +504,11 @@ void EnergyMqttShow(void)
|
||||
void EnergyEverySecond(void)
|
||||
{
|
||||
// Overtemp check
|
||||
if (global_update) {
|
||||
if (power && !isnan(global_temperature_celsius) && (global_temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays
|
||||
if (TasmotaGlobal.global_update) {
|
||||
if (TasmotaGlobal.power && !isnan(TasmotaGlobal.temperature_celsius) && (TasmotaGlobal.temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays
|
||||
|
||||
char temperature[33];
|
||||
dtostrfd(global_temperature_celsius, 1, temperature);
|
||||
dtostrfd(TasmotaGlobal.temperature_celsius, 1, temperature);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %s"), temperature);
|
||||
|
||||
SetAllPower(POWER_ALL_OFF, SRC_OVERTEMP);
|
||||
@ -896,7 +898,7 @@ void EnergySnsInit(void)
|
||||
{
|
||||
XnrgCall(FUNC_INIT);
|
||||
|
||||
if (energy_flg) {
|
||||
if (TasmotaGlobal.energy_driver) {
|
||||
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()) {
|
||||
@ -1031,7 +1033,7 @@ void EnergyShow(bool json)
|
||||
char value3_chr[FLOATSZ *3];
|
||||
|
||||
if (json) {
|
||||
bool show_energy_period = (0 == tele_period);
|
||||
bool show_energy_period = (0 == TasmotaGlobal.tele_period);
|
||||
|
||||
ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s"),
|
||||
GetDateAndTime(DT_ENERGY).c_str(),
|
||||
@ -1178,16 +1180,18 @@ bool Xdrv03(uint8_t function)
|
||||
bool result = false;
|
||||
|
||||
if (FUNC_PRE_INIT == function) {
|
||||
energy_flg = ENERGY_NONE;
|
||||
TasmotaGlobal.energy_driver = ENERGY_NONE;
|
||||
XnrgCall(FUNC_PRE_INIT); // Find first energy driver
|
||||
}
|
||||
else if (energy_flg) {
|
||||
else if (TasmotaGlobal.energy_driver) {
|
||||
switch (function) {
|
||||
case FUNC_LOOP:
|
||||
XnrgCall(FUNC_LOOP);
|
||||
break;
|
||||
case FUNC_EVERY_250_MSECOND:
|
||||
XnrgCall(FUNC_EVERY_250_MSECOND);
|
||||
if (TasmotaGlobal.uptime > 4) {
|
||||
XnrgCall(FUNC_EVERY_250_MSECOND);
|
||||
}
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
XnrgCall(FUNC_EVERY_SECOND);
|
||||
@ -1212,7 +1216,7 @@ bool Xsns03(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (energy_flg) {
|
||||
if (TasmotaGlobal.energy_driver) {
|
||||
switch (function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
EnergyEverySecond();
|
||||
|
||||
@ -572,7 +572,7 @@ class LightStateClass {
|
||||
_briRGB = bri_rgb;
|
||||
if (bri_rgb > 0) { addRGBMode(); }
|
||||
#ifdef USE_PWM_DIMMER
|
||||
if (PWM_DIMMER == my_module_type) PWMDimmerSetBrightnessLeds(-1);
|
||||
if (PWM_DIMMER == TasmotaGlobal.module_type) PWMDimmerSetBrightnessLeds(-1);
|
||||
#endif // USE_PWM_DIMMER
|
||||
return prev_bri;
|
||||
}
|
||||
@ -583,7 +583,7 @@ class LightStateClass {
|
||||
_briCT = bri_ct;
|
||||
if (bri_ct > 0) { addCTMode(); }
|
||||
#ifdef USE_PWM_DIMMER
|
||||
if (PWM_DIMMER == my_module_type) PWMDimmerSetBrightnessLeds(-1);
|
||||
if (PWM_DIMMER == TasmotaGlobal.module_type) PWMDimmerSetBrightnessLeds(-1);
|
||||
#endif // USE_PWM_DIMMER
|
||||
return prev_bri;
|
||||
}
|
||||
@ -973,7 +973,7 @@ public:
|
||||
Settings.light_color[0], Settings.light_color[1], Settings.light_color[2],
|
||||
Settings.light_color[3], Settings.light_color[4], Settings.light_dimmer);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, "LightControllerClass::loadSettings light_type/sub (%d %d)",
|
||||
light_type, Light.subtype);
|
||||
TasmotaGlobal.light_type, Light.subtype);
|
||||
#endif
|
||||
if (_pwm_multi_channels) {
|
||||
_state->setChannelsRaw(Settings.light_color);
|
||||
@ -1246,64 +1246,64 @@ void LightPwmOffset(uint32_t offset)
|
||||
|
||||
bool LightModuleInit(void)
|
||||
{
|
||||
light_type = LT_BASIC; // Use basic PWM control if SetOption15 = 0
|
||||
TasmotaGlobal.light_type = LT_BASIC; // Use basic PWM control if SetOption15 = 0
|
||||
|
||||
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 (PinUsed(GPIO_PWM1, i)) { light_type++; } // Use Dimmer/Color control for all PWM as SetOption15 = 1
|
||||
if (PinUsed(GPIO_PWM1, i)) { TasmotaGlobal.light_type++; } // Use Dimmer/Color control for all PWM as SetOption15 = 1
|
||||
}
|
||||
}
|
||||
|
||||
light_flg = 0;
|
||||
TasmotaGlobal.light_driver = 0;
|
||||
if (XlgtCall(FUNC_MODULE_INIT)) {
|
||||
// serviced
|
||||
}
|
||||
#ifdef ESP8266
|
||||
else if (SONOFF_BN == my_module_type) { // PWM Single color led (White)
|
||||
light_type = LT_PWM1;
|
||||
else if (SONOFF_BN == TasmotaGlobal.module_type) { // PWM Single color led (White)
|
||||
TasmotaGlobal.light_type = LT_PWM1;
|
||||
}
|
||||
else if (SONOFF_LED == my_module_type) { // PWM Dual color led (White warm and cold)
|
||||
if (!my_module.io[4]) { // Fix Sonoff Led instabilities
|
||||
else if (SONOFF_LED == TasmotaGlobal.module_type) { // PWM Dual color led (White warm and cold)
|
||||
if (!TasmotaGlobal.my_module.io[4]) { // Fix Sonoff Led instabilities
|
||||
pinMode(4, OUTPUT); // Stop floating outputs
|
||||
digitalWrite(4, LOW);
|
||||
}
|
||||
if (!my_module.io[5]) {
|
||||
if (!TasmotaGlobal.my_module.io[5]) {
|
||||
pinMode(5, OUTPUT); // Stop floating outputs
|
||||
digitalWrite(5, LOW);
|
||||
}
|
||||
if (!my_module.io[14]) {
|
||||
if (!TasmotaGlobal.my_module.io[14]) {
|
||||
pinMode(14, OUTPUT); // Stop floating outputs
|
||||
digitalWrite(14, LOW);
|
||||
}
|
||||
light_type = LT_PWM2;
|
||||
TasmotaGlobal.light_type = LT_PWM2;
|
||||
}
|
||||
#endif // ESP8266
|
||||
#ifdef USE_PWM_DIMMER
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
else if (PWM_DIMMER == my_module_type) {
|
||||
light_type = Settings.pwm_dimmer_cfg.pwm_count + 1;
|
||||
else if (PWM_DIMMER == TasmotaGlobal.module_type) {
|
||||
TasmotaGlobal.light_type = Settings.pwm_dimmer_cfg.pwm_count + 1;
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
#endif // USE_PWM_DIMMER
|
||||
|
||||
if (light_type > LT_BASIC) {
|
||||
devices_present++;
|
||||
if (TasmotaGlobal.light_type > LT_BASIC) {
|
||||
TasmotaGlobal.devices_present++;
|
||||
}
|
||||
|
||||
// post-process for lights
|
||||
uint32_t pwm_channels = (light_type & 7) > LST_MAX ? LST_MAX : (light_type & 7);
|
||||
uint32_t pwm_channels = (TasmotaGlobal.light_type & 7) > LST_MAX ? LST_MAX : (TasmotaGlobal.light_type & 7);
|
||||
if (Settings.flag3.pwm_multi_channels) { // SetOption68 - Enable multi-channels PWM instead of Color PWM
|
||||
if (0 == pwm_channels) { pwm_channels = 1; }
|
||||
devices_present += pwm_channels - 1; // add the pwm channels controls at the end
|
||||
TasmotaGlobal.devices_present += pwm_channels - 1; // add the pwm channels controls at the end
|
||||
} else if ((Settings.param[P_RGB_REMAP] & 128) && (LST_RGBW <= pwm_channels)) {
|
||||
// if RGBW or RGBCW, and SetOption37 >= 128, we manage RGB and W separately, hence adding a device
|
||||
devices_present++;
|
||||
TasmotaGlobal.devices_present++;
|
||||
} else if ((Settings.flag4.virtual_ct) && (LST_RGBW == pwm_channels)) {
|
||||
Light.virtual_ct = true; // enabled
|
||||
light_type++; // create an additional virtual 5th channel
|
||||
TasmotaGlobal.light_type++; // create an additional virtual 5th channel
|
||||
}
|
||||
|
||||
return (light_type > LT_BASIC);
|
||||
return (TasmotaGlobal.light_type > LT_BASIC);
|
||||
}
|
||||
|
||||
// compute actual PWM min/max values from DimmerRange
|
||||
@ -1333,8 +1333,8 @@ void LightInit(void)
|
||||
Settings.rgbwwTable[4] = 255; // set RGBWWTable value to its default
|
||||
}
|
||||
|
||||
Light.device = devices_present;
|
||||
Light.subtype = (light_type & 7) > LST_MAX ? LST_MAX : (light_type & 7); // Always 0 - LST_MAX (5)
|
||||
Light.device = TasmotaGlobal.devices_present;
|
||||
Light.subtype = (TasmotaGlobal.light_type & 7) > LST_MAX ? LST_MAX : (TasmotaGlobal.light_type & 7); // Always 0 - LST_MAX (5)
|
||||
Light.pwm_multi_channels = Settings.flag3.pwm_multi_channels; // SetOption68 - Enable multi-channels PWM instead of Color PWM
|
||||
|
||||
if (LST_RGBW <= Light.subtype) {
|
||||
@ -1347,15 +1347,15 @@ void LightInit(void)
|
||||
if ((LST_SINGLE <= Light.subtype) && Light.pwm_multi_channels) {
|
||||
// we treat each PWM channel as an independant one, hence we switch to
|
||||
light_controller.setPWMMultiChannel(true);
|
||||
Light.device = devices_present - Light.subtype + 1; // adjust if we also have relays
|
||||
Light.device = TasmotaGlobal.devices_present - Light.subtype + 1; // adjust if we also have relays
|
||||
} else if (!light_controller.isCTRGBLinked()) {
|
||||
// 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);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, "LightInit Light.pwm_multi_channels=%d Light.subtype=%d Light.device=%d TasmotaGlobal.devices_present=%d",
|
||||
Light.pwm_multi_channels, Light.subtype, Light.device, TasmotaGlobal.devices_present);
|
||||
#endif
|
||||
|
||||
light_controller.setSubType(Light.subtype);
|
||||
@ -1366,8 +1366,8 @@ void LightInit(void)
|
||||
if (LST_SINGLE == Light.subtype) {
|
||||
Settings.light_color[0] = 255; // One channel only supports Dimmer but needs max color
|
||||
}
|
||||
if (light_type < LT_PWM6) { // PWM
|
||||
for (uint32_t i = 0; i < light_type; i++) {
|
||||
if (TasmotaGlobal.light_type < LT_PWM6) { // PWM
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.light_type; i++) {
|
||||
Settings.pwm_value[i] = 0; // Disable direct PWM control
|
||||
if (PinUsed(GPIO_PWM1, i)) {
|
||||
#ifdef ESP8266
|
||||
@ -1457,7 +1457,7 @@ void LightHsToRgb(uint16_t hue, uint8_t sat, uint8_t *r_r, uint8_t *r_g, uint8_t
|
||||
uint8_t LightGetBri(uint8_t device) {
|
||||
uint8_t bri = 254; // default value if relay
|
||||
if (Light.pwm_multi_channels) {
|
||||
if ((device >= Light.device) && (device < Light.device + LST_MAX) && (device <= devices_present)) {
|
||||
if ((device >= Light.device) && (device < Light.device + LST_MAX) && (device <= TasmotaGlobal.devices_present)) {
|
||||
bri = Light.current_color[device - Light.device];
|
||||
}
|
||||
} else if (light_controller.isCTRGBLinked()) { // standard behavior
|
||||
@ -1477,7 +1477,7 @@ uint8_t LightGetBri(uint8_t device) {
|
||||
// If SetOption68 is set, set the brightness for a specific device
|
||||
void LightSetBri(uint8_t device, uint8_t bri) {
|
||||
if (Light.pwm_multi_channels) {
|
||||
if ((device >= Light.device) && (device < Light.device + LST_MAX) && (device <= devices_present)) {
|
||||
if ((device >= Light.device) && (device < Light.device + LST_MAX) && (device <= TasmotaGlobal.devices_present)) {
|
||||
Light.current_color[device - Light.device] = bri;
|
||||
light_controller.changeChannels(Light.current_color);
|
||||
}
|
||||
@ -1668,7 +1668,7 @@ void ResponseLightState(uint8_t append)
|
||||
|
||||
void LightPreparePower(power_t channels = 0xFFFFFFFF) { // 1 = only RGB, 2 = only CT, 3 = both RGB and CT
|
||||
#ifdef DEBUG_LIGHT
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "LightPreparePower power=%d Light.power=%d", power, Light.power);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "LightPreparePower power=%d Light.power=%d", TasmotaGlobal.power, Light.power);
|
||||
#endif
|
||||
// If multi-channels, then we only switch off channels with a value of zero
|
||||
if (Light.pwm_multi_channels) {
|
||||
@ -1731,9 +1731,9 @@ void LightPreparePower(power_t channels = 0xFFFFFFFF) { // 1 = only RGB, 2 =
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LIGHT
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "LightPreparePower End power=%d Light.power=%d", power, Light.power);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "LightPreparePower End power=%d Light.power=%d", TasmotaGlobal.power, Light.power);
|
||||
#endif
|
||||
Light.power = power >> (Light.device - 1); // reset next state, works also with unlinked RGB/CT
|
||||
Light.power = TasmotaGlobal.power >> (Light.device - 1); // reset next state, works also with unlinked RGB/CT
|
||||
ResponseLightState(0);
|
||||
}
|
||||
|
||||
@ -1825,10 +1825,10 @@ void LightSetPower(void)
|
||||
}
|
||||
uint32_t shift = Light.device - 1;
|
||||
// If PWM multi_channels
|
||||
// Ex: 3 Relays and 4 PWM - devices_present = 7, Light.device = 4, Light.subtype = 4
|
||||
// Ex: 3 Relays and 4 PWM - TasmotaGlobal.devices_present = 7, Light.device = 4, Light.subtype = 4
|
||||
// Result: mask = 0b00001111 = 0x0F, shift = 3.
|
||||
// Power bits we consider are: 0b01111000 = 0x78
|
||||
// If regular situation: devices_present == Light.subtype
|
||||
// If regular situation: TasmotaGlobal.devices_present == Light.subtype
|
||||
Light.power = (XdrvMailbox.index & (mask << shift)) >> shift;
|
||||
if (Light.wakeup_active) {
|
||||
Light.wakeup_active--;
|
||||
@ -1859,12 +1859,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) {
|
||||
ssleep = PWM_MAX_SLEEP; // set a maxumum value of 10 milliseconds to ensure that animations are smooth
|
||||
TasmotaGlobal.sleep = PWM_MAX_SLEEP; // set a maxumum value of 10 milliseconds to ensure that animations are smooth
|
||||
} else {
|
||||
ssleep = Settings.sleep; // or keep the current sleep if it's lower than 50
|
||||
TasmotaGlobal.sleep = Settings.sleep; // or keep the current sleep if it's lower than 50
|
||||
}
|
||||
} else {
|
||||
ssleep = Settings.sleep;
|
||||
TasmotaGlobal.sleep = Settings.sleep;
|
||||
}
|
||||
|
||||
if (!Light.power) { // All channels powered off
|
||||
@ -2035,7 +2035,7 @@ void LightAnimate(void)
|
||||
cur_col_10[i] = orig_col_10bits[Light.color_remap[i]];
|
||||
}
|
||||
|
||||
if (!Settings.light_fade || skip_light_fade || power_off || (!Light.fade_initialized)) { // no fade
|
||||
if (!Settings.light_fade || TasmotaGlobal.skip_light_fade || power_off || (!Light.fade_initialized)) { // no fade
|
||||
// record the current value for a future Fade
|
||||
memcpy(Light.fade_start_10, cur_col_10, sizeof(Light.fade_start_10));
|
||||
// push the final values at 8 and 10 bits resolution to the PWMs
|
||||
@ -2063,7 +2063,7 @@ void LightAnimate(void)
|
||||
}
|
||||
#ifdef USE_PWM_DIMMER
|
||||
// If the power is off and the fade is done, turn the relay off.
|
||||
if (PWM_DIMMER == my_module_type && !Light.power && !Light.fade_running) PWMDimmerSetPower();
|
||||
if (PWM_DIMMER == TasmotaGlobal.module_type && !Light.power && !Light.fade_running) PWMDimmerSetPower();
|
||||
#endif // USE_PWM_DIMMER
|
||||
}
|
||||
}
|
||||
@ -2072,7 +2072,7 @@ bool isChannelGammaCorrected(uint32_t channel) {
|
||||
if (!Settings.light_correction) { return false; } // Gamma correction not activated
|
||||
if (channel >= Light.subtype) { return false; } // Out of range
|
||||
#ifdef ESP8266
|
||||
if ((PHILIPS == my_module_type) || (Settings.flag4.pwm_ct_mode)) {
|
||||
if ((PHILIPS == TasmotaGlobal.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
|
||||
}
|
||||
@ -2083,7 +2083,7 @@ bool isChannelGammaCorrected(uint32_t channel) {
|
||||
// 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 ((PHILIPS == TasmotaGlobal.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
|
||||
}
|
||||
@ -2134,9 +2134,9 @@ bool LightApplyFade(void) { // did the value chanegd and needs to be applied
|
||||
if (Settings.save_data) {
|
||||
// Also postpone the save_data for the duration of the Fade (in seconds)
|
||||
uint32_t delay_seconds = 1 + (Light.fade_duration + 999) / 1000; // add one more second
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR("delay_seconds %d, save_data_counter %d"), delay_seconds, save_data_counter);
|
||||
if (save_data_counter < delay_seconds) {
|
||||
save_data_counter = delay_seconds; // pospone
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR("delay_seconds %d, save_data_counter %d"), delay_seconds, TasmotaGlobal.save_data_counter);
|
||||
if (TasmotaGlobal.save_data_counter < delay_seconds) {
|
||||
TasmotaGlobal.save_data_counter = delay_seconds; // pospone
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2207,7 +2207,7 @@ void LightApplyPower(uint8_t new_color[LST_MAX], power_t power) {
|
||||
|
||||
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...
|
||||
if (TasmotaGlobal.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 (PinUsed(GPIO_PWM1, i)) {
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Cur_Col%d 10 bits %d"), i, cur_col_10[i]);
|
||||
@ -2216,7 +2216,7 @@ void LightSetOutputs(const uint16_t *cur_col_10) {
|
||||
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);
|
||||
analogWrite(Pin(GPIO_PWM1, i), bitRead(TasmotaGlobal.pwm_inverted, i) ? Settings.pwm_range - cur_col : cur_col);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2269,7 +2269,7 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) {
|
||||
uint16_t white_bri10_1023 = (white_bri10 > 1023) ? 1023 : white_bri10; // max 1023
|
||||
|
||||
#ifdef ESP8266
|
||||
if ((PHILIPS == my_module_type) || (Settings.flag4.pwm_ct_mode)) { // channel 1 is the color tone, mapped to cold channel (0..255)
|
||||
if ((PHILIPS == TasmotaGlobal.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
|
||||
@ -2833,7 +2833,7 @@ void CmndDimmer(void)
|
||||
// Dimmer<x> - - Decrement Dimmer in steps of 10
|
||||
uint32_t dimmer;
|
||||
if (XdrvMailbox.index == 3) {
|
||||
skip_light_fade = true;
|
||||
TasmotaGlobal.skip_light_fade = true;
|
||||
XdrvMailbox.index = 0;
|
||||
}
|
||||
else if (XdrvMailbox.index > 2) {
|
||||
@ -2878,11 +2878,11 @@ void CmndDimmer(void)
|
||||
}
|
||||
#endif // USE_PWM_DIMMER && USE_DEVICE_GROUPS
|
||||
Light.update = true;
|
||||
if (skip_light_fade) LightAnimate();
|
||||
if (TasmotaGlobal.skip_light_fade) LightAnimate();
|
||||
} else {
|
||||
ResponseCmndNumber(dimmer);
|
||||
}
|
||||
skip_light_fade = false;
|
||||
TasmotaGlobal.skip_light_fade = false;
|
||||
}
|
||||
|
||||
void CmndDimmerRange(void)
|
||||
@ -3093,7 +3093,7 @@ void CmndUndocA(void)
|
||||
scolor[6] = '\0'; // RGB only
|
||||
Response_P(PSTR("%s,%d,%d,%d,%d,%d"), scolor, Settings.light_fade, Settings.light_correction, Settings.light_scheme, Settings.light_speed, Settings.light_width);
|
||||
MqttPublishPrefixTopic_P(STAT, XdrvMailbox.topic);
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -3107,7 +3107,7 @@ bool Xdrv04(uint8_t function)
|
||||
if (FUNC_MODULE_INIT == function) {
|
||||
return LightModuleInit();
|
||||
}
|
||||
else if (light_type) {
|
||||
else if (TasmotaGlobal.light_type) {
|
||||
switch (function) {
|
||||
case FUNC_SERIAL:
|
||||
result = XlgtCall(FUNC_SERIAL);
|
||||
|
||||
@ -62,7 +62,7 @@ def ir_expand(ir_compact):
|
||||
#include <IRremoteESP8266.h>
|
||||
#include <IRutils.h>
|
||||
|
||||
enum IrErrors { IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND };
|
||||
enum IrErrors { IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND, IE_PROTO_UNSUPPORTED };
|
||||
|
||||
const char kIrRemoteCommands[] PROGMEM = "|" D_CMND_IRSEND ;
|
||||
|
||||
@ -72,7 +72,7 @@ void (* const IrRemoteCommand[])(void) PROGMEM = {
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Class used to make a compact IR Raw format.
|
||||
*
|
||||
*
|
||||
* We round timings to the closest 10ms value,
|
||||
* and store up to last 26 values with seen.
|
||||
* A value already seen is encoded with a letter indicating the position in the table.
|
||||
@ -215,7 +215,7 @@ void IrReceiveCheck(void)
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IR_RAWDATA "\":\""));
|
||||
size_t rawlen = results.rawlen;
|
||||
uint32_t i;
|
||||
|
||||
|
||||
for (i = 1; i < rawlen; i++) {
|
||||
// round to closest 10ms
|
||||
uint32_t raw_val_millis = results.rawbuf[i] * kRawTick;
|
||||
@ -232,7 +232,7 @@ void IrReceiveCheck(void)
|
||||
prev_number = true;
|
||||
}
|
||||
ir_high = !ir_high;
|
||||
if (strlen(mqtt_data) > sizeof(mqtt_data) - 40) { break; } // Quit if char string becomes too long
|
||||
if (strlen(TasmotaGlobal.mqtt_data) > sizeof(TasmotaGlobal.mqtt_data) - 40) { break; } // Quit if char string becomes too long
|
||||
}
|
||||
uint16_t extended_length = getCorrectedRawLength(&results);
|
||||
ResponseAppend_P(PSTR("\",\"" D_JSON_IR_RAWDATA "Info\":[%d,%d,%d]"), extended_length, i -1, results.overflow);
|
||||
@ -274,7 +274,7 @@ uint32_t IrRemoteCmndIrSendJson(void)
|
||||
uint16_t bits = root.getUInt(PSTR(D_JSON_IR_BITS), 0);
|
||||
uint64_t data = root.getULong(PSTR(D_JSON_IR_DATA), 0);
|
||||
uint16_t repeat = root.getUInt(PSTR(D_JSON_IR_REPEAT), 0);
|
||||
|
||||
|
||||
// check if the IRSend<x> is great than repeat
|
||||
if (XdrvMailbox.index > repeat + 1) {
|
||||
repeat = XdrvMailbox.index - 1;
|
||||
@ -307,7 +307,7 @@ uint32_t IrRemoteCmndIrSendJson(void)
|
||||
#endif
|
||||
default:
|
||||
irsend_active = false;
|
||||
ResponseCmndChar(D_JSON_PROTOCOL_NOT_SUPPORTED);
|
||||
return IE_PROTO_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return IE_NO_ERROR;
|
||||
@ -336,6 +336,9 @@ void IrRemoteCmndResponse(uint32_t error)
|
||||
case IE_INVALID_JSON:
|
||||
ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON));
|
||||
break;
|
||||
case IE_PROTO_UNSUPPORTED:
|
||||
ResponseCmndChar(D_JSON_PROTOCOL_NOT_SUPPORTED);
|
||||
break;
|
||||
case IE_SYNTAX_IRSEND:
|
||||
Response_P(PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_NO " " D_JSON_IR_PROTOCOL ", " D_JSON_IR_BITS " " D_JSON_OR " " D_JSON_IR_DATA "\"}"));
|
||||
break;
|
||||
|
||||
@ -76,7 +76,7 @@ void (* const IrRemoteCommand[])(void) PROGMEM = {
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Class used to make a compact IR Raw format.
|
||||
*
|
||||
*
|
||||
* We round timings to the closest 10ms value,
|
||||
* and store up to last 26 values with seen.
|
||||
* A value already seen is encoded with a letter indicating the position in the table.
|
||||
@ -303,7 +303,7 @@ void IrReceiveCheck(void)
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IR_RAWDATA "\":\""));
|
||||
size_t rawlen = results.rawlen;
|
||||
uint32_t i;
|
||||
|
||||
|
||||
for (i = 1; i < rawlen; i++) {
|
||||
// round to closest 10ms
|
||||
uint32_t raw_val_millis = results.rawbuf[i] * kRawTick;
|
||||
@ -320,7 +320,7 @@ void IrReceiveCheck(void)
|
||||
prev_number = true;
|
||||
}
|
||||
ir_high = !ir_high;
|
||||
if (strlen(mqtt_data) > sizeof(mqtt_data) - 40) { break; } // Quit if char string becomes too long
|
||||
if (strlen(TasmotaGlobal.mqtt_data) > sizeof(TasmotaGlobal.mqtt_data) - 40) { break; } // Quit if char string becomes too long
|
||||
}
|
||||
uint16_t extended_length = getCorrectedRawLength(&results);
|
||||
ResponseAppend_P(PSTR("\",\"" D_JSON_IR_RAWDATA "Info\":[%d,%d,%d]"), extended_length, i -1, results.overflow);
|
||||
@ -646,7 +646,7 @@ uint32_t IrRemoteSendRawFormatted(char ** pp, uint32_t count, uint32_t repeat) {
|
||||
return IE_NO_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Parse data as compact or standard form
|
||||
//
|
||||
// In:
|
||||
|
||||
@ -213,14 +213,14 @@ void SonoffBridgeReceivedRaw(void)
|
||||
// Decoding according to https://github.com/Portisch/RF-Bridge-EFM8BB1
|
||||
uint8_t buckets = 0;
|
||||
|
||||
if (0xB1 == serial_in_buffer[1]) { buckets = serial_in_buffer[2] << 1; } // Bucket sniffing
|
||||
if (0xB1 == TasmotaGlobal.serial_in_buffer[1]) { buckets = TasmotaGlobal.serial_in_buffer[2] << 1; } // Bucket sniffing
|
||||
|
||||
ResponseTime_P(PSTR(",\"" D_CMND_RFRAW "\":{\"" D_JSON_DATA "\":\""));
|
||||
for (uint32_t i = 0; i < serial_in_byte_counter; i++) {
|
||||
ResponseAppend_P(PSTR("%02X"), serial_in_buffer[i]);
|
||||
if (0xB1 == serial_in_buffer[1]) {
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.serial_in_byte_counter; i++) {
|
||||
ResponseAppend_P(PSTR("%02X"), TasmotaGlobal.serial_in_buffer[i]);
|
||||
if (0xB1 == TasmotaGlobal.serial_in_buffer[1]) {
|
||||
if ((i > 3) && buckets) { buckets--; }
|
||||
if ((i < 3) || (buckets % 2) || (i == serial_in_byte_counter -2)) {
|
||||
if ((i < 3) || (buckets % 2) || (i == TasmotaGlobal.serial_in_byte_counter -2)) {
|
||||
ResponseAppend_P(PSTR(" "));
|
||||
}
|
||||
}
|
||||
@ -249,16 +249,16 @@ void SonoffBridgeReceived(void)
|
||||
|
||||
AddLogSerial(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (0xA2 == serial_in_buffer[0]) { // Learn timeout
|
||||
if (0xA2 == TasmotaGlobal.serial_in_buffer[0]) { // Learn timeout
|
||||
SonoffBridgeLearnFailed();
|
||||
}
|
||||
else if (0xA3 == serial_in_buffer[0]) { // Learned A3 20 F8 01 18 03 3E 2E 1A 22 55
|
||||
else if (0xA3 == TasmotaGlobal.serial_in_buffer[0]) { // Learned A3 20 F8 01 18 03 3E 2E 1A 22 55
|
||||
SnfBridge.learn_active = 0;
|
||||
low_time = serial_in_buffer[3] << 8 | serial_in_buffer[4]; // Low time in uSec
|
||||
high_time = serial_in_buffer[5] << 8 | serial_in_buffer[6]; // High time in uSec
|
||||
low_time = TasmotaGlobal.serial_in_buffer[3] << 8 | TasmotaGlobal.serial_in_buffer[4]; // Low time in uSec
|
||||
high_time = TasmotaGlobal.serial_in_buffer[5] << 8 | TasmotaGlobal.serial_in_buffer[6]; // High time in uSec
|
||||
if (low_time && high_time) {
|
||||
for (uint32_t i = 0; i < 9; i++) {
|
||||
Settings.rf_code[SnfBridge.learn_key][i] = serial_in_buffer[i +1];
|
||||
Settings.rf_code[SnfBridge.learn_key][i] = TasmotaGlobal.serial_in_buffer[i +1];
|
||||
}
|
||||
Response_P(S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, SnfBridge.learn_key, D_JSON_LEARNED);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY));
|
||||
@ -266,14 +266,14 @@ void SonoffBridgeReceived(void)
|
||||
SonoffBridgeLearnFailed();
|
||||
}
|
||||
}
|
||||
else if (0xA4 == serial_in_buffer[0]) { // Received RF data A4 20 EE 01 18 03 3E 2E 1A 22 55
|
||||
else if (0xA4 == TasmotaGlobal.serial_in_buffer[0]) { // Received RF data A4 20 EE 01 18 03 3E 2E 1A 22 55
|
||||
if (SnfBridge.learn_active) {
|
||||
SonoffBridgeLearnFailed();
|
||||
} else {
|
||||
sync_time = serial_in_buffer[1] << 8 | serial_in_buffer[2]; // Sync time in uSec
|
||||
low_time = serial_in_buffer[3] << 8 | serial_in_buffer[4]; // Low time in uSec
|
||||
high_time = serial_in_buffer[5] << 8 | serial_in_buffer[6]; // High time in uSec
|
||||
received_id = serial_in_buffer[7] << 16 | serial_in_buffer[8] << 8 | serial_in_buffer[9];
|
||||
sync_time = TasmotaGlobal.serial_in_buffer[1] << 8 | TasmotaGlobal.serial_in_buffer[2]; // Sync time in uSec
|
||||
low_time = TasmotaGlobal.serial_in_buffer[3] << 8 | TasmotaGlobal.serial_in_buffer[4]; // Low time in uSec
|
||||
high_time = TasmotaGlobal.serial_in_buffer[5] << 8 | TasmotaGlobal.serial_in_buffer[6]; // High time in uSec
|
||||
received_id = TasmotaGlobal.serial_in_buffer[7] << 16 | TasmotaGlobal.serial_in_buffer[8] << 8 | TasmotaGlobal.serial_in_buffer[9];
|
||||
|
||||
unsigned long now = millis();
|
||||
if (!((received_id == SnfBridge.last_received_id) && (now - SnfBridge.last_time < SFB_TIME_AVOID_DUPLICATE))) {
|
||||
@ -312,45 +312,45 @@ bool SonoffBridgeSerialInput(void)
|
||||
|
||||
if (SnfBridge.receive_flag) {
|
||||
if (SnfBridge.receive_raw_flag) {
|
||||
if (!serial_in_byte_counter) {
|
||||
serial_in_buffer[serial_in_byte_counter++] = 0xAA;
|
||||
if (!TasmotaGlobal.serial_in_byte_counter) {
|
||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = 0xAA;
|
||||
}
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
if (serial_in_byte_counter == 3) {
|
||||
if ((0xA6 == serial_in_buffer[1]) || (0xAB == serial_in_buffer[1])) { // AA A6 06 023908010155 55 - 06 is receive_len
|
||||
receive_len = serial_in_buffer[2] + 4; // Get at least receive_len bytes
|
||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte;
|
||||
if (TasmotaGlobal.serial_in_byte_counter == 3) {
|
||||
if ((0xA6 == TasmotaGlobal.serial_in_buffer[1]) || (0xAB == TasmotaGlobal.serial_in_buffer[1])) { // AA A6 06 023908010155 55 - 06 is receive_len
|
||||
receive_len = TasmotaGlobal.serial_in_buffer[2] + 4; // Get at least receive_len bytes
|
||||
}
|
||||
}
|
||||
if ((!receive_len && (0x55 == serial_in_byte)) || (receive_len && (serial_in_byte_counter == receive_len))) { // 0x55 - End of text
|
||||
if ((!receive_len && (0x55 == TasmotaGlobal.serial_in_byte)) || (receive_len && (TasmotaGlobal.serial_in_byte_counter == receive_len))) { // 0x55 - End of text
|
||||
SonoffBridgeReceivedRaw();
|
||||
SnfBridge.receive_flag = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (!((0 == serial_in_byte_counter) && (0 == serial_in_byte))) { // Skip leading 0
|
||||
if (0 == serial_in_byte_counter) {
|
||||
else if (!((0 == TasmotaGlobal.serial_in_byte_counter) && (0 == TasmotaGlobal.serial_in_byte))) { // Skip leading 0
|
||||
if (0 == TasmotaGlobal.serial_in_byte_counter) {
|
||||
SnfBridge.expected_bytes = 2; // 0xA0, 0xA1, 0xA2
|
||||
if (serial_in_byte >= 0xA3) {
|
||||
if (TasmotaGlobal.serial_in_byte >= 0xA3) {
|
||||
SnfBridge.expected_bytes = 11; // 0xA3, 0xA4, 0xA5
|
||||
}
|
||||
if (serial_in_byte == 0xA6) {
|
||||
if (TasmotaGlobal.serial_in_byte == 0xA6) {
|
||||
SnfBridge.expected_bytes = 0; // 0xA6 and up supported by Portisch firmware only
|
||||
serial_in_buffer[serial_in_byte_counter++] = 0xAA;
|
||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = 0xAA;
|
||||
SnfBridge.receive_raw_flag = 1;
|
||||
}
|
||||
}
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
if ((SnfBridge.expected_bytes == serial_in_byte_counter) && (0x55 == serial_in_byte)) { // 0x55 - End of text
|
||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte;
|
||||
if ((SnfBridge.expected_bytes == TasmotaGlobal.serial_in_byte_counter) && (0x55 == TasmotaGlobal.serial_in_byte)) { // 0x55 - End of text
|
||||
SonoffBridgeReceived();
|
||||
SnfBridge.receive_flag = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
serial_in_byte = 0;
|
||||
TasmotaGlobal.serial_in_byte = 0;
|
||||
}
|
||||
if (0xAA == serial_in_byte) { // 0xAA - Start of text
|
||||
serial_in_byte_counter = 0;
|
||||
serial_in_byte = 0;
|
||||
if (0xAA == TasmotaGlobal.serial_in_byte) { // 0xAA - Start of text
|
||||
TasmotaGlobal.serial_in_byte_counter = 0;
|
||||
TasmotaGlobal.serial_in_byte = 0;
|
||||
SnfBridge.receive_flag = 1;
|
||||
receive_len = 0;
|
||||
}
|
||||
@ -563,7 +563,7 @@ bool Xdrv06(uint8_t function)
|
||||
bool result = false;
|
||||
|
||||
#ifdef ESP8266
|
||||
if (SONOFF_BRIDGE == my_module_type) {
|
||||
if (SONOFF_BRIDGE == TasmotaGlobal.module_type) {
|
||||
switch (function) {
|
||||
case FUNC_SERIAL:
|
||||
result = SonoffBridgeSerialInput();
|
||||
|
||||
@ -112,7 +112,7 @@ void DomoticzUpdateFanState(void) {
|
||||
void MqttPublishDomoticzPowerState(uint8_t device) {
|
||||
if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT
|
||||
if (device < 1) { device = 1; }
|
||||
if ((device > devices_present) || (device > MAX_DOMOTICZ_IDX)) { return; }
|
||||
if ((device > TasmotaGlobal.devices_present) || (device > MAX_DOMOTICZ_IDX)) { return; }
|
||||
if (Settings.domoticz_relay_idx[device -1]) {
|
||||
#ifdef USE_SHUTTER
|
||||
if (domoticz_is_shutter) {
|
||||
@ -127,7 +127,7 @@ void MqttPublishDomoticzPowerState(uint8_t device) {
|
||||
char svalue[8]; // Dimmer value
|
||||
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), Settings.light_dimmer);
|
||||
Response_P(DOMOTICZ_MESSAGE, (int)Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? svalue : "", DomoticzBatteryQuality(), DomoticzRssiQuality());
|
||||
Response_P(DOMOTICZ_MESSAGE, (int)Settings.domoticz_relay_idx[device -1], (TasmotaGlobal.power & (1 << (device -1))) ? 1 : 0, (TasmotaGlobal.light_type) ? svalue : "", DomoticzBatteryQuality(), DomoticzRssiQuality());
|
||||
MqttPublish(domoticz_in_topic);
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
}
|
||||
@ -151,7 +151,7 @@ void DomoticzMqttUpdate(void) {
|
||||
domoticz_update_timer--;
|
||||
if (domoticz_update_timer <= 0) {
|
||||
domoticz_update_timer = Settings.domoticz_update_timer;
|
||||
for (uint32_t i = 1; i <= devices_present; i++) {
|
||||
for (uint32_t i = 1; i <= TasmotaGlobal.devices_present; i++) {
|
||||
#ifdef USE_SHUTTER
|
||||
if (domoticz_is_shutter)
|
||||
{
|
||||
@ -175,7 +175,7 @@ void DomoticzMqttUpdate(void) {
|
||||
}
|
||||
|
||||
void DomoticzMqttSubscribe(void) {
|
||||
uint8_t maxdev = (devices_present > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : devices_present;
|
||||
uint8_t maxdev = (TasmotaGlobal.devices_present > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : TasmotaGlobal.devices_present;
|
||||
for (uint32_t i = 0; i < maxdev; i++) {
|
||||
if (Settings.domoticz_relay_idx[i]) {
|
||||
domoticz_subscribe = true;
|
||||
@ -223,7 +223,7 @@ bool DomoticzMqttData(void) {
|
||||
|
||||
bool found = false;
|
||||
if ((idx > 0) && (nvalue >= 0) && (nvalue <= 15)) {
|
||||
uint8_t maxdev = (devices_present > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : devices_present;
|
||||
uint8_t maxdev = (TasmotaGlobal.devices_present > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : TasmotaGlobal.devices_present;
|
||||
for (uint32_t i = 0; i < maxdev; i++) {
|
||||
if (idx == Settings.domoticz_relay_idx[i]) {
|
||||
bool iscolordimmer = strcmp_P(domoticz.getStr(PSTR("dtype")), PSTR("Color Switch")) == 0;
|
||||
@ -293,7 +293,7 @@ bool DomoticzMqttData(void) {
|
||||
} else {
|
||||
return true; // Invalid data
|
||||
}
|
||||
if (light_type && (Settings.light_dimmer == nvalue) && ((power >> i) &1)) {
|
||||
if (TasmotaGlobal.light_type && (Settings.light_dimmer == nvalue) && ((TasmotaGlobal.power >> i) &1)) {
|
||||
return true; // State already set
|
||||
}
|
||||
snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_DIMMER));
|
||||
@ -302,10 +302,10 @@ bool DomoticzMqttData(void) {
|
||||
} else
|
||||
#endif // USE_LIGHT
|
||||
if (1 == nvalue || 0 == nvalue) {
|
||||
if (((power >> i) &1) == (power_t)nvalue) {
|
||||
if (((TasmotaGlobal.power >> i) &1) == (power_t)nvalue) {
|
||||
return true; // Stop loop
|
||||
}
|
||||
snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_POWER "%s"), (devices_present > 1) ? stemp1 : "");
|
||||
snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_POWER "%s"), (TasmotaGlobal.devices_present > 1) ? stemp1 : "");
|
||||
snprintf_P(XdrvMailbox.data, XdrvMailbox.data_len, PSTR("%d"), nvalue);
|
||||
found = true;
|
||||
}
|
||||
@ -381,9 +381,9 @@ void DomoticzSensor(uint8_t idx, char *data) {
|
||||
if (Settings.domoticz_sensor_idx[idx]) {
|
||||
char dmess[128]; // {"idx":26700,"nvalue":0,"svalue":"22330.1;10234.4;22000.5;10243.4;1006;3000","Battery":100,"RSSI":10}
|
||||
|
||||
memcpy(dmess, mqtt_data, sizeof(dmess));
|
||||
memcpy(dmess, TasmotaGlobal.mqtt_data, sizeof(dmess));
|
||||
DomoticzSendData(idx, Settings.domoticz_sensor_idx[idx], data);
|
||||
memcpy(mqtt_data, dmess, sizeof(dmess));
|
||||
memcpy(TasmotaGlobal.mqtt_data, dmess, sizeof(dmess));
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,7 +448,7 @@ void CmndDomoticzIdx(void) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
||||
if (XdrvMailbox.payload >= 0) {
|
||||
Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndIdxNumber(Settings.domoticz_relay_idx[XdrvMailbox.index -1]);
|
||||
}
|
||||
@ -560,7 +560,7 @@ void HandleDomoticzConfiguration(void) {
|
||||
WSContentSendStyle();
|
||||
WSContentSend_P(HTTP_FORM_DOMOTICZ);
|
||||
for (uint32_t i = 0; i < MAX_DOMOTICZ_IDX; i++) {
|
||||
if (i < devices_present) {
|
||||
if (i < TasmotaGlobal.devices_present) {
|
||||
WSContentSend_P(HTTP_FORM_DOMOTICZ_RELAY,
|
||||
i +1, i, Settings.domoticz_relay_idx[i],
|
||||
i +1, i, Settings.domoticz_key_idx[i]);
|
||||
|
||||
@ -109,7 +109,7 @@ void SerialBridgeInit(void)
|
||||
if (SerialBridgeSerial->begin(Settings.sbaudrate * 300)) { // Baud rate is stored div 300 so it fits into 16 bits
|
||||
if (SerialBridgeSerial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
serial_bridge_buffer = serial_in_buffer; // Use idle serial buffer to save RAM
|
||||
serial_bridge_buffer = TasmotaGlobal.serial_in_buffer; // Use idle serial buffer to save RAM
|
||||
} else {
|
||||
serial_bridge_buffer = (char*)(malloc(SERIAL_BRIDGE_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
@ -177,7 +177,7 @@ void ApplyTimerOffsets(Timer *duskdawn)
|
||||
if (hour[mode]==255) {
|
||||
// Permanent day/night sets the unreachable limit values
|
||||
if ((Settings.latitude > 0) != (RtcTime.month>=4 && RtcTime.month<=9)) {
|
||||
duskdawn->time=2046; // permanent night
|
||||
duskdawn->time=2046; // permanent night
|
||||
} else {
|
||||
duskdawn->time=2047; // permanent day
|
||||
}
|
||||
@ -256,7 +256,7 @@ void TimerEverySecond(void)
|
||||
if (RtcTime.valid) {
|
||||
if (!RtcTime.hour && !RtcTime.minute && !RtcTime.second) { TimerSetRandomWindows(); } // Midnight
|
||||
if (Settings.flag3.timers_enable && // CMND_TIMERS
|
||||
(uptime > 60) && (RtcTime.minute != timer_last_minute)) { // Execute from one minute after restart every minute only once
|
||||
(TasmotaGlobal.uptime > 60) && (RtcTime.minute != timer_last_minute)) { // Execute from one minute after restart every minute only once
|
||||
timer_last_minute = RtcTime.minute;
|
||||
int32_t time = (RtcTime.hour *60) + RtcTime.minute;
|
||||
uint8_t days = 1 << (RtcTime.day_of_week -1);
|
||||
@ -290,7 +290,7 @@ void TimerEverySecond(void)
|
||||
XdrvRulesProcess();
|
||||
} else
|
||||
#endif // USE_RULES
|
||||
if (devices_present) { ExecuteCommandPower(xtimer.device +1, xtimer.power, SRC_TIMER); }
|
||||
if (TasmotaGlobal.devices_present) { ExecuteCommandPower(xtimer.device +1, xtimer.power, SRC_TIMER); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -311,7 +311,7 @@ void PrepShowTimer(uint32_t index)
|
||||
|
||||
char soutput[80];
|
||||
soutput[0] = '\0';
|
||||
if (devices_present) {
|
||||
if (TasmotaGlobal.devices_present) {
|
||||
snprintf_P(soutput, sizeof(soutput), PSTR(",\"" D_JSON_TIMER_OUTPUT "\":%d"), xtimer.device +1);
|
||||
}
|
||||
#ifdef USE_SUNRISE
|
||||
@ -350,7 +350,7 @@ void CmndTimer(void)
|
||||
} else {
|
||||
//#ifndef USE_RULES
|
||||
#if defined(USE_RULES)==0 && defined(USE_SCRIPT)==0
|
||||
if (devices_present) {
|
||||
if (TasmotaGlobal.devices_present) {
|
||||
#endif
|
||||
JsonParser parser(XdrvMailbox.data);
|
||||
JsonParserObject root = parser.getRootObject();
|
||||
@ -425,12 +425,12 @@ void CmndTimer(void)
|
||||
val = root[PSTR(D_JSON_TIMER_OUTPUT)];
|
||||
if (val) {
|
||||
uint8_t device = (val.getUInt() -1) & 0x0F;
|
||||
Settings.timer[index].device = (device < devices_present) ? device : 0;
|
||||
Settings.timer[index].device = (device < TasmotaGlobal.devices_present) ? device : 0;
|
||||
}
|
||||
val = root[PSTR(D_JSON_TIMER_ACTION)];
|
||||
if (val) {
|
||||
uint8_t action = val.getUInt() & 0x03;
|
||||
Settings.timer[index].power = (devices_present) ? action : 3; // If no devices than only allow rules
|
||||
Settings.timer[index].power = (TasmotaGlobal.devices_present) ? action : 3; // If no devices than only allow rules
|
||||
}
|
||||
|
||||
index++;
|
||||
@ -482,7 +482,7 @@ void CmndTimers(void)
|
||||
jsflg = 0;
|
||||
}
|
||||
}
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
}
|
||||
|
||||
#ifdef USE_SUNRISE
|
||||
@ -856,10 +856,10 @@ void HandleTimerConfiguration(void)
|
||||
#ifdef USE_SUNRISE
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT2);
|
||||
#endif // USE_SUNRISE
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT3, devices_present);
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT4, WebColor(COL_TIMER_TAB_BACKGROUND), WebColor(COL_TIMER_TAB_TEXT), WebColor(COL_FORM), WebColor(COL_TEXT), devices_present);
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT5, MAX_TIMERS, devices_present);
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT6, devices_present);
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT3, TasmotaGlobal.devices_present);
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT4, WebColor(COL_TIMER_TAB_BACKGROUND), WebColor(COL_TIMER_TAB_TEXT), WebColor(COL_FORM), WebColor(COL_TEXT), TasmotaGlobal.devices_present);
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT5, MAX_TIMERS, TasmotaGlobal.devices_present);
|
||||
WSContentSend_P(HTTP_TIMER_SCRIPT6, TasmotaGlobal.devices_present);
|
||||
WSContentSendStyle_P(HTTP_TIMER_STYLE, WebColor(COL_FORM));
|
||||
WSContentSend_P(HTTP_FORM_TIMER1, (Settings.flag3.timers_enable) ? " checked" : ""); // CMND_TIMERS
|
||||
for (uint32_t i = 0; i < MAX_TIMERS; i++) {
|
||||
@ -924,7 +924,7 @@ bool Xdrv09(uint8_t function)
|
||||
#if defined(USE_RULES) || defined(USE_SCRIPT)
|
||||
WSContentSend_P(HTTP_BTN_MENU_TIMER);
|
||||
#else
|
||||
if (devices_present) { WSContentSend_P(HTTP_BTN_MENU_TIMER); }
|
||||
if (TasmotaGlobal.devices_present) { WSContentSend_P(HTTP_BTN_MENU_TIMER); }
|
||||
#endif // USE_RULES
|
||||
break;
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
|
||||
@ -725,7 +725,7 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved)
|
||||
RulesVarReplace(commands, F("%UTCTIME%"), String(UtcTime()));
|
||||
RulesVarReplace(commands, F("%UPTIME%"), String(MinutesUptime()));
|
||||
RulesVarReplace(commands, F("%TIMESTAMP%"), GetDateAndTime(DT_LOCAL));
|
||||
RulesVarReplace(commands, F("%TOPIC%"), mqtt_topic);
|
||||
RulesVarReplace(commands, F("%TOPIC%"), TasmotaGlobal.mqtt_topic);
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("%06X"), ESP_getChipId());
|
||||
RulesVarReplace(commands, F("%DEVICEID%"), stemp);
|
||||
String mac_address = WiFi.macAddress();
|
||||
@ -805,7 +805,7 @@ bool RulesProcessEvent(char *json_event)
|
||||
|
||||
bool RulesProcess(void)
|
||||
{
|
||||
return RulesProcessEvent(mqtt_data);
|
||||
return RulesProcessEvent(TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
|
||||
void RulesInit(void)
|
||||
@ -815,7 +815,7 @@ void RulesInit(void)
|
||||
// and indicates scripter do not use compress
|
||||
bitWrite(Settings.rule_once, 6, 0);
|
||||
|
||||
rules_flag.data = 0;
|
||||
TasmotaGlobal.rules_flag.data = 0;
|
||||
for (uint32_t i = 0; i < MAX_RULE_SETS; i++) {
|
||||
if (0 == GetRuleLen(i)) {
|
||||
bitWrite(Settings.rule_enabled, i, 0);
|
||||
@ -830,10 +830,10 @@ void RulesEvery50ms(void)
|
||||
if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled
|
||||
char json_event[120];
|
||||
|
||||
if (-1 == Rules.new_power) { Rules.new_power = power; }
|
||||
if (-1 == Rules.new_power) { Rules.new_power = TasmotaGlobal.power; }
|
||||
if (Rules.new_power != Rules.old_power) {
|
||||
if (Rules.old_power != -1) {
|
||||
for (uint32_t i = 0; i < devices_present; i++) {
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
|
||||
uint8_t new_state = (Rules.new_power >> i) &1;
|
||||
if (new_state != ((Rules.old_power >> i) &1)) {
|
||||
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Power%d\":{\"State\":%d}}"), i +1, new_state);
|
||||
@ -842,7 +842,7 @@ void RulesEvery50ms(void)
|
||||
}
|
||||
} else {
|
||||
// Boot time POWER OUTPUTS (Relays) Status
|
||||
for (uint32_t i = 0; i < devices_present; i++) {
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
|
||||
uint8_t new_state = (Rules.new_power >> i) &1;
|
||||
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Power%d\":{\"Boot\":%d}}"), i +1, new_state);
|
||||
RulesProcessEvent(json_event);
|
||||
@ -854,7 +854,7 @@ void RulesEvery50ms(void)
|
||||
#else
|
||||
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)));
|
||||
snprintf_P(json_event, sizeof(json_event), PSTR("{\"%s\":{\"Boot\":%d}}"), GetSwitchText(i).c_str(), (SwitchState(i)));
|
||||
RulesProcessEvent(json_event);
|
||||
}
|
||||
}
|
||||
@ -911,11 +911,11 @@ void RulesEvery50ms(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rules_flag.data) {
|
||||
else if (TasmotaGlobal.rules_flag.data) {
|
||||
uint16_t mask = 1;
|
||||
for (uint32_t i = 0; i < MAX_RULES_FLAG; i++) {
|
||||
if (rules_flag.data & mask) {
|
||||
rules_flag.data ^= mask;
|
||||
if (TasmotaGlobal.rules_flag.data & mask) {
|
||||
TasmotaGlobal.rules_flag.data ^= mask;
|
||||
json_event[0] = '\0';
|
||||
switch (i) {
|
||||
case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Init\":1}}"), sizeof(json_event)); break;
|
||||
@ -947,16 +947,16 @@ uint8_t rules_xsns_index = 0;
|
||||
|
||||
void RulesEvery100ms(void)
|
||||
{
|
||||
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
|
||||
if (Settings.rule_enabled && !Rules.busy && (TasmotaGlobal.uptime > 4)) { // Any rule enabled and allow 4 seconds start-up time for sensors (#3811)
|
||||
ResponseClear();
|
||||
int tele_period_save = TasmotaGlobal.tele_period;
|
||||
TasmotaGlobal.tele_period = 2; // Do not allow HA updates during next function call
|
||||
XsnsNextCall(FUNC_JSON_APPEND, rules_xsns_index); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
tele_period = tele_period_save;
|
||||
if (strlen(mqtt_data)) {
|
||||
mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
TasmotaGlobal.tele_period = tele_period_save;
|
||||
if (strlen(TasmotaGlobal.mqtt_data)) {
|
||||
TasmotaGlobal.mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
ResponseJsonEnd();
|
||||
RulesProcessEvent(mqtt_data);
|
||||
RulesProcessEvent(TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -967,7 +967,7 @@ void RulesEverySecond(void)
|
||||
char json_event[120];
|
||||
|
||||
if (RtcTime.valid) {
|
||||
if ((uptime > 60) && (RtcTime.minute != Rules.last_minute)) { // Execute from one minute after restart every minute only once
|
||||
if ((TasmotaGlobal.uptime > 60) && (RtcTime.minute != Rules.last_minute)) { // Execute from one minute after restart every minute only once
|
||||
Rules.last_minute = RtcTime.minute;
|
||||
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Minute\":%d}}"), MinutesPastMidnight());
|
||||
RulesProcessEvent(json_event);
|
||||
@ -1882,12 +1882,12 @@ void ExecuteCommandBlock(const char * commands, int len)
|
||||
String sCurrentCommand = oneCommand;
|
||||
sCurrentCommand.trim();
|
||||
if (sCurrentCommand.length() > 0
|
||||
&& backlog.size() < MAX_BACKLOG && !backlog_mutex)
|
||||
&& backlog.size() < MAX_BACKLOG && !TasmotaGlobal.backlog_mutex)
|
||||
{
|
||||
//Insert into backlog
|
||||
backlog_mutex = true;
|
||||
TasmotaGlobal.backlog_mutex = true;
|
||||
backlog.add(insertPosition, sCurrentCommand);
|
||||
backlog_mutex = false;
|
||||
TasmotaGlobal.backlog_mutex = false;
|
||||
insertPosition++;
|
||||
}
|
||||
}
|
||||
@ -2030,7 +2030,7 @@ void CmndRule(void)
|
||||
CmndRule();
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command);
|
||||
}
|
||||
mqtt_data[0] = '\0'; // Disable further processing
|
||||
ResponseClear(); // Disable further processing
|
||||
return;
|
||||
}
|
||||
uint8_t index = XdrvMailbox.index;
|
||||
@ -2099,10 +2099,10 @@ void CmndRule(void)
|
||||
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\"}"),
|
||||
// snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.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\"}"),
|
||||
snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.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)),
|
||||
rule_len, MAX_RULE_SIZE - GetRuleLenStorage(index - 1),
|
||||
@ -2121,7 +2121,7 @@ void CmndRuleTimer(void)
|
||||
Rules.timer[XdrvMailbox.index -1] = (XdrvMailbox.payload > 0) ? millis() + (1000 * XdrvMailbox.payload) : 0;
|
||||
#endif // USE_EXPRESSION
|
||||
}
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
for (uint32_t i = 0; i < MAX_RULE_TIMERS; i++) {
|
||||
ResponseAppend_P(PSTR("%c\"T%d\":%d"), (i) ? ',' : '{', i +1, (Rules.timer[i]) ? (Rules.timer[i] - millis()) / 1000 : 0);
|
||||
}
|
||||
@ -2144,7 +2144,7 @@ void CmndVariable(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_RULE_VARS)) {
|
||||
if (!XdrvMailbox.usridx) {
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
for (uint32_t i = 0; i < MAX_RULE_VARS; i++) {
|
||||
ResponseAppend_P(PSTR("%c\"Var%d\":\"%s\""), (i) ? ',' : '{', i +1, rules_vars[i]);
|
||||
}
|
||||
@ -2179,7 +2179,6 @@ void CmndMemory(void)
|
||||
char rules_mem[FLOATSZ];
|
||||
dtostrfd(evaluateExpression(XdrvMailbox.data + 1, XdrvMailbox.data_len - 1), Settings.flag2.calc_resolution, rules_mem);
|
||||
SettingsUpdateText(SET_MEM1 + XdrvMailbox.index -1, rules_mem);
|
||||
|
||||
} else {
|
||||
SettingsUpdateText(SET_MEM1 + XdrvMailbox.index -1, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data);
|
||||
}
|
||||
|
||||
@ -512,7 +512,7 @@ void ScriptEverySecond(void) {
|
||||
}
|
||||
|
||||
void RulesTeleperiod(void) {
|
||||
if (bitRead(Settings.rule_enabled, 0) && mqtt_data[0]) Run_Scripter(">T", 2, mqtt_data);
|
||||
if (bitRead(Settings.rule_enabled, 0) && TasmotaGlobal.mqtt_data[0]) Run_Scripter(">T", 2, TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
|
||||
// EEPROM MACROS
|
||||
@ -1019,7 +1019,7 @@ void Script_Stop_UDP(void) {
|
||||
}
|
||||
|
||||
void Script_Init_UDP() {
|
||||
if (global_state.network_down) return;
|
||||
if (TasmotaGlobal.global_state.network_down) return;
|
||||
if (!glob_script_mem.udp_flags.udp_used) return;
|
||||
if (glob_script_mem.udp_flags.udp_connected) return;
|
||||
|
||||
@ -1033,7 +1033,7 @@ void Script_Init_UDP() {
|
||||
}
|
||||
|
||||
void Script_PollUdp(void) {
|
||||
if (global_state.network_down) return;
|
||||
if (TasmotaGlobal.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()) {
|
||||
@ -1826,8 +1826,8 @@ chknext:
|
||||
|
||||
case 'b':
|
||||
if (!strncmp(vname, "boot", 4)) {
|
||||
if (rules_flag.system_boot) {
|
||||
rules_flag.system_boot = 0;
|
||||
if (TasmotaGlobal.rules_flag.system_boot) {
|
||||
TasmotaGlobal.rules_flag.system_boot = 0;
|
||||
fvar = 1;
|
||||
}
|
||||
goto exit;
|
||||
@ -2343,15 +2343,15 @@ chknext:
|
||||
break;
|
||||
case 'g':
|
||||
if (!strncmp(vname, "gtmp", 4)) {
|
||||
fvar = global_temperature_celsius;
|
||||
fvar = TasmotaGlobal.temperature_celsius;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "ghum", 4)) {
|
||||
fvar = global_humidity;
|
||||
fvar = TasmotaGlobal.humidity;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "gprs", 4)) {
|
||||
fvar = global_pressure_hpa;
|
||||
fvar = TasmotaGlobal.pressure_hpa;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "gtopic", 6)) {
|
||||
@ -2534,21 +2534,21 @@ chknext:
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "mqttc", 5)) {
|
||||
if (rules_flag.mqtt_connected) {
|
||||
rules_flag.mqtt_connected = 0;
|
||||
if (TasmotaGlobal.rules_flag.mqtt_connected) {
|
||||
TasmotaGlobal.rules_flag.mqtt_connected = 0;
|
||||
fvar = 1;
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "mqttd", 5)) {
|
||||
if (rules_flag.mqtt_disconnected) {
|
||||
rules_flag.mqtt_disconnected = 0;
|
||||
if (TasmotaGlobal.rules_flag.mqtt_disconnected) {
|
||||
TasmotaGlobal.rules_flag.mqtt_disconnected = 0;
|
||||
fvar = 1;
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "mqtts", 5)) {
|
||||
fvar = !global_state.mqtt_down;
|
||||
fvar = !TasmotaGlobal.global_state.mqtt_down;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "mp(", 3)) {
|
||||
@ -2637,8 +2637,8 @@ chknext:
|
||||
}
|
||||
}
|
||||
*/
|
||||
if ((gpiopin < ARRAY_SIZE(gpio_pin)) && (gpio_pin[gpiopin] > 0)) {
|
||||
fvar = gpio_pin[gpiopin];
|
||||
if ((gpiopin < ARRAY_SIZE(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) {
|
||||
fvar = TasmotaGlobal.gpio_pin[gpiopin];
|
||||
// skip ] bracket
|
||||
len++;
|
||||
goto exit;
|
||||
@ -2680,8 +2680,8 @@ chknext:
|
||||
if (!strncmp(vname, "pwr[", 4)) {
|
||||
GetNumericArgument(vname + 4, OPER_EQU, &fvar, 0);
|
||||
uint8_t index = fvar;
|
||||
if (index<=devices_present) {
|
||||
fvar = bitRead(power, index - 1);
|
||||
if (index<=TasmotaGlobal.devices_present) {
|
||||
fvar = bitRead(TasmotaGlobal.power, index - 1);
|
||||
} else {
|
||||
fvar = -1;
|
||||
}
|
||||
@ -2854,7 +2854,7 @@ chknext:
|
||||
if (!strncmp(vname, "sht[", 4)) {
|
||||
GetNumericArgument(vname + 4, OPER_EQU, &fvar, 0);
|
||||
uint8_t index = fvar;
|
||||
if (index<=shutters_present) {
|
||||
if (index<=TasmotaGlobal.shutters_present) {
|
||||
fvar = Settings.shutter_position[index - 1];
|
||||
} else {
|
||||
fvar = -1;
|
||||
@ -2937,11 +2937,11 @@ chknext:
|
||||
goto exit_settable;
|
||||
}
|
||||
if (!strncmp(vname, "tinit", 5)) {
|
||||
fvar = rules_flag.time_init;
|
||||
fvar = TasmotaGlobal.rules_flag.time_init;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "tset", 4)) {
|
||||
fvar = rules_flag.time_set;
|
||||
fvar = TasmotaGlobal.rules_flag.time_set;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "tstamp", 6)) {
|
||||
@ -3012,7 +3012,7 @@ chknext:
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "upsecs", 6)) {
|
||||
fvar = uptime;
|
||||
fvar = TasmotaGlobal.uptime;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "upd[", 4)) {
|
||||
@ -3125,21 +3125,21 @@ chknext:
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "wific", 5)) {
|
||||
if (rules_flag.wifi_connected) {
|
||||
rules_flag.wifi_connected = 0;
|
||||
if (TasmotaGlobal.rules_flag.wifi_connected) {
|
||||
TasmotaGlobal.rules_flag.wifi_connected = 0;
|
||||
fvar = 1;
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "wifid", 5)) {
|
||||
if (rules_flag.wifi_disconnected) {
|
||||
rules_flag.wifi_disconnected = 0;
|
||||
if (TasmotaGlobal.rules_flag.wifi_disconnected) {
|
||||
TasmotaGlobal.rules_flag.wifi_disconnected = 0;
|
||||
fvar = 1;
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname, "wifis", 5)) {
|
||||
fvar = !global_state.wifi_down;
|
||||
fvar = !TasmotaGlobal.global_state.wifi_down;
|
||||
goto exit;
|
||||
}
|
||||
break;
|
||||
@ -3555,7 +3555,7 @@ void toLogN(const char *cp, uint8_t len) {
|
||||
void toLogEOL(const char *s1,const char *str) {
|
||||
if (!str) return;
|
||||
uint8_t index = 0;
|
||||
char *cp = log_data;
|
||||
char *cp = TasmotaGlobal.log_data;
|
||||
strcpy(cp, s1);
|
||||
cp += strlen(s1);
|
||||
while (*str) {
|
||||
@ -4495,16 +4495,16 @@ uint8_t script_xsns_index = 0;
|
||||
|
||||
void ScripterEvery100ms(void) {
|
||||
|
||||
if (Settings.rule_enabled && (uptime > 4)) {
|
||||
mqtt_data[0] = '\0';
|
||||
uint16_t script_tele_period_save = tele_period;
|
||||
tele_period = 2;
|
||||
if (Settings.rule_enabled && (TasmotaGlobal.uptime > 4)) {
|
||||
ResponseClear();
|
||||
uint16_t script_tele_period_save = TasmotaGlobal.tele_period;
|
||||
TasmotaGlobal.tele_period = 2;
|
||||
XsnsNextCall(FUNC_JSON_APPEND, script_xsns_index);
|
||||
tele_period = script_tele_period_save;
|
||||
if (strlen(mqtt_data)) {
|
||||
mqtt_data[0] = '{';
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
Run_Scripter(">T", 2, mqtt_data);
|
||||
TasmotaGlobal.tele_period = script_tele_period_save;
|
||||
if (strlen(TasmotaGlobal.mqtt_data)) {
|
||||
TasmotaGlobal.mqtt_data[0] = '{';
|
||||
snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("%s}"), TasmotaGlobal.mqtt_data);
|
||||
Run_Scripter(">T", 2, TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
}
|
||||
if (Settings.rule_enabled) {
|
||||
@ -5517,14 +5517,14 @@ void Script_Check_Hue(String *response) {
|
||||
}
|
||||
// append response
|
||||
if (response) {
|
||||
if (devices_present) {
|
||||
if (TasmotaGlobal.devices_present) {
|
||||
*response += ",\"";
|
||||
}
|
||||
else {
|
||||
if (hue_devs>0) *response += ",\"";
|
||||
else *response += "\"";
|
||||
}
|
||||
*response += String(EncodeLightId(hue_devs + devices_present + 1))+"\":";
|
||||
*response += String(EncodeLightId(hue_devs + TasmotaGlobal.devices_present + 1))+"\":";
|
||||
Script_HueStatus(response, hue_devs);
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Hue: %s - %d "),response->c_str(), hue_devs);
|
||||
}
|
||||
@ -5571,7 +5571,7 @@ void Script_Handle_Hue(String *path) {
|
||||
bool resp = false;
|
||||
|
||||
uint8_t device = DecodeLightId(atoi(path->c_str()));
|
||||
uint8_t index = device - devices_present - 1;
|
||||
uint8_t index = device - TasmotaGlobal.devices_present - 1;
|
||||
|
||||
if (Webserver->args()) {
|
||||
response = "[";
|
||||
@ -5784,7 +5784,7 @@ bool ScriptCommand(void) {
|
||||
} else {
|
||||
if ('>' == XdrvMailbox.data[0]) {
|
||||
// execute script
|
||||
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\"}"), command,XdrvMailbox.data);
|
||||
snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s\":\"%s\"}"), command,XdrvMailbox.data);
|
||||
if (bitRead(Settings.rule_enabled, 0)) {
|
||||
for (uint8_t count = 0; count<XdrvMailbox.data_len; count++) {
|
||||
if (XdrvMailbox.data[count]==';') XdrvMailbox.data[count] = '\n';
|
||||
@ -5803,15 +5803,15 @@ bool ScriptCommand(void) {
|
||||
if (glob_script_mem.glob_error==1) {
|
||||
// was string, not number
|
||||
GetStringArgument(lp, OPER_EQU, str, 0);
|
||||
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"script\":{\"%s\":\"%s\"}}"), lp, str);
|
||||
snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"script\":{\"%s\":\"%s\"}}"), lp, str);
|
||||
} else {
|
||||
dtostrfd(fvar, 6, str);
|
||||
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"script\":{\"%s\":%s}}"), lp, str);
|
||||
snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"script\":{\"%s\":%s}}"), lp, str);
|
||||
}
|
||||
}
|
||||
return serviced;
|
||||
}
|
||||
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"Free\":%d}"),command, GetStateText(bitRead(Settings.rule_enabled, 0)), glob_script_mem.script_size - strlen(glob_script_mem.script_ram));
|
||||
snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s\":\"%s\",\"Free\":%d}"),command, GetStateText(bitRead(Settings.rule_enabled, 0)), glob_script_mem.script_size - strlen(glob_script_mem.script_ram));
|
||||
#ifdef SUPPORT_MQTT_EVENT
|
||||
} else if (CMND_SUBSCRIBE == command_code) { //MQTT Subscribe command. Subscribe <Event>, <Topic> [, <Key>]
|
||||
String result = ScriptSubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||
@ -7231,7 +7231,7 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core, uint32
|
||||
|
||||
// get tesla powerwall info page json string
|
||||
uint32_t call2https(const char *host, const char *path) {
|
||||
if (global_state.wifi_down) return 1;
|
||||
if (TasmotaGlobal.global_state.wifi_down) return 1;
|
||||
uint32_t status = 0;
|
||||
#ifdef ESP32
|
||||
WiFiClientSecure *httpsClient;
|
||||
@ -7481,7 +7481,7 @@ bool Xdrv10(uint8_t function)
|
||||
break;
|
||||
case FUNC_RULES_PROCESS:
|
||||
if (bitRead(Settings.rule_enabled, 0)) {
|
||||
Run_Scripter(">E", 2, mqtt_data);
|
||||
Run_Scripter(">E", 2, TasmotaGlobal.mqtt_data);
|
||||
result = event_handeled;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -468,45 +468,45 @@ void KNX_INIT(void)
|
||||
// and activate options according to the hardware
|
||||
/*for (uint32_t i = GPIO_REL1; i < GPIO_REL8 + 1; ++i)
|
||||
{
|
||||
if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_REL1].show = true; }
|
||||
if (GetUsedInModule(i, TasmotaGlobal.my_module.io)) { device_param[i - GPIO_REL1].show = true; }
|
||||
}
|
||||
for (uint32_t i = GPIO_REL1_INV; i < GPIO_REL8_INV + 1; ++i)
|
||||
{
|
||||
if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_REL1_INV].show = true; }
|
||||
if (GetUsedInModule(i, TasmotaGlobal.my_module.io)) { device_param[i - GPIO_REL1_INV].show = true; }
|
||||
}*/
|
||||
for (uint32_t i = 0; i < devices_present; ++i)
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; ++i)
|
||||
{
|
||||
device_param[i].show = true;
|
||||
}
|
||||
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; }
|
||||
if (GetUsedInModule(i, TasmotaGlobal.my_module.io)) { device_param[i - GPIO_SWT1 + 8].show = true; }
|
||||
}
|
||||
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; }
|
||||
if (GetUsedInModule(i, TasmotaGlobal.my_module.io)) { device_param[i - GPIO_KEY1 + 8].show = true; }
|
||||
}
|
||||
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; }
|
||||
if (GetUsedInModule(i, TasmotaGlobal.my_module.io)) { device_param[i - GPIO_SWT1_NP + 8].show = true; }
|
||||
}
|
||||
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; }
|
||||
if (GetUsedInModule(i, TasmotaGlobal.my_module.io)) { device_param[i - GPIO_KEY1_NP + 8].show = true; }
|
||||
}
|
||||
if (GetUsedInModule(GPIO_DHT11, my_module.io)) { device_param[KNX_TEMPERATURE-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_DHT22, my_module.io)) { device_param[KNX_TEMPERATURE-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_SI7021, my_module.io)) { device_param[KNX_TEMPERATURE-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_DHT11, TasmotaGlobal.my_module.io)) { device_param[KNX_TEMPERATURE-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_DHT22, TasmotaGlobal.my_module.io)) { device_param[KNX_TEMPERATURE-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_SI7021, TasmotaGlobal.my_module.io)) { device_param[KNX_TEMPERATURE-1].show = true; }
|
||||
#ifdef USE_DS18x20
|
||||
if (GetUsedInModule(GPIO_DSB, my_module.io)) { device_param[KNX_TEMPERATURE-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_DSB, TasmotaGlobal.my_module.io)) { device_param[KNX_TEMPERATURE-1].show = true; }
|
||||
#endif
|
||||
if (GetUsedInModule(GPIO_DHT11, my_module.io)) { device_param[KNX_HUMIDITY-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_DHT22, my_module.io)) { device_param[KNX_HUMIDITY-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_SI7021, my_module.io)) { device_param[KNX_HUMIDITY-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_DHT11, TasmotaGlobal.my_module.io)) { device_param[KNX_HUMIDITY-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_DHT22, TasmotaGlobal.my_module.io)) { device_param[KNX_HUMIDITY-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_SI7021, TasmotaGlobal.my_module.io)) { device_param[KNX_HUMIDITY-1].show = true; }
|
||||
|
||||
#if defined(USE_ENERGY_SENSOR)
|
||||
// Any device with a Power Monitoring
|
||||
if ( energy_flg != ENERGY_NONE ) {
|
||||
if ( TasmotaGlobal.energy_driver != ENERGY_NONE ) {
|
||||
device_param[KNX_ENERGY_POWER-1].show = true;
|
||||
device_param[KNX_ENERGY_DAILY-1].show = true;
|
||||
device_param[KNX_ENERGY_START-1].show = true;
|
||||
@ -565,7 +565,7 @@ void KNX_CB_Action(message_t const &msg, void *arg)
|
||||
sprintf(tempchar,"%d",msg.data[0]);
|
||||
} else if (chan->type == KNX_SCENE) {
|
||||
// VALUE
|
||||
uint8_t tempvar = knx.data_to_1byte_uint(msg.data);
|
||||
uint8_t tempvar = knx.data_to_1byte_uint(msg.data);
|
||||
dtostrfd(tempvar,0,tempchar);
|
||||
} else {
|
||||
// VALUE
|
||||
@ -623,7 +623,7 @@ void KNX_CB_Action(message_t const &msg, void *arg)
|
||||
toggle_inhibit = TOGGLE_INHIBIT_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -1097,7 +1097,7 @@ void CmndKnxTxScene(void)
|
||||
device_param_ga[KNX_SCENE-1], XdrvMailbox.data,
|
||||
KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member);
|
||||
ResponseCmndIdxChar (XdrvMailbox.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1255,7 +1255,7 @@ bool Xdrv11(uint8_t function)
|
||||
bool result = false;
|
||||
switch (function) {
|
||||
case FUNC_LOOP:
|
||||
if (!global_state.network_down) { knx.loop(); } // Process knx events
|
||||
if (!TasmotaGlobal.global_state.network_down) { knx.loop(); } // Process knx events
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
if (toggle_inhibit) {
|
||||
|
||||
@ -213,27 +213,27 @@ void HassDiscoveryRelays(struct HASS &Hass)
|
||||
uint8_t lightidx = MAX_RELAYS + 1; // Will store the starting position of the lights
|
||||
bool iFan = false;
|
||||
|
||||
Hass.RelPst = devices_present > 0;
|
||||
Hass.RelPst = TasmotaGlobal.devices_present > 0;
|
||||
|
||||
#ifdef ESP8266
|
||||
if (SONOFF_IFAN02 == my_module_type || SONOFF_IFAN03 == my_module_type) { iFan = true;}
|
||||
if (SONOFF_IFAN02 == TasmotaGlobal.module_type || SONOFF_IFAN03 == TasmotaGlobal.module_type) { iFan = true;}
|
||||
#endif // ESP8266
|
||||
|
||||
if (Light.subtype > LST_NONE) {
|
||||
if (!light_controller.isCTRGBLinked()) { // One or two lights present
|
||||
lightidx = devices_present - 2;
|
||||
lightidx = TasmotaGlobal.devices_present - 2;
|
||||
} else {
|
||||
lightidx = devices_present - 1;
|
||||
lightidx = TasmotaGlobal.devices_present - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Light.device > 0 && Settings.flag3.pwm_multi_channels) { // How many relays are light devices?
|
||||
lightidx = devices_present - Light.subtype;
|
||||
lightidx = TasmotaGlobal.devices_present - Light.subtype;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < MAX_RELAYS; i++) {
|
||||
|
||||
if (i < devices_present) {
|
||||
if (i < TasmotaGlobal.devices_present) {
|
||||
|
||||
#ifdef USE_SHUTTER
|
||||
if (Settings.flag3.shutter_mode) {
|
||||
@ -255,7 +255,7 @@ void HassDiscoveryRelays(struct HASS &Hass)
|
||||
if (i >= lightidx || (iFan && i == 0)) { // First relay on Ifan controls the light
|
||||
Hass.Relay[i] = 2; // Relay is a light
|
||||
} else {
|
||||
if (!iFan) { // Relays 2-4 for ifan are controlled by FANSPEED and don't need to be present if my_module_type = SONOFF_IFAN02 or SONOFF_IFAN03
|
||||
if (!iFan) { // Relays 2-4 for ifan are controlled by FANSPEED and don't need to be present if TasmotaGlobal.module_type = SONOFF_IFAN02 or SONOFF_IFAN03
|
||||
Hass.Relay[i] = 1; // Simple Relay
|
||||
}
|
||||
}
|
||||
@ -282,7 +282,7 @@ void NewHAssDiscovery(void)
|
||||
struct HASS Hass;
|
||||
HassDiscoveryRelays(Hass);
|
||||
|
||||
uint32_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!devices_present) ? 1 : devices_present;
|
||||
uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!TasmotaGlobal.devices_present) ? 1 : TasmotaGlobal.devices_present;
|
||||
for (uint32_t i = 0; i < MAX_FRIENDLYNAMES; i++) {
|
||||
char fname[TOPSZ];
|
||||
snprintf_P(fname, sizeof(fname), PSTR("\"%s\""), EscapeJSONString(SettingsText(SET_FRIENDLYNAME1 +i)).c_str());
|
||||
@ -291,7 +291,7 @@ void NewHAssDiscovery(void)
|
||||
|
||||
stemp3[0] = '\0';
|
||||
// Enable Discovery for Switches only if SwitchTopic is set to a custom name or if there is not a Power device
|
||||
auto discover_switches = ((KeyTopicActive(1) && (strcmp(SettingsText(SET_MQTT_SWITCH_TOPIC), mqtt_topic))) || !Hass.RelPst);
|
||||
auto discover_switches = ((KeyTopicActive(1) && (strcmp(SettingsText(SET_MQTT_SWITCH_TOPIC), TasmotaGlobal.mqtt_topic))) || !Hass.RelPst);
|
||||
for (uint32_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
snprintf_P(stemp3, sizeof(stemp3), PSTR("%s%s%d"), stemp3, (i > 0 ? "," : ""), (PinUsed(GPIO_SWT1, i) & discover_switches) ? Settings.switchmode[i] : -1);
|
||||
}
|
||||
@ -301,15 +301,15 @@ void NewHAssDiscovery(void)
|
||||
for (uint32_t i = 0; i < MAX_KEYS; i++) {
|
||||
|
||||
#ifdef ESP8266
|
||||
if (i == 0 && (SONOFF_DUAL == my_module_type )) { SerialButton = true; }
|
||||
if (TUYA_DIMMER == my_module_type || SK03_TUYA == my_module_type) { TuyaMod = true; }
|
||||
if (i == 0 && (SONOFF_DUAL == TasmotaGlobal.module_type )) { SerialButton = true; }
|
||||
if (TUYA_DIMMER == TasmotaGlobal.module_type || SK03_TUYA == TasmotaGlobal.module_type) { TuyaMod = true; }
|
||||
#endif // ESP8266
|
||||
|
||||
snprintf_P(stemp4, sizeof(stemp4), PSTR("%s%s%d"), stemp4, (i > 0 ? "," : ""), (SerialButton ? 1 : (PinUsed(GPIO_KEY1, i)) & Settings.flag3.mqtt_buttons));
|
||||
SerialButton = false;
|
||||
}
|
||||
|
||||
mqtt_data[0] = '\0'; // Clear retained message
|
||||
ResponseClear(); // Clear retained message
|
||||
|
||||
// Full 12 chars MAC address as ID
|
||||
String mac_address = WiFi.macAddress();
|
||||
@ -318,11 +318,11 @@ void NewHAssDiscovery(void)
|
||||
snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/config"), unique_id);
|
||||
|
||||
// Send empty message if new discovery is disabled
|
||||
masterlog_level = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
TasmotaGlobal.masterlog_level = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
if (!Settings.flag.hass_discovery) { // HassDiscoveryRelays(relays)
|
||||
Response_P(HASS_DISCOVER_DEVICE, WiFi.localIP().toString().c_str(), SettingsText(SET_DEVICENAME),
|
||||
stemp2, my_hostname, unique_id, ModuleName().c_str(), TuyaMod, GetStateText(0), GetStateText(1), GetStateText(2), GetStateText(3),
|
||||
my_version, mqtt_topic, SettingsText(SET_MQTT_FULLTOPIC), SUB_PREFIX, PUB_PREFIX, PUB_PREFIX2, Hass.RelLst, stemp3, stemp4, Settings.flag.button_swap,
|
||||
stemp2, TasmotaGlobal.hostname, unique_id, ModuleName().c_str(), TuyaMod, GetStateText(0), GetStateText(1), GetStateText(2), GetStateText(3),
|
||||
TasmotaGlobal.version, TasmotaGlobal.mqtt_topic, SettingsText(SET_MQTT_FULLTOPIC), SUB_PREFIX, PUB_PREFIX, PUB_PREFIX2, Hass.RelLst, stemp3, stemp4, Settings.flag.button_swap,
|
||||
Settings.flag.button_single, Settings.flag.decimal_text, Settings.flag.not_power_linked, Settings.flag.hass_light, Settings.flag3.pwm_multi_channels,
|
||||
Settings.flag3.mqtt_buttons, Settings.flag3.shutter_mode, Settings.flag4.alexa_ct_range, light_controller.isCTRGBLinked(), Light.subtype);
|
||||
}
|
||||
@ -335,7 +335,7 @@ void NewHAssDiscovery(void)
|
||||
ResponseAppend_P(PSTR(",\"ver\":1}"));
|
||||
MqttPublish(stopic, true);
|
||||
}
|
||||
masterlog_level = 0; // Restore WebLog state
|
||||
TasmotaGlobal.masterlog_level = 0; // Restore WebLog state
|
||||
}
|
||||
|
||||
// NEW DISCOVERY
|
||||
@ -347,19 +347,19 @@ void TryResponseAppend_P(const char *format, ...)
|
||||
char dummy[2];
|
||||
int dlen = vsnprintf_P(dummy, 1, format, args);
|
||||
|
||||
int mlen = strlen(mqtt_data);
|
||||
int slen = sizeof(mqtt_data) - 1 - mlen;
|
||||
int mlen = strlen(TasmotaGlobal.mqtt_data);
|
||||
int slen = sizeof(TasmotaGlobal.mqtt_data) - 1 - mlen;
|
||||
if (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);
|
||||
vsnprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), format, args);
|
||||
AddLog(LOG_LEVEL_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
va_start(args, format);
|
||||
vsnprintf_P(mqtt_data + mlen, slen, format, args);
|
||||
vsnprintf_P(TasmotaGlobal.mqtt_data + mlen, slen, format, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
@ -393,10 +393,10 @@ void HAssAnnounceRelayLight(void)
|
||||
uint8_t shutter_mask = 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; }
|
||||
if (PWM_DIMMER == TasmotaGlobal.module_type ) { PwmMod = true; } //
|
||||
if (SONOFF_IFAN02 == TasmotaGlobal.module_type || SONOFF_IFAN03 == TasmotaGlobal.module_type) { FanMod = true; }
|
||||
if (SONOFF_DUAL == TasmotaGlobal.module_type) { valid_relay = 2; }
|
||||
if (TUYA_DIMMER == TasmotaGlobal.module_type || SK03_TUYA == TasmotaGlobal.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
|
||||
@ -423,16 +423,16 @@ void HAssAnnounceRelayLight(void)
|
||||
{
|
||||
|
||||
#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);
|
||||
TuyaRel = TuyaGetDpId((TUYA_MCU_FUNC_REL1+ i-1) + TasmotaGlobal.active_device - 1);
|
||||
TuyaRelInv = TuyaGetDpId((TUYA_MCU_FUNC_REL1_INV+ i-1) + TasmotaGlobal.active_device - 1);
|
||||
TuyaDim = TuyaGetDpId((TUYA_MCU_FUNC_DIMMER) + TasmotaGlobal.active_device - 1);
|
||||
#endif //USE_TUYA_MCU
|
||||
|
||||
masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
TasmotaGlobal.masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
|
||||
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
|
||||
is_topic_light = Settings.flag.hass_light && RelayX || TasmotaGlobal.light_type && !RelayX || PwmMod || (TuyaDim > 0 && TuyaMod); // SetOption30 - Enforce HAss autodiscovery as light
|
||||
ResponseClear(); // 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);
|
||||
@ -468,9 +468,9 @@ void HAssAnnounceRelayLight(void)
|
||||
}
|
||||
|
||||
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);
|
||||
GetTopic_P(command_topic, CMND, TasmotaGlobal.mqtt_topic, value_template);
|
||||
GetTopic_P(state_topic, TELE, TasmotaGlobal.mqtt_topic, D_RSLT_STATE);
|
||||
GetTopic_P(availability_topic, TELE, TasmotaGlobal.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));
|
||||
@ -492,7 +492,7 @@ void HAssAnnounceRelayLight(void)
|
||||
snprintf_P(channel_num, sizeof(channel_num), PSTR("" D_CMND_DIMMER ""));
|
||||
}
|
||||
}
|
||||
GetTopic_P(brightness_command_topic, CMND, mqtt_topic, channel_num);
|
||||
GetTopic_P(brightness_command_topic, CMND, TasmotaGlobal.mqtt_topic, channel_num);
|
||||
TryResponseAppend_P(HASS_DISCOVER_BASE_LIGHT, brightness_command_topic, state_topic, stemp3, channel_num);
|
||||
}
|
||||
if ((ind_light && !PwmMulti) || LightControl) {
|
||||
@ -500,11 +500,11 @@ void HAssAnnounceRelayLight(void)
|
||||
if (Light.subtype >= LST_RGB) {
|
||||
char *rgb_command_topic = stemp1;
|
||||
|
||||
GetTopic_P(rgb_command_topic, CMND, mqtt_topic, D_CMND_COLOR);
|
||||
GetTopic_P(rgb_command_topic, CMND, TasmotaGlobal.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);
|
||||
GetTopic_P(effect_command_topic, CMND, TasmotaGlobal.mqtt_topic, D_CMND_SCHEME);
|
||||
TryResponseAppend_P(HASS_DISCOVER_LIGHT_SCHEME, effect_command_topic, state_topic);
|
||||
}
|
||||
if (LST_RGBW <= Light.subtype) { wt_light = true; }
|
||||
@ -515,7 +515,7 @@ void HAssAnnounceRelayLight(void)
|
||||
!PwmMulti && LightControl)) {
|
||||
char *color_temp_command_topic = stemp1;
|
||||
|
||||
GetTopic_P(color_temp_command_topic, CMND, mqtt_topic, D_CMND_COLORTEMPERATURE);
|
||||
GetTopic_P(color_temp_command_topic, CMND, TasmotaGlobal.mqtt_topic, D_CMND_COLORTEMPERATURE);
|
||||
TryResponseAppend_P(HASS_DISCOVER_LIGHT_CT, color_temp_command_topic, state_topic);
|
||||
ct_light = false;
|
||||
}
|
||||
@ -523,7 +523,7 @@ void HAssAnnounceRelayLight(void)
|
||||
!PwmMulti && LightControl)) {
|
||||
char *white_temp_command_topic = stemp1;
|
||||
|
||||
GetTopic_P(white_temp_command_topic, CMND, mqtt_topic, D_CMND_WHITE);
|
||||
GetTopic_P(white_temp_command_topic, CMND, TasmotaGlobal.mqtt_topic, D_CMND_WHITE);
|
||||
TryResponseAppend_P(HASS_DISCOVER_LIGHT_WHITE, white_temp_command_topic, state_topic);
|
||||
wt_light = false;
|
||||
}
|
||||
@ -534,7 +534,7 @@ void HAssAnnounceRelayLight(void)
|
||||
TryResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
}
|
||||
masterlog_level = ShowTopic;
|
||||
TasmotaGlobal.masterlog_level = ShowTopic;
|
||||
MqttPublish(stopic, true);
|
||||
}
|
||||
}
|
||||
@ -549,14 +549,14 @@ void HAssAnnouncerTriggers(uint8_t device, uint8_t present, uint8_t key, uint8_t
|
||||
char unique_id[30];
|
||||
char trigger2[8];
|
||||
uint8_t ShowTopic; // Used to hide/unhide a topic during Discovery to spare some cpu load
|
||||
mqtt_data[0] = '\0'; // Clear retained message
|
||||
ResponseClear(); // Clear retained message
|
||||
|
||||
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);
|
||||
|
||||
masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
TasmotaGlobal.masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
|
||||
if (Settings.flag.hass_discovery && present) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59)
|
||||
char name[TOPSZ]; // friendlyname(33) + " " + "BTN" + " " + index
|
||||
@ -569,8 +569,8 @@ void HAssAnnouncerTriggers(uint8_t device, uint8_t present, uint8_t key, uint8_t
|
||||
|
||||
GetPowerDevice(value_template, device + 1, sizeof(value_template), key + Settings.flag.device_index_enable); // Force index for Switch 1, Index on Button1 is controlled by SetOption26 - Switch between POWER or POWER1
|
||||
snprintf_P(jsoname, sizeof(jsoname), PSTR("%s%d"), key ? "SWITCH" : "BUTTON", device + 1);
|
||||
GetTopic_P(state_topic, STAT, mqtt_topic, jsoname);
|
||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||
GetTopic_P(state_topic, STAT, TasmotaGlobal.mqtt_topic, jsoname);
|
||||
GetTopic_P(availability_topic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
|
||||
char param[21];
|
||||
char subtype[9];
|
||||
@ -581,19 +581,19 @@ void HAssAnnouncerTriggers(uint8_t device, uint8_t present, uint8_t key, uint8_t
|
||||
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 { ResponseClear(); } // 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
|
||||
ResponseClear(); // Need to be cleaned again to avoid duplicate
|
||||
} else {
|
||||
Response_P(HASS_TRIGGER_TYPE, state_topic, trigger2, trigger1, subtype, ESP_getChipId());
|
||||
}
|
||||
}
|
||||
}
|
||||
masterlog_level = ShowTopic;
|
||||
TasmotaGlobal.masterlog_level = ShowTopic;
|
||||
MqttPublish(stopic, true);
|
||||
}
|
||||
}
|
||||
@ -606,14 +606,14 @@ void HAssAnnouncerBinSensors(uint8_t device, uint8_t present, uint8_t dual, uint
|
||||
char unique_id[30];
|
||||
uint8_t ShowTopic; // Used to hide/unhide a topic during Discovery to spare some cpu load
|
||||
|
||||
mqtt_data[0] = '\0'; // Clear retained message
|
||||
masterlog_level = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
ResponseClear(); // Clear retained message
|
||||
TasmotaGlobal.masterlog_level = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
|
||||
|
||||
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);
|
||||
|
||||
masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
TasmotaGlobal.masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
|
||||
if (Settings.flag.hass_discovery && present ) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59)
|
||||
if (!toggle || dual) {
|
||||
@ -628,8 +628,8 @@ void HAssAnnouncerBinSensors(uint8_t device, uint8_t present, uint8_t dual, uint
|
||||
|
||||
GetPowerDevice(value_template, device + 1, sizeof(value_template), 1 + Settings.flag.device_index_enable); // Force index for Switch 1, Index on Button1 is controlled by SetOption26 - Switch between POWER or POWER1
|
||||
snprintf_P(jsoname, sizeof(jsoname), PSTR("SWITCH%d"), device + 1);
|
||||
GetTopic_P(state_topic, STAT, mqtt_topic, jsoname);
|
||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||
GetTopic_P(state_topic, STAT, TasmotaGlobal.mqtt_topic, jsoname);
|
||||
GetTopic_P(availability_topic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
|
||||
snprintf_P(name, sizeof(name), PSTR("%s Switch%d"), SettingsText(SET_DEVICENAME), device + 1);
|
||||
Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic);
|
||||
@ -650,7 +650,7 @@ void HAssAnnouncerBinSensors(uint8_t device, uint8_t present, uint8_t dual, uint
|
||||
TryResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
}
|
||||
masterlog_level = ShowTopic;
|
||||
TasmotaGlobal.masterlog_level = ShowTopic;
|
||||
MqttPublish(stopic, true);
|
||||
|
||||
}
|
||||
@ -667,7 +667,7 @@ void HAssAnnounceSwitches(void)
|
||||
|
||||
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), TasmotaGlobal.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):
|
||||
@ -739,7 +739,7 @@ void HAssAnnounceButtons(void)
|
||||
uint8_t single = 0;
|
||||
|
||||
#ifdef ESP8266
|
||||
if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)))
|
||||
if (!button_index && ((SONOFF_DUAL == TasmotaGlobal.module_type) || (CH4 == TasmotaGlobal.module_type)))
|
||||
{
|
||||
button_present = 1;
|
||||
} else
|
||||
@ -782,7 +782,7 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const
|
||||
char unique_id[30];
|
||||
char subname[20];
|
||||
|
||||
mqtt_data[0] = '\0'; // Clear retained message
|
||||
ResponseClear(); // Clear retained message
|
||||
|
||||
// Clear or Set topic
|
||||
NoAlNumToUnderscore(subname, MultiSubName); //Replace all non alphaumeric characters to '_' to avoid topic name issues
|
||||
@ -794,11 +794,11 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const
|
||||
char prefix[TOPSZ];
|
||||
char *state_topic = stemp1;
|
||||
char *availability_topic = stemp2;
|
||||
masterlog_level = 0; // Show the new generated topic
|
||||
TasmotaGlobal.masterlog_level = 0; // Show the new generated topic
|
||||
|
||||
GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_SENSOR));
|
||||
GetTopic_P(state_topic, TELE, TasmotaGlobal.mqtt_topic, PSTR(D_RSLT_SENSOR));
|
||||
snprintf_P(name, sizeof(name), PSTR("%s %s %s"), SettingsText(SET_DEVICENAME), sensorname, MultiSubName);
|
||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||
GetTopic_P(availability_topic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
|
||||
Response_P(HASS_DISCOVER_BASE, name, state_topic);
|
||||
#ifdef DEEPSLEEP_LWT_HA_DISCOVERY
|
||||
@ -850,14 +850,14 @@ void HAssAnnounceSensors(void)
|
||||
uint8_t hass_xsns_index = 0;
|
||||
do
|
||||
{
|
||||
mqtt_data[0] = '\0';
|
||||
int tele_period_save = tele_period;
|
||||
tele_period = 2; // Do not allow HA updates during next function call
|
||||
ResponseClear();
|
||||
int tele_period_save = TasmotaGlobal.tele_period;
|
||||
TasmotaGlobal.tele_period = 2; // Do not allow HA updates during next function call
|
||||
XsnsNextCall(FUNC_JSON_APPEND, hass_xsns_index); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
tele_period = tele_period_save;
|
||||
size_t sensordata_len = strlen(mqtt_data);
|
||||
TasmotaGlobal.tele_period = tele_period_save;
|
||||
size_t sensordata_len = strlen(TasmotaGlobal.mqtt_data);
|
||||
char sensordata[sensordata_len+2]; // dynamically adjust the size
|
||||
strcpy(sensordata, mqtt_data); // we can use strcpy since the buffer has the right size
|
||||
strcpy(sensordata, TasmotaGlobal.mqtt_data); // we can use strcpy since the buffer has the right size
|
||||
|
||||
// ******************* JSON TEST *******************
|
||||
// char sensordata[512];
|
||||
@ -932,8 +932,8 @@ void HAssAnnounceShutters(void)
|
||||
uint8_t ShowTopic; // Used to hide/unhide a topic during Discovery to spare some cpu load
|
||||
|
||||
for (uint32_t i = 0; i < MAX_SHUTTERS; i++) {
|
||||
mqtt_data[0] = '\0'; // Clear retained message
|
||||
masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
ResponseClear(); // Clear retained message
|
||||
TasmotaGlobal.masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
|
||||
|
||||
snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_SHT_%d"), ESP_getChipId(), i + 1);
|
||||
@ -946,24 +946,24 @@ void HAssAnnounceShutters(void)
|
||||
} else {
|
||||
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s"), SettingsText(SET_FRIENDLYNAME1 + i));
|
||||
}
|
||||
GetTopic_P(stemp2, TELE, mqtt_topic, D_RSLT_STATE);
|
||||
GetTopic_P(stemp2, TELE, TasmotaGlobal.mqtt_topic, D_RSLT_STATE);
|
||||
Response_P(HASS_DISCOVER_BASE, stemp1, stemp2);
|
||||
|
||||
GetTopic_P(stemp1, TELE, mqtt_topic, S_LWT);
|
||||
GetTopic_P(stemp1, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, stemp1);
|
||||
|
||||
GetTopic_P(stemp1, CMND, mqtt_topic, PSTR("Backlog"));
|
||||
GetTopic_P(stemp1, CMND, TasmotaGlobal.mqtt_topic, PSTR("Backlog"));
|
||||
TryResponseAppend_P(HASS_DISCOVER_SHUTTER_BASE, stemp1, i + 1, i + 1, i + 1);
|
||||
|
||||
GetTopic_P(stemp1, STAT, mqtt_topic, PSTR("SHUTTER"));
|
||||
GetTopic_P(stemp2, CMND, mqtt_topic, PSTR("ShutterPosition"));
|
||||
GetTopic_P(stemp1, STAT, TasmotaGlobal.mqtt_topic, PSTR("SHUTTER"));
|
||||
GetTopic_P(stemp2, CMND, TasmotaGlobal.mqtt_topic, PSTR("ShutterPosition"));
|
||||
TryResponseAppend_P(HASS_DISCOVER_SHUTTER_POS, stemp1, i + 1, stemp2, i + 1);
|
||||
|
||||
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId());
|
||||
TryResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
|
||||
masterlog_level = ShowTopic;
|
||||
TasmotaGlobal.masterlog_level = ShowTopic;
|
||||
MqttPublish(stopic, true);
|
||||
}
|
||||
#endif
|
||||
@ -978,8 +978,8 @@ void HAssAnnounceDeviceInfoAndStatusSensor(void)
|
||||
uint8_t ShowTopic; // Used to hide/unhide a topic during Discovery to spare some cpu load
|
||||
|
||||
// Announce sensor
|
||||
mqtt_data[0] = '\0'; // Clear retained message
|
||||
masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
ResponseClear(); // Clear retained message
|
||||
TasmotaGlobal.masterlog_level = ShowTopic = 4; // Hide topic on clean and remove use weblog 4 to see it
|
||||
// Clear or Set topic
|
||||
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);
|
||||
@ -992,21 +992,21 @@ void HAssAnnounceDeviceInfoAndStatusSensor(void)
|
||||
char *availability_topic = stemp2;
|
||||
ShowTopic = 0; // Show the new generated topic
|
||||
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);
|
||||
GetTopic_P(state_topic, TELE, TasmotaGlobal.mqtt_topic, PSTR(D_RSLT_HASS_STATE));
|
||||
GetTopic_P(availability_topic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
|
||||
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_DEVICENAME),
|
||||
ModuleName().c_str(), my_version, my_image);
|
||||
ModuleName().c_str(), TasmotaGlobal.version, TasmotaGlobal.image_name);
|
||||
TryResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
masterlog_level = ShowTopic;
|
||||
TasmotaGlobal.masterlog_level = ShowTopic;
|
||||
MqttPublish(stopic, true);
|
||||
|
||||
if (!Settings.flag.hass_discovery) {
|
||||
masterlog_level = 0;
|
||||
TasmotaGlobal.masterlog_level = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_LOG "Home Assistant MQTT Discovery disabled."));
|
||||
}
|
||||
}
|
||||
@ -1017,9 +1017,9 @@ void HAssPublishStatus(void)
|
||||
"\"" 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);
|
||||
TasmotaGlobal.version, TasmotaGlobal.image_name, GetBuildDateAndTime().c_str(), ModuleName().c_str(), GetResetReason().c_str(),
|
||||
GetUptime().c_str(), TasmotaGlobal.hostname, WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()),
|
||||
WiFi.RSSI(), WifiLinkCount(), WifiDowntime().c_str(), MqttConnectCount(), TasmotaGlobal.loop_load_avg);
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE));
|
||||
}
|
||||
|
||||
@ -1056,7 +1056,7 @@ void HAssDiscovery(void)
|
||||
|
||||
// Send info about status sensor
|
||||
HAssAnnounceDeviceInfoAndStatusSensor();
|
||||
masterlog_level = 0; // Restores weblog level
|
||||
TasmotaGlobal.masterlog_level = 0; // Restores weblog level
|
||||
hass_mode = 3; // Needed for generating bluetooth entities for MI_ESP32
|
||||
}
|
||||
}
|
||||
@ -1102,7 +1102,7 @@ void HAssAnyKey(void)
|
||||
}
|
||||
}
|
||||
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
|
||||
GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, scommand);
|
||||
Response_P(S_JSON_COMMAND_SVALUE, (evkey) ? "TRIG" : PSTR(D_RSLT_STATE), (key) ? GetStateText(state) : trg_state);
|
||||
MqttPublish(stopic);
|
||||
}
|
||||
@ -1155,7 +1155,7 @@ bool Xdrv12(uint8_t function)
|
||||
if (hass_tele_period >= Settings.tele_period)
|
||||
{
|
||||
hass_tele_period = 0;
|
||||
mqtt_data[0] = '\0';
|
||||
ResponseClear();
|
||||
HAssPublishStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@ -776,7 +776,7 @@ void DisplayText(void)
|
||||
buttons[num]->vpower.disable=dis;
|
||||
if (!dis) {
|
||||
if (buttons[num]->vpower.is_virtual) buttons[num]->xdrawButton(buttons[num]->vpower.on_off);
|
||||
else buttons[num]->xdrawButton(bitRead(power,num));
|
||||
else buttons[num]->xdrawButton(bitRead(TasmotaGlobal.power,num));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -828,7 +828,7 @@ void DisplayText(void)
|
||||
renderer->GetColorFromIndex(fill),renderer->GetColorFromIndex(textcolor),bbuff,textsize);
|
||||
if (!bflags) {
|
||||
// power button
|
||||
if (dflg) buttons[num]->xdrawButton(bitRead(power,num));
|
||||
if (dflg) buttons[num]->xdrawButton(bitRead(TasmotaGlobal.power,num));
|
||||
buttons[num]->vpower.is_virtual=0;
|
||||
} else {
|
||||
// virtual button
|
||||
@ -1034,7 +1034,7 @@ void DisplayLogBufferInit(void)
|
||||
DisplayReAllocLogBuffer();
|
||||
|
||||
char buffer[40];
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_VERSION " %s%s"), my_version, my_image);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_VERSION " %s%s"), TasmotaGlobal.version, TasmotaGlobal.image_name);
|
||||
DisplayLogBufferAdd(buffer);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR("Display mode %d"), Settings.display_mode);
|
||||
DisplayLogBufferAdd(buffer);
|
||||
@ -1045,7 +1045,7 @@ void DisplayLogBufferInit(void)
|
||||
DisplayLogBufferAdd(buffer);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), NetworkAddress().toString().c_str());
|
||||
DisplayLogBufferAdd(buffer);
|
||||
if (!global_state.wifi_down) {
|
||||
if (!TasmotaGlobal.global_state.wifi_down) {
|
||||
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()));
|
||||
@ -1262,10 +1262,10 @@ bool DisplayMqttData(void)
|
||||
|
||||
void DisplayLocalSensor(void)
|
||||
{
|
||||
if ((Settings.display_mode &0x02) && (0 == tele_period)) {
|
||||
if ((Settings.display_mode &0x02) && (0 == TasmotaGlobal.tele_period)) {
|
||||
char no_topic[1] = { 0 };
|
||||
// DisplayAnalyzeJson(mqtt_topic, mqtt_data); // Add local topic
|
||||
DisplayAnalyzeJson(no_topic, mqtt_data); // Discard any topic
|
||||
// DisplayAnalyzeJson(TasmotaGlobal.mqtt_topic, TasmotaGlobal.mqtt_data); // Add local topic
|
||||
DisplayAnalyzeJson(no_topic, TasmotaGlobal.mqtt_data); // Discard any topic
|
||||
}
|
||||
}
|
||||
|
||||
@ -1288,13 +1288,13 @@ void DisplayInitDriver(void)
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings.display_model);
|
||||
|
||||
if (Settings.display_model) {
|
||||
devices_present++;
|
||||
TasmotaGlobal.devices_present++;
|
||||
if (!PinUsed(GPIO_BACKLIGHT)) {
|
||||
if (light_type && (4 == Settings.display_model)) {
|
||||
devices_present--; // Assume PWM channel is used for backlight
|
||||
if (TasmotaGlobal.light_type && (4 == Settings.display_model)) {
|
||||
TasmotaGlobal.devices_present--; // Assume PWM channel is used for backlight
|
||||
}
|
||||
}
|
||||
disp_device = devices_present;
|
||||
disp_device = TasmotaGlobal.devices_present;
|
||||
|
||||
#ifndef USE_DISPLAY_MODES1TO5
|
||||
Settings.display_mode = 0;
|
||||
@ -1339,7 +1339,7 @@ void CmndDisplayModel(void)
|
||||
uint32_t last_display_model = Settings.display_model;
|
||||
Settings.display_model = XdrvMailbox.payload;
|
||||
if (XdspCall(FUNC_DISPLAY_MODEL)) {
|
||||
restart_flag = 2; // Restart to re-init interface and add/Remove MQTT subscribe
|
||||
TasmotaGlobal.restart_flag = 2; // Restart to re-init interface and add/Remove MQTT subscribe
|
||||
} else {
|
||||
Settings.display_model = last_display_model;
|
||||
}
|
||||
@ -1352,7 +1352,7 @@ void CmndDisplayWidth(void)
|
||||
if (XdrvMailbox.payload > 0) {
|
||||
if (XdrvMailbox.payload != Settings.display_width) {
|
||||
Settings.display_width = XdrvMailbox.payload;
|
||||
restart_flag = 2; // Restart to re-init width
|
||||
TasmotaGlobal.restart_flag = 2; // Restart to re-init width
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber(Settings.display_width);
|
||||
@ -1363,7 +1363,7 @@ void CmndDisplayHeight(void)
|
||||
if (XdrvMailbox.payload > 0) {
|
||||
if (XdrvMailbox.payload != Settings.display_height) {
|
||||
Settings.display_height = XdrvMailbox.payload;
|
||||
restart_flag = 2; // Restart to re-init height
|
||||
TasmotaGlobal.restart_flag = 2; // Restart to re-init height
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber(Settings.display_height);
|
||||
@ -1384,7 +1384,7 @@ void CmndDisplayMode(void)
|
||||
Settings.display_mode = XdrvMailbox.payload;
|
||||
|
||||
if (disp_subscribed != (Settings.display_mode &0x04)) {
|
||||
restart_flag = 2; // Restart to Add/Remove MQTT subscribe
|
||||
TasmotaGlobal.restart_flag = 2; // Restart to Add/Remove MQTT subscribe
|
||||
} else {
|
||||
if (last_display_mode && !Settings.display_mode) { // Switch to mode 0
|
||||
DisplayInit(DISPLAY_INIT_MODE);
|
||||
@ -2124,7 +2124,7 @@ uint8_t vbutt=0;
|
||||
buttons[count]->press(true);
|
||||
if (buttons[count]->justPressed()) {
|
||||
if (!buttons[count]->vpower.is_virtual) {
|
||||
uint8_t pwr=bitRead(power, rbutt);
|
||||
uint8_t pwr=bitRead(TasmotaGlobal.power, rbutt);
|
||||
if (!SendKey(KEY_BUTTON, rbutt+1, POWER_TOGGLE)) {
|
||||
ExecuteCommandPower(rbutt+1, POWER_TOGGLE, SRC_BUTTON);
|
||||
Touch_RDW_BUTT(count, !pwr);
|
||||
@ -2171,7 +2171,7 @@ uint8_t vbutt=0;
|
||||
}
|
||||
if (!buttons[count]->vpower.is_virtual) {
|
||||
// check if power button stage changed
|
||||
uint8_t pwr = bitRead(power, rbutt);
|
||||
uint8_t pwr = bitRead(TasmotaGlobal.power, rbutt);
|
||||
uint8_t vpwr = buttons[count]->vpower.on_off;
|
||||
if (pwr != vpwr) {
|
||||
Touch_RDW_BUTT(count, pwr);
|
||||
@ -2196,7 +2196,7 @@ bool Xdrv13(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if ((i2c_flg || spi_flg || soft_spi_flg) && XdspPresent()) {
|
||||
if ((TasmotaGlobal.i2c_enabled || TasmotaGlobal.spi_enabled || TasmotaGlobal.soft_spi_enabled) && XdspPresent()) {
|
||||
switch (function) {
|
||||
case FUNC_PRE_INIT:
|
||||
DisplayInitDriver();
|
||||
|
||||
@ -196,7 +196,7 @@ bool Xdrv15(uint8_t function)
|
||||
else if (pca9685_detected) {
|
||||
switch (function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
if (tele_period == 0) {
|
||||
if (TasmotaGlobal.tele_period == 0) {
|
||||
PCA9685_OutputTelemetry(true);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -93,12 +93,12 @@ void (* const TuyaCommand[])(void) PROGMEM = {
|
||||
\*********************************************************************************************/
|
||||
bool IsModuleTuya(void)
|
||||
{
|
||||
return ((TUYA_DIMMER == my_module_type) || (SK03_TUYA == my_module_type));
|
||||
return ((TUYA_DIMMER == TasmotaGlobal.module_type) || (SK03_TUYA == TasmotaGlobal.module_type));
|
||||
}
|
||||
|
||||
bool AsModuleTuyaMS(void) // ModeSet Layout
|
||||
{
|
||||
return ((light_type > LT_RGB) && TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0);
|
||||
return ((TasmotaGlobal.light_type > LT_RGB) && TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0);
|
||||
}
|
||||
|
||||
bool IsTuyaFanCtrl(void) // Fan Speed Controller Layout
|
||||
@ -195,7 +195,7 @@ void CmndTuyaMcu(void) {
|
||||
|
||||
if (TuyaFuncIdValid(parm[0])) {
|
||||
// TuyaAddMcuFunc(parm[0], parm[1]);
|
||||
// restart_flag = 2;
|
||||
// TasmotaGlobal.restart_flag = 2;
|
||||
// } else {
|
||||
// AddLog_P2(LOG_LEVEL_ERROR, PSTR("TYA: TuyaMcu Invalid function id=%d"), parm[0]);
|
||||
// }
|
||||
@ -212,7 +212,7 @@ void CmndTuyaMcu(void) {
|
||||
Settings.flag3.pwm_multi_channels = 1;
|
||||
} else { Settings.flag3.pwm_multi_channels = 0; }
|
||||
TuyaAddMcuFunc(parm[0], parm[1]);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
} else {
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("TYA: TuyaMcu Invalid function id=%d"), parm[0]);
|
||||
}
|
||||
@ -270,9 +270,9 @@ void UpdateDevices() {
|
||||
if (fnId > TUYA_MCU_FUNC_NONE && Settings.tuya_fnid_map[i].dpid > 0) {
|
||||
|
||||
if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) { //Relay
|
||||
bitClear(rel_inverted, fnId - TUYA_MCU_FUNC_REL1);
|
||||
bitClear(TasmotaGlobal.rel_inverted, fnId - TUYA_MCU_FUNC_REL1);
|
||||
} else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) { // Inverted Relay
|
||||
bitSet(rel_inverted, fnId - TUYA_MCU_FUNC_REL1_INV);
|
||||
bitSet(TasmotaGlobal.rel_inverted, fnId - TUYA_MCU_FUNC_REL1_INV);
|
||||
}
|
||||
|
||||
}
|
||||
@ -317,15 +317,15 @@ void TuyaSendCmd(uint8_t cmd, uint8_t payload[] = nullptr, uint16_t payload_len
|
||||
TuyaSerial->write(cmd); // Tuya command
|
||||
TuyaSerial->write(payload_len >> 8); // following data length (Hi)
|
||||
TuyaSerial->write(payload_len & 0xFF); // following data length (Lo)
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Send \"55aa00%02x%02x%02x"), cmd, payload_len >> 8, payload_len & 0xFF);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("TYA: Send \"55aa00%02x%02x%02x"), cmd, payload_len >> 8, payload_len & 0xFF);
|
||||
for (uint32_t i = 0; i < payload_len; ++i) {
|
||||
TuyaSerial->write(payload[i]);
|
||||
checksum += payload[i];
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, payload[i]);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s%02x"), TasmotaGlobal.log_data, payload[i]);
|
||||
}
|
||||
TuyaSerial->write(checksum);
|
||||
TuyaSerial->flush();
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x\""), log_data, checksum);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s%02x\""), TasmotaGlobal.log_data, checksum);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
}
|
||||
|
||||
@ -397,11 +397,11 @@ bool TuyaSetPower(void)
|
||||
uint8_t rpower = XdrvMailbox.index;
|
||||
int16_t source = XdrvMailbox.payload;
|
||||
|
||||
uint8_t dpid = TuyaGetDpId(TUYA_MCU_FUNC_REL1 + active_device - 1);
|
||||
if (dpid == 0) dpid = TuyaGetDpId(TUYA_MCU_FUNC_REL1_INV + active_device - 1);
|
||||
uint8_t dpid = TuyaGetDpId(TUYA_MCU_FUNC_REL1 + TasmotaGlobal.active_device - 1);
|
||||
if (dpid == 0) dpid = TuyaGetDpId(TUYA_MCU_FUNC_REL1_INV + TasmotaGlobal.active_device - 1);
|
||||
|
||||
if (source != SRC_SWITCH && TuyaSerial) { // ignore to prevent loop from pushing state from faceplate interaction
|
||||
TuyaSendBool(dpid, bitRead(rpower, active_device-1) ^ bitRead(rel_inverted, active_device-1));
|
||||
TuyaSendBool(dpid, bitRead(rpower, TasmotaGlobal.active_device-1) ^ bitRead(TasmotaGlobal.rel_inverted, TasmotaGlobal.active_device-1));
|
||||
delay(20); // Hack when power is off and dimmer is set then both commands go too soon to Serial out.
|
||||
status = true;
|
||||
}
|
||||
@ -419,12 +419,12 @@ bool TuyaSetChannels(void)
|
||||
uint8_t idx = 0;
|
||||
snprintf_P(hex_char, sizeof(hex_char), PSTR("000000000000"));
|
||||
|
||||
if (LT_SERIAL1 == light_type) {
|
||||
if (LT_SERIAL1 == TasmotaGlobal.light_type) {
|
||||
Tuya.Snapshot[0] = light_state.getDimmer();
|
||||
}
|
||||
if (LT_SERIAL2 == light_type || LT_RGBWC == light_type) {
|
||||
if (LT_SERIAL2 == TasmotaGlobal.light_type || LT_RGBWC == TasmotaGlobal.light_type) {
|
||||
idx = 1;
|
||||
if (LT_SERIAL2 == light_type && Settings.flag3.pwm_multi_channels && (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER2) != 0)) {
|
||||
if (LT_SERIAL2 == TasmotaGlobal.light_type && Settings.flag3.pwm_multi_channels && (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER2) != 0)) {
|
||||
// Special setup for dual dimmer (like the MOES 2 Way Dimmer) emulating 2 PWM channels
|
||||
Tuya.Snapshot[0] = changeUIntScale(Light.current_color[0], 0, 255, 0, 100);
|
||||
Tuya.Snapshot[1] = changeUIntScale(Light.current_color[1], 0, 255, 0, 100);
|
||||
@ -434,15 +434,15 @@ bool TuyaSetChannels(void)
|
||||
Tuya.Snapshot[1] = light_state.getCT();
|
||||
}
|
||||
}
|
||||
if (LT_RGBW == light_type) {
|
||||
if (LT_RGBW == TasmotaGlobal.light_type) {
|
||||
idx = 1;
|
||||
Tuya.Snapshot[0] = light_state.getDimmer(1);
|
||||
Tuya.Snapshot[1] = light_state.getDimmer(2);
|
||||
}
|
||||
|
||||
if (light_type > LT_BASIC) {
|
||||
if (TasmotaGlobal.light_type > LT_BASIC) {
|
||||
|
||||
if (LT_RGB != light_type) {
|
||||
if (LT_RGB != TasmotaGlobal.light_type) {
|
||||
for (uint8_t i = 0; i <= idx; i++) {
|
||||
if (Tuya.Snapshot[i] != Tuya.Levels[i]) {
|
||||
if (i == 0 && LightMode && Tuya.ModeSet ) { noupd = true;}
|
||||
@ -455,13 +455,13 @@ bool TuyaSetChannels(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (light_type >= LT_RGB) {
|
||||
if (TasmotaGlobal.light_type >= LT_RGB) {
|
||||
|
||||
light_state.getHSB(&hue, &sat, &bri);
|
||||
sat = changeUIntScale(sat, 0, 255, 0, 100);
|
||||
bri = changeUIntScale(bri, 0, 255, 0, 100);
|
||||
if (hue != Tuya.Snapshot[2] || sat != Tuya.Snapshot[3] || bri != Tuya.Snapshot[4]) {
|
||||
if ((LightMode && Tuya.ModeSet) || LT_RGB == light_type) {
|
||||
if ((LightMode && Tuya.ModeSet) || LT_RGB == TasmotaGlobal.light_type) {
|
||||
snprintf_P(hex_char, sizeof(hex_char), PSTR("%04X%04X%04X"), hue, sat * 10, bri * 10); // Create a TuyaMCU readable RGB payload
|
||||
LightSerialDuty(0, &hex_char[0], 3);
|
||||
memcpy_P(Tuya.HSBColor, hex_char, strlen(hex_char));
|
||||
@ -496,7 +496,7 @@ void LightSerialDuty(uint16_t duty, char *hex_char, uint8_t TuyaIdx)
|
||||
|
||||
if (duty < Settings.dimmer_hw_min) { duty = Settings.dimmer_hw_min; } // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself
|
||||
Tuya.ignore_dimmer_cmd_timeout = millis() + 250; // Ignore serial received dim commands for the next 250ms
|
||||
if (Tuya.ModeSet && (TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0) && light_type > LT_RGB) {
|
||||
if (Tuya.ModeSet && (TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0) && TasmotaGlobal.light_type > LT_RGB) {
|
||||
TuyaSendEnum(TuyaGetDpId(TUYA_MCU_FUNC_MODESET), 0);
|
||||
}
|
||||
TuyaSendValue(dpid, duty);
|
||||
@ -518,7 +518,7 @@ void LightSerialDuty(uint16_t duty, char *hex_char, uint8_t TuyaIdx)
|
||||
|
||||
if (TuyaIdx == 3) {
|
||||
dpid = TuyaGetDpId(TUYA_MCU_FUNC_RGB);
|
||||
if (!Tuya.ModeSet && (TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0) && light_type > LT_RGB) {
|
||||
if (!Tuya.ModeSet && (TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0) && TasmotaGlobal.light_type > LT_RGB) {
|
||||
TuyaSendEnum(TuyaGetDpId(TUYA_MCU_FUNC_MODESET), 1);
|
||||
}
|
||||
TuyaSendString(dpid, hex_char);
|
||||
@ -568,13 +568,13 @@ void TuyaProcessStatePacket(void) {
|
||||
if (Tuya.buffer[dpidStart + 1] == 1) { // Data Type 1
|
||||
|
||||
if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4]?"On":"Off",bitRead(power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off");
|
||||
if ((power || Settings.light_dimmer > 0) && (Tuya.buffer[dpidStart + 4] != bitRead(power, fnId - TUYA_MCU_FUNC_REL1))) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4]?"On":"Off",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off");
|
||||
if ((TasmotaGlobal.power || Settings.light_dimmer > 0) && (Tuya.buffer[dpidStart + 4] != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1))) {
|
||||
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
|
||||
}
|
||||
} else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d-Inverted --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[dpidStart + 4]?"Off":"On",bitRead(power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1?"Off":"On");
|
||||
if (Tuya.buffer[dpidStart + 4] != bitRead(power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d-Inverted --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[dpidStart + 4]?"Off":"On",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1?"Off":"On");
|
||||
if (Tuya.buffer[dpidStart + 4] != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1) {
|
||||
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[dpidStart + 4] ^ 1, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
|
||||
}
|
||||
} else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) {
|
||||
@ -587,7 +587,7 @@ void TuyaProcessStatePacket(void) {
|
||||
}
|
||||
}
|
||||
else if (Tuya.buffer[dpidStart + 1] == 2) { // Data Type 2
|
||||
bool tuya_energy_enabled = (XNRG_32 == energy_flg);
|
||||
bool tuya_energy_enabled = (XNRG_32 == TasmotaGlobal.energy_driver);
|
||||
uint16_t packetValue = Tuya.buffer[dpidStart + 6] << 8 | Tuya.buffer[dpidStart + 7];
|
||||
uint8_t dimIndex;
|
||||
if ((fnId == TUYA_MCU_FUNC_FAN3) || (fnId == TUYA_MCU_FUNC_FAN4) ||
|
||||
@ -613,10 +613,10 @@ void TuyaProcessStatePacket(void) {
|
||||
|
||||
if (Tuya.ignore_dimmer_cmd_timeout < millis()) {
|
||||
|
||||
if ((power || Settings.flag3.tuya_apply_o20) && ((Tuya.Levels[dimIndex] > 0) && (Tuya.Levels[dimIndex] != Tuya.Snapshot[dimIndex]))) { // SetOption54 - Apply SetOption20 settings to Tuya device
|
||||
if ((TasmotaGlobal.power || Settings.flag3.tuya_apply_o20) && ((Tuya.Levels[dimIndex] > 0) && (Tuya.Levels[dimIndex] != Tuya.Snapshot[dimIndex]))) { // SetOption54 - Apply SetOption20 settings to Tuya device
|
||||
|
||||
Tuya.ignore_dim = true;
|
||||
skip_light_fade = true;
|
||||
TasmotaGlobal.skip_light_fade = true;
|
||||
|
||||
scmnd[0] = '\0';
|
||||
if ((fnId == TUYA_MCU_FUNC_DIMMER) || (fnId == TUYA_MCU_FUNC_REPORT1)) {
|
||||
@ -770,11 +770,11 @@ void TuyaNormalPowerModePacketProcess(void)
|
||||
}
|
||||
if (!Settings.my_gp.io[led1_gpio] && !led1_set) {
|
||||
Settings.my_gp.io[led1_gpio] = AGPIO(GPIO_LED1);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
if (!Settings.my_gp.io[key1_gpio] && !key1_set) {
|
||||
Settings.my_gp.io[key1_gpio] = AGPIO(GPIO_KEY1);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
}
|
||||
TuyaRequestState(0);
|
||||
@ -796,7 +796,7 @@ bool TuyaModuleSelected(void)
|
||||
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;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER) == 0 && TUYA_DIMMER_ID > 0) {
|
||||
@ -809,13 +809,13 @@ bool TuyaModuleSelected(void)
|
||||
if ((Settings.tuya_fnid_map[i].fnid >= TUYA_MCU_FUNC_REL1 && Settings.tuya_fnid_map[i].fnid <= TUYA_MCU_FUNC_REL8 ) ||
|
||||
(Settings.tuya_fnid_map[i].fnid >= TUYA_MCU_FUNC_REL1_INV && Settings.tuya_fnid_map[i].fnid <= TUYA_MCU_FUNC_REL8_INV )) {
|
||||
relaySet = true;
|
||||
devices_present++;
|
||||
TasmotaGlobal.devices_present++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!relaySet && TuyaGetDpId(TUYA_MCU_FUNC_DUMMY) == 0) { //by default the first relay is created automatically the dummy let remove it if not needed
|
||||
TuyaAddMcuFunc(TUYA_MCU_FUNC_REL1, 1);
|
||||
devices_present++;
|
||||
TasmotaGlobal.devices_present++;
|
||||
SettingsSaveAll();
|
||||
}
|
||||
|
||||
@ -831,17 +831,17 @@ bool TuyaModuleSelected(void)
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER) != 0) {
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_RGB) != 0) {
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_CT) != 0) {
|
||||
light_type = LT_RGBWC;
|
||||
TasmotaGlobal.light_type = LT_RGBWC;
|
||||
} else if (TuyaGetDpId(TUYA_MCU_FUNC_WHITE) != 0) {
|
||||
light_type = LT_RGBW;
|
||||
} else { light_type = LT_RGB; }
|
||||
TasmotaGlobal.light_type = LT_RGBW;
|
||||
} else { TasmotaGlobal.light_type = LT_RGB; }
|
||||
} else if (TuyaGetDpId(TUYA_MCU_FUNC_CT) != 0 || TuyaGetDpId(TUYA_MCU_FUNC_DIMMER2) != 0) {
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_RGB) != 0) {
|
||||
light_type = LT_RGBWC;
|
||||
} else { light_type = LT_SERIAL2; }
|
||||
} else { light_type = LT_SERIAL1; }
|
||||
TasmotaGlobal.light_type = LT_RGBWC;
|
||||
} else { TasmotaGlobal.light_type = LT_SERIAL2; }
|
||||
} else { TasmotaGlobal.light_type = LT_SERIAL1; }
|
||||
} else {
|
||||
light_type = LT_BASIC;
|
||||
TasmotaGlobal.light_type = LT_BASIC;
|
||||
}
|
||||
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_LOWPOWER_MODE) != 0) {
|
||||
@ -963,7 +963,7 @@ void TuyaSerialInput(void)
|
||||
if (Settings.flag3.tuya_serial_mqtt_publish) { // SetOption66 - Enable TuyaMcuReceived messages over Mqtt
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_TUYA_MCU_RECEIVED));
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, mqtt_data);
|
||||
AddLog_P(LOG_LEVEL_DEBUG, TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
XdrvRulesProcess();
|
||||
|
||||
@ -1071,7 +1071,7 @@ bool Xnrg32(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (TUYA_DIMMER == my_module_type) {
|
||||
if (TUYA_DIMMER == TasmotaGlobal.module_type) {
|
||||
if (FUNC_PRE_INIT == function) {
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_POWER) != 0) {
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_CURRENT) == 0) {
|
||||
@ -1080,7 +1080,7 @@ bool Xnrg32(uint8_t function)
|
||||
if (TuyaGetDpId(TUYA_MCU_FUNC_VOLTAGE) == 0) {
|
||||
Energy.voltage_available = false;
|
||||
}
|
||||
energy_flg = XNRG_32;
|
||||
TasmotaGlobal.energy_driver = XNRG_32;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1096,7 +1096,7 @@ bool Xdrv16(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (TUYA_DIMMER == my_module_type) {
|
||||
if (TUYA_DIMMER == TasmotaGlobal.module_type) {
|
||||
switch (function) {
|
||||
case FUNC_LOOP:
|
||||
if (TuyaSerial) { TuyaSerialInput(); }
|
||||
@ -1123,7 +1123,7 @@ bool Xdrv16(uint8_t function)
|
||||
TuyaSendCmd(TUYA_CMD_HEARTBEAT);
|
||||
}
|
||||
#ifdef USE_TUYA_TIME
|
||||
if (!(uptime % 60)) {
|
||||
if (!(TasmotaGlobal.uptime % 60)) {
|
||||
TuyaSetTime();
|
||||
}
|
||||
#endif //USE_TUYA_TIME
|
||||
|
||||
@ -86,8 +86,8 @@ void ArmtronixRequestState(void)
|
||||
|
||||
bool ArmtronixModuleSelected(void)
|
||||
{
|
||||
devices_present++;
|
||||
light_type = LT_SERIAL2;
|
||||
TasmotaGlobal.devices_present++;
|
||||
TasmotaGlobal.light_type = LT_SERIAL2;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ bool Xdrv18(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (ARMTRONIX_DIMMERS == my_module_type) {
|
||||
if (ARMTRONIX_DIMMERS == TasmotaGlobal.module_type) {
|
||||
switch (function) {
|
||||
case FUNC_LOOP:
|
||||
if (ArmtronixSerial) { ArmtronixSerialInput(); }
|
||||
@ -182,7 +182,7 @@ bool Xdrv18(uint8_t function)
|
||||
case FUNC_EVERY_SECOND:
|
||||
if (ArmtronixSerial) {
|
||||
if (Armtronix.wifi_state!=WifiState()) { ArmtronixSetWifiLed(); }
|
||||
if (uptime &1) {
|
||||
if (TasmotaGlobal.uptime &1) {
|
||||
ArmtronixSerial->println("Status");
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ void PS16DZSerialSendUpdateCommand(void)
|
||||
|
||||
char tx_buffer[80];
|
||||
snprintf_P(tx_buffer, sizeof(tx_buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"bright\":%d"),
|
||||
LocalTime(), millis()%1000, power?"on":"off", light_state_dimmer);
|
||||
LocalTime(), millis()%1000, TasmotaGlobal.power?"on":"off", light_state_dimmer);
|
||||
|
||||
PS16DZSerialSend(tx_buffer);
|
||||
}
|
||||
@ -120,7 +120,7 @@ void PS16DZSerialInput(void)
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Switch %d"), switch_state);
|
||||
|
||||
is_switch_change = (switch_state != power);
|
||||
is_switch_change = (switch_state != TasmotaGlobal.power);
|
||||
if (is_switch_change) {
|
||||
ExecuteCommandPower(1, switch_state, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
|
||||
}
|
||||
@ -131,7 +131,7 @@ void PS16DZSerialInput(void)
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Brightness %d"), Ps16dz.dimmer);
|
||||
|
||||
is_brightness_change = Ps16dz.dimmer != Settings.light_dimmer;
|
||||
if (power && (Ps16dz.dimmer > 0) && is_brightness_change) {
|
||||
if (TasmotaGlobal.power && (Ps16dz.dimmer > 0) && is_brightness_change) {
|
||||
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), Ps16dz.dimmer);
|
||||
ExecuteCommand(scmnd, SRC_SWITCH);
|
||||
}
|
||||
@ -196,8 +196,8 @@ void PS16DZInit(void)
|
||||
|
||||
bool PS16DZModuleSelected(void)
|
||||
{
|
||||
devices_present++;
|
||||
light_type = LT_SERIAL1;
|
||||
TasmotaGlobal.devices_present++;
|
||||
TasmotaGlobal.light_type = LT_SERIAL1;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -210,7 +210,7 @@ bool Xdrv19(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (PS_16_DZ == my_module_type) {
|
||||
if (PS_16_DZ == TasmotaGlobal.module_type) {
|
||||
switch (function) {
|
||||
case FUNC_LOOP:
|
||||
if (PS16DZSerial) { PS16DZSerialInput(); }
|
||||
|
||||
@ -305,7 +305,7 @@ char prev_x_str[24] = "\0"; // store previously set xy by Alexa app
|
||||
char prev_y_str[24] = "\0";
|
||||
|
||||
uint8_t getLocalLightSubtype(uint8_t device) {
|
||||
if (light_type) {
|
||||
if (TasmotaGlobal.light_type) {
|
||||
if (device >= Light.device) {
|
||||
if (Settings.flag3.pwm_multi_channels) { // SetOption68 - Enable multi-channels PWM instead of Color PWM
|
||||
return LST_SINGLE; // If SetOption68, each channel acts like a dimmer
|
||||
@ -343,7 +343,7 @@ void HueLightStatus1(uint8_t device, String *response)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (light_type) {
|
||||
if (TasmotaGlobal.light_type) {
|
||||
light_state.getHSB(&hue, &sat, nullptr);
|
||||
if (sat > 254) sat = 254; // Philips Hue only accepts 254 as max hue
|
||||
hue = changeUIntScale(hue, 0, 360, 0, 65535);
|
||||
@ -361,7 +361,7 @@ void HueLightStatus1(uint8_t device, String *response)
|
||||
const size_t buf_size = 256;
|
||||
char * buf = (char*) malloc(buf_size); // temp buffer for strings, avoid stack
|
||||
|
||||
snprintf_P(buf, buf_size, PSTR("{\"on\":%s,"), (power & (1 << (device-1))) ? "true" : "false");
|
||||
snprintf_P(buf, buf_size, PSTR("{\"on\":%s,"), (TasmotaGlobal.power & (1 << (device-1))) ? "true" : "false");
|
||||
// Brightness for all devices with PWM
|
||||
if ((1 == echo_gen) || (LST_SINGLE <= local_light_subtype)) { // force dimmer for 1st gen Echo
|
||||
snprintf_P(buf, buf_size, PSTR("%s\"bri\":%d,"), buf, bri);
|
||||
@ -475,6 +475,7 @@ uint32_t DecodeLightId(uint32_t hue_id, uint16_t * shortaddr = nullptr)
|
||||
relay_id = 32;
|
||||
}
|
||||
#ifdef USE_ZIGBEE
|
||||
if (shortaddr) { *shortaddr = 0x0000; }
|
||||
if (hue_id & (1 << 29)) {
|
||||
// this is actually a Zigbee ID
|
||||
if (shortaddr) { *shortaddr = hue_id & 0xFFFF; }
|
||||
@ -517,7 +518,7 @@ void HueAuthentication(String *path)
|
||||
|
||||
// refactored to remove code duplicates
|
||||
void CheckHue(String * response, bool &appending) {
|
||||
uint8_t maxhue = (devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : devices_present;
|
||||
uint8_t maxhue = (TasmotaGlobal.devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : TasmotaGlobal.devices_present;
|
||||
for (uint32_t i = 1; i <= maxhue; i++) {
|
||||
if (HueActive(i)) {
|
||||
if (appending) { *response += ","; }
|
||||
@ -576,7 +577,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
|
||||
#endif // USE_SHUTTER
|
||||
}
|
||||
|
||||
if (light_type && (local_light_subtype >= LST_SINGLE)) {
|
||||
if (TasmotaGlobal.light_type && (local_light_subtype >= LST_SINGLE)) {
|
||||
if (!Settings.flag3.pwm_multi_channels) { // SetOption68 - Enable multi-channels PWM instead of Color PWM
|
||||
light_state.getHSB(&hue, &sat, nullptr);
|
||||
bri = light_state.getBri(); // get the combined bri for CT and RGB, not only the RGB one
|
||||
@ -691,7 +692,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
|
||||
}
|
||||
resp = true;
|
||||
}
|
||||
|
||||
|
||||
if (change) {
|
||||
#ifdef USE_SHUTTER
|
||||
if (ShutterState(device)) {
|
||||
@ -699,7 +700,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
|
||||
ShutterSetPosition(device, bri * 100.0f );
|
||||
} else
|
||||
#endif
|
||||
if (light_type && (local_light_subtype > LST_NONE)) { // not relay
|
||||
if (TasmotaGlobal.light_type && (local_light_subtype > LST_NONE)) { // not relay
|
||||
if (!Settings.flag3.pwm_multi_channels) { // SetOption68 - Enable multi-channels PWM instead of Color PWM
|
||||
if (g_gotct) {
|
||||
light_controller.changeCTB(ct, bri);
|
||||
@ -739,7 +740,7 @@ void HueLights(String *path)
|
||||
int code = 200;
|
||||
uint8_t device = 1;
|
||||
uint32_t device_id; // the raw device_id used by Hue emulation
|
||||
uint8_t maxhue = (devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : devices_present;
|
||||
uint8_t maxhue = (TasmotaGlobal.devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : TasmotaGlobal.devices_present;
|
||||
|
||||
path->remove(0,path->indexOf(F("/lights"))); // Remove until /lights
|
||||
if (path->endsWith(F("/lights"))) { // Got /lights
|
||||
@ -768,7 +769,7 @@ void HueLights(String *path)
|
||||
#endif // USE_ZIGBEE
|
||||
|
||||
#ifdef USE_SCRIPT_HUE
|
||||
if (device > devices_present) {
|
||||
if (device > TasmotaGlobal.devices_present) {
|
||||
return Script_Handle_Hue(path);
|
||||
}
|
||||
#endif
|
||||
@ -792,8 +793,8 @@ void HueLights(String *path)
|
||||
#endif // USE_ZIGBEE
|
||||
|
||||
#ifdef USE_SCRIPT_HUE
|
||||
if (device > devices_present) {
|
||||
Script_HueStatus(&response, device-devices_present - 1);
|
||||
if (device > TasmotaGlobal.devices_present) {
|
||||
Script_HueStatus(&response, device-TasmotaGlobal.devices_present - 1);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
@ -820,7 +821,7 @@ void HueGroups(String *path)
|
||||
* http://tasmota/api/username/groups?1={"name":"Woonkamer","lights":[],"type":"Room","class":"Living room"})
|
||||
*/
|
||||
String response = "{}";
|
||||
uint8_t maxhue = (devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : devices_present;
|
||||
uint8_t maxhue = (TasmotaGlobal.devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : TasmotaGlobal.devices_present;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " HueGroups (%s)"), path->c_str());
|
||||
|
||||
if (path->endsWith("/0")) {
|
||||
@ -893,7 +894,7 @@ bool Xdrv20(uint8_t function)
|
||||
#if defined(USE_SCRIPT_HUE) || defined(USE_ZIGBEE)
|
||||
if ((EMUL_HUE == Settings.flag2.emulation)) {
|
||||
#else
|
||||
if (devices_present && (EMUL_HUE == Settings.flag2.emulation)) {
|
||||
if (TasmotaGlobal.devices_present && (EMUL_HUE == Settings.flag2.emulation)) {
|
||||
#endif
|
||||
switch (function) {
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
|
||||
@ -292,15 +292,15 @@ void HandleUpnpEvent(void)
|
||||
power = POWER_OFF;
|
||||
}
|
||||
if (power != POWER_TOGGLE) {
|
||||
uint8_t device = (light_type) ? devices_present : 1; // Select either a configured light or relay1
|
||||
uint8_t device = (TasmotaGlobal.light_type) ? TasmotaGlobal.devices_present : 1; // Select either a configured light or relay1
|
||||
ExecuteCommandPower(device, power, SRC_WEMO);
|
||||
}
|
||||
}
|
||||
|
||||
#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);
|
||||
snprintf_P(event, sizeof(event), Decompress(WEMO_RESPONSE_STATE_SOAP, WEMO_RESPONSE_STATE_SOAP_SIZE).c_str(), state, bitRead(TasmotaGlobal.power, TasmotaGlobal.devices_present -1), state);
|
||||
#else
|
||||
snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(power, devices_present -1), state);
|
||||
snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(TasmotaGlobal.power, TasmotaGlobal.devices_present -1), state);
|
||||
#endif
|
||||
WSSend(200, CT_XML, event);
|
||||
}
|
||||
@ -350,7 +350,7 @@ bool Xdrv21(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (devices_present && (EMUL_WEMO == Settings.flag2.emulation)) {
|
||||
if (TasmotaGlobal.devices_present && (EMUL_WEMO == Settings.flag2.emulation)) {
|
||||
switch (function) {
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer_on(PSTR("/upnp/control/basicevent1"), HandleUpnpEvent, HTTP_POST);
|
||||
|
||||
@ -45,7 +45,7 @@ bool ifan_restart_flag = true;
|
||||
|
||||
bool IsModuleIfan(void)
|
||||
{
|
||||
return ((SONOFF_IFAN02 == my_module_type) || (SONOFF_IFAN03 == my_module_type));
|
||||
return ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type));
|
||||
}
|
||||
|
||||
uint8_t MaxFanspeed(void)
|
||||
@ -64,7 +64,7 @@ uint8_t GetFanspeed(void)
|
||||
011x = 2
|
||||
101x = 3 (ifan02) or 100x = 3 (ifan03)
|
||||
*/
|
||||
uint8_t fanspeed = (uint8_t)(power &0xF) >> 1;
|
||||
uint8_t fanspeed = (uint8_t)(TasmotaGlobal.power &0xF) >> 1;
|
||||
if (fanspeed) { fanspeed = (fanspeed >> 1) +1; } // 0, 1, 2, 3
|
||||
return fanspeed;
|
||||
}
|
||||
@ -82,7 +82,7 @@ void SonoffIFanSetFanspeed(uint8_t fanspeed, bool sequence)
|
||||
if (fanspeed == fanspeed_now) { return; }
|
||||
|
||||
uint8_t fans = kIFan02Speed[fanspeed];
|
||||
if (SONOFF_IFAN03 == my_module_type) {
|
||||
if (SONOFF_IFAN03 == TasmotaGlobal.module_type) {
|
||||
if (sequence) {
|
||||
fanspeed = kIFan03Sequence[fanspeed_now][ifan_fanspeed_goal];
|
||||
if (fanspeed != ifan_fanspeed_goal) {
|
||||
@ -112,8 +112,8 @@ void SonoffIfanReceived(void)
|
||||
{
|
||||
char svalue[32];
|
||||
|
||||
uint8_t mode = serial_in_buffer[3];
|
||||
uint8_t action = serial_in_buffer[6];
|
||||
uint8_t mode = TasmotaGlobal.serial_in_buffer[3];
|
||||
uint8_t action = TasmotaGlobal.serial_in_buffer[6];
|
||||
|
||||
if (4 == mode) {
|
||||
if (action < 4) {
|
||||
@ -146,25 +146,25 @@ void SonoffIfanReceived(void)
|
||||
|
||||
// Send Acknowledge - Copy first 5 bytes, reset byte 6 and store crc in byte 7
|
||||
// AA 55 01 04 00 00 05
|
||||
serial_in_buffer[5] = 0; // Ack
|
||||
serial_in_buffer[6] = 0; // Crc
|
||||
TasmotaGlobal.serial_in_buffer[5] = 0; // Ack
|
||||
TasmotaGlobal.serial_in_buffer[6] = 0; // Crc
|
||||
for (uint32_t i = 0; i < 7; i++) {
|
||||
if ((i > 1) && (i < 6)) { serial_in_buffer[6] += serial_in_buffer[i]; }
|
||||
Serial.write(serial_in_buffer[i]);
|
||||
if ((i > 1) && (i < 6)) { TasmotaGlobal.serial_in_buffer[6] += TasmotaGlobal.serial_in_buffer[i]; }
|
||||
Serial.write(TasmotaGlobal.serial_in_buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool SonoffIfanSerialInput(void)
|
||||
{
|
||||
if (SONOFF_IFAN03 != my_module_type) { return false; }
|
||||
if (SONOFF_IFAN03 != TasmotaGlobal.module_type) { return false; }
|
||||
|
||||
if (0xAA == serial_in_byte) { // 0xAA - Start of text
|
||||
serial_in_byte_counter = 0;
|
||||
if (0xAA == TasmotaGlobal.serial_in_byte) { // 0xAA - Start of text
|
||||
TasmotaGlobal.serial_in_byte_counter = 0;
|
||||
ifan_receive_flag = true;
|
||||
}
|
||||
if (ifan_receive_flag) {
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
if (serial_in_byte_counter == 8) {
|
||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte;
|
||||
if (TasmotaGlobal.serial_in_byte_counter == 8) {
|
||||
// AA 55 01 01 00 01 01 04 - Wifi long press - start wifi setup
|
||||
// AA 55 01 01 00 01 02 05 - Rf and Wifi short press
|
||||
// AA 55 01 04 00 01 00 06 - Fan 0
|
||||
@ -177,15 +177,15 @@ bool SonoffIfanSerialInput(void)
|
||||
AddLogSerial(LOG_LEVEL_DEBUG);
|
||||
uint8_t crc = 0;
|
||||
for (uint32_t i = 2; i < 7; i++) {
|
||||
crc += serial_in_buffer[i];
|
||||
crc += TasmotaGlobal.serial_in_buffer[i];
|
||||
}
|
||||
if (crc == serial_in_buffer[7]) {
|
||||
if (crc == TasmotaGlobal.serial_in_buffer[7]) {
|
||||
SonoffIfanReceived();
|
||||
ifan_receive_flag = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
serial_in_byte = 0;
|
||||
TasmotaGlobal.serial_in_byte = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -216,7 +216,7 @@ void CmndFanspeed(void)
|
||||
|
||||
bool SonoffIfanInit(void)
|
||||
{
|
||||
if (SONOFF_IFAN03 == my_module_type) {
|
||||
if (SONOFF_IFAN03 == TasmotaGlobal.module_type) {
|
||||
SetSerial(9600, TS_SERIAL_8N1);
|
||||
}
|
||||
return false; // Continue init chain
|
||||
@ -224,7 +224,7 @@ bool SonoffIfanInit(void)
|
||||
|
||||
void SonoffIfanUpdate(void)
|
||||
{
|
||||
if (SONOFF_IFAN03 == my_module_type) {
|
||||
if (SONOFF_IFAN03 == TasmotaGlobal.module_type) {
|
||||
if (ifan_fanspeed_timer) {
|
||||
ifan_fanspeed_timer--;
|
||||
if (!ifan_fanspeed_timer) {
|
||||
@ -233,10 +233,10 @@ void SonoffIfanUpdate(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (ifan_restart_flag && (4 == uptime) && (SONOFF_IFAN02 == my_module_type)) { // Microcontroller needs 3 seconds before accepting commands
|
||||
if (ifan_restart_flag && (4 == TasmotaGlobal.uptime) && (SONOFF_IFAN02 == TasmotaGlobal.module_type)) { // Microcontroller needs 3 seconds before accepting commands
|
||||
ifan_restart_flag = false;
|
||||
SetDevicePower(1, SRC_RETRY); // Sync with default power on state microcontroller being Light ON and Fan OFF
|
||||
SetDevicePower(power, SRC_RETRY); // Set required power on state
|
||||
SetDevicePower(TasmotaGlobal.power, SRC_RETRY); // Set required power on state
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -64,46 +64,6 @@ uint16_t Z_GetLastGroup(void) { return gZbLastMessage.groupaddr; }
|
||||
uint16_t Z_GetLastCluster(void) { return gZbLastMessage.cluster; }
|
||||
uint8_t Z_GetLastEndpoint(void) { return gZbLastMessage.endpoint; }
|
||||
|
||||
/*********************************************************************************************\
|
||||
*
|
||||
* Class for attribute array of values
|
||||
* This is a helper function to generate a clean list of unsigned ints
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
||||
class Z_json_array {
|
||||
public:
|
||||
|
||||
Z_json_array(): val("[]") {} // start with empty array
|
||||
void add(uint32_t uval32) {
|
||||
// remove trailing ']'
|
||||
val.remove(val.length()-1);
|
||||
if (val.length() > 1) { // if not empty, prefix with comma
|
||||
val += ',';
|
||||
}
|
||||
val += uval32;
|
||||
val += ']';
|
||||
}
|
||||
void addStrRaw(const char * sval) {
|
||||
// remove trailing ']'
|
||||
val.remove(val.length()-1);
|
||||
if (val.length() > 1) { // if not empty, prefix with comma
|
||||
val += ',';
|
||||
}
|
||||
val += sval;
|
||||
val += ']';
|
||||
}
|
||||
void addStr(const char * sval) {
|
||||
addStrRaw(EscapeJSONString(sval).c_str());
|
||||
}
|
||||
String &toString(void) {
|
||||
return val;
|
||||
}
|
||||
|
||||
private :
|
||||
String val;
|
||||
};
|
||||
|
||||
/*********************************************************************************************\
|
||||
*
|
||||
* Class for single attribute
|
||||
@ -143,8 +103,8 @@ public:
|
||||
float fval;
|
||||
SBuffer* bval;
|
||||
char* sval;
|
||||
class Z_attribute_list * objval;
|
||||
class Z_json_array * arrval;
|
||||
class Z_attribute_list * objval;
|
||||
class JsonGeneratorArray * arrval;
|
||||
} val;
|
||||
Za_type type; // uint8_t in size, type of attribute, see above
|
||||
bool key_is_str; // is the key a string?
|
||||
@ -217,7 +177,7 @@ public:
|
||||
}
|
||||
|
||||
Z_attribute_list & newAttrList(void);
|
||||
Z_json_array & newJsonArray(void);
|
||||
JsonGeneratorArray & newJsonArray(void);
|
||||
|
||||
inline bool isNum(void) const { return (type >= Za_type::Za_bool) && (type <= Za_type::Za_float); }
|
||||
inline bool isNone(void) const { return (type == Za_type::Za_none);}
|
||||
@ -446,9 +406,9 @@ Z_attribute_list & Z_attribute::newAttrList(void) {
|
||||
return *val.objval;
|
||||
}
|
||||
|
||||
Z_json_array & Z_attribute::newJsonArray(void) {
|
||||
JsonGeneratorArray & Z_attribute::newJsonArray(void) {
|
||||
freeVal();
|
||||
val.arrval = new Z_json_array();
|
||||
val.arrval = new JsonGeneratorArray();
|
||||
type = Za_type::Za_arr;
|
||||
return *val.arrval;
|
||||
}
|
||||
@ -849,11 +809,10 @@ Z_attribute & Z_attribute_list::findOrCreateAttribute(const char * name, uint8_t
|
||||
|
||||
// same but passing a Z_attribute as key
|
||||
Z_attribute & Z_attribute_list::findOrCreateAttribute(const Z_attribute &attr) {
|
||||
if (attr.key_is_str) {
|
||||
return findOrCreateAttribute(attr.key.key, attr.key_suffix);
|
||||
} else {
|
||||
return findOrCreateAttribute(attr.key.id.cluster, attr.key.id.attr_id, attr.key_suffix);
|
||||
}
|
||||
Z_attribute & ret = attr.key_is_str ? findOrCreateAttribute(attr.key.key, attr.key_suffix)
|
||||
: findOrCreateAttribute(attr.key.id.cluster, attr.key.id.attr_id, attr.key_suffix);
|
||||
ret.key_suffix = attr.key_suffix;
|
||||
return ret;
|
||||
}
|
||||
// replace the entire content with new attribute or create
|
||||
Z_attribute & Z_attribute_list::replaceOrCreate(const Z_attribute &attr) {
|
||||
@ -870,9 +829,17 @@ bool Z_attribute_list::mergeList(const Z_attribute_list &attr_list) {
|
||||
} else if (0xFF != attr_list.src_ep) {
|
||||
if (src_ep != attr_list.src_ep) { return false; }
|
||||
}
|
||||
// Check group address
|
||||
if (0xFFFF == group_id) {
|
||||
group_id = attr_list.group_id;
|
||||
} else if (0xFFFF != attr_list.group_id) {
|
||||
if (group_id != attr_list.group_id) { return false; }
|
||||
}
|
||||
// copy LQI
|
||||
if (0xFF != attr_list.lqi) {
|
||||
lqi = attr_list.lqi;
|
||||
}
|
||||
// merge attributes
|
||||
for (auto & attr : attr_list) {
|
||||
replaceOrCreate(attr);
|
||||
}
|
||||
|
||||
@ -36,31 +36,110 @@ enum class Z_Data_Type : uint8_t {
|
||||
Z_Device = 0xFF // special value when parsing Device level attributes
|
||||
};
|
||||
|
||||
const uint8_t Z_Data_Type_char[] PROGMEM = {
|
||||
'?', // 0x00 Z_Data_Type::Z_Unknown
|
||||
'L', // 0x01 Z_Data_Type::Z_Light
|
||||
'P', // 0x02 Z_Data_Type::Z_Plug
|
||||
'I', // 0x03 Z_Data_Type::Z_PIR
|
||||
'A', // 0x04 Z_Data_Type::Z_Alarm
|
||||
'T', // 0x05 Z_Data_Type::Z_Thermo
|
||||
'O', // 0x05 Z_Data_Type::Z_OnOff
|
||||
'\0', // 0x06
|
||||
'\0', // 0x07
|
||||
'\0', // 0x08
|
||||
'\0', // 0x09
|
||||
'\0', // 0x0A
|
||||
'\0', // 0x0B
|
||||
'\0', // 0x0C
|
||||
'\0', // 0x0D
|
||||
'\0', // 0x0E
|
||||
'E', // 0x05 Z_Data_Type::Z_Ext
|
||||
// '_' maps to 0xFF Z_Data_Type::Z_Device
|
||||
};
|
||||
|
||||
class Z_Data_Set;
|
||||
/*********************************************************************************************\
|
||||
* Device specific data, sensors...
|
||||
\*********************************************************************************************/
|
||||
class Z_Data {
|
||||
public:
|
||||
Z_Data(Z_Data_Type type = Z_Data_Type::Z_Unknown, uint8_t endpoint = 0) : _type(type), _endpoint(endpoint), _config(-1), _power(0) {}
|
||||
Z_Data(Z_Data_Type type = Z_Data_Type::Z_Unknown, uint8_t endpoint = 0) : _type(type), _endpoint(endpoint), _config(0xF), _power(0) {}
|
||||
inline Z_Data_Type getType(void) const { return _type; }
|
||||
inline int8_t getConfig(void) const { return _config; }
|
||||
inline bool validConfig(void) const { return _config != 0xF; }
|
||||
inline void setConfig(int8_t config) { _config = config; }
|
||||
uint8_t getConfigByte(void) const { return ( ((uint8_t)_type) << 4) | ((_config & 0xF) & 0x0F); }
|
||||
|
||||
inline uint8_t getEndpoint(void) const { return _endpoint; }
|
||||
|
||||
void toAttributes(Z_attribute_list & attr_list, Z_Data_Type type) const;
|
||||
|
||||
static const Z_Data_Type type = Z_Data_Type::Z_Unknown;
|
||||
static bool ConfigToZData(const char * config_str, Z_Data_Type * type, uint8_t * ep, uint8_t * config);
|
||||
|
||||
static Z_Data_Type CharToDataType(char c);
|
||||
static char DataTypeToChar(Z_Data_Type t);
|
||||
|
||||
friend class Z_Data_Set;
|
||||
protected:
|
||||
Z_Data_Type _type; // encoded on 4 bits, type of the device
|
||||
uint8_t _endpoint; // source endpoint, or 0x00 if any endpoint
|
||||
int8_t _config; // encoded on 4 bits, customize behavior
|
||||
uint8_t _config : 4; // encoded on 4 bits, customize behavior
|
||||
uint8_t _power; // power state if the type supports it
|
||||
};
|
||||
|
||||
Z_Data_Type Z_Data::CharToDataType(char c) {
|
||||
if (c) {
|
||||
if (c == '_') {
|
||||
return Z_Data_Type::Z_Device;
|
||||
} else {
|
||||
for (uint32_t i=0; i<ARRAY_SIZE(Z_Data_Type_char); i++) {
|
||||
if (pgm_read_byte(&Z_Data_Type_char[i]) == c) {
|
||||
return (Z_Data_Type) i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Z_Data_Type::Z_Unknown;
|
||||
}
|
||||
|
||||
char Z_Data::DataTypeToChar(Z_Data_Type t) {
|
||||
if (t == Z_Data_Type::Z_Device) {
|
||||
return '_';
|
||||
} else {
|
||||
uint8_t tt = (uint8_t) t;
|
||||
if (tt < ARRAY_SIZE(Z_Data_Type_char)) {
|
||||
return pgm_read_byte(&Z_Data_Type_char[tt]);
|
||||
}
|
||||
}
|
||||
return '\0';
|
||||
}
|
||||
|
||||
// Parse configuration
|
||||
// Either '_'
|
||||
// or 'T01' or 'L01.2'
|
||||
// result: true if parsing ok
|
||||
bool Z_Data::ConfigToZData(const char * config_str, Z_Data_Type * type, uint8_t * ep, uint8_t * config) {
|
||||
if (config_str == nullptr) { return false; }
|
||||
|
||||
Z_Data_Type data_type = Z_Data::CharToDataType(config_str[0]);
|
||||
if (data_type == Z_Data_Type::Z_Unknown) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type != nullptr) {
|
||||
*type = data_type;
|
||||
}
|
||||
if (ep != nullptr) {
|
||||
*ep = strtoul(&config_str[1], nullptr, 16); // hex base 16
|
||||
}
|
||||
if ((config != nullptr) && (config_str[3] == '.')) {
|
||||
// we have a config attribute
|
||||
*config = strtoul(&config_str[4], nullptr, 16) & 0x0F; // hex base 16
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Device specific: On/Off, power up to 8 relays
|
||||
\*********************************************************************************************/
|
||||
@ -93,7 +172,7 @@ void Z_Data_OnOff::setPower(bool val, uint32_t relay) {
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Device specific: Light device
|
||||
* Device specific: Plug device
|
||||
\*********************************************************************************************/
|
||||
class Z_Data_Plug : public Z_Data {
|
||||
public:
|
||||
@ -157,8 +236,6 @@ public:
|
||||
inline void setCT(uint16_t _ct) { ct = _ct; }
|
||||
inline void setX(uint16_t _x) { x = _x; }
|
||||
inline void setY(uint16_t _y) { y = _y; }
|
||||
|
||||
void toAttributes(Z_attribute_list & attr_list, Z_Data_Type type) const;
|
||||
|
||||
static const Z_Data_Type type = Z_Data_Type::Z_Light;
|
||||
// 12 bytes
|
||||
@ -170,6 +247,65 @@ public:
|
||||
uint16_t x, y; // last color [x,y] | 0xFFFF not set, default 0
|
||||
};
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Device specific: PIR
|
||||
*
|
||||
// List of occupancy time-outs:
|
||||
// 0xF = default (90 s)
|
||||
// 0x0 = no time-out
|
||||
// 0x1 = 15 s
|
||||
// 0x2 = 30 s
|
||||
// 0x3 = 45 s
|
||||
// 0x4 = 60 s
|
||||
// 0x5 = 75 s
|
||||
// 0x6 = 90 s -- default
|
||||
// 0x7 = 105 s
|
||||
// 0x8 = 120 s
|
||||
\*********************************************************************************************/
|
||||
class Z_Data_PIR : public Z_Data {
|
||||
public:
|
||||
Z_Data_PIR(uint8_t endpoint = 0) :
|
||||
Z_Data(Z_Data_Type::Z_PIR, endpoint),
|
||||
occupancy(0xFF),
|
||||
illuminance(0xFFFF)
|
||||
{}
|
||||
|
||||
inline bool validOccupancy(void) const { return 0xFF != occupancy; }
|
||||
inline bool validIlluminance(void) const { return 0xFFFF != illuminance; }
|
||||
|
||||
inline uint8_t getOccupancy(void) const { return occupancy; }
|
||||
inline uint16_t getIlluminance(void) const { return illuminance; }
|
||||
|
||||
inline void setOccupancy(uint8_t _occupancy) { occupancy = _occupancy; }
|
||||
inline void setIlluminance(uint16_t _illuminance) { illuminance = _illuminance; }
|
||||
|
||||
uint32_t getTimeoutSeconds(void) const;
|
||||
void setTimeoutSeconds(int32_t value);
|
||||
|
||||
static const Z_Data_Type type = Z_Data_Type::Z_PIR;
|
||||
// PIR
|
||||
uint8_t occupancy; // map8
|
||||
uint16_t illuminance; // illuminance
|
||||
};
|
||||
|
||||
uint32_t Z_Data_PIR::getTimeoutSeconds(void) const {
|
||||
if (_config != 0xF) {
|
||||
return _config * 15;
|
||||
} else {
|
||||
return 90;
|
||||
}
|
||||
}
|
||||
|
||||
void Z_Data_PIR::setTimeoutSeconds(int32_t value) {
|
||||
if (value < 0) {
|
||||
_config = 0xF;
|
||||
} else {
|
||||
uint32_t val_15 = (value + 14)/ 15; // always round up
|
||||
if (val_15 > 8) { val_15 = 8; }
|
||||
_config = val_15;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Device specific: Sensors: temp, humidity, pressure...
|
||||
\*********************************************************************************************/
|
||||
@ -286,6 +422,8 @@ Z_Data & Z_Data_Set::getByType(Z_Data_Type type, uint8_t ep) {
|
||||
return get<Z_Data_Thermo>(ep);
|
||||
case Z_Data_Type::Z_OnOff:
|
||||
return get<Z_Data_OnOff>(ep);
|
||||
case Z_Data_Type::Z_PIR:
|
||||
return get<Z_Data_PIR>(ep);
|
||||
default:
|
||||
return *(Z_Data*)nullptr;
|
||||
}
|
||||
@ -330,14 +468,6 @@ const Z_Data & Z_Data_Set::find(Z_Data_Type type, uint8_t ep) const {
|
||||
return *(Z_Data*)nullptr;
|
||||
}
|
||||
|
||||
// Low-level
|
||||
// Add light attributes, used by dumpLightState and by SbData
|
||||
//
|
||||
void Z_Data_Light::toAttributes(Z_attribute_list & attr_list, Z_Data_Type type) const {
|
||||
attr_list.addAttribute(PSTR(D_JSON_ZIGBEE_LIGHT)).setInt(getConfig()); // special case, since type is 0x00 we can assume getConfig() is good
|
||||
Z_Data::toAttributes(attr_list, type);
|
||||
}
|
||||
|
||||
void Z_Data_OnOff::toAttributes(Z_attribute_list & attr_list, Z_Data_Type type) const {
|
||||
if (validPower()) { attr_list.addAttribute(PSTR("Power")).setUInt(getPower() ? 1 : 0); }
|
||||
}
|
||||
@ -370,7 +500,7 @@ public:
|
||||
// Light information for Hue integration integration, last known values
|
||||
|
||||
// New version of device data handling
|
||||
Z_Data_Set data; // Linkedlist of device data per endpoint
|
||||
Z_Data_Set data; // Linkedlist of device data per endpoint
|
||||
// other status
|
||||
uint8_t lqi; // lqi from last message, 0xFF means unknown
|
||||
uint8_t batterypercent; // battery percentage (0..100), 0xFF means unknwon
|
||||
@ -390,7 +520,7 @@ public:
|
||||
seqNumber(0),
|
||||
hidden(false),
|
||||
reachable(false),
|
||||
// Hue support
|
||||
data(),
|
||||
lqi(0xFF),
|
||||
batterypercent(0xFF),
|
||||
last_seen(0)
|
||||
@ -413,6 +543,15 @@ public:
|
||||
inline bool getReachable(void) const { return reachable; }
|
||||
inline bool getPower(uint8_t ep =0) const;
|
||||
|
||||
// Add an endpoint to a device
|
||||
bool addEndpoint(uint8_t endpoint);
|
||||
void clearEndpoints(void);
|
||||
uint32_t countEndpoints(void) const; // return the number of known endpoints (0 if unknown)
|
||||
|
||||
void setManufId(const char * str);
|
||||
void setModelId(const char * str);
|
||||
void setFriendlyName(const char * str);
|
||||
|
||||
// dump device attributes to ZbData
|
||||
void toAttributes(Z_attribute_list & attr_list) const;
|
||||
|
||||
@ -439,10 +578,12 @@ public:
|
||||
light.setConfig(channels);
|
||||
dirty = true;
|
||||
}
|
||||
Z_Data_OnOff & onoff = data.get<Z_Data_OnOff>(0);
|
||||
} else {
|
||||
// remove light object if any
|
||||
// remove light / onoff object if any
|
||||
for (auto & data_elt : data) {
|
||||
if (data_elt.getType() == Z_Data_Type::Z_Light) {
|
||||
if ((data_elt.getType() == Z_Data_Type::Z_Light) ||
|
||||
(data_elt.getType() == Z_Data_Type::Z_OnOff)) {
|
||||
// remove light object
|
||||
data.remove(&data_elt);
|
||||
dirty = true;
|
||||
@ -451,6 +592,9 @@ public:
|
||||
}
|
||||
return dirty;
|
||||
}
|
||||
protected:
|
||||
|
||||
static void setStringAttribute(char*& attr, const char * str);
|
||||
};
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -533,16 +677,8 @@ public:
|
||||
|
||||
// Add new device, provide ShortAddr and optional longAddr
|
||||
// If it is already registered, update information, otherwise create the entry
|
||||
void updateDevice(uint16_t shortaddr, uint64_t longaddr = 0);
|
||||
Z_Device & updateDevice(uint16_t shortaddr, uint64_t longaddr = 0);
|
||||
|
||||
// Add an endpoint to a device
|
||||
void addEndpoint(uint16_t shortaddr, uint8_t endpoint);
|
||||
void clearEndpoints(uint16_t shortaddr);
|
||||
uint32_t countEndpoints(uint16_t shortaddr) const; // return the number of known endpoints (0 if unknown)
|
||||
|
||||
void setManufId(uint16_t shortaddr, const char * str);
|
||||
void setModelId(uint16_t shortaddr, const char * str);
|
||||
void setFriendlyName(uint16_t shortaddr, const char * str);
|
||||
inline const char * getFriendlyName(uint16_t shortaddr) const {
|
||||
return findShortAddr(shortaddr).friendlyName;
|
||||
}
|
||||
@ -629,8 +765,6 @@ private:
|
||||
// Create a new entry in the devices list - must be called if it is sure it does not already exist
|
||||
Z_Device & createDeviceEntry(uint16_t shortaddr, uint64_t longaddr = 0);
|
||||
void freeDeviceEntry(Z_Device *device);
|
||||
|
||||
void setStringAttribute(char*& attr, const char * str);
|
||||
};
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
||||
@ -29,10 +29,12 @@
|
||||
//
|
||||
Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) {
|
||||
if ((BAD_SHORTADDR == shortaddr) && !longaddr) { return (Z_Device&) device_unk; } // it is not legal to create this entry
|
||||
Z_Device device(shortaddr, longaddr);
|
||||
Z_Device & device = _devices.addToLast();
|
||||
device.shortaddr = shortaddr;
|
||||
device.longaddr = longaddr;
|
||||
|
||||
dirty();
|
||||
return _devices.addHead(device);
|
||||
return device;
|
||||
}
|
||||
|
||||
void Z_Devices::freeDeviceEntry(Z_Device *device) {
|
||||
@ -178,7 +180,7 @@ bool Z_Devices::removeDevice(uint16_t shortaddr) {
|
||||
// In:
|
||||
// shortaddr
|
||||
// longaddr (both can't be null at the same time)
|
||||
void Z_Devices::updateDevice(uint16_t shortaddr, uint64_t longaddr) {
|
||||
Z_Device & Z_Devices::updateDevice(uint16_t shortaddr, uint64_t longaddr) {
|
||||
Z_Device * s_found = &findShortAddr(shortaddr); // is there already a shortaddr entry
|
||||
Z_Device * l_found = &findLongAddr(longaddr); // is there already a longaddr entry
|
||||
|
||||
@ -191,64 +193,64 @@ void Z_Devices::updateDevice(uint16_t shortaddr, uint64_t longaddr) {
|
||||
freeDeviceEntry(s_found);
|
||||
_devices.remove(s_found);
|
||||
dirty();
|
||||
return *l_found;
|
||||
}
|
||||
} else if (foundDevice(*s_found)) {
|
||||
// shortaddr already exists but longaddr not
|
||||
// add the longaddr to the entry
|
||||
s_found->longaddr = longaddr;
|
||||
dirty();
|
||||
return *s_found;
|
||||
} else if (foundDevice(*l_found)) {
|
||||
// longaddr entry exists, update shortaddr
|
||||
l_found->shortaddr = shortaddr;
|
||||
dirty();
|
||||
return *l_found;
|
||||
} else {
|
||||
// neither short/lonf addr are found.
|
||||
if ((BAD_SHORTADDR != shortaddr) || longaddr) {
|
||||
createDeviceEntry(shortaddr, longaddr);
|
||||
return createDeviceEntry(shortaddr, longaddr);
|
||||
}
|
||||
return (Z_Device&) device_unk;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Clear all endpoints
|
||||
//
|
||||
void Z_Devices::clearEndpoints(uint16_t shortaddr) {
|
||||
Z_Device &device = getShortAddr(shortaddr);
|
||||
void Z_Device::clearEndpoints(void) {
|
||||
for (uint32_t i = 0; i < endpoints_max; i++) {
|
||||
device.endpoints[i] = 0;
|
||||
endpoints[i] = 0;
|
||||
// no dirty here because it doesn't make sense to store it, does it?
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add an endpoint to a shortaddr
|
||||
// return true if a change was made
|
||||
//
|
||||
void Z_Devices::addEndpoint(uint16_t shortaddr, uint8_t endpoint) {
|
||||
if (0x00 == endpoint) { return; }
|
||||
Z_Device &device = getShortAddr(shortaddr);
|
||||
bool Z_Device::addEndpoint(uint8_t endpoint) {
|
||||
if ((0x00 == endpoint) || (endpoint > 240)) { return false; }
|
||||
|
||||
for (uint32_t i = 0; i < endpoints_max; i++) {
|
||||
if (endpoint == device.endpoints[i]) {
|
||||
return; // endpoint already there
|
||||
if (endpoint == endpoints[i]) {
|
||||
return false; // endpoint already there
|
||||
}
|
||||
if (0 == device.endpoints[i]) {
|
||||
device.endpoints[i] = endpoint;
|
||||
dirty();
|
||||
return;
|
||||
if (0 == endpoints[i]) {
|
||||
endpoints[i] = endpoint;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Count the number of known endpoints
|
||||
//
|
||||
uint32_t Z_Devices::countEndpoints(uint16_t shortaddr) const {
|
||||
uint32_t Z_Device::countEndpoints(void) const {
|
||||
uint32_t count_ep = 0;
|
||||
const Z_Device & device =findShortAddr(shortaddr);
|
||||
if (!foundDevice(device)) return 0;
|
||||
|
||||
for (uint32_t i = 0; i < endpoints_max; i++) {
|
||||
if (0 != device.endpoints[i]) {
|
||||
if (0 != endpoints[i]) {
|
||||
count_ep++;
|
||||
}
|
||||
}
|
||||
@ -262,7 +264,7 @@ uint8_t Z_Devices::findFirstEndpoint(uint16_t shortaddr) const {
|
||||
return findShortAddr(shortaddr).endpoints[0]; // returns 0x00 if no endpoint
|
||||
}
|
||||
|
||||
void Z_Devices::setStringAttribute(char*& attr, const char * str) {
|
||||
void Z_Device::setStringAttribute(char*& attr, const char * str) {
|
||||
if (nullptr == str) { return; } // ignore a null parameter
|
||||
size_t str_len = strlen(str);
|
||||
|
||||
@ -278,10 +280,11 @@ void Z_Devices::setStringAttribute(char*& attr, const char * str) {
|
||||
}
|
||||
}
|
||||
if (str_len) {
|
||||
if (str_len > 31) { str_len = 31; }
|
||||
attr = (char*) malloc(str_len + 1);
|
||||
strlcpy(attr, str, str_len + 1);
|
||||
}
|
||||
dirty();
|
||||
zigbee_devices.dirty();
|
||||
}
|
||||
|
||||
//
|
||||
@ -293,16 +296,16 @@ void Z_Devices::setStringAttribute(char*& attr, const char * str) {
|
||||
// Impact:
|
||||
// - Any actual change in ManufId (i.e. setting a different value) triggers a `dirty()` and saving to Flash
|
||||
//
|
||||
void Z_Devices::setManufId(uint16_t shortaddr, const char * str) {
|
||||
setStringAttribute(getShortAddr(shortaddr).manufacturerId, str);
|
||||
void Z_Device::setManufId(const char * str) {
|
||||
setStringAttribute(manufacturerId, str);
|
||||
}
|
||||
|
||||
void Z_Devices::setModelId(uint16_t shortaddr, const char * str) {
|
||||
setStringAttribute(getShortAddr(shortaddr).modelId, str);
|
||||
void Z_Device::setModelId(const char * str) {
|
||||
setStringAttribute(modelId, str);
|
||||
}
|
||||
|
||||
void Z_Devices::setFriendlyName(uint16_t shortaddr, const char * str) {
|
||||
setStringAttribute(getShortAddr(shortaddr).friendlyName, str);
|
||||
void Z_Device::setFriendlyName(const char * str) {
|
||||
setStringAttribute(friendlyName, str);
|
||||
}
|
||||
|
||||
|
||||
@ -473,7 +476,7 @@ bool Z_Devices::jsonIsConflict(uint16_t shortaddr, const Z_attribute_list &attr_
|
||||
if (device.attr_list.isValidSrcEp() && attr_list.isValidSrcEp()) {
|
||||
if (device.attr_list.src_ep != attr_list.src_ep) { return true; }
|
||||
}
|
||||
|
||||
|
||||
// LQI does not count as conflicting
|
||||
|
||||
// parse all other parameters
|
||||
@ -507,28 +510,28 @@ void Z_Devices::jsonPublishFlush(uint16_t shortaddr) {
|
||||
gZbLastMessage.groupaddr = attr_list.group_id; // %zbgroup%
|
||||
gZbLastMessage.endpoint = attr_list.src_ep; // %zbendpoint%
|
||||
|
||||
mqtt_data[0] = 0; // clear string
|
||||
TasmotaGlobal.mqtt_data[0] = 0; // clear string
|
||||
// Do we prefix with `ZbReceived`?
|
||||
if (!Settings.flag4.remove_zbreceived) {
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_RECEIVED "\":"));
|
||||
}
|
||||
// What key do we use, shortaddr or name?
|
||||
if (use_fname) {
|
||||
Response_P(PSTR("%s{\"%s\":{"), mqtt_data, fname);
|
||||
Response_P(PSTR("%s{\"%s\":{"), TasmotaGlobal.mqtt_data, fname);
|
||||
} else {
|
||||
Response_P(PSTR("%s{\"0x%04X\":{"), mqtt_data, shortaddr);
|
||||
Response_P(PSTR("%s{\"0x%04X\":{"), TasmotaGlobal.mqtt_data, shortaddr);
|
||||
}
|
||||
// Add "Device":"0x...."
|
||||
Response_P(PSTR("%s\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\","), mqtt_data, shortaddr);
|
||||
ResponseAppend_P(PSTR("\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\","), shortaddr);
|
||||
// Add "Name":"xxx" if name is present
|
||||
if (fname) {
|
||||
Response_P(PSTR("%s\"" D_JSON_ZIGBEE_NAME "\":\"%s\","), mqtt_data, EscapeJSONString(fname).c_str());
|
||||
ResponseAppend_P(PSTR("\"" D_JSON_ZIGBEE_NAME "\":\"%s\","), EscapeJSONString(fname).c_str());
|
||||
}
|
||||
// Add all other attributes
|
||||
Response_P(PSTR("%s%s}}"), mqtt_data, attr_list.toString().c_str());
|
||||
|
||||
ResponseAppend_P(PSTR("%s}}"), attr_list.toString().c_str());
|
||||
|
||||
if (!Settings.flag4.remove_zbreceived) {
|
||||
Response_P(PSTR("%s}"), mqtt_data);
|
||||
ResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
attr_list.reset(); // clear the attributes
|
||||
|
||||
@ -636,7 +639,7 @@ String Z_Devices::dumpLightState(uint16_t shortaddr) const {
|
||||
}
|
||||
// Z_Data_Light::toAttributes(attr_list, device.data.find<Z_Data_Light>(0));
|
||||
}
|
||||
|
||||
|
||||
Z_attribute_list attr_list_root;
|
||||
Z_attribute * attr_root;
|
||||
if (use_fname) {
|
||||
@ -652,7 +655,7 @@ String Z_Devices::dumpLightState(uint16_t shortaddr) const {
|
||||
// Mode = 1: simple dump of devices addresses
|
||||
// Mode = 2: simple dump of devices addresses and names, endpoints, light
|
||||
String Z_Devices::dump(uint32_t dump_mode, uint16_t status_shortaddr) const {
|
||||
Z_json_array json_arr;
|
||||
JsonGeneratorArray json_arr;
|
||||
|
||||
for (const auto & device : _devices) {
|
||||
uint16_t shortaddr = device.shortaddr;
|
||||
@ -678,20 +681,30 @@ String Z_Devices::dump(uint32_t dump_mode, uint16_t status_shortaddr) const {
|
||||
if (device.modelId) {
|
||||
attr_list.addAttribute(F(D_JSON_MODEL D_JSON_ID)).setStr(device.modelId);
|
||||
}
|
||||
int8_t bulbtype = getHueBulbtype(shortaddr);
|
||||
if (bulbtype >= 0) {
|
||||
attr_list.addAttribute(F(D_JSON_ZIGBEE_LIGHT)).setInt(bulbtype); // sign extend, 0xFF changed as -1
|
||||
}
|
||||
if (device.manufacturerId) {
|
||||
attr_list.addAttribute(F("Manufacturer")).setStr(device.manufacturerId);
|
||||
}
|
||||
Z_json_array arr_ep;
|
||||
|
||||
JsonGeneratorArray arr_ep;
|
||||
for (uint32_t i = 0; i < endpoints_max; i++) {
|
||||
uint8_t endpoint = device.endpoints[i];
|
||||
if (0x00 == endpoint) { break; }
|
||||
arr_ep.add(endpoint);
|
||||
}
|
||||
attr_list.addAttribute(F("Endpoints")).setStrRaw(arr_ep.toString().c_str());
|
||||
|
||||
JsonGeneratorArray arr_data;
|
||||
for (auto & data_elt : device.data) {
|
||||
char key[8];
|
||||
if (data_elt.validConfig()) {
|
||||
snprintf_P(key, sizeof(key), "?%02X.%1X", data_elt.getEndpoint(), data_elt.getConfig());
|
||||
} else {
|
||||
snprintf_P(key, sizeof(key), "?%02X", data_elt.getEndpoint());
|
||||
}
|
||||
key[0] = Z_Data::DataTypeToChar(data_elt.getType());
|
||||
arr_data.addStr(key);
|
||||
}
|
||||
attr_list.addAttribute(F("Config")).setStrRaw(arr_data.toString().c_str());
|
||||
}
|
||||
json_arr.addStrRaw(attr_list.toString(true).c_str());
|
||||
}
|
||||
@ -710,18 +723,17 @@ String Z_Devices::dump(uint32_t dump_mode, uint16_t status_shortaddr) const {
|
||||
int32_t Z_Devices::deviceRestore(JsonParserObject json) {
|
||||
|
||||
// params
|
||||
uint16_t device = 0x0000; // 0x0000 is coordinator so considered invalid
|
||||
uint16_t shortaddr = 0x0000; // 0x0000 is coordinator so considered invalid
|
||||
uint64_t ieeeaddr = 0x0000000000000000LL; // 0 means unknown
|
||||
const char * modelid = nullptr;
|
||||
const char * manufid = nullptr;
|
||||
const char * friendlyname = nullptr;
|
||||
int8_t bulbtype = -1;
|
||||
size_t endpoints_len = 0;
|
||||
|
||||
// read mandatory "Device"
|
||||
JsonParserToken val_device = json[PSTR("Device")];
|
||||
if (val_device) {
|
||||
device = (uint32_t) val_device.getUInt(device);
|
||||
shortaddr = (uint32_t) val_device.getUInt(shortaddr);
|
||||
} else {
|
||||
return -1; // missing "Device" attribute
|
||||
}
|
||||
@ -730,23 +742,41 @@ int32_t Z_Devices::deviceRestore(JsonParserObject json) {
|
||||
friendlyname = json.getStr(PSTR("Name"), nullptr); // read "Name"
|
||||
modelid = json.getStr(PSTR("ModelId"), nullptr);
|
||||
manufid = json.getStr(PSTR("Manufacturer"), nullptr);
|
||||
JsonParserToken tok_bulbtype = json[PSTR(D_JSON_ZIGBEE_LIGHT)];
|
||||
|
||||
// update internal device information
|
||||
updateDevice(device, ieeeaddr);
|
||||
if (modelid) { setModelId(device, modelid); }
|
||||
if (manufid) { setManufId(device, manufid); }
|
||||
if (friendlyname) { setFriendlyName(device, friendlyname); }
|
||||
if (tok_bulbtype) { setLightProfile(device, tok_bulbtype.getInt()); }
|
||||
updateDevice(shortaddr, ieeeaddr);
|
||||
Z_Device & device = getShortAddr(shortaddr);
|
||||
if (modelid) { device.setModelId(modelid); }
|
||||
if (manufid) { device.setManufId(manufid); }
|
||||
if (friendlyname) { device.setFriendlyName(friendlyname); }
|
||||
|
||||
// read "Endpoints"
|
||||
JsonParserToken val_endpoints = json[PSTR("Endpoints")];
|
||||
if (val_endpoints.isArray()) {
|
||||
JsonParserArray arr_ep = JsonParserArray(val_endpoints);
|
||||
clearEndpoints(device); // clear even if array is empty
|
||||
device.clearEndpoints(); // clear even if array is empty
|
||||
for (auto ep_elt : arr_ep) {
|
||||
uint8_t ep = ep_elt.getUInt();
|
||||
if (ep) { addEndpoint(device, ep); }
|
||||
if (ep) { device.addEndpoint(ep); }
|
||||
}
|
||||
}
|
||||
|
||||
// read "Config"
|
||||
JsonParserToken val_config = json[PSTR("Config")];
|
||||
if (val_config.isArray()) {
|
||||
JsonParserArray arr_config = JsonParserArray(val_config);
|
||||
device.data.reset(); // remove existing configuration
|
||||
for (auto config_elt : arr_config) {
|
||||
const char * conf_str = config_elt.getStr();
|
||||
Z_Data_Type data_type;
|
||||
uint8_t ep, config;
|
||||
|
||||
if (Z_Data::ConfigToZData(conf_str, &data_type, &ep, &config)) {
|
||||
Z_Data & data = device.data.getByType(data_type, ep);
|
||||
if (&data != nullptr) {
|
||||
data.setConfig(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,14 @@
|
||||
// uint16 - start address in Flash (offset)
|
||||
// uint16 - length in bytes (makes sure parsing stops)
|
||||
//
|
||||
// First byte:
|
||||
// 0x00 - Empty or V3 format
|
||||
// 0x01-0xFE - Legacy format
|
||||
// 0xFF - invalid
|
||||
//
|
||||
//
|
||||
// V1 Legacy
|
||||
// =========
|
||||
// File structure:
|
||||
// uint8 - number of devices, 0=none, 0xFF=invalid entry (probably Flash was erased)
|
||||
//
|
||||
@ -47,6 +55,29 @@
|
||||
// reserved for extensions
|
||||
// -- V2 --
|
||||
// int8_t - zigbee profile of the device
|
||||
//
|
||||
// =======================
|
||||
// v3 with version number
|
||||
// File structure:
|
||||
//
|
||||
// uint8 - number of devices, 0=none, 0xFF=invalid entry (probably Flash was erased)
|
||||
//
|
||||
// [Array of devices]
|
||||
// [Offset = 2]
|
||||
// uint8 - length of device record
|
||||
// uint16 - short address
|
||||
// uint64 - long IEEE address
|
||||
//
|
||||
// str - ModelID (null terminated C string, 32 chars max)
|
||||
// str - Manuf (null terminated C string, 32 chars max)
|
||||
// str - FriendlyName (null terminated C string, 32 chars max)
|
||||
//
|
||||
// [Array of endpoints]
|
||||
// uint8 - endpoint number, 0xFF marks the end of endpoints
|
||||
// uint8[] - list of configuration bytes, 0xFF marks the end
|
||||
// i.e. 0xFF-0xFF marks the end of the array of endpoints
|
||||
//
|
||||
|
||||
|
||||
// Memory footprint
|
||||
#ifdef ESP8266
|
||||
@ -63,71 +94,81 @@ 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 {
|
||||
// Each entry consumes 8 bytes
|
||||
class Z_Flashentry {
|
||||
public:
|
||||
uint32_t name; // simple 4 letters name. Currently 'zig1', 'zig2'. 0xFFFFFFFF if not entry
|
||||
uint16_t len; // len of object in bytes, 0xFFFF if no entry
|
||||
uint16_t start; // address of start, 0xFFFF if empty, must be aligned on 128 bytes boundaries
|
||||
};
|
||||
|
||||
class Z_Flashdirectory {
|
||||
public:
|
||||
// 8 bytes header
|
||||
uint32_t magic; // magic value 'Tsmt' to check that the block is initialized
|
||||
uint32_t clock; // clock vector to discard entries that are made before this one. This should be incremented by 1 for each new entry (future anti-weavering)
|
||||
// entries, 14*8 = 112 bytes
|
||||
Z_Flashentry entries[14];
|
||||
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
|
||||
// link to next entry, none for now, but may be used for anti-weavering
|
||||
uint16_t next_dir; // 0xFFFF if none
|
||||
uint16_t reserved1; // must be 0xFFFF
|
||||
uint32_t reserved2; // must be 0xFFFFFFFF
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
const static uint32_t ZIGB_NAME1 = 0x3167697A; // 'zig1' little endian
|
||||
const static uint32_t ZIGB_NAME2 = 0x3267697A; // 'zig2' little endian, v2
|
||||
const static size_t Z_MAX_FLASH = z_block_len - sizeof(Z_Flashentry); // 2040
|
||||
|
||||
class SBuffer hibernateDevice(const struct Z_Device &device) {
|
||||
bool hibernateDeviceConfiguration(SBuffer & buf, const class Z_Data_Set & data, uint8_t endpoint) {
|
||||
bool found = false;
|
||||
for (auto & elt : data) {
|
||||
if (endpoint == elt.getEndpoint()) {
|
||||
buf.add8(elt.getConfigByte());
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
class SBuffer hibernateDevicev2(const struct Z_Device &device) {
|
||||
SBuffer buf(128);
|
||||
|
||||
buf.add8(0x00); // overall length, will be updated later
|
||||
buf.add16(device.shortaddr);
|
||||
buf.add64(device.longaddr);
|
||||
|
||||
uint32_t endpoints_count = 0;
|
||||
for (endpoints_count = 0; endpoints_count < endpoints_max; endpoints_count++) {
|
||||
if (0x00 == device.endpoints[endpoints_count]) { break; }
|
||||
char *names[3] = { device.modelId, device.manufacturerId, device.friendlyName };
|
||||
|
||||
for (uint32_t i=0; i<ARRAY_SIZE(names); i++) {
|
||||
char *p = names[i];
|
||||
if (p) {
|
||||
size_t len = strlen(p);
|
||||
if (len > 32) { len = 32; } // max 32 chars
|
||||
buf.addBuffer(p, len);
|
||||
}
|
||||
buf.add8(0x00); // end of string marker
|
||||
}
|
||||
|
||||
buf.add8(endpoints_count);
|
||||
// iterate on endpoints
|
||||
for (uint32_t i = 0; i < endpoints_max; i++) {
|
||||
// check if we need to write fake endpoint 0x00
|
||||
buf.add8(0x00);
|
||||
if (hibernateDeviceConfiguration(buf, device.data, 0)) {
|
||||
buf.add8(0xFF); // end of configuration
|
||||
} else {
|
||||
buf.setLen(buf.len()-1); // remove 1 byte header
|
||||
}
|
||||
// scan endpoints
|
||||
for (uint32_t i=0; i<endpoints_max; i++) {
|
||||
uint8_t endpoint = device.endpoints[i];
|
||||
if (0x00 == endpoint) { break; } // stop
|
||||
|
||||
if (0x00 == endpoint) { break; }
|
||||
buf.add8(endpoint);
|
||||
buf.add16(0x0000); // profile_id, not used anymore
|
||||
|
||||
// removed clusters_in
|
||||
buf.add8(0xFF); // end of endpoint marker
|
||||
|
||||
// no more storage of clusters_out
|
||||
buf.add8(0xFF); // end of endpoint marker
|
||||
hibernateDeviceConfiguration(buf, device.data, endpoint);
|
||||
buf.add8(0xFF); // end of configuration
|
||||
}
|
||||
|
||||
// ModelID
|
||||
if (device.modelId) {
|
||||
size_t model_len = strlen(device.modelId);
|
||||
if (model_len > 32) { model_len = 32; } // max 32 chars
|
||||
buf.addBuffer(device.modelId, model_len);
|
||||
}
|
||||
buf.add8(0x00); // end of string marker
|
||||
|
||||
// ManufID
|
||||
if (device.manufacturerId) {
|
||||
size_t manuf_len = strlen(device.manufacturerId);
|
||||
if (manuf_len > 32) { manuf_len = 32; } // max 32 chars
|
||||
buf.addBuffer(device.manufacturerId, manuf_len);
|
||||
}
|
||||
buf.add8(0x00); // end of string marker
|
||||
|
||||
// FriendlyName
|
||||
if (device.friendlyName) {
|
||||
size_t frname_len = strlen(device.friendlyName);
|
||||
if (frname_len > 32) {frname_len = 32; } // max 32 chars
|
||||
buf.addBuffer(device.friendlyName, frname_len);
|
||||
}
|
||||
buf.add8(0x00); // end of string marker
|
||||
|
||||
// Zigbee Profile
|
||||
buf.add8(device.getLightChannels());
|
||||
buf.add8(0xFF); // end of endpoints
|
||||
|
||||
// update overall length
|
||||
buf.set8(0, buf.len());
|
||||
@ -144,7 +185,7 @@ class SBuffer hibernateDevices(void) {
|
||||
|
||||
for (uint32_t i = 0; i < devices_size; i++) {
|
||||
const Z_Device & device = zigbee_devices.devicesAt(i);
|
||||
const SBuffer buf_device = hibernateDevice(device);
|
||||
const SBuffer buf_device = hibernateDevicev2(device);
|
||||
buf.addBuffer(buf_device);
|
||||
}
|
||||
|
||||
@ -164,74 +205,102 @@ class SBuffer hibernateDevices(void) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
void hydrateDevices(const SBuffer &buf) {
|
||||
uint32_t buf_len = buf.len();
|
||||
if (buf_len <= 10) { return; }
|
||||
// parse a single string from the saved data
|
||||
// if something wrong happens, returns nullptr to ignore the string
|
||||
// Index d is incremented to just after the string
|
||||
const char * hydrateSingleString(const SBuffer & buf, uint32_t *d) {
|
||||
size_t s_len = buf.strlen(*d);
|
||||
const char * ptr = s_len ? buf.charptr(*d) : "";
|
||||
*d += s_len + 1;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint32_t k = 0;
|
||||
uint32_t num_devices = buf.get8(k++);
|
||||
for (uint32_t i = 0; (i < num_devices) && (k < buf_len); i++) {
|
||||
uint32_t dev_record_len = buf.get8(k);
|
||||
|
||||
SBuffer buf_d = buf.subBuffer(k, dev_record_len);
|
||||
|
||||
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;
|
||||
zigbee_devices.updateDevice(shortaddr, longaddr); // update device's addresses
|
||||
void hydrateSingleDevice(const SBuffer & buf_d, uint32_t version) {
|
||||
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;
|
||||
size_t buf_len = buf_d.len();
|
||||
Z_Device & device = zigbee_devices.updateDevice(shortaddr, longaddr); // update device's addresses
|
||||
|
||||
if (1 == version) {
|
||||
uint32_t endpoints = buf_d.get8(d++);
|
||||
for (uint32_t j = 0; j < endpoints; j++) {
|
||||
uint8_t ep = buf_d.get8(d++);
|
||||
uint16_t ep_profile = buf_d.get16(d); d += 2;
|
||||
zigbee_devices.addEndpoint(shortaddr, ep);
|
||||
device.addEndpoint(ep);
|
||||
|
||||
// in clusters
|
||||
while (d < dev_record_len) { // safe guard against overflow
|
||||
while (d < buf_len) { // safe guard against overflow
|
||||
uint8_t ep_cluster = buf_d.get8(d++);
|
||||
if (0xFF == ep_cluster) { break; } // end of block
|
||||
// ignore
|
||||
}
|
||||
// out clusters
|
||||
while (d < dev_record_len) { // safe guard against overflow
|
||||
while (d < buf_len) { // safe guard against overflow
|
||||
uint8_t ep_cluster = buf_d.get8(d++);
|
||||
if (0xFF == ep_cluster) { break; } // end of block
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse 3 strings
|
||||
char empty[] = "";
|
||||
// ModelId
|
||||
device.setModelId(hydrateSingleString(buf_d, &d));
|
||||
|
||||
// ManufID
|
||||
uint32_t s_len = buf_d.strlen_s(d);
|
||||
char *ptr = s_len ? buf_d.charptr(d) : empty;
|
||||
zigbee_devices.setModelId(shortaddr, ptr);
|
||||
d += s_len + 1;
|
||||
// ManufID
|
||||
device.setManufId(hydrateSingleString(buf_d, &d));
|
||||
|
||||
// ManufID
|
||||
s_len = buf_d.strlen_s(d);
|
||||
ptr = s_len ? buf_d.charptr(d) : empty;
|
||||
zigbee_devices.setManufId(shortaddr, ptr);
|
||||
d += s_len + 1;
|
||||
// FriendlyName
|
||||
device.setFriendlyName(hydrateSingleString(buf_d, &d));
|
||||
|
||||
// FriendlyName
|
||||
s_len = buf_d.strlen_s(d);
|
||||
ptr = s_len ? buf_d.charptr(d) : empty;
|
||||
zigbee_devices.setFriendlyName(shortaddr, ptr);
|
||||
d += s_len + 1;
|
||||
if (d >= buf_len) { return; }
|
||||
|
||||
// Hue bulbtype - if present
|
||||
if (d < dev_record_len) {
|
||||
zigbee_devices.setLightProfile(shortaddr, buf_d.get8(d));
|
||||
d++;
|
||||
// Hue bulbtype - if present
|
||||
if (1 == version) {
|
||||
zigbee_devices.setLightProfile(shortaddr, buf_d.get8(d));
|
||||
d++;
|
||||
} else if (2 == version) {
|
||||
// v2 parser
|
||||
while (d < buf_len) {
|
||||
uint8_t ep = buf_d.get8(d++);
|
||||
if (0xFF == ep) { break; } // ep 0xFF marks the end of the endpoints
|
||||
if (ep > 240) { ep = 0xFF; } // ep == 0xFF means ignore
|
||||
device.addEndpoint(ep); // it will ignore invalid endpoints
|
||||
while (d < buf_len) {
|
||||
uint8_t config_type = buf_d.get8(d++);
|
||||
if (0xFF == config_type) { break; } // 0xFF marks the end of congiguration
|
||||
uint8_t config = config_type & 0x0F;
|
||||
Z_Data_Type type = (Z_Data_Type) (config_type >> 4);
|
||||
// set the configuration
|
||||
if (ep != 0xFF) {
|
||||
Z_Data & z_data = device.data.getByType(type, ep);
|
||||
if (&z_data != nullptr) {
|
||||
z_data.setConfig(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hydrateDevices(const SBuffer &buf, uint32_t version) {
|
||||
uint32_t buf_len = buf.len();
|
||||
if (buf_len <= 10) { return; }
|
||||
|
||||
uint32_t k = 0; // byte index in global buffer
|
||||
uint32_t num_devices = buf.get8(k++);
|
||||
for (uint32_t i = 0; (i < num_devices) && (k < buf_len); i++) {
|
||||
uint32_t dev_record_len = buf.get8(k);
|
||||
|
||||
SBuffer buf_d = buf.subBuffer(k, dev_record_len);
|
||||
hydrateSingleDevice(buf_d, version);
|
||||
|
||||
// next iteration
|
||||
k += dev_record_len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loadZigbeeDevices(void) {
|
||||
#ifdef ESP32
|
||||
// first copy SPI buffer into ram
|
||||
@ -243,19 +312,24 @@ void loadZigbeeDevices(void) {
|
||||
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));
|
||||
Z_Flashentry flashdata;
|
||||
memcpy_P(&flashdata, z_dev_start, sizeof(Z_Flashentry));
|
||||
// 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
|
||||
if ((flashdata.name == ZIGB_NAME) && (flashdata.len > 0)) {
|
||||
if ( ((flashdata.name == ZIGB_NAME1) || (flashdata.name == ZIGB_NAME2))
|
||||
&& (flashdata.len > 0)) {
|
||||
uint16_t buf_len = flashdata.len;
|
||||
uint32_t version = (flashdata.name == ZIGB_NAME2) ? 2 : 1;
|
||||
// parse what seems to be a valid entry
|
||||
SBuffer buf(buf_len);
|
||||
buf.addBuffer(z_dev_start + sizeof(z_flashdata_t), buf_len);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee devices data in Flash (%d bytes)"), buf_len);
|
||||
hydrateDevices(buf);
|
||||
buf.addBuffer(z_dev_start + sizeof(Z_Flashentry), buf_len);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee devices data in Flash v%d (%d bytes)"), version, buf_len);
|
||||
// Serial.printf(">> Buffer=");
|
||||
// for (uint32_t i=0; i<buf.len(); i++) Serial.printf("%02X ", buf.get8(i));
|
||||
// Serial.printf("\n");
|
||||
hydrateDevices(buf, version);
|
||||
zigbee_devices.clean(); // don't write back to Flash what we just loaded
|
||||
} else {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "No zigbee devices data in Flash"));
|
||||
@ -287,12 +361,12 @@ void saveZigbeeDevices(void) {
|
||||
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;
|
||||
Z_Flashentry *flashdata = (Z_Flashentry*)(spi_buffer + z_block_offset);
|
||||
flashdata->name = ZIGB_NAME2; // v2
|
||||
flashdata->len = buf_len;
|
||||
flashdata->reserved = 0;
|
||||
flashdata->start = 0;
|
||||
|
||||
memcpy(spi_buffer + z_block_offset + sizeof(z_flashdata_t), buf.getBuffer(), buf_len);
|
||||
memcpy(spi_buffer + z_block_offset + sizeof(Z_Flashentry), buf.getBuffer(), buf_len);
|
||||
|
||||
// buffer is now ready, write it back
|
||||
#ifdef ESP8266
|
||||
|
||||
@ -504,7 +504,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
||||
{ Zuint8, Cx0300, 0x003C, Z_(ColorPointBIntensity), Cm1, 0 },
|
||||
|
||||
// Illuminance Measurement cluster
|
||||
{ Zuint16, Cx0400, 0x0000, Z_(Illuminance), Cm1, 0 }, // Illuminance (in Lux)
|
||||
{ Zuint16, Cx0400, 0x0000, Z_(Illuminance), Cm1 + Z_EXPORT_DATA, Z_MAPPING(Z_Data_PIR, illuminance) }, // Illuminance (in Lux)
|
||||
{ Zuint16, Cx0400, 0x0001, Z_(IlluminanceMinMeasuredValue), Cm1, 0 }, //
|
||||
{ Zuint16, Cx0400, 0x0002, Z_(IlluminanceMaxMeasuredValue), Cm1, 0 }, //
|
||||
{ Zuint16, Cx0400, 0x0003, Z_(IlluminanceTolerance), Cm1, 0 }, //
|
||||
@ -552,7 +552,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
||||
{ Zunk, Cx0405, 0xFFFF, Z_(), Cm0, 0 }, // Remove all other values
|
||||
|
||||
// Occupancy Sensing cluster
|
||||
{ Zmap8, Cx0406, 0x0000, Z_(Occupancy), Cm1, 0 }, // Occupancy (map8)
|
||||
{ Zmap8, Cx0406, 0x0000, Z_(Occupancy), Cm1 + Z_EXPORT_DATA, Z_MAPPING(Z_Data_PIR, occupancy) }, // Occupancy (map8)
|
||||
{ Zenum8, Cx0406, 0x0001, Z_(OccupancySensorType), Cm1, 0 }, // OccupancySensorType
|
||||
{ Zunk, Cx0406, 0xFFFF, Z_(), Cm0, 0 }, // Remove all other values
|
||||
|
||||
@ -706,7 +706,7 @@ public:
|
||||
if (Settings.flag3.tuya_serial_mqtt_publish) {
|
||||
MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR));
|
||||
} else {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -749,7 +749,6 @@ public:
|
||||
void parseResponse(void);
|
||||
void parseResponseOld(void);
|
||||
void parseClusterSpecificCommand(Z_attribute_list& attr_list);
|
||||
void postProcessAttributes(uint16_t shortaddr, Z_attribute_list& attr_list);
|
||||
|
||||
// synthetic attributes converters
|
||||
void syntheticAqaraSensor(Z_attribute_list &attr_list, class Z_attribute &attr);
|
||||
@ -1239,6 +1238,15 @@ void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) {
|
||||
attr_list.addAttribute(0x0001, 0x0021).setUInt(toPercentageCR2032(mv) * 2);
|
||||
}
|
||||
break;
|
||||
case 0x00010021: // BatteryPercentage
|
||||
{
|
||||
const char * model_c = zigbee_devices.getModelId(_srcaddr); // null if unknown
|
||||
String modelId((char*) model_c);
|
||||
if (modelId.startsWith(F("TRADFRI"))) {
|
||||
attr.setUInt(attr.getUInt() * 2); // bug in TRADFRI battery, need to double the value
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x02010008: // Pi Heating Demand - solve Eutotronic bug
|
||||
{
|
||||
const char * manufacturer_c = zigbee_devices.getManufacturerId(_srcaddr); // null if unknown
|
||||
@ -1277,10 +1285,15 @@ void ZCLFrame::generateCallBacks(Z_attribute_list& attr_list) {
|
||||
case 0x04060000: // Occupancy
|
||||
uint32_t occupancy = attr.getUInt();
|
||||
if (occupancy) {
|
||||
zigbee_devices.setTimer(_srcaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, _cluster_id, _srcendpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback);
|
||||
uint32_t pir_timer = OCCUPANCY_TIMEOUT;
|
||||
const Z_Data_PIR & pir_found = (const Z_Data_PIR&) zigbee_devices.getShortAddr(_srcaddr).data.find(Z_Data_Type::Z_PIR, _srcendpoint);
|
||||
if (&pir_found != nullptr) {
|
||||
pir_timer = pir_found.getTimeoutSeconds() * 1000;
|
||||
}
|
||||
zigbee_devices.setTimer(_srcaddr, 0 /* groupaddr */, pir_timer, _cluster_id, _srcendpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback);
|
||||
} else {
|
||||
zigbee_devices.resetTimersForDevice(_srcaddr, 0 /* groupaddr */, Z_CAT_VIRTUAL_OCCUPANCY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1332,7 +1345,7 @@ void ZCLFrame::parseReadAttributes(Z_attribute_list& attr_list) {
|
||||
|
||||
attr_list.addAttribute(F(D_CMND_ZIGBEE_CLUSTER)).setUInt(_cluster_id);
|
||||
|
||||
Z_json_array attr_numbers;
|
||||
JsonGeneratorArray attr_numbers;
|
||||
Z_attribute_list attr_names;
|
||||
while (len >= 2 + i) {
|
||||
uint16_t attrid = _payload.get16(i);
|
||||
@ -1354,7 +1367,7 @@ void ZCLFrame::parseReadAttributes(Z_attribute_list& attr_list) {
|
||||
}
|
||||
attr_list.addAttribute(F("Read")).setStrRaw(attr_numbers.toString().c_str());
|
||||
attr_list.addAttribute(F("ReadNames")).setStrRaw(attr_names.toString(true).c_str());
|
||||
|
||||
|
||||
// call auto-responder
|
||||
autoResponder(read_attr_ids, len/2);
|
||||
}
|
||||
@ -1755,22 +1768,30 @@ void ZCLFrame::syntheticAqaraVibration(class Z_attribute_list &attr_list, class
|
||||
/// Publish a message for `"Occupancy":0` when the timer expired
|
||||
void Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
|
||||
Z_attribute_list attr_list;
|
||||
attr_list.addAttribute(F(OCCUPANCY)).setUInt(0);
|
||||
attr_list.addAttribute(0x0406, 0x0000).setUInt(0); // Occupancy
|
||||
Z_postProcessAttributes(shortaddr, endpoint, attr_list); // make sure all is updated accordingly
|
||||
zigbee_devices.jsonPublishNow(shortaddr, attr_list);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
void ZCLFrame::postProcessAttributes(uint16_t shortaddr, Z_attribute_list& attr_list) {
|
||||
// source endpoint
|
||||
uint8_t src_ep = _srcendpoint;
|
||||
|
||||
void Z_postProcessAttributes(uint16_t shortaddr, uint16_t src_ep, class Z_attribute_list& attr_list) {
|
||||
Z_Device & device = zigbee_devices.getShortAddr(shortaddr);
|
||||
uint8_t count_ep = device.countEndpoints();
|
||||
|
||||
for (auto &attr : attr_list) {
|
||||
// add endpoint suffix if needed
|
||||
if ((Settings.flag4.zb_index_ep) && (src_ep != 1) && (count_ep > 1)) {
|
||||
// we need to add suffix if the suffix is not already different from 1
|
||||
if (attr.key_suffix == 1) {
|
||||
attr.key_suffix = src_ep;
|
||||
}
|
||||
}
|
||||
|
||||
// attr is Z_attribute&
|
||||
if (!attr.key_is_str) {
|
||||
uint16_t cluster = attr.key.id.cluster;
|
||||
uint16_t attribute = attr.key.id.attr_id;
|
||||
uint32_t ccccaaaa = (attr.key.id.cluster << 16) | attr.key.id.attr_id;
|
||||
Z_Device & device = zigbee_devices.getShortAddr(shortaddr);
|
||||
|
||||
// Look for an entry in the converter table
|
||||
bool found = false;
|
||||
@ -1803,6 +1824,8 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, Z_attribute_list& attr_
|
||||
// First we find or instantiate the correct Z_Data_XXX accorfing to the endpoint
|
||||
// Then store the attribute at the attribute addres (via offset) and according to size 8/16/32 bits
|
||||
|
||||
// add the endpoint if it was not already known
|
||||
device.addEndpoint(src_ep);
|
||||
// we don't apply the multiplier, but instead store in Z_Data_XXX object
|
||||
Z_Data & data = device.data.getByType(map_type, src_ep);
|
||||
uint8_t *attr_address = ((uint8_t*)&data) + sizeof(Z_Data) + map_offset;
|
||||
@ -1811,8 +1834,10 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, Z_attribute_list& attr_
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Mapping type=%d offset=%d zigbee_type=%02X value=%d\n"), (uint8_t) map_type, map_offset, zigbee_type, ival32);
|
||||
switch (zigbee_type) {
|
||||
case Zenum8:
|
||||
case Zmap8:
|
||||
case Zuint8: *(uint8_t*)attr_address = uval32; break;
|
||||
case Zenum16:
|
||||
case Zmap16:
|
||||
case Zuint16: *(uint16_t*)attr_address = uval32; break;
|
||||
case Zuint32: *(uint32_t*)attr_address = uval32; break;
|
||||
case Zint8: *(int8_t*)attr_address = ival32; break;
|
||||
@ -1826,8 +1851,8 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, Z_attribute_list& attr_
|
||||
Z_Data_Set & data = device.data;
|
||||
// update any internal structure
|
||||
switch (ccccaaaa) {
|
||||
case 0x00000004: zigbee_devices.setManufId(shortaddr, attr.getStr()); break;
|
||||
case 0x00000005: zigbee_devices.setModelId(shortaddr, attr.getStr()); break;
|
||||
case 0x00000004: device.setManufId(attr.getStr()); break;
|
||||
case 0x00000005: device.setModelId(attr.getStr()); break;
|
||||
case 0x00010021: zigbee_devices.setBatteryPercent(shortaddr, uval16 / 2); break;
|
||||
case 0x00060000:
|
||||
case 0x00068000: device.setPower(attr.getBool(), src_ep); break;
|
||||
@ -1952,7 +1977,9 @@ void Z_Data::toAttributes(Z_attribute_list & attr_list, Z_Data_Type type) const
|
||||
uint32_t uval32;
|
||||
switch (zigbee_type) {
|
||||
case Zenum8:
|
||||
case Zmap8:
|
||||
case Zuint8: uval32 = *(uint8_t*)attr_address; if (uval32 != 0xFF) data_size = 8; break;
|
||||
case Zmap16:
|
||||
case Zenum16:
|
||||
case Zuint16: uval32 = *(uint16_t*)attr_address; if (uval32 != 0xFFFF) data_size = 16; break;
|
||||
case Zuint32: uval32 = *(uint32_t*)attr_address; if (uval32 != 0xFFFFFFFF) data_size = 32; break;
|
||||
@ -1963,7 +1990,7 @@ void Z_Data::toAttributes(Z_attribute_list & attr_list, Z_Data_Type type) const
|
||||
if (data_size != 0) {
|
||||
Z_attribute & attr = attr_list.addAttribute(conv_name);
|
||||
|
||||
if (data_size > 0) { attr.setUInt(uval32); }
|
||||
if (data_size > 0) { attr.setUInt(uval32); }
|
||||
else { attr.setInt(ival32); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,7 +370,7 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster,
|
||||
attr_list.addAttribute(command_name, PSTR("Count")).setUInt(xyz.y);
|
||||
{
|
||||
|
||||
Z_json_array group_list;
|
||||
JsonGeneratorArray group_list;
|
||||
for (uint32_t i = 0; i < xyz.y; i++) {
|
||||
group_list.add(payload.get16(2 + 2*i));
|
||||
}
|
||||
@ -431,7 +431,7 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster,
|
||||
char command_suffix[4] = { 0x00 }; // empty string by default
|
||||
// if SO101 and multiple endpoints, append endpoint number
|
||||
if (Settings.flag4.zb_index_ep) {
|
||||
if (zigbee_devices.countEndpoints(shortaddr) > 0) {
|
||||
if (zigbee_devices.getShortAddr(shortaddr).countEndpoints() > 0) {
|
||||
snprintf_P(command_suffix, sizeof(command_suffix), PSTR("%d"), srcendpoint);
|
||||
}
|
||||
}
|
||||
@ -441,7 +441,7 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster,
|
||||
attr_list.addAttribute(command_name, command_suffix).setUInt(xyz.x);
|
||||
} else {
|
||||
// multiple answers, create an array
|
||||
Z_json_array arr;
|
||||
JsonGeneratorArray arr;
|
||||
arr.add(xyz.x);
|
||||
arr.add(xyz.y);
|
||||
if (xyz.z_type) {
|
||||
|
||||
@ -165,7 +165,7 @@ int32_t EZ_RouteError(int32_t res, const class SBuffer &buf) {
|
||||
//
|
||||
int32_t EZ_PermitJoinRsp(int32_t res, const class SBuffer &buf) {
|
||||
uint8_t status = buf.get8(2);
|
||||
|
||||
|
||||
if (status) { // only report if there is an error
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":23,\"Message\":\"Pairing mode error 0x%02X\"}}"), status);
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
|
||||
@ -539,7 +539,7 @@ int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) {
|
||||
|
||||
for (uint32_t i = 0; i < activeEpCount; i++) {
|
||||
uint8_t ep = activeEpList[i];
|
||||
zigbee_devices.addEndpoint(nwkAddr, ep);
|
||||
zigbee_devices.getShortAddr(nwkAddr).addEndpoint(ep);
|
||||
if ((i < 4) && (ep < 0x10)) {
|
||||
zigbee_devices.queueTimer(nwkAddr, 0 /* groupaddr */, 1500, ep /* fake cluster as ep */, ep, Z_CAT_EP_DESC, 0 /* value */, &Z_SendSimpleDescReq);
|
||||
}
|
||||
@ -925,6 +925,7 @@ int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle MgMt Bind Rsp incoming message
|
||||
//
|
||||
@ -1002,6 +1003,116 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return false, true or null (if unknown)
|
||||
const char * TrueFalseNull(uint32_t value) {
|
||||
if (value == 0) {
|
||||
return PSTR("false");
|
||||
} else if (value == 1) {
|
||||
return PSTR("true");
|
||||
} else {
|
||||
return PSTR("null");
|
||||
}
|
||||
}
|
||||
|
||||
const char * Z_DeviceRelationship(uint32_t value) {
|
||||
switch (value) {
|
||||
case 0: return PSTR("Parent");
|
||||
case 1: return PSTR("Child");
|
||||
case 2: return PSTR("Sibling");
|
||||
case 4: return PSTR("Previous");
|
||||
case 3:
|
||||
default: return PSTR("None");
|
||||
}
|
||||
}
|
||||
|
||||
const char * Z_DeviceType(uint32_t value) {
|
||||
switch (value) {
|
||||
case 0: return PSTR("Coordinator");
|
||||
case 1: return PSTR("Router");
|
||||
case 2: return PSTR("Device");
|
||||
default: return PSTR("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle MgMt Bind Rsp incoming message
|
||||
//
|
||||
int32_t Z_MgmtLqiRsp(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 lqi_total = buf.get8(5);
|
||||
uint8_t lqi_start = buf.get8(6);
|
||||
uint8_t lqi_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 lqi_total = buf.get8(1);
|
||||
uint8_t lqi_start = buf.get8(2);
|
||||
uint8_t lqi_len = buf.get8(3);
|
||||
const size_t prefix_len = 4;
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr);
|
||||
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_MAP "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), shortaddr);
|
||||
if (friendlyName) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName);
|
||||
}
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
||||
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
||||
",\"MapTotal\":%d"
|
||||
",\"MapStart\":%d"
|
||||
",\"Map\":["
|
||||
), status, getZigbeeStatusMessage(status).c_str(), lqi_total, lqi_start + 1);
|
||||
|
||||
uint32_t idx = prefix_len;
|
||||
for (uint32_t i = 0; i < lqi_len; i++) {
|
||||
if (idx + 22 > buf.len()) { break; } // size 22 for EZSP
|
||||
|
||||
//uint64_t extpanid = buf.get16(idx); // unused
|
||||
// uint64_t m_longaddr = buf.get64(idx + 8);
|
||||
uint16_t m_shortaddr = buf.get16(idx + 16);
|
||||
uint8_t m_dev_type = buf.get8(idx + 18);
|
||||
uint8_t m_permitjoin = buf.get8(idx + 19);
|
||||
uint8_t m_depth = buf.get8(idx + 20);
|
||||
uint8_t m_lqi = buf.get8(idx + 21);
|
||||
idx += 22;
|
||||
|
||||
if (i > 0) {
|
||||
ResponseAppend_P(PSTR(","));
|
||||
}
|
||||
ResponseAppend_P(PSTR("{\"Device\":\"0x%04X\","), m_shortaddr);
|
||||
|
||||
const char * friendlyName = zigbee_devices.getFriendlyName(m_shortaddr);
|
||||
if (friendlyName) {
|
||||
ResponseAppend_P(PSTR("\"Name\":\"%s\","), friendlyName);
|
||||
}
|
||||
ResponseAppend_P(PSTR("\"DeviceType\":\"%s\","
|
||||
"\"RxOnWhenIdle\":%s,"
|
||||
"\"Relationship\":\"%s\","
|
||||
"\"PermitJoin\":%s,"
|
||||
"\"Depth\":%d,"
|
||||
"\"LinkQuality\":%d"
|
||||
"}"
|
||||
),
|
||||
Z_DeviceType(m_dev_type & 0x03),
|
||||
TrueFalseNull((m_dev_type & 0x0C) >> 2),
|
||||
Z_DeviceRelationship((m_dev_type & 0x70) >> 4),
|
||||
TrueFalseNull(m_permitjoin & 0x02),
|
||||
m_depth,
|
||||
m_lqi);
|
||||
}
|
||||
|
||||
ResponseAppend_P(PSTR("]}}"));
|
||||
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_MAP));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
//
|
||||
// Handle Parent Annonce Rsp incoming message
|
||||
@ -1116,7 +1227,7 @@ void Z_SendSimpleDescReq(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluste
|
||||
// Queue requests for the device
|
||||
// 1. Request for 'ModelId' and 'Manufacturer': 0000/0005, 0000/0006
|
||||
// 2. Auto-bind to coordinator:
|
||||
// Iterate among
|
||||
// Iterate among
|
||||
//
|
||||
void Z_SendDeviceInfoRequest(uint16_t shortaddr) {
|
||||
uint8_t endpoint = zigbee_devices.findFirstEndpoint(shortaddr);
|
||||
@ -1167,7 +1278,7 @@ void Z_SendSingleAttributeRead(uint16_t shortaddr, uint16_t groupaddr, uint16_t
|
||||
//
|
||||
void Z_AutoBind(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
|
||||
uint64_t srcLongAddr = zigbee_devices.getDeviceLongAddr(shortaddr);
|
||||
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "auto-bind `ZbBind {\"Device\":\"0x%04X\",\"Endpoint\":%d,\"Cluster\":\"0x%04X\"}`"),
|
||||
shortaddr, endpoint, cluster);
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
@ -1215,8 +1326,8 @@ typedef struct Z_autoAttributeReporting_t {
|
||||
|
||||
// Note the attribute must be registered in the converter list, used to retrieve the type of the attribute
|
||||
const Z_autoAttributeReporting_t Z_autoAttributeReporting[] PROGMEM = {
|
||||
{ 0x0001, 0x0020, 15*60, 15*60, 0.1 }, // BatteryVoltage
|
||||
{ 0x0001, 0x0021, 15*60, 15*60, 1 }, // BatteryPercentage
|
||||
{ 0x0001, 0x0020, 60*60, 4*60*60, 0.1 }, // BatteryVoltage
|
||||
{ 0x0001, 0x0021, 60*60, 4*60*60, 1 }, // BatteryPercentage
|
||||
{ 0x0006, 0x0000, 1, 60*60, 0 }, // Power
|
||||
{ 0x0201, 0x0000, 60, 60*10, 0.5 }, // LocalTemperature
|
||||
{ 0x0201, 0x0008, 60, 60*10, 10 }, // PIHeatingDemand
|
||||
@ -1293,7 +1404,7 @@ void Z_AutoConfigReportingForCluster(uint16_t shortaddr, uint16_t groupaddr, uin
|
||||
ResponseAppend_P(PSTR("}}"));
|
||||
|
||||
if (buf.len() > 0) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "auto-bind `%s`"), mqtt_data);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "auto-bind `%s`"), TasmotaGlobal.mqtt_data);
|
||||
ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
|
||||
shortaddr,
|
||||
0x0000, /* group */
|
||||
@ -1404,7 +1515,7 @@ void Z_IncomingMessage(class ZCLFrame &zcl_received) {
|
||||
zcl_received.generateSyntheticAttributes(attr_list);
|
||||
zcl_received.computeSyntheticAttributes(attr_list);
|
||||
zcl_received.generateCallBacks(attr_list); // set deferred callbacks, ex: Occupancy
|
||||
zcl_received.postProcessAttributes(srcaddr, attr_list);
|
||||
Z_postProcessAttributes(srcaddr, zcl_received.getSrcEndpoint(), attr_list);
|
||||
|
||||
// since we just receveived data from the device, it is reachable
|
||||
zigbee_devices.resetTimersForDevice(srcaddr, 0 /* groupaddr */, Z_CAT_REACHABILITY); // remove any reachability timer already there
|
||||
@ -1494,7 +1605,7 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) {
|
||||
uint16_t groupid = buf.get16(11);
|
||||
uint8_t seqnumber = buf.get8(13);
|
||||
int8_t linkrssi = buf.get8(15);
|
||||
uint8_t linkquality = ZNP_RSSI2Lqi(linkrssi); // don't take EZSP LQI but calculate our own based on ZNP
|
||||
uint8_t linkquality = ZNP_RSSI2Lqi(linkrssi); // don't take EZSP LQI but calculate our own based on ZNP
|
||||
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
|
||||
@ -1524,6 +1635,8 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) {
|
||||
return Z_BindRsp(res, zdo_buf);
|
||||
case ZDO_Unbind_rsp:
|
||||
return Z_UnbindRsp(res, zdo_buf);
|
||||
case ZDO_Mgmt_Lqi_rsp:
|
||||
return Z_MgmtLqiRsp(res, zdo_buf);
|
||||
case ZDO_Mgmt_Bind_rsp:
|
||||
return Z_MgmtBindRsp(res, zdo_buf);
|
||||
case ZDO_Parent_annce:
|
||||
@ -1697,6 +1810,7 @@ const Z_Dispatcher Z_DispatchTable[] PROGMEM = {
|
||||
{ { 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_LQI_RSP }, &Z_MgmtLqiRsp }, // 45B1
|
||||
{ { Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP }, &Z_MgmtBindRsp }, // 45B3
|
||||
};
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@ void ZigbeeInputLoop(void) {
|
||||
if (Settings.flag3.tuya_serial_mqtt_publish) {
|
||||
MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR));
|
||||
} else {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
// now process the message
|
||||
ZigbeeProcessInput(znp_buffer);
|
||||
@ -293,13 +293,13 @@ void ZigbeeInitSerial(void)
|
||||
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
|
||||
// if TasmotaGlobal.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), TasmotaGlobal.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);
|
||||
uint32_t aligned_buffer = ((uint32_t)TasmotaGlobal.serial_in_buffer + 3) & ~3;
|
||||
zigbee_buffer = new PreAllocatedSBuffer(sizeof(TasmotaGlobal.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);
|
||||
@ -545,7 +545,7 @@ void ZigbeeEZSPSendDATA(const uint8_t *msg, size_t len) {
|
||||
}
|
||||
EZSP_Serial.to_packets[to_frm] = buf;
|
||||
EZSP_Serial.to_end = (to_frm + 1) & 0x07; // move cursor
|
||||
|
||||
|
||||
// ZigbeeEZSPSendDATA_frm(send_cancel, to_frm, EZSP_Serial.from_ack);
|
||||
|
||||
// increment to_frame
|
||||
@ -609,7 +609,7 @@ int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) {
|
||||
log_level = LOG_LEVEL_DEBUG;
|
||||
break;
|
||||
}
|
||||
AddLog_P2(log_level, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable
|
||||
AddLog_P2(log_level, PSTR(D_LOG_ZIGBEE "%s"), TasmotaGlobal.mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable
|
||||
}
|
||||
|
||||
// Pass message to state machine
|
||||
@ -672,14 +672,14 @@ int32_t ZigbeeProcessInputRaw(class SBuffer &buf) {
|
||||
// ERROR
|
||||
EZ_ERROR(buf.get8(2));
|
||||
zigbee.active = false; // stop all zigbee activities
|
||||
restart_flag = 2; // there is nothing more we can do except restart
|
||||
TasmotaGlobal.restart_flag = 2; // there is nothing more we can do except restart
|
||||
} else {
|
||||
|
||||
// Unknown
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Received unknown control byte 0x%02X"), control_byte);
|
||||
}
|
||||
} else { // DATA Frame
|
||||
|
||||
|
||||
// adjust to latest acked packet
|
||||
uint8_t new_ack = control_byte & 0x07;
|
||||
EZSP_HandleAck(new_ack);
|
||||
|
||||
@ -347,8 +347,8 @@ bool ZigbeeUploadXmodem(void) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init sync"));
|
||||
ZigbeeSerial->flush();
|
||||
ZigbeeSerial->write('1'); // upload ebl
|
||||
if (ssleep > 0) {
|
||||
ssleep = 1; // Speed up loop used for xmodem upload
|
||||
if (TasmotaGlobal.sleep > 0) {
|
||||
TasmotaGlobal.sleep = 1; // Speed up loop used for xmodem upload
|
||||
}
|
||||
XModem.timeout = millis() + (XMODEM_SYNC_TIMEOUT * 1000);
|
||||
ZbUpload.ota_step = ZBU_SYNC;
|
||||
@ -442,10 +442,10 @@ bool ZigbeeUploadXmodem(void) {
|
||||
case ZBU_DONE: { // *** Clean up and restart to disable bootloader and use new firmware
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: " D_RESTARTING));
|
||||
ZigbeeUploadSetBootloader(1); // Disable bootloader and reset MCU - should happen at restart
|
||||
if (1 == ssleep) {
|
||||
ssleep = Settings.sleep; // Restore loop sleep
|
||||
if (1 == TasmotaGlobal.sleep) {
|
||||
TasmotaGlobal.sleep = Settings.sleep; // Restore loop sleep
|
||||
}
|
||||
// restart_flag = 2; // Restart to disable bootloader and use new firmware
|
||||
// TasmotaGlobal.restart_flag = 2; // Restart to disable bootloader and use new firmware
|
||||
ZbUpload.ota_step = ZBU_FINISH; // Never return to zero without a restart to get a sane Zigbee environment
|
||||
break;
|
||||
}
|
||||
|
||||
@ -32,7 +32,8 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
|
||||
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_LIGHT "|" D_CMND_ZIGBEE_OCCUPANCY "|"
|
||||
D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" D_CMND_ZIGBEE_MAP "|"
|
||||
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA
|
||||
;
|
||||
|
||||
@ -47,7 +48,8 @@ void (* const ZigbeeCommand[])(void) PROGMEM = {
|
||||
&CmndZbStatus, &CmndZbReset, &CmndZbSend, &CmndZbProbe,
|
||||
&CmndZbForget, &CmndZbSave, &CmndZbName,
|
||||
&CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId,
|
||||
&CmndZbLight, &CmndZbRestore, &CmndZbBindState,
|
||||
&CmndZbLight, &CmndZbOccupancy,
|
||||
&CmndZbRestore, &CmndZbBindState, &CmndZbMap,
|
||||
&CmndZbConfig, CmndZbData,
|
||||
};
|
||||
|
||||
@ -126,7 +128,7 @@ void CmndZbReset(void) {
|
||||
eraseZigbeeDevices();
|
||||
case 2: // fall through
|
||||
Settings.zb_txradio_dbm = - abs(Settings.zb_txradio_dbm);
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
ResponseCmndChar_P(PSTR(D_JSON_ZIGBEE_CC2530 " " D_JSON_RESET_AND_RESTARTING));
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
@ -937,11 +939,7 @@ void CmndZbUnbind(void) {
|
||||
ZbBindUnbind(true);
|
||||
}
|
||||
|
||||
//
|
||||
// Command `ZbBindState`
|
||||
// `ZbBindState<x>` as index if it does not fit. If default, `1` starts at the beginning
|
||||
//
|
||||
void CmndZbBindState(void) {
|
||||
void CmndZbBindState_or_Map(uint16_t zdo_cmd) {
|
||||
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; }
|
||||
@ -950,7 +948,7 @@ void CmndZbBindState(void) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
SBuffer buf(10);
|
||||
buf.add8(Z_SREQ | Z_ZDO); // 25
|
||||
buf.add8(ZDO_MGMT_BIND_REQ); // 33
|
||||
buf.add8(zdo_cmd); // 33
|
||||
buf.add16(shortaddr); // shortaddr
|
||||
buf.add8(index); // StartIndex = 0
|
||||
|
||||
@ -962,12 +960,38 @@ void CmndZbBindState(void) {
|
||||
// ZDO message payload (see Zigbee spec 2.4.3.3.4)
|
||||
uint8_t buf[] = { index }; // index = 0
|
||||
|
||||
EZ_SendZDO(shortaddr, ZDO_Mgmt_Bind_req, buf, sizeof(buf));
|
||||
EZ_SendZDO(shortaddr, zdo_cmd, buf, sizeof(buf));
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
//
|
||||
// Command `ZbBindState`
|
||||
// `ZbBindState<x>` as index if it does not fit. If default, `1` starts at the beginning
|
||||
//
|
||||
void CmndZbBindState(void) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
CmndZbBindState_or_Map(ZDO_MGMT_BIND_REQ);
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
CmndZbBindState_or_Map(ZDO_Mgmt_Bind_req);
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
}
|
||||
|
||||
//
|
||||
// Command `ZbMap`
|
||||
// `ZbMap<x>` as index if it does not fit. If default, `1` starts at the beginning
|
||||
//
|
||||
void CmndZbMap(void) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
CmndZbBindState_or_Map(ZDO_MGMT_LQI_REQ);
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
CmndZbBindState_or_Map(ZDO_Mgmt_Lqi_req);
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
}
|
||||
|
||||
// Probe a specific device to get its endpoints and supported clusters
|
||||
void CmndZbProbe(void) {
|
||||
CmndZbProbeOrPing(true);
|
||||
@ -1021,7 +1045,7 @@ void CmndZbName(void) {
|
||||
Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), shortaddr, friendlyName ? friendlyName : "");
|
||||
} else {
|
||||
if (strlen(p) > 32) { p[32] = 0x00; } // truncate to 32 chars max
|
||||
zigbee_devices.setFriendlyName(shortaddr, p);
|
||||
zigbee_devices.getShortAddr(shortaddr).setFriendlyName(p);
|
||||
Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), shortaddr, p);
|
||||
}
|
||||
}
|
||||
@ -1052,7 +1076,7 @@ void CmndZbModelId(void) {
|
||||
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);
|
||||
zigbee_devices.getShortAddr(shortaddr).setModelId(p);
|
||||
Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_MODELID "\":\"%s\"}}"), shortaddr, p);
|
||||
}
|
||||
}
|
||||
@ -1089,6 +1113,56 @@ void CmndZbLight(void) {
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_ZB D_CMND_ZIGBEE_LIGHT));
|
||||
ResponseCmndDone();
|
||||
}
|
||||
//
|
||||
// Command `ZbOccupancy`
|
||||
// Specify, read or erase the Occupancy detector configuration
|
||||
void CmndZbOccupancy(void) {
|
||||
// Syntax is:
|
||||
// ZbOccupancy <device_id>,<x> - set the occupancy time-out
|
||||
// ZbOccupancy <device_id> - display the configuration
|
||||
//
|
||||
// List of occupancy time-outs:
|
||||
// 0xF = default (90 s)
|
||||
// 0x0 = no time-out
|
||||
// 0x1 = 15 s
|
||||
// 0x2 = 30 s
|
||||
// 0x3 = 45 s
|
||||
// 0x4 = 60 s
|
||||
// 0x5 = 75 s
|
||||
// 0x6 = 90 s -- default
|
||||
// 0x7 = 105 s
|
||||
// 0x8 = 120 s
|
||||
// Where <device_id> 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, <device_id>
|
||||
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; }
|
||||
|
||||
Z_Device & device = zigbee_devices.getShortAddr(shortaddr);
|
||||
|
||||
int8_t occupancy_time = -1;
|
||||
if (p) {
|
||||
Z_Data_PIR & pir = (Z_Data_PIR&) device.data.getByType(Z_Data_Type::Z_PIR);
|
||||
occupancy_time = strtol(p, nullptr, 10);
|
||||
pir.setTimeoutSeconds(occupancy_time);
|
||||
zigbee_devices.dirty();
|
||||
} else {
|
||||
const Z_Data_PIR & pir_found = (const Z_Data_PIR&) device.data.find(Z_Data_Type::Z_PIR);
|
||||
if (&pir_found != nullptr) {
|
||||
occupancy_time = pir_found.getTimeoutSeconds();
|
||||
}
|
||||
}
|
||||
Response_P(PSTR("{\"" D_PRFX_ZB D_CMND_ZIGBEE_OCCUPANCY "\":%d}"), occupancy_time);
|
||||
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_ZB D_CMND_ZIGBEE_LIGHT));
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
//
|
||||
// Command `ZbForget`
|
||||
@ -1283,7 +1357,7 @@ void ZigbeeGlowPermitJoinLight(void) {
|
||||
// change the led state
|
||||
uint32_t led_pin = Pin(GPIO_LEDLNK);
|
||||
if (led_pin < 99) {
|
||||
analogWrite(led_pin, ledlnk_inverted ? 1023 - led_power : led_power);
|
||||
analogWrite(led_pin, TasmotaGlobal.ledlnk_inverted ? 1023 - led_power : led_power);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1314,17 +1388,12 @@ bool parseDeviceInnerData(class Z_Device & device, JsonParserObject root) {
|
||||
// Parse key in format "L02":....
|
||||
const char * data_type_str = data_elt.getStr();
|
||||
Z_Data_Type data_type;
|
||||
uint8_t endpoint;
|
||||
uint8_t config = 0xFF; // unspecified
|
||||
|
||||
// parse key in the form "L01.5"
|
||||
if (!Z_Data::ConfigToZData(data_type_str, &data_type, &endpoint, &config)) { data_type = Z_Data_Type::Z_Unknown; }
|
||||
|
||||
switch (data_type_str[0]) {
|
||||
case 'P': data_type = Z_Data_Type::Z_Plug; break;
|
||||
case 'L': data_type = Z_Data_Type::Z_Light; break;
|
||||
case 'O': data_type = Z_Data_Type::Z_OnOff; break;
|
||||
case 'T': data_type = Z_Data_Type::Z_Thermo; break;
|
||||
case 'A': data_type = Z_Data_Type::Z_Alarm; break;
|
||||
case '_': data_type = Z_Data_Type::Z_Device; break;
|
||||
default: data_type = Z_Data_Type::Z_Unknown; break;
|
||||
}
|
||||
// The format should be a valid Code Lette followed by '-'
|
||||
if (data_type == Z_Data_Type::Z_Unknown) {
|
||||
Response_P(PSTR("{\"%s\":\"%s \"%s\"\"}"), XdrvMailbox.command, PSTR("Invalid Parameters"), data_type_str);
|
||||
return false;
|
||||
@ -1333,79 +1402,82 @@ bool parseDeviceInnerData(class Z_Device & device, JsonParserObject root) {
|
||||
JsonParserObject data_values = data_elt.getValue().getObject();
|
||||
if (!data_values) { return false; }
|
||||
|
||||
// Decode the endpoint number
|
||||
uint8_t endpoint = strtoul(&data_type_str[1], nullptr, 16); // hex base 16
|
||||
JsonParserToken val;
|
||||
if (data_type == Z_Data_Type::Z_Device) {
|
||||
if (val = data_values[PSTR(D_CMND_ZIGBEE_LINKQUALITY)]) { device.lqi = val.getUInt(); }
|
||||
if (val = data_values[PSTR("BatteryPercentage")]) { device.batterypercent = val.getUInt(); }
|
||||
if (val = data_values[PSTR("LastSeen")]) { device.last_seen = val.getUInt(); }
|
||||
} else {
|
||||
// Import generic attributes first
|
||||
device.addEndpoint(endpoint);
|
||||
Z_Data & data = device.data.getByType(data_type, endpoint);
|
||||
|
||||
// Import generic attributes first
|
||||
Z_Data & data = device.data.getByType(data_type, endpoint);
|
||||
// scan through attributes
|
||||
if (&data != nullptr) {
|
||||
if (config != 0xFF) {
|
||||
data.setConfig(config);
|
||||
}
|
||||
|
||||
// scan through attributes
|
||||
for (auto attr : data_values) {
|
||||
JsonParserToken attr_value = attr.getValue();
|
||||
uint8_t conv_zigbee_type;
|
||||
Z_Data_Type conv_data_type;
|
||||
uint8_t conv_map_offset;
|
||||
if (zigbeeFindAttributeByName(attr.getStr(), nullptr, nullptr, nullptr, &conv_zigbee_type, &conv_data_type, &conv_map_offset) != nullptr) {
|
||||
// found an attribute matching the name, does is fit the type?
|
||||
if (conv_data_type == data_type) {
|
||||
// we got a match. Bear in mind that a zero value is not a valid 'data_type'
|
||||
for (auto attr : data_values) {
|
||||
JsonParserToken attr_value = attr.getValue();
|
||||
uint8_t conv_zigbee_type;
|
||||
Z_Data_Type conv_data_type;
|
||||
uint8_t conv_map_offset;
|
||||
if (zigbeeFindAttributeByName(attr.getStr(), nullptr, nullptr, nullptr, &conv_zigbee_type, &conv_data_type, &conv_map_offset) != nullptr) {
|
||||
// found an attribute matching the name, does is fit the type?
|
||||
if (conv_data_type == data_type) {
|
||||
// we got a match. Bear in mind that a zero value is not a valid 'data_type'
|
||||
|
||||
uint8_t *attr_address = ((uint8_t*)&data) + sizeof(Z_Data) + conv_map_offset;
|
||||
uint32_t uval32 = attr_value.getUInt(); // call converter to uint only once
|
||||
int32_t ival32 = attr_value.getInt(); // call converter to int only once
|
||||
switch (conv_zigbee_type) {
|
||||
case Zenum8:
|
||||
case Zuint8: *(uint8_t*)attr_address = uval32; break;
|
||||
case Zenum16:
|
||||
case Zuint16: *(uint16_t*)attr_address = uval32; break;
|
||||
case Zuint32: *(uint32_t*)attr_address = uval32; break;
|
||||
case Zint8: *(int8_t*)attr_address = ival32; break;
|
||||
case Zint16: *(int16_t*)attr_address = ival32; break;
|
||||
case Zint32: *(int32_t*)attr_address = ival32; break;
|
||||
uint8_t *attr_address = ((uint8_t*)&data) + sizeof(Z_Data) + conv_map_offset;
|
||||
uint32_t uval32 = attr_value.getUInt(); // call converter to uint only once
|
||||
int32_t ival32 = attr_value.getInt(); // call converter to int only once
|
||||
switch (conv_zigbee_type) {
|
||||
case Zenum8:
|
||||
case Zuint8: *(uint8_t*)attr_address = uval32; break;
|
||||
case Zenum16:
|
||||
case Zuint16: *(uint16_t*)attr_address = uval32; break;
|
||||
case Zuint32: *(uint32_t*)attr_address = uval32; break;
|
||||
case Zint8: *(int8_t*)attr_address = ival32; break;
|
||||
case Zint16: *(int16_t*)attr_address = ival32; break;
|
||||
case Zint32: *(int32_t*)attr_address = ival32; break;
|
||||
}
|
||||
} else if (conv_data_type != Z_Data_Type::Z_Unknown) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "attribute %s is wrong type %d (expected %d)"), attr.getStr(), (uint8_t)data_type, (uint8_t)conv_data_type);
|
||||
}
|
||||
}
|
||||
} else if (conv_data_type != Z_Data_Type::Z_Unknown) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "attribute %s is wrong type %d (expected %d)"), attr.getStr(), (uint8_t)data_type, (uint8_t)conv_data_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Import specific attributes that are not handled with the generic method
|
||||
switch (data_type) {
|
||||
// case Z_Data_Type::Z_Plug:
|
||||
// {
|
||||
// Z_Data_Plug & plug = (Z_Data_Plug&) data;
|
||||
// }
|
||||
// break;
|
||||
// case Z_Data_Type::Z_Light:
|
||||
// {
|
||||
// Z_Data_Light & light = (Z_Data_Light&) data;
|
||||
// }
|
||||
// break;
|
||||
case Z_Data_Type::Z_OnOff:
|
||||
{
|
||||
Z_Data_OnOff & onoff = (Z_Data_OnOff&) data;
|
||||
// Import specific attributes that are not handled with the generic method
|
||||
switch (data_type) {
|
||||
// case Z_Data_Type::Z_Plug:
|
||||
// {
|
||||
// Z_Data_Plug & plug = (Z_Data_Plug&) data;
|
||||
// }
|
||||
// break;
|
||||
// case Z_Data_Type::Z_Light:
|
||||
// {
|
||||
// Z_Data_Light & light = (Z_Data_Light&) data;
|
||||
// }
|
||||
// break;
|
||||
case Z_Data_Type::Z_OnOff:
|
||||
{
|
||||
Z_Data_OnOff & onoff = (Z_Data_OnOff&) data;
|
||||
|
||||
if (val = data_values[PSTR("Power")]) { onoff.setPower(val.getUInt() ? true : false); }
|
||||
if (val = data_values[PSTR("Power")]) { onoff.setPower(val.getUInt() ? true : false); }
|
||||
}
|
||||
break;
|
||||
// case Z_Data_Type::Z_Thermo:
|
||||
// {
|
||||
// Z_Data_Thermo & thermo = (Z_Data_Thermo&) data;
|
||||
// }
|
||||
// break;
|
||||
// case Z_Data_Type::Z_Alarm:
|
||||
// {
|
||||
// Z_Data_Alarm & alarm = (Z_Data_Alarm&) data;
|
||||
// }
|
||||
// break;
|
||||
}
|
||||
break;
|
||||
// case Z_Data_Type::Z_Thermo:
|
||||
// {
|
||||
// Z_Data_Thermo & thermo = (Z_Data_Thermo&) data;
|
||||
// }
|
||||
// break;
|
||||
// case Z_Data_Type::Z_Alarm:
|
||||
// {
|
||||
// Z_Data_Alarm & alarm = (Z_Data_Alarm&) data;
|
||||
// }
|
||||
// break;
|
||||
case Z_Data_Type::Z_Device:
|
||||
{
|
||||
if (val = data_values[PSTR(D_CMND_ZIGBEE_LINKQUALITY)]) { device.lqi = val.getUInt(); }
|
||||
if (val = data_values[PSTR("BatteryPercentage")]) { device.batterypercent = val.getUInt(); }
|
||||
if (val = data_values[PSTR("LastSeen")]) { device.last_seen = val.getUInt(); }
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -1440,6 +1512,7 @@ void CmndZbData(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
zigbee_devices.dirty(); // save to flash
|
||||
ResponseCmndDone();
|
||||
} else {
|
||||
// non-JSON, export current data
|
||||
@ -1454,56 +1527,42 @@ void CmndZbData(void) {
|
||||
{ // scope to force object deallocation
|
||||
Z_attribute_list device_attr;
|
||||
device.toAttributes(device_attr);
|
||||
attr_data.addAttribute(F("_00")).setStrRaw(device_attr.toString(true).c_str());
|
||||
attr_data.addAttribute(F("_")).setStrRaw(device_attr.toString(true).c_str());
|
||||
}
|
||||
|
||||
// Iterate on data objects
|
||||
for (auto & data_elt : device.data) {
|
||||
Z_attribute_list inner_attr;
|
||||
char key[4];
|
||||
snprintf_P(key, sizeof(key), "?%02X", data_elt.getEndpoint());
|
||||
// The key is in the form "L01", where 'L' is the type and '01' the endpoint in hex format
|
||||
// 'P' = Power
|
||||
// 'L' = Light
|
||||
// 'O' = OnOff
|
||||
// 'T' = Thermo & sensors
|
||||
// 'A' = Alarm
|
||||
// '?' = Device wide
|
||||
//
|
||||
char key[8];
|
||||
if (data_elt.validConfig()) {
|
||||
snprintf_P(key, sizeof(key), "?%02X.%1X", data_elt.getEndpoint(), data_elt.getConfig());
|
||||
} else {
|
||||
snprintf_P(key, sizeof(key), "?%02X", data_elt.getEndpoint());
|
||||
}
|
||||
|
||||
Z_Data_Type data_type = data_elt.getType();
|
||||
key[0] = Z_Data::DataTypeToChar(data_type);
|
||||
switch (data_type) {
|
||||
case Z_Data_Type::Z_Plug:
|
||||
{
|
||||
key[0] = 'P';
|
||||
((Z_Data_Plug&)data_elt).toAttributes(inner_attr, data_type);
|
||||
}
|
||||
((Z_Data_Plug&)data_elt).toAttributes(inner_attr, data_type);
|
||||
break;
|
||||
case Z_Data_Type::Z_Light:
|
||||
{
|
||||
key[0] = 'L';
|
||||
((Z_Data_Light&)data_elt).toAttributes(inner_attr, data_type);
|
||||
}
|
||||
((Z_Data_Light&)data_elt).toAttributes(inner_attr, data_type);
|
||||
break;
|
||||
case Z_Data_Type::Z_OnOff:
|
||||
{
|
||||
key[0] = 'O';
|
||||
((Z_Data_OnOff&)data_elt).toAttributes(inner_attr, data_type);
|
||||
}
|
||||
((Z_Data_OnOff&)data_elt).toAttributes(inner_attr, data_type);
|
||||
break;
|
||||
case Z_Data_Type::Z_Thermo:
|
||||
{
|
||||
key[0] = 'T';
|
||||
((Z_Data_Thermo&)data_elt).toAttributes(inner_attr, data_type);
|
||||
}
|
||||
((Z_Data_Thermo&)data_elt).toAttributes(inner_attr, data_type);
|
||||
break;
|
||||
case Z_Data_Type::Z_Alarm:
|
||||
{
|
||||
key[0] = 'A';
|
||||
((Z_Data_Alarm&)data_elt).toAttributes(inner_attr, data_type);
|
||||
}
|
||||
((Z_Data_Alarm&)data_elt).toAttributes(inner_attr, data_type);
|
||||
break;
|
||||
case Z_Data_Type::Z_PIR:
|
||||
((Z_Data_PIR&)data_elt).toAttributes(inner_attr, data_type);
|
||||
break;
|
||||
}
|
||||
if (key[0] != '?') {
|
||||
if ((key[0] != '\0') && (key[0] != '?')) {
|
||||
attr_data.addAttribute(key).setStrRaw(inner_attr.toString(true).c_str());
|
||||
}
|
||||
}
|
||||
@ -1564,7 +1623,7 @@ void CmndZbConfig(void) {
|
||||
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
|
||||
TasmotaGlobal.restart_flag = 2; // save and reboot
|
||||
}
|
||||
}
|
||||
|
||||
@ -1710,10 +1769,13 @@ void ZigbeeShow(bool json)
|
||||
|
||||
WSContentSend_PD(PSTR(
|
||||
"<tr class='ztd htr'>"
|
||||
"<td><b>%s</b></td>" // name
|
||||
"<td><b title='0x%04X %s - %s'>%s</b></td>" // name
|
||||
"<td>%s</td>" // sbatt (Battery Indicator)
|
||||
"<td><div title='" D_LQI " %s' class='ssi'>" // slqi
|
||||
), name, sbatt, slqi);
|
||||
), shortaddr,
|
||||
device.modelId ? device.modelId : "",
|
||||
device.manufacturerId ? device.manufacturerId : "",
|
||||
name, sbatt, slqi);
|
||||
|
||||
if(device.validLqi()) {
|
||||
for(uint32_t j = 0; j < 4; ++j) {
|
||||
@ -1736,28 +1798,36 @@ void ZigbeeShow(bool json)
|
||||
const Z_Data_Thermo & thermo = device.data.find<Z_Data_Thermo>();
|
||||
|
||||
if (&thermo != nullptr) {
|
||||
WSContentSend_P(PSTR("<tr class='htr'><td colspan=\"4\">┆"));
|
||||
if (thermo.validTemperature()) {
|
||||
char buf[12];
|
||||
dtostrf(thermo.getTemperature() / 100.0f, 3, 1, buf);
|
||||
WSContentSend_PD(PSTR(" ☀️ %s°C"), buf);
|
||||
}
|
||||
if (thermo.validTempTarget()) {
|
||||
char buf[12];
|
||||
dtostrf(thermo.getTempTarget() / 100.0f, 3, 1, buf);
|
||||
WSContentSend_PD(PSTR(" 🎯 %s°C"), buf);
|
||||
}
|
||||
if (thermo.validThSetpoint()) {
|
||||
WSContentSend_PD(PSTR(" ⚙️ %d%%"), thermo.getThSetpoint());
|
||||
}
|
||||
if (thermo.validHumidity()) {
|
||||
WSContentSend_P(PSTR(" 💧 %d%%"), (uint16_t)(thermo.getHumidity() / 100.0f + 0.5f));
|
||||
}
|
||||
if (thermo.validPressure()) {
|
||||
WSContentSend_P(PSTR(" ⛅ %d hPa"), thermo.getPressure());
|
||||
}
|
||||
bool validTemp = thermo.validTemperature();
|
||||
bool validTempTarget = thermo.validTempTarget();
|
||||
bool validThSetpoint = thermo.validThSetpoint();
|
||||
bool validHumidity = thermo.validHumidity();
|
||||
bool validPressure = thermo.validPressure();
|
||||
|
||||
WSContentSend_P(PSTR("{e}"));
|
||||
if (validTemp || validTempTarget || validThSetpoint || validHumidity || validPressure) {
|
||||
WSContentSend_P(PSTR("<tr class='htr'><td colspan=\"4\">┆"));
|
||||
if (validTemp) {
|
||||
char buf[12];
|
||||
dtostrf(thermo.getTemperature() / 100.0f, 3, 1, buf);
|
||||
WSContentSend_PD(PSTR(" ☀️ %s°C"), buf);
|
||||
}
|
||||
if (validTempTarget) {
|
||||
char buf[12];
|
||||
dtostrf(thermo.getTempTarget() / 100.0f, 3, 1, buf);
|
||||
WSContentSend_PD(PSTR(" 🎯 %s°C"), buf);
|
||||
}
|
||||
if (validThSetpoint) {
|
||||
WSContentSend_PD(PSTR(" ⚙️ %d%%"), thermo.getThSetpoint());
|
||||
}
|
||||
if (validHumidity) {
|
||||
WSContentSend_P(PSTR(" 💧 %d%%"), (uint16_t)(thermo.getHumidity() / 100.0f + 0.5f));
|
||||
}
|
||||
if (validPressure) {
|
||||
WSContentSend_P(PSTR(" ⛅ %d hPa"), thermo.getPressure());
|
||||
}
|
||||
|
||||
WSContentSend_P(PSTR("{e}"));
|
||||
}
|
||||
}
|
||||
|
||||
// Light, switches and plugs
|
||||
@ -1792,12 +1862,16 @@ void ZigbeeShow(bool json)
|
||||
}
|
||||
}
|
||||
if (&plug != nullptr) {
|
||||
WSContentSend_P(PSTR(" ⚡ "));
|
||||
if (plug.validMainsVoltage()) {
|
||||
WSContentSend_P(PSTR(" %dV"), plug.getMainsVoltage());
|
||||
}
|
||||
if (plug.validMainsPower()) {
|
||||
WSContentSend_P(PSTR(" %dW"), plug.getMainsPower());
|
||||
bool validMainsVoltage = plug.validMainsVoltage();
|
||||
bool validMainsPower = plug.validMainsPower();
|
||||
if (validMainsVoltage || validMainsPower) {
|
||||
WSContentSend_P(PSTR(" ⚡ "));
|
||||
if (validMainsVoltage) {
|
||||
WSContentSend_P(PSTR(" %dV"), plug.getMainsVoltage());
|
||||
}
|
||||
if (validMainsPower) {
|
||||
WSContentSend_P(PSTR(" %dW"), plug.getMainsPower());
|
||||
}
|
||||
}
|
||||
}
|
||||
WSContentSend_P(PSTR("{e}"));
|
||||
|
||||
@ -53,7 +53,7 @@ void BuzzerSet(uint8_t state)
|
||||
analogWrite(Pin(GPIO_BUZZER, 0), Settings.pwm_range / 2); // set 50% duty cycle for frequency output
|
||||
}
|
||||
else {
|
||||
analogWrite(Pin(GPIO_BUZZER, 0), 0); // set 0% (or 100% for inverted PWM) duty cycle which turns off frequency output either way
|
||||
analogWrite(Pin(GPIO_BUZZER, 0), 0); // set 0% (or 100% for inverted PWM) duty cycle which turns off frequency output either way
|
||||
}
|
||||
last_state = state;
|
||||
}
|
||||
@ -61,7 +61,7 @@ void BuzzerSet(uint8_t state)
|
||||
else {
|
||||
DigitalWrite(GPIO_BUZZER, 0, state); // Buzzer On/Off
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//void BuzzerBeep(uint32_t count = 1, uint32_t on = 1, uint32_t off = 1, uint32_t tune = 0, uint32_t mode = 0);
|
||||
@ -101,14 +101,14 @@ void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune, uint32
|
||||
|
||||
Buzzer.enable = (Buzzer.count > 0);
|
||||
if (Buzzer.enable) {
|
||||
if (Settings.sleep > PWM_MAX_SLEEP) {
|
||||
ssleep = PWM_MAX_SLEEP; // set a maxumum value of 10 milliseconds to ensure that buzzer periods are a bit more accurate
|
||||
} else {
|
||||
ssleep = Settings.sleep; // or keep the current sleep if it's lower than 10
|
||||
}
|
||||
if (Settings.sleep > PWM_MAX_SLEEP) {
|
||||
TasmotaGlobal.sleep = PWM_MAX_SLEEP; // set a maxumum value of 10 milliseconds to ensure that buzzer periods are a bit more accurate
|
||||
} else {
|
||||
TasmotaGlobal.sleep = Settings.sleep; // or keep the current sleep if it's lower than 10
|
||||
}
|
||||
}
|
||||
else {
|
||||
ssleep = Settings.sleep; // restore original sleep
|
||||
TasmotaGlobal.sleep = Settings.sleep; // restore original sleep
|
||||
BuzzerSet(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,10 +146,9 @@ void AriluxRfHandler(void)
|
||||
void AriluxRfInit(void)
|
||||
{
|
||||
if (PinUsed(GPIO_ARIRFRCV) && PinUsed(GPIO_ARIRFSEL)) {
|
||||
if (Settings.last_module != Settings.module) {
|
||||
if (TasmotaGlobal.module_changed) {
|
||||
Settings.rf_code[1][6] = 0;
|
||||
Settings.rf_code[1][7] = 0;
|
||||
Settings.last_module = Settings.module;
|
||||
}
|
||||
Arilux.rf_received_value = 0;
|
||||
|
||||
@ -179,7 +178,7 @@ bool Xdrv26(uint8_t function)
|
||||
if (PinUsed(GPIO_ARIRFRCV)) { AriluxRfHandler(); }
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
if (10 == uptime) { AriluxRfInit(); } // Needs rest before enabling RF interrupts
|
||||
if (10 == TasmotaGlobal.uptime) { AriluxRfInit(); } // Needs rest before enabling RF interrupts
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -114,7 +114,7 @@ void ShutterLogPos(uint32_t i)
|
||||
void ExecuteCommandPowerShutter(uint32_t device, uint32_t state, uint32_t source)
|
||||
{
|
||||
// first implementation for virtual relays. Avoid switching relay numbers that do not exist.
|
||||
if (device <= devices_present) ExecuteCommandPower(device,state,source);
|
||||
if (device <= TasmotaGlobal.devices_present) ExecuteCommandPower(device,state,source);
|
||||
}
|
||||
|
||||
void ShutterUpdateVelocity(uint8_t i)
|
||||
@ -128,7 +128,7 @@ void ShutterUpdateVelocity(uint8_t i)
|
||||
void ShutterRtc50mS(void)
|
||||
{
|
||||
// No Logging allowed. RTC Timer
|
||||
for (uint8_t i = 0; i < shutters_present; i++) {
|
||||
for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
if (Shutter[i].direction) {
|
||||
// update position data before increasing counter
|
||||
Shutter[i].real_position = ShutterCalculatePosition(i);
|
||||
@ -218,10 +218,10 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index)
|
||||
|
||||
void ShutterInit(void)
|
||||
{
|
||||
shutters_present = 0;
|
||||
TasmotaGlobal.shutters_present = 0;
|
||||
ShutterGlobal.RelayShutterMask = 0;
|
||||
//Initialize to get relay that changed
|
||||
ShutterGlobal.RelayOldMask = power;
|
||||
ShutterGlobal.RelayOldMask = TasmotaGlobal.power;
|
||||
|
||||
|
||||
// if shutter 4 is unused
|
||||
@ -232,7 +232,7 @@ void ShutterInit(void)
|
||||
// set startrelay to 1 on first init, but only to shutter 1. 90% usecase
|
||||
Settings.shutter_startrelay[i] = (Settings.shutter_startrelay[i] == 0 && i == 0? 1 : Settings.shutter_startrelay[i]);
|
||||
if (Settings.shutter_startrelay[i] && (Settings.shutter_startrelay[i] < 9)) {
|
||||
shutters_present++;
|
||||
TasmotaGlobal.shutters_present++;
|
||||
|
||||
// Add the two relays to the mask to knaw they belong to shutters
|
||||
ShutterGlobal.RelayShutterMask |= 3 << (Settings.shutter_startrelay[i] -1) ;
|
||||
@ -328,9 +328,9 @@ void ShutterInit(void)
|
||||
void ShutterReportPosition(bool always, uint32_t index)
|
||||
{
|
||||
Response_P(PSTR("{"));
|
||||
rules_flag.shutter_moving = 0;
|
||||
TasmotaGlobal.rules_flag.shutter_moving = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t n = shutters_present;
|
||||
uint32_t n = TasmotaGlobal.shutters_present;
|
||||
if( index != MAX_SHUTTERS) {
|
||||
i = index;
|
||||
n = index+1;
|
||||
@ -339,7 +339,7 @@ void ShutterReportPosition(bool always, uint32_t index)
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Real Pos: %d"), i+1,Shutter[i].real_position);
|
||||
uint32_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i);
|
||||
if (Shutter[i].direction != 0) {
|
||||
rules_flag.shutter_moving = 1;
|
||||
TasmotaGlobal.rules_flag.shutter_moving = 1;
|
||||
ShutterLogPos(i);
|
||||
}
|
||||
if (i && index == MAX_SHUTTERS) { ResponseAppend_P(PSTR(",")); }
|
||||
@ -347,10 +347,10 @@ void ShutterReportPosition(bool always, uint32_t index)
|
||||
ResponseAppend_P(JSON_SHUTTER_POS, i+1, (Settings.shutter_options[i] & 1) ? 100-position : position, Shutter[i].direction,(Settings.shutter_options[i] & 1) ? 100-target : target );
|
||||
}
|
||||
ResponseJsonEnd();
|
||||
if (always || (rules_flag.shutter_moving)) {
|
||||
if (always || (TasmotaGlobal.rules_flag.shutter_moving)) {
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); // RulesProcess() now re-entry protected
|
||||
}
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, 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: TasmotaGlobal.rules_flag.shutter_moving: %d, moved %d"), TasmotaGlobal.rules_flag.shutter_moving, TasmotaGlobal.rules_flag.shutter_moved);
|
||||
}
|
||||
|
||||
void ShutterLimitRealAndTargetPositions(uint32_t i) {
|
||||
@ -436,24 +436,24 @@ void ShutterPowerOff(uint8_t i) {
|
||||
}
|
||||
switch (Shutter[i].switch_mode) {
|
||||
case SHT_SWITCH:
|
||||
if ((1 << (Settings.shutter_startrelay[i]-1)) & power) {
|
||||
if ((1 << (Settings.shutter_startrelay[i]-1)) & TasmotaGlobal.power) {
|
||||
ExecuteCommandPowerShutter(Settings.shutter_startrelay[i], 0, SRC_SHUTTER);
|
||||
}
|
||||
if ((1 << (Settings.shutter_startrelay[i])) & power) {
|
||||
if ((1 << (Settings.shutter_startrelay[i])) & TasmotaGlobal.power) {
|
||||
ExecuteCommandPowerShutter(Settings.shutter_startrelay[i]+1, 0, SRC_SHUTTER);
|
||||
}
|
||||
break;
|
||||
case SHT_PULSE:
|
||||
uint8_t cur_relay = Settings.shutter_startrelay[i] + (Shutter[i].direction == 1 ? 0 : (uint8_t)(ShutterGlobal.position_mode == SHT_TIME)) ;
|
||||
// we have a momentary switch here. Needs additional pulse on same relay after the end
|
||||
if ((SRC_PULSETIMER == last_source || SRC_SHUTTER == last_source || SRC_WEBGUI == last_source)) {
|
||||
if ((SRC_PULSETIMER == TasmotaGlobal.last_source || SRC_SHUTTER == TasmotaGlobal.last_source || SRC_WEBGUI == TasmotaGlobal.last_source)) {
|
||||
ExecuteCommandPowerShutter(cur_relay, 1, SRC_SHUTTER);
|
||||
// switch off direction relay to make it power less
|
||||
if ((1 << (Settings.shutter_startrelay[i])) & power) {
|
||||
if ((1 << (Settings.shutter_startrelay[i])) & TasmotaGlobal.power) {
|
||||
ExecuteCommandPowerShutter(Settings.shutter_startrelay[i]+1, 0, SRC_SHUTTER);
|
||||
}
|
||||
} else {
|
||||
last_source = SRC_SHUTTER;
|
||||
TasmotaGlobal.last_source = SRC_SHUTTER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -472,7 +472,7 @@ void ShutterUpdatePosition(void)
|
||||
|
||||
char scommand[CMDSZ];
|
||||
char stopic[TOPSZ];
|
||||
for (uint32_t i = 0; i < shutters_present; i++) {
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
if (Shutter[i].direction != 0) {
|
||||
if (!ShutterGlobal.start_reported) {
|
||||
ShutterReportPosition(true, i);
|
||||
@ -496,11 +496,11 @@ void ShutterUpdatePosition(void)
|
||||
|
||||
// sending MQTT result to broker
|
||||
snprintf_P(scommand, sizeof(scommand),PSTR(D_SHUTTER "%d"), i+1);
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
|
||||
GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, scommand);
|
||||
Response_P("%d", (Settings.shutter_options[i] & 1) ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i]);
|
||||
MqttPublish(stopic, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN
|
||||
ShutterReportPosition(true, i);
|
||||
rules_flag.shutter_moved = 1;
|
||||
TasmotaGlobal.rules_flag.shutter_moved = 1;
|
||||
XdrvRulesProcess();
|
||||
}
|
||||
}
|
||||
@ -520,10 +520,10 @@ void ShutterAllowPreStartProcedure(uint8_t i)
|
||||
#ifdef USE_RULES
|
||||
uint32_t uptime_Local=0;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay Start. var%d <99>=<%s>, max10s?"),i+i, rules_vars[i]);
|
||||
rules_flag.shutter_moving = 1;
|
||||
TasmotaGlobal.rules_flag.shutter_moving = 1;
|
||||
XdrvRulesProcess();
|
||||
uptime_Local = uptime;
|
||||
while (uptime_Local+10 > uptime && (String)rules_vars[i] == "99") {
|
||||
uptime_Local = TasmotaGlobal.uptime;
|
||||
while (uptime_Local+10 > TasmotaGlobal.uptime && (String)rules_vars[i] == "99") {
|
||||
loop();
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay Start. Done"));
|
||||
@ -550,12 +550,12 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos)
|
||||
Shutter[i].accelerator = ShutterGlobal.open_velocity_max / (Shutter[i].motordelay>0 ? Shutter[i].motordelay : 1);
|
||||
Shutter[i].target_position = target_pos;
|
||||
Shutter[i].start_position = Shutter[i].real_position;
|
||||
rules_flag.shutter_moving = 1;
|
||||
TasmotaGlobal.rules_flag.shutter_moving = 1;
|
||||
ShutterAllowPreStartProcedure(i);
|
||||
Shutter[i].time = 0;
|
||||
Shutter[i].direction = direction;
|
||||
ShutterGlobal.skip_relay_change = 0;
|
||||
rules_flag.shutter_moved = 0;
|
||||
TasmotaGlobal.rules_flag.shutter_moved = 0;
|
||||
ShutterGlobal.start_reported = 0;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: real %d, start %d, counter %d,freq_max %d, dir %d, freq %d"),Shutter[i].real_position, Shutter[i].start_position ,RtcSettings.pulse_counter[i],ShutterGlobal.open_velocity_max , Shutter[i].direction ,ShutterGlobal.open_velocity_max );
|
||||
}
|
||||
@ -596,12 +596,12 @@ void ShutterRelayChanged(void)
|
||||
// relays_changed = bool if one of the relays that belong to the shutter changed not by shutter or pulsetimer
|
||||
char stemp1[10];
|
||||
|
||||
for (uint32_t i = 0; i < shutters_present; i++) {
|
||||
power_t powerstate_local = (power >> (Settings.shutter_startrelay[i] -1)) & 3;
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
power_t powerstate_local = (TasmotaGlobal.power >> (Settings.shutter_startrelay[i] -1)) & 3;
|
||||
// SRC_IGNORE added because INTERLOCK function bite causes this as last source for changing the relay.
|
||||
//uint8 manual_relays_changed = ((ShutterGlobal.RelayCurrentMask >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_IGNORE != last_source && SRC_SHUTTER != last_source && SRC_PULSETIMER != last_source ;
|
||||
uint8 manual_relays_changed = ((ShutterGlobal.RelayCurrentMask >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_SHUTTER != last_source && SRC_PULSETIMER != last_source ;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: source: %s, powerstate_local %ld, ShutterGlobal.RelayCurrentMask %d, manual change %d"), i+1, GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed);
|
||||
//uint8 manual_relays_changed = ((ShutterGlobal.RelayCurrentMask >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_IGNORE != TasmotaGlobal.last_source && SRC_SHUTTER != TasmotaGlobal.last_source && SRC_PULSETIMER != TasmotaGlobal.last_source ;
|
||||
uint8 manual_relays_changed = ((ShutterGlobal.RelayCurrentMask >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_SHUTTER != TasmotaGlobal.last_source && SRC_PULSETIMER != TasmotaGlobal.last_source ;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: source: %s, powerstate_local %ld, ShutterGlobal.RelayCurrentMask %d, manual change %d"), i+1, GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed);
|
||||
if (manual_relays_changed) {
|
||||
//ShutterGlobal.skip_relay_change = true;
|
||||
ShutterLimitRealAndTargetPositions(i);
|
||||
@ -610,11 +610,11 @@ void ShutterRelayChanged(void)
|
||||
if (Shutter[i].direction != 0 && powerstate_local) {
|
||||
Shutter[i].target_position = Shutter[i].real_position;
|
||||
powerstate_local = 0;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor. Target: %ld, source: %s, powerstate_local %ld, ShutterGlobal.RelayCurrentMask %d, manual change %d"), i+1, Shutter[i].target_position, GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor. Target: %ld, source: %s, powerstate_local %ld, ShutterGlobal.RelayCurrentMask %d, manual change %d"), i+1, Shutter[i].target_position, GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
last_source = SRC_SHUTTER; // avoid switch off in the next loop
|
||||
TasmotaGlobal.last_source = SRC_SHUTTER; // avoid switch off in the next loop
|
||||
if (Shutter[i].direction != 0 ) ShutterPowerOff(i);
|
||||
}
|
||||
switch (ShutterGlobal.position_mode) {
|
||||
@ -663,7 +663,7 @@ void ShutterRelayChanged(void)
|
||||
} // switch (ShutterGlobal.position_mode)
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Target: %ld, powerstatelocal %d"), i+1, Shutter[i].target_position, powerstate_local);
|
||||
} // if (manual_relays_changed)
|
||||
} // for (uint32_t i = 0; i < shutters_present; i++)
|
||||
} // for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++)
|
||||
}
|
||||
|
||||
bool ShutterButtonIsSimultaneousHold(uint32_t button_index, uint32_t shutter_index) {
|
||||
@ -700,7 +700,7 @@ void ShutterButtonHandler(void)
|
||||
Button.window_timer[button_index] = (loops_per_second >> 2) * 3; // 0.75 second multi press window
|
||||
}
|
||||
}
|
||||
blinks = 201;
|
||||
TasmotaGlobal.blinks = 201;
|
||||
}
|
||||
|
||||
if (NOT_PRESSED == button) {
|
||||
@ -747,7 +747,7 @@ void ShutterButtonHandler(void)
|
||||
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)) {
|
||||
if (!TasmotaGlobal.restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0)) {
|
||||
if (Button.press_counter[button_index]<99) {
|
||||
// check for simultaneous shutter button press
|
||||
uint32 min_shutterbutton_press_counter = -1; // -1 == max(uint32)
|
||||
@ -809,7 +809,7 @@ void ShutterButtonHandler(void)
|
||||
if (pos_press_index>3) pos_press_index=3;
|
||||
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;
|
||||
TasmotaGlobal.last_source = SRC_BUTTON;
|
||||
XdrvMailbox.data_len = 0;
|
||||
char databuf[1] = "";
|
||||
XdrvMailbox.data = databuf;
|
||||
@ -870,7 +870,7 @@ void ShutterToggle(bool dir)
|
||||
if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) {
|
||||
XdrvMailbox.index = XdrvMailbox.payload;
|
||||
}
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
uint32_t index = XdrvMailbox.index-1;
|
||||
if (dir) {
|
||||
XdrvMailbox.payload = (Shutter[index].lastdirection > 0) ? 0 : 100;
|
||||
@ -879,7 +879,7 @@ void ShutterToggle(bool dir)
|
||||
XdrvMailbox.payload = (50 < ShutterRealToPercentPosition(Shutter[index].real_position, index)) ? 0 : 100;
|
||||
}
|
||||
XdrvMailbox.data_len = 0;
|
||||
last_source = SRC_WEBGUI;
|
||||
TasmotaGlobal.last_source = SRC_WEBGUI;
|
||||
CmndShutterPosition();
|
||||
}
|
||||
}
|
||||
@ -895,13 +895,13 @@ void CmndShutterOpen(void)
|
||||
XdrvMailbox.index = XdrvMailbox.payload;
|
||||
}
|
||||
XdrvMailbox.payload = 100;
|
||||
last_source = SRC_WEBGUI;
|
||||
TasmotaGlobal.last_source = SRC_WEBGUI;
|
||||
CmndShutterPosition();
|
||||
}
|
||||
|
||||
void CmndShutterStopOpen(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
uint32_t index = XdrvMailbox.index-1;
|
||||
if (Shutter[index].direction) {
|
||||
CmndShutterStop();
|
||||
@ -919,13 +919,13 @@ void CmndShutterClose(void)
|
||||
}
|
||||
XdrvMailbox.payload = 0;
|
||||
XdrvMailbox.data_len = 0;
|
||||
last_source = SRC_WEBGUI;
|
||||
TasmotaGlobal.last_source = SRC_WEBGUI;
|
||||
CmndShutterPosition();
|
||||
}
|
||||
|
||||
void CmndShutterStopClose(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
uint32_t index = XdrvMailbox.index-1;
|
||||
if (Shutter[index].direction) {
|
||||
CmndShutterStop();
|
||||
@ -947,7 +947,7 @@ void CmndShutterToggleDir(void)
|
||||
|
||||
void CmndShutterStopToggle(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
uint32_t index = XdrvMailbox.index-1;
|
||||
if (Shutter[index].direction) {
|
||||
CmndShutterStop();
|
||||
@ -959,7 +959,7 @@ void CmndShutterStopToggle(void)
|
||||
|
||||
void CmndShutterStopToggleDir(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
uint32_t index = XdrvMailbox.index-1;
|
||||
if (Shutter[index].direction) {
|
||||
CmndShutterStop();
|
||||
@ -971,7 +971,7 @@ void CmndShutterStopToggleDir(void)
|
||||
|
||||
void CmndShutterStop(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (!(Settings.shutter_options[XdrvMailbox.index-1] & 2)) {
|
||||
if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) {
|
||||
XdrvMailbox.index = XdrvMailbox.payload;
|
||||
@ -983,7 +983,7 @@ void CmndShutterStop(void)
|
||||
|
||||
int32_t temp_realpos = ShutterCalculatePosition(i);
|
||||
XdrvMailbox.payload = ShutterRealToPercentPosition(temp_realpos, i);
|
||||
last_source = SRC_WEBGUI;
|
||||
TasmotaGlobal.last_source = SRC_WEBGUI;
|
||||
CmndShutterPosition();
|
||||
} else {
|
||||
if (XdrvMailbox.command)
|
||||
@ -998,8 +998,8 @@ void CmndShutterStop(void)
|
||||
|
||||
void CmndShutterIncDec(void)
|
||||
{
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Change in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, last_source );
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Change in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, TasmotaGlobal.last_source );
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
XdrvMailbox.payload = ShutterRealToPercentPosition(Shutter[XdrvMailbox.index-1].target_position, XdrvMailbox.index-1)+XdrvMailbox.payload;
|
||||
// limit position to boundaries
|
||||
@ -1012,11 +1012,11 @@ void CmndShutterIncDec(void)
|
||||
|
||||
void CmndShutterPosition(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (!(Settings.shutter_options[XdrvMailbox.index-1] & 2)) {
|
||||
uint32_t index = XdrvMailbox.index-1;
|
||||
//limit the payload
|
||||
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 );
|
||||
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, TasmotaGlobal.last_source );
|
||||
|
||||
// value 0 with data_len > 0 can mean Open
|
||||
// special handling fo UP,DOWN,TOGGLE,STOP command comming with payload -99
|
||||
@ -1047,13 +1047,13 @@ void CmndShutterPosition(void)
|
||||
|
||||
int8_t target_pos_percent = (XdrvMailbox.payload < 0) ? (XdrvMailbox.payload == -99 ? ShutterRealToPercentPosition(Shutter[index].real_position, index) : 0) : ((XdrvMailbox.payload > 100) ? 100 : XdrvMailbox.payload);
|
||||
// webgui still send also on inverted shutter the native position.
|
||||
target_pos_percent = ((Settings.shutter_options[index] & 1) && (SRC_WEBGUI != last_source)) ? 100 - target_pos_percent : target_pos_percent;
|
||||
target_pos_percent = ((Settings.shutter_options[index] & 1) && (SRC_WEBGUI != TasmotaGlobal.last_source)) ? 100 - target_pos_percent : target_pos_percent;
|
||||
if (XdrvMailbox.payload != -99) {
|
||||
//target_pos_percent = (Settings.shutter_options[index] & 1) ? 100 - target_pos_percent : target_pos_percent;
|
||||
Shutter[index].target_position = ShutterPercentToRealPosition(target_pos_percent, index);
|
||||
//Shutter[i].accelerator[index] = ShutterGlobal.open_velocity_max / ((Shutter[i].motordelay[index] > 0) ? Shutter[i].motordelay[index] : 1);
|
||||
//Shutter[i].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_MORE, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), last_source, Shutter[index].real_position ,Shutter[index].target_position,target_pos_percent);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), TasmotaGlobal.last_source, Shutter[index].real_position ,Shutter[index].target_position,target_pos_percent);
|
||||
}
|
||||
if ( (target_pos_percent >= 0) && (target_pos_percent <= 100) && abs(Shutter[index].target_position - Shutter[index].real_position ) / Shutter[index].close_velocity > 2) {
|
||||
if (Settings.shutter_options[index] & 4) {
|
||||
@ -1081,7 +1081,7 @@ void CmndShutterPosition(void)
|
||||
break;
|
||||
case SHT_TIME:
|
||||
if (!ShutterGlobal.skip_relay_change) {
|
||||
if ( (power >> (Settings.shutter_startrelay[index] -1)) & 3 > 0 ) {
|
||||
if ( (TasmotaGlobal.power >> (Settings.shutter_startrelay[index] -1)) & 3 > 0 ) {
|
||||
ExecuteCommandPowerShutter(Settings.shutter_startrelay[index] + (new_shutterdirection == 1 ? 1 : 0), Shutter[index].switch_mode == SHT_SWITCH ? 0 : 1, SRC_SHUTTER);
|
||||
}
|
||||
ExecuteCommandPowerShutter(Settings.shutter_startrelay[index] + (new_shutterdirection == 1 ? 0 : 1), 1, SRC_SHUTTER);
|
||||
@ -1123,7 +1123,7 @@ void CmndShutterPosition(void)
|
||||
|
||||
void CmndShutterStopPosition(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
uint32_t index = XdrvMailbox.index-1;
|
||||
if (Shutter[index].direction) {
|
||||
XdrvMailbox.payload = -99;
|
||||
@ -1135,7 +1135,7 @@ void CmndShutterStopPosition(void)
|
||||
}
|
||||
void CmndShutterOpenTime(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
Settings.shutter_opentime[XdrvMailbox.index -1] = (uint16_t)(10 * CharToFloat(XdrvMailbox.data));
|
||||
ShutterInit();
|
||||
@ -1148,7 +1148,7 @@ void CmndShutterOpenTime(void)
|
||||
|
||||
void CmndShutterCloseTime(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
Settings.shutter_closetime[XdrvMailbox.index -1] = (uint16_t)(10 * CharToFloat(XdrvMailbox.data));
|
||||
ShutterInit();
|
||||
@ -1161,7 +1161,7 @@ void CmndShutterCloseTime(void)
|
||||
|
||||
void CmndShutterMotorDelay(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
Settings.shutter_motordelay[XdrvMailbox.index -1] = (uint16_t)(STEPS_PER_SECOND * CharToFloat(XdrvMailbox.data));
|
||||
ShutterInit();
|
||||
@ -1339,9 +1339,10 @@ void CmndShutterButton(void)
|
||||
|
||||
void CmndShutterSetHalfway(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
||||
Settings.shutter_set50percent[XdrvMailbox.index -1] = (Settings.shutter_options[XdrvMailbox.index -1] & 1) ? 100 - XdrvMailbox.payload : XdrvMailbox.payload;
|
||||
Settings.shuttercoeff[0][XdrvMailbox.index -1] = 0;
|
||||
ShutterInit();
|
||||
}
|
||||
ResponseCmndIdxNumber((Settings.shutter_options[XdrvMailbox.index -1] & 1) ? 100 - Settings.shutter_set50percent[XdrvMailbox.index -1] : Settings.shutter_set50percent[XdrvMailbox.index -1]);
|
||||
@ -1352,7 +1353,7 @@ void CmndShutterFrequency(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 20000)) {
|
||||
ShutterGlobal.open_velocity_max = XdrvMailbox.payload;
|
||||
if (shutters_present < 4) {
|
||||
if (TasmotaGlobal.shutters_present < 4) {
|
||||
Settings.shuttercoeff[4][3] = ShutterGlobal.open_velocity_max;
|
||||
}
|
||||
ShutterInit();
|
||||
@ -1362,7 +1363,7 @@ void CmndShutterFrequency(void)
|
||||
|
||||
void CmndShutterSetClose(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
Shutter[XdrvMailbox.index -1].real_position = 0;
|
||||
ShutterStartInit(XdrvMailbox.index -1, 0, 0);
|
||||
Settings.shutter_position[XdrvMailbox.index -1] = 0;
|
||||
@ -1372,7 +1373,7 @@ void CmndShutterSetClose(void)
|
||||
|
||||
void CmndShutterSetOpen(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
Shutter[XdrvMailbox.index -1].real_position = Shutter[XdrvMailbox.index -1].open_max;
|
||||
ShutterStartInit(XdrvMailbox.index -1, 0, Shutter[XdrvMailbox.index -1].open_max);
|
||||
Settings.shutter_position[XdrvMailbox.index -1] = 100;
|
||||
@ -1382,7 +1383,7 @@ void CmndShutterSetOpen(void)
|
||||
|
||||
void CmndShutterPwmRange(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
uint8_t i = 0;
|
||||
char *str_ptr;
|
||||
@ -1412,7 +1413,7 @@ void CmndShutterPwmRange(void)
|
||||
|
||||
void CmndShutterCalibration(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
uint8_t i = 0;
|
||||
char *str_ptr;
|
||||
@ -1429,6 +1430,7 @@ void CmndShutterCalibration(void)
|
||||
}
|
||||
messwerte[i] = field;
|
||||
}
|
||||
Settings.shutter_set50percent[XdrvMailbox.index -1] = 50;
|
||||
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_DEBUG, PSTR("Settings.shuttercoeff: %d, i: %d, value: %d, messwert %d"), i,XdrvMailbox.index -1,Settings.shuttercoeff[i][XdrvMailbox.index -1], messwerte[i]);
|
||||
@ -1444,7 +1446,7 @@ void CmndShutterCalibration(void)
|
||||
}
|
||||
|
||||
void ShutterOptionsSetHelper(uint16_t option){
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) {
|
||||
if (XdrvMailbox.payload == 0) {
|
||||
Settings.shutter_options[XdrvMailbox.index -1] &= ~(option);
|
||||
} else if (XdrvMailbox.payload == 1) {
|
||||
@ -1495,14 +1497,14 @@ bool Xdrv27(uint8_t function)
|
||||
result = DecodeCommand(kShutterCommands, ShutterCommand);
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
for (uint8_t i = 0; i < shutters_present; i++) {
|
||||
for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
uint8_t position = (Settings.shutter_options[i] & 1) ? 100 - Settings.shutter_position[i] : Settings.shutter_position[i];
|
||||
uint8_t target = (Settings.shutter_options[i] & 1) ? 100 - ShutterRealToPercentPosition(Shutter[i].target_position, i) : ShutterRealToPercentPosition(Shutter[i].target_position, i);
|
||||
|
||||
ResponseAppend_P(",");
|
||||
ResponseAppend_P(JSON_SHUTTER_POS, i+1, position, Shutter[i].direction,target);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if ((0 == tele_period) && (0 == i)) {
|
||||
if ((0 == TasmotaGlobal.tele_period) && (0 == i)) {
|
||||
DomoticzSensor(DZ_SHUTTER, position);
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
@ -1512,14 +1514,14 @@ bool Xdrv27(uint8_t function)
|
||||
char stemp1[10];
|
||||
// extract the number of the relay that was switched and save for later in Update Position.
|
||||
ShutterGlobal.RelayCurrentMask = XdrvMailbox.index ^ ShutterGlobal.RelayOldMask;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Switched relay: %d by %s"), ShutterGlobal.RelayCurrentMask,GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource));
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Switched relay: %d by %s"), ShutterGlobal.RelayCurrentMask,GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource));
|
||||
ShutterRelayChanged();
|
||||
ShutterGlobal.RelayOldMask = XdrvMailbox.index;
|
||||
break;
|
||||
case FUNC_SET_DEVICE_POWER:
|
||||
if (ShutterGlobal.skip_relay_change ) {
|
||||
uint8_t i;
|
||||
for (i = 0; i < devices_present; i++) {
|
||||
for (i = 0; i < TasmotaGlobal.devices_present; i++) {
|
||||
if (ShutterGlobal.RelayCurrentMask &1) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ struct PCF8574 {
|
||||
|
||||
void Pcf8574SwitchRelay(void)
|
||||
{
|
||||
for (uint32_t i = 0; i < devices_present; i++) {
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
|
||||
uint8_t relay_state = bitRead(XdrvMailbox.index, i);
|
||||
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PCF: Pcf8574.max_devices %d requested pin %d"), Pcf8574.max_devices,Pcf8574.pin[i]);
|
||||
@ -53,7 +53,7 @@ void Pcf8574SwitchRelay(void)
|
||||
if (Pcf8574.max_devices > 0 && Pcf8574.pin[i] < 99) {
|
||||
uint8_t board = Pcf8574.pin[i]>>3;
|
||||
uint8_t oldpinmask = Pcf8574.pin_mask[board];
|
||||
uint8_t _val = bitRead(rel_inverted, i) ? !relay_state : relay_state;
|
||||
uint8_t _val = bitRead(TasmotaGlobal.rel_inverted, i) ? !relay_state : relay_state;
|
||||
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PCF: Pcf8574SwitchRelay %d on pin %d"), i,state);
|
||||
|
||||
@ -67,7 +67,7 @@ void Pcf8574SwitchRelay(void)
|
||||
Wire.write(Pcf8574.pin_mask[board]);
|
||||
Pcf8574.error = Wire.endTransmission();
|
||||
}
|
||||
//pcf8574.write(Pcf8574.pin[i]&0x7, rel_inverted[i] ? !state : state);
|
||||
//pcf8574.write(Pcf8574.pin[i]&0x7, TasmotaGlobal.rel_inverted[i] ? !state : state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,7 +111,7 @@ void Pcf8574Init(void)
|
||||
for (uint32_t i = 0; i < sizeof(Pcf8574.pin); i++) {
|
||||
Pcf8574.pin[i] = 99;
|
||||
}
|
||||
devices_present = devices_present - Pcf8574.max_connected_ports; // reset no of devices to avoid duplicate ports on duplicate init.
|
||||
TasmotaGlobal.devices_present = TasmotaGlobal.devices_present - Pcf8574.max_connected_ports; // reset no of devices to avoid duplicate ports on duplicate init.
|
||||
Pcf8574.max_connected_ports = 0; // reset no of devices to avoid duplicate ports on duplicate init.
|
||||
for (uint32_t idx = 0; idx < Pcf8574.max_devices; idx++) { // suport up to 8 boards PCF8574
|
||||
|
||||
@ -119,11 +119,11 @@ void Pcf8574Init(void)
|
||||
|
||||
for (uint32_t i = 0; i < 8; i++) {
|
||||
uint8_t _result = Settings.pcf8574_config[idx] >> i &1;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PCF: I2C shift i %d: %d. Powerstate: %d, devices_present: %d"), i,_result, Settings.power>>i&1, devices_present);
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PCF: I2C shift i %d: %d. Powerstate: %d, TasmotaGlobal.devices_present: %d"), i,_result, Settings.power>>i&1, TasmotaGlobal.devices_present);
|
||||
if (_result > 0) {
|
||||
Pcf8574.pin[devices_present] = i + 8 * idx;
|
||||
bitWrite(rel_inverted, devices_present, Settings.flag3.pcf8574_ports_inverted); // SetOption81 - Invert all ports on PCF8574 devices
|
||||
devices_present++;
|
||||
Pcf8574.pin[TasmotaGlobal.devices_present] = i + 8 * idx;
|
||||
bitWrite(TasmotaGlobal.rel_inverted, TasmotaGlobal.devices_present, Settings.flag3.pcf8574_ports_inverted); // SetOption81 - Invert all ports on PCF8574 devices
|
||||
TasmotaGlobal.devices_present++;
|
||||
Pcf8574.max_connected_ports++;
|
||||
}
|
||||
}
|
||||
@ -203,8 +203,8 @@ void Pcf8574SaveSettings(void)
|
||||
n = n&(n-1);
|
||||
count++;
|
||||
}
|
||||
if (count <= devices_present) {
|
||||
devices_present = devices_present - count;
|
||||
if (count <= TasmotaGlobal.devices_present) {
|
||||
TasmotaGlobal.devices_present = TasmotaGlobal.devices_present - count;
|
||||
}
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("i2cs%d"), i+8*idx);
|
||||
@ -212,7 +212,7 @@ void Pcf8574SaveSettings(void)
|
||||
byte _value = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
if (_value) {
|
||||
Settings.pcf8574_config[idx] = Settings.pcf8574_config[idx] | 1 << i;
|
||||
devices_present++;
|
||||
TasmotaGlobal.devices_present++;
|
||||
Pcf8574.max_connected_ports++;
|
||||
} else {
|
||||
Settings.pcf8574_config[idx] = Settings.pcf8574_config[idx] & ~(1 << i );
|
||||
|
||||
@ -124,12 +124,12 @@ void ExsSerialSend(const uint8_t data[] = nullptr, uint16_t len = 0)
|
||||
char rc;
|
||||
|
||||
#ifdef EXS_DEBUG
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("EXS: Tx Packet: \""));
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("EXS: Tx Packet: \""));
|
||||
for (uint32_t i = 0; i < len; i++)
|
||||
{
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, data[i]);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s%02x"), TasmotaGlobal.log_data, data[i]);
|
||||
}
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s\""), log_data);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s\""), TasmotaGlobal.log_data);
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE);
|
||||
#endif
|
||||
|
||||
@ -360,20 +360,20 @@ bool ExsModuleSelected(void)
|
||||
Settings.flag3.pwm_multi_channels = 1; // SetOption68 - Enable multi-channels PWM instead of Color PWM
|
||||
SetSeriallog(LOG_LEVEL_NONE);
|
||||
|
||||
devices_present = +2;
|
||||
light_type = LT_SERIAL2;
|
||||
TasmotaGlobal.devices_present = +2;
|
||||
TasmotaGlobal.light_type = LT_SERIAL2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExsSetChannels(void)
|
||||
{
|
||||
#ifdef EXS_DEBUG
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("EXS: SetChannels: \""));
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("EXS: SetChannels: \""));
|
||||
for (int i = 0; i < XdrvMailbox.data_len; i++)
|
||||
{
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, ((uint8_t *)XdrvMailbox.data)[i]);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s%02x"), TasmotaGlobal.log_data, ((uint8_t *)XdrvMailbox.data)[i]);
|
||||
}
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s\""), log_data);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s\""), TasmotaGlobal.log_data);
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE);
|
||||
#endif
|
||||
|
||||
@ -385,7 +385,7 @@ bool ExsSetChannels(void)
|
||||
bool ExsSetPower(void)
|
||||
{
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("EXS: Set Power, Device %d, Power 0x%02x"),
|
||||
active_device, XdrvMailbox.index);
|
||||
TasmotaGlobal.active_device, XdrvMailbox.index);
|
||||
|
||||
Exs.power = XdrvMailbox.index;
|
||||
return ExsSyncState();
|
||||
@ -466,12 +466,12 @@ void ExsSerialInput(void)
|
||||
Exs.cmd_status = 0;
|
||||
|
||||
#ifdef EXS_DEBUG
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("EXS: RX Packet: \""));
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("EXS: RX Packet: \""));
|
||||
for (uint32_t i = 0; i < Exs.byte_counter; i++)
|
||||
{
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, Exs.buffer[i]);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s%02x"), TasmotaGlobal.log_data, Exs.buffer[i]);
|
||||
}
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s\", CRC: 0x%02x"), log_data, crc);
|
||||
snprintf_P(TasmotaGlobal.log_data, sizeof(TasmotaGlobal.log_data), PSTR("%s\", CRC: 0x%02x"), TasmotaGlobal.log_data, crc);
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE);
|
||||
#endif
|
||||
|
||||
@ -604,7 +604,7 @@ bool Xdrv30(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (EXS_DIMMER == my_module_type)
|
||||
if (EXS_DIMMER == TasmotaGlobal.module_type)
|
||||
{
|
||||
switch (function)
|
||||
{
|
||||
|
||||
@ -347,7 +347,7 @@ void TasmotaClient_Flash(void) {
|
||||
if (!TasmotaClient_SetupFlash()) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flashing aborted!"));
|
||||
TClient.flashing = false;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@ void TasmotaClient_Flash(void) {
|
||||
TasmotaClient_exitProgMode();
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flash done!"));
|
||||
TClient.flashing = false;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
|
||||
void TasmotaClient_SetFlagFlashing(bool value) {
|
||||
@ -543,7 +543,7 @@ void TasmotaClient_ProcessIn(void) {
|
||||
Response_P(PSTR("{\"TasmotaClient\":"));
|
||||
ResponseAppend_P("%s", inbuf);
|
||||
ResponseJsonEnd();
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, mqtt_data);
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
if (CMND_EXECUTE_CMND == TClientCommand.command) { // We need to execute the incoming command
|
||||
ExecuteCommand(inbuf, SRC_IGNORE);
|
||||
|
||||
@ -88,10 +88,9 @@ void PWMModulePreInit(void)
|
||||
Settings.ledstate = 0; // Disable LED usage
|
||||
|
||||
// If the module was just changed to PWM Dimmer, set the defaults.
|
||||
if (Settings.last_module != Settings.module) {
|
||||
if (TasmotaGlobal.module_changed) {
|
||||
Settings.flag.pwm_control = true; // SetOption15 - Switch between commands PWM or COLOR/DIMMER/CT/CHANNEL
|
||||
Settings.bri_power_on = Settings.bri_preset_low = Settings.bri_preset_high = 0;
|
||||
Settings.last_module = Settings.module;
|
||||
|
||||
// Previous versions of PWM Dimmer used SetOption32 - Button held for factor times longer as the
|
||||
// hold time. The hold time is now fixed and SetOption32 is used as normal including to
|
||||
@ -108,7 +107,7 @@ void PWMModulePreInit(void)
|
||||
PWMDimmerSetPoweredOffLed();
|
||||
|
||||
// The relay initializes to on. If the power is supposed to be off, turn the relay off.
|
||||
// if (!power && PinUsed(GPIO_REL1)) digitalWrite(Pin(GPIO_REL1), bitRead(rel_inverted, 0) ? 1 : 0);
|
||||
// if (!TasmotaGlobal.power && PinUsed(GPIO_REL1)) digitalWrite(Pin(GPIO_REL1), bitRead(TasmotaGlobal.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
|
||||
@ -126,8 +125,8 @@ void PWMModulePreInit(void)
|
||||
first_device_group_is_local = false;
|
||||
|
||||
// Back out the changes made in the light module under the assumtion we have a relay or PWM.
|
||||
devices_present--;
|
||||
light_type = 0;
|
||||
TasmotaGlobal.devices_present--;
|
||||
TasmotaGlobal.light_type = 0;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < MAX_PWM_DIMMER_KEYS; i++) {
|
||||
@ -148,7 +147,7 @@ void PWMDimmerSetBrightnessLeds(int32_t bri)
|
||||
uint32_t leds = 0;
|
||||
uint32_t mask = 1;
|
||||
int32_t led;
|
||||
for (led = 0; led < leds_present; led++) {
|
||||
for (led = 0; led < TasmotaGlobal.leds_present; led++) {
|
||||
if (Settings.ledmask & mask) leds++;
|
||||
mask <<= 1;
|
||||
}
|
||||
@ -184,15 +183,15 @@ void PWMDimmerSetPoweredOffLed(void)
|
||||
{
|
||||
// Set the powered-off LED state.
|
||||
if (PinUsed(GPIO_LEDLNK)) {
|
||||
bool power_off_led_on = !power && Settings.flag4.powered_off_led;
|
||||
if (ledlnk_inverted) power_off_led_on ^= 1;
|
||||
bool power_off_led_on = !TasmotaGlobal.power && Settings.flag4.powered_off_led;
|
||||
if (TasmotaGlobal.ledlnk_inverted) power_off_led_on ^= 1;
|
||||
digitalWrite(Pin(GPIO_LEDLNK), power_off_led_on);
|
||||
}
|
||||
}
|
||||
|
||||
void PWMDimmerSetPower(void)
|
||||
{
|
||||
DigitalWrite(GPIO_REL1, 0, bitRead(rel_inverted, 0) ? !power : power);
|
||||
DigitalWrite(GPIO_REL1, 0, bitRead(TasmotaGlobal.rel_inverted, 0) ? !TasmotaGlobal.power : TasmotaGlobal.power);
|
||||
PWMDimmerSetBrightnessLeds(-1);
|
||||
PWMDimmerSetPoweredOffLed();
|
||||
}
|
||||
@ -272,11 +271,11 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
|
||||
|
||||
// Initialize some variables.
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
bool power_is_on = (active_remote_pwm_dimmer ? active_remote_pwm_dimmer->power_on : power);
|
||||
bool power_is_on = (active_remote_pwm_dimmer ? active_remote_pwm_dimmer->power_on : TasmotaGlobal.power);
|
||||
bool is_power_button = (button_index == power_button_index);
|
||||
bool is_down_button = (button_index == down_button_index);
|
||||
#else // USE_PWM_DIMMER_REMOTE
|
||||
bool power_is_on = power;
|
||||
bool power_is_on = TasmotaGlobal.power;
|
||||
bool is_power_button = !button_index;
|
||||
bool is_down_button = (button_index == (power_button_index ? 0 : 1));
|
||||
#endif // USE_PWM_DIMMER_REMOTE
|
||||
@ -502,13 +501,13 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
|
||||
}
|
||||
else {
|
||||
#endif // USE_PWM_DIMMER_REMOTE
|
||||
skip_light_fade = true;
|
||||
TasmotaGlobal.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;
|
||||
TasmotaGlobal.skip_light_fade = false;
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
ignore_dgr_sends = false;
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
@ -537,7 +536,7 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
|
||||
}
|
||||
else {
|
||||
#endif // USE_PWM_DIMMER_REMOTE
|
||||
new_power = power ^ 1;
|
||||
new_power = TasmotaGlobal.power ^ 1;
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
}
|
||||
#endif // USE_PWM_DIMMER_REMOTE
|
||||
@ -599,7 +598,7 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
|
||||
// If we need to publish an MQTT trigger, do it.
|
||||
if (mqtt_trigger) {
|
||||
char topic[TOPSZ];
|
||||
sprintf_P(mqtt_data, PSTR("Trigger%u"), mqtt_trigger);
|
||||
sprintf_P(TasmotaGlobal.mqtt_data, PSTR("Trigger%u"), mqtt_trigger);
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
if (active_remote_pwm_dimmer) {
|
||||
snprintf_P(topic, sizeof(topic), PSTR("cmnd/%s/EVENT"), device_groups[power_button_index].group_name);
|
||||
@ -615,9 +614,9 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
DevGroupMessageType message_type = DGR_MSGTYP_UPDATE_DIRECT;
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
if (handle_tap && !active_remote_pwm_dimmer)
|
||||
if (handle_tap && !active_remote_pwm_dimmer)
|
||||
#else // USE_PWM_DIMMER_REMOTE
|
||||
if (handle_tap)
|
||||
if (handle_tap)
|
||||
#endif // USE_PWM_DIMMER_REMOTE
|
||||
message_type = (DevGroupMessageType)(message_type + DGR_MSGTYPFLAG_WITH_LOCAL);
|
||||
SendDeviceGroupMessage(power_button_index, message_type, dgr_item, dgr_value);
|
||||
@ -690,7 +689,7 @@ void CmndPWMDimmerPWMs(void)
|
||||
{
|
||||
if (XdrvMailbox.data_len > 0 && XdrvMailbox.payload <= 5) {
|
||||
Settings.pwm_dimmer_cfg.pwm_count = XdrvMailbox.payload - 1;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
Response_P(PSTR("{\"" D_CMND_PWM_DIMMER_PWMS "\":%u}"), Settings.pwm_dimmer_cfg.pwm_count + 1);
|
||||
}
|
||||
@ -704,7 +703,7 @@ bool Xdrv35(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (PWM_DIMMER != my_module_type) return result;
|
||||
if (PWM_DIMMER != TasmotaGlobal.module_type) return result;
|
||||
|
||||
switch (function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
@ -717,7 +716,7 @@ bool Xdrv35(uint8_t function)
|
||||
// the LED will be set to a blinking state and will be turned off when the connection is
|
||||
// restored. If the state is blinking now, set a flag so we know that we need to restore it
|
||||
// when it stops blinking.
|
||||
if (global_state.data)
|
||||
if (TasmotaGlobal.global_state.data)
|
||||
restore_powered_off_led_counter = 5;
|
||||
else if (restore_powered_off_led_counter) {
|
||||
PWMDimmerSetPoweredOffLed();
|
||||
@ -758,7 +757,7 @@ bool Xdrv35(uint8_t function)
|
||||
// Bottom 15 3 15 1
|
||||
if (buttons_pressed == 1 && Settings.flag4.multiple_device_groups) {
|
||||
power_button_index = button_index;
|
||||
down_button_index = (Pin(GPIO_KEY1, power_button_index) == 15 ? gpio_pin[1] : gpio_pin[15]) - 32;
|
||||
down_button_index = (Pin(GPIO_KEY1, power_button_index) == 15 ? TasmotaGlobal.gpio_pin[1] : TasmotaGlobal.gpio_pin[15]) - 32;
|
||||
active_remote_pwm_dimmer = nullptr;
|
||||
if (power_button_index || !first_device_group_is_local)
|
||||
active_remote_pwm_dimmer = &remote_pwm_dimmers[power_button_index];
|
||||
|
||||
@ -44,9 +44,9 @@ struct SONOFFD1 {
|
||||
|
||||
void SonoffD1Received(void)
|
||||
{
|
||||
if (serial_in_byte_counter < 8) { return; } // Received ack from Rf chip (aa 55 01 04 00 00 05)
|
||||
if (TasmotaGlobal.serial_in_byte_counter < 8) { return; } // Received ack from Rf chip (aa 55 01 04 00 00 05)
|
||||
|
||||
uint8_t action = serial_in_buffer[6] & 1;
|
||||
uint8_t action = TasmotaGlobal.serial_in_buffer[6] & 1;
|
||||
if (action != SnfD1.power) {
|
||||
SnfD1.power = action;
|
||||
|
||||
@ -55,7 +55,7 @@ void SonoffD1Received(void)
|
||||
ExecuteCommandPower(1, action, SRC_SWITCH);
|
||||
}
|
||||
|
||||
uint8_t dimmer = serial_in_buffer[7];
|
||||
uint8_t dimmer = TasmotaGlobal.serial_in_buffer[7];
|
||||
if (dimmer != SnfD1.dimmer) {
|
||||
SnfD1.dimmer = dimmer;
|
||||
|
||||
@ -69,27 +69,27 @@ void SonoffD1Received(void)
|
||||
/*
|
||||
// Send Acknowledge - Copy first 5 bytes, reset byte 6 and store crc in byte 7
|
||||
// AA 55 01 04 00 00 05
|
||||
serial_in_buffer[5] = 0; // Ack
|
||||
serial_in_buffer[6] = 0; // Crc
|
||||
TasmotaGlobal.serial_in_buffer[5] = 0; // Ack
|
||||
TasmotaGlobal.serial_in_buffer[6] = 0; // Crc
|
||||
for (uint32_t i = 0; i < 7; i++) {
|
||||
if ((i > 1) && (i < 6)) { serial_in_buffer[6] += serial_in_buffer[i]; }
|
||||
Serial.write(serial_in_buffer[i]);
|
||||
if ((i > 1) && (i < 6)) { TasmotaGlobal.serial_in_buffer[6] += TasmotaGlobal.serial_in_buffer[i]; }
|
||||
Serial.write(TasmotaGlobal.serial_in_buffer[i]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
bool SonoffD1SerialInput(void)
|
||||
{
|
||||
if (0xAA == serial_in_byte) { // 0xAA - Start of text
|
||||
serial_in_byte_counter = 0;
|
||||
if (0xAA == TasmotaGlobal.serial_in_byte) { // 0xAA - Start of text
|
||||
TasmotaGlobal.serial_in_byte_counter = 0;
|
||||
SnfD1.receive_len = 7;
|
||||
}
|
||||
if (SnfD1.receive_len) {
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
if (6 == serial_in_byte_counter) {
|
||||
SnfD1.receive_len += serial_in_byte; // 8 or 17
|
||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte;
|
||||
if (6 == TasmotaGlobal.serial_in_byte_counter) {
|
||||
SnfD1.receive_len += TasmotaGlobal.serial_in_byte; // 8 or 17
|
||||
}
|
||||
if (serial_in_byte_counter == SnfD1.receive_len) {
|
||||
if (TasmotaGlobal.serial_in_byte_counter == SnfD1.receive_len) {
|
||||
|
||||
// Sonoff D1 codes
|
||||
// aa 55 01 04 00 0a 01 01 ff ff ff ff ff ff ff ff 09 - Power On, Dimmer 1%
|
||||
@ -102,15 +102,15 @@ bool SonoffD1SerialInput(void)
|
||||
AddLogSerial(LOG_LEVEL_DEBUG);
|
||||
uint8_t crc = 0;
|
||||
for (uint32_t i = 2; i < SnfD1.receive_len -1; i++) {
|
||||
crc += serial_in_buffer[i];
|
||||
crc += TasmotaGlobal.serial_in_buffer[i];
|
||||
}
|
||||
if (crc == serial_in_buffer[SnfD1.receive_len -1]) {
|
||||
if (crc == TasmotaGlobal.serial_in_buffer[SnfD1.receive_len -1]) {
|
||||
SonoffD1Received();
|
||||
SnfD1.receive_len = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
serial_in_byte = 0;
|
||||
TasmotaGlobal.serial_in_byte = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -163,8 +163,8 @@ bool SonoffD1ModuleSelected(void)
|
||||
{
|
||||
SetSerial(9600, TS_SERIAL_8N1);
|
||||
|
||||
devices_present++;
|
||||
light_type = LT_SERIAL1;
|
||||
TasmotaGlobal.devices_present++;
|
||||
TasmotaGlobal.light_type = LT_SERIAL1;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -177,7 +177,7 @@ bool Xdrv37(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (SONOFF_D1 == my_module_type) {
|
||||
if (SONOFF_D1 == TasmotaGlobal.module_type) {
|
||||
switch (function) {
|
||||
case FUNC_SERIAL:
|
||||
result = SonoffD1SerialInput();
|
||||
|
||||
@ -323,7 +323,7 @@ uint8_t ThermostatInputStatus(uint8_t input_switch)
|
||||
|
||||
uint8_t ThermostatOutputStatus(uint8_t output_switch)
|
||||
{
|
||||
return (uint8_t)bitRead(power, (output_switch - 1));
|
||||
return (uint8_t)bitRead(TasmotaGlobal.power, (output_switch - 1));
|
||||
}
|
||||
|
||||
int16_t ThermostatCelsiusToFahrenheit(const int32_t deg, uint8_t conv_type) {
|
||||
@ -367,7 +367,7 @@ int16_t ThermostatFahrenheitToCelsius(const int32_t deg, uint8_t conv_type) {
|
||||
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)) {
|
||||
if ((TasmotaGlobal.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;
|
||||
@ -392,7 +392,7 @@ void ThermostatSignalProcessingFast(uint8_t ctr_output)
|
||||
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;
|
||||
Thermostat[ctr_output].timestamp_input_on = TasmotaGlobal.uptime;
|
||||
}
|
||||
// Update real status of the output
|
||||
Thermostat[ctr_output].status.status_output = (uint32_t)ThermostatOutputStatus(Thermostat[ctr_output].status.output_relay_number);
|
||||
@ -453,7 +453,7 @@ void ThermostatHybridCtrPhase(uint8_t ctr_output)
|
||||
// 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)) {
|
||||
&& (TasmotaGlobal.uptime >= Thermostat[ctr_output].time_ctr_checkpoint)) {
|
||||
// Reset pause period
|
||||
Thermostat[ctr_output].time_ctr_checkpoint = 0;
|
||||
// Reset timers
|
||||
@ -468,13 +468,13 @@ void ThermostatHybridCtrPhase(uint8_t ctr_output)
|
||||
// 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))
|
||||
if (((TasmotaGlobal.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].timestamp_rampup_start = TasmotaGlobal.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;
|
||||
@ -541,7 +541,7 @@ bool ThermostatStateManualToAuto(uint8_t ctr_output)
|
||||
// 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))) {
|
||||
&& ((TasmotaGlobal.uptime - Thermostat[ctr_output].timestamp_input_on) > ((uint32_t)Thermostat[ctr_output].time_manual_to_auto * 60))) {
|
||||
change_state = true;
|
||||
}
|
||||
return change_state;
|
||||
@ -608,7 +608,7 @@ void ThermostatOutputRelay(uint8_t ctr_output, uint32_t command)
|
||||
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].timestamp_output_off = TasmotaGlobal.uptime;
|
||||
Thermostat[ctr_output].status.status_output = IFACE_OFF;
|
||||
#ifdef DEBUG_THERMOSTAT
|
||||
ThermostatVirtualSwitch(ctr_output);
|
||||
@ -793,15 +793,15 @@ void ThermostatCalculatePI(uint8_t ctr_output)
|
||||
}
|
||||
|
||||
// Adjust output switch point
|
||||
Thermostat[ctr_output].time_ctr_changepoint = uptime + (uint32_t)Thermostat[ctr_output].time_total_pi;
|
||||
Thermostat[ctr_output].time_ctr_changepoint = TasmotaGlobal.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);
|
||||
Thermostat[ctr_output].time_ctr_checkpoint = TasmotaGlobal.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)
|
||||
if ( (TasmotaGlobal.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)
|
||||
@ -815,7 +815,7 @@ void ThermostatWorkAutomaticPI(uint8_t ctr_output)
|
||||
// Reset cycle active
|
||||
Thermostat[ctr_output].status.status_cycle_active = CYCLE_OFF;
|
||||
}
|
||||
if (uptime < Thermostat[ctr_output].time_ctr_changepoint) {
|
||||
if (TasmotaGlobal.uptime < Thermostat[ctr_output].time_ctr_changepoint) {
|
||||
Thermostat[ctr_output].status.status_cycle_active = CYCLE_ON;
|
||||
Thermostat[ctr_output].status.command_output = IFACE_ON;
|
||||
}
|
||||
@ -842,7 +842,7 @@ void ThermostatWorkAutomaticRampUp(uint8_t ctr_output)
|
||||
}
|
||||
|
||||
// Update time in ramp-up as well as delta temp
|
||||
time_in_rampup = uptime - Thermostat[ctr_output].timestamp_rampup_start;
|
||||
time_in_rampup = TasmotaGlobal.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;
|
||||
@ -873,14 +873,14 @@ void ThermostatWorkAutomaticRampUp(uint8_t ctr_output)
|
||||
}
|
||||
// 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);
|
||||
Thermostat[ctr_output].time_rampup_nextcycle = TasmotaGlobal.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].time_ctr_changepoint = TasmotaGlobal.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)) {
|
||||
else if ((Thermostat[ctr_output].time_rampup_deadtime > 0) && (TasmotaGlobal.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;
|
||||
@ -900,9 +900,9 @@ void ThermostatWorkAutomaticRampUp(uint8_t ctr_output)
|
||||
|
||||
// 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;
|
||||
Thermostat[ctr_output].temp_rampup_output_off = (int16_t)(((int32_t)temp_delta_rampup * (int32_t)(Thermostat[ctr_output].time_ctr_changepoint - (TasmotaGlobal.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].time_rampup_nextcycle = TasmotaGlobal.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;
|
||||
@ -911,9 +911,9 @@ void ThermostatWorkAutomaticRampUp(uint8_t ctr_output)
|
||||
// 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);
|
||||
Thermostat[ctr_output].time_rampup_nextcycle = TasmotaGlobal.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].time_ctr_changepoint = TasmotaGlobal.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
|
||||
@ -927,7 +927,7 @@ void ThermostatWorkAutomaticRampUp(uint8_t ctr_output)
|
||||
// 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)
|
||||
|| (TasmotaGlobal.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)
|
||||
@ -951,7 +951,7 @@ void ThermostatWorkAutomaticRampUp(uint8_t ctr_output)
|
||||
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;
|
||||
Thermostat[ctr_output].time_ctr_checkpoint = TasmotaGlobal.uptime;
|
||||
// Switch Off output
|
||||
Thermostat[ctr_output].status.command_output = IFACE_OFF;
|
||||
}
|
||||
@ -971,7 +971,7 @@ void ThermostatPeakDetectorInit(uint8_t ctr_output)
|
||||
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;
|
||||
Thermostat[ctr_output].time_ctr_checkpoint = TasmotaGlobal.uptime + THERMOSTAT_TIME_MAX_AUTOTUNE;
|
||||
}
|
||||
|
||||
void ThermostatPeakDetector(uint8_t ctr_output)
|
||||
@ -1020,7 +1020,7 @@ void ThermostatPeakDetector(uint8_t ctr_output)
|
||||
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].time_peak_timestamps_atune[peak_num] = (TasmotaGlobal.uptime / 60);
|
||||
Thermostat[ctr_output].peak_ctr++;
|
||||
peak_transition = true;
|
||||
}
|
||||
@ -1040,7 +1040,7 @@ void ThermostatPeakDetector(uint8_t ctr_output)
|
||||
&& (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].time_peak_timestamps_atune[peak_num] = (TasmotaGlobal.uptime / 60);
|
||||
Thermostat[ctr_output].peak_ctr++;
|
||||
peak_transition = true;
|
||||
}
|
||||
@ -1117,17 +1117,17 @@ 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)
|
||||
if ((TasmotaGlobal.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) {
|
||||
if (TasmotaGlobal.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);
|
||||
Thermostat[ctr_output].time_ctr_changepoint = TasmotaGlobal.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) {
|
||||
if (TasmotaGlobal.uptime < Thermostat[ctr_output].time_ctr_changepoint) {
|
||||
Thermostat[ctr_output].status.status_cycle_active = CYCLE_ON;
|
||||
Thermostat[ctr_output].status.command_output = IFACE_ON;
|
||||
}
|
||||
@ -1318,9 +1318,9 @@ void ThermostatDebug(uint8_t ctr_output)
|
||||
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);
|
||||
dtostrfd(TasmotaGlobal.uptime, 0, result_chr);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("uptime: %s"), result_chr);
|
||||
dtostrfd(power, 0, result_chr);
|
||||
dtostrfd(TasmotaGlobal.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(""));
|
||||
@ -1328,7 +1328,7 @@ void ThermostatDebug(uint8_t ctr_output)
|
||||
#endif // DEBUG_THERMOSTAT
|
||||
|
||||
void ThermostatGetLocalSensor(uint8_t ctr_output) {
|
||||
String buf = mqtt_data; // copy the string into a new buffer that will be modified
|
||||
String buf = TasmotaGlobal.mqtt_data; // copy the string into a new buffer that will be modified
|
||||
JsonParser parser((char*)buf.c_str());
|
||||
JsonParserObject root = parser.getRootObject();
|
||||
if (root) {
|
||||
@ -1341,7 +1341,7 @@ void ThermostatGetLocalSensor(uint8_t ctr_output) {
|
||||
if ( (value >= -1000)
|
||||
&& (value <= 1000)
|
||||
&& (Thermostat[ctr_output].status.sensor_type == SENSOR_LOCAL)) {
|
||||
uint32_t timestamp = uptime;
|
||||
uint32_t timestamp = TasmotaGlobal.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
|
||||
@ -1385,7 +1385,7 @@ void CmndClimateModeSet(void)
|
||||
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;
|
||||
Thermostat[ctr_output].time_ctr_checkpoint = TasmotaGlobal.uptime;
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber((int)Thermostat[ctr_output].status.climate_mode);
|
||||
@ -1428,7 +1428,7 @@ void CmndControllerModeSet(void)
|
||||
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].timestamp_rampup_start = TasmotaGlobal.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;
|
||||
@ -1449,7 +1449,7 @@ void CmndInputSwitchSet(void)
|
||||
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;
|
||||
Thermostat[ctr_output].timestamp_input_on = TasmotaGlobal.uptime;
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber((int)Thermostat[ctr_output].status.input_switch_number);
|
||||
@ -1538,7 +1538,7 @@ void CmndTempMeasuredSet(void)
|
||||
if ( (value >= -1000)
|
||||
&& (value <= 1000)
|
||||
&& (Thermostat[ctr_output].status.sensor_type == SENSOR_MQTT)) {
|
||||
uint32_t timestamp = uptime;
|
||||
uint32_t timestamp = TasmotaGlobal.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
|
||||
|
||||
@ -289,9 +289,9 @@ void TelegramSendGetMe(void) {
|
||||
String TelegramExecuteCommand(const char *svalue) {
|
||||
String response = "";
|
||||
|
||||
uint32_t curridx = web_log_index;
|
||||
uint32_t curridx = TasmotaGlobal.web_log_index;
|
||||
ExecuteCommand(svalue, SRC_CHAT);
|
||||
if (web_log_index != curridx) {
|
||||
if (TasmotaGlobal.web_log_index != curridx) {
|
||||
uint32_t counter = curridx;
|
||||
response = F("{");
|
||||
bool cflg = false;
|
||||
@ -304,7 +304,7 @@ String TelegramExecuteCommand(const char *svalue) {
|
||||
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); }
|
||||
if (JSONlen > sizeof(TasmotaGlobal.mqtt_data)) { JSONlen = sizeof(TasmotaGlobal.mqtt_data); }
|
||||
char stemp[JSONlen];
|
||||
strlcpy(stemp, JSON +1, JSONlen -2);
|
||||
if (cflg) { response += F(","); }
|
||||
@ -315,7 +315,7 @@ String TelegramExecuteCommand(const char *svalue) {
|
||||
counter++;
|
||||
counter &= 0xFF;
|
||||
if (!counter) counter++; // Skip 0 as it is not allowed
|
||||
} while (counter != web_log_index);
|
||||
} while (counter != TasmotaGlobal.web_log_index);
|
||||
response += F("}");
|
||||
} else {
|
||||
response = F("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}");
|
||||
@ -325,7 +325,7 @@ String TelegramExecuteCommand(const char *svalue) {
|
||||
}
|
||||
|
||||
void TelegramLoop(void) {
|
||||
if (!global_state.network_down && (Telegram.recv_enable || Telegram.echo_enable)) {
|
||||
if (!TasmotaGlobal.global_state.network_down && (Telegram.recv_enable || Telegram.echo_enable)) {
|
||||
switch (Telegram.state) {
|
||||
case 0:
|
||||
TelegramInit();
|
||||
@ -412,7 +412,7 @@ void CmndTmState(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":{\"Send\":\"%s\",\"Receive\":\"%s\",\"Echo\":\"%s\"}}"),
|
||||
snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s\":{\"Send\":\"%s\",\"Receive\":\"%s\",\"Echo\":\"%s\"}}"),
|
||||
XdrvMailbox.command, GetStateText(Telegram.send_enable), GetStateText(Telegram.recv_enable), GetStateText(Telegram.echo_enable));
|
||||
}
|
||||
|
||||
|
||||
@ -130,7 +130,7 @@ void TCPInit(void) {
|
||||
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 = new TasmotaSerial(Pin(GPIO_TCP_RX), Pin(GPIO_TCP_TX), TasmotaGlobal.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();
|
||||
@ -168,7 +168,7 @@ void CmndTCPStart(void) {
|
||||
server_tcp->setNoDelay(true);
|
||||
}
|
||||
|
||||
ResponseCmndDone();
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
void CmndTCPBaudrate(void) {
|
||||
|
||||
@ -926,7 +926,7 @@ miel_hvac_input_settings(struct miel_hvac_softc *sc,
|
||||
return;
|
||||
}
|
||||
|
||||
if (bitRead(power, sc->sc_device) != !!state)
|
||||
if (bitRead(TasmotaGlobal.power, sc->sc_device) != !!state)
|
||||
ExecuteCommandPower(sc->sc_device, state, SRC_SWITCH);
|
||||
|
||||
publish = (sc->sc_settings_set == 0) ||
|
||||
@ -1044,7 +1044,7 @@ miel_hvac_pre_init(void)
|
||||
SetSerial(baudrate, TS_SERIAL_8E1);
|
||||
}
|
||||
|
||||
sc->sc_device = devices_present++; /* claim a POWER device slot */
|
||||
sc->sc_device = TasmotaGlobal.devices_present++; /* claim a POWER device slot */
|
||||
|
||||
miel_hvac_sc = sc;
|
||||
return;
|
||||
|
||||
@ -807,7 +807,7 @@ void HandleWebcamRoot(void) {
|
||||
/*********************************************************************************************/
|
||||
|
||||
uint32_t WcSetStreamserver(uint32_t flag) {
|
||||
if (global_state.network_down) { return 0; }
|
||||
if (TasmotaGlobal.global_state.network_down) { return 0; }
|
||||
|
||||
Wc.stream_active = 0;
|
||||
|
||||
@ -857,7 +857,7 @@ void WcLoop(void) {
|
||||
|
||||
#ifdef ENABLE_RTSPSERVER
|
||||
|
||||
if (!rtsp_start && !global_state.wifi_down && Wc.up) {
|
||||
if (!rtsp_start && !TasmotaGlobal.global_state.wifi_down && Wc.up) {
|
||||
rtspServer.begin();
|
||||
rtsp_start = 1;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: RTSP init"));
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
|
||||
#include <ETH.h>
|
||||
|
||||
char eth_hostname[sizeof(my_hostname)];
|
||||
char eth_hostname[sizeof(TasmotaGlobal.hostname)];
|
||||
|
||||
void EthernetEvent(WiFiEvent_t event) {
|
||||
switch (event) {
|
||||
@ -98,15 +98,15 @@ void EthernetEvent(WiFiEvent_t event) {
|
||||
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;
|
||||
TasmotaGlobal.global_state.eth_down = 0;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: Disconnected"));
|
||||
global_state.eth_down = 1;
|
||||
TasmotaGlobal.global_state.eth_down = 1;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_STOP:
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Stopped"));
|
||||
global_state.eth_down = 1;
|
||||
TasmotaGlobal.global_state.eth_down = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -120,8 +120,8 @@ void EthernetInit(void) {
|
||||
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"
|
||||
// snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), TasmotaGlobal.hostname);
|
||||
strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "_eth"
|
||||
strcat(eth_hostname, "_eth");
|
||||
|
||||
WiFi.onEvent(EthernetEvent);
|
||||
@ -164,7 +164,7 @@ void CmndEthernet(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
|
||||
Settings.flag4.network_ethernet = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndStateText(Settings.flag4.network_ethernet);
|
||||
}
|
||||
@ -173,7 +173,7 @@ void CmndEthAddress(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 31)) {
|
||||
Settings.eth_address = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndNumber(Settings.eth_address);
|
||||
}
|
||||
@ -182,7 +182,7 @@ void CmndEthType(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) {
|
||||
Settings.eth_type = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndNumber(Settings.eth_type);
|
||||
}
|
||||
@ -191,7 +191,7 @@ void CmndEthClockMode(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) {
|
||||
Settings.eth_clk_mode = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndNumber(Settings.eth_clk_mode);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user