Merge branch 'development' into pre-release-9.3.0

This commit is contained in:
Theo Arends 2021-02-22 14:18:00 +01:00
commit cabe894933
50 changed files with 297 additions and 165 deletions

View File

@ -7,15 +7,22 @@ All notable changes to this project will be documented in this file.
- Release Kenneth - Release Kenneth
## [9.3.0.1] ## [9.3.0.1]
### Added
- Animate PWM dimmer brightness LEDs during transitions and with variable brightness (#11076)
- Commands ``StateRetain`` and ``InfoRetain`` (#11084)
### Changed ### Changed
- Remove the need to start filenames with a slash (/) in Ufs commands - Remove the need to start filenames with a slash (/) in Ufs commands
- Removed command ``VirtualCT`` as synonym for ``SetOption106`` (#11049) - Removed command ``VirtualCT`` as synonym for ``SetOption106`` (#11049)
### Fixed ### Fixed
- Web request accepts wrong password (#11039)
- Ili1942 driver (#11046) - Ili1942 driver (#11046)
- Shutter driver (#11055)
- ESP32 Mi32 driver (#11048) - ESP32 Mi32 driver (#11048)
- Shutter driver (#11055)
- TM1637 driver now needs ``TM1637 CLK`` and ``TM1637 DIO`` to enable (#11057) - TM1637 driver now needs ``TM1637 CLK`` and ``TM1637 DIO`` to enable (#11057)
- Sml driver (#11082)
- Ezo drivers (#11083)
## [9.3.0] 20210219 ## [9.3.0] 20210219
- Release Kenneth - Release Kenneth

View File

@ -79,15 +79,22 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
[Complete list](BUILDS.md) of available feature and sensors. [Complete list](BUILDS.md) of available feature and sensors.
## Changelog v9.3.1 Kenneth ## Changelog v9.3.1 Kenneth
### Added
- Animate PWM dimmer brightness LEDs during transitions and with variable brightness [#11076](https://github.com/arendst/Tasmota/issues/11076)
- Commands ``StateRetain`` and ``InfoRetain`` [#11084](https://github.com/arendst/Tasmota/issues/11084)
### Changed ### Changed
- Remove the need to start filenames with a slash (/) in Ufs commands - Remove the need to start filenames with a slash (/) in Ufs commands
- Removed command ``VirtualCT`` as synonym for ``SetOption106`` [#11049](https://github.com/arendst/Tasmota/issues/11049) - Removed command ``VirtualCT`` as synonym for ``SetOption106`` [#11049](https://github.com/arendst/Tasmota/issues/11049)
### Fixed ### Fixed
- Web request accepts wrong password [#11039](https://github.com/arendst/Tasmota/issues/11039)
- Ili1942 driver [#11046](https://github.com/arendst/Tasmota/issues/11046) - Ili1942 driver [#11046](https://github.com/arendst/Tasmota/issues/11046)
- Shutter driver [#11055](https://github.com/arendst/Tasmota/issues/11055)
- ESP32 Mi32 driver [#11048](https://github.com/arendst/Tasmota/issues/11048) - ESP32 Mi32 driver [#11048](https://github.com/arendst/Tasmota/issues/11048)
- Shutter driver [#11055](https://github.com/arendst/Tasmota/issues/11055)
- TM1637 driver now needs ``TM1637 CLK`` and ``TM1637 DIO`` to enable [#11057](https://github.com/arendst/Tasmota/issues/11057) - TM1637 driver now needs ``TM1637 CLK`` and ``TM1637 DIO`` to enable [#11057](https://github.com/arendst/Tasmota/issues/11057)
- Sml driver [#11082](https://github.com/arendst/Tasmota/issues/11082)
- Ezo drivers [#11083](https://github.com/arendst/Tasmota/issues/11083)
## Changelog v9.3.0 Kenneth ## Changelog v9.3.0 Kenneth
### Added ### Added

View File

@ -380,6 +380,8 @@
#define D_CMND_SWITCHRETAIN "SwitchRetain" #define D_CMND_SWITCHRETAIN "SwitchRetain"
#define D_CMND_POWERRETAIN "PowerRetain" #define D_CMND_POWERRETAIN "PowerRetain"
#define D_CMND_SENSORRETAIN "SensorRetain" #define D_CMND_SENSORRETAIN "SensorRetain"
#define D_CMND_INFORETAIN "InfoRetain"
#define D_CMND_STATERETAIN "StateRetain"
#define D_CMND_PUBLISH "Publish" #define D_CMND_PUBLISH "Publish"
// Commands xdrv_01_webserver.ino // Commands xdrv_01_webserver.ino
@ -829,7 +831,7 @@ const char HTTP_SNS_EC[] PROGMEM = "{s}%s " D_EC "{
const char HTTP_SNS_O2[] PROGMEM = "{s}%s " D_O2 "{m}%s " D_UNIT_PERCENT "{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_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 HTTP_SNS_LPM[] PROGMEM = "{s}%s " D_FLOW_RATE "{m}%s " D_UNIT_LITERS_PER_MIN "{e}";
const char HTTP_SNS_DO[] PROGMEM = "{s}%s " D_DO "{m}%s " D_UNIT_PARTS_PER_MILLION "{e}"; const char HTTP_SNS_DO[] PROGMEM = "{s}%s " D_DO "{m}%s " D_UNIT_MILIGRAMS_PER_LITER "{e}";
const char HTTP_SNS_COLOR_RED[] PROGMEM = "{s}%s " D_COLOR_RED "{m}%u " "{e}"; const char HTTP_SNS_COLOR_RED[] PROGMEM = "{s}%s " D_COLOR_RED "{m}%u " "{e}";
const char HTTP_SNS_COLOR_GREEN[] PROGMEM = "{s}%s " D_COLOR_GREEN "{m}%u " "{e}"; const char HTTP_SNS_COLOR_GREEN[] PROGMEM = "{s}%s " D_COLOR_GREEN "{m}%u " "{e}";
const char HTTP_SNS_COLOR_BLUE[] PROGMEM = "{s}%s " D_COLOR_BLUE "{m}%u " "{e}"; const char HTTP_SNS_COLOR_BLUE[] PROGMEM = "{s}%s " D_COLOR_BLUE "{m}%u " "{e}";

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -826,6 +826,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "s" #define D_UNIT_SECOND "s"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "s" #define D_UNIT_SECOND "s"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"
@ -876,7 +877,7 @@
#define D_SOLAX_ERROR_8 "Other Device Fault" #define D_SOLAX_ERROR_8 "Other Device Fault"
//xdrv_10_scripter.ino //xdrv_10_scripter.ino
#define D_CONFIGURE_SCRIPT "Edit script" #define D_CONFIGURE_SCRIPT "Edit Script"
#define D_SCRIPT "edit script" #define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload" #define D_SDCARD_UPLOAD "file upload"
#define D_UFSDIR "ufs directory" #define D_UFSDIR "ufs directory"
@ -884,7 +885,7 @@
#define D_SCRIPT_CHARS_LEFT "chars left" #define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars" #define D_SCRIPT_CHARS_NO_MORE "no more chars"
#define D_SCRIPT_DOWNLOAD "Download" #define D_SCRIPT_DOWNLOAD "Download"
#define D_SCRIPT_ENABLE "script enable" #define D_SCRIPT_ENABLE "Script enable"
#define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD "Upload"
#define D_SCRIPT_UPLOAD_FILES "Upload files" #define D_SCRIPT_UPLOAD_FILES "Upload files"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "seg" #define D_UNIT_SECOND "seg"

View File

@ -823,6 +823,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "s" #define D_UNIT_SECOND "s"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "s" #define D_UNIT_SECOND "s"

View File

@ -826,6 +826,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "초" #define D_UNIT_SECOND "초"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "s" #define D_UNIT_SECOND "s"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "гПа" #define D_UNIT_PRESSURE "гПа"
#define D_UNIT_SECOND "сек" #define D_UNIT_SECOND "сек"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sek" #define D_UNIT_SECOND "sek"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sek" #define D_UNIT_SECOND "sek"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "млрд⁻¹" #define D_UNIT_PARTS_PER_BILLION "млрд⁻¹"
#define D_UNIT_PARTS_PER_DECILITER "децилітр⁻¹" #define D_UNIT_PARTS_PER_DECILITER "децилітр⁻¹"
#define D_UNIT_PARTS_PER_MILLION "млн⁻¹" #define D_UNIT_PARTS_PER_MILLION "млн⁻¹"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "гПа" #define D_UNIT_PRESSURE "гПа"
#define D_UNIT_SECOND "сек" #define D_UNIT_SECOND "сек"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "hPa" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "sec" #define D_UNIT_SECOND "sec"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "每分升" #define D_UNIT_PARTS_PER_DECILITER "每分升"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "百帕" #define D_UNIT_PRESSURE "百帕"
#define D_UNIT_SECOND "秒" #define D_UNIT_SECOND "秒"

View File

@ -827,6 +827,7 @@
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "每分升" #define D_UNIT_PARTS_PER_DECILITER "每分升"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_MILIGRAMS_PER_LITER "mg/L"
#define D_UNIT_PERCENT "%%" #define D_UNIT_PERCENT "%%"
#define D_UNIT_PRESSURE "百帕" #define D_UNIT_PRESSURE "百帕"
#define D_UNIT_SECOND "秒" #define D_UNIT_SECOND "秒"

View File

@ -112,6 +112,8 @@
#define MQTT_POWER_RETAIN false // [PowerRetain] Power status message may send retain flag (false = off, true = on) #define MQTT_POWER_RETAIN false // [PowerRetain] Power status message may send retain flag (false = off, true = on)
#define MQTT_SWITCH_RETAIN false // [SwitchRetain] Switch may send retain flag (false = off, true = on) #define MQTT_SWITCH_RETAIN false // [SwitchRetain] Switch may send retain flag (false = off, true = on)
#define MQTT_SENSOR_RETAIN false // [SensorRetain] Sensor may send retain flag (false = off, true = on) #define MQTT_SENSOR_RETAIN false // [SensorRetain] Sensor may send retain flag (false = off, true = on)
#define MQTT_INFO_RETAIN false // [InfoRetain] Info may send retain flag (false = off, true = on)
#define MQTT_STATE_RETAIN false // [StateRetain] State may send retain flag (false = off, true = on)
#define MQTT_NO_HOLD_RETAIN false // [SetOption62] Disable retain flag on HOLD messages #define MQTT_NO_HOLD_RETAIN false // [SetOption62] Disable retain flag on HOLD messages
#define MQTT_NO_RETAIN false // [SetOption104] No Retain - disable all MQTT retained messages, some brokers don't support it: AWS IoT, Losant #define MQTT_NO_RETAIN false // [SetOption104] No Retain - disable all MQTT retained messages, some brokers don't support it: AWS IoT, Losant

View File

@ -146,8 +146,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t zb_received_as_subtopic : 1; // bit 4 (v9.2.0.3) - SetOption118 - (Zigbee) Move ZbReceived from JSON message and into the subtopic replacing "SENSOR" default uint32_t zb_received_as_subtopic : 1; // bit 4 (v9.2.0.3) - SetOption118 - (Zigbee) Move ZbReceived from JSON message and into the subtopic replacing "SENSOR" default
uint32_t zb_omit_json_addr : 1; // bit 5 (v9.2.0.3) - SetOption119 - (Zigbee) Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic uint32_t zb_omit_json_addr : 1; // bit 5 (v9.2.0.3) - SetOption119 - (Zigbee) Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic
uint32_t zb_topic_endpoint : 1; // bit 6 (v9.2.0.4) - SetOption120 - (Zigbee) Append endpoint number to topic if device dependent (use with SetOption89) uint32_t zb_topic_endpoint : 1; // bit 6 (v9.2.0.4) - SetOption120 - (Zigbee) Append endpoint number to topic if device dependent (use with SetOption89)
uint32_t spare07 : 1; // bit 7 uint32_t mqtt_state_retain : 1; // bit 7 (v9.3.0.1) - CMND_STATERETAIN
uint32_t spare08 : 1; // bit 8 uint32_t mqtt_info_retain : 1; // bit 8 (v9.3.0.1) - CMND_INFORETAIN
uint32_t spare09 : 1; // bit 9 uint32_t spare09 : 1; // bit 9
uint32_t spare10 : 1; // bit 10 uint32_t spare10 : 1; // bit 10
uint32_t spare11 : 1; // bit 11 uint32_t spare11 : 1; // bit 11

View File

@ -831,6 +831,8 @@ void SettingsDefaultSet2(void) {
flag.mqtt_button_retain |= MQTT_BUTTON_RETAIN; flag.mqtt_button_retain |= MQTT_BUTTON_RETAIN;
flag.mqtt_switch_retain |= MQTT_SWITCH_RETAIN; flag.mqtt_switch_retain |= MQTT_SWITCH_RETAIN;
flag.mqtt_sensor_retain |= MQTT_SENSOR_RETAIN; flag.mqtt_sensor_retain |= MQTT_SENSOR_RETAIN;
flag5.mqtt_info_retain |= MQTT_INFO_RETAIN;
flag5.mqtt_state_retain |= MQTT_STATE_RETAIN;
// flag.mqtt_serial |= 0; // flag.mqtt_serial |= 0;
flag.device_index_enable |= MQTT_POWER_FORMAT; flag.device_index_enable |= MQTT_POWER_FORMAT;
flag3.time_append_timezone |= MQTT_APPEND_TIMEZONE; flag3.time_append_timezone |= MQTT_APPEND_TIMEZONE;

View File

@ -426,7 +426,8 @@ void CmndStatus(void)
Response_P(PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_DEVICENAME "\":\"%s\",\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" Response_P(PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_DEVICENAME "\":\"%s\",\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\""
D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_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_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}}"), D_CMND_SWITCHMODE "\":[%s],\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_SWITCHRETAIN "\":%d,\"" D_CMND_SENSORRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d,\""
D_CMND_INFORETAIN "\":%d,\"" D_CMND_STATERETAIN "\":%d}}"),
ModuleNr(), EscapeJSONString(SettingsText(SET_DEVICENAME)).c_str(), stemp, TasmotaGlobal.mqtt_topic, ModuleNr(), EscapeJSONString(SettingsText(SET_DEVICENAME)).c_str(), stemp, TasmotaGlobal.mqtt_topic,
SettingsText(SET_MQTT_BUTTON_TOPIC), TasmotaGlobal.power, Settings.poweronstate, Settings.ledstate, SettingsText(SET_MQTT_BUTTON_TOPIC), TasmotaGlobal.power, Settings.poweronstate, Settings.ledstate,
Settings.ledmask, Settings.save_data, Settings.ledmask, Settings.save_data,
@ -436,7 +437,9 @@ void CmndStatus(void)
Settings.flag.mqtt_button_retain, // CMND_BUTTONRETAIN Settings.flag.mqtt_button_retain, // CMND_BUTTONRETAIN
Settings.flag.mqtt_switch_retain, // CMND_SWITCHRETAIN Settings.flag.mqtt_switch_retain, // CMND_SWITCHRETAIN
Settings.flag.mqtt_sensor_retain, // CMND_SENSORRETAIN Settings.flag.mqtt_sensor_retain, // CMND_SENSORRETAIN
Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN Settings.flag.mqtt_power_retain, // CMND_POWERRETAIN
Settings.flag5.mqtt_info_retain, // CMND_INFORETAIN
Settings.flag5.mqtt_state_retain); // CMND_STATERETAIN
MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS)); MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS));
} }
@ -629,7 +632,7 @@ void CmndState(void)
ResponseClear(); ResponseClear();
MqttShowState(); MqttShowState();
if (Settings.flag3.hass_tele_on_power) { // SetOption59 - Send tele/%topic%/STATE in addition to stat/%topic%/RESULT 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); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), Settings.flag5.mqtt_state_retain);
} }
#ifdef USE_HOME_ASSISTANT #ifdef USE_HOME_ASSISTANT
if (Settings.flag.hass_discovery) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59) if (Settings.flag.hass_discovery) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59)

View File

@ -715,7 +715,7 @@ void MqttPublishTeleState(void)
{ {
ResponseClear(); ResponseClear();
MqttShowState(); MqttShowState();
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), Settings.flag5.mqtt_state_retain);
#ifdef USE_DT_VARS #ifdef USE_DT_VARS
DTVarsTeleperiod(); DTVarsTeleperiod();

View File

@ -2676,7 +2676,7 @@ void HandleHttpCommand(void)
// Prefer authorization via HTTP header (Basic auth), if it fails, use legacy method via GET parameters // Prefer authorization via HTTP header (Basic auth), if it fails, use legacy method via GET parameters
char tmp1[33]; char tmp1[33];
WebGetArg(PSTR("user"), tmp1, sizeof(tmp1)); WebGetArg(PSTR("user"), tmp1, sizeof(tmp1));
char tmp2[strlen(SettingsText(SET_WEBPWD)) + 1]; char tmp2[strlen(SettingsText(SET_WEBPWD)) + 2]; // Need space for an entered password longer than set password
WebGetArg(PSTR("password"), tmp2, sizeof(tmp2)); WebGetArg(PSTR("password"), tmp2, sizeof(tmp2));
if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) { if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) {

View File

@ -48,7 +48,8 @@ const char kMqttCommands[] PROGMEM = "|" // No prefix
#endif #endif
D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTCLIENT "|" D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTCLIENT "|"
D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|" D_CMND_MQTTLOG "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|" D_CMND_MQTTLOG "|"
D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ; D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|"
D_CMND_SENSORRETAIN "|" D_CMND_INFORETAIN "|" D_CMND_STATERETAIN ;
SO_SYNONYMS(kMqttSynonyms, SO_SYNONYMS(kMqttSynonyms,
90, 90,
@ -73,7 +74,8 @@ void (* const MqttCommand[])(void) PROGMEM = {
#endif #endif
&CmndMqttHost, &CmndMqttPort, &CmndMqttRetry, &CmndStateText, &CmndMqttClient, &CmndMqttHost, &CmndMqttPort, &CmndMqttRetry, &CmndStateText, &CmndMqttClient,
&CmndFullTopic, &CmndPrefix, &CmndGroupTopic, &CmndTopic, &CmndPublish, &CmndMqttlog, &CmndFullTopic, &CmndPrefix, &CmndGroupTopic, &CmndTopic, &CmndPublish, &CmndMqttlog,
&CmndButtonTopic, &CmndSwitchTopic, &CmndButtonRetain, &CmndSwitchRetain, &CmndPowerRetain, &CmndSensorRetain }; &CmndButtonTopic, &CmndSwitchTopic, &CmndButtonRetain, &CmndSwitchRetain, &CmndPowerRetain, &CmndSensorRetain,
&CmndInfoRetain, &CmndStateRetain };
struct MQTT { struct MQTT {
uint16_t connect_count = 0; // MQTT re-connect count uint16_t connect_count = 0; // MQTT re-connect count
@ -542,17 +544,17 @@ void MqttConnected(void) {
char stopic2[TOPSZ]; char stopic2[TOPSZ];
Response_P(PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"), Response_P(PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"),
ModuleName().c_str(), TasmotaGlobal.version, TasmotaGlobal.image_name, 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")); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "1"), Settings.flag5.mqtt_info_retain);
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
if (Settings.webserver) { if (Settings.webserver) {
#if LWIP_IPV6 #if LWIP_IPV6
Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"IPv6Address\":\"%s\"}"), Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"IPv6Address\":\"%s\"}"),
(2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), NetworkAddress().toString().c_str(), WifiGetIPv6().c_str()); (2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), NetworkAddress().toString().c_str(), WifiGetIPv6().c_str(), Settings.flag5.mqtt_info_retain);
#else #else
Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"), Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"),
(2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), NetworkAddress().toString().c_str()); (2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), NetworkAddress().toString().c_str(), Settings.flag5.mqtt_info_retain);
#endif // LWIP_IPV6 = 1 #endif // LWIP_IPV6 = 1
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2")); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2"), Settings.flag5.mqtt_info_retain);
} }
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
Response_P(PSTR("{\"" D_JSON_RESTARTREASON "\":")); Response_P(PSTR("{\"" D_JSON_RESTARTREASON "\":"));
@ -562,7 +564,7 @@ void MqttConnected(void) {
ResponseAppend_P(PSTR("\"%s\""), GetResetReason().c_str()); ResponseAppend_P(PSTR("\"%s\""), GetResetReason().c_str());
} }
ResponseJsonEnd(); ResponseJsonEnd();
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3")); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3"), Settings.flag5.mqtt_info_retain);
} }
MqttPublishAllPowerState(); MqttPublishAllPowerState();
@ -1080,6 +1082,28 @@ void CmndSensorRetain(void) {
ResponseCmndStateText(Settings.flag.mqtt_sensor_retain); // CMND_SENSORRETAIN ResponseCmndStateText(Settings.flag.mqtt_sensor_retain); // CMND_SENSORRETAIN
} }
void CmndInfoRetain(void) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
ResponseClear();
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO), Settings.flag5.mqtt_info_retain); // CMND_INFORETAIN
}
Settings.flag5.mqtt_info_retain = XdrvMailbox.payload; // CMND_INFORETAIN
}
ResponseCmndStateText(Settings.flag5.mqtt_info_retain); // CMND_INFORETAIN
}
void CmndStateRetain(void) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
ResponseClear();
MqttPublishPrefixTopic_P(STAT, PSTR(D_RSLT_STATE), Settings.flag5.mqtt_state_retain); // CMND_STATERETAIN
}
Settings.flag5.mqtt_state_retain = XdrvMailbox.payload; // CMND_STATERETAIN
}
ResponseCmndStateText(Settings.flag5.mqtt_state_retain); // CMND_STATERETAIN
}
/*********************************************************************************************\ /*********************************************************************************************\
* TLS private key and certificate - store into Flash * TLS private key and certificate - store into Flash
\*********************************************************************************************/ \*********************************************************************************************/

View File

@ -505,9 +505,6 @@ class LightStateClass {
uint8_t prev_bri = _briRGB; uint8_t prev_bri = _briRGB;
_briRGB = bri_rgb; _briRGB = bri_rgb;
if (bri_rgb > 0) { addRGBMode(); } if (bri_rgb > 0) { addRGBMode(); }
#ifdef USE_PWM_DIMMER
if (PWM_DIMMER == TasmotaGlobal.module_type) PWMDimmerSetBrightnessLeds(-1);
#endif // USE_PWM_DIMMER
return prev_bri; return prev_bri;
} }
@ -516,9 +513,6 @@ class LightStateClass {
uint8_t prev_bri = _briCT; uint8_t prev_bri = _briCT;
_briCT = bri_ct; _briCT = bri_ct;
if (bri_ct > 0) { addCTMode(); } if (bri_ct > 0) { addCTMode(); }
#ifdef USE_PWM_DIMMER
if (PWM_DIMMER == TasmotaGlobal.module_type) PWMDimmerSetBrightnessLeds(-1);
#endif // USE_PWM_DIMMER
return prev_bri; return prev_bri;
} }
@ -1958,6 +1952,10 @@ void LightSetOutputs(const uint16_t *cur_col_10) {
if (!Settings.flag4.zerocross_dimmer) { if (!Settings.flag4.zerocross_dimmer) {
analogWrite(Pin(GPIO_PWM1, i), bitRead(TasmotaGlobal.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);
} }
#ifdef USE_PWM_DIMMER
// Animate brightness LEDs to follow PWM dimmer brightness
if (PWM_DIMMER == TasmotaGlobal.module_type) PWMDimmerSetBrightnessLeds(change10to8(cur_col));
#endif // USE_PWM_DIMMER
} }
} }
} }

View File

@ -162,6 +162,7 @@ void Script_ticker4_end(void) {
#endif #endif
#endif #endif
extern uint8_t sml_json_enable;
#if defined(EEP_SCRIPT_SIZE) && !defined(ESP32) #if defined(EEP_SCRIPT_SIZE) && !defined(ESP32)
@ -208,7 +209,7 @@ void alt_eeprom_readBytes(uint32_t adr, uint32_t len, uint8_t *buf) {
#define EPOCH_OFFSET 1546300800 #define EPOCH_OFFSET 1546300800
enum {OPER_EQU=1,OPER_PLS,OPER_MIN,OPER_MUL,OPER_DIV,OPER_PLSEQU,OPER_MINEQU,OPER_MULEQU,OPER_DIVEQU,OPER_EQUEQU,OPER_NOTEQU,OPER_GRTEQU,OPER_LOWEQU,OPER_GRT,OPER_LOW,OPER_PERC,OPER_XOR,OPER_AND,OPER_OR,OPER_ANDEQU,OPER_OREQU,OPER_XOREQU,OPER_PERCEQU}; enum {OPER_EQU=1,OPER_PLS,OPER_MIN,OPER_MUL,OPER_DIV,OPER_PLSEQU,OPER_MINEQU,OPER_MULEQU,OPER_DIVEQU,OPER_EQUEQU,OPER_NOTEQU,OPER_GRTEQU,OPER_LOWEQU,OPER_GRT,OPER_LOW,OPER_PERC,OPER_XOR,OPER_AND,OPER_OR,OPER_ANDEQU,OPER_OREQU,OPER_XOREQU,OPER_PERCEQU};
enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD,SCRIPT_EVENT_HANDLED}; enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD,SCRIPT_EVENT_HANDLED,SML_JSON_ENABLE};
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
@ -2985,6 +2986,11 @@ chknext:
len = 0; len = 0;
goto exit; goto exit;
} }
if (!strncmp(vname, "smlj", 4)) {
fvar = sml_json_enable;
tind->index = SML_JSON_ENABLE;
goto exit_settable;
}
#endif //USE_SML_M #endif //USE_SML_M
break; break;
case 't': case 't':
@ -4527,6 +4533,11 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
case SCRIPT_EVENT_HANDLED: case SCRIPT_EVENT_HANDLED:
glob_script_mem.event_handeled = *dfvar; glob_script_mem.event_handeled = *dfvar;
break; break;
#if defined(USE_SML_M) && defined (USE_SML_SCRIPT_CMD)
case SML_JSON_ENABLE:
sml_json_enable = *dfvar;
break;
#endif
} }
sysv_type = 0; sysv_type = 0;
} }

View File

@ -167,6 +167,7 @@ void PWMDimmerSetBrightnessLeds(int32_t bri)
uint32_t level = 0; uint32_t level = 0;
led = -1; led = -1;
mask = 0; mask = 0;
uint16_t pwm_led_bri = 0;
for (uint32_t count = 0; count < leds; count++) { for (uint32_t count = 0; count < leds; count++) {
level += step; level += step;
for (;;) { for (;;) {
@ -175,7 +176,8 @@ void PWMDimmerSetBrightnessLeds(int32_t bri)
if (!mask) mask = 1; if (!mask) mask = 1;
if (Settings.ledmask & mask) break; if (Settings.ledmask & mask) break;
} }
SetLedPowerIdx(led, bri >= level); pwm_led_bri = changeUIntScale((bri > level ? bri - level : 0), 0, step, 0, Settings.pwm_range);
analogWrite(Pin(GPIO_LED1, led), bitRead(TasmotaGlobal.led_inverted, led) ? Settings.pwm_range - pwm_led_bri : pwm_led_bri);
} }
} }
} }
@ -193,7 +195,6 @@ void PWMDimmerSetPoweredOffLed(void)
void PWMDimmerSetPower(void) void PWMDimmerSetPower(void)
{ {
DigitalWrite(GPIO_REL1, 0, bitRead(TasmotaGlobal.rel_inverted, 0) ? !TasmotaGlobal.power : TasmotaGlobal.power); DigitalWrite(GPIO_REL1, 0, bitRead(TasmotaGlobal.rel_inverted, 0) ? !TasmotaGlobal.power : TasmotaGlobal.power);
PWMDimmerSetBrightnessLeds(-1);
PWMDimmerSetPoweredOffLed(); PWMDimmerSetPoweredOffLed();
} }

View File

@ -144,7 +144,7 @@
#define SCROLL_MAX_LEN 50 #define SCROLL_MAX_LEN 50
#include "SevenSegmentTM1637.h" #include "SevenSegmentTM1637.h"
SevenSegmentTM1637 *display; SevenSegmentTM1637 *tm1637display;
struct { struct {
char scroll_text[CMD_MAX_LEN]; char scroll_text[CMD_MAX_LEN];
@ -166,21 +166,20 @@ struct {
\*********************************************************************************************/ \*********************************************************************************************/
void TM1637Init(void) { void TM1637Init(void) {
if (PinUsed(GPIO_TM1637CLK) && PinUsed(GPIO_TM1637DIO)) { if (PinUsed(GPIO_TM1637CLK) && PinUsed(GPIO_TM1637DIO)) {
display = new SevenSegmentTM1637(Pin(GPIO_TM1637CLK), Pin(GPIO_TM1637DIO) ); tm1637display = new SevenSegmentTM1637(Pin(GPIO_TM1637CLK), Pin(GPIO_TM1637DIO));
if (display) { if (tm1637display) {
Settings.display_model = XDSP_15; Settings.display_model = XDSP_15;
TM1637Data.num_digits = Settings.display_size > 3 ? Settings.display_size : 4; TM1637Data.num_digits = Settings.display_size > 3 ? Settings.display_size : 4;
Settings.display_size = TM1637Data.num_digits; Settings.display_size = TM1637Data.num_digits;
display->begin(TM1637Data.num_digits, 1); tm1637display->begin(TM1637Data.num_digits, 1);
display->setBacklight(TM1637Data.brightness * 10); tm1637display->setBacklight(TM1637Data.brightness * 10);
TM1637ClearDisplay(); TM1637ClearDisplay();
AddLog(LOG_LEVEL_INFO, PSTR("DSP: TM1637")); AddLog(LOG_LEVEL_INFO, PSTR("DSP: TM1637"));
} }
} }
} }
/*********************************************************************************************\ /*********************************************************************************************\
* Displays number without decimal, with/without leading zeros, specifying start-position * Displays number without decimal, with/without leading zeros, specifying start-position
* and length, optionally skipping clearing display before displaying the number. * and length, optionally skipping clearing display before displaying the number.
@ -229,17 +228,17 @@ bool CmndTM1637Number(bool clear) {
char pad = (leadingzeros ? '0': ' '); char pad = (leadingzeros ? '0': ' ');
uint32_t i = position; uint32_t i = position;
uint8_t rawBytes[1]; uint8_t rawBytes[1];
rawBytes[0] = display->encode(pad); rawBytes[0] = tm1637display->encode(pad);
for(; i<position + (length - strlen(txt)); i++) { for(; i<position + (length - strlen(txt)); i++) {
if(i>TM1637Data.num_digits) break; if(i>TM1637Data.num_digits) break;
display->printRaw(rawBytes, 1, i); tm1637display->printRaw(rawBytes, 1, i);
} }
for(uint32_t j = 0; i< position + length; i++, j++) { for(uint32_t j = 0; i< position + length; i++, j++) {
if(txt[j] == 0) break; if(txt[j] == 0) break;
rawBytes[0] = display->encode(txt[j]); rawBytes[0] = tm1637display->encode(txt[j]);
if(i>TM1637Data.num_digits) break; if(i>TM1637Data.num_digits) break;
display->printRaw(rawBytes, 1, i); tm1637display->printRaw(rawBytes, 1, i);
} }
return true; return true;
@ -296,14 +295,14 @@ bool CmndTM1637Float(bool clear) {
uint8_t rawBytes[1]; uint8_t rawBytes[1];
for(uint32_t i=0, j=0; i<length; i++, j++) { for(uint32_t i=0, j=0; i<length; i++, j++) {
if(txt[i] == 0) break; if(txt[i] == 0) break;
rawBytes[0] = display->encode(txt[i]); rawBytes[0] = tm1637display->encode(txt[i]);
if(txt[i+1] == '.') { if(txt[i+1] == '.') {
rawBytes[0] = rawBytes[0] | 128; rawBytes[0] = rawBytes[0] | 128;
i++; i++;
length++; length++;
} }
if((j+position) > TM1637Data.num_digits) break; if((j+position) > TM1637Data.num_digits) break;
display->printRaw(rawBytes, 1, j+position); tm1637display->printRaw(rawBytes, 1, j+position);
} }
return true; return true;
@ -325,7 +324,7 @@ bool CmndTM1637Clear(void) {
void TM1637ClearDisplay (void) { void TM1637ClearDisplay (void) {
unsigned char arr[] = {0}; unsigned char arr[] = {0};
AddLog(LOG_LEVEL_DEBUG, PSTR("Clearing digit %d"), TM1637Data.num_digits); AddLog(LOG_LEVEL_DEBUG, PSTR("Clearing digit %d"), TM1637Data.num_digits);
for(int i=0; i<TM1637Data.num_digits; i++) display->printRaw(arr, 1, i); for(int i=0; i<TM1637Data.num_digits; i++) tm1637display->printRaw(arr, 1, i);
} }
@ -386,8 +385,8 @@ void TM1637ScrollText(void) {
if(i > (TM1637Data.num_digits-1)) break; if(i > (TM1637Data.num_digits-1)) break;
if(TM1637Data.scroll_text[j] == 0) {clr = true;}; if(TM1637Data.scroll_text[j] == 0) {clr = true;};
char charToDisp = (clr ? ' ' : TM1637Data.scroll_text[j]); char charToDisp = (clr ? ' ' : TM1637Data.scroll_text[j]);
rawBytes[0] = display->encode(charToDisp); rawBytes[0] = tm1637display->encode(charToDisp);
display->printRaw(rawBytes, 1, i); tm1637display->printRaw(rawBytes, 1, i);
} }
TM1637Data.scroll_index++; TM1637Data.scroll_index++;
} }
@ -424,7 +423,7 @@ bool CmndTM1637Level(void) {
uint8_t value = (((i%2) == 0) ? 54 : 48); uint8_t value = (((i%2) == 0) ? 54 : 48);
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: CmndTM1637Level value %d"), value); AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: CmndTM1637Level value %d"), value);
rawBytes[0] = value; rawBytes[0] = value;
display->printRaw(rawBytes, 1, digit); tm1637display->printRaw(rawBytes, 1, digit);
} }
return true; return true;
} }
@ -494,7 +493,7 @@ bool CmndTM1637Raw(void) {
for(uint32_t i=position; i<position+length; i++ ) { for(uint32_t i=position; i<position+length; i++ ) {
if(i>(TM1637Data.num_digits-1)) break; if(i>(TM1637Data.num_digits-1)) break;
rawBytes[0] = DATA[i-position]; rawBytes[0] = DATA[i-position];
display->printRaw(rawBytes, 1, i); tm1637display->printRaw(rawBytes, 1, i);
} }
return true; return true;
@ -540,14 +539,14 @@ bool CmndTM1637Text(bool clear) {
for(uint32_t j = 0; i< position + length; i++, j++) { for(uint32_t j = 0; i< position + length; i++, j++) {
if(i > (TM1637Data.num_digits-1)) break; if(i > (TM1637Data.num_digits-1)) break;
if(sString[j] == 0) break; if(sString[j] == 0) break;
rawBytes[0] = display->encode(sString[j]); rawBytes[0] = tm1637display->encode(sString[j]);
if(sString[j+1] == '.') { if(sString[j+1] == '.') {
rawBytes[0] = rawBytes[0] | 128; rawBytes[0] = rawBytes[0] | 128;
j++; j++;
} else if(sString[j] == '^') { } else if(sString[j] == '^') {
rawBytes[0] = 1 | 2 | 32 | 64; rawBytes[0] = 1 | 2 | 32 | 64;
} }
display->printRaw(rawBytes, 1, i); tm1637display->printRaw(rawBytes, 1, i);
} }
return true; return true;
@ -573,7 +572,7 @@ bool CmndTM1637Brightness(void) {
} }
TM1637Data.brightness = val; TM1637Data.brightness = val;
display->setBacklight(TM1637Data.brightness*10); tm1637display->setBacklight(TM1637Data.brightness*10);
return true; return true;
} }
@ -629,9 +628,9 @@ void TM1637ShowTime() {
} }
uint8_t rawBytes[1]; uint8_t rawBytes[1];
for(uint32_t i = 0; i< 4; i++) { for(uint32_t i = 0; i< 4; i++) {
rawBytes[0] = display->encode(tm[i]); rawBytes[0] = tm1637display->encode(tm[i]);
if((millis() % 1000) > 500 && (i == 1)) rawBytes[0] = rawBytes[0] | 128; if((millis() % 1000) > 500 && (i == 1)) rawBytes[0] = rawBytes[0] | 128;
display->printRaw(rawBytes, 1, i); tm1637display->printRaw(rawBytes, 1, i);
} }
} }
@ -643,9 +642,9 @@ bool TM1637Cmd(uint8_t fn) {
TM1637Data.num_digits = Settings.display_size; TM1637Data.num_digits = Settings.display_size;
if(TM1637Data.prev_num_digits != TM1637Data.num_digits) { // Cleck for change of display size, and re-init the library if(TM1637Data.prev_num_digits != TM1637Data.num_digits) { // Cleck for change of display size, and re-init the library
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: Size changed. Re-initializing library...")); AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: Size changed. Re-initializing library..."));
display = new SevenSegmentTM1637(Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSPI_MOSI) ); tm1637display = new SevenSegmentTM1637(Pin(GPIO_TM1637CLK), Pin(GPIO_TM1637DIO));
display->begin(TM1637Data.num_digits, 1); tm1637display->begin(TM1637Data.num_digits, 1);
display->setBacklight(40); tm1637display->setBacklight(40);
TM1637ClearDisplay(); TM1637ClearDisplay();
TM1637Data.prev_num_digits = TM1637Data.num_digits; TM1637Data.prev_num_digits = TM1637Data.num_digits;
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: Re-initialized library")); AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: Re-initialized library"));

View File

@ -49,8 +49,9 @@
#define SPECIAL_SS #define SPECIAL_SS
#endif #endif
#undef TMSBSIZ #ifndef TMSBSIZ
#define TMSBSIZ 256 #define TMSBSIZ 256
#endif
// addresses a bug in meter DWS74 // addresses a bug in meter DWS74
//#define DWS74_BUG //#define DWS74_BUG
@ -469,7 +470,7 @@ uint8_t dvalid[SML_MAX_VARS];
struct METER_DESC const *meter_desc_p; struct METER_DESC const *meter_desc_p;
const uint8_t *meter_p; const uint8_t *meter_p;
uint8_t meter_spos[MAX_METERS]; uint16_t meter_spos[MAX_METERS];
// software serial pointers // software serial pointers
#ifdef ESP8266 #ifdef ESP8266
@ -820,13 +821,12 @@ uint8_t Serial_peek() {
} }
uint8_t sml_logindex; uint8_t sml_logindex;
char log_data[128];
void Dump2log(void) { void Dump2log(void) {
int16_t index=0,hcnt=0; int16_t index=0,hcnt=0;
uint32_t d_lastms; uint32_t d_lastms;
uint8_t dchars[16]; uint8_t dchars[16];
char log_data[128];
//if (!SML_SAVAILABLE) return; //if (!SML_SAVAILABLE) return;
@ -1258,7 +1258,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) {
// QQ,ZZ,PB,SB,NN ..... CRC, ACK SYNC // QQ,ZZ,PB,SB,NN ..... CRC, ACK SYNC
if (meter_spos[meters]>4+5) { if (meter_spos[meters]>4+5) {
// get telegramm lenght // get telegramm lenght
uint8_t tlen=smltbuf[meters][4]+5; uint16_t tlen=smltbuf[meters][4]+5;
// test crc // test crc
if (smltbuf[meters][tlen]=ebus_CalculateCRC(smltbuf[meters],tlen)) { if (smltbuf[meters][tlen]=ebus_CalculateCRC(smltbuf[meters],tlen)) {
ebus_esc(smltbuf[meters],tlen); ebus_esc(smltbuf[meters],tlen);
@ -1548,15 +1548,17 @@ void SML_Decode(uint8_t index) {
#endif #endif
if (*mp == '#') { if (*mp == '#') {
// get string value // get string value
getstr:
mp++; mp++;
if (meter_desc_p[mindex].type == 'o') { if (meter_desc_p[mindex].type == 'o') {
for (uint8_t p=0; p<METER_ID_SIZE; p++) { uint32_t p;
for (p = 0; p < METER_ID_SIZE - 2; p++) {
if (*cp == *mp) { if (*cp == *mp) {
meter_id[mindex][p] = 0;
break; break;
} }
meter_id[mindex][p] = *cp++; meter_id[mindex][p] = *cp++;
} }
meter_id[mindex][p] = 0;
} else { } else {
sml_getvalue(cp,mindex); sml_getvalue(cp,mindex);
} }
@ -1567,12 +1569,26 @@ void SML_Decode(uint8_t index) {
if (meter_desc_p[mindex].type=='o' || meter_desc_p[mindex].type=='c') { if (meter_desc_p[mindex].type=='o' || meter_desc_p[mindex].type=='c') {
if (*mp == '(') { if (*mp == '(') {
mp++; mp++;
// skip this bracket // skip this number of brackets
char *bp = strchr((char*)cp, '('); uint8_t toskip = strtol((char*)mp,(char**)&mp, 10);
if (bp) { mp++;
cp = (uint8_t*) (bp + 1); char *lcp = (char*)cp;
if (toskip) {
char *bp = (char*)cp;
for (uint32_t cnt = 0; cnt < toskip; cnt++) {
bp = strchr(bp, '(');
if (!bp) {
break;
} }
dval=CharToDouble((char*)cp); bp++;
lcp = bp;
}
}
if (*mp=='#') {
cp = (uint8_t*)lcp;
goto getstr;
}
dval=CharToDouble((char*)lcp);
} else { } else {
dval=CharToDouble((char*)cp); dval=CharToDouble((char*)cp);
} }
@ -1623,13 +1639,14 @@ void SML_Decode(uint8_t index) {
#else #else
meter_vars[vindex]=dval; meter_vars[vindex]=dval;
#endif #endif
dvalid[vindex] = 1;
//AddLog_P(LOG_LEVEL_INFO, PSTR(">> %s"),mp); //AddLog_P(LOG_LEVEL_INFO, PSTR(">> %s"),mp);
// get scaling factor // get scaling factor
double fac=CharToDouble((char*)mp); double fac=CharToDouble((char*)mp);
meter_vars[vindex]/=fac; meter_vars[vindex]/=fac;
SML_Immediate_MQTT((const char*)mp,vindex,mindex); SML_Immediate_MQTT((const char*)mp,vindex,mindex);
} }
dvalid[vindex] = 1;
} }
} }
nextsect: nextsect:
@ -1737,10 +1754,20 @@ void SML_Show(boolean json) {
cp=strchr(mp,'@'); cp=strchr(mp,'@');
if (cp) { if (cp) {
cp++; cp++;
tststr:
if (*cp=='#') { if (*cp=='#') {
// meter id // meter id
sprintf(tpowstr,"\"%s\"",&meter_id[mindex][0]); sprintf(tpowstr,"\"%s\"",&meter_id[mindex][0]);
mid=1; mid=1;
} else if (*cp=='(') {
if (meter_desc_p[mindex].type=='o') {
cp++;
strtol((char*)cp,(char**)&cp, 10);
cp++;
goto tststr;
} else {
mid=0;
}
} else { } else {
mid=0; mid=0;
} }
@ -1987,155 +2014,182 @@ void SML_Init(void) {
if (meter_script==99) { if (meter_script==99) {
// use script definition // use script definition
if (script_meter) free(script_meter); if (script_meter) free(script_meter);
script_meter=0; script_meter = 0;
uint8_t *tp=0; uint8_t *tp = 0;
uint16_t index=0; uint16_t index = 0;
uint8_t section=0; uint8_t section = 0;
uint8_t srcpin=0; uint8_t srcpin = 0;
char *lp=glob_script_mem.scriptptr; uint8_t dec_line = 0;
sml_send_blocks=0; char *lp = glob_script_mem.scriptptr;
sml_send_blocks = 0;
while (lp) { while (lp) {
if (!section) { if (!section) {
if (*lp=='>' && *(lp+1)=='M') { if (*lp == '>' && *(lp+1) == 'M') {
lp+=2; lp += 2;
meters_used=strtol(lp,0,10); meters_used = strtol(lp, 0, 10);
section=1; section = 1;
uint32_t mlen=SML_getscriptsize(lp); uint32_t mlen = SML_getscriptsize(lp);
if (mlen==0) return; // missing end # if (mlen == 0) return; // missing end #
script_meter=(uint8_t*)calloc(mlen,1); script_meter = (uint8_t*)calloc(mlen, 1);
if (!script_meter) { if (!script_meter) {
goto dddef_exit; goto dddef_exit;
} }
tp=script_meter; tp = script_meter;
goto next_line; goto next_line;
} }
} }
else { else {
if (!*lp || *lp=='#' || *lp=='>') { if (!*lp || *lp == '#' || *lp == '>') {
if (*(tp-1)=='|') *(tp-1)=0; if (*(tp-1) == '|') *(tp-1) = 0;
break; break;
} }
if (*lp=='+') { if (*lp == '+') {
// add descriptor +1,1,c,0,10,H20 // add descriptor +1,1,c,0,10,H20
//toLogEOL(">>",lp); //toLogEOL(">>",lp);
lp++; lp++;
index=*lp&7; index = *lp&7;
lp+=2; lp += 2;
if (index<1 || index>meters_used) goto next_line; if (index < 1 || index > meters_used) {
AddLog(LOG_LEVEL_INFO, PSTR("illegal meter number!"));
goto next_line;
}
index--; index--;
srcpin=strtol(lp,&lp,10); srcpin = strtol(lp,&lp,10);
if (Gpio_used(srcpin)) { if (Gpio_used(srcpin)) {
AddLog(LOG_LEVEL_INFO, PSTR("gpio rx double define!")); AddLog(LOG_LEVEL_INFO, PSTR("gpio rx double define!"));
dddef_exit: dddef_exit:
if (script_meter) free(script_meter); if (script_meter) free(script_meter);
script_meter=0; script_meter = 0;
meters_used=METERS_USED; meters_used = METERS_USED;
goto init10; goto init10;
} }
script_meter_desc[index].srcpin=srcpin; script_meter_desc[index].srcpin = srcpin;
if (*lp!=',') goto next_line; if (*lp != ',') goto next_line;
lp++; lp++;
script_meter_desc[index].type=*lp; script_meter_desc[index].type = *lp;
lp++; lp++;
if (*lp!=',') { if (*lp != ',') {
script_meter_desc[index].sopt=*lp&7; script_meter_desc[index].sopt = *lp&7;
lp++; lp++;
} else { } else {
script_meter_desc[index].sopt=0; script_meter_desc[index].sopt = 0;
} }
lp++; lp++;
script_meter_desc[index].flag=strtol(lp,&lp,10); script_meter_desc[index].flag = strtol(lp, &lp, 10);
if (*lp!=',') goto next_line; if (*lp != ',') goto next_line;
lp++; lp++;
script_meter_desc[index].params=strtol(lp,&lp,10); script_meter_desc[index].params = strtol(lp, &lp, 10);
if (*lp!=',') goto next_line; if (*lp != ',') goto next_line;
lp++; lp++;
script_meter_desc[index].prefix[7]=0; script_meter_desc[index].prefix[7] = 0;
for (uint32_t cnt=0; cnt<8; cnt++) { for (uint32_t cnt = 0; cnt < 8; cnt++) {
if (*lp==SCRIPT_EOL || *lp==',') { if (*lp == SCRIPT_EOL || *lp == ',') {
script_meter_desc[index].prefix[cnt]=0; script_meter_desc[index].prefix[cnt] = 0;
break; break;
} }
script_meter_desc[index].prefix[cnt]=*lp++; script_meter_desc[index].prefix[cnt] = *lp++;
} }
if (*lp==',') { if (*lp == ',') {
lp++; lp++;
script_meter_desc[index].trxpin=strtol(lp,&lp,10); script_meter_desc[index].trxpin = strtol(lp, &lp, 10);
if (Gpio_used(script_meter_desc[index].trxpin)) { if (Gpio_used(script_meter_desc[index].trxpin)) {
AddLog(LOG_LEVEL_INFO, PSTR("gpio tx double define!")); AddLog(LOG_LEVEL_INFO, PSTR("gpio tx double define!"));
goto dddef_exit; goto dddef_exit;
} }
if (*lp!=',') goto next_line; if (*lp != ',') goto next_line;
lp++; lp++;
script_meter_desc[index].tsecs=strtol(lp,&lp,10); script_meter_desc[index].tsecs = strtol(lp, &lp, 10);
if (*lp==',') { if (*lp == ',') {
lp++; lp++;
char txbuff[256]; char txbuff[256];
uint32_t txlen=0,tx_entries=1; uint32_t txlen = 0, tx_entries = 1;
for (uint32_t cnt=0; cnt<sizeof(txbuff); cnt++) { for (uint32_t cnt = 0; cnt < sizeof(txbuff); cnt++) {
if (*lp==SCRIPT_EOL) { if (*lp == SCRIPT_EOL) {
txbuff[cnt]=0; txbuff[cnt] = 0;
txlen=cnt; txlen = cnt;
break; break;
} }
if (*lp==',') tx_entries++; if (*lp == ',') tx_entries++;
txbuff[cnt]=*lp++; txbuff[cnt] = *lp++;
} }
if (txlen) { if (txlen) {
script_meter_desc[index].txmem=(char*)calloc(txlen+2,1); script_meter_desc[index].txmem = (char*)calloc(txlen+2, 1);
if (script_meter_desc[index].txmem) { if (script_meter_desc[index].txmem) {
strcpy(script_meter_desc[index].txmem,txbuff); strcpy(script_meter_desc[index].txmem,txbuff);
} }
script_meter_desc[index].index=0; script_meter_desc[index].index = 0;
script_meter_desc[index].max_index=tx_entries; script_meter_desc[index].max_index = tx_entries;
sml_send_blocks++; sml_send_blocks++;
} }
} }
} }
if (*lp==SCRIPT_EOL) lp--; if (*lp == SCRIPT_EOL) lp--;
goto next_line; goto next_line;
} }
#ifdef SML_REPLACE_VARS #ifdef SML_REPLACE_VARS
char dstbuf[SML_SRCBSIZE*2]; char dstbuf[SML_SRCBSIZE*2];
Replace_Cmd_Vars(lp,1,dstbuf,sizeof(dstbuf)); Replace_Cmd_Vars(lp, 1, dstbuf,sizeof(dstbuf));
lp+=SML_getlinelen(lp); lp += SML_getlinelen(lp);
//AddLog_P(LOG_LEVEL_INFO, PSTR("%s"),dstbuf); //AddLog_P(LOG_LEVEL_INFO, PSTR("%s"),dstbuf);
char *lp1=dstbuf; char *lp1 = dstbuf;
if (*lp1=='-' || isdigit(*lp1)) { if (*lp1 == '-' || isdigit(*lp1)) {
//toLogEOL(">>",lp); //toLogEOL(">>",lp);
// add meters line -1,1-0:1.8.0*255(@10000,H2OIN,cbm,COUNTER,4| // add meters line -1,1-0:1.8.0*255(@10000,H2OIN,cbm,COUNTER,4|
if (*lp1=='-') lp1++; if (*lp1 == '-') lp1++;
uint8_t mnum=strtol(lp1,0,10); uint8_t mnum = strtol(lp1, 0, 10);
if (mnum<1 || mnum>meters_used) goto next_line; if (mnum < 1 || mnum > meters_used) {
while (1) { AddLog(LOG_LEVEL_INFO, PSTR("illegal meter number!"));
if (*lp1==0) {
*tp++='|';
goto next_line; goto next_line;
} }
*tp++=*lp1++; // 1,=h—————————————
if (strncmp(lp1 + 1, ",=h", 3)) {
dec_line++;
if (dec_line >= SML_MAX_VARS) {
AddLog(LOG_LEVEL_INFO, PSTR("too many decode lines: %d !"), dec_line);
goto next_line;
}
}
while (1) {
if (*lp1 == 0) {
*tp++ = '|';
goto next_line;
}
*tp++ = *lp1++;
index++; index++;
if (index>=METER_DEF_SIZE) break; if (index >= METER_DEF_SIZE) break;
} }
} }
#else #else
if (*lp=='-' || isdigit(*lp)) { if (*lp == '-' || isdigit(*lp)) {
//toLogEOL(">>",lp); //toLogEOL(">>",lp);
// add meters line -1,1-0:1.8.0*255(@10000,H2OIN,cbm,COUNTER,4| // add meters line -1,1-0:1.8.0*255(@10000,H2OIN,cbm,COUNTER,4|
if (*lp=='-') lp++; if (*lp == '-') lp++;
uint8_t mnum=strtol(lp,0,10); uint8_t mnum = strtol(lp,0,10);
if (mnum<1 || mnum>meters_used) goto next_line; if (mnum < 1 || mnum > meters_used) {
while (1) { AddLog(LOG_LEVEL_INFO, PSTR("illegal meter number!"));
if (*lp==SCRIPT_EOL) {
if (*(tp-1)!='|') *tp++='|';
goto next_line; goto next_line;
} }
*tp++=*lp++; if (strncmp(lp + 1, ",=h", 3)) {
index++; dec_line++;
if (index>=METER_DEF_SIZE) break; if (dec_line >= SML_MAX_VARS) {
AddLog(LOG_LEVEL_INFO, PSTR("too many decode lines: %d !"), dec_line);
goto next_line;
} }
} }
while (1) {
if (*lp == SCRIPT_EOL) {
if (*(tp-1) != '|') *tp++ = '|';
goto next_line;
}
*tp++ = *lp++;
index++;
if (index >= METER_DEF_SIZE) break;
}
}
#endif #endif
} }

View File

@ -41,9 +41,8 @@ struct EZOCO2 : public EZOStruct {
{ {
if (json) { if (json) {
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_CO2 "\":%d}" ), name, CO2); ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_CO2 "\":%d}" ), name, CO2);
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { }else {
WSContentSend_PD(HTTP_SNS_CO2, name, CO2); WSContentSend_PD(HTTP_SNS_CO2, name, CO2);
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }

View File

@ -23,7 +23,7 @@
#define EZO_DO_READ_LATENCY 600 #define EZO_DO_READ_LATENCY 600
struct EZODO : public EZOStruct { struct EZODO : public EZOStruct {
EZODO(uint32_t addr) : EZOStruct(addr), DO(0) {} EZODO(uint32_t addr) : EZOStruct(addr), DO(NAN) {}
virtual void ProcessMeasurement(void) virtual void ProcessMeasurement(void)
{ {
@ -39,10 +39,11 @@ struct EZODO : public EZOStruct {
dtostrfd(DO, 2, str); dtostrfd(DO, 2, str);
if (json) { if (json) {
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DO "\":%d}" ), name, str); ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DO "\":%s" ), name, str);
} ResponseJsonEnd();
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { }else {
WSContentSend_PD(HTTP_SNS_DO, name, str); WSContentSend_PD(HTTP_SNS_DO, name, str);
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }
@ -54,7 +55,7 @@ private:
float DO; float DO;
}; };
const char EZODO::id[] PROGMEM = "D.O."; const char EZODO::id[] PROGMEM = "DO";
#endif // USE_EZODO #endif // USE_EZODO
#endif // USE_I2C #endif // USE_I2C

View File

@ -40,9 +40,8 @@ struct EZOEC : public EZOStruct {
if (json) { if (json) {
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_EC "\":%s}" ), name, str); ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_EC "\":%s}" ), name, str);
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { }else {
WSContentSend_PD(HTTP_SNS_EC, name, str); WSContentSend_PD(HTTP_SNS_EC, name, str);
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }

View File

@ -40,9 +40,8 @@ struct EZOO2 : public EZOStruct {
if (json) { if (json) {
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_O2 "\":%d}" ), name, str); ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_O2 "\":%d}" ), name, str);
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { }else {
WSContentSend_PD(HTTP_SNS_O2, name, str); WSContentSend_PD(HTTP_SNS_O2, name, str);
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }

View File

@ -40,9 +40,8 @@ struct EZOORP : public EZOStruct {
if (json) { if (json) {
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_ORP "\":%s}" ), name, str); ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_ORP "\":%s}" ), name, str);
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { }else {
WSContentSend_PD(HTTP_SNS_ORP, name, str); WSContentSend_PD(HTTP_SNS_ORP, name, str);
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }

View File

@ -40,9 +40,8 @@ struct EZOPH : public EZOStruct {
if (json) { if (json) {
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_PH "\":%s}" ), name, str); ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_PH "\":%s}" ), name, str);
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { }else {
WSContentSend_PD(HTTP_SNS_PH, name, str); WSContentSend_PD(HTTP_SNS_PH, name, str);
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }

View File

@ -46,9 +46,8 @@ struct EZOPRS : public EZOStruct {
ResponseAppend_P(PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sealevelstr); ResponseAppend_P(PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sealevelstr);
} }
ResponseJsonEnd(); ResponseJsonEnd();
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { }else {
WSContentSend_PD(HTTP_SNS_PRESSURE, name, str, PressureUnit().c_str()); WSContentSend_PD(HTTP_SNS_PRESSURE, name, str, PressureUnit().c_str());
if (Settings.altitude != 0) { if (Settings.altitude != 0) {
WSContentSend_PD(HTTP_SNS_SEAPRESSURE, name, sealevelstr, PressureUnit().c_str()); WSContentSend_PD(HTTP_SNS_SEAPRESSURE, name, sealevelstr, PressureUnit().c_str());

View File

@ -39,9 +39,8 @@ struct EZORTD : public EZOStruct {
if (json) { if (json) {
ResponseAppend_P(JSON_SNS_F_TEMP, name, Settings.flag2.temperature_resolution, &temp); ResponseAppend_P(JSON_SNS_F_TEMP, name, Settings.flag2.temperature_resolution, &temp);
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { }else {
WSContentSend_Temp(name, temp); WSContentSend_Temp(name, temp);
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }

View File

@ -174,8 +174,10 @@ a_setoption = [[
"(Light) run fading at fixed duration instead of fixed slew rate", "(Light) run fading at fixed duration instead of fixed slew rate",
"(Zigbee) Move ZbReceived from JSON message and into the subtopic replacing SENSOR default", "(Zigbee) Move ZbReceived from JSON message and into the subtopic replacing SENSOR default",
"(Zigbee) Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic", "(Zigbee) Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic",
"","", "(Zigbee) Append endpoint number to topic if device dependent (use with SetOption89)",
"","","","", "(MQTT) Retain on State",
"(MQTT) Retain on Info",
"","","",
"","","","", "","","","",
"","","","", "","","","",
"","","","", "","","","",
@ -282,7 +284,7 @@ else:
obj = json.load(fp) obj = json.load(fp)
def StartDecode(): def StartDecode():
print ("\n*** decode-status.py v20210217 by Theo Arends and Jacek Ziolkowski ***") print ("\n*** decode-status.py v20210222 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj)) # print("Decoding\n{}".format(obj))