Merge branch 'development' of https://github.com/arendst/Tasmota into development

This commit is contained in:
Christopher Tremblay 2020-10-24 00:55:51 -07:00
commit 3ec4246bbe
38 changed files with 572 additions and 252 deletions

View File

@ -134,6 +134,7 @@
| USE_EZOPH | - | - | - | - | - | - | - | | USE_EZOPH | - | - | - | - | - | - | - |
| USE_EZOORP | - | - | - | - | - | - | - | | USE_EZOORP | - | - | - | - | - | - | - |
| USE_EZORTD | - | - | - | - | - | - | - | | USE_EZORTD | - | - | - | - | - | - | - |
| USE_EZOHUM | - | - | - | - | - | - | - |
| | | | | | | | | | | | | | | | | |
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
| USE_SPI | - | - | - | - | - | - | x | | USE_SPI | - | - | - | - | - | - | x |

View File

@ -9,18 +9,24 @@ All notable changes to this project will be documented in this file.
- Support for timers in case of no-sunset permanent day by cybermaus (#9543) - Support for timers in case of no-sunset permanent day by cybermaus (#9543)
- Command ``NoDelay`` for immediate backlog command execution by Erik Montnemery (#9544) - Command ``NoDelay`` for immediate backlog command execution by Erik Montnemery (#9544)
- Command ``SwitchMode 15`` sending only MQTT message on switch change (#9593) - Command ``SwitchMode 15`` sending only MQTT message on switch change (#9593)
- Command ``ShutterChange`` to increment change position (#9594)
- Support for EZO Ph and ORP sensors by Christopher Tremblay (#9567) - Support for EZO Ph and ORP sensors by Christopher Tremblay (#9567)
- Support for EZO RTD sensors by Christopher Tremblay (#9585) - Support for EZO RTD sensors by Christopher Tremblay (#9585)
- Support for EZO HUM sensors by Christopher Tremblay (#9599)
- On ZigbeeBridge support for glowing led when permit join is active (#9581) - On ZigbeeBridge support for glowing led when permit join is active (#9581)
- Support for PWM Dimmer multi-press and ledmask (#9584) - Support for PWM Dimmer multi-press and ledmask (#9584)
- Support for fixed output Hi or Lo GPIO selection
- ESP32 support for Wireless-Tag WT32-ETH01 (#9496)
- ESP32 MI32 Beacon support, RSSI at TELEPERIOD, refactoring (#9609)
### Changed ### Changed
- Command ``Gpio17`` replaces command ``Adc`` - Command ``Gpio17`` replaces command ``Adc``
- Command ``Gpios`` replaces command ``Adcs`` - Command ``Gpios`` replaces command ``Adcs``
- Management of serial baudrate (#9554) - Management of serial baudrate (#9554)
- ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570) - TLS fingerprint ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570)
- Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399) - Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399)
- Tasmota Arduino Core v2.7.4.5 allowing webpassword over 47 characters (#9687) - Tasmota Arduino Core v2.7.4.5 allowing webpassword over 47 characters (#9687)
- Webserver code optimizations (#9580, #9590)
### Fixed ### Fixed
- Convert AdcParam parameters from versions before v9.0.0.2 - Convert AdcParam parameters from versions before v9.0.0.2
@ -28,7 +34,12 @@ All notable changes to this project will be documented in this file.
- Correct Energy period display shortly after midnight by gominoa (#9536) - Correct Energy period display shortly after midnight by gominoa (#9536)
- Rule handling of Var or Mem using text regression from v8.5.0.1 (#9540) - Rule handling of Var or Mem using text regression from v8.5.0.1 (#9540)
- TuyaMcu energy display regression from v8.5.0.1 (#9547) - TuyaMcu energy display regression from v8.5.0.1 (#9547)
- Tuyamcu dimmers MQTT topic (#9606)
- MQTT data corruption on ``MQTTLog 4`` (#9571) - MQTT data corruption on ``MQTTLog 4`` (#9571)
- Scripter memory alignment (#9608)
- Zigbee battery percentage (#9607)
- HassAnyKey anomaly (#9601)
- ESP32 Webcam broken regression from #9590
## [9.0.0.1] - 20201010 ## [9.0.0.1] - 20201010
### Added ### Added

View File

@ -61,6 +61,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
### Added ### Added
- Command ``NoDelay`` for immediate backlog command execution by Erik Montnemery (#9544) - Command ``NoDelay`` for immediate backlog command execution by Erik Montnemery (#9544)
- Command ``SwitchMode 15`` sending only MQTT message on switch change (#9593) - Command ``SwitchMode 15`` sending only MQTT message on switch change (#9593)
- Command ``ShutterChange`` to increment change position (#9594)
- Zigbee command ``ZbData`` for better support of device specific data - Zigbee command ``ZbData`` for better support of device specific data
- Optional support for Mitsubishi Electric HVAC by David Gwynne (#9237) - Optional support for Mitsubishi Electric HVAC by David Gwynne (#9237)
- Optional support for Orno WE517-Modbus energy meter by Maxime Vincent (#9353) - Optional support for Orno WE517-Modbus energy meter by Maxime Vincent (#9353)
@ -71,11 +72,14 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
- Support for analog buttons indexed within standard button range - Support for analog buttons indexed within standard button range
- Support for Vietnamese language translations by Tâm.NT - Support for Vietnamese language translations by Tâm.NT
- Support for timers in case of no-sunset permanent day by cybermaus (#9543) - Support for timers in case of no-sunset permanent day by cybermaus (#9543)
- Support for EZO Ph, ORP and RTD sensors by Christopher Tremblay (#9567, #9585) - Support for EZO Ph, ORP, RTD and HUM sensors by Christopher Tremblay (#9567, #9585, #9599)
- Support for fixed output Hi or Lo GPIO selection
- ESP32 support for Wireless-Tag WT32-ETH01 (#9496)
- ESP32 MI32 Beacon support, RSSI at TELEPERIOD, refactoring (#9609)
### Breaking Changed ### Breaking Changed
- Redesigned ESP8266 GPIO internal representation in line with ESP32 changing ``Template`` layout too - Redesigned ESP8266 GPIO internal representation in line with ESP32 changing ``Template`` layout too
- ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570) - TLS fingerprint ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570)
- Command ``Status`` output for disabled status types now returns {"Command":"Error"} - Command ``Status`` output for disabled status types now returns {"Command":"Error"}
- MAX31865 driver to support up to 6 thermocouples selected by ``MX31865 CS`` instead of ``SSPI CS`` (#9103) - MAX31865 driver to support up to 6 thermocouples selected by ``MX31865 CS`` instead of ``SSPI CS`` (#9103)
@ -90,6 +94,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
- Management of serial baudrate (#9554) - Management of serial baudrate (#9554)
- Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399) - Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399)
- Tasmota Arduino Core v2.7.4.5 allowing webpassword over 47 characters (#9687) - Tasmota Arduino Core v2.7.4.5 allowing webpassword over 47 characters (#9687)
- Webserver code optimizations (#9580, #9590)
### Fixed ### Fixed
- Ledlink blink when no network connected regression from v8.3.1.4 (#9292) - Ledlink blink when no network connected regression from v8.3.1.4 (#9292)
@ -101,6 +106,10 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
- Rule handling of Var or Mem using text regression from v8.5.0.1 (#9540) - Rule handling of Var or Mem using text regression from v8.5.0.1 (#9540)
- Correct Energy period display shortly after midnight by gominoa (#9536) - Correct Energy period display shortly after midnight by gominoa (#9536)
- TuyaMcu energy display regression from v8.5.0.1 (#9547) - TuyaMcu energy display regression from v8.5.0.1 (#9547)
- Tuyamcu dimmers MQTT topic (#9606)
- Scripter memory alignment (#9608)
- Zigbee battery percentage (#9607)
- HassAnyKey anomaly (#9601)
### Removed ### Removed
- Support for direct upgrade from Tasmota versions before v7.0 - Support for direct upgrade from Tasmota versions before v7.0

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -664,8 +664,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 TX" #define D_SENSOR_DDS2382_TX "DDS238-2 TX"
#define D_SENSOR_DDS2382_RX "DDS238-2 RX" #define D_SENSOR_DDS2382_RX "DDS238-2 RX"
#define D_SENSOR_DDSU666_TX "DDSU666 TX" #define D_SENSOR_DDSU666_TX "DDSU666 TX"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 - STP" #define D_SENSOR_A4988_STP "A4988 - STP"
#define D_SENSOR_A4988_ENA "A4988 - ENA" #define D_SENSOR_A4988_ENA "A4988 - ENA"
#define D_SENSOR_A4988_MS1 "A4988 - MS1" #define D_SENSOR_A4988_MS1 "A4988 - MS1"
#define D_SENSOR_A4988_MS2 "A4988 - MS2" #define D_SENSOR_OUTPUT_HI "Output - Hi"
#define D_SENSOR_A4988_MS3 "A4988 - MS3" #define D_SENSOR_OUTPUT_LO "Output - Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 - TX" #define D_SENSOR_DDS2382_TX "DDS238-2 - TX"
#define D_SENSOR_DDS2382_RX "DDS238-2 - RX" #define D_SENSOR_DDS2382_RX "DDS238-2 - RX"
#define D_SENSOR_DDSU666_TX "DDSU666 - TX" #define D_SENSOR_DDSU666_TX "DDSU666 - TX"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -668,8 +668,8 @@
#define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1" #define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2" #define D_SENSOR_OUTPUT_HI "Output Hi"
#define D_SENSOR_A4988_MS3 "A4988 MS3" #define D_SENSOR_OUTPUT_LO "Output Lo"
#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx"
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx"

View File

@ -631,12 +631,14 @@ void GetFeatures(void)
feature7 = 0x00000000; feature7 = 0x00000000;
#if defined(USE_I2C) && defined(USE_EZOORP) #if defined(USE_I2C) && defined(USE_EZOORP)
feature7 |= 0x00000001; // xsns_79_ezoorp.ino feature7 |= 0x00000001; // xsns_78_ezoorp.ino
#endif #endif
#if defined(USE_I2C) && defined(USE_EZORTD) #if defined(USE_I2C) && defined(USE_EZORTD)
feature7 |= 0x00000002; // xsns_80_ezortd.ino feature7 |= 0x00000002; // xsns_78_ezortd.ino
#endif
#if defined(USE_I2C) && defined(USE_EZOHUM)
feature7 |= 0x00000004; // xsns_78_exohum.ino
#endif #endif
// feature7 |= 0x00000004;
// feature7 |= 0x00000008; // feature7 |= 0x00000008;
// feature7 |= 0x00000010; // feature7 |= 0x00000010;

View File

@ -1642,12 +1642,20 @@ void GpioInit(void)
#endif // ESP8266 - ESP32 #endif // ESP8266 - ESP32
soft_spi_flg = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); soft_spi_flg = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO)));
// Set any non-used GPIO to INPUT - Related to resetPins() in support_legacy_cores.ino
// Doing it here solves relay toggles at restart.
for (uint32_t i = 0; i < ARRAY_SIZE(my_module.io); i++) { for (uint32_t i = 0; i < ARRAY_SIZE(my_module.io); i++) {
uint32_t mpin = ValidPin(i, my_module.io[i]); uint32_t mpin = ValidPin(i, my_module.io[i]);
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("INI: gpio pin %d, mpin %d"), i, mpin); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("INI: gpio pin %d, mpin %d"), i, mpin);
if (((i < 6) || (i > 11)) && (0 == mpin)) { // Skip SPI flash interface if (AGPIO(GPIO_OUTPUT_HI) == mpin) {
pinMode(i, OUTPUT);
digitalWrite(i, 1);
}
else if (AGPIO(GPIO_OUTPUT_LO) == mpin) {
pinMode(i, OUTPUT);
digitalWrite(i, 0);
}
// Set any non-used GPIO to INPUT - Related to resetPins() in support_legacy_cores.ino
// Doing it here solves relay toggles at restart.
else if (((i < 6) || (i > 11)) && (GPIO_NONE == mpin)) { // Skip SPI flash interface
if (!((1 == i) || (3 == i))) { // Skip serial if (!((1 == i) || (3 == i))) { // Skip serial
pinMode(i, INPUT); pinMode(i, INPUT);
} }

View File

@ -127,9 +127,10 @@
//#define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code) //#define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code)
//#define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) //#define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code)
//#define USE_MLX90640 // [I2cDriver53] Enable MLX90640 IR array temperature sensor (I2C address 0x33) (+20k code) //#define USE_MLX90640 // [I2cDriver53] Enable MLX90640 IR array temperature sensor (I2C address 0x33) (+20k code)
//#define USE_EZOPH // [I2cDriver55] Enable support for EZO's pH sensor (+0k6 code) - Shared EZO code required for any EZO device (+1k0 code) //#define USE_EZOPH // [I2cDriver55] Enable support for EZO's pH sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
//#define USE_EZOORP // [I2cDriver55] Enable support for EZO's ORP sensor (+0k6 code) - Shared EZO code required for any EZO device (+1k0 code) //#define USE_EZOORP // [I2cDriver55] Enable support for EZO's ORP sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
//#define USE_EZORTD // [I2cDriver55] Enable support for EZO's RTD sensor (+0k6 code) - Shared EZO code required for any EZO device (+1k0 code) //#define USE_EZORTD // [I2cDriver55] Enable support for EZO's RTD sensor (+0k2 code) - Shared EZO code required for any EZO device (+1k2 code)
//#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_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k 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) #define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)

View File

@ -101,8 +101,7 @@ enum UserSelectablePins {
GPIO_RDM6300_RX, // RDM6300 RX GPIO_RDM6300_RX, // RDM6300 RX
GPIO_IBEACON_TX, GPIO_IBEACON_RX, // HM17 IBEACON Serial interface GPIO_IBEACON_TX, GPIO_IBEACON_RX, // HM17 IBEACON Serial interface
GPIO_A4988_DIR, GPIO_A4988_STP, GPIO_A4988_ENA, GPIO_A4988_MS1, // A4988 interface GPIO_A4988_DIR, GPIO_A4988_STP, GPIO_A4988_ENA, GPIO_A4988_MS1, // A4988 interface
GPIO_SPARE1, // Do not use GPIO_OUTPUT_HI, GPIO_OUTPUT_LO, // Fixed output state
GPIO_SPARE2, // Do not use
GPIO_DDS2382_TX, GPIO_DDS2382_RX, // DDS2382 Serial interface GPIO_DDS2382_TX, GPIO_DDS2382_RX, // DDS2382 Serial interface
GPIO_DDSU666_TX, GPIO_DDSU666_RX, // DDSU666 Serial interface GPIO_DDSU666_TX, GPIO_DDSU666_RX, // DDSU666 Serial interface
GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller
@ -147,10 +146,8 @@ enum UserSelectablePins {
GPIO_IEM3000_TX, GPIO_IEM3000_RX, // IEM3000 Serial interface GPIO_IEM3000_TX, GPIO_IEM3000_RX, // IEM3000 Serial interface
GPIO_ZIGBEE_RST, // Zigbee reset GPIO_ZIGBEE_RST, // Zigbee reset
GPIO_DYP_RX, GPIO_DYP_RX,
GPIO_MIEL_HVAC_TX, // Mitsubishi Electric HVAC TX pin GPIO_MIEL_HVAC_TX, GPIO_MIEL_HVAC_RX, // Mitsubishi Electric HVAC
GPIO_MIEL_HVAC_RX, // Mitsubishi Electric HVAC RX pin GPIO_WE517_TX, GPIO_WE517_RX, // ORNO WE517 Serial interface
GPIO_WE517_TX, // ORNO WE517 Serial interface
GPIO_WE517_RX, // ORNO WE517 Serial interface
GPIO_SENSOR_END }; GPIO_SENSOR_END };
enum ProgramSelectablePins { enum ProgramSelectablePins {
@ -214,8 +211,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_RDM6300_RX "|" D_SENSOR_RDM6300_RX "|"
D_SENSOR_IBEACON_TX "|" D_SENSOR_IBEACON_RX "|" D_SENSOR_IBEACON_TX "|" D_SENSOR_IBEACON_RX "|"
D_SENSOR_A4988_DIR "|" D_SENSOR_A4988_STP "|" D_SENSOR_A4988_ENA "|" D_SENSOR_A4988_MS1 "|" D_SENSOR_A4988_DIR "|" D_SENSOR_A4988_STP "|" D_SENSOR_A4988_ENA "|" D_SENSOR_A4988_MS1 "|"
"s1|" D_SENSOR_OUTPUT_HI "|" D_SENSOR_OUTPUT_LO "|"
"s2|"
D_SENSOR_DDS2382_TX "|" D_SENSOR_DDS2382_RX "|" D_SENSOR_DDS2382_TX "|" D_SENSOR_DDS2382_RX "|"
D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|"
D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|"
@ -297,6 +293,8 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#endif #endif
AGPIO(GPIO_LEDLNK), // Link led AGPIO(GPIO_LEDLNK), // Link led
AGPIO(GPIO_LEDLNK_INV), // Inverted link led AGPIO(GPIO_LEDLNK_INV), // Inverted link led
AGPIO(GPIO_OUTPUT_HI), // Fixed output high
AGPIO(GPIO_OUTPUT_LO), // Fixed output low
/*-------------------------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------------------------*\
* Protocol specifics * Protocol specifics

View File

@ -381,6 +381,8 @@ const char Z_strings[] PROGMEM =
"TuyaFanMode" "\x00" "TuyaFanMode" "\x00"
"TuyaForceMode" "\x00" "TuyaForceMode" "\x00"
"TuyaWeekSelect" "\x00" "TuyaWeekSelect" "\x00"
"TerncyRotate" "\x00"
"TerncyDuration" "\x00"
"Identify" "\x00" "Identify" "\x00"
"xxxx" "\x00" "xxxx" "\x00"
"IdentifyQuery" "\x00" "IdentifyQuery" "\x00"
@ -780,95 +782,97 @@ enum Z_offsets {
Zo_TuyaFanMode = 5097, Zo_TuyaFanMode = 5097,
Zo_TuyaForceMode = 5109, Zo_TuyaForceMode = 5109,
Zo_TuyaWeekSelect = 5123, Zo_TuyaWeekSelect = 5123,
Zo_Identify = 5138, Zo_TerncyRotate = 5138,
Zo_xxxx = 5147, Zo_TerncyDuration = 5151,
Zo_IdentifyQuery = 5152, Zo_Identify = 5166,
Zo_AddGroup = 5166, Zo_xxxx = 5175,
Zo_xxxx00 = 5175, Zo_IdentifyQuery = 5180,
Zo_ViewGroup = 5182, Zo_AddGroup = 5194,
Zo_GetGroup = 5192, Zo_xxxx00 = 5203,
Zo_01xxxx = 5201, Zo_ViewGroup = 5210,
Zo_GetAllGroups = 5208, Zo_GetGroup = 5220,
Zo_00 = 5221, Zo_01xxxx = 5229,
Zo_RemoveGroup = 5224, Zo_GetAllGroups = 5236,
Zo_RemoveAllGroups = 5236, Zo_00 = 5249,
Zo_ViewScene = 5252, Zo_RemoveGroup = 5252,
Zo_xxxxyy = 5262, Zo_RemoveAllGroups = 5264,
Zo_RemoveScene = 5269, Zo_ViewScene = 5280,
Zo_RemoveAllScenes = 5281, Zo_xxxxyy = 5290,
Zo_RecallScene = 5297, Zo_RemoveScene = 5297,
Zo_GetSceneMembership = 5309, Zo_RemoveAllScenes = 5309,
Zo_PowerOffEffect = 5328, Zo_RecallScene = 5325,
Zo_xxyy = 5343, Zo_GetSceneMembership = 5337,
Zo_PowerOnRecall = 5348, Zo_PowerOffEffect = 5356,
Zo_PowerOnTimer = 5362, Zo_xxyy = 5371,
Zo_xxyyyyzzzz = 5375, Zo_PowerOnRecall = 5376,
Zo_xx0A00 = 5386, Zo_PowerOnTimer = 5390,
Zo_DimmerUp = 5393, Zo_xxyyyyzzzz = 5403,
Zo_00190200 = 5402, Zo_xx0A00 = 5414,
Zo_DimmerDown = 5411, Zo_DimmerUp = 5421,
Zo_01190200 = 5422, Zo_00190200 = 5430,
Zo_DimmerStop = 5431, Zo_DimmerDown = 5439,
Zo_ResetAlarm = 5442, Zo_01190200 = 5450,
Zo_xxyyyy = 5453, Zo_DimmerStop = 5459,
Zo_ResetAllAlarms = 5460, Zo_ResetAlarm = 5470,
Zo_xx000A00 = 5475, Zo_xxyyyy = 5481,
Zo_HueSat = 5484, Zo_ResetAllAlarms = 5488,
Zo_xxyy0A00 = 5491, Zo_xx000A00 = 5503,
Zo_Color = 5500, Zo_HueSat = 5512,
Zo_xxxxyyyy0A00 = 5506, Zo_xxyy0A00 = 5519,
Zo_xxxx0A00 = 5519, Zo_Color = 5528,
Zo_ShutterOpen = 5528, Zo_xxxxyyyy0A00 = 5534,
Zo_ShutterClose = 5540, Zo_xxxx0A00 = 5547,
Zo_ShutterStop = 5553, Zo_ShutterOpen = 5556,
Zo_ShutterLift = 5565, Zo_ShutterClose = 5568,
Zo_xx = 5577, Zo_ShutterStop = 5581,
Zo_ShutterTilt = 5580, Zo_ShutterLift = 5593,
Zo_Shutter = 5592, Zo_xx = 5605,
Zo_DimmerMove = 5600, Zo_ShutterTilt = 5608,
Zo_xx0A = 5611, Zo_Shutter = 5620,
Zo_DimmerStepUp = 5616, Zo_DimmerMove = 5628,
Zo_00xx0A00 = 5629, Zo_xx0A = 5639,
Zo_DimmerStepDown = 5638, Zo_DimmerStepUp = 5644,
Zo_01xx0A00 = 5653, Zo_00xx0A00 = 5657,
Zo_DimmerStep = 5662, Zo_DimmerStepDown = 5666,
Zo_xx190A00 = 5673, Zo_01xx0A00 = 5681,
Zo_01 = 5682, Zo_DimmerStep = 5690,
Zo_HueMove = 5685, Zo_xx190A00 = 5701,
Zo_xx19 = 5693, Zo_01 = 5710,
Zo_HueStepUp = 5698, Zo_HueMove = 5713,
Zo_HueStepDown = 5708, Zo_xx19 = 5721,
Zo_03xx0A00 = 5720, Zo_HueStepUp = 5726,
Zo_HueStep = 5729, Zo_HueStepDown = 5736,
Zo_SatMove = 5737, Zo_03xx0A00 = 5748,
Zo_SatStep = 5745, Zo_HueStep = 5757,
Zo_xx190A = 5753, Zo_SatMove = 5765,
Zo_ColorMove = 5760, Zo_SatStep = 5773,
Zo_xxxxyyyy = 5770, Zo_xx190A = 5781,
Zo_ColorStep = 5779, Zo_ColorMove = 5788,
Zo_ColorTempMoveUp = 5789, Zo_xxxxyyyy = 5798,
Zo_01xxxx000000000000 = 5805, Zo_ColorStep = 5807,
Zo_ColorTempMoveDown = 5824, Zo_ColorTempMoveUp = 5817,
Zo_03xxxx000000000000 = 5842, Zo_01xxxx000000000000 = 5833,
Zo_ColorTempMoveStop = 5861, Zo_ColorTempMoveDown = 5852,
Zo_00xxxx000000000000 = 5879, Zo_03xxxx000000000000 = 5870,
Zo_ColorTempMove = 5898, Zo_ColorTempMoveStop = 5889,
Zo_xxyyyy000000000000 = 5912, Zo_00xxxx000000000000 = 5907,
Zo_ColorTempStepUp = 5931, Zo_ColorTempMove = 5926,
Zo_01xxxx0A0000000000 = 5947, Zo_xxyyyy000000000000 = 5940,
Zo_ColorTempStepDown = 5966, Zo_ColorTempStepUp = 5959,
Zo_03xxxx0A0000000000 = 5984, Zo_01xxxx0A0000000000 = 5975,
Zo_ColorTempStep = 6003, Zo_ColorTempStepDown = 5994,
Zo_xxyyyy0A0000000000 = 6017, Zo_03xxxx0A0000000000 = 6012,
Zo_ArrowClick = 6036, Zo_ColorTempStep = 6031,
Zo_ArrowHold = 6047, Zo_xxyyyy0A0000000000 = 6045,
Zo_ArrowRelease = 6057, Zo_ArrowClick = 6064,
Zo_ZoneStatusChange = 6070, Zo_ArrowHold = 6075,
Zo_xxxxyyzz = 6087, Zo_ArrowRelease = 6085,
Zo_xxyyzzzz = 6096, Zo_ZoneStatusChange = 6098,
Zo_AddScene = 6105, Zo_xxxxyyzz = 6115,
Zo_xxyyyyzz = 6114, Zo_xxyyzzzz = 6124,
Zo_StoreScene = 6123, Zo_AddScene = 6133,
Zo_xxyyyyzz = 6142,
Zo_StoreScene = 6151,
}; };

View File

@ -129,7 +129,7 @@ enum Cx_cluster_short {
Cx0010, Cx0011, Cx0012, Cx0013, Cx0014, Cx001A, Cx0020, Cx0100, Cx0010, Cx0011, Cx0012, Cx0013, Cx0014, Cx001A, Cx0020, Cx0100,
Cx0101, Cx0102, Cx0201, Cx0300, Cx0400, Cx0401, Cx0402, Cx0403, Cx0101, Cx0102, Cx0201, Cx0300, Cx0400, Cx0401, Cx0402, Cx0403,
Cx0404, Cx0405, Cx0406, Cx0500, Cx0702, Cx0B01, Cx0B04, Cx0B05, Cx0404, Cx0405, Cx0406, Cx0500, Cx0702, Cx0B01, Cx0B04, Cx0B05,
CxEF00, CxEF00, CxFCCC,
}; };
const uint16_t Cx_cluster[] PROGMEM = { const uint16_t Cx_cluster[] PROGMEM = {
@ -138,7 +138,7 @@ const uint16_t Cx_cluster[] PROGMEM = {
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x001A, 0x0020, 0x0100, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x001A, 0x0020, 0x0100,
0x0101, 0x0102, 0x0201, 0x0300, 0x0400, 0x0401, 0x0402, 0x0403, 0x0101, 0x0102, 0x0201, 0x0300, 0x0400, 0x0401, 0x0402, 0x0403,
0x0404, 0x0405, 0x0406, 0x0500, 0x0702, 0x0B01, 0x0B04, 0x0B05, 0x0404, 0x0405, 0x0406, 0x0500, 0x0702, 0x0B01, 0x0B04, 0x0B05,
0xEF00, 0xEF00, 0xFCCC,
}; };
uint16_t CxToCluster(uint8_t cx) { uint16_t CxToCluster(uint8_t cx) {
@ -611,6 +611,10 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
{ Ztuya1, CxEF00, 0x0405, Z_(TuyaFanMode), Cm1, 0 }, { Ztuya1, CxEF00, 0x0405, Z_(TuyaFanMode), Cm1, 0 },
{ Ztuya1, CxEF00, 0x046A, Z_(TuyaForceMode), Cm1, 0 }, { Ztuya1, CxEF00, 0x046A, Z_(TuyaForceMode), Cm1, 0 },
{ Ztuya1, CxEF00, 0x046F, Z_(TuyaWeekSelect), Cm1, 0 }, { Ztuya1, CxEF00, 0x046F, Z_(TuyaWeekSelect), Cm1, 0 },
// Terncy specific - 0xFCCC
{ Zuint16, CxFCCC, 0x001A, Z_(TerncyDuration), Cm1, 0 },
{ Zint16, CxFCCC, 0x001B, Z_(TerncyRotate), Cm1, 0 },
}; };
#pragma GCC diagnostic pop #pragma GCC diagnostic pop

View File

@ -136,6 +136,8 @@ const Z_CommandConverter Z_Commands[] PROGMEM = {
{ Z_(GetSceneMembership),0x0005, 0x06, 0x82,Z_(xxyyzzzz) }, // specific { Z_(GetSceneMembership),0x0005, 0x06, 0x82,Z_(xxyyzzzz) }, // specific
// Tuya - Moes specific // Tuya - Moes specific
{ Z_(), 0xEF00, 0xFF, 0x83, Z_() }, // capture any command in 0xEF00 cluster { Z_(), 0xEF00, 0xFF, 0x83, Z_() }, // capture any command in 0xEF00 cluster
// Terncy specific
{ Z_(), 0xFCCC, 0x00, 0x82, Z_(xxyy) }, // Terncy button (multi-)press
}; };
/*********************************************************************************************\ /*********************************************************************************************\
@ -419,6 +421,10 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster,
attr_list.removeAttribute(&attr_raw); // remove raw command attr_list.removeAttribute(&attr_raw); // remove raw command
} }
break; break;
case 0xFCCC0000: // Terncy button (multi-)press
attr_list.addAttribute(PSTR("TerncyPress"), true).setUInt(xyz.y);
attr_list.addAttribute(PSTR("TerncyCount"), true).setUInt(xyz.x);
break;
} }
} else { // general case } else { // general case
// do we send command with endpoint suffix // do we send command with endpoint suffix

View File

@ -814,10 +814,15 @@ uint32_t WcSetStreamserver(uint32_t flag) {
if (flag) { if (flag) {
if (!CamServer) { if (!CamServer) {
CamServer = new ESP8266WebServer(81); CamServer = new ESP8266WebServer(81);
WebServer_on(PSTR("/"), HandleWebcamRoot); CamServer->on("/", HandleWebcamRoot);
WebServer_on(PSTR("/cam.mjpeg"), HandleWebcamMjpeg); CamServer->on("/cam.mjpeg", HandleWebcamMjpeg);
WebServer_on(PSTR("/cam.jpg"), HandleWebcamMjpeg); CamServer->on("/cam.jpg", HandleWebcamMjpeg);
WebServer_on(PSTR("/stream"), HandleWebcamMjpeg); CamServer->on("/stream", HandleWebcamMjpeg);
// WebServer_on(PSTR("/"), HandleWebcamRoot);
// WebServer_on(PSTR("/cam.mjpeg"), HandleWebcamMjpeg);
// WebServer_on(PSTR("/cam.jpg"), HandleWebcamMjpeg);
// WebServer_on(PSTR("/stream"), HandleWebcamMjpeg);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Stream init")); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Stream init"));
CamServer->begin(); CamServer->begin();
} }

View File

@ -32,7 +32,28 @@
* GPIO27 - EMAC_RX_CRS_DV * GPIO27 - EMAC_RX_CRS_DV
* *
* {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} * {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
* GPIO12 = ETH POWER
* GPIO18 = ETH MDIO
* GPIO23 = ETH MDC
* #define ETH_TYPE ETH_PHY_LAN8720
* #define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT
* #define ETH_ADDR 0
*
* {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} * {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
* GPIO16 = ETH MDC
* GPIO17 = ETH MDIO
* #define ETH_TYPE ETH_PHY_LAN8720
* #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN
* #define ETH_ADDR 0
*
* {"NAME":"WT32-ETH01","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1],"FLAG":0,"BASE":1}
* GPIO16 = Force Hi
* GPIO18 = ETH MDIO
* GPIO23 = ETH MDC
* #define ETH_TYPE ETH_PHY_LAN8720
* #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN
* #define ETH_ADDR 1
*
\*********************************************************************************************/ \*********************************************************************************************/
#define XDRV_82 82 #define XDRV_82 82
@ -68,19 +89,12 @@ void EthernetEvent(WiFiEvent_t event) {
ETH.setHostname(eth_hostname); ETH.setHostname(eth_hostname);
break; break;
case SYSTEM_EVENT_ETH_CONNECTED: case SYSTEM_EVENT_ETH_CONNECTED:
AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED)); AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED " at %dMbps%s"),
ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "");
break; break;
case SYSTEM_EVENT_ETH_GOT_IP: case SYSTEM_EVENT_ETH_GOT_IP:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"), AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"),
ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), eth_hostname); ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), eth_hostname);
/*
if (ETH.fullDuplex()) {
Serial.print(", FULL_DUPLEX");
}
Serial.print(", ");
Serial.print(ETH.linkSpeed());
Serial.println("Mbps");
*/
Settings.ip_address[1] = (uint32_t)ETH.gatewayIP(); Settings.ip_address[1] = (uint32_t)ETH.gatewayIP();
Settings.ip_address[2] = (uint32_t)ETH.subnetMask(); Settings.ip_address[2] = (uint32_t)ETH.subnetMask();
Settings.ip_address[3] = (uint32_t)ETH.dnsIP(); Settings.ip_address[3] = (uint32_t)ETH.dnsIP();

View File

@ -20,6 +20,8 @@
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
Version yyyymmdd Action Description Version yyyymmdd Action Description
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
0.9.1.6 20201022 changed - Beacon support, RSSI at TELEPERIOD, refactoring
-------
0.9.1.5 20201021 changed - HASS related ('null', hold back discovery), number of found sensors for RULES 0.9.1.5 20201021 changed - HASS related ('null', hold back discovery), number of found sensors for RULES
------- -------
0.9.1.4 20201020 changed - use BearSSL for decryption, revert to old TELEPERIOD-cycle as default 0.9.1.4 20201020 changed - use BearSSL for decryption, revert to old TELEPERIOD-cycle as default
@ -57,7 +59,6 @@
void MI32scanEndedCB(NimBLEScanResults results); void MI32scanEndedCB(NimBLEScanResults results);
void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify); void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify);
struct { struct {
uint16_t perPage = 4; uint16_t perPage = 4;
uint32_t period; // set manually in addition to TELE-period, is set to TELE-period after start uint32_t period; // set manually in addition to TELE-period, is set to TELE-period after start
@ -82,11 +83,13 @@ struct {
uint32_t shallClearResults:1; // BLE scan results uint32_t shallClearResults:1; // BLE scan results
uint32_t shallShowStatusInfo:1; // react to amount of found sensors via RULES uint32_t shallShowStatusInfo:1; // react to amount of found sensors via RULES
uint32_t firstAutodiscoveryDone:1; uint32_t firstAutodiscoveryDone:1;
uint32_t activeBeacon;
}; };
uint32_t all = 0; uint32_t all = 0;
} mode; } mode;
struct { struct {
uint8_t sensor; // points to to the number 0...255 uint8_t sensor; // points to to the number 0...255
uint8_t beaconScanCounter; // countdown timer in seconds
} state; } state;
struct { struct {
uint32_t allwaysAggregate:1; // always show all known values of one sensor in brdigemode uint32_t allwaysAggregate:1; // always show all known values of one sensor in brdigemode
@ -226,7 +229,7 @@ struct mi_sensor_t{
uint32_t raw; uint32_t raw;
} eventType; } eventType;
int rssi; int RSSI;
uint32_t lastTime; uint32_t lastTime;
uint32_t lux; uint32_t lux;
float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx
@ -250,8 +253,28 @@ struct mi_sensor_t{
}; };
}; };
struct scan_entry_t {
uint8_t MAC[6];
uint16_t CID;
uint16_t SVC;
uint16_t UUID;
int32_t RSSI;
};
struct generic_beacon_t {
uint8_t MAC[6];
uint32_t time;
int32_t RSSI;
uint16_t CID; // company identifier
uint16_t UUID; // the first, if more than one exists
uint16_t SVC;
bool active = false;
};
std::vector<mi_sensor_t> MIBLEsensors; std::vector<mi_sensor_t> MIBLEsensors;
std::vector<mi_bindKey_t> MIBLEbindKeys; std::vector<mi_bindKey_t> MIBLEbindKeys;
std::array<generic_beacon_t,4> MIBLEbeacons; // we support a fixed number
std::vector<scan_entry_t> MINBLEscanResult;
static BLEScan* MI32Scan; static BLEScan* MI32Scan;
@ -263,7 +286,9 @@ static BLEScan* MI32Scan;
const char S_JSON_MI32_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%d}"; const char S_JSON_MI32_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%d}";
const char S_JSON_MI32_COMMAND[] PROGMEM = "{\"" D_CMND_MI32 "%s%s\"}"; const char S_JSON_MI32_COMMAND[] PROGMEM = "{\"" D_CMND_MI32 "%s%s\"}";
const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit|Key"; // const char S_JSON_MI32_BCOMMAND_SVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%s}";
const char S_JSON_MI32_BCOMMAND_SVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s%u\":\"%s\"}";
const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit|Key|Beacon";
#define FLORA 1 #define FLORA 1
#define MJ_HT_V1 2 #define MJ_HT_V1 2
@ -318,7 +343,8 @@ enum MI32_Commands { // commands useable in console or rules
CMND_MI32_PAGE, // sensor entries per web page, which will be shown alternated CMND_MI32_PAGE, // sensor entries per web page, which will be shown alternated
CMND_MI32_BATTERY, // read all battery levels CMND_MI32_BATTERY, // read all battery levels
CMND_MI32_UNIT, // toggles the displayed unit between C/F (LYWSD02) CMND_MI32_UNIT, // toggles the displayed unit between C/F (LYWSD02)
CMND_MI32_KEY // add bind key to a mac for packet decryption CMND_MI32_KEY, // add bind key to a mac for packet decryption
CMND_MI32_BEACON // add up to 4 beacons defined by their MAC addresses
}; };
enum MI32_TASK { enum MI32_TASK {
@ -329,6 +355,12 @@ enum MI32_TASK {
MI32_TASK_UNIT = 4, MI32_TASK_UNIT = 4,
}; };
enum MI32_BEACON_CMND {
MI32_BEACON_ON = 0,
MI32_BEACON_OFF = 1,
MI32_BEACON_DEL = 2,
};
/*********************************************************************************************\ /*********************************************************************************************\
* Classes * Classes
\*********************************************************************************************/ \*********************************************************************************************/
@ -360,32 +392,40 @@ class MI32SensorCallback : public NimBLEClientCallbacks {
class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks {
void onResult(NimBLEAdvertisedDevice* advertisedDevice) { void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length()); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length());
if (advertisedDevice->getServiceDataCount() == 0) { int RSSI = advertisedDevice->getRSSI();
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length());
MI32Scan->erase(advertisedDevice->getAddress());
return;
}
uint16_t uuid = advertisedDevice->getServiceDataUUID(0).getNative()->u16.value;
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("UUID: %x"),uuid);
uint8_t addr[6]; uint8_t addr[6];
memcpy(addr,advertisedDevice->getAddress().getNative(),6); memcpy(addr,advertisedDevice->getAddress().getNative(),6);
MI32_ReverseMAC(addr); MI32_ReverseMAC(addr);
int rssi = 0xffff; if (advertisedDevice->getServiceDataCount() == 0) {
if(advertisedDevice->haveRSSI()) { // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length());
rssi = advertisedDevice->getRSSI(); if(MI32.state.beaconScanCounter==0 && !MI32.mode.activeBeacon){
MI32Scan->erase(advertisedDevice->getAddress());
return;
}
else{
MI32HandleGenericBeacon(advertisedDevice->getPayload(), advertisedDevice->getPayloadLength(), RSSI, addr);
return;
}
} }
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("RSSI: %d"),rssi); // actually i never got a 0xffff uint16_t UUID = advertisedDevice->getServiceDataUUID(0).getNative()->u16.value;
if(uuid==0xfe95) { // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("UUID: %x"),UUID);
MI32ParseResponse((char*)advertisedDevice->getServiceData(0).data(),advertisedDevice->getServiceData(0).length(), addr, rssi);
size_t ServiceDataLength = advertisedDevice->getServiceData(0).length();
if(UUID==0xfe95) {
MI32ParseResponse((char*)advertisedDevice->getServiceData(0).data(),ServiceDataLength, addr, RSSI);
} }
else if(uuid==0xfdcd) { else if(UUID==0xfdcd) {
MI32parseCGD1Packet((char*)advertisedDevice->getServiceData(0).data(),advertisedDevice->getServiceData(0).length(), addr, rssi); MI32parseCGD1Packet((char*)advertisedDevice->getServiceData(0).data(),ServiceDataLength, addr, RSSI);
} }
else if(uuid==0x181a) { //ATC else if(UUID==0x181a) { //ATC
MI32ParseATCPacket((char*)advertisedDevice->getServiceData(0).data(),advertisedDevice->getServiceData(0).length(), addr, rssi); MI32ParseATCPacket((char*)advertisedDevice->getServiceData(0).data(),ServiceDataLength, addr, RSSI);
} }
else { else {
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %x: %s Buffer: %u"), uuid, advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length()); if(MI32.state.beaconScanCounter!=0 || MI32.mode.activeBeacon){
MI32HandleGenericBeacon(advertisedDevice->getPayload(), advertisedDevice->getPayloadLength(), RSSI, addr);
}
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %x: %s Buffer: %u"), UUID, advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length());
MI32Scan->erase(advertisedDevice->getAddress()); MI32Scan->erase(advertisedDevice->getAddress());
} }
}; };
@ -421,6 +461,54 @@ void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pD
* Helper functions * Helper functions
\*********************************************************************************************/ \*********************************************************************************************/
/**
* @brief Remove all colons from null terminated char array
*
* @param _string Typically representing a MAC-address like AA:BB:CC:DD:EE:FF
*/
void MI32stripColon(char* _string){
uint32_t _length = strlen(_string);
uint32_t _index = 0;
while (_index < _length) {
char c = _string[_index];
if(c==':'){
memmove(_string+_index,_string+_index+1,_length-_index);
}
_index++;
}
_string[_index] = 0;
}
/**
* @brief Convert string that repesents a hexadecimal number to a byte array
*
* @param _string input string in format: AABBCCDDEEFF or AA:BB:CC:DD:EE:FF, caseinsensitive
* @param _mac target byte array must match the correct size (i.e. AA:BB -> uint8_t bytes[2])
*/
void MI32HexStringToBytes(char* _string, uint8_t* _byteArray) {
MI32stripColon(_string);
UpperCase(_string,_string);
uint32_t index = 0;
uint32_t _end = strlen(_string);
memset(_byteArray,0,_end/2);
while (index < _end) {
char c = _string[index];
uint8_t value = 0;
if(c >= '0' && c <= '9')
value = (c - '0');
else if (c >= 'A' && c <= 'F')
value = (10 + (c - 'A'));
_byteArray[(index/2)] += value << (((index + 1) % 2) * 4);
index++;
}
}
/**
* @brief Reverse an array of 6 bytes
*
* @param _mac a byte array of size 6 (typicalliy representing a MAC address)
*/
void MI32_ReverseMAC(uint8_t _mac[]){ void MI32_ReverseMAC(uint8_t _mac[]){
uint8_t _reversedMAC[6]; uint8_t _reversedMAC[6];
for (uint8_t i=0; i<6; i++){ for (uint8_t i=0; i<6; i++){
@ -432,9 +520,7 @@ void MI32_ReverseMAC(uint8_t _mac[]){
#ifdef USE_MI_DECRYPTION #ifdef USE_MI_DECRYPTION
void MI32AddKey(char* payload){ void MI32AddKey(char* payload){
mi_bindKey_t keyMAC; mi_bindKey_t keyMAC;
memset(keyMAC.buf,0,sizeof(keyMAC)); MI32HexStringToBytes(payload,keyMAC.buf);
UpperCase(payload,payload);
MI32KeyMACStringToBytes(payload,keyMAC.buf);
bool unknownKey = true; bool unknownKey = true;
for(uint32_t i=0; i<MIBLEbindKeys.size(); i++){ for(uint32_t i=0; i<MIBLEbindKeys.size(); i++){
if(memcmp(keyMAC.MAC,MIBLEbindKeys[i].MAC,sizeof(keyMAC.MAC))==0){ if(memcmp(keyMAC.MAC,MIBLEbindKeys[i].MAC,sizeof(keyMAC.MAC))==0){
@ -448,29 +534,6 @@ void MI32AddKey(char* payload){
} }
} }
/**
* @brief Convert combined key-MAC-string to
*
* @param _string input string in format: AABBCCDDEEFF... (upper case!), must be 44 chars!!
* @param _mac target byte array with fixed size of 16 + 6
*/
void MI32KeyMACStringToBytes(char* _string,uint8_t _keyMAC[]) { //uppercase
uint32_t index = 0;
while (index < 44) {
char c = _string[index];
uint8_t value = 0;
if(c >= '0' && c <= '9')
value = (c - '0');
else if (c >= 'A' && c <= 'F')
value = (10 + (c - 'A'));
_keyMAC[(index/2)] += value << (((index + 1) % 2) * 4);
index++;
}
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: %s to:"),_string);
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMAC[0],_keyMAC[1],_keyMAC[2],_keyMAC[3],_keyMAC[4],_keyMAC[5],_keyMAC[6],_keyMAC[7],_keyMAC[8],_keyMAC[9],_keyMAC[10],_keyMAC[11],_string,_keyMAC[12],_keyMAC[13],_keyMAC[14],_keyMAC[15]);
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMAC[16],_keyMAC[17],_keyMAC[18],_keyMAC[19],_keyMAC[20],_keyMAC[21]);
}
/** /**
* @brief Decrypts payload in place * @brief Decrypts payload in place
* *
@ -533,10 +596,7 @@ int MI32_decryptPacket(char *_buf, uint16_t _bufSize, uint32_t _type){
br_ccm_run(&ctx, 0, payload, data_len); br_ccm_run(&ctx, 0, payload, data_len);
memcpy((uint8_t*)packet->payload+1,payload,data_len); //back to the packet memcpy((uint8_t*)packet->payload+1,payload,data_len); //back to the packet
// br_ccm_get_tag(&ctx, &checkTag);
ret = br_ccm_check_tag(&ctx, &tag); ret = br_ccm_check_tag(&ctx, &tag);
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("packetTag: %08x"),tag);
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("computedTag: %08x"),checkTag);
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, packet->payload[1],packet->payload[2],packet->payload[3],packet->payload[4],packet->payload[5]); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, packet->payload[1],packet->payload[2],packet->payload[3],packet->payload[4],packet->payload[5]);
return ret-1; return ret-1;
@ -611,7 +671,7 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter)
_newSensor.feature.raw = 0; _newSensor.feature.raw = 0;
_newSensor.temp =NAN; _newSensor.temp =NAN;
_newSensor.bat=0x00; _newSensor.bat=0x00;
_newSensor.rssi=0xffff; _newSensor.RSSI=0xffff;
_newSensor.lux = 0x00ffffff; _newSensor.lux = 0x00ffffff;
switch (_type) switch (_type)
{ {
@ -670,6 +730,10 @@ void MI32triggerTele(void){
} }
} }
/**
* @brief Is called after every finding of new BLE sensor
*
*/
void MI32StatusInfo() { void MI32StatusInfo() {
MI32.mode.shallShowStatusInfo = 0; MI32.mode.shallShowStatusInfo = 0;
Response_P(PSTR("{\"%s\":{\"found\":%u}}"), D_CMND_MI32, MIBLEsensors.size()); Response_P(PSTR("{\"%s\":{\"found\":%u}}"), D_CMND_MI32, MIBLEsensors.size());
@ -684,6 +748,7 @@ void MI32Init(void) {
MIBLEsensors.reserve(10); MIBLEsensors.reserve(10);
MIBLEbindKeys.reserve(10); MIBLEbindKeys.reserve(10);
MINBLEscanResult.reserve(20);
MI32.mode.init = false; MI32.mode.init = false;
if (!MI32.mode.init) { if (!MI32.mode.init) {
NimBLEDevice::init(""); NimBLEDevice::init("");
@ -1167,6 +1232,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot, uint16_t _bufSize){
decryptRet = MI32_decryptPacket((char*)&_beacon.productID,_bufSize, LYWSD03MMC); //start with PID decryptRet = MI32_decryptPacket((char*)&_beacon.productID,_bufSize, LYWSD03MMC); //start with PID
// AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*)&_beacon.productID,_bufSize); // AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*)&_beacon.productID,_bufSize);
} }
else return; // 0x3058 holds no data, TODO: check for unpaired devices, that need connections
break; break;
case MJYD2S: case MJYD2S:
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MJYD2S: %x"),_beacon.frame); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MJYD2S: %x"),_beacon.frame);
@ -1180,18 +1246,6 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot, uint16_t _bufSize){
if (_beacon.frame != 0x5910){ if (_beacon.frame != 0x5910){
decryptRet = MI32_decryptPacket((char*)&_beacon.productID,_bufSize,MJYD2S); //start with PID decryptRet = MI32_decryptPacket((char*)&_beacon.productID,_bufSize,MJYD2S); //start with PID
} }
else{
// This seems to be some kind of wake-up packet only, as it shows up before all kinds of messages, not only motion
// if(millis()-MIBLEsensors[_slot].lastTime>120000){
// MIBLEsensors[_slot].eventType = 1;
// MIBLEsensors[_slot].events++;
// MIBLEsensors[_slot].shallSendMQTT = 1;
// MIBLEsensors[_slot].lastTime = millis();
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MJYD2S secondary PIR"));
// MIBLEsensors[_slot].NMT = 0;
// MI32.mode.shallTriggerTele = 1;
// }
}
break; break;
} }
if(decryptRet!=0){ if(decryptRet!=0){
@ -1315,13 +1369,13 @@ if(decryptRet!=0){
if(MI32.option.directBridgeMode) MI32.mode.shallTriggerTele = 1; if(MI32.option.directBridgeMode) MI32.mode.shallTriggerTele = 1;
} }
void MI32ParseATCPacket(char * _buf, uint32_t length, uint8_t addr[6], int rssi){ void MI32ParseATCPacket(char * _buf, uint32_t length, uint8_t addr[6], int RSSI){
ATCPacket_t *_packet = (ATCPacket_t*)_buf; ATCPacket_t *_packet = (ATCPacket_t*)_buf;
uint32_t _slot = MIBLEgetSensorSlot(_packet->MAC, 0x0a1c, _packet->frameCnt); // This must be a hard-coded fake ID uint32_t _slot = MIBLEgetSensorSlot(_packet->MAC, 0x0a1c, _packet->frameCnt); // This must be a hard-coded fake ID
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot);
if(_slot==0xff) return; if(_slot==0xff) return;
MIBLEsensors[_slot].rssi=rssi; MIBLEsensors[_slot].RSSI=RSSI;
MIBLEsensors.at(_slot).temp = (float)(__builtin_bswap16(_packet->temp))/10.0f; MIBLEsensors.at(_slot).temp = (float)(__builtin_bswap16(_packet->temp))/10.0f;
MIBLEsensors.at(_slot).hum = (float)_packet->hum; MIBLEsensors.at(_slot).hum = (float)_packet->hum;
@ -1334,13 +1388,13 @@ void MI32ParseATCPacket(char * _buf, uint32_t length, uint8_t addr[6], int rssi)
} }
void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi){ // no MiBeacon void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int RSSI){ // no MiBeacon
uint8_t _addr[6]; uint8_t _addr[6];
memcpy(_addr,addr,6); memcpy(_addr,addr,6);
uint32_t _slot = MIBLEgetSensorSlot(_addr, 0x0576, 0); // This must be hard-coded, no object-id in Cleargrass-packet, we have no packet counter too uint32_t _slot = MIBLEgetSensorSlot(_addr, 0x0576, 0); // This must be hard-coded, no object-id in Cleargrass-packet, we have no packet counter too
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot);
if(_slot==0xff) return; if(_slot==0xff) return;
MIBLEsensors[_slot].rssi=rssi; MIBLEsensors[_slot].RSSI=RSSI;
cg_packet_t _packet; cg_packet_t _packet;
memcpy((char*)&_packet,_buf,sizeof(_packet)); memcpy((char*)&_packet,_buf,sizeof(_packet));
switch (_packet.mode){ switch (_packet.mode){
@ -1375,7 +1429,7 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi
if(MI32.option.directBridgeMode) MI32.mode.shallTriggerTele = 1; if(MI32.option.directBridgeMode) MI32.mode.shallTriggerTele = 1;
} }
void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int rssi) { void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int RSSI) {
if(bufsize<9) { //9 is from the NLIGHT if(bufsize<9) { //9 is from the NLIGHT
return; return;
} }
@ -1385,11 +1439,137 @@ void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int rssi) {
memcpy(_addr,addr,6); memcpy(_addr,addr,6);
uint16_t _slot = MIBLEgetSensorSlot(_addr, _type, buf[4]); uint16_t _slot = MIBLEgetSensorSlot(_addr, _type, buf[4]);
if(_slot!=0xff) { if(_slot!=0xff) {
MIBLEsensors[_slot].rssi=rssi; MIBLEsensors[_slot].RSSI=RSSI;
MI32parseMiBeacon(buf,_slot,bufsize); MI32parseMiBeacon(buf,_slot,bufsize);
} }
} }
/**
* @brief Parse a BLE advertisement packet
*
* @param payload
* @param payloadLength
* @param CID
* @param SVC
* @param UUID
*/
void MI32ParseGenericBeacon(uint8_t* payload, size_t payloadLength, uint16_t* CID, uint16_t*SVC, uint16_t* UUID){
AddLog_P2(LOG_LEVEL_DEBUG_MORE,PSTR("MI32: Beacon:____________"));
for (uint32_t i = 0; i<payloadLength;){
uint32_t ADtype = payload[i+1];
uint32_t offset = payload[i];
switch(ADtype){
case 0x01:
AddLog_P2(LOG_LEVEL_DEBUG_MORE,PSTR("Flags: %02x"), payload[i+2]);
break;
case 0x02: case 0x03:
*UUID = payload[i+3]*256 + payload[i+2];
AddLog_P2(LOG_LEVEL_DEBUG_MORE,PSTR("UUID: %04x"), *UUID);
break;
case 0x08: case 0x09:
{
uint8_t _saveChar = payload[i+offset+1];
payload[i+offset+1] = 0;
AddLog_P2(LOG_LEVEL_DEBUG_MORE,PSTR("Name: %s"), (char*)&payload[i+2]);
payload[i+offset+1] = _saveChar;
}
break;
case 0x0a:
AddLog_P2(LOG_LEVEL_DEBUG_MORE,PSTR("TxPow: %02u"), payload[i+2]);
break;
case 0xff:
*CID = payload[i+3]*256 + payload[i+2];
AddLog_P2(LOG_LEVEL_DEBUG_MORE,PSTR("CID: %04x"), *CID);
break;
case 0x16:
*SVC = payload[i+3]*256 + payload[i+2];
AddLog_P2(LOG_LEVEL_DEBUG_MORE,PSTR("SVC: %04x"), *SVC);
break;
}
i+=offset+1;
}
}
/**
* @brief Handle a generic BLE advertisment in a running scan or to check a beacon
*
* @param payload
* @param payloadLength
* @param RSSI
* @param addr
*/
void MI32HandleGenericBeacon(uint8_t* payload, size_t payloadLength, int RSSI, uint8_t* addr){
if(MI32.state.beaconScanCounter==0){ //handle beacon
for(auto &_beacon : MIBLEbeacons){
if(memcmp(addr,_beacon.MAC,6)==0){
MI32ParseGenericBeacon(payload,payloadLength,&_beacon.CID,&_beacon.SVC,&_beacon.UUID);
_beacon.time = 0;
_beacon.RSSI = RSSI;
return;
}
}
return;
}
// else handle scan
if(MINBLEscanResult.size()>19) {
AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: Scan buffer full"));
MI32.state.beaconScanCounter = 1;
return;
}
for(auto _scanResult : MINBLEscanResult){
if(memcmp(addr,_scanResult.MAC,6)==0){
// AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: known device"));
return;
}
}
scan_entry_t _new;
_new.RSSI = RSSI;
_new.CID = 0;
_new.SVC = 0;
_new.UUID = 0;
memcpy(_new.MAC,addr,sizeof(_new.MAC));
MI32ParseGenericBeacon(payload,payloadLength,&_new.CID,&_new.SVC,&_new.UUID);
MINBLEscanResult.push_back(_new);
}
/**
* @brief Add a beacon defined by its MAC-address, if only zeros are given, the beacon will be deactivated
*
* @param index 1-4 beacons are currently supported
* @param data null terminated char array representing a MAC-address in hex
*/
void MI32addBeacon(uint8_t index, char* data){
auto &_new = MIBLEbeacons[index-1]; //TODO: check
MI32HexStringToBytes(data,_new.MAC);
char _MAC[18];
ToHex_P(MIBLEbeacons[index-1].MAC,6,_MAC,18,':');
char _empty[6] = {0};
_new.time = 0;
if(memcmp(_empty,_new.MAC,6) == 0){
_new.active = false;
AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: beacon%u deactivated"), index);
}
else{
_new.active = true;
MI32.mode.activeBeacon = 1;
AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: beacon added with MAC: %s"), _MAC);
}
}
/**
* @brief Present BLE scan in the console, after that deleting the scan data
*
*/
void MI32showScanResults(){
AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: found %u devices in scan:"), MINBLEscanResult.size());
for(auto _scanResult : MINBLEscanResult){
char _MAC[18];
ToHex_P(_scanResult.MAC,6,_MAC,18,':');
AddLog_P2(LOG_LEVEL_INFO,PSTR("MAC: %s _ CID: %04x _ SVC: %04x _ UUID: %04x _ RSSI: %d"), _MAC, _scanResult.CID, _scanResult.SVC, _scanResult.UUID, _scanResult.RSSI);
}
MINBLEscanResult.clear();
}
/***********************************************************************\ /***********************************************************************\
* Read data from connections * Read data from connections
\***********************************************************************/ \***********************************************************************/
@ -1473,6 +1653,25 @@ void MI32EverySecond(bool restart){
} }
} }
uint32_t _idx = 0;
uint32_t _activeBeacons = 0;
for (auto &_beacon : MIBLEbeacons){
_idx++;
if(_beacon.active == false) continue;
_activeBeacons++;
_beacon.time++;
Response_P(PSTR("{\"Beacon%u\":{\"Time\":%u}}"), _beacon.time);
XdrvRulesProcess();
}
if(_activeBeacons==0) MI32.mode.activeBeacon = 0;
if(MI32.state.beaconScanCounter!=0){
MI32.state.beaconScanCounter--;
if(MI32.state.beaconScanCounter==0){
MI32showScanResults();
}
}
if(MI32.mode.shallShowStatusInfo == 1){ if(MI32.mode.shallShowStatusInfo == 1){
MI32StatusInfo(); MI32StatusInfo();
} }
@ -1522,16 +1721,17 @@ void MI32EverySecond(bool restart){
if(_counter==0) { if(_counter==0) {
MI32.state.sensor = _nextSensorSlot; MI32.state.sensor = _nextSensorSlot;
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1);
MI32.mode.canScan = 0; MI32.mode.canScan = 0;
// if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return; // if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return;
if (MI32.mode.connected || MI32.mode.willConnect) return; if (MI32.mode.connected || MI32.mode.willConnect) return;
_nextSensorSlot++; _nextSensorSlot++;
MI32.mode.canConnect = 1; MI32.mode.canConnect = 1;
if(MI32.mode.connected == 0) { if(MI32.mode.connected == 0) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("will connect to %s"),kMI32DeviceType[MIBLEsensors[MI32.state.sensor].type-1] ); if (MI32.mode.shallReadBatt) {
//TODO: decide automatically, which sensor can not work without connections
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("will connect to %s"),kMI32DeviceType[MIBLEsensors[MI32.state.sensor].type-1] );
if (MI32.mode.shallReadBatt) {
MI32StartTask(MI32_TASK_BATT); MI32StartTask(MI32_TASK_BATT);
} }
#ifndef USE_MI_DECRYPTION // turn off connections, because we only listen to advertisements #ifndef USE_MI_DECRYPTION // turn off connections, because we only listen to advertisements
@ -1638,6 +1838,32 @@ bool MI32Cmd(void) {
} }
break; break;
#endif //USE_MI_DECRYPTION #endif //USE_MI_DECRYPTION
case CMND_MI32_BEACON:
if (XdrvMailbox.data_len == 0) {
switch(XdrvMailbox.index){
case 0:
MI32.state.beaconScanCounter = 8;
Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,PSTR("\"scanning\""));
break;
case 1: case 2: case 3: case 4:
char _MAC[18];
ToHex_P(MIBLEbeacons[XdrvMailbox.index-1].MAC,6,_MAC,18,':');
Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,_MAC);
break;
}
}
else {
if(XdrvMailbox.data_len == 12 || XdrvMailbox.data_len == 17){ // MAC-string without or with colons
switch(XdrvMailbox.index){
case 1: case 2: case 3: case 4:
MI32addBeacon(XdrvMailbox.index,XdrvMailbox.data);
break;
}
}
Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,XdrvMailbox.data);
}
break;
default: default:
// else for Unknown command // else for Unknown command
serviced = false; serviced = false;
@ -1654,7 +1880,7 @@ bool MI32Cmd(void) {
* Presentation * Presentation
\*********************************************************************************************/ \*********************************************************************************************/
const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 v0.9.1.5{m}%u%s / %u{e}"; const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 v0916{m}%u%s / %u{e}";
const char HTTP_MI32_MAC[] PROGMEM = "{s}%s %s{m}%s{e}"; const char HTTP_MI32_MAC[] PROGMEM = "{s}%s %s{m}%s{e}";
const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}"; const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}";
const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}";
@ -1825,8 +2051,7 @@ void MI32Show(bool json)
} }
} }
} }
if (MI32.option.showRSSI && MI32.mode.triggeredTele) ResponseAppend_P(PSTR(",\"RSSI\":%d"), MIBLEsensors[i].rssi); if (MI32.option.showRSSI) ResponseAppend_P(PSTR(",\"RSSI\":%d"), MIBLEsensors[i].RSSI);
if(_positionCurlyBracket==strlen(mqtt_data)) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step if(_positionCurlyBracket==strlen(mqtt_data)) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step
ResponseAppend_P(PSTR("}")); ResponseAppend_P(PSTR("}"));
@ -1838,6 +2063,17 @@ void MI32Show(bool json)
} }
} }
MI32.mode.triggeredTele = 0; MI32.mode.triggeredTele = 0;
// add beacons
uint32_t _idx = 0;
for (auto _beacon : MIBLEbeacons){
_idx++;
if(!_beacon.active) continue;
char _MAC[18];
ToHex_P(_beacon.MAC,6,_MAC,18,':');
ResponseAppend_P(PSTR(",\"Beacon%u\":{\"MAC\":\"%s\",\"CID\":\"0x%04x\",\"SVC\":\"0x%04x\","
"\"UUID\":\"0x%04x\",\"Time\":%u,\"RSSI\":%d}"),
_idx,_MAC,_beacon.CID,_beacon.SVC,_beacon.UUID,_beacon.time,_beacon.RSSI);
}
#ifdef USE_HOME_ASSISTANT #ifdef USE_HOME_ASSISTANT
if(hass_mode==2){ if(hass_mode==2){
MI32.option.noSummary = _noSummarySave; MI32.option.noSummary = _noSummarySave;
@ -1865,7 +2101,7 @@ void MI32Show(bool json)
char _MAC[18]; char _MAC[18];
ToHex_P(MIBLEsensors[i].MAC,6,_MAC,18,':'); ToHex_P(MIBLEsensors[i].MAC,6,_MAC,18,':');
WSContentSend_PD(HTTP_MI32_MAC, kMI32DeviceType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, _MAC); WSContentSend_PD(HTTP_MI32_MAC, kMI32DeviceType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, _MAC);
WSContentSend_PD(HTTP_RSSI, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].rssi); WSContentSend_PD(HTTP_RSSI, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].RSSI);
if (MIBLEsensors[i].type==FLORA) { if (MIBLEsensors[i].type==FLORA) {
if (!isnan(MIBLEsensors[i].temp)) { if (!isnan(MIBLEsensors[i].temp)) {
char temperature[FLOATSZ]; char temperature[FLOATSZ];
@ -1909,6 +2145,27 @@ void MI32Show(bool json)
} }
if (MIBLEsensors.size()%MI32.perPage==0 && _page==MIBLEsensors.size()/MI32.perPage) { _page = 0; } if (MIBLEsensors.size()%MI32.perPage==0 && _page==MIBLEsensors.size()/MI32.perPage) { _page = 0; }
if (_page>MIBLEsensors.size()/MI32.perPage) { _page = 0; } if (_page>MIBLEsensors.size()/MI32.perPage) { _page = 0; }
//always at the bottom of the page
uint32_t _idx=0;
if(MI32.mode.activeBeacon){
WSContentSend_PD(HTTP_MI32_HL);
char _sbeacon[] = "Beacon1";
for (auto &_beacon : MIBLEbeacons){
_idx++;
if(!_beacon.active) continue;
WSContentSend_PD(HTTP_MI32_HL);
_sbeacon[6] = _idx + 0x30;
char _MAC[18];
ToHex_P(_beacon.MAC,6,_MAC,18,':');
WSContentSend_PD(HTTP_MI32_MAC, _sbeacon, D_MAC_ADDRESS, _MAC);
WSContentSend_PD(HTTP_RSSI, _sbeacon, _beacon.RSSI);
if(_beacon.CID!=0) WSContentSend_PD(PSTR("{s}Beacon%u CID{m}0x%04X{e}"),_idx, _beacon.CID);
if(_beacon.SVC!=0) WSContentSend_PD(PSTR("{s}Beacon%u SVC{m}0x%04X{e}"),_idx, _beacon.SVC);
if(_beacon.UUID!=0) WSContentSend_PD(PSTR("{s}Beacon%u UUID{m}0x%04X{e}"),_idx, _beacon.UUID);
WSContentSend_PD(PSTR("{s}Beacon%u Time{m}%u seconds{e}"),_idx, _beacon.time);
}
}
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }
} }

View File

@ -232,7 +232,7 @@ a_features = [[
"USE_MLX90640","USE_VL53L1X","USE_MIEL_HVAC","USE_WE517", "USE_MLX90640","USE_VL53L1X","USE_MIEL_HVAC","USE_WE517",
"USE_EZOPH","USE_TTGO_WATCH","USE_ETHERNET","USE_WEBCAM" "USE_EZOPH","USE_TTGO_WATCH","USE_ETHERNET","USE_WEBCAM"
],[ ],[
"USE_EZOORP","USE_EZORTD","","", "USE_EZOORP","USE_EZORTD","USE_EZOHUM","",
"","","","", "","","","",
"","","","", "","","","",
"","","","", "","","","",
@ -267,7 +267,7 @@ else:
obj = json.load(fp) obj = json.load(fp)
def StartDecode(): def StartDecode():
print ("\n*** decode-status.py v20201020 by Theo Arends and Jacek Ziolkowski ***") print ("\n*** decode-status.py v20201023 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj)) # print("Decoding\n{}".format(obj))