mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' of https://github.com/arendst/Sonoff-Tasmota into development
This commit is contained in:
commit
1e3b024edc
|
@ -3,8 +3,9 @@
|
||||||
**Related issue (if applicable):** fixes #<Sonoff-Tasmota issue number goes here>
|
**Related issue (if applicable):** fixes #<Sonoff-Tasmota issue number goes here>
|
||||||
|
|
||||||
## Checklist:
|
## Checklist:
|
||||||
- [ ] The pull request is done against the dev branch
|
- [ ] The pull request is done against the latest dev branch
|
||||||
- [ ] Only relevant files were touched (Also beware if your editor has auto-formatting feature enabled)
|
- [ ] Only relevant files were touched (Also remember to update _changelog.ino_ file)
|
||||||
- [ ] Only one feature/fix was added per PR.
|
- [ ] Only one feature/fix was added per PR.
|
||||||
- [ ] The code change is tested and works.
|
- [ ] The code change is tested and works.
|
||||||
- [ ] The code change pass travis tests. **Your PR cannot be merged unless tests pass**
|
- [ ] The code change pass travis tests. **Your PR cannot be merged unless tests pass**
|
||||||
|
- [ ] I accept the [CLA](https://github.com/arendst/Sonoff-Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
|
||||||
|
|
|
@ -56,7 +56,57 @@ The process is straight-forward.
|
||||||
7. All pull requests should consider updates to the documentation.
|
7. All pull requests should consider updates to the documentation.
|
||||||
8. Pull requests that address an outstanding issue, particularly an issue deemed to be severe, should be given priority.
|
8. Pull requests that address an outstanding issue, particularly an issue deemed to be severe, should be given priority.
|
||||||
9. If a PR is accepted, then it should undergo review and updated based on the feedback provided, then merged.
|
9. If a PR is accepted, then it should undergo review and updated based on the feedback provided, then merged.
|
||||||
10. Pull requests that don't meet the above will be denied and closed.
|
10. By submitting a PR, it is needed to use the provided PR template and check all boxes, performing the required tasks and accepting the CLA.
|
||||||
|
11. Pull requests that don't meet the above will be denied and closed.
|
||||||
|
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
## Contributor License Agreement (CLA)
|
||||||
|
|
||||||
|
```
|
||||||
|
By making a contribution to this project, I certify that:
|
||||||
|
|
||||||
|
(a) The contribution was created in whole or in part by me and I
|
||||||
|
have the right to submit it under the GPL-3.0 license; or
|
||||||
|
|
||||||
|
(b) The contribution is based upon previous work that, to the best
|
||||||
|
of my knowledge, is covered under an appropriate open source
|
||||||
|
license and I have the right under that license to submit that
|
||||||
|
work with modifications, whether created in whole or in part
|
||||||
|
by me, under the GPL-3.0 license; or
|
||||||
|
|
||||||
|
(c) The contribution was provided directly to me by some other
|
||||||
|
person who certified (a), (b) or (c) and I have not modified
|
||||||
|
it.
|
||||||
|
|
||||||
|
(d) I understand and agree that this project and the contribution
|
||||||
|
are public and that a record of the contribution (including all
|
||||||
|
personal information I submit with it) is maintained indefinitely
|
||||||
|
and may be redistributed consistent with this project or the open
|
||||||
|
source license(s) involved.
|
||||||
|
```
|
||||||
|
|
||||||
|
This Contributor License Agreement (CLA) was adopted on April 1st, 2019.
|
||||||
|
|
||||||
|
The text of this license is available under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/). It is based on the Linux [Developer Certificate Of Origin](http://elinux.org/Developer_Certificate_Of_Origin), but is modified to explicitly use the GPL-3.0 license and not mention sign-off (due to GitHub.com keeps an historial, with your user name, of PRs' commits and all editions on PR's comments).
|
||||||
|
|
||||||
|
To accept the CLA it is required to put a x between [ ] on `[ ] I accept the CLA` in the PR template when submitting it. The [ ] is an opt-in box, so you have to manually accept it.
|
||||||
|
|
||||||
|
**Why a CLA ?**
|
||||||
|
|
||||||
|
_"A Contributor Licence Agreement (CLA) is strongly recommended when accepting third party contributions to an open development project, such as an open source software project. In order to redistribute contributions, it is necessary to ensure that the project has the necessary rights to do so. A Contributor Licence Agreement is a lightweight agreement, signed by the copyright holder, that grants the necessary rights for the contribution to be redistributed as part of the project."_ [OSS Watch](http://oss-watch.ac.uk/resources/cla)
|
||||||
|
|
||||||
|
A CLA is a legal document in which you state _you are entitled to contribute the code/documentation/translation to the project_ you’re contributing to and that _you are willing to have it used in distributions and derivative works_. This means that should there be any kind of legal issue in the future as to the origins and ownership of any particular piece of code, then that project has the necessary forms on file from the contributor(s) saying they were permitted to make this contribution.
|
||||||
|
|
||||||
|
CLA is a safety because it also ensures that once you have provided a contribution, you cannot try to withdraw permission for its use at a later date. People can therefore use that software, confident that they will not be asked to stop using pieces of the code at a later date.
|
||||||
|
|
||||||
|
A __license__ grants "outbound" rights to the user of project.
|
||||||
|
|
||||||
|
A __CLA__ enables a contributor to grant "inbound" rights to a project.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Other>
|
<Other>
|
||||||
<A table should be maintained for relating maintainers and components. When triaging, this is essential to figure out if someone in particular should be consulted about specific changes.>
|
<A table should be maintained for relating maintainers and components. When triaging, this is essential to figure out if someone in particular should be consulted about specific changes.>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
## Sonoff-Tasmota
|
## Sonoff-Tasmota
|
||||||
|
|
||||||
Alternative firmware for _ESP8266 based devices_ like [iTead](https://www.itead.cc/) _**Sonoff**_ with **web UI, rules and timers, OTA updates, custome device templates and sensors support**. Allows control over **MQTT**, **HTTP**, **Serial** and **KNX** for integrations with smart home systems. Written for Arduino IDE and PlatformIO.
|
Alternative firmware for _ESP8266 based devices_ like [iTead](https://www.itead.cc/) _**Sonoff**_ with **web UI, rules and timers, OTA updates, custom device templates and sensor support**. Allows control over **MQTT**, **HTTP**, **Serial** and **KNX** for integrations with smart home systems. Written for Arduino IDE and PlatformIO.
|
||||||
|
|
||||||
[![GitHub version](https://img.shields.io/github/release/arendst/Sonoff-Tasmota.svg)](https://github.com/arendst/Sonoff-Tasmota/releases/latest)
|
[![GitHub version](https://img.shields.io/github/release/arendst/Sonoff-Tasmota.svg)](https://github.com/arendst/Sonoff-Tasmota/releases/latest)
|
||||||
[![GitHub download](https://img.shields.io/github/downloads/arendst/Sonoff-Tasmota/total.svg)](https://github.com/arendst/Sonoff-Tasmota/releases/latest)
|
[![GitHub download](https://img.shields.io/github/downloads/arendst/Sonoff-Tasmota/total.svg)](https://github.com/arendst/Sonoff-Tasmota/releases/latest)
|
||||||
|
@ -15,7 +15,7 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute!
|
||||||
|
|
||||||
See [RELEASENOTES.md](https://github.com/arendst/Sonoff-Tasmota/blob/development/RELEASENOTES.md) for release information.
|
See [RELEASENOTES.md](https://github.com/arendst/Sonoff-Tasmota/blob/development/RELEASENOTES.md) for release information.
|
||||||
|
|
||||||
In addition to the [release webpage](https://github.com/arendst/Sonoff-Tasmota/releases/latest) the binaries can also be OTA downloaded from http://thehackbox.org/tasmota/release/
|
In addition to the [release webpage](https://github.com/arendst/Sonoff-Tasmota/releases/latest), the binaries can also be OTA downloaded from http://thehackbox.org/tasmota/release/
|
||||||
|
|
||||||
### Development
|
### Development
|
||||||
[![Dev Version](https://img.shields.io/badge/development%20version-6.5.0.x-blue.svg)](https://github.com/arendst/Sonoff-Tasmota)
|
[![Dev Version](https://img.shields.io/badge/development%20version-6.5.0.x-blue.svg)](https://github.com/arendst/Sonoff-Tasmota)
|
||||||
|
@ -29,12 +29,12 @@ The development codebase is checked hourly for changes and if new commits have b
|
||||||
### Disclaimer
|
### Disclaimer
|
||||||
:warning: **DANGER OF ELECTROCUTION** :warning:
|
:warning: **DANGER OF ELECTROCUTION** :warning:
|
||||||
|
|
||||||
A Sonoff device is not a toy. It uses Mains AC so there is a danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician. Remember: _**SAFETY FIRST**_. It is not worth to risk yourself, your family and your home if you don't know exactly what you are doing. Never try to flash a Sonoff device while it is connected to MAINS AC.
|
A Sonoff device is not a toy. It uses Mains AC so there is a danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician. Remember: _**SAFETY FIRST**_. It is not worth risk to yourself, your family, and your home if you don't know exactly what you are doing. Never try to flash a Sonoff device while it is connected to MAINS AC.
|
||||||
|
|
||||||
We don't take any responsibility nor liability for using this software nor for the installation or any tips, advice, videos, etc. given by any member of this site or any related site.
|
We don't take any responsibility nor liability for using this software nor for the installation or any tips, advice, videos, etc. given by any member of this site or any related site.
|
||||||
|
|
||||||
### Note
|
### Note
|
||||||
Please do not ask to add devices where you can't provide a basic working configuration (other than sonoff). Since there are thousands of them..
|
Please do not ask to add devices where you can't provide a basic working configuration (other than sonoff). Since there are thousands of them.
|
||||||
|
|
||||||
### Quick Install
|
### Quick Install
|
||||||
Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki.
|
Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki.
|
||||||
|
|
|
@ -71,14 +71,14 @@ Module | Description
|
||||||
49 Neo Coolcam | Neo Coolcam Wifi Smart Socket
|
49 Neo Coolcam | Neo Coolcam Wifi Smart Socket
|
||||||
50 ESP Switch | ESP Switch 4-gang Wifi Switch with Leds
|
50 ESP Switch | ESP Switch 4-gang Wifi Switch with Leds
|
||||||
51 OBI Socket | OBI Wifi Smart Socket
|
51 OBI Socket | OBI Wifi Smart Socket
|
||||||
52 Teckin | Teckin SP20 Wifi Smart Switch with Energy Monitoring
|
52 Teckin | Teckin SP22 Wifi Smart Switch with Energy Monitoring
|
||||||
53 AplicWDP303075 | Aplic WDP 303075 CSL Wifi Smart Switch with Energy Monitoring
|
53 AplicWDP303075 | Aplic WDP 303075 CSL Wifi Smart Switch with Energy Monitoring
|
||||||
54 Tuya Dimmer | MIUO (and other Tuya based) Wifi Dimmer for Incandescent Lights and Led
|
54 Tuya Dimmer | MIUO (and other Tuya based) Wifi Dimmer for Incandescent Lights and Led
|
||||||
55 Gosund SP1 v23 | Gosund SP1 v2.3 Wifi Smart Switch with Energy Monitoring
|
55 Gosund SP1 v23 | Gosund SP1 v2.3 Wifi Smart Switch with Energy Monitoring
|
||||||
56 ARMTR Dimmer | ARMtronix Wifi dimmer for Incandescent Lights and Led
|
56 ARMTR Dimmer | ARMtronix Wifi dimmer for Incandescent Lights and Led
|
||||||
57 SK03 Outdoor | SK03 Outdoor Wifi Smart Switch with Energy Monitoring
|
57 SK03 Outdoor | SK03 Outdoor Wifi Smart Switch with Energy Monitoring
|
||||||
58 PS-16-DZ | PS-16-DZ Wifi dimmer for Incandescent Lights and Led
|
58 PS-16-DZ | PS-16-DZ Wifi dimmer for Incandescent Lights and Led
|
||||||
59 Teckin US | Teckin US and ZooZee SA102 Wifi Smart Switch with Energy Monitoring
|
59 Teckin US | Teckin SP20 and ZooZee SA102 Wifi Smart Switch with Energy Monitoring
|
||||||
60 Manzoku strip | Manzoku Wifi Smart Power Strip with four Relays
|
60 Manzoku strip | Manzoku Wifi Smart Power Strip with four Relays
|
||||||
61 OBI Socket 2 | OBI 2 Wifi Smart Socket
|
61 OBI Socket 2 | OBI 2 Wifi Smart Socket
|
||||||
62 YTF IR Bridge | YTF Infra Red Wifi Bridge
|
62 YTF IR Bridge | YTF Infra Red Wifi Bridge
|
||||||
|
@ -194,6 +194,7 @@ Core version **2.4.2** binaries can be found at http://thehackbox.org/tasmota/re
|
||||||
| USE_RC_SWITCH | - | - | - | x | x | x | x |
|
| USE_RC_SWITCH | - | - | - | x | x | x | x |
|
||||||
| USE_RF_SENSOR | - | - | - | - | - | x | - | AlectoV2 only
|
| USE_RF_SENSOR | - | - | - | - | - | x | - | AlectoV2 only
|
||||||
| USE_SM16716 | - | x | x | x | x | x | x |
|
| USE_SM16716 | - | x | x | x | x | x | x |
|
||||||
|
| USE_HRE | - | - | - | - | - | x | - |
|
||||||
| USE_DISPLAY | - | - | - | - | - | - | x |
|
| USE_DISPLAY | - | - | - | - | - | - | x |
|
||||||
| USE_DISPLAY_LCD | - | - | - | - | - | - | x |
|
| USE_DISPLAY_LCD | - | - | - | - | - | - | x |
|
||||||
| USE_DISPLAY_SSD1306 | - | - | - | - | - | - | x |
|
| USE_DISPLAY_SSD1306 | - | - | - | - | - | - | x |
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -67,9 +67,11 @@ build_flags = ${esp82xx_defaults.build_flags}
|
||||||
|
|
||||||
[core_2_5_0]
|
[core_2_5_0]
|
||||||
; *** Esp8266 core for Arduino version 2.5.0
|
; *** Esp8266 core for Arduino version 2.5.0
|
||||||
platform = espressif8266@2.0.1
|
platform = espressif8266@~2.0.4
|
||||||
build_flags = ${esp82xx_defaults.build_flags}
|
build_flags = ${esp82xx_defaults.build_flags}
|
||||||
-Wl,-Teagle.flash.1m.ld
|
-Wl,-Teagle.flash.1m.ld
|
||||||
|
; Code optimization see https://github.com/esp8266/Arduino/issues/5790#issuecomment-475672473
|
||||||
|
-O2
|
||||||
; lwIP 1.4 (Default)
|
; lwIP 1.4 (Default)
|
||||||
; -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
|
; -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
|
||||||
; lwIP 2 - Low Memory
|
; lwIP 2 - Low Memory
|
||||||
|
@ -89,6 +91,8 @@ build_flags = ${esp82xx_defaults.build_flags}
|
||||||
platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
|
platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
|
||||||
build_flags = ${esp82xx_defaults.build_flags}
|
build_flags = ${esp82xx_defaults.build_flags}
|
||||||
-Wl,-Teagle.flash.1m.ld
|
-Wl,-Teagle.flash.1m.ld
|
||||||
|
; Code optimization see https://github.com/esp8266/Arduino/issues/5790#issuecomment-475672473
|
||||||
|
-O2
|
||||||
; nonos-sdk 22x
|
; nonos-sdk 22x
|
||||||
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x
|
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x
|
||||||
; nonos-sdk-pre-v3
|
; nonos-sdk-pre-v3
|
||||||
|
@ -343,7 +347,7 @@ board = ${common.board}
|
||||||
board_build.flash_mode = ${common.board_build.flash_mode}
|
board_build.flash_mode = ${common.board_build.flash_mode}
|
||||||
board_build.f_cpu = ${common.board_build.f_cpu}
|
board_build.f_cpu = ${common.board_build.f_cpu}
|
||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags} -DMY_LANGUAGE=es-AR
|
build_flags = ${common.build_flags} -DMY_LANGUAGE=es-ES
|
||||||
monitor_speed = ${common.monitor_speed}
|
monitor_speed = ${common.monitor_speed}
|
||||||
upload_port = ${common.upload_port}
|
upload_port = ${common.upload_port}
|
||||||
upload_resetmethod = ${common.upload_resetmethod}
|
upload_resetmethod = ${common.upload_resetmethod}
|
||||||
|
|
|
@ -510,7 +510,7 @@ readfile:
|
||||||
uint8_t endBuf[boundary.length()];
|
uint8_t endBuf[boundary.length()];
|
||||||
client.readBytes(endBuf, boundary.length());
|
client.readBytes(endBuf, boundary.length());
|
||||||
|
|
||||||
if (strstr((const char*)endBuf, boundary.c_str()) != NULL){
|
if (strstr((const char*)endBuf, boundary.c_str()) != nullptr){
|
||||||
if(_currentHandler && _currentHandler->canUpload(_currentUri))
|
if(_currentHandler && _currentHandler->canUpload(_currentUri))
|
||||||
_currentHandler->upload(*this, _currentUri, *_currentUpload);
|
_currentHandler->upload(*this, _currentUri, *_currentUpload);
|
||||||
_currentUpload->totalSize += _currentUpload->currentSize;
|
_currentUpload->totalSize += _currentUpload->currentSize;
|
||||||
|
|
|
@ -1,4 +1,37 @@
|
||||||
/* 6.5.0.1 20190319
|
/* 6.5.0.7 20190410
|
||||||
|
* Add command LedMask to assign which relay has access to power LED (#5602, #5612)
|
||||||
|
*
|
||||||
|
* 6.5.0.6 20190409
|
||||||
|
* Add WebColor parameters to Settings making them persistent and remove the need for using a rule
|
||||||
|
* Add alternative IRSend command syntax IRSend raw,<freq>,<header mark>,<header space>,<bit mark>,<zero space>,<one space>,<bit stream> (#5610)
|
||||||
|
*
|
||||||
|
* 6.5.0.5 20190406
|
||||||
|
* Add compile time GUI hexadecimal only color options in my_user_config.h (#5586)
|
||||||
|
* Fix template activation and/or module selection regression from 6.5.0.4 (#5598)
|
||||||
|
* Add rule Http#Initialized
|
||||||
|
* Add command WebColor to change non-persistent GUI colors on the fly
|
||||||
|
Use a rule like:
|
||||||
|
rule3 on http#initialized do webcolor {"webcolor":["#eeeeee","#181818","#4f4f4f","#000000","#dddddd","#008000","#222222","#ff0000","#008000","#ffffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#ffffff","#999999"]} endon
|
||||||
|
or
|
||||||
|
rule3 on http#initialized do webcolor {"webcolor":["#eee","#181818","#4f4f4f","#000","#ddd","#009800","#222"]} endon
|
||||||
|
to make color changes persistent)
|
||||||
|
*
|
||||||
|
* 6.5.0.4 20190402
|
||||||
|
* Fix Configure Timer Web GUI (#5568)
|
||||||
|
* Add validation check when loading settings from flash
|
||||||
|
* Fixed Display Bug in KNX webmenu for Physical Address
|
||||||
|
*
|
||||||
|
* 6.5.0.3 20190328
|
||||||
|
* Add command Sensor20 1..255 to change Nova Fitness SDS01 working period in minutes (#5452)
|
||||||
|
* Change some defines to const
|
||||||
|
* Change IRsend and receive for 64-bit support (#5523)
|
||||||
|
* Change IRSend Panasonic protocol to 64-bit (#5523)
|
||||||
|
*
|
||||||
|
* 6.5.0.2 20190325
|
||||||
|
* Change UDP initial message handling from string to char using static memory and add debug info (#5505)
|
||||||
|
* Add optional support for Badger HR-E Water Meter (#5539)
|
||||||
|
*
|
||||||
|
* 6.5.0.1 20190319
|
||||||
* Change Web GUI sensor data collection
|
* Change Web GUI sensor data collection
|
||||||
*
|
*
|
||||||
* 6.5.0 20190319
|
* 6.5.0 20190319
|
||||||
|
@ -17,7 +50,7 @@
|
||||||
* Change image name BE_MINIMAL to FIRMWARE_MINIMAL and USE_xyz to FIRMWARE_xyz (#5106)
|
* Change image name BE_MINIMAL to FIRMWARE_MINIMAL and USE_xyz to FIRMWARE_xyz (#5106)
|
||||||
* Change GUI weblog from XML to plain text solving possible empty screens (#5154)
|
* Change GUI weblog from XML to plain text solving possible empty screens (#5154)
|
||||||
* Fix most compiler warnings
|
* Fix most compiler warnings
|
||||||
* Fix Display exception 28 when JSON value is NULL received
|
* Fix Display exception 28 when JSON value is nullptr received
|
||||||
* Fix epaper driver (#4785)
|
* Fix epaper driver (#4785)
|
||||||
* Fix HAss Sensor Discovery Software Watchdog restart (#4831, #4988)
|
* Fix HAss Sensor Discovery Software Watchdog restart (#4831, #4988)
|
||||||
* Fix allowable MAX_RULE_VARS to 16 (#4933)
|
* Fix allowable MAX_RULE_VARS to 16 (#4933)
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
#define D_JSON_FLASHCHIPID "FlashChipId"
|
#define D_JSON_FLASHCHIPID "FlashChipId"
|
||||||
#define D_JSON_FLASHMODE "FlashMode"
|
#define D_JSON_FLASHMODE "FlashMode"
|
||||||
#define D_JSON_FLASHSIZE "FlashSize"
|
#define D_JSON_FLASHSIZE "FlashSize"
|
||||||
|
#define D_JSON_FLOWRATE "FlowRate"
|
||||||
#define D_JSON_FREEMEMORY "Free"
|
#define D_JSON_FREEMEMORY "Free"
|
||||||
#define D_JSON_FREQUENCY "Frequency"
|
#define D_JSON_FREQUENCY "Frequency"
|
||||||
#define D_JSON_FROM "from"
|
#define D_JSON_FROM "from"
|
||||||
|
@ -143,6 +144,7 @@
|
||||||
#define D_JSON_TIME "Time"
|
#define D_JSON_TIME "Time"
|
||||||
#define D_JSON_TODAY "Today"
|
#define D_JSON_TODAY "Today"
|
||||||
#define D_JSON_TOTAL "Total"
|
#define D_JSON_TOTAL "Total"
|
||||||
|
#define D_JSON_TOTAL_USAGE "TotalUsage"
|
||||||
#define D_JSON_TOTAL_REACTIVE "TotalReactivePower"
|
#define D_JSON_TOTAL_REACTIVE "TotalReactivePower"
|
||||||
#define D_JSON_TOTAL_START_TIME "TotalStartTime"
|
#define D_JSON_TOTAL_START_TIME "TotalStartTime"
|
||||||
#define D_JSON_TVOC "TVOC"
|
#define D_JSON_TVOC "TVOC"
|
||||||
|
@ -264,6 +266,7 @@
|
||||||
#define D_CMND_ALTITUDE "Altitude"
|
#define D_CMND_ALTITUDE "Altitude"
|
||||||
#define D_CMND_LEDPOWER "LedPower"
|
#define D_CMND_LEDPOWER "LedPower"
|
||||||
#define D_CMND_LEDSTATE "LedState"
|
#define D_CMND_LEDSTATE "LedState"
|
||||||
|
#define D_CMND_LEDMASK "LedMask"
|
||||||
#define D_CMND_I2CSCAN "I2CScan"
|
#define D_CMND_I2CSCAN "I2CScan"
|
||||||
#define D_CMND_SERIALSEND "SerialSend"
|
#define D_CMND_SERIALSEND "SerialSend"
|
||||||
#define D_CMND_SERIALDELIMITER "SerialDelimiter"
|
#define D_CMND_SERIALDELIMITER "SerialDelimiter"
|
||||||
|
@ -309,6 +312,7 @@
|
||||||
#define D_CMND_WEBLOG "WebLog"
|
#define D_CMND_WEBLOG "WebLog"
|
||||||
#define D_CMND_WEBREFRESH "WebRefresh"
|
#define D_CMND_WEBREFRESH "WebRefresh"
|
||||||
#define D_CMND_WEBSEND "WebSend"
|
#define D_CMND_WEBSEND "WebSend"
|
||||||
|
#define D_CMND_WEBCOLOR "WebColor"
|
||||||
#define D_CMND_EMULATION "Emulation"
|
#define D_CMND_EMULATION "Emulation"
|
||||||
|
|
||||||
// Commands xdrv_03_energy.ino
|
// Commands xdrv_03_energy.ino
|
||||||
|
@ -495,7 +499,6 @@ const char S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE[] PROGMEM = "{\"%s\":\"%d (" D
|
||||||
const char S_JSON_COMMAND_NVALUE[] PROGMEM = "{\"%s\":%d}";
|
const char S_JSON_COMMAND_NVALUE[] PROGMEM = "{\"%s\":%d}";
|
||||||
const char S_JSON_COMMAND_LVALUE[] PROGMEM = "{\"%s\":%lu}";
|
const char S_JSON_COMMAND_LVALUE[] PROGMEM = "{\"%s\":%lu}";
|
||||||
const char S_JSON_COMMAND_SVALUE[] PROGMEM = "{\"%s\":\"%s\"}";
|
const char S_JSON_COMMAND_SVALUE[] PROGMEM = "{\"%s\":\"%s\"}";
|
||||||
const char S_JSON_COMMAND_HVALUE[] PROGMEM = "{\"%s\":\"#%X\"}";
|
|
||||||
const char S_JSON_COMMAND_ASTERIX[] PROGMEM = "{\"%s\":\"" D_ASTERIX "\"}";
|
const char S_JSON_COMMAND_ASTERIX[] PROGMEM = "{\"%s\":\"" D_ASTERIX "\"}";
|
||||||
const char S_JSON_COMMAND_XVALUE[] PROGMEM = "{\"%s\":%s}"; // %s must provide quotes on non-number
|
const char S_JSON_COMMAND_XVALUE[] PROGMEM = "{\"%s\":%s}"; // %s must provide quotes on non-number
|
||||||
|
|
||||||
|
@ -512,8 +515,10 @@ const char S_JSON_SENSOR_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_SENSOR
|
||||||
const char S_JSON_DRIVER_INDEX_NVALUE[] PROGMEM = "{\"" D_CMND_DRIVER "%d\":%d}";
|
const char S_JSON_DRIVER_INDEX_NVALUE[] PROGMEM = "{\"" D_CMND_DRIVER "%d\":%d}";
|
||||||
const char S_JSON_DRIVER_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_DRIVER "%d\":\"%s\"}";
|
const char S_JSON_DRIVER_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_DRIVER "%d\":\"%s\"}";
|
||||||
|
|
||||||
const char JSON_SNS_TEMP[] PROGMEM = "%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}";
|
const char JSON_SNS_TEMP[] PROGMEM = ",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}";
|
||||||
const char JSON_SNS_TEMPHUM[] PROGMEM = "%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s}";
|
const char JSON_SNS_TEMPHUM[] PROGMEM = ",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s}";
|
||||||
|
|
||||||
|
const char JSON_SNS_GNGPM[] PROGMEM = ",\"%s\":{\"" D_JSON_TOTAL_USAGE "\":%s,\"" D_JSON_FLOWRATE "\":%s}";
|
||||||
|
|
||||||
const char S_LOG_I2C_FOUND_AT[] PROGMEM = D_LOG_I2C "%s " D_FOUND_AT " 0x%x";
|
const char S_LOG_I2C_FOUND_AT[] PROGMEM = D_LOG_I2C "%s " D_FOUND_AT " 0x%x";
|
||||||
|
|
||||||
|
@ -567,14 +572,10 @@ const char HTTP_SNS_PRESSURE[] PROGMEM = "{s}%s " D_PRESSURE "{m}%s %s{e}";
|
||||||
const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "{s}%s " D_PRESSUREATSEALEVEL "{m}%s %s{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "{s}%s " D_PRESSUREATSEALEVEL "{m}%s %s{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
const char HTTP_SNS_ANALOG[] PROGMEM = "{s}%s " D_ANALOG_INPUT "%d{m}%d{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
const char HTTP_SNS_ANALOG[] PROGMEM = "{s}%s " D_ANALOG_INPUT "%d{m}%d{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
const char HTTP_SNS_ILLUMINANCE[] PROGMEM = "{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
const char HTTP_SNS_ILLUMINANCE[] PROGMEM = "{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
|
|
||||||
#if defined(USE_MHZ19) || defined(USE_SENSEAIR) || defined(USE_AZ7798) || defined(USE_SCD30)
|
|
||||||
const char HTTP_SNS_CO2[] PROGMEM = "{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
const char HTTP_SNS_CO2[] PROGMEM = "{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
#endif // USE_MHZ19
|
|
||||||
|
|
||||||
#if defined(USE_SCD30)
|
|
||||||
const char HTTP_SNS_CO2EAVG[] PROGMEM = "{s}%s " D_ECO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
const char HTTP_SNS_CO2EAVG[] PROGMEM = "{s}%s " D_ECO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
#endif // USE_SCD30
|
const char HTTP_SNS_GALLONS[] PROGMEM = "{s}%s " D_TOTAL_USAGE "{m}%s " D_UNIT_GALLONS " {e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
|
const char HTTP_SNS_GPM[] PROGMEM = "{s}%s " D_FLOW_RATE "{m}%s " D_UNIT_GALLONS_PER_MIN" {e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
|
|
||||||
const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
|
const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
|
||||||
const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION;
|
const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION;
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Помощен топик"
|
#define D_FALLBACK_TOPIC "Помощен топик"
|
||||||
#define D_FALSE "Невярно"
|
#define D_FALSE "Невярно"
|
||||||
#define D_FILE "Файл"
|
#define D_FILE "Файл"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Свободна памет"
|
#define D_FREE_MEMORY "Свободна памет"
|
||||||
#define D_FREQUENCY "Честота"
|
#define D_FREQUENCY "Честота"
|
||||||
#define D_GAS "Газ"
|
#define D_GAS "Газ"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "към"
|
#define D_TO "към"
|
||||||
#define D_TOGGLE "Превключване"
|
#define D_TOGGLE "Превключване"
|
||||||
#define D_TOPIC "Топик"
|
#define D_TOPIC "Топик"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Предаване"
|
#define D_TRANSMIT "Предаване"
|
||||||
#define D_TRUE "Вярно"
|
#define D_TRUE "Вярно"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Базиран на"
|
#define D_BASE_TYPE "Базиран на"
|
||||||
#define D_TEMPLATE_FLAGS "Флагове"
|
#define D_TEMPLATE_FLAGS "Флагове"
|
||||||
#define D_ALLOW_ADC0 "ADC0 вход"
|
#define D_ALLOW_ADC0 "ADC0 вход"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 температура"
|
||||||
#define D_ALLOW_PULLUP "Потребителски избор на pull-up"
|
#define D_ALLOW_PULLUP "Потребителски избор на pull-up"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Запазване на конфигурацията"
|
#define D_SAVE_CONFIGURATION "Запазване на конфигурацията"
|
||||||
|
@ -492,6 +495,10 @@
|
||||||
#define D_TX20_SOUTH "Ю"
|
#define D_TX20_SOUTH "Ю"
|
||||||
#define D_TX20_WEST "З"
|
#define D_TX20_WEST "З"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Няма"
|
#define D_SENSOR_NONE "Няма"
|
||||||
#define D_SENSOR_USER "Потребит."
|
#define D_SENSOR_USER "Потребит."
|
||||||
|
@ -576,12 +583,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "h"
|
#define D_UNIT_HOUR "h"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Záložní topic"
|
#define D_FALLBACK_TOPIC "Záložní topic"
|
||||||
#define D_FALSE "Nepravda"
|
#define D_FALSE "Nepravda"
|
||||||
#define D_FILE "Soubor"
|
#define D_FILE "Soubor"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Volná paměť"
|
#define D_FREE_MEMORY "Volná paměť"
|
||||||
#define D_FREQUENCY "Kmitočet"
|
#define D_FREQUENCY "Kmitočet"
|
||||||
#define D_GAS "Plyn"
|
#define D_GAS "Plyn"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "do"
|
#define D_TO "do"
|
||||||
#define D_TOGGLE "Přepni"
|
#define D_TOGGLE "Přepni"
|
||||||
#define D_TOPIC "Topic"
|
#define D_TOPIC "Topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Odešli"
|
#define D_TRANSMIT "Odešli"
|
||||||
#define D_TRUE "Pravda"
|
#define D_TRUE "Pravda"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Ulož nastavení"
|
#define D_SAVE_CONFIGURATION "Ulož nastavení"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "J"
|
#define D_TX20_SOUTH "J"
|
||||||
#define D_TX20_WEST "Z"
|
#define D_TX20_WEST "Z"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Není"
|
#define D_SENSOR_NONE "Není"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "hod"
|
#define D_UNIT_HOUR "hod"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Fallback-Topic"
|
#define D_FALLBACK_TOPIC "Fallback-Topic"
|
||||||
#define D_FALSE "falsch"
|
#define D_FALSE "falsch"
|
||||||
#define D_FILE "Datei"
|
#define D_FILE "Datei"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Freier Arbeitsspeicher"
|
#define D_FREE_MEMORY "Freier Arbeitsspeicher"
|
||||||
#define D_FREQUENCY "Frequenz"
|
#define D_FREQUENCY "Frequenz"
|
||||||
#define D_GAS "Gas"
|
#define D_GAS "Gas"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "zu"
|
#define D_TO "zu"
|
||||||
#define D_TOGGLE "An/Aus"
|
#define D_TOGGLE "An/Aus"
|
||||||
#define D_TOPIC "topic"
|
#define D_TOPIC "topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Übertragen"
|
#define D_TRANSMIT "Übertragen"
|
||||||
#define D_TRUE "wahr"
|
#define D_TRUE "wahr"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "basiert auf"
|
#define D_BASE_TYPE "basiert auf"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 Temperatur"
|
||||||
#define D_ALLOW_PULLUP "Nutzer pull-up Auswahl"
|
#define D_ALLOW_PULLUP "Nutzer pull-up Auswahl"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Konfiguration speichern"
|
#define D_SAVE_CONFIGURATION "Konfiguration speichern"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "h"
|
#define D_UNIT_HOUR "h"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Fallback Topic"
|
#define D_FALLBACK_TOPIC "Fallback Topic"
|
||||||
#define D_FALSE "Ψευδές"
|
#define D_FALSE "Ψευδές"
|
||||||
#define D_FILE "Αρχείο"
|
#define D_FILE "Αρχείο"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Ελεύθερη μνήμη"
|
#define D_FREE_MEMORY "Ελεύθερη μνήμη"
|
||||||
#define D_FREQUENCY "Συχνότητα"
|
#define D_FREQUENCY "Συχνότητα"
|
||||||
#define D_GAS "Αέριο"
|
#define D_GAS "Αέριο"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "έως"
|
#define D_TO "έως"
|
||||||
#define D_TOGGLE "Εναλλαγή"
|
#define D_TOGGLE "Εναλλαγή"
|
||||||
#define D_TOPIC "Topic"
|
#define D_TOPIC "Topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Μετάδοση"
|
#define D_TRANSMIT "Μετάδοση"
|
||||||
#define D_TRUE "Αληθές"
|
#define D_TRUE "Αληθές"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Αποθήκευση ρυθμίσεων"
|
#define D_SAVE_CONFIGURATION "Αποθήκευση ρυθμίσεων"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "Ν"
|
#define D_TX20_SOUTH "Ν"
|
||||||
#define D_TX20_WEST "Δ"
|
#define D_TX20_WEST "Δ"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Κανένα"
|
#define D_SENSOR_NONE "Κανένα"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Hr"
|
#define D_UNIT_HOUR "Hr"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Fallback Topic"
|
#define D_FALLBACK_TOPIC "Fallback Topic"
|
||||||
#define D_FALSE "False"
|
#define D_FALSE "False"
|
||||||
#define D_FILE "File"
|
#define D_FILE "File"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Free Memory"
|
#define D_FREE_MEMORY "Free Memory"
|
||||||
#define D_FREQUENCY "Frequency"
|
#define D_FREQUENCY "Frequency"
|
||||||
#define D_GAS "Gas"
|
#define D_GAS "Gas"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "to"
|
#define D_TO "to"
|
||||||
#define D_TOGGLE "Toggle"
|
#define D_TOGGLE "Toggle"
|
||||||
#define D_TOPIC "Topic"
|
#define D_TOPIC "Topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Transmit"
|
#define D_TRANSMIT "Transmit"
|
||||||
#define D_TRUE "True"
|
#define D_TRUE "True"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Save configuration"
|
#define D_SAVE_CONFIGURATION "Save configuration"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,15 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Hr"
|
#define D_UNIT_HOUR "Hr"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
es-AR.h - localization for Spanish - Argentina for Sonoff-Tasmota
|
es-ES.h - localization for Spanish - Spain for Sonoff-Tasmota
|
||||||
|
|
||||||
Copyright (C) 2019 Adrian Scillato
|
Copyright (C) 2019 Adrian Scillato
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LANGUAGE_ES_AR_H_
|
#ifndef _LANGUAGE_ES_ES_H_
|
||||||
#define _LANGUAGE_ES_AR_H_
|
#define _LANGUAGE_ES_ES_H_
|
||||||
|
|
||||||
/*************************** ATTENTION *******************************\
|
/*************************** ATTENTION *******************************\
|
||||||
*
|
*
|
||||||
|
@ -28,12 +28,12 @@
|
||||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||||
* Use online command Prefix to translate cmnd, stat and tele.
|
* Use online command Prefix to translate cmnd, stat and tele.
|
||||||
*
|
*
|
||||||
* Updated until v6.3.0.17
|
* Updated until v6.5.0.7
|
||||||
\*********************************************************************/
|
\*********************************************************************/
|
||||||
|
|
||||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||||
|
|
||||||
#define LANGUAGE_LCID 11274
|
#define LANGUAGE_LCID 1034
|
||||||
// HTML (ISO 639-1) Language Code
|
// HTML (ISO 639-1) Language Code
|
||||||
#define D_HTML_LANGUAGE "es"
|
#define D_HTML_LANGUAGE "es"
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "FallbackTopic"
|
#define D_FALLBACK_TOPIC "FallbackTopic"
|
||||||
#define D_FALSE "Falso"
|
#define D_FALSE "Falso"
|
||||||
#define D_FILE "Archivo"
|
#define D_FILE "Archivo"
|
||||||
|
#define D_FLOW_RATE "Caudal"
|
||||||
#define D_FREE_MEMORY "Memoria Libre"
|
#define D_FREE_MEMORY "Memoria Libre"
|
||||||
#define D_FREQUENCY "Frecuencia"
|
#define D_FREQUENCY "Frecuencia"
|
||||||
#define D_GAS "Gas"
|
#define D_GAS "Gas"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "a"
|
#define D_TO "a"
|
||||||
#define D_TOGGLE "Conmutar"
|
#define D_TOGGLE "Conmutar"
|
||||||
#define D_TOPIC "Topic"
|
#define D_TOPIC "Topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usado"
|
||||||
#define D_TRANSMIT "Transmitir"
|
#define D_TRANSMIT "Transmitir"
|
||||||
#define D_TRUE "Verdadero"
|
#define D_TRUE "Verdadero"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -289,8 +291,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Período de Telemetría"
|
#define D_TELEMETRY_PERIOD "Período de Telemetría"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Otros parámetros"
|
#define D_OTHER_PARAMETERS "Otros parámetros"
|
||||||
#define D_TEMPLATE "Template"
|
#define D_TEMPLATE "Plantilla"
|
||||||
#define D_ACTIVATE "Activate"
|
#define D_ACTIVATE "Activar"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Clave Administrador Web"
|
#define D_WEB_ADMIN_PASSWORD "Clave Administrador Web"
|
||||||
#define D_MQTT_ENABLE "Habilitar MQTT"
|
#define D_MQTT_ENABLE "Habilitar MQTT"
|
||||||
#define D_FRIENDLY_NAME "Nombre Amigable"
|
#define D_FRIENDLY_NAME "Nombre Amigable"
|
||||||
|
@ -299,13 +301,14 @@
|
||||||
#define D_SINGLE_DEVICE "dispositivo simple"
|
#define D_SINGLE_DEVICE "dispositivo simple"
|
||||||
#define D_MULTI_DEVICE "dispositivo múltiple"
|
#define D_MULTI_DEVICE "dispositivo múltiple"
|
||||||
|
|
||||||
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
#define D_CONFIGURE_TEMPLATE "Configurar Plantilla"
|
||||||
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
#define D_TEMPLATE_PARAMETERS "Parámetros de Plantilla"
|
||||||
#define D_TEMPLATE_NAME "Name"
|
#define D_TEMPLATE_NAME "Nombre"
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Basada en"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Opciones"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "Entrada ADC0"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_ADC0_TEMP "Temperatura por ADC0"
|
||||||
|
#define D_ALLOW_PULLUP "Habilitar pull-up"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Grabar configuración"
|
#define D_SAVE_CONFIGURATION "Grabar configuración"
|
||||||
#define D_CONFIGURATION_SAVED "Configuración grabada"
|
#define D_CONFIGURATION_SAVED "Configuración grabada"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "O"
|
#define D_TX20_WEST "O"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Ninguno"
|
#define D_SENSOR_NONE "Ninguno"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Hr"
|
#define D_UNIT_HOUR "Hr"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
@ -644,4 +654,4 @@
|
||||||
#define D_UNIT_KWARH "kVArH"
|
#define D_UNIT_KWARH "kVArH"
|
||||||
#define D_UNIT_ANGLE "Grados"
|
#define D_UNIT_ANGLE "Grados"
|
||||||
|
|
||||||
#endif // _LANGUAGE_ES_AR_H_
|
#endif // _LANGUAGE_ES_ES_H_
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Topic de secours"
|
#define D_FALLBACK_TOPIC "Topic de secours"
|
||||||
#define D_FALSE "Faux"
|
#define D_FALSE "Faux"
|
||||||
#define D_FILE "Fichier"
|
#define D_FILE "Fichier"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Mémoire libre"
|
#define D_FREE_MEMORY "Mémoire libre"
|
||||||
#define D_FREQUENCY "Fréquence"
|
#define D_FREQUENCY "Fréquence"
|
||||||
#define D_GAS "Gaz"
|
#define D_GAS "Gaz"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "à"
|
#define D_TO "à"
|
||||||
#define D_TOGGLE "Inverser"
|
#define D_TOGGLE "Inverser"
|
||||||
#define D_TOPIC "Topic" // Keep MQTT keyword
|
#define D_TOPIC "Topic" // Keep MQTT keyword
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Transmettre"
|
#define D_TRANSMIT "Transmettre"
|
||||||
#define D_TRUE "Vrai"
|
#define D_TRUE "Vrai"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Basé sur"
|
#define D_BASE_TYPE "Basé sur"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "Entrée ADC0"
|
#define D_ALLOW_ADC0 "Entrée ADC0"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "Pull-up utilisateur"
|
#define D_ALLOW_PULLUP "Pull-up utilisateur"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Enregistrer la configuration"
|
#define D_SAVE_CONFIGURATION "Enregistrer la configuration"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "O"
|
#define D_TX20_WEST "O"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Aucun"
|
#define D_SENSOR_NONE "Aucun"
|
||||||
#define D_SENSOR_USER "Utilisateur"
|
#define D_SENSOR_USER "Utilisateur"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "h"
|
#define D_UNIT_HOUR "h"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "נושא לחזרה"
|
#define D_FALLBACK_TOPIC "נושא לחזרה"
|
||||||
#define D_FALSE "שגוי"
|
#define D_FALSE "שגוי"
|
||||||
#define D_FILE "קובץ"
|
#define D_FILE "קובץ"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "זכרון פנוי"
|
#define D_FREE_MEMORY "זכרון פנוי"
|
||||||
#define D_FREQUENCY "תדר"
|
#define D_FREQUENCY "תדר"
|
||||||
#define D_GAS "גז"
|
#define D_GAS "גז"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "ל"
|
#define D_TO "ל"
|
||||||
#define D_TOGGLE "מתג"
|
#define D_TOGGLE "מתג"
|
||||||
#define D_TOPIC "נושא"
|
#define D_TOPIC "נושא"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "עבר"
|
#define D_TRANSMIT "עבר"
|
||||||
#define D_TRUE "נכון"
|
#define D_TRUE "נכון"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "מבוסס על"
|
#define D_BASE_TYPE "מבוסס על"
|
||||||
#define D_TEMPLATE_FLAGS "אפשריות"
|
#define D_TEMPLATE_FLAGS "אפשריות"
|
||||||
#define D_ALLOW_ADC0 "ADC0 כניסת"
|
#define D_ALLOW_ADC0 "ADC0 כניסת"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "pull-up בחירת משתמש עבור"
|
#define D_ALLOW_PULLUP "pull-up בחירת משתמש עבור"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "שמירת הגדרות"
|
#define D_SAVE_CONFIGURATION "שמירת הגדרות"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
#define D_SENSOR_USER "משתמש"
|
#define D_SENSOR_USER "משתמש"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Hr"
|
#define D_UNIT_HOUR "Hr"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "fallback topik"
|
#define D_FALLBACK_TOPIC "fallback topik"
|
||||||
#define D_FALSE "Hamis"
|
#define D_FALSE "Hamis"
|
||||||
#define D_FILE "Fájl"
|
#define D_FILE "Fájl"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Szabad memória"
|
#define D_FREE_MEMORY "Szabad memória"
|
||||||
#define D_FREQUENCY "Frekvencia"
|
#define D_FREQUENCY "Frekvencia"
|
||||||
#define D_GAS "Gáz"
|
#define D_GAS "Gáz"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "-nak"
|
#define D_TO "-nak"
|
||||||
#define D_TOGGLE "Megfordítás"
|
#define D_TOGGLE "Megfordítás"
|
||||||
#define D_TOPIC "Topic"
|
#define D_TOPIC "Topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Továbbít"
|
#define D_TRANSMIT "Továbbít"
|
||||||
#define D_TRUE "Igaz"
|
#define D_TRUE "Igaz"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Beállítások mentése"
|
#define D_SAVE_CONFIGURATION "Beállítások mentése"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "D"
|
#define D_TX20_SOUTH "D"
|
||||||
#define D_TX20_WEST "NY"
|
#define D_TX20_WEST "NY"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Nincs"
|
#define D_SENSOR_NONE "Nincs"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "h"
|
#define D_UNIT_HOUR "h"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Topic Riserva"
|
#define D_FALLBACK_TOPIC "Topic Riserva"
|
||||||
#define D_FALSE "Falso"
|
#define D_FALSE "Falso"
|
||||||
#define D_FILE "File"
|
#define D_FILE "File"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Memoria Libera"
|
#define D_FREE_MEMORY "Memoria Libera"
|
||||||
#define D_FREQUENCY "Frequenza"
|
#define D_FREQUENCY "Frequenza"
|
||||||
#define D_GAS "Gas"
|
#define D_GAS "Gas"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "a"
|
#define D_TO "a"
|
||||||
#define D_TOGGLE "Toggle"
|
#define D_TOGGLE "Toggle"
|
||||||
#define D_TOPIC "Topic"
|
#define D_TOPIC "Topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Trasmesso"
|
#define D_TRANSMIT "Trasmesso"
|
||||||
#define D_TRUE "Vero"
|
#define D_TRUE "Vero"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Salva configurazione"
|
#define D_SAVE_CONFIGURATION "Salva configurazione"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Nessuno"
|
#define D_SENSOR_NONE "Nessuno"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Hr"
|
#define D_UNIT_HOUR "Hr"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Fallback Topic"
|
#define D_FALLBACK_TOPIC "Fallback Topic"
|
||||||
#define D_FALSE "거짓"
|
#define D_FALSE "거짓"
|
||||||
#define D_FILE "파일"
|
#define D_FILE "파일"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "남은 메모리"
|
#define D_FREE_MEMORY "남은 메모리"
|
||||||
#define D_FREQUENCY "빈도"
|
#define D_FREQUENCY "빈도"
|
||||||
#define D_GAS "가스"
|
#define D_GAS "가스"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "to"
|
#define D_TO "to"
|
||||||
#define D_TOGGLE "전환"
|
#define D_TOGGLE "전환"
|
||||||
#define D_TOPIC "Topic"
|
#define D_TOPIC "Topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "전송"
|
#define D_TRANSMIT "전송"
|
||||||
#define D_TRUE "참"
|
#define D_TRUE "참"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "옵션"
|
#define D_TEMPLATE_FLAGS "옵션"
|
||||||
#define D_ALLOW_ADC0 "ADC0 입력"
|
#define D_ALLOW_ADC0 "ADC0 입력"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "설정 저장"
|
#define D_SAVE_CONFIGURATION "설정 저장"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "없음"
|
#define D_SENSOR_NONE "없음"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "시"
|
#define D_UNIT_HOUR "시"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Fallback Topic"
|
#define D_FALLBACK_TOPIC "Fallback Topic"
|
||||||
#define D_FALSE "Onwaar"
|
#define D_FALSE "Onwaar"
|
||||||
#define D_FILE "Bestand"
|
#define D_FILE "Bestand"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Vrij geheugen"
|
#define D_FREE_MEMORY "Vrij geheugen"
|
||||||
#define D_FREQUENCY "Frequentie"
|
#define D_FREQUENCY "Frequentie"
|
||||||
#define D_GAS "Gas"
|
#define D_GAS "Gas"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "naar"
|
#define D_TO "naar"
|
||||||
#define D_TOGGLE "Toggle" // Wissel, Tuimel
|
#define D_TOGGLE "Toggle" // Wissel, Tuimel
|
||||||
#define D_TOPIC "Topic" // Onderwerp
|
#define D_TOPIC "Topic" // Onderwerp
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Verzend"
|
#define D_TRANSMIT "Verzend"
|
||||||
#define D_TRUE "Waar"
|
#define D_TRUE "Waar"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -289,8 +291,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Telemetry periode"
|
#define D_TELEMETRY_PERIOD "Telemetry periode"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Overige parameters"
|
#define D_OTHER_PARAMETERS "Overige parameters"
|
||||||
#define D_TEMPLATE "Template"
|
#define D_TEMPLATE "Sjabloon"
|
||||||
#define D_ACTIVATE "Activate"
|
#define D_ACTIVATE "Activeer"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Web Admin Wachtwoord"
|
#define D_WEB_ADMIN_PASSWORD "Web Admin Wachtwoord"
|
||||||
#define D_MQTT_ENABLE "MQTT ingeschakeld"
|
#define D_MQTT_ENABLE "MQTT ingeschakeld"
|
||||||
#define D_FRIENDLY_NAME "Beschrijvende naam"
|
#define D_FRIENDLY_NAME "Beschrijvende naam"
|
||||||
|
@ -299,12 +301,13 @@
|
||||||
#define D_SINGLE_DEVICE "een apparaat"
|
#define D_SINGLE_DEVICE "een apparaat"
|
||||||
#define D_MULTI_DEVICE "meer apparaten"
|
#define D_MULTI_DEVICE "meer apparaten"
|
||||||
|
|
||||||
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
#define D_CONFIGURE_TEMPLATE "Configureer Sjabloon"
|
||||||
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
#define D_TEMPLATE_PARAMETERS "Sjabloon parameters"
|
||||||
#define D_TEMPLATE_NAME "Name"
|
#define D_TEMPLATE_NAME "Naam"
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Op basis van"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Opties"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 ingang"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperatuur"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Bewaar configuratie"
|
#define D_SAVE_CONFIGURATION "Bewaar configuratie"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Geen"
|
#define D_SENSOR_NONE "Geen"
|
||||||
#define D_SENSOR_USER "Gebruiker"
|
#define D_SENSOR_USER "Gebruiker"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "h"
|
#define D_UNIT_HOUR "h"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Zastępczy temat"
|
#define D_FALLBACK_TOPIC "Zastępczy temat"
|
||||||
#define D_FALSE "Fałsz"
|
#define D_FALSE "Fałsz"
|
||||||
#define D_FILE "Plik"
|
#define D_FILE "Plik"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Wolna pamięć"
|
#define D_FREE_MEMORY "Wolna pamięć"
|
||||||
#define D_FREQUENCY "Frequency"
|
#define D_FREQUENCY "Frequency"
|
||||||
#define D_GAS "Gas"
|
#define D_GAS "Gas"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "do"
|
#define D_TO "do"
|
||||||
#define D_TOGGLE "Przełącz"
|
#define D_TOGGLE "Przełącz"
|
||||||
#define D_TOPIC "Temat"
|
#define D_TOPIC "Temat"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Wyślij"
|
#define D_TRANSMIT "Wyślij"
|
||||||
#define D_TRUE "Prawda"
|
#define D_TRUE "Prawda"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Zapisz ustawienia"
|
#define D_SAVE_CONFIGURATION "Zapisz ustawienia"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Brak"
|
#define D_SENSOR_NONE "Brak"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Godz"
|
#define D_UNIT_HOUR "Godz"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Tópico para retornar"
|
#define D_FALLBACK_TOPIC "Tópico para retornar"
|
||||||
#define D_FALSE "Falso"
|
#define D_FALSE "Falso"
|
||||||
#define D_FILE "Arquivo"
|
#define D_FILE "Arquivo"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Memória livre"
|
#define D_FREE_MEMORY "Memória livre"
|
||||||
#define D_FREQUENCY "Frequência"
|
#define D_FREQUENCY "Frequência"
|
||||||
#define D_GAS "Gás"
|
#define D_GAS "Gás"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "Para"
|
#define D_TO "Para"
|
||||||
#define D_TOGGLE "Inverter"
|
#define D_TOGGLE "Inverter"
|
||||||
#define D_TOPIC "Tópico"
|
#define D_TOPIC "Tópico"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Transmitir"
|
#define D_TRANSMIT "Transmitir"
|
||||||
#define D_TRUE "Verdadeiro"
|
#define D_TRUE "Verdadeiro"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Gravar configuração"
|
#define D_SAVE_CONFIGURATION "Gravar configuração"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Nenhum"
|
#define D_SENSOR_NONE "Nenhum"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "H"
|
#define D_UNIT_HOUR "H"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Tópico para retornar"
|
#define D_FALLBACK_TOPIC "Tópico para retornar"
|
||||||
#define D_FALSE "Falso"
|
#define D_FALSE "Falso"
|
||||||
#define D_FILE "Ficheiro"
|
#define D_FILE "Ficheiro"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Memoria Livre"
|
#define D_FREE_MEMORY "Memoria Livre"
|
||||||
#define D_FREQUENCY "Frequency"
|
#define D_FREQUENCY "Frequency"
|
||||||
#define D_GAS "Gás"
|
#define D_GAS "Gás"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "para"
|
#define D_TO "para"
|
||||||
#define D_TOGGLE "Pressionar"
|
#define D_TOGGLE "Pressionar"
|
||||||
#define D_TOPIC "Tópico"
|
#define D_TOPIC "Tópico"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Transmitir"
|
#define D_TRANSMIT "Transmitir"
|
||||||
#define D_TRUE "Verdadeiro"
|
#define D_TRUE "Verdadeiro"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Salvar configuração"
|
#define D_SAVE_CONFIGURATION "Salvar configuração"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Nenhum"
|
#define D_SENSOR_NONE "Nenhum"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Hr"
|
#define D_UNIT_HOUR "Hr"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Топик обратной связи"
|
#define D_FALLBACK_TOPIC "Топик обратной связи"
|
||||||
#define D_FALSE "Ложно"
|
#define D_FALSE "Ложно"
|
||||||
#define D_FILE "Файл"
|
#define D_FILE "Файл"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Свободная память"
|
#define D_FREE_MEMORY "Свободная память"
|
||||||
#define D_FREQUENCY "Frequency"
|
#define D_FREQUENCY "Frequency"
|
||||||
#define D_GAS "Газ"
|
#define D_GAS "Газ"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "до"
|
#define D_TO "до"
|
||||||
#define D_TOGGLE "Переключить"
|
#define D_TOGGLE "Переключить"
|
||||||
#define D_TOPIC "Топик"
|
#define D_TOPIC "Топик"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Передать"
|
#define D_TRANSMIT "Передать"
|
||||||
#define D_TRUE "Истина"
|
#define D_TRUE "Истина"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Сохранить конфигурацию"
|
#define D_SAVE_CONFIGURATION "Сохранить конфигурацию"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "-нет-"
|
#define D_SENSOR_NONE "-нет-"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "А"
|
#define D_UNIT_AMPERE "А"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Ч"
|
#define D_UNIT_HOUR "Ч"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
#define D_COUNTER "Počítadlo"
|
#define D_COUNTER "Počítadlo"
|
||||||
#define D_CURRENT "Prúd" // As in Voltage and Current
|
#define D_CURRENT "Prúd" // As in Voltage and Current
|
||||||
#define D_DATA "Dáta"
|
#define D_DATA "Dáta"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_DARKLIGHT "Tmavý"
|
#define D_DARKLIGHT "Tmavý"
|
||||||
#define D_DEBUG "Debug"
|
#define D_DEBUG "Debug"
|
||||||
#define D_DISABLED "Zablokované"
|
#define D_DISABLED "Zablokované"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "do"
|
#define D_TO "do"
|
||||||
#define D_TOGGLE "Prepni"
|
#define D_TOGGLE "Prepni"
|
||||||
#define D_TOPIC "Topic"
|
#define D_TOPIC "Topic"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Odošli"
|
#define D_TRANSMIT "Odošli"
|
||||||
#define D_TRUE "Pravda"
|
#define D_TRUE "Pravda"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Ulož nastavenia"
|
#define D_SAVE_CONFIGURATION "Ulož nastavenia"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "J"
|
#define D_TX20_SOUTH "J"
|
||||||
#define D_TX20_WEST "Z"
|
#define D_TX20_WEST "Z"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Žiaden"
|
#define D_SENSOR_NONE "Žiaden"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "hod"
|
#define D_UNIT_HOUR "hod"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Reservämne"
|
#define D_FALLBACK_TOPIC "Reservämne"
|
||||||
#define D_FALSE "Falskt"
|
#define D_FALSE "Falskt"
|
||||||
#define D_FILE "Fil"
|
#define D_FILE "Fil"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Ledigt minne"
|
#define D_FREE_MEMORY "Ledigt minne"
|
||||||
#define D_FREQUENCY "Frekvens"
|
#define D_FREQUENCY "Frekvens"
|
||||||
#define D_GAS "Gas"
|
#define D_GAS "Gas"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "till"
|
#define D_TO "till"
|
||||||
#define D_TOGGLE "Växla"
|
#define D_TOGGLE "Växla"
|
||||||
#define D_TOPIC "Ämne"
|
#define D_TOPIC "Ämne"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Sänd"
|
#define D_TRANSMIT "Sänd"
|
||||||
#define D_TRUE "Sant"
|
#define D_TRUE "Sant"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Spara konfiguration"
|
#define D_SAVE_CONFIGURATION "Spara konfiguration"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "V"
|
#define D_TX20_WEST "V"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Ingen"
|
#define D_SENSOR_NONE "Ingen"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "Tim"
|
#define D_UNIT_HOUR "Tim"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "ink"
|
#define D_UNIT_INCREMENTS "ink"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Geri İletim Topiği"
|
#define D_FALLBACK_TOPIC "Geri İletim Topiği"
|
||||||
#define D_FALSE "False"
|
#define D_FALSE "False"
|
||||||
#define D_FILE "Dosya"
|
#define D_FILE "Dosya"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Boş Hafıza"
|
#define D_FREE_MEMORY "Boş Hafıza"
|
||||||
#define D_FREQUENCY "Frekans"
|
#define D_FREQUENCY "Frekans"
|
||||||
#define D_GAS "Gas"
|
#define D_GAS "Gas"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "den"
|
#define D_TO "den"
|
||||||
#define D_TOGGLE "Geçiş Tuşu"
|
#define D_TOGGLE "Geçiş Tuşu"
|
||||||
#define D_TOPIC "Başlık"
|
#define D_TOPIC "Başlık"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "İletim"
|
#define D_TRANSMIT "İletim"
|
||||||
#define D_TRUE "True"
|
#define D_TRUE "True"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Ayarları Kaydet"
|
#define D_SAVE_CONFIGURATION "Ayarları Kaydet"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,11 +582,15 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HOUR "Hr"
|
#define D_UNIT_HOUR "Hr"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Топік зворотнього зв'язку"
|
#define D_FALLBACK_TOPIC "Топік зворотнього зв'язку"
|
||||||
#define D_FALSE "Помилково"
|
#define D_FALSE "Помилково"
|
||||||
#define D_FILE "Файл"
|
#define D_FILE "Файл"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "Вільна память"
|
#define D_FREE_MEMORY "Вільна память"
|
||||||
#define D_FREQUENCY "Частота"
|
#define D_FREQUENCY "Частота"
|
||||||
#define D_GAS "Газ"
|
#define D_GAS "Газ"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "до"
|
#define D_TO "до"
|
||||||
#define D_TOGGLE "Перекл."
|
#define D_TOGGLE "Перекл."
|
||||||
#define D_TOPIC "Топік"
|
#define D_TOPIC "Топік"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "Передати"
|
#define D_TRANSMIT "Передати"
|
||||||
#define D_TRUE "Істина"
|
#define D_TRUE "Істина"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Зберегти конфігурацію"
|
#define D_SAVE_CONFIGURATION "Зберегти конфігурацію"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "-відсутньо-"
|
#define D_SENSOR_NONE "-відсутньо-"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "А"
|
#define D_UNIT_AMPERE "А"
|
||||||
#define D_UNIT_CENTIMETER "cм"
|
#define D_UNIT_CENTIMETER "cм"
|
||||||
#define D_UNIT_HERTZ "Гц"
|
#define D_UNIT_HERTZ "Гц"
|
||||||
#define D_UNIT_HOUR "Г"
|
#define D_UNIT_HOUR "Г"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "回退主题"
|
#define D_FALLBACK_TOPIC "回退主题"
|
||||||
#define D_FALSE "False"
|
#define D_FALSE "False"
|
||||||
#define D_FILE "文件:"
|
#define D_FILE "文件:"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "空闲内存"
|
#define D_FREE_MEMORY "空闲内存"
|
||||||
#define D_FREQUENCY "频率"
|
#define D_FREQUENCY "频率"
|
||||||
#define D_GAS "气体"
|
#define D_GAS "气体"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "to"
|
#define D_TO "to"
|
||||||
#define D_TOGGLE "切换"
|
#define D_TOGGLE "切换"
|
||||||
#define D_TOPIC "主题"
|
#define D_TOPIC "主题"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "发送"
|
#define D_TRANSMIT "发送"
|
||||||
#define D_TRUE "True"
|
#define D_TRUE "True"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "基于"
|
#define D_BASE_TYPE "基于"
|
||||||
#define D_TEMPLATE_FLAGS "选项"
|
#define D_TEMPLATE_FLAGS "选项"
|
||||||
#define D_ALLOW_ADC0 "ADC0 输入"
|
#define D_ALLOW_ADC0 "ADC0 输入"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "用户上拉选择"
|
#define D_ALLOW_PULLUP "用户上拉选择"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "保存设置"
|
#define D_SAVE_CONFIGURATION "保存设置"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "南"
|
#define D_TX20_SOUTH "南"
|
||||||
#define D_TX20_WEST "西"
|
#define D_TX20_WEST "西"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "无"
|
#define D_SENSOR_NONE "无"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,11 +582,15 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "安"
|
#define D_UNIT_AMPERE "安"
|
||||||
#define D_UNIT_CENTIMETER "厘米"
|
#define D_UNIT_CENTIMETER "厘米"
|
||||||
#define D_UNIT_HOUR "时"
|
#define D_UNIT_HOUR "时"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "千克"
|
#define D_UNIT_KILOGRAM "千克"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "公里/时" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "公里/时" // or "km/h"
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define D_FALLBACK_TOPIC "Fallback Topic"
|
#define D_FALLBACK_TOPIC "Fallback Topic"
|
||||||
#define D_FALSE "False"
|
#define D_FALSE "False"
|
||||||
#define D_FILE "文件:"
|
#define D_FILE "文件:"
|
||||||
|
#define D_FLOW_RATE "Flow rate"
|
||||||
#define D_FREE_MEMORY "可用記憶體"
|
#define D_FREE_MEMORY "可用記憶體"
|
||||||
#define D_FREQUENCY "Frequency"
|
#define D_FREQUENCY "Frequency"
|
||||||
#define D_GAS "氣體"
|
#define D_GAS "氣體"
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
#define D_TO "to"
|
#define D_TO "to"
|
||||||
#define D_TOGGLE "切換"
|
#define D_TOGGLE "切換"
|
||||||
#define D_TOPIC "主題"
|
#define D_TOPIC "主題"
|
||||||
|
#define D_TOTAL_USAGE "Total Usage"
|
||||||
#define D_TRANSMIT "發送"
|
#define D_TRANSMIT "發送"
|
||||||
#define D_TRUE "True"
|
#define D_TRUE "True"
|
||||||
#define D_TVOC "TVOC"
|
#define D_TVOC "TVOC"
|
||||||
|
@ -305,6 +307,7 @@
|
||||||
#define D_BASE_TYPE "Based on"
|
#define D_BASE_TYPE "Based on"
|
||||||
#define D_TEMPLATE_FLAGS "Options"
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
#define D_ALLOW_ADC0 "ADC0 input"
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_ADC0_TEMP "ADC0 temperature"
|
||||||
#define D_ALLOW_PULLUP "User pull-up selection"
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "保存設置"
|
#define D_SAVE_CONFIGURATION "保存設置"
|
||||||
|
@ -492,6 +495,9 @@
|
||||||
#define D_TX20_SOUTH "S"
|
#define D_TX20_SOUTH "S"
|
||||||
#define D_TX20_WEST "W"
|
#define D_TX20_WEST "W"
|
||||||
|
|
||||||
|
//xsns_43_hre.ino
|
||||||
|
#define D_LOG_HRE "HRE: "
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
#define D_SENSOR_USER "User"
|
#define D_SENSOR_USER "User"
|
||||||
|
@ -576,12 +582,16 @@
|
||||||
#define D_SENSOR_TXD "Serial Tx"
|
#define D_SENSOR_TXD "Serial Tx"
|
||||||
#define D_SENSOR_RXD "Serial Rx"
|
#define D_SENSOR_RXD "Serial Rx"
|
||||||
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
#define D_SENSOR_ROTARY "Rotary" // Suffix "1A"
|
||||||
|
#define D_SENSOR_HRE_CLOCK "HRE Clock"
|
||||||
|
#define D_SENSOR_HRE_DATA "HRE Data"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "安"
|
#define D_UNIT_AMPERE "安"
|
||||||
#define D_UNIT_CENTIMETER "cm"
|
#define D_UNIT_CENTIMETER "cm"
|
||||||
#define D_UNIT_HERTZ "Hz"
|
#define D_UNIT_HERTZ "Hz"
|
||||||
#define D_UNIT_HOUR "時"
|
#define D_UNIT_HOUR "時"
|
||||||
|
#define D_UNIT_GALLONS "gal"
|
||||||
|
#define D_UNIT_GALLONS_PER_MIN "g/m"
|
||||||
#define D_UNIT_INCREMENTS "inc"
|
#define D_UNIT_INCREMENTS "inc"
|
||||||
#define D_UNIT_KILOGRAM "kg"
|
#define D_UNIT_KILOGRAM "kg"
|
||||||
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
|
||||||
|
|
|
@ -135,6 +135,25 @@
|
||||||
#define WEB_PASSWORD "" // [WebPassword] Web server Admin mode Password for WEB_USERNAME (empty string = Disable)
|
#define WEB_PASSWORD "" // [WebPassword] Web server Admin mode Password for WEB_USERNAME (empty string = Disable)
|
||||||
#define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa
|
#define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa
|
||||||
#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo (single relay/light) or Hue Bridge emulation (multi relay/light) (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
|
#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo (single relay/light) or Hue Bridge emulation (multi relay/light) (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
|
||||||
|
// HTML hex color codes. Only 3 and 6 digit hex string values are supported!! See https://www.w3schools.com/colors/colors_hex.asp
|
||||||
|
#define COLOR_TEXT "#000" // [WebColor1] Global text color - Black
|
||||||
|
#define COLOR_BACKGROUND "#fff" // [WebColor2] Global background color - White
|
||||||
|
#define COLOR_FORM "#f2f2f2" // [WebColor3] Form background color - Greyish
|
||||||
|
#define COLOR_INPUT_TEXT "#000" // [WebColor4] Input text color - Black
|
||||||
|
#define COLOR_INPUT "#fff" // [WebColor5] Input background color - White
|
||||||
|
#define COLOR_CONSOLE_TEXT "#000" // [WebColor6] Console text color - Black
|
||||||
|
#define COLOR_CONSOLE "#fff" // [WebColor7] Console background color - White
|
||||||
|
#define COLOR_TEXT_WARNING "#f00" // [WebColor8] Warning text color - Red
|
||||||
|
#define COLOR_TEXT_SUCCESS "#008000" // [WebColor9] Success text color - Green
|
||||||
|
#define COLOR_BUTTON_TEXT "#fff" // [WebColor10] Button text color - White
|
||||||
|
#define COLOR_BUTTON "#1fa3ec" // [WebColor11] Button color - Blueish
|
||||||
|
#define COLOR_BUTTON_HOVER "#0e70a4" // [WebColor12] Button color when hovered over - Darker blueish
|
||||||
|
#define COLOR_BUTTON_RESET "#d43535" // [WebColor13] Restart/Reset/Delete button color - Redish
|
||||||
|
#define COLOR_BUTTON_RESET_HOVER "#931f1f" // [WebColor14] Restart/Reset/Delete button color when hovered over - Darker redish
|
||||||
|
#define COLOR_BUTTON_SAVE "#47c266" // [WebColor15] Save button color - Greenish
|
||||||
|
#define COLOR_BUTTON_SAVE_HOVER "#5aaf6f" // [WebColor16] Save button color when hovered over - Darker greenish
|
||||||
|
#define COLOR_TIMER_TAB_TEXT "#fff" // [WebColor17] Config timer tab text color - White
|
||||||
|
#define COLOR_TIMER_TAB_BACKGROUND "#999" // [WebColor18] Config timer tab background color - Light grey
|
||||||
|
|
||||||
// -- mDNS ----------------------------------------
|
// -- mDNS ----------------------------------------
|
||||||
#define MDNS_ENABLED 0 // [SetOption55] Use mDNS (0 = Disable, 1 = Enable)
|
#define MDNS_ENABLED 0 // [SetOption55] Use mDNS (0 = Disable, 1 = Enable)
|
||||||
|
@ -168,6 +187,7 @@
|
||||||
#define APP_TIMEZONE 1 // [Timezone] +1 hour (Amsterdam) (-13 .. 14 = hours from UTC, 99 = use TIME_DST/TIME_STD)
|
#define APP_TIMEZONE 1 // [Timezone] +1 hour (Amsterdam) (-13 .. 14 = hours from UTC, 99 = use TIME_DST/TIME_STD)
|
||||||
#define APP_LEDSTATE LED_POWER // [LedState] Function of led
|
#define APP_LEDSTATE LED_POWER // [LedState] Function of led
|
||||||
// (LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT)
|
// (LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT)
|
||||||
|
#define APP_LEDMASK 0xFFFF // [LedMask] Assign Relay to Power led (0xFFFF is default)
|
||||||
#define APP_PULSETIME 0 // [PulseTime] Time in 0.1 Sec to turn off power for relay 1 (0 = disabled)
|
#define APP_PULSETIME 0 // [PulseTime] Time in 0.1 Sec to turn off power for relay 1 (0 = disabled)
|
||||||
#define APP_POWERON_STATE POWER_ALL_SAVED // [PowerOnState] Power On Relay state
|
#define APP_POWERON_STATE POWER_ALL_SAVED // [PowerOnState] Power On Relay state
|
||||||
// (POWER_ALL_OFF, POWER_ALL_ON, POWER_ALL_SAVED_TOGGLE, POWER_ALL_SAVED, POWER_ALL_ALWAYS_ON, POWER_ALL_OFF_PULSETIME_ON)
|
// (POWER_ALL_OFF, POWER_ALL_ON, POWER_ALL_SAVED_TOGGLE, POWER_ALL_SAVED, POWER_ALL_ALWAYS_ON, POWER_ALL_OFF_PULSETIME_ON)
|
||||||
|
@ -204,7 +224,7 @@
|
||||||
//#define MY_LANGUAGE de-DE // German in Germany
|
//#define MY_LANGUAGE de-DE // German in Germany
|
||||||
//#define MY_LANGUAGE el-GR // Greek in Greece
|
//#define MY_LANGUAGE el-GR // Greek in Greece
|
||||||
//#define MY_LANGUAGE en-GB // English in Great Britain. Enabled by Default
|
//#define MY_LANGUAGE en-GB // English in Great Britain. Enabled by Default
|
||||||
//#define MY_LANGUAGE es-AR // Spanish in Argentina
|
//#define MY_LANGUAGE es-ES // Spanish in Spain
|
||||||
//#define MY_LANGUAGE fr-FR // French in France
|
//#define MY_LANGUAGE fr-FR // French in France
|
||||||
//#define MY_LANGUAGE he-HE // Hebrew in Israel
|
//#define MY_LANGUAGE he-HE // Hebrew in Israel
|
||||||
//#define MY_LANGUAGE hu-HU // Hungarian in Hungary
|
//#define MY_LANGUAGE hu-HU // Hungarian in Hungary
|
||||||
|
@ -369,6 +389,7 @@
|
||||||
#define TUYA_DIMMER_ID 0 // Default dimmer Id
|
#define TUYA_DIMMER_ID 0 // Default dimmer Id
|
||||||
#define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code)
|
#define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code)
|
||||||
#define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer
|
#define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer
|
||||||
|
//#define ROTARY_V1 // Add support for MI Desk Lamp
|
||||||
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
|
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
|
||||||
//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
|
//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
|
||||||
// #define USE_PN532_CAUSE_EVENTS // Cause event execution for PN532_UID= and PN532_DATA=[if defined] (+ 30 bytes code)
|
// #define USE_PN532_CAUSE_EVENTS // Cause event execution for PN532_UID= and PN532_DATA=[if defined] (+ 30 bytes code)
|
||||||
|
@ -415,6 +436,8 @@
|
||||||
|
|
||||||
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
|
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
|
||||||
|
|
||||||
|
//#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code)
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Debug features are only supported in development branch
|
* Debug features are only supported in development branch
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef _SETTINGS_H_
|
#ifndef _SETTINGS_H_
|
||||||
#define _SETTINGS_H_
|
#define _SETTINGS_H_
|
||||||
|
|
||||||
#define PARAM8_SIZE 18 // Number of param bytes (SetOption)
|
const uint8_t PARAM8_SIZE = 18; // Number of param bytes (SetOption)
|
||||||
|
|
||||||
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
|
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
|
||||||
uint32_t data; // Allow bit manipulation using SetOption
|
uint32_t data; // Allow bit manipulation using SetOption
|
||||||
|
@ -330,8 +330,10 @@ struct SYSCFG {
|
||||||
uint8_t rgbwwTable[5]; // 71A
|
uint8_t rgbwwTable[5]; // 71A
|
||||||
uint8_t user_template_base; // 71F
|
uint8_t user_template_base; // 71F
|
||||||
mytmplt user_template; // 720 29 bytes
|
mytmplt user_template; // 720 29 bytes
|
||||||
|
uint8_t novasds_period; // 73D
|
||||||
|
uint8_t web_color[18][3]; // 73E
|
||||||
|
|
||||||
uint8_t free_73D[87]; // 73D
|
uint8_t free_774[32]; // 774
|
||||||
|
|
||||||
uint32_t drivers[3]; // 794
|
uint32_t drivers[3]; // 794
|
||||||
uint32_t monitors; // 7A0
|
uint32_t monitors; // 7A0
|
||||||
|
@ -339,9 +341,7 @@ struct SYSCFG {
|
||||||
uint32_t displays; // 7B0
|
uint32_t displays; // 7B0
|
||||||
uint32_t energy_kWhtotal_time; // 7B4
|
uint32_t energy_kWhtotal_time; // 7B4
|
||||||
unsigned long weight_item; // 7B8 Weight of one item in gram * 10
|
unsigned long weight_item; // 7B8 Weight of one item in gram * 10
|
||||||
|
uint16_t ledmask; // 7BC
|
||||||
uint8_t free_7BC[2]; // 7BC
|
|
||||||
|
|
||||||
uint16_t weight_max; // 7BE Total max weight in kilogram
|
uint16_t weight_max; // 7BE Total max weight in kilogram
|
||||||
unsigned long weight_reference; // 7C0 Reference weight in gram
|
unsigned long weight_reference; // 7C0 Reference weight in gram
|
||||||
unsigned long weight_calibration; // 7C4
|
unsigned long weight_calibration; // 7C4
|
||||||
|
@ -396,7 +396,7 @@ struct XDRVMAILBOX {
|
||||||
char *data;
|
char *data;
|
||||||
} XdrvMailbox;
|
} XdrvMailbox;
|
||||||
|
|
||||||
#define MAX_RULES_FLAG 7 // Number of bits used in RulesBitfield (tricky I know...)
|
const uint8_t MAX_RULES_FLAG = 8; // Number of bits used in RulesBitfield (tricky I know...)
|
||||||
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
|
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
|
||||||
uint16_t data; // Allow bit manipulation
|
uint16_t data; // Allow bit manipulation
|
||||||
struct {
|
struct {
|
||||||
|
@ -407,7 +407,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||||
uint16_t mqtt_disconnected : 1;
|
uint16_t mqtt_disconnected : 1;
|
||||||
uint16_t wifi_connected : 1;
|
uint16_t wifi_connected : 1;
|
||||||
uint16_t wifi_disconnected : 1;
|
uint16_t wifi_disconnected : 1;
|
||||||
uint16_t spare07 : 1;
|
uint16_t http_init : 1;
|
||||||
uint16_t spare08 : 1;
|
uint16_t spare08 : 1;
|
||||||
uint16_t spare09 : 1;
|
uint16_t spare09 : 1;
|
||||||
uint16_t spare10 : 1;
|
uint16_t spare10 : 1;
|
||||||
|
|
|
@ -61,11 +61,85 @@
|
||||||
#define LONGITUDE 2.294442 // [Longitude] Your location to be used with sunrise and sunset
|
#define LONGITUDE 2.294442 // [Longitude] Your location to be used with sunrise and sunset
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef WORKING_PERIOD
|
||||||
|
#define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef COLOR_TEXT
|
||||||
|
#define COLOR_TEXT "#000" // Global text color - Black
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_BACKGROUND
|
||||||
|
#define COLOR_BACKGROUND "#fff" // Global background color - White
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_FORM
|
||||||
|
#define COLOR_FORM "#f2f2f2" // Form background color - Greyish
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_INPUT_TEXT
|
||||||
|
#define COLOR_INPUT_TEXT "#000" // Input text color - Black
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_INPUT
|
||||||
|
#define COLOR_INPUT "#fff" // Input background color - White
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_CONSOLE_TEXT
|
||||||
|
#define COLOR_CONSOLE_TEXT "#000" // Console text color - Black
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_CONSOLE
|
||||||
|
#define COLOR_CONSOLE "#fff" // Console background color - White
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_TEXT_WARNING
|
||||||
|
#define COLOR_TEXT_WARNING "#f00" // Warning text color - Red
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_TEXT_SUCCESS
|
||||||
|
#define COLOR_TEXT_SUCCESS "#008000" // Success text color - Green
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_BUTTON_TEXT
|
||||||
|
#define COLOR_BUTTON_TEXT "#fff" // Button text color - White
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_BUTTON
|
||||||
|
#define COLOR_BUTTON "#1fa3ec" // Button color - Blueish
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_BUTTON_HOVER
|
||||||
|
#define COLOR_BUTTON_HOVER "#0e70a4" // Button color when hovered over - Darker blueish
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_BUTTON_RESET
|
||||||
|
#define COLOR_BUTTON_RESET "#d43535" // Restart/Reset/Delete button color - Redish
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_BUTTON_RESET_HOVER
|
||||||
|
#define COLOR_BUTTON_RESET_HOVER "#931f1f" // Restart/Reset/Delete button color when hovered over - Darker redish
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_BUTTON_SAVE
|
||||||
|
#define COLOR_BUTTON_SAVE "#47c266" // Save button color - Greenish
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_BUTTON_SAVE_HOVER
|
||||||
|
#define COLOR_BUTTON_SAVE_HOVER "#5aaf6f" // Save button color when hovered over - Darker greenish
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_TIMER_TAB_TEXT
|
||||||
|
#define COLOR_TIMER_TAB_TEXT "#fff" // Config timer tab text color - White
|
||||||
|
#endif
|
||||||
|
#ifndef COLOR_TIMER_TAB_BACKGROUND
|
||||||
|
#define COLOR_TIMER_TAB_BACKGROUND "#999" // Config timer tab background color - Light grey
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum WebColors {
|
||||||
|
COL_TEXT, COL_BACKGROUND, COL_FORM,
|
||||||
|
COL_INPUT_TEXT, COL_INPUT, COL_CONSOLE_TEXT, COL_CONSOLE,
|
||||||
|
COL_TEXT_WARNING, COL_TEXT_SUCCESS,
|
||||||
|
COL_BUTTON_TEXT, COL_BUTTON, COL_BUTTON_HOVER, COL_BUTTON_RESET, COL_BUTTON_RESET_HOVER, COL_BUTTON_SAVE, COL_BUTTON_SAVE_HOVER,
|
||||||
|
COL_TIMER_TAB_TEXT, COL_TIMER_TAB_BACKGROUND,
|
||||||
|
COL_LAST };
|
||||||
|
|
||||||
|
const char kWebColors[] PROGMEM =
|
||||||
|
COLOR_TEXT "|" COLOR_BACKGROUND "|" COLOR_FORM "|"
|
||||||
|
COLOR_INPUT_TEXT "|" COLOR_INPUT "|" COLOR_CONSOLE_TEXT "|" COLOR_CONSOLE "|"
|
||||||
|
COLOR_TEXT_WARNING "|" COLOR_TEXT_SUCCESS "|"
|
||||||
|
COLOR_BUTTON_TEXT "|" COLOR_BUTTON "|" COLOR_BUTTON_HOVER "|" COLOR_BUTTON_RESET "|" COLOR_BUTTON_RESET_HOVER "|" COLOR_BUTTON_SAVE "|" COLOR_BUTTON_SAVE_HOVER "|"
|
||||||
|
COLOR_TIMER_TAB_TEXT "|" COLOR_TIMER_TAB_BACKGROUND;
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* RTC memory
|
* RTC memory
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define RTC_MEM_VALID 0xA55A
|
const uint16_t RTC_MEM_VALID = 0xA55A;
|
||||||
|
|
||||||
uint32_t rtc_settings_crc = 0;
|
uint32_t rtc_settings_crc = 0;
|
||||||
|
|
||||||
|
@ -164,16 +238,18 @@ extern "C" {
|
||||||
extern "C" uint32_t _SPIFFS_end;
|
extern "C" uint32_t _SPIFFS_end;
|
||||||
|
|
||||||
// From libraries/EEPROM/EEPROM.cpp EEPROMClass
|
// From libraries/EEPROM/EEPROM.cpp EEPROMClass
|
||||||
#define SPIFFS_END ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE
|
const uint32_t SPIFFS_END = ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE;
|
||||||
|
|
||||||
// Version 4.2 config = eeprom area
|
// Version 4.2 config = eeprom area
|
||||||
#define SETTINGS_LOCATION SPIFFS_END // No need for SPIFFS as it uses EEPROM area
|
const uint32_t SETTINGS_LOCATION = SPIFFS_END; // No need for SPIFFS as it uses EEPROM area
|
||||||
// Version 5.2 allow for more flash space
|
// Version 5.2 allow for more flash space
|
||||||
#define CFG_ROTATES 8 // Number of flash sectors used (handles uploads)
|
const uint8_t CFG_ROTATES = 8; // Number of flash sectors used (handles uploads)
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* EEPROM support based on EEPROM library and tuned for Tasmota
|
* Optional EEPROM support based on EEPROM library and tuned for Tasmota
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
//#define USE_EEPROM
|
||||||
|
#ifdef USE_EEPROM
|
||||||
|
|
||||||
uint32_t eeprom_sector = SPIFFS_END;
|
uint32_t eeprom_sector = SPIFFS_END;
|
||||||
uint8_t* eeprom_data = 0;
|
uint8_t* eeprom_data = 0;
|
||||||
|
@ -301,12 +377,12 @@ void EepromEnd(void)
|
||||||
eeprom_size = 0;
|
eeprom_size = 0;
|
||||||
eeprom_dirty = false;
|
eeprom_dirty = false;
|
||||||
}
|
}
|
||||||
|
#endif // USE_EEPROM
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
uint16_t settings_crc = 0;
|
uint16_t settings_crc = 0;
|
||||||
uint32_t settings_location = SETTINGS_LOCATION;
|
uint32_t settings_location = SETTINGS_LOCATION;
|
||||||
uint8_t *settings_buffer = NULL;
|
uint8_t *settings_buffer = nullptr;
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
/*
|
/*
|
||||||
|
@ -333,9 +409,9 @@ void SetFlashModeDout(void)
|
||||||
|
|
||||||
void SettingsBufferFree(void)
|
void SettingsBufferFree(void)
|
||||||
{
|
{
|
||||||
if (settings_buffer != NULL) {
|
if (settings_buffer != nullptr) {
|
||||||
free(settings_buffer);
|
free(settings_buffer);
|
||||||
settings_buffer = NULL;
|
settings_buffer = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +444,9 @@ void SettingsSaveAll(void)
|
||||||
Settings.power = 0;
|
Settings.power = 0;
|
||||||
}
|
}
|
||||||
XsnsCall(FUNC_SAVE_BEFORE_RESTART);
|
XsnsCall(FUNC_SAVE_BEFORE_RESTART);
|
||||||
|
#ifdef USE_EEPROM
|
||||||
EepromCommit();
|
EepromCommit();
|
||||||
|
#endif
|
||||||
SettingsSave(0);
|
SettingsSave(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,6 +489,7 @@ void SettingsSave(uint8_t rotate)
|
||||||
Settings.cfg_size = sizeof(SYSCFG);
|
Settings.cfg_size = sizeof(SYSCFG);
|
||||||
Settings.cfg_crc = GetSettingsCrc();
|
Settings.cfg_crc = GetSettingsCrc();
|
||||||
|
|
||||||
|
#ifdef USE_EEPROM
|
||||||
if (SPIFFS_END == settings_location) {
|
if (SPIFFS_END == settings_location) {
|
||||||
uint8_t* flash_buffer;
|
uint8_t* flash_buffer;
|
||||||
flash_buffer = new uint8_t[SPI_FLASH_SEC_SIZE];
|
flash_buffer = new uint8_t[SPI_FLASH_SEC_SIZE];
|
||||||
|
@ -428,6 +507,10 @@ void SettingsSave(uint8_t rotate)
|
||||||
ESP.flashEraseSector(settings_location);
|
ESP.flashEraseSector(settings_location);
|
||||||
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
ESP.flashEraseSector(settings_location);
|
||||||
|
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||||
|
#endif // USE_EEPROM
|
||||||
|
|
||||||
if (!stop_flash_rotate && rotate) {
|
if (!stop_flash_rotate && rotate) {
|
||||||
for (uint8_t i = 1; i < CFG_ROTATES; i++) {
|
for (uint8_t i = 1; i < CFG_ROTATES; i++) {
|
||||||
|
@ -456,13 +539,17 @@ void SettingsLoad(void)
|
||||||
|
|
||||||
settings_location = 0;
|
settings_location = 0;
|
||||||
uint32_t flash_location = SETTINGS_LOCATION +1;
|
uint32_t flash_location = SETTINGS_LOCATION +1;
|
||||||
|
uint16_t cfg_holder = 0;
|
||||||
for (uint8_t i = 0; i < CFG_ROTATES; i++) {
|
for (uint8_t i = 0; i < CFG_ROTATES; i++) {
|
||||||
flash_location--;
|
flash_location--;
|
||||||
ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||||
|
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
if (Settings.version > 0x06000000) {
|
if (Settings.version > 0x06000000) {
|
||||||
valid = (Settings.cfg_crc == GetSettingsCrc());
|
bool almost_valid = (Settings.cfg_crc == GetSettingsCrc());
|
||||||
|
// Sometimes CRC on pages below FB, overwritten by OTA, is fine but Settings are still invalid. So check cfg_holder too
|
||||||
|
if (almost_valid && (0 == cfg_holder)) { cfg_holder = Settings.cfg_holder; } // At FB always active cfg_holder
|
||||||
|
valid = (cfg_holder == Settings.cfg_holder);
|
||||||
} else {
|
} else {
|
||||||
ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
|
ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
|
||||||
valid = (Settings.cfg_holder == _SettingsH.cfg_holder);
|
valid = (Settings.cfg_holder == _SettingsH.cfg_holder);
|
||||||
|
@ -481,7 +568,7 @@ void SettingsLoad(void)
|
||||||
}
|
}
|
||||||
if (settings_location > 0) {
|
if (settings_location > 0) {
|
||||||
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %d"), settings_location, Settings.save_flag);
|
AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FIRMWARE_MINIMAL
|
#ifndef FIRMWARE_MINIMAL
|
||||||
|
@ -608,6 +695,7 @@ void SettingsDefaultSet2(void)
|
||||||
Settings.blinktime = APP_BLINKTIME;
|
Settings.blinktime = APP_BLINKTIME;
|
||||||
Settings.blinkcount = APP_BLINKCOUNT;
|
Settings.blinkcount = APP_BLINKCOUNT;
|
||||||
Settings.ledstate = APP_LEDSTATE;
|
Settings.ledstate = APP_LEDSTATE;
|
||||||
|
Settings.ledmask = APP_LEDMASK;
|
||||||
Settings.pulse_timer[0] = APP_PULSETIME;
|
Settings.pulse_timer[0] = APP_PULSETIME;
|
||||||
// for (uint8_t i = 1; i < MAX_PULSETIMERS; i++) { Settings.pulse_timer[i] = 0; }
|
// for (uint8_t i = 1; i < MAX_PULSETIMERS; i++) { Settings.pulse_timer[i] = 0; }
|
||||||
|
|
||||||
|
@ -815,6 +903,10 @@ void SettingsDefaultSet2(void)
|
||||||
Settings.rgbwwTable[j] = 255;
|
Settings.rgbwwTable[j] = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Settings.novasds_period = WORKING_PERIOD;
|
||||||
|
|
||||||
|
SettingsDefaultWebColor();
|
||||||
|
|
||||||
memset(&Settings.drivers, 0xFF, 32); // Enable all possible monitors, displays, drivers and sensors
|
memset(&Settings.drivers, 0xFF, 32); // Enable all possible monitors, displays, drivers and sensors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,6 +977,14 @@ void SettingsDefaultSet_5_13_1c(void)
|
||||||
SettingsResetDst();
|
SettingsResetDst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsDefaultWebColor(void)
|
||||||
|
{
|
||||||
|
char scolor[10];
|
||||||
|
for (uint8_t i = 0; i < COL_LAST; i++) {
|
||||||
|
WebHexCode(i, GetTextIndexed(scolor, sizeof(scolor), i, kWebColors));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
void SettingsDelta(void)
|
void SettingsDelta(void)
|
||||||
|
@ -1055,6 +1155,15 @@ void SettingsDelta(void)
|
||||||
if (Settings.version < 0x06040113) {
|
if (Settings.version < 0x06040113) {
|
||||||
Settings.param[P_RGB_REMAP] = RGB_REMAP_RGBW;
|
Settings.param[P_RGB_REMAP] = RGB_REMAP_RGBW;
|
||||||
}
|
}
|
||||||
|
if (Settings.version < 0x06050003) {
|
||||||
|
Settings.novasds_period = WORKING_PERIOD;
|
||||||
|
}
|
||||||
|
if (Settings.version < 0x06050006) {
|
||||||
|
SettingsDefaultWebColor();
|
||||||
|
}
|
||||||
|
if (Settings.version < 0x06050007) {
|
||||||
|
Settings.ledmask = APP_LEDMASK;
|
||||||
|
}
|
||||||
|
|
||||||
Settings.version = VERSION;
|
Settings.version = VERSION;
|
||||||
SettingsSave(1);
|
SettingsSave(1);
|
||||||
|
|
190
sonoff/sonoff.h
190
sonoff/sonoff.h
|
@ -42,109 +42,109 @@
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
typedef unsigned long power_t; // Power (Relay) type
|
typedef unsigned long power_t; // Power (Relay) type
|
||||||
#define POWER_MASK 0xffffffffUL // Power (Relay) full mask
|
const uint32_t POWER_MASK = 0xffffffffUL; // Power (Relay) full mask
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Constants
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
// Changes to the following MAX_ defines will impact settings layout
|
||||||
|
const uint8_t MAX_SWITCHES = 8; // Max number of switches
|
||||||
|
const uint8_t MAX_RELAYS = 8; // Max number of relays
|
||||||
|
const uint8_t MAX_INTERLOCKS = 4; // Max number of interlock groups (MAX_RELAYS / 2)
|
||||||
|
const uint8_t MAX_LEDS = 4; // Max number of leds
|
||||||
|
const uint8_t MAX_KEYS = 4; // Max number of keys or buttons
|
||||||
|
const uint8_t MAX_PWMS = 5; // Max number of PWM channels
|
||||||
|
const uint8_t MAX_COUNTERS = 4; // Max number of counter sensors
|
||||||
|
const uint8_t MAX_TIMERS = 16; // Max number of Timers
|
||||||
|
const uint8_t MAX_PULSETIMERS = 8; // Max number of supported pulse timers
|
||||||
|
const uint8_t MAX_FRIENDLYNAMES = 4; // Max number of Friendly names
|
||||||
|
const uint8_t MAX_DOMOTICZ_IDX = 4; // Max number of Domoticz device, key and switch indices
|
||||||
|
const uint8_t MAX_DOMOTICZ_SNS_IDX = 12; // Max number of Domoticz sensors indices
|
||||||
|
const uint8_t MAX_KNX_GA = 10; // Max number of KNX Group Addresses to read that can be set
|
||||||
|
const uint8_t MAX_KNX_CB = 10; // Max number of KNX Group Addresses to write that can be set
|
||||||
|
const uint8_t MAX_XNRG_DRIVERS = 32; // Max number of allowed energy drivers
|
||||||
|
const uint8_t MAX_XDSP_DRIVERS = 32; // Max number of allowed display drivers
|
||||||
|
const uint8_t MAX_XDRV_DRIVERS = 96; // Max number of allowed driver drivers
|
||||||
|
const uint8_t MAX_XSNS_DRIVERS = 96; // Max number of allowed sensor drivers
|
||||||
|
const uint8_t MAX_RULE_MEMS = 5; // Max number of saved vars
|
||||||
|
const uint8_t MAX_RULE_SETS = 3; // Max number of rule sets of size 512 characters
|
||||||
|
const uint16_t MAX_RULE_SIZE = 512; // Max number of characters in rules
|
||||||
|
|
||||||
|
const uint8_t MAX_FAN_SPEED = 4; // Max number of iFan02 fan speeds (0 .. 3)
|
||||||
|
|
||||||
|
const char MQTT_TOKEN_PREFIX[] PROGMEM = "%prefix%"; // To be substituted by mqtt_prefix[x]
|
||||||
|
const char MQTT_TOKEN_TOPIC[] PROGMEM = "%topic%"; // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
|
||||||
|
const char WIFI_HOSTNAME[] = "%s-%04d"; // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address>
|
||||||
|
|
||||||
|
const uint8_t CONFIG_FILE_SIGN = 0xA5; // Configuration file signature
|
||||||
|
const uint8_t CONFIG_FILE_XOR = 0x5A; // Configuration file xor (0 = No Xor)
|
||||||
|
|
||||||
|
const uint32_t HLW_PREF_PULSE = 12530; // was 4975us = 201Hz = 1000W
|
||||||
|
const uint32_t HLW_UREF_PULSE = 1950; // was 1666us = 600Hz = 220V
|
||||||
|
const uint32_t HLW_IREF_PULSE = 3500; // was 1666us = 600Hz = 4.545A
|
||||||
|
|
||||||
|
const uint8_t MQTT_RETRY_SECS = 10; // Minimum seconds to retry MQTT connection
|
||||||
|
const uint32_t GLOBAL_VALUES_VALID = 300; // Max number of seconds to keep last received values
|
||||||
|
const power_t APP_POWER = 0; // Default saved power state Off
|
||||||
|
const uint16_t WS2812_MAX_LEDS = 512; // Max number of LEDs
|
||||||
|
|
||||||
|
const uint32_t PWM_RANGE = 1023; // 255..1023 needs to be devisible by 256
|
||||||
|
//const uint16_t PWM_FREQ = 1000; // 100..1000 Hz led refresh
|
||||||
|
//const uint16_t PWM_FREQ = 910; // 100..1000 Hz led refresh (iTead value)
|
||||||
|
const uint16_t PWM_FREQ = 880; // 100..1000 Hz led refresh (BN-SZ01 value)
|
||||||
|
const uint16_t PWM_MAX = 4000; // [PWM_MAX] Maximum frequency - Default: 4000
|
||||||
|
const uint16_t PWM_MIN = 100; // [PWM_MIN] Minimum frequency - Default: 100
|
||||||
|
// For Dimmers use double of your mains AC frequecy (100 for 50Hz and 120 for 60Hz)
|
||||||
|
// For Controlling Servos use 50 and also set PWM_FREQ as 50 (DO NOT USE THESE VALUES FOR DIMMERS)
|
||||||
|
//#define PWM_LIGHTSCHEME0_IGNORE_SLEEP // Do not change sleep value for LightAnimate() scheme 0
|
||||||
|
|
||||||
|
const uint8_t DEFAULT_POWER_DELTA = 80; // Power change percentage
|
||||||
|
const uint16_t MAX_POWER_HOLD = 10; // Time in SECONDS to allow max agreed power
|
||||||
|
const uint16_t MAX_POWER_WINDOW = 30; // Time in SECONDS to disable allow max agreed power
|
||||||
|
const uint16_t SAFE_POWER_HOLD = 10; // Time in SECONDS to allow max unit safe power
|
||||||
|
const uint16_t SAFE_POWER_WINDOW = 30; // Time in MINUTES to disable allow max unit safe power
|
||||||
|
const uint8_t MAX_POWER_RETRY = 5; // Retry count allowing agreed power limit overflow
|
||||||
|
|
||||||
|
const uint8_t STATES = 20; // Number of states per second using 50 mSec interval
|
||||||
|
const uint8_t IMMINENT_RESET_FACTOR = 10; // Factor to extent button hold time for imminent Reset to default 40 seconds using KEY_HOLD_TIME of 40
|
||||||
|
const uint32_t BOOT_LOOP_TIME = 10; // Number of seconds to stop detecting boot loops
|
||||||
|
const uint16_t SYSLOG_TIMER = 600; // Seconds to restore syslog_level
|
||||||
|
const uint16_t SERIALLOG_TIMER = 600; // Seconds to disable SerialLog
|
||||||
|
const uint8_t OTA_ATTEMPTS = 5; // Number of times to try fetching the new firmware
|
||||||
|
|
||||||
|
const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in (serial and http) command buffer
|
||||||
|
const uint16_t CMDSZ = 24; // Max number of characters in command
|
||||||
|
const uint16_t TOPSZ = 100; // Max number of characters in topic string
|
||||||
|
const uint16_t LOGSZ = 520; // Max number of characters in log
|
||||||
|
const uint16_t MIN_MESSZ = 893; // Min number of characters in MQTT message
|
||||||
|
|
||||||
|
const uint8_t SENSOR_MAX_MISS = 5; // Max number of missed sensor reads before deciding it's offline
|
||||||
|
|
||||||
|
#ifdef USE_MQTT_TLS
|
||||||
|
const uint16_t WEB_LOG_SIZE = 2000; // Max number of characters in weblog
|
||||||
|
#else
|
||||||
|
const uint16_t WEB_LOG_SIZE = 4000; // Max number of characters in weblog
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const uint8_t MAX_BACKLOG = 30; // Max number of commands in backlog
|
||||||
|
const uint32_t MIN_BACKLOG_DELAY = 2; // Minimal backlog delay in 0.1 seconds
|
||||||
|
|
||||||
|
const uint32_t SOFT_BAUDRATE = 9600; // Default software serial baudrate
|
||||||
|
const uint32_t APP_BAUDRATE = 115200; // Default serial baudrate
|
||||||
|
const uint32_t SERIAL_POLLING = 100; // Serial receive polling in ms
|
||||||
|
const uint8_t MAX_STATUS = 11; // Max number of status lines
|
||||||
|
|
||||||
|
const uint32_t DRIVER_BOOT_DELAY = 1; // Number of milliseconds to retard driver cycles during boot-up time to reduce overall CPU load whilst Wifi is connecting
|
||||||
|
const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to go through the main loop using delay when needed
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Defines
|
* Defines
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
// Changes to the following MAX_ defines will impact settings layout
|
|
||||||
#define MAX_SWITCHES 8 // Max number of switches
|
|
||||||
#define MAX_RELAYS 8 // Max number of relays
|
|
||||||
#define MAX_INTERLOCKS 4 // Max number of interlock groups (MAX_RELAYS / 2)
|
|
||||||
#define MAX_LEDS 4 // Max number of leds
|
|
||||||
#define MAX_KEYS 4 // Max number of keys or buttons
|
|
||||||
#define MAX_PWMS 5 // Max number of PWM channels
|
|
||||||
#define MAX_COUNTERS 4 // Max number of counter sensors
|
|
||||||
#define MAX_TIMERS 16 // Max number of Timers
|
|
||||||
#define MAX_PULSETIMERS 8 // Max number of supported pulse timers
|
|
||||||
#define MAX_FRIENDLYNAMES 4 // Max number of Friendly names
|
|
||||||
#define MAX_DOMOTICZ_IDX 4 // Max number of Domoticz device, key and switch indices
|
|
||||||
#define MAX_DOMOTICZ_SNS_IDX 12 // Max number of Domoticz sensors indices
|
|
||||||
#define MAX_KNX_GA 10 // Max number of KNX Group Addresses to read that can be set
|
|
||||||
#define MAX_KNX_CB 10 // Max number of KNX Group Addresses to write that can be set
|
|
||||||
#define MAX_XNRG_DRIVERS 32 // Max number of allowed energy drivers
|
|
||||||
#define MAX_XDSP_DRIVERS 32 // Max number of allowed display drivers
|
|
||||||
#define MAX_XDRV_DRIVERS 96 // Max number of allowed driver drivers
|
|
||||||
#define MAX_XSNS_DRIVERS 96 // Max number of allowed sensor drivers
|
|
||||||
#define MAX_RULE_MEMS 5 // Max number of saved vars
|
|
||||||
#define MAX_RULE_SETS 3 // Max number of rule sets of size 512 characters
|
|
||||||
#define MAX_RULE_SIZE 512 // Max number of characters in rules
|
|
||||||
|
|
||||||
// Changes to the following defines have no impact on settings layout
|
|
||||||
#define MAX_RULE_TIMERS 8 // Max number of rule timers (4 bytes / timer)
|
#define MAX_RULE_TIMERS 8 // Max number of rule timers (4 bytes / timer)
|
||||||
#define MAX_RULE_VARS 5 // Max number of rule variables (10 bytes / variable)
|
#define MAX_RULE_VARS 5 // Max number of rule variables (10 bytes / variable)
|
||||||
|
|
||||||
#define MAX_FAN_SPEED 4 // Max number of iFan02 fan speeds (0 .. 3)
|
|
||||||
|
|
||||||
#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
|
|
||||||
#define MQTT_TOKEN_TOPIC "%topic%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
|
|
||||||
#define MQTT_TOKEN_HOSTNAME "%hostname%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
|
|
||||||
#define MQTT_TOKEN_ID "%id%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
|
|
||||||
|
|
||||||
#define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address>
|
|
||||||
|
|
||||||
#define CONFIG_FILE_SIGN 0xA5 // Configuration file signature
|
|
||||||
#define CONFIG_FILE_XOR 0x5A // Configuration file xor (0 = No Xor)
|
|
||||||
|
|
||||||
#define HLW_PREF_PULSE 12530 // was 4975us = 201Hz = 1000W
|
|
||||||
#define HLW_UREF_PULSE 1950 // was 1666us = 600Hz = 220V
|
|
||||||
#define HLW_IREF_PULSE 3500 // was 1666us = 600Hz = 4.545A
|
|
||||||
|
|
||||||
#define MQTT_RETRY_SECS 10 // Minimum seconds to retry MQTT connection
|
|
||||||
#define GLOBAL_VALUES_VALID 300 // Max number of seconds to keep last received values
|
|
||||||
#define APP_POWER 0 // Default saved power state Off
|
|
||||||
#define WS2812_MAX_LEDS 512 // Max number of LEDs
|
|
||||||
|
|
||||||
#define PWM_RANGE 1023 // 255..1023 needs to be devisible by 256
|
|
||||||
//#define PWM_FREQ 1000 // 100..1000 Hz led refresh
|
|
||||||
//#define PWM_FREQ 910 // 100..1000 Hz led refresh (iTead value)
|
|
||||||
#define PWM_FREQ 880 // 100..1000 Hz led refresh (BN-SZ01 value)
|
|
||||||
#define PWM_MAX 4000 // [PWM_MAX] Maximum frequency - Default: 4000
|
|
||||||
#define PWM_MIN 100 // [PWM_MIN] Minimum frequency - Default: 100
|
|
||||||
// For Dimmers use double of your mains AC frequecy (100 for 50Hz and 120 for 60Hz)
|
|
||||||
// For Controlling Servos use 50 and also set PWM_FREQ as 50 (DO NOT USE THESE VALUES FOR DIMMERS)
|
|
||||||
//#define PWM_LIGHTSCHEME0_IGNORE_SLEEP // Do not change sleep value for LightAnimate() scheme 0
|
|
||||||
|
|
||||||
#define DEFAULT_POWER_DELTA 80 // Power change percentage
|
|
||||||
#define MAX_POWER_HOLD 10 // Time in SECONDS to allow max agreed power
|
|
||||||
#define MAX_POWER_WINDOW 30 // Time in SECONDS to disable allow max agreed power
|
|
||||||
#define SAFE_POWER_HOLD 10 // Time in SECONDS to allow max unit safe power
|
|
||||||
#define SAFE_POWER_WINDOW 30 // Time in MINUTES to disable allow max unit safe power
|
|
||||||
#define MAX_POWER_RETRY 5 // Retry count allowing agreed power limit overflow
|
|
||||||
|
|
||||||
#define STATES 20 // Number of states per second using 50 mSec interval
|
|
||||||
#define IMMINENT_RESET_FACTOR 10 // Factor to extent button hold time for imminent Reset to default 40 seconds using KEY_HOLD_TIME of 40
|
|
||||||
#define BOOT_LOOP_TIME 10 // Number of seconds to stop detecting boot loops
|
|
||||||
#define SYSLOG_TIMER 600 // Seconds to restore syslog_level
|
|
||||||
#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
|
|
||||||
#define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware
|
|
||||||
|
|
||||||
#define INPUT_BUFFER_SIZE 520 // Max number of characters in (serial and http) command buffer
|
|
||||||
#define CMDSZ 24 // Max number of characters in command
|
|
||||||
#define TOPSZ 100 // Max number of characters in topic string
|
|
||||||
#define LOGSZ 520 // Max number of characters in log
|
|
||||||
#define MIN_MESSZ 893 // Min number of characters in MQTT message
|
|
||||||
|
|
||||||
#define SENSOR_MAX_MISS 5 // Max number of missed sensor reads before deciding it's offline
|
|
||||||
|
|
||||||
#ifdef USE_MQTT_TLS
|
|
||||||
#define WEB_LOG_SIZE 2000 // Max number of characters in weblog
|
|
||||||
#else
|
|
||||||
#define WEB_LOG_SIZE 4000 // Max number of characters in weblog
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_BACKLOG 30 // Max number of commands in backlog
|
|
||||||
#define MIN_BACKLOG_DELAY 2 // Minimal backlog delay in 0.1 seconds
|
|
||||||
|
|
||||||
#define SOFT_BAUDRATE 9600 // Default software serial baudrate
|
|
||||||
#define APP_BAUDRATE 115200 // Default serial baudrate
|
|
||||||
#define SERIAL_POLLING 100 // Serial receive polling in ms
|
|
||||||
#define MAX_STATUS 11 // Max number of status lines
|
|
||||||
|
|
||||||
#define DRIVER_BOOT_DELAY 1 // Number of milliseconds to retard driver cycles during boot-up time to reduce overall CPU load whilst Wifi is connecting
|
|
||||||
#define LOOP_SLEEP_DELAY 50 // Lowest number of milliseconds to go through the main loop using delay when needed
|
|
||||||
|
|
||||||
#define NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions)
|
#define NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -140,6 +140,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||||
#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
|
#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
|
||||||
// #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code)
|
// #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code)
|
||||||
#define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code)
|
#define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code)
|
||||||
|
#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code)
|
||||||
#endif // FIRMWARE_SENSORS
|
#endif // FIRMWARE_SENSORS
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -197,6 +198,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||||
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
|
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
|
||||||
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
|
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
|
||||||
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
|
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
|
||||||
|
#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code)
|
||||||
#undef DEBUG_THEO // Disable debug code
|
#undef DEBUG_THEO // Disable debug code
|
||||||
#undef USE_DEBUG_DRIVER // Disable debug code
|
#undef USE_DEBUG_DRIVER // Disable debug code
|
||||||
#endif // FIRMWARE_CLASSIC
|
#endif // FIRMWARE_CLASSIC
|
||||||
|
@ -326,6 +328,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||||
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
|
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
|
||||||
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
|
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
|
||||||
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
|
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
|
||||||
|
#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code)
|
||||||
#undef DEBUG_THEO // Disable debug code
|
#undef DEBUG_THEO // Disable debug code
|
||||||
#undef USE_DEBUG_DRIVER // Disable debug code
|
#undef USE_DEBUG_DRIVER // Disable debug code
|
||||||
#endif // FIRMWARE_BASIC
|
#endif // FIRMWARE_BASIC
|
||||||
|
@ -391,6 +394,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||||
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
|
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
|
||||||
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
|
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
|
||||||
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
|
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
|
||||||
|
#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code)
|
||||||
#undef DEBUG_THEO // Disable debug code
|
#undef DEBUG_THEO // Disable debug code
|
||||||
#undef USE_DEBUG_DRIVER // Disable debug code
|
#undef USE_DEBUG_DRIVER // Disable debug code
|
||||||
#endif // FIRMWARE_MINIMAL
|
#endif // FIRMWARE_MINIMAL
|
||||||
|
|
|
@ -178,6 +178,8 @@ enum UserSelectablePins {
|
||||||
GPIO_ROT1B, // Rotary switch1 B Pin
|
GPIO_ROT1B, // Rotary switch1 B Pin
|
||||||
GPIO_ROT2A, // Rotary switch2 A Pin
|
GPIO_ROT2A, // Rotary switch2 A Pin
|
||||||
GPIO_ROT2B, // Rotary switch2 B Pin
|
GPIO_ROT2B, // Rotary switch2 B Pin
|
||||||
|
GPIO_HRE_CLOCK, // Clock/Power line for HR-E Water Meter
|
||||||
|
GPIO_HRE_DATA, // Data line for HR-E Water Meter
|
||||||
GPIO_SENSOR_END };
|
GPIO_SENSOR_END };
|
||||||
|
|
||||||
// Programmer selectable GPIO functionality
|
// Programmer selectable GPIO functionality
|
||||||
|
@ -241,6 +243,7 @@ const char kSensorNames[] PROGMEM =
|
||||||
D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|"
|
D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|"
|
||||||
D_SENSOR_ARIRFRCV "|" D_SENSOR_TXD "|" D_SENSOR_RXD "|"
|
D_SENSOR_ARIRFRCV "|" D_SENSOR_TXD "|" D_SENSOR_RXD "|"
|
||||||
D_SENSOR_ROTARY "1a|" D_SENSOR_ROTARY "1b|" D_SENSOR_ROTARY "2a|" D_SENSOR_ROTARY "2b|"
|
D_SENSOR_ROTARY "1a|" D_SENSOR_ROTARY "1b|" D_SENSOR_ROTARY "2a|" D_SENSOR_ROTARY "2b|"
|
||||||
|
D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|"
|
||||||
;
|
;
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
@ -335,10 +338,10 @@ typedef struct MYCFGIO {
|
||||||
uint8_t io[MAX_GPIO_PIN - MIN_FLASH_PINS];
|
uint8_t io[MAX_GPIO_PIN - MIN_FLASH_PINS];
|
||||||
} mycfgio;
|
} mycfgio;
|
||||||
|
|
||||||
#define GPIO_FLAG_USED 1 // Currently only one flag used
|
#define GPIO_FLAG_USED 2 // Currently two flags used
|
||||||
|
|
||||||
#define GPIO_FLAG_ADC0 1 // Allow ADC0 when define USE_ADC_VCC is disabled
|
#define GPIO_FLAG_ADC0 1 // Allow ADC0 when define USE_ADC_VCC is disabled
|
||||||
#define GPIO_FLAG_SPARE01 2 // Allow input pull-up control using SetOption62 - Superseded by user template editing
|
#define GPIO_FLAG_ADC0_TEMP 2 // Allow ADC0 as Temperature sensor when define USE_ADC_VCC is disabled
|
||||||
#define GPIO_FLAG_SPARE02 4
|
#define GPIO_FLAG_SPARE02 4
|
||||||
#define GPIO_FLAG_SPARE03 8
|
#define GPIO_FLAG_SPARE03 8
|
||||||
#define GPIO_FLAG_SPARE04 16
|
#define GPIO_FLAG_SPARE04 16
|
||||||
|
@ -350,7 +353,7 @@ typedef union {
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
struct {
|
struct {
|
||||||
uint8_t adc0 : 1; // Allow ADC0 when define USE_ADC_VCC is disabled
|
uint8_t adc0 : 1; // Allow ADC0 when define USE_ADC_VCC is disabled
|
||||||
uint8_t spare01 : 1;
|
uint8_t adc0_temp : 1; // Allow ADC0 as Temperature sensor when define USE_ADC_VCC is disabled
|
||||||
uint8_t spare02 : 1;
|
uint8_t spare02 : 1;
|
||||||
uint8_t spare03 : 1;
|
uint8_t spare03 : 1;
|
||||||
uint8_t spare04 : 1;
|
uint8_t spare04 : 1;
|
||||||
|
@ -463,7 +466,9 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
||||||
GPIO_DHT11, // DHT11
|
GPIO_DHT11, // DHT11
|
||||||
GPIO_DHT22, // DHT21, DHT22, AM2301, AM2302, AM2321
|
GPIO_DHT22, // DHT21, DHT22, AM2301, AM2302, AM2321
|
||||||
GPIO_SI7021, // iTead SI7021
|
GPIO_SI7021, // iTead SI7021
|
||||||
|
#if defined(USE_DS18B20) || defined(USE_DS18x20) || defined(USE_DS18x20_LEGACY)
|
||||||
GPIO_DSB, // Single wire DS18B20 or DS18S20
|
GPIO_DSB, // Single wire DS18B20 or DS18S20
|
||||||
|
#endif
|
||||||
#ifdef USE_WS2812
|
#ifdef USE_WS2812
|
||||||
GPIO_WS2812, // WS2812 Led string
|
GPIO_WS2812, // WS2812 Led string
|
||||||
#endif
|
#endif
|
||||||
|
@ -580,14 +585,22 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
||||||
GPIO_SM16716_DAT, // SM16716 DATA
|
GPIO_SM16716_DAT, // SM16716 DATA
|
||||||
GPIO_SM16716_SEL, // SM16716 SELECT
|
GPIO_SM16716_SEL, // SM16716 SELECT
|
||||||
#endif // USE_SM16716
|
#endif // USE_SM16716
|
||||||
|
#ifdef ROTARY_V1
|
||||||
GPIO_ROT1A, // Rotary switch1 A Pin
|
GPIO_ROT1A, // Rotary switch1 A Pin
|
||||||
GPIO_ROT1B, // Rotary switch1 B Pin
|
GPIO_ROT1B, // Rotary switch1 B Pin
|
||||||
GPIO_ROT2A, // Rotary switch2 A Pin
|
GPIO_ROT2A, // Rotary switch2 A Pin
|
||||||
GPIO_ROT2B, // Rotary switch2 B Pin
|
GPIO_ROT2B, // Rotary switch2 B Pin
|
||||||
GPIO_ARIRFRCV // AliLux RF Receive input
|
#endif
|
||||||
|
#ifdef USE_ARILUX_RF
|
||||||
|
GPIO_ARIRFRCV, // AliLux RF Receive input
|
||||||
|
#endif
|
||||||
|
#ifdef USE_HRE
|
||||||
|
GPIO_HRE_CLOCK,
|
||||||
|
GPIO_HRE_DATA
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
|
const uint8_t kModuleNiceList[] PROGMEM = {
|
||||||
SONOFF_BASIC, // Sonoff Relay Devices
|
SONOFF_BASIC, // Sonoff Relay Devices
|
||||||
SONOFF_RF,
|
SONOFF_RF,
|
||||||
SONOFF_TH,
|
SONOFF_TH,
|
||||||
|
@ -639,9 +652,15 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
|
||||||
OBI2,
|
OBI2,
|
||||||
MANZOKU_EU_4,
|
MANZOKU_EU_4,
|
||||||
ESP_SWITCH, // Switch Devices
|
ESP_SWITCH, // Switch Devices
|
||||||
|
#ifdef USE_TUYA_DIMMER
|
||||||
TUYA_DIMMER, // Dimmer Devices
|
TUYA_DIMMER, // Dimmer Devices
|
||||||
|
#endif
|
||||||
|
#ifdef USE_ARMTRONIX_DIMMERS
|
||||||
ARMTRONIX_DIMMERS,
|
ARMTRONIX_DIMMERS,
|
||||||
|
#endif
|
||||||
|
#ifdef USE_PS_16_DZ
|
||||||
PS_16_DZ,
|
PS_16_DZ,
|
||||||
|
#endif
|
||||||
H801, // Light Devices
|
H801, // Light Devices
|
||||||
MAGICHOME,
|
MAGICHOME,
|
||||||
ARILUX_LC01,
|
ARILUX_LC01,
|
||||||
|
@ -649,7 +668,9 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
|
||||||
ARILUX_LC11,
|
ARILUX_LC11,
|
||||||
ZENGGE_ZF_WF017,
|
ZENGGE_ZF_WF017,
|
||||||
HUAFAN_SS,
|
HUAFAN_SS,
|
||||||
|
#ifdef ROTARY_V1
|
||||||
MI_DESK_LAMP,
|
MI_DESK_LAMP,
|
||||||
|
#endif
|
||||||
KMC_70011,
|
KMC_70011,
|
||||||
AILIGHT, // Light Bulbs
|
AILIGHT, // Light Bulbs
|
||||||
PHILIPS,
|
PHILIPS,
|
||||||
|
|
|
@ -20,11 +20,6 @@
|
||||||
#ifndef _SONOFF_VERSION_H_
|
#ifndef _SONOFF_VERSION_H_
|
||||||
#define _SONOFF_VERSION_H_
|
#define _SONOFF_VERSION_H_
|
||||||
|
|
||||||
#define VERSION 0x06050001
|
const uint32_t VERSION = 0x06050007;
|
||||||
|
|
||||||
#define D_PROGRAMNAME "Sonoff-Tasmota"
|
|
||||||
#define D_AUTHOR "Theo Arends"
|
|
||||||
//#define D_WEBLINK "https://github.com/arendst/Sonoff-Tasmota"
|
|
||||||
#define D_WEBLINK "https://bit.ly/tasmota"
|
|
||||||
|
|
||||||
#endif // _SONOFF_VERSION_H_
|
#endif // _SONOFF_VERSION_H_
|
||||||
|
|
|
@ -28,7 +28,7 @@ uint32_t syslog_host_hash = 0; // Syslog host name hash
|
||||||
|
|
||||||
Ticker tickerOSWatch;
|
Ticker tickerOSWatch;
|
||||||
|
|
||||||
#define OSWATCH_RESET_TIME 120
|
const uint32_t OSWATCH_RESET_TIME = 120;
|
||||||
|
|
||||||
static unsigned long oswatch_last_loop_time;
|
static unsigned long oswatch_last_loop_time;
|
||||||
uint8_t oswatch_blocked_loop = 0;
|
uint8_t oswatch_blocked_loop = 0;
|
||||||
|
@ -108,7 +108,7 @@ void* memchr(const void* ptr, int value, size_t num)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://clc-wiki.net/wiki/C_standard_library:string.h:strspn
|
// http://clc-wiki.net/wiki/C_standard_library:string.h:strcspn
|
||||||
// Get span until any character in string
|
// Get span until any character in string
|
||||||
size_t strcspn(const char *str1, const char *str2)
|
size_t strcspn(const char *str1, const char *str2)
|
||||||
{
|
{
|
||||||
|
@ -123,6 +123,77 @@ size_t strcspn(const char *str1, const char *str2)
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://opensource.apple.com/source/Libc/Libc-583/stdlib/FreeBSD/strtoull.c
|
||||||
|
// Convert a string to an unsigned long long integer
|
||||||
|
#ifndef __LONG_LONG_MAX__
|
||||||
|
#define __LONG_LONG_MAX__ 9223372036854775807LL
|
||||||
|
#endif
|
||||||
|
#ifndef ULLONG_MAX
|
||||||
|
#define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned long long strtoull(const char *__restrict nptr, char **__restrict endptr, int base)
|
||||||
|
{
|
||||||
|
const char *s = nptr;
|
||||||
|
char c;
|
||||||
|
do { c = *s++; } while (isspace((unsigned char)c)); // Trim leading spaces
|
||||||
|
|
||||||
|
int neg = 0;
|
||||||
|
if (c == '-') { // Set minus flag and/or skip sign
|
||||||
|
neg = 1;
|
||||||
|
c = *s++;
|
||||||
|
} else {
|
||||||
|
if (c == '+') {
|
||||||
|
c = *s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((base == 0 || base == 16) && (c == '0') && (*s == 'x' || *s == 'X')) { // Set Hexadecimal
|
||||||
|
c = s[1];
|
||||||
|
s += 2;
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
if (base == 0) { base = (c == '0') ? 8 : 10; } // Set Octal or Decimal
|
||||||
|
|
||||||
|
unsigned long long acc = 0;
|
||||||
|
int any = 0;
|
||||||
|
if (base > 1 && base < 37) {
|
||||||
|
unsigned long long cutoff = ULLONG_MAX / base;
|
||||||
|
int cutlim = ULLONG_MAX % base;
|
||||||
|
for ( ; ; c = *s++) {
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
c -= '0';
|
||||||
|
else if (c >= 'A' && c <= 'Z')
|
||||||
|
c -= 'A' - 10;
|
||||||
|
else if (c >= 'a' && c <= 'z')
|
||||||
|
c -= 'a' - 10;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (c >= base)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||||
|
any = -1;
|
||||||
|
else {
|
||||||
|
any = 1;
|
||||||
|
acc *= base;
|
||||||
|
acc += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (any < 0) {
|
||||||
|
acc = ULLONG_MAX; // Range error
|
||||||
|
}
|
||||||
|
else if (any && neg) {
|
||||||
|
acc = -acc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endptr != nullptr) { *endptr = (char *)(any ? s - 1 : nptr); }
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||||
|
|
||||||
// Get span until single character in string
|
// Get span until single character in string
|
||||||
|
@ -139,15 +210,15 @@ size_t strchrspn(const char *str1, int character)
|
||||||
char* subStr(char* dest, char* str, const char *delim, int index)
|
char* subStr(char* dest, char* str, const char *delim, int index)
|
||||||
{
|
{
|
||||||
char *act;
|
char *act;
|
||||||
char *sub = NULL;
|
char *sub = nullptr;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Since strtok consumes the first arg, make a copy
|
// Since strtok consumes the first arg, make a copy
|
||||||
strncpy(dest, str, strlen(str)+1);
|
strncpy(dest, str, strlen(str)+1);
|
||||||
for (i = 1, act = dest; i <= index; i++, act = NULL) {
|
for (i = 1, act = dest; i <= index; i++, act = nullptr) {
|
||||||
sub = strtok_r(act, delim, &ptr);
|
sub = strtok_r(act, delim, &ptr);
|
||||||
if (sub == NULL) break;
|
if (sub == nullptr) break;
|
||||||
}
|
}
|
||||||
sub = Trim(sub);
|
sub = Trim(sub);
|
||||||
return sub;
|
return sub;
|
||||||
|
@ -200,6 +271,27 @@ int TextToInt(char *str)
|
||||||
return strtol(str, &p, radix);
|
return strtol(str, &p, radix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* ulltoa(unsigned long long value, char *str, int radix)
|
||||||
|
{
|
||||||
|
char digits[64];
|
||||||
|
char *dst = str;
|
||||||
|
int i = 0;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
// if (radix < 2 || radix > 36) { radix = 10; }
|
||||||
|
|
||||||
|
do {
|
||||||
|
n = value % radix;
|
||||||
|
digits[i++] = (n < 10) ? (char)n+'0' : (char)n-10+'A';
|
||||||
|
value /= radix;
|
||||||
|
} while (value != 0);
|
||||||
|
|
||||||
|
while (i > 0) { *dst++ = digits[--i]; }
|
||||||
|
|
||||||
|
*dst = 0;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
char* dtostrfd(double number, unsigned char prec, char *s)
|
char* dtostrfd(double number, unsigned char prec, char *s)
|
||||||
{
|
{
|
||||||
if ((isnan(number)) || (isinf(number))) { // Fix for JSON output (https://stackoverflow.com/questions/1423081/json-left-out-infinity-and-nan-json-status-in-ecmascript)
|
if ((isnan(number)) || (isinf(number))) { // Fix for JSON output (https://stackoverflow.com/questions/1423081/json-left-out-infinity-and-nan-json-status-in-ecmascript)
|
||||||
|
@ -283,6 +375,19 @@ char* RemoveSpace(char* p)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* LowerCase(char* dest, const char* source)
|
||||||
|
{
|
||||||
|
char* write = dest;
|
||||||
|
const char* read = source;
|
||||||
|
char ch = '.';
|
||||||
|
|
||||||
|
while (ch != '\0') {
|
||||||
|
ch = *read++;
|
||||||
|
*write++ = tolower(ch);
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
char* UpperCase(char* dest, const char* source)
|
char* UpperCase(char* dest, const char* source)
|
||||||
{
|
{
|
||||||
char* write = dest;
|
char* write = dest;
|
||||||
|
@ -357,6 +462,14 @@ uint8_t Shortcut(const char* str)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ValidIpAddress(const char* str)
|
||||||
|
{
|
||||||
|
const char* p = str;
|
||||||
|
|
||||||
|
while (*p && ((*p == '.') || ((*p >= '0') && (*p <= '9')))) { p++; }
|
||||||
|
return (*p == '\0');
|
||||||
|
}
|
||||||
|
|
||||||
bool ParseIp(uint32_t* addr, const char* str)
|
bool ParseIp(uint32_t* addr, const char* str)
|
||||||
{
|
{
|
||||||
uint8_t *part = (uint8_t*)addr;
|
uint8_t *part = (uint8_t*)addr;
|
||||||
|
@ -364,9 +477,9 @@ bool ParseIp(uint32_t* addr, const char* str)
|
||||||
|
|
||||||
*addr = 0;
|
*addr = 0;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
part[i] = strtoul(str, NULL, 10); // Convert byte
|
part[i] = strtoul(str, nullptr, 10); // Convert byte
|
||||||
str = strchr(str, '.');
|
str = strchr(str, '.');
|
||||||
if (str == NULL || *str == '\0') {
|
if (str == nullptr || *str == '\0') {
|
||||||
break; // No more separators, exit
|
break; // No more separators, exit
|
||||||
}
|
}
|
||||||
str++; // Point to next character after separator
|
str++; // Point to next character after separator
|
||||||
|
@ -409,7 +522,7 @@ bool NewerVersion(char* version_str)
|
||||||
return false; // Bail if we can't duplicate. Assume bad.
|
return false; // Bail if we can't duplicate. Assume bad.
|
||||||
}
|
}
|
||||||
// Loop through the version string, splitting on '.' seperators.
|
// Loop through the version string, splitting on '.' seperators.
|
||||||
for (char *str = strtok_r(version_dup, ".", &str_ptr); str && i < sizeof(VERSION); str = strtok_r(NULL, ".", &str_ptr), i++) {
|
for (char *str = strtok_r(version_dup, ".", &str_ptr); str && i < sizeof(VERSION); str = strtok_r(nullptr, ".", &str_ptr), i++) {
|
||||||
int field = atoi(str);
|
int field = atoi(str);
|
||||||
// The fields in a version string can only range from 0-255.
|
// The fields in a version string can only range from 0-255.
|
||||||
if ((field < 0) || (field > 255)) {
|
if ((field < 0) || (field > 255)) {
|
||||||
|
@ -697,6 +810,67 @@ void ShowSource(int source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebHexCode(uint8_t i, const char* code)
|
||||||
|
{
|
||||||
|
char scolor[10];
|
||||||
|
|
||||||
|
strlcpy(scolor, code, sizeof(scolor));
|
||||||
|
char* p = scolor;
|
||||||
|
if ('#' == p[0]) { p++; } // Skip
|
||||||
|
|
||||||
|
if (3 == strlen(p)) { // Convert 3 character to 6 character color code
|
||||||
|
p[6] = p[3]; // \0
|
||||||
|
p[5] = p[2]; // 3
|
||||||
|
p[4] = p[2]; // 3
|
||||||
|
p[3] = p[1]; // 2
|
||||||
|
p[2] = p[1]; // 2
|
||||||
|
p[1] = p[0]; // 1
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t color = strtol(p, nullptr, 16);
|
||||||
|
/*
|
||||||
|
if (3 == strlen(p)) { // Convert 3 character to 6 character color code
|
||||||
|
uint32_t w = ((color & 0xF00) << 8) | ((color & 0x0F0) << 4) | (color & 0x00F); // 00010203
|
||||||
|
color = w | (w << 4); // 00112233
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Settings.web_color[i][0] = (color >> 16) & 0xFF; // Red
|
||||||
|
Settings.web_color[i][1] = (color >> 8) & 0xFF; // Green
|
||||||
|
Settings.web_color[i][2] = color & 0xFF; // Blue
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WebColor(uint8_t i)
|
||||||
|
{
|
||||||
|
uint32_t tcolor = (Settings.web_color[i][0] << 16) | (Settings.web_color[i][1] << 8) | Settings.web_color[i][2];
|
||||||
|
return tcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Response data handling
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
int Response_P(const char* format, ...) // Content send snprintf_P char data
|
||||||
|
{
|
||||||
|
// This uses char strings. Be aware of sending %% if % is needed
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
int len = vsnprintf_P(mqtt_data, sizeof(mqtt_data), format, args);
|
||||||
|
va_end(args);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ResponseAppend_P(const char* format, ...) // Content send snprintf_P char data
|
||||||
|
{
|
||||||
|
// This uses char strings. Be aware of sending %% if % is needed
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
int mlen = strlen(mqtt_data);
|
||||||
|
int len = vsnprintf_P(mqtt_data + mlen, sizeof(mqtt_data) - mlen, format, args);
|
||||||
|
va_end(args);
|
||||||
|
return len + mlen;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* GPIO Module and Template management
|
* GPIO Module and Template management
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -708,6 +882,22 @@ uint8_t ModuleNr()
|
||||||
return (USER_MODULE == Settings.module) ? 0 : Settings.module +1;
|
return (USER_MODULE == Settings.module) ? 0 : Settings.module +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ValidTemplateModule(uint8_t index)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < sizeof(kModuleNiceList); i++) {
|
||||||
|
if (index == pgm_read_byte(kModuleNiceList + i)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ValidModule(uint8_t index)
|
||||||
|
{
|
||||||
|
if (index == USER_MODULE) { return true; }
|
||||||
|
return ValidTemplateModule(index);
|
||||||
|
}
|
||||||
|
|
||||||
String AnyModuleName(uint8_t index)
|
String AnyModuleName(uint8_t index)
|
||||||
{
|
{
|
||||||
if (USER_MODULE == index) {
|
if (USER_MODULE == index) {
|
||||||
|
@ -855,6 +1045,10 @@ bool GetUsedInModule(uint8_t val, uint8_t *arr)
|
||||||
|
|
||||||
bool JsonTemplate(const char* dataBuf)
|
bool JsonTemplate(const char* dataBuf)
|
||||||
{
|
{
|
||||||
|
// {"NAME":"Generic","GPIO":[17,254,29,254,7,254,254,254,138,254,139,254,254],"FLAG":1,"BASE":255}
|
||||||
|
|
||||||
|
if (strlen(dataBuf) < 9) { return false; } // Workaround exception if empty JSON like {} - Needs checks
|
||||||
|
|
||||||
StaticJsonBuffer<350> jb; // 331 from https://arduinojson.org/v5/assistant/
|
StaticJsonBuffer<350> jb; // 331 from https://arduinojson.org/v5/assistant/
|
||||||
JsonObject& obj = jb.parseObject(dataBuf);
|
JsonObject& obj = jb.parseObject(dataBuf);
|
||||||
if (!obj.success()) { return false; }
|
if (!obj.success()) { return false; }
|
||||||
|
@ -875,20 +1069,19 @@ bool JsonTemplate(const char* dataBuf)
|
||||||
}
|
}
|
||||||
if (obj[D_JSON_BASE].success()) {
|
if (obj[D_JSON_BASE].success()) {
|
||||||
uint8_t base = obj[D_JSON_BASE];
|
uint8_t base = obj[D_JSON_BASE];
|
||||||
if ((0 == base) || (base >= MAXMODULE)) { base = 17; } else { base--; }
|
if ((0 == base) || !ValidTemplateModule(base -1)) { base = 18; }
|
||||||
Settings.user_template_base = base; // Default WEMOS
|
Settings.user_template_base = base -1; // Default WEMOS
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TemplateJson()
|
void TemplateJson()
|
||||||
{
|
{
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), Settings.user_template.name);
|
Response_P(PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), Settings.user_template.name);
|
||||||
for (uint8_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
|
for (uint8_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d"), mqtt_data, (i>0)?",":"", Settings.user_template.gp.io[i]);
|
ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", Settings.user_template.gp.io[i]);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"),
|
ResponseAppend_P(PSTR("],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), Settings.user_template.flag, Settings.user_template_base +1);
|
||||||
mqtt_data, Settings.user_template.flag, Settings.user_template_base +1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -959,7 +1152,7 @@ void SetNextTimeInterval(unsigned long& timer, const unsigned long step)
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#ifdef USE_I2C
|
#ifdef USE_I2C
|
||||||
#define I2C_RETRY_COUNTER 3
|
const uint8_t I2C_RETRY_COUNTER = 3;
|
||||||
|
|
||||||
uint32_t i2c_buffer = 0;
|
uint32_t i2c_buffer = 0;
|
||||||
|
|
||||||
|
@ -1182,7 +1375,7 @@ void SetSeriallog(uint8_t loglevel)
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
void GetLog(uint8_t idx, char** entry_pp, size_t* len_p)
|
void GetLog(uint8_t idx, char** entry_pp, size_t* len_p)
|
||||||
{
|
{
|
||||||
char* entry_p = NULL;
|
char* entry_p = nullptr;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (idx) {
|
if (idx) {
|
||||||
|
@ -1210,8 +1403,9 @@ void Syslog(void)
|
||||||
// Destroys log_data
|
// Destroys log_data
|
||||||
char syslog_preamble[64]; // Hostname + Id
|
char syslog_preamble[64]; // Hostname + Id
|
||||||
|
|
||||||
if (syslog_host_hash != GetHash(Settings.syslog_host, strlen(Settings.syslog_host))) {
|
uint32_t current_hash = GetHash(Settings.syslog_host, strlen(Settings.syslog_host));
|
||||||
syslog_host_hash = GetHash(Settings.syslog_host, strlen(Settings.syslog_host));
|
if (syslog_host_hash != current_hash) {
|
||||||
|
syslog_host_hash = current_hash;
|
||||||
WiFi.hostByName(Settings.syslog_host, syslog_host_addr); // If sleep enabled this might result in exception so try to do it once using hash
|
WiFi.hostByName(Settings.syslog_host, syslog_host_addr); // If sleep enabled this might result in exception so try to do it once using hash
|
||||||
}
|
}
|
||||||
if (PortUdp.beginPacket(syslog_host_addr, Settings.syslog_port)) {
|
if (PortUdp.beginPacket(syslog_host_addr, Settings.syslog_port)) {
|
||||||
|
@ -1221,6 +1415,7 @@ void Syslog(void)
|
||||||
memcpy(log_data, syslog_preamble, strlen(syslog_preamble));
|
memcpy(log_data, syslog_preamble, strlen(syslog_preamble));
|
||||||
PortUdp.write(log_data);
|
PortUdp.write(log_data);
|
||||||
PortUdp.endPacket();
|
PortUdp.endPacket();
|
||||||
|
delay(1); // Add time for UDP handling (#5512)
|
||||||
} else {
|
} else {
|
||||||
syslog_level = 0;
|
syslog_level = 0;
|
||||||
syslog_timer = SYSLOG_TIMER;
|
syslog_timer = SYSLOG_TIMER;
|
||||||
|
|
|
@ -382,12 +382,14 @@ void GetFeatures(void)
|
||||||
feature_sns2 |= 0x00100000; // xsns_40_pn532.ino
|
feature_sns2 |= 0x00100000; // xsns_40_pn532.ino
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_MAX44009
|
#ifdef USE_MAX44009
|
||||||
feature_sns2 |= 0x00200000;
|
feature_sns2 |= 0x00200000; // xsns_41_max44009.ino
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SCD30
|
#ifdef USE_SCD30
|
||||||
feature_sns2 |= 0x00400000;
|
feature_sns2 |= 0x00400000; // xsns_42_scd30.ino
|
||||||
|
#endif
|
||||||
|
#ifdef USE_HRE
|
||||||
|
feature_sns2 |= 0x00800000; // xsns_43_hre.ino
|
||||||
#endif
|
#endif
|
||||||
// feature_sns2 |= 0x00800000;
|
|
||||||
// feature_sns2 |= 0x01000000;
|
// feature_sns2 |= 0x01000000;
|
||||||
// feature_sns2 |= 0x02000000;
|
// feature_sns2 |= 0x02000000;
|
||||||
// feature_sns2 |= 0x04000000;
|
// feature_sns2 |= 0x04000000;
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ROTARY_V1
|
|
||||||
#ifdef ROTARY_V1
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Rotary support
|
* Rotary support
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -31,6 +30,9 @@ uint8_t rotary_last_position = 128;
|
||||||
uint8_t interrupts_in_use = 0;
|
uint8_t interrupts_in_use = 0;
|
||||||
uint8_t rotary_changed = 0;
|
uint8_t rotary_changed = 0;
|
||||||
|
|
||||||
|
//#define ROTARY_V1
|
||||||
|
#ifdef ROTARY_V1
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
void update_position(void)
|
void update_position(void)
|
||||||
|
|
|
@ -22,10 +22,11 @@
|
||||||
* Timezone by Jack Christensen (https://github.com/JChristensen/Timezone)
|
* Timezone by Jack Christensen (https://github.com/JChristensen/Timezone)
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define SECS_PER_MIN ((uint32_t)(60UL))
|
const uint32_t SECS_PER_MIN = 60UL;
|
||||||
#define SECS_PER_HOUR ((uint32_t)(3600UL))
|
const uint32_t SECS_PER_HOUR = 3600UL;
|
||||||
#define SECS_PER_DAY ((uint32_t)(SECS_PER_HOUR * 24UL))
|
const uint32_t SECS_PER_DAY = SECS_PER_HOUR * 24UL;
|
||||||
#define MINS_PER_HOUR ((uint32_t)(60UL))
|
const uint32_t MINS_PER_HOUR = 60UL;
|
||||||
|
|
||||||
#define LEAP_YEAR(Y) (((1970+Y)>0) && !((1970+Y)%4) && (((1970+Y)%100) || !((1970+Y)%400)))
|
#define LEAP_YEAR(Y) (((1970+Y)>0) && !((1970+Y)%4) && (((1970+Y)%100) || !((1970+Y)%400)))
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -61,7 +62,7 @@ String GetBuildDateAndTime(void)
|
||||||
|
|
||||||
// sscanf(mdate, "%s %d %d", bdt, &day, &year); // Not implemented in 2.3.0 and probably too much code
|
// sscanf(mdate, "%s %d %d", bdt, &day, &year); // Not implemented in 2.3.0 and probably too much code
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
for (char *str = strtok_r(mdate, " ", &p); str && i < 3; str = strtok_r(NULL, " ", &p)) {
|
for (char *str = strtok_r(mdate, " ", &p); str && i < 3; str = strtok_r(nullptr, " ", &p)) {
|
||||||
switch (i++) {
|
switch (i++) {
|
||||||
case 0: // Month
|
case 0: // Month
|
||||||
smonth = str;
|
smonth = str;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
* Inspired by (https://github.com/OLIMEX/olimex-iot-firmware-esp8266/blob/master/olimex/user/user_switch2.c)
|
* Inspired by (https://github.com/OLIMEX/olimex-iot-firmware-esp8266/blob/master/olimex/user/user_switch2.c)
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define SWITCH_PROBE_INTERVAL 10 // Time in milliseconds between switch input probe
|
const uint8_t SWITCH_PROBE_INTERVAL = 10; // Time in milliseconds between switch input probe
|
||||||
|
|
||||||
#include <Ticker.h>
|
#include <Ticker.h>
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,9 @@
|
||||||
#define WIFI_RESCAN_MINUTES 44 // Number of minutes between wifi network rescan
|
#define WIFI_RESCAN_MINUTES 44 // Number of minutes between wifi network rescan
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WIFI_CONFIG_SEC 180 // seconds before restart
|
const uint8_t WIFI_CONFIG_SEC = 180; // seconds before restart
|
||||||
#define WIFI_CHECK_SEC 20 // seconds
|
const uint8_t WIFI_CHECK_SEC = 20; // seconds
|
||||||
#define WIFI_RETRY_OFFSET_SEC 20 // seconds
|
const uint8_t WIFI_RETRY_OFFSET_SEC = 20; // seconds
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// This worked for 2_5_0_BETA2 but fails since then. Waiting for a solution from core team (#4952)
|
// This worked for 2_5_0_BETA2 but fails since then. Waiting for a solution from core team (#4952)
|
||||||
|
|
|
@ -27,13 +27,13 @@
|
||||||
|
|
||||||
#define XDRV_01 1
|
#define XDRV_01 1
|
||||||
|
|
||||||
#define CHUNKED_BUFFER_SIZE 400 // Chunk buffer size
|
|
||||||
|
|
||||||
#ifndef WIFI_SOFT_AP_CHANNEL
|
#ifndef WIFI_SOFT_AP_CHANNEL
|
||||||
#define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 11 as used by SmartConfig web GUI
|
#define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 11 as used by SmartConfig web GUI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HTTP_REFRESH_TIME 2345 // milliseconds
|
const uint16_t CHUNKED_BUFFER_SIZE = 400; // Chunk buffer size (should be smaller than half mqtt_date size)
|
||||||
|
|
||||||
|
const uint16_t HTTP_REFRESH_TIME = 2345; // milliseconds
|
||||||
#define HTTP_RESTART_RECONNECT_TIME 9000 // milliseconds
|
#define HTTP_RESTART_RECONNECT_TIME 9000 // milliseconds
|
||||||
#define HTTP_OTA_RESTART_RECONNECT_TIME 20000 // milliseconds
|
#define HTTP_OTA_RESTART_RECONNECT_TIME 20000 // milliseconds
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
#include <DNSServer.h>
|
#include <DNSServer.h>
|
||||||
|
|
||||||
#ifdef USE_RF_FLASH
|
#ifdef USE_RF_FLASH
|
||||||
uint8_t *efm8bb1_update = NULL;
|
uint8_t *efm8bb1_update = nullptr;
|
||||||
#endif // USE_RF_FLASH
|
#endif // USE_RF_FLASH
|
||||||
|
|
||||||
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1 };
|
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1 };
|
||||||
|
@ -239,21 +239,21 @@ const char HTTP_HEAD_STYLE1[] PROGMEM =
|
||||||
|
|
||||||
"<style>"
|
"<style>"
|
||||||
"div,fieldset,input,select{padding:5px;font-size:1em;}"
|
"div,fieldset,input,select{padding:5px;font-size:1em;}"
|
||||||
"fieldset{background-color:#f2f2f2;}" // Also update HTTP_TIMER_STYLE
|
"fieldset{background:#%06x;}" // COLOR_FORM, Also update HTTP_TIMER_STYLE
|
||||||
"p{margin:0.5em 0;}"
|
"p{margin:0.5em 0;}"
|
||||||
"input{width:100%%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;}"
|
"input{width:100%%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;background:#%06x;color:#%06x;}" // COLOR_INPUT, COLOR_INPUT_TEXT
|
||||||
"input[type=checkbox],input[type=radio]{width:1em;margin-right:6px;vertical-align:-1px;}"
|
"input[type=checkbox],input[type=radio]{width:1em;margin-right:6px;vertical-align:-1px;}"
|
||||||
"select{width:100%%;}"
|
"select{width:100%%;background:#%06x;color:#%06x;}" // COLOR_INPUT, COLOR_INPUT_TEXT
|
||||||
"textarea{resize:none;width:98%%;height:318px;padding:5px;overflow:auto;}"
|
"textarea{resize:none;width:98%%;height:318px;padding:5px;overflow:auto;background:#%06x;color:#%06x;}" // COLOR_CONSOLE, COLOR_CONSOLE_TEXT
|
||||||
"body{text-align:center;font-family:verdana;}"
|
"body{text-align:center;font-family:verdana;background:#%06x;}" // COLOR_BACKGROUND
|
||||||
"td{padding:0px;}";
|
"td{padding:0px;}";
|
||||||
const char HTTP_HEAD_STYLE2[] PROGMEM =
|
const char HTTP_HEAD_STYLE2[] PROGMEM =
|
||||||
"button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%%;-webkit-transition-duration:0.4s;transition-duration:0.4s;cursor:pointer;}"
|
"button{border:0;border-radius:0.3rem;background:#%06x;color:#%06x;line-height:2.4rem;font-size:1.2rem;width:100%%;-webkit-transition-duration:0.4s;transition-duration:0.4s;cursor:pointer;}" // COLOR_BUTTON, COLOR_BUTTON_TEXT
|
||||||
"button:hover{background-color:#0e70a4;}"
|
"button:hover{background:#%06x;}" // COLOR_BUTTON_HOVER
|
||||||
".bred{background-color:#d43535;}"
|
".bred{background:#%06x;}" // COLOR_BUTTON_RESET
|
||||||
".bred:hover{background-color:#931f1f;}"
|
".bred:hover{background:#%06x;}" // COLOR_BUTTON_RESET_HOVER
|
||||||
".bgrn{background-color:#47c266;}"
|
".bgrn{background:#%06x;}" // COLOR_BUTTON_SAVE
|
||||||
".bgrn:hover{background-color:#5aaf6f;}"
|
".bgrn:hover{background:#%06x;}" // COLOR_BUTTON_SAVE_HOVER
|
||||||
"a{text-decoration:none;}"
|
"a{text-decoration:none;}"
|
||||||
".p{float:left;text-align:left;}"
|
".p{float:left;text-align:left;}"
|
||||||
".q{float:right;text-align:right;}";
|
".q{float:right;text-align:right;}";
|
||||||
|
@ -262,9 +262,9 @@ const char HTTP_HEAD_STYLE3[] PROGMEM =
|
||||||
|
|
||||||
"</head>"
|
"</head>"
|
||||||
"<body>"
|
"<body>"
|
||||||
"<div style='text-align:left;display:inline-block;min-width:340px;'>"
|
"<div style='text-align:left;display:inline-block;color:#%06x;min-width:340px;'>" // COLOR_TEXT
|
||||||
#ifdef FIRMWARE_MINIMAL
|
#ifdef FIRMWARE_MINIMAL
|
||||||
"<div style='text-align:center;color:red;'><h3>" D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "</h3></div>"
|
"<div style='text-align:center;color:#%06x;'><h3>" D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "</h3></div>" // COLOR_TEXT_WARNING
|
||||||
#endif
|
#endif
|
||||||
"<div style='text-align:center;'><noscript>" D_NOSCRIPT "<br/></noscript>"
|
"<div style='text-align:center;'><noscript>" D_NOSCRIPT "<br/></noscript>"
|
||||||
#ifdef LANGUAGE_MODULE_NAME
|
#ifdef LANGUAGE_MODULE_NAME
|
||||||
|
@ -299,6 +299,7 @@ const char HTTP_FORM_TEMPLATE_FLAG[] PROGMEM =
|
||||||
"<p></p>" // Keep close so do not use <br/>
|
"<p></p>" // Keep close so do not use <br/>
|
||||||
"<fieldset><legend><b> " D_TEMPLATE_FLAGS " </b></legend><p>"
|
"<fieldset><legend><b> " D_TEMPLATE_FLAGS " </b></legend><p>"
|
||||||
"<input id='c0' name='c0' type='checkbox'><b>" D_ALLOW_ADC0 "</b><br/>"
|
"<input id='c0' name='c0' type='checkbox'><b>" D_ALLOW_ADC0 "</b><br/>"
|
||||||
|
"<input id='c1' name='c1' type='checkbox'><b>" D_ALLOW_ADC0_TEMP "</b><br/>"
|
||||||
"</p></fieldset>";
|
"</p></fieldset>";
|
||||||
|
|
||||||
const char HTTP_FORM_MODULE[] PROGMEM =
|
const char HTTP_FORM_MODULE[] PROGMEM =
|
||||||
|
@ -333,7 +334,7 @@ const char HTTP_FORM_OTHER[] PROGMEM =
|
||||||
"<p><input id='t2' name='t2' type='checkbox'%s><b>" D_ACTIVATE "</b></p>"
|
"<p><input id='t2' name='t2' type='checkbox'%s><b>" D_ACTIVATE "</b></p>"
|
||||||
"</fieldset>"
|
"</fieldset>"
|
||||||
"<br/>"
|
"<br/>"
|
||||||
"<b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" D_WEB_ADMIN_PASSWORD "' value='" D_ASTERIX "'><br/>"
|
"<b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='wp' name='wp' type='password' placeholder='" D_WEB_ADMIN_PASSWORD "' value='" D_ASTERIX "'><br/>"
|
||||||
"<br>"
|
"<br>"
|
||||||
"<input id='b1' name='b1' type='checkbox'%s><b>" D_MQTT_ENABLE "</b><br/>"
|
"<input id='b1' name='b1' type='checkbox'%s><b>" D_MQTT_ENABLE "</b><br/>"
|
||||||
"<br/>";
|
"<br/>";
|
||||||
|
@ -376,7 +377,7 @@ const char HTTP_COUNTER[] PROGMEM =
|
||||||
"<br/><div id='t' name='t' style='text-align:center;'></div>";
|
"<br/><div id='t' name='t' style='text-align:center;'></div>";
|
||||||
|
|
||||||
const char HTTP_END[] PROGMEM =
|
const char HTTP_END[] PROGMEM =
|
||||||
"<div style='text-align:right;font-size:11px;'><hr/><a href='" D_WEBLINK "' target='_blank' style='color:#aaa;'>" D_PROGRAMNAME " %s " D_BY " " D_AUTHOR "</a></div>"
|
"<div style='text-align:right;font-size:11px;'><hr/><a href='https://bit.ly/tasmota' target='_blank' style='color:#aaa;'>Sonoff-Tasmota %s " D_BY " Theo Arends</a></div>"
|
||||||
"</div>"
|
"</div>"
|
||||||
"</body>"
|
"</body>"
|
||||||
"</html>";
|
"</html>";
|
||||||
|
@ -413,7 +414,7 @@ const char kUploadErrors[] PROGMEM =
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
#define DNS_PORT 53
|
const uint16_t DNS_PORT = 53;
|
||||||
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY};
|
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY};
|
||||||
|
|
||||||
DNSServer *DnsServer;
|
DNSServer *DnsServer;
|
||||||
|
@ -494,6 +495,7 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||||
}
|
}
|
||||||
if (webserver_state != type) {
|
if (webserver_state != type) {
|
||||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), my_hostname, (mdns_begun) ? ".local" : "", ipweb.toString().c_str());
|
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), my_hostname, (mdns_begun) ? ".local" : "", ipweb.toString().c_str());
|
||||||
|
rules_flag.http_init = 1;
|
||||||
}
|
}
|
||||||
if (type) { webserver_state = type; }
|
if (type) { webserver_state = type; }
|
||||||
}
|
}
|
||||||
|
@ -524,7 +526,7 @@ void WifiManagerBegin(bool reset_only)
|
||||||
|
|
||||||
int channel = WIFI_SOFT_AP_CHANNEL;
|
int channel = WIFI_SOFT_AP_CHANNEL;
|
||||||
if ((channel < 1) || (channel > 13)) { channel = 1; }
|
if ((channel < 1) || (channel > 13)) { channel = 1; }
|
||||||
WiFi.softAP(my_hostname, NULL, channel);
|
WiFi.softAP(my_hostname, nullptr, channel);
|
||||||
|
|
||||||
delay(500); // Without delay I've seen the IP address blank
|
delay(500); // Without delay I've seen the IP address blank
|
||||||
/* Setup the DNS server redirecting all the domains to the apIP */
|
/* Setup the DNS server redirecting all the domains to the apIP */
|
||||||
|
@ -689,7 +691,7 @@ void WSContentStart_P(const char* title, bool auth)
|
||||||
|
|
||||||
WSContentBegin(200, CT_HTML);
|
WSContentBegin(200, CT_HTML);
|
||||||
|
|
||||||
if (title != NULL) {
|
if (title != nullptr) {
|
||||||
char ctitle[strlen_P(title) +1];
|
char ctitle[strlen_P(title) +1];
|
||||||
strcpy_P(ctitle, title); // Get title from flash to RAM
|
strcpy_P(ctitle, title); // Get title from flash to RAM
|
||||||
WSContentSend_P(HTTP_HEAD, Settings.friendlyname[0], ctitle);
|
WSContentSend_P(HTTP_HEAD, Settings.friendlyname[0], ctitle);
|
||||||
|
@ -701,19 +703,28 @@ void WSContentStart_P(const char* title)
|
||||||
WSContentStart_P(title, true);
|
WSContentStart_P(title, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSContentSendStyle_P(const char* style)
|
void WSContentSendStyle_P(const char* formatP, ...)
|
||||||
{
|
{
|
||||||
if (WifiIsInManagerMode()) {
|
if (WifiIsInManagerMode()) {
|
||||||
if (WifiConfigCounter()) {
|
if (WifiConfigCounter()) {
|
||||||
WSContentSend_P(HTTP_SCRIPT_COUNTER);
|
WSContentSend_P(HTTP_SCRIPT_COUNTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WSContentSend_P(HTTP_HEAD_STYLE1);
|
WSContentSend_P(HTTP_HEAD_STYLE1, WebColor(COL_FORM), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_CONSOLE), WebColor(COL_CONSOLE_TEXT), WebColor(COL_BACKGROUND));
|
||||||
WSContentSend_P(HTTP_HEAD_STYLE2);
|
WSContentSend_P(HTTP_HEAD_STYLE2, WebColor(COL_BUTTON), WebColor(COL_BUTTON_TEXT), WebColor(COL_BUTTON_HOVER), WebColor(COL_BUTTON_RESET), WebColor(COL_BUTTON_RESET_HOVER), WebColor(COL_BUTTON_SAVE), WebColor(COL_BUTTON_SAVE_HOVER));
|
||||||
if (style != NULL) {
|
if (formatP != nullptr) {
|
||||||
WSContentSend_P(style);
|
// This uses char strings. Be aware of sending %% if % is needed
|
||||||
|
va_list arg;
|
||||||
|
va_start(arg, formatP);
|
||||||
|
vsnprintf_P(mqtt_data, sizeof(mqtt_data), formatP, arg);
|
||||||
|
va_end(arg);
|
||||||
|
_WSContentSendBuffer();
|
||||||
}
|
}
|
||||||
WSContentSend_P(HTTP_HEAD_STYLE3, ModuleName().c_str(), Settings.friendlyname[0]);
|
WSContentSend_P(HTTP_HEAD_STYLE3, WebColor(COL_TEXT),
|
||||||
|
#ifdef FIRMWARE_MINIMAL
|
||||||
|
WebColor(COL_TEXT_WARNING),
|
||||||
|
#endif
|
||||||
|
ModuleName().c_str(), Settings.friendlyname[0]);
|
||||||
if (Settings.flag3.gui_hostname_ip) {
|
if (Settings.flag3.gui_hostname_ip) {
|
||||||
bool lip = (static_cast<uint32_t>(WiFi.localIP()) != 0);
|
bool lip = (static_cast<uint32_t>(WiFi.localIP()) != 0);
|
||||||
bool sip = (static_cast<uint32_t>(WiFi.softAPIP()) != 0);
|
bool sip = (static_cast<uint32_t>(WiFi.softAPIP()) != 0);
|
||||||
|
@ -729,7 +740,7 @@ void WSContentSendStyle_P(const char* style)
|
||||||
|
|
||||||
void WSContentSendStyle(void)
|
void WSContentSendStyle(void)
|
||||||
{
|
{
|
||||||
WSContentSendStyle_P(NULL);
|
WSContentSendStyle_P(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSContentButton(uint8_t title_index)
|
void WSContentButton(uint8_t title_index)
|
||||||
|
@ -1038,7 +1049,7 @@ void HandleTemplateConfiguration(void)
|
||||||
|
|
||||||
if (WebServer->hasArg("m")) {
|
if (WebServer->hasArg("m")) {
|
||||||
WSContentBegin(200, CT_PLAIN);
|
WSContentBegin(200, CT_PLAIN);
|
||||||
for (uint8_t i = 0; i < MAXMODULE; i++) { // "}2'%d'>%s (%d)}3" - "}2'0'>Sonoff Basic (1)}3"
|
for (uint8_t i = 0; i < sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'0'>Sonoff Basic (1)}3"
|
||||||
uint8_t midx = pgm_read_byte(kModuleNiceList + i);
|
uint8_t midx = pgm_read_byte(kModuleNiceList + i);
|
||||||
WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, midx, AnyModuleName(midx).c_str(), midx +1);
|
WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, midx, AnyModuleName(midx).c_str(), midx +1);
|
||||||
}
|
}
|
||||||
|
@ -1094,9 +1105,8 @@ void HandleTemplateConfiguration(void)
|
||||||
WSContentSend_P(HTTP_TABLE100);
|
WSContentSend_P(HTTP_TABLE100);
|
||||||
for (uint8_t i = 0; i < 17; i++) {
|
for (uint8_t i = 0; i < 17; i++) {
|
||||||
if ((i < 6) || ((i > 8) && (i != 11))) { // Ignore flash pins GPIO06, 7, 8 and 11
|
if ((i < 6) || ((i > 8) && (i != 11))) { // Ignore flash pins GPIO06, 7, 8 and 11
|
||||||
bool esp8285 = ((9==i)||(10==i));
|
WSContentSend_P(PSTR("<tr><td><b><font color='#%06x'>" D_GPIO "%d</font></b></td><td%s><select id='g%d' name='g%d'></select></td></tr>"),
|
||||||
WSContentSend_P(PSTR("<tr><td><b>%s" D_GPIO "%d%s</b></td><td%s><select id='g%d' name='g%d'></select></td></tr>"),
|
((9==i)||(10==i)) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? " style='width:200px'" : "", i, i);
|
||||||
(esp8285) ? "<font color='red'>" : "", i, (esp8285) ? "</font>" : "", (0==i) ? " style='width:200px'" : "", i, i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WSContentSend_P(PSTR("</table>"));
|
WSContentSend_P(PSTR("</table>"));
|
||||||
|
@ -1159,7 +1169,7 @@ void HandleModuleConfiguration(void)
|
||||||
if (WebServer->hasArg("m")) {
|
if (WebServer->hasArg("m")) {
|
||||||
WSContentBegin(200, CT_PLAIN);
|
WSContentBegin(200, CT_PLAIN);
|
||||||
uint8_t vidx = 0;
|
uint8_t vidx = 0;
|
||||||
for (uint8_t i = 0; i <= MAXMODULE; i++) { // "}2'%d'>%s (%d)}3" - "}2'255'>UserTemplate (0)}3" - "}2'0'>Sonoff Basic (1)}3"
|
for (uint8_t i = 0; i <= sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'255'>UserTemplate (0)}3" - "}2'0'>Sonoff Basic (1)}3"
|
||||||
if (0 == i) {
|
if (0 == i) {
|
||||||
midx = USER_MODULE;
|
midx = USER_MODULE;
|
||||||
vidx = 0;
|
vidx = 0;
|
||||||
|
@ -1201,8 +1211,10 @@ void HandleModuleConfiguration(void)
|
||||||
for (uint8_t i = 0; i < sizeof(cmodule); i++) {
|
for (uint8_t i = 0; i < sizeof(cmodule); i++) {
|
||||||
if (ValidGPIO(i, cmodule.io[i])) {
|
if (ValidGPIO(i, cmodule.io[i])) {
|
||||||
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
||||||
|
char sesp8285[40];
|
||||||
|
snprintf_P(sesp8285, sizeof(sesp8285), PSTR("<font color='#%06x'>ESP8285</font>"), WebColor(COL_TEXT_WARNING));
|
||||||
WSContentSend_P(PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:176px'><select id='g%d' name='g%d'></select></td></tr>"),
|
WSContentSend_P(PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:176px'><select id='g%d' name='g%d'></select></td></tr>"),
|
||||||
(WEMOS==my_module_type)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :((9==i)||(10==i))? "<font color='red'>ESP8285</font>" :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
|
(WEMOS==my_module_type)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :((9==i)||(10==i))? sesp8285 :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WSContentSend_P(PSTR("</table>"));
|
WSContentSend_P(PSTR("</table>"));
|
||||||
|
@ -1359,7 +1371,7 @@ void WifiSaveSettings(void)
|
||||||
|
|
||||||
WebGetArg("h", tmp, sizeof(tmp));
|
WebGetArg("h", tmp, sizeof(tmp));
|
||||||
strlcpy(Settings.hostname, (!strlen(tmp)) ? WIFI_HOSTNAME : tmp, sizeof(Settings.hostname));
|
strlcpy(Settings.hostname, (!strlen(tmp)) ? WIFI_HOSTNAME : tmp, sizeof(Settings.hostname));
|
||||||
if (strstr(Settings.hostname,"%")) {
|
if (strstr(Settings.hostname, "%") != nullptr) {
|
||||||
strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname));
|
strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname));
|
||||||
}
|
}
|
||||||
WebGetArg("s1", tmp, sizeof(tmp));
|
WebGetArg("s1", tmp, sizeof(tmp));
|
||||||
|
@ -1494,7 +1506,7 @@ void OtherSaveSettings(void)
|
||||||
char webindex[5];
|
char webindex[5];
|
||||||
char friendlyname[sizeof(Settings.friendlyname[0])];
|
char friendlyname[sizeof(Settings.friendlyname[0])];
|
||||||
|
|
||||||
WebGetArg("p1", tmp, sizeof(tmp));
|
WebGetArg("wp", tmp, sizeof(tmp));
|
||||||
strlcpy(Settings.web_password, (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? Settings.web_password : tmp, sizeof(Settings.web_password));
|
strlcpy(Settings.web_password, (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? Settings.web_password : tmp, sizeof(Settings.web_password));
|
||||||
Settings.flag.mqtt_enabled = WebServer->hasArg("b1");
|
Settings.flag.mqtt_enabled = WebServer->hasArg("b1");
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
|
@ -1769,9 +1781,10 @@ void HandleUploadDone(void)
|
||||||
WSContentSend_P(HTTP_SCRIPT_RELOAD_OTA); // Refesh main web ui after OTA upgrade
|
WSContentSend_P(HTTP_SCRIPT_RELOAD_OTA); // Refesh main web ui after OTA upgrade
|
||||||
}
|
}
|
||||||
WSContentSendStyle();
|
WSContentSendStyle();
|
||||||
WSContentSend_P(PSTR("<div style='text-align:center;'><b>" D_UPLOAD " <font color='"));
|
WSContentSend_P(PSTR("<div style='text-align:center;'><b>" D_UPLOAD " <font color='#"));
|
||||||
if (upload_error) {
|
if (upload_error) {
|
||||||
WSContentSend_P(PSTR("red'>" D_FAILED "</font></b><br/><br/>"));
|
// WSContentSend_P(PSTR(COLOR_TEXT_WARNING "'>" D_FAILED "</font></b><br/><br/>"));
|
||||||
|
WSContentSend_P(PSTR("%06x'>" D_FAILED "</font></b><br/><br/>"), WebColor(COL_TEXT_WARNING));
|
||||||
#ifdef USE_RF_FLASH
|
#ifdef USE_RF_FLASH
|
||||||
if (upload_error < 14) {
|
if (upload_error < 14) {
|
||||||
#else
|
#else
|
||||||
|
@ -1785,7 +1798,7 @@ void HandleUploadDone(void)
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_UPLOAD ": %s"), error);
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_UPLOAD ": %s"), error);
|
||||||
stop_flash_rotate = Settings.flag.stop_flash_rotate;
|
stop_flash_rotate = Settings.flag.stop_flash_rotate;
|
||||||
} else {
|
} else {
|
||||||
WSContentSend_P(PSTR("green'>" D_SUCCESSFUL "</font></b><br/>"));
|
WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "</font></b><br/>"), WebColor(COL_TEXT_SUCCESS));
|
||||||
WSContentSend_P(HTTP_MSG_RSTRT);
|
WSContentSend_P(HTTP_MSG_RSTRT);
|
||||||
ShowWebSource(SRC_WEBGUI);
|
ShowWebSource(SRC_WEBGUI);
|
||||||
restart_flag = 2; // Always restart to re-enable disabled features during update
|
restart_flag = 2; // Always restart to re-enable disabled features during update
|
||||||
|
@ -1885,10 +1898,10 @@ void HandleUploadLoop(void)
|
||||||
}
|
}
|
||||||
#ifdef USE_RF_FLASH
|
#ifdef USE_RF_FLASH
|
||||||
else if (UPL_EFM8BB1 == upload_file_type) {
|
else if (UPL_EFM8BB1 == upload_file_type) {
|
||||||
if (efm8bb1_update != NULL) { // We have carry over data since last write, i. e. a start but not an end
|
if (efm8bb1_update != nullptr) { // We have carry over data since last write, i. e. a start but not an end
|
||||||
ssize_t result = rf_glue_remnant_with_new_data_and_write(efm8bb1_update, upload.buf, upload.currentSize);
|
ssize_t result = rf_glue_remnant_with_new_data_and_write(efm8bb1_update, upload.buf, upload.currentSize);
|
||||||
free(efm8bb1_update);
|
free(efm8bb1_update);
|
||||||
efm8bb1_update = NULL;
|
efm8bb1_update = nullptr;
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
upload_error = abs(result); // 2 = Not enough space, 8 = File invalid
|
upload_error = abs(result); // 2 = Not enough space, 8 = File invalid
|
||||||
return;
|
return;
|
||||||
|
@ -1907,7 +1920,7 @@ void HandleUploadLoop(void)
|
||||||
// A remnant has been detected, allocate data for it plus a null termination byte
|
// A remnant has been detected, allocate data for it plus a null termination byte
|
||||||
size_t remnant_sz = upload.currentSize - result;
|
size_t remnant_sz = upload.currentSize - result;
|
||||||
efm8bb1_update = (uint8_t *) malloc(remnant_sz + 1);
|
efm8bb1_update = (uint8_t *) malloc(remnant_sz + 1);
|
||||||
if (efm8bb1_update == NULL) {
|
if (efm8bb1_update == nullptr) {
|
||||||
upload_error = 2; // Not enough space - Unable to allocate memory to store new RF firmware
|
upload_error = 2; // Not enough space - Unable to allocate memory to store new RF firmware
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2136,20 +2149,20 @@ void HandleNotFound(void)
|
||||||
} else
|
} else
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
{
|
{
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_FILE_NOT_FOUND "\n\nURI: %s\nMethod: %s\nArguments: %d\n"),
|
WSContentBegin(404, CT_PLAIN);
|
||||||
WebServer->uri().c_str(), (WebServer->method() == HTTP_GET) ? "GET" : "POST", WebServer->args());
|
WSContentSend_P(PSTR(D_FILE_NOT_FOUND "\n\nURI: %s\nMethod: %s\nArguments: %d\n"), WebServer->uri().c_str(), (WebServer->method() == HTTP_GET) ? "GET" : "POST", WebServer->args());
|
||||||
for (uint8_t i = 0; i < WebServer->args(); i++) {
|
for (uint8_t i = 0; i < WebServer->args(); i++) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s %s: %s\n"), mqtt_data, WebServer->argName(i).c_str(), WebServer->arg(i).c_str());
|
WSContentSend_P(PSTR(" %s: %s\n"), WebServer->argName(i).c_str(), WebServer->arg(i).c_str());
|
||||||
}
|
}
|
||||||
WSHeaderSend();
|
WSContentEnd();
|
||||||
WSSend(404, CT_PLAIN, mqtt_data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */
|
/* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */
|
||||||
bool CaptivePortal(void)
|
bool CaptivePortal(void)
|
||||||
{
|
{
|
||||||
if ((WifiIsInManagerMode()) && !ValidIpAddress(WebServer->hostHeader())) {
|
// Possible hostHeader: connectivitycheck.gstatic.com or 192.168.4.1
|
||||||
|
if ((WifiIsInManagerMode()) && !ValidIpAddress(WebServer->hostHeader().c_str())) {
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
|
||||||
|
|
||||||
WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true);
|
WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true);
|
||||||
|
@ -2160,16 +2173,6 @@ bool CaptivePortal(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Is this an IP? */
|
|
||||||
bool ValidIpAddress(String str)
|
|
||||||
{
|
|
||||||
for (uint16_t i = 0; i < str.length(); i++) {
|
|
||||||
int c = str.charAt(i);
|
|
||||||
if (c != '.' && (c < '0' || c > '9')) { return false; }
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
String UrlEncode(const String& text)
|
String UrlEncode(const String& text)
|
||||||
|
@ -2285,8 +2288,36 @@ int WebSend(char *buffer)
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
enum WebCommands { CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_WEBREFRESH, CMND_WEBSEND, CMND_EMULATION };
|
bool JsonWebColor(const char* dataBuf)
|
||||||
const char kWebCommands[] PROGMEM = D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_WEBREFRESH "|" D_CMND_WEBSEND "|" D_CMND_EMULATION ;
|
{
|
||||||
|
// Default (light)
|
||||||
|
// {"WebColor":["#000000","#ffffff","#f2f2f2","#000000","#ffffff","#000000","#ffffff","#ff0000","#008000","#ffffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#ffffff","#999999","#000000"]}
|
||||||
|
// Alternative (Dark)
|
||||||
|
// {"webcolor":["#eeeeee","#181818","#4f4f4f","#000000","#dddddd","#008000","#222222","#ff0000","#008000","#ffffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#ffffff","#999999","#000000"]}
|
||||||
|
|
||||||
|
char dataBufLc[strlen(dataBuf) +1];
|
||||||
|
LowerCase(dataBufLc, dataBuf);
|
||||||
|
RemoveSpace(dataBufLc);
|
||||||
|
if (strlen(dataBufLc) < 9) { return false; } // Workaround exception if empty JSON like {} - Needs checks
|
||||||
|
|
||||||
|
StaticJsonBuffer<450> jb; // 421 from https://arduinojson.org/v5/assistant/
|
||||||
|
JsonObject& obj = jb.parseObject(dataBufLc);
|
||||||
|
if (!obj.success()) { return false; }
|
||||||
|
|
||||||
|
char parm_lc[10];
|
||||||
|
if (obj[LowerCase(parm_lc, D_CMND_WEBCOLOR)].success()) {
|
||||||
|
for (uint8_t i = 0; i < COL_LAST; i++) {
|
||||||
|
const char* color = obj[parm_lc][i];
|
||||||
|
if (color != nullptr) {
|
||||||
|
WebHexCode(i, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum WebCommands { CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_WEBREFRESH, CMND_WEBSEND, CMND_WEBCOLOR, CMND_EMULATION };
|
||||||
|
const char kWebCommands[] PROGMEM = D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_WEBREFRESH "|" D_CMND_WEBSEND "|" D_CMND_WEBCOLOR "|" D_CMND_EMULATION ;
|
||||||
const char kWebSendStatus[] PROGMEM = D_JSON_DONE "|" D_JSON_WRONG_PARAMETERS "|" D_JSON_CONNECT_FAILED "|" D_JSON_HOST_NOT_FOUND ;
|
const char kWebSendStatus[] PROGMEM = D_JSON_DONE "|" D_JSON_WRONG_PARAMETERS "|" D_JSON_CONNECT_FAILED "|" D_JSON_HOST_NOT_FOUND ;
|
||||||
|
|
||||||
bool WebCommand(void)
|
bool WebCommand(void)
|
||||||
|
@ -2301,42 +2332,63 @@ bool WebCommand(void)
|
||||||
if (CMND_WEBSERVER == command_code) {
|
if (CMND_WEBSERVER == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { Settings.webserver = XdrvMailbox.payload; }
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { Settings.webserver = XdrvMailbox.payload; }
|
||||||
if (Settings.webserver) {
|
if (Settings.webserver) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %s\"}"),
|
Response_P(PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %s\"}"),
|
||||||
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
|
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(0));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_WEBPASSWORD == command_code) {
|
else if (CMND_WEBPASSWORD == command_code) {
|
||||||
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.web_password))) {
|
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.web_password))) {
|
||||||
strlcpy(Settings.web_password, (SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? WEB_PASSWORD : XdrvMailbox.data, sizeof(Settings.web_password));
|
strlcpy(Settings.web_password, (SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? WEB_PASSWORD : XdrvMailbox.data, sizeof(Settings.web_password));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.web_password);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.web_password);
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_ASTERIX, command);
|
Response_P(S_JSON_COMMAND_ASTERIX, command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_WEBLOG == command_code) {
|
else if (CMND_WEBLOG == command_code) {
|
||||||
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_ALL)) { Settings.weblog_level = XdrvMailbox.payload; }
|
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_ALL)) { Settings.weblog_level = XdrvMailbox.payload; }
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.weblog_level);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.weblog_level);
|
||||||
}
|
}
|
||||||
else if (CMND_WEBREFRESH == command_code) {
|
else if (CMND_WEBREFRESH == command_code) {
|
||||||
if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload <= 10000)) { Settings.web_refresh = XdrvMailbox.payload; }
|
if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload <= 10000)) { Settings.web_refresh = XdrvMailbox.payload; }
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.web_refresh);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.web_refresh);
|
||||||
}
|
}
|
||||||
else if (CMND_WEBSEND == command_code) {
|
else if (CMND_WEBSEND == command_code) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
uint8_t result = WebSend(XdrvMailbox.data);
|
uint8_t result = WebSend(XdrvMailbox.data);
|
||||||
char stemp1[20];
|
char stemp1[20];
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetTextIndexed(stemp1, sizeof(stemp1), result, kWebSendStatus));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetTextIndexed(stemp1, sizeof(stemp1), result, kWebSendStatus));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (CMND_WEBCOLOR == command_code) {
|
||||||
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
if (strstr(XdrvMailbox.data, "{") == nullptr) { // If no JSON it must be parameter
|
||||||
|
if ((XdrvMailbox.data_len > 3) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= COL_LAST)) {
|
||||||
|
WebHexCode(XdrvMailbox.index -1, XdrvMailbox.data);
|
||||||
|
}
|
||||||
|
else if (0 == XdrvMailbox.payload) {
|
||||||
|
SettingsDefaultWebColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JsonWebColor(XdrvMailbox.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Response_P(PSTR("{\"" D_CMND_WEBCOLOR "\":["));
|
||||||
|
for (uint8_t i = 0; i < COL_LAST; i++) {
|
||||||
|
if (i) { ResponseAppend_P(PSTR(",")); }
|
||||||
|
ResponseAppend_P(PSTR("\"#%06x\""), WebColor(i));
|
||||||
|
}
|
||||||
|
ResponseAppend_P(PSTR("]}"));
|
||||||
|
}
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
else if (CMND_EMULATION == command_code) {
|
else if (CMND_EMULATION == command_code) {
|
||||||
if ((XdrvMailbox.payload >= EMUL_NONE) && (XdrvMailbox.payload < EMUL_MAX)) {
|
if ((XdrvMailbox.payload >= EMUL_NONE) && (XdrvMailbox.payload < EMUL_MAX)) {
|
||||||
Settings.flag2.emulation = XdrvMailbox.payload;
|
Settings.flag2.emulation = XdrvMailbox.payload;
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.emulation);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.flag2.emulation);
|
||||||
}
|
}
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
@ -2356,7 +2408,7 @@ bool Xdrv01(uint8_t function)
|
||||||
case FUNC_LOOP:
|
case FUNC_LOOP:
|
||||||
PollDnsWebserver();
|
PollDnsWebserver();
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
if (Settings.flag2.emulation) PollUdp();
|
if (Settings.flag2.emulation) { PollUdp(); }
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
break;
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
|
|
|
@ -37,6 +37,9 @@ const char kMqttCommands[] PROGMEM =
|
||||||
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|"
|
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|"
|
||||||
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 ;
|
||||||
|
|
||||||
|
IPAddress mqtt_host_addr; // MQTT host IP address
|
||||||
|
uint32_t mqtt_host_hash = 0; // MQTT host name hash
|
||||||
|
|
||||||
uint16_t mqtt_connect_count = 0; // MQTT re-connect count
|
uint16_t mqtt_connect_count = 0; // MQTT re-connect count
|
||||||
uint16_t mqtt_retry_counter = 1; // MQTT connection retry counter
|
uint16_t mqtt_retry_counter = 1; // MQTT connection retry counter
|
||||||
uint8_t mqtt_initial_connection_state = 2; // MQTT connection messages state
|
uint8_t mqtt_initial_connection_state = 2; // MQTT connection messages state
|
||||||
|
@ -50,7 +53,6 @@ bool mqtt_allowed = false; // MQTT enabled and parameters valid
|
||||||
* void MqttDisconnect()
|
* void MqttDisconnect()
|
||||||
* void MqttSubscribeLib(char *topic)
|
* void MqttSubscribeLib(char *topic)
|
||||||
* bool MqttPublishLib(const char* topic, bool retained)
|
* bool MqttPublishLib(const char* topic, bool retained)
|
||||||
* void MqttLoop()
|
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#include <PubSubClient.h>
|
#include <PubSubClient.h>
|
||||||
|
@ -91,11 +93,6 @@ bool MqttPublishLib(const char* topic, bool retained)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttLoop(void)
|
|
||||||
{
|
|
||||||
MqttClient.loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
#ifdef USE_DISCOVERY
|
#ifdef USE_DISCOVERY
|
||||||
|
@ -237,17 +234,17 @@ void MqttPublishPowerState(uint8_t device)
|
||||||
#endif // USE_DOMOTICZ
|
#endif // USE_DOMOTICZ
|
||||||
snprintf_P(scommand, sizeof(scommand), PSTR(D_CMND_FANSPEED));
|
snprintf_P(scommand, sizeof(scommand), PSTR(D_CMND_FANSPEED));
|
||||||
GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
|
GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, scommand, GetFanspeed());
|
Response_P(S_JSON_COMMAND_NVALUE, scommand, GetFanspeed());
|
||||||
MqttPublish(stopic);
|
MqttPublish(stopic);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable);
|
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable);
|
||||||
GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
|
GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(power, device -1)));
|
Response_P(S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(power, device -1)));
|
||||||
MqttPublish(stopic);
|
MqttPublish(stopic);
|
||||||
|
|
||||||
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
|
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), GetStateText(bitRead(power, device -1)));
|
Response_P(GetStateText(bitRead(power, device -1)));
|
||||||
MqttPublish(stopic, Settings.flag.mqtt_power_retain);
|
MqttPublish(stopic, Settings.flag.mqtt_power_retain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,7 +256,7 @@ void MqttPublishPowerBlinkState(uint8_t device)
|
||||||
if ((device < 1) || (device > devices_present)) {
|
if ((device < 1) || (device > devices_present)) {
|
||||||
device = 1;
|
device = 1;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"" D_JSON_BLINK " %s\"}"),
|
Response_P(PSTR("{\"%s\":\"" D_JSON_BLINK " %s\"}"),
|
||||||
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable), GetStateText(bitRead(blink_mask, device -1)));
|
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable), GetStateText(bitRead(blink_mask, device -1)));
|
||||||
|
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, S_RSLT_POWER);
|
MqttPublishPrefixTopic_P(RESULT_OR_STAT, S_RSLT_POWER);
|
||||||
|
@ -292,7 +289,7 @@ void MqttConnected(void)
|
||||||
mqtt_connect_count++;
|
mqtt_connect_count++;
|
||||||
|
|
||||||
GetTopic_P(stopic, TELE, mqtt_topic, S_LWT);
|
GetTopic_P(stopic, TELE, mqtt_topic, S_LWT);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_ONLINE));
|
Response_P(PSTR(D_ONLINE));
|
||||||
MqttPublish(stopic, true);
|
MqttPublish(stopic, true);
|
||||||
|
|
||||||
// Satisfy iobroker (#299)
|
// Satisfy iobroker (#299)
|
||||||
|
@ -301,7 +298,7 @@ void MqttConnected(void)
|
||||||
|
|
||||||
GetTopic_P(stopic, CMND, mqtt_topic, PSTR("#"));
|
GetTopic_P(stopic, CMND, mqtt_topic, PSTR("#"));
|
||||||
MqttSubscribe(stopic);
|
MqttSubscribe(stopic);
|
||||||
if (strstr(Settings.mqtt_fulltopic, MQTT_TOKEN_TOPIC) != NULL) {
|
if (strstr_P(Settings.mqtt_fulltopic, MQTT_TOKEN_TOPIC) != nullptr) {
|
||||||
GetTopic_P(stopic, CMND, Settings.mqtt_grptopic, PSTR("#"));
|
GetTopic_P(stopic, CMND, Settings.mqtt_grptopic, PSTR("#"));
|
||||||
MqttSubscribe(stopic);
|
MqttSubscribe(stopic);
|
||||||
GetFallbackTopic_P(stopic, CMND, PSTR("#"));
|
GetFallbackTopic_P(stopic, CMND, PSTR("#"));
|
||||||
|
@ -312,18 +309,17 @@ void MqttConnected(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mqtt_initial_connection_state) {
|
if (mqtt_initial_connection_state) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), 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(), my_version, my_image, GetFallbackTopic_P(stopic, CMND, ""), Settings.mqtt_grptopic);
|
ModuleName().c_str(), my_version, my_image, GetFallbackTopic_P(stopic, CMND, ""), Settings.mqtt_grptopic);
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "1"));
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "1"));
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
if (Settings.webserver) {
|
if (Settings.webserver) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), 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) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
|
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2"));
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2"));
|
||||||
}
|
}
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"),
|
Response_P(PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"), (GetResetReason() == "Exception") ? ESP.getResetInfo().c_str() : GetResetReason().c_str());
|
||||||
(GetResetReason() == "Exception") ? ESP.getResetInfo().c_str() : GetResetReason().c_str());
|
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3"));
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3"));
|
||||||
for (uint8_t i = 1; i <= devices_present; i++) {
|
for (uint8_t i = 1; i <= devices_present; i++) {
|
||||||
MqttPublishPowerState(i);
|
MqttPublishPowerState(i);
|
||||||
|
@ -432,13 +428,13 @@ void MqttReconnect(void)
|
||||||
mqtt_retry_counter = Settings.mqtt_retry;
|
mqtt_retry_counter = Settings.mqtt_retry;
|
||||||
global_state.mqtt_down = 1;
|
global_state.mqtt_down = 1;
|
||||||
|
|
||||||
char *mqtt_user = NULL;
|
char *mqtt_user = nullptr;
|
||||||
char *mqtt_pwd = NULL;
|
char *mqtt_pwd = nullptr;
|
||||||
if (strlen(Settings.mqtt_user) > 0) mqtt_user = Settings.mqtt_user;
|
if (strlen(Settings.mqtt_user) > 0) mqtt_user = Settings.mqtt_user;
|
||||||
if (strlen(Settings.mqtt_pwd) > 0) mqtt_pwd = Settings.mqtt_pwd;
|
if (strlen(Settings.mqtt_pwd) > 0) mqtt_pwd = Settings.mqtt_pwd;
|
||||||
|
|
||||||
GetTopic_P(stopic, TELE, mqtt_topic, S_LWT);
|
GetTopic_P(stopic, TELE, mqtt_topic, S_LWT);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_OFFLINE);
|
Response_P(S_OFFLINE);
|
||||||
|
|
||||||
#ifdef USE_MQTT_TLS
|
#ifdef USE_MQTT_TLS
|
||||||
EspClient = WiFiClientSecure(); // Wifi Secure Client reconnect issue 4497 (https://github.com/esp8266/Arduino/issues/4497)
|
EspClient = WiFiClientSecure(); // Wifi Secure Client reconnect issue 4497 (https://github.com/esp8266/Arduino/issues/4497)
|
||||||
|
@ -456,6 +452,15 @@ void MqttReconnect(void)
|
||||||
|
|
||||||
MqttClient.setCallback(MqttDataHandler);
|
MqttClient.setCallback(MqttDataHandler);
|
||||||
MqttClient.setServer(Settings.mqtt_host, Settings.mqtt_port);
|
MqttClient.setServer(Settings.mqtt_host, Settings.mqtt_port);
|
||||||
|
/*
|
||||||
|
// Skip MQTT host DNS lookup if not needed
|
||||||
|
uint32_t current_hash = GetHash(Settings.mqtt_host, strlen(Settings.mqtt_host));
|
||||||
|
if (mqtt_host_hash != current_hash) {
|
||||||
|
mqtt_host_hash = current_hash;
|
||||||
|
WiFi.hostByName(Settings.mqtt_host, mqtt_host_addr); // Skips DNS lookup if mqtt_host is IP address string as from mDns
|
||||||
|
}
|
||||||
|
MqttClient.setServer(mqtt_host_addr, Settings.mqtt_port);
|
||||||
|
*/
|
||||||
if (MqttClient.connect(mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, true, mqtt_data)) {
|
if (MqttClient.connect(mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, true, mqtt_data)) {
|
||||||
MqttConnected();
|
MqttConnected();
|
||||||
} else {
|
} else {
|
||||||
|
@ -514,21 +519,21 @@ bool MqttCommand(void)
|
||||||
strlcpy(Settings.mqtt_host, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host));
|
strlcpy(Settings.mqtt_host, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host));
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_host);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_host);
|
||||||
}
|
}
|
||||||
else if (CMND_MQTTPORT == command_code) {
|
else if (CMND_MQTTPORT == command_code) {
|
||||||
if (payload16 > 0) {
|
if (payload16 > 0) {
|
||||||
Settings.mqtt_port = (1 == payload16) ? MQTT_PORT : payload16;
|
Settings.mqtt_port = (1 == payload16) ? MQTT_PORT : payload16;
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.mqtt_port);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.mqtt_port);
|
||||||
}
|
}
|
||||||
else if (CMND_MQTTRETRY == command_code) {
|
else if (CMND_MQTTRETRY == command_code) {
|
||||||
if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) {
|
if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) {
|
||||||
Settings.mqtt_retry = payload;
|
Settings.mqtt_retry = payload;
|
||||||
mqtt_retry_counter = Settings.mqtt_retry;
|
mqtt_retry_counter = Settings.mqtt_retry;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.mqtt_retry);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.mqtt_retry);
|
||||||
}
|
}
|
||||||
else if ((CMND_STATETEXT == command_code) && (index > 0) && (index <= 4)) {
|
else if ((CMND_STATETEXT == command_code) && (index > 0) && (index <= 4)) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(Settings.state_text[0]))) {
|
if ((data_len > 0) && (data_len < sizeof(Settings.state_text[0]))) {
|
||||||
|
@ -537,7 +542,7 @@ bool MqttCommand(void)
|
||||||
}
|
}
|
||||||
strlcpy(Settings.state_text[index -1], dataBuf, sizeof(Settings.state_text[0]));
|
strlcpy(Settings.state_text[index -1], dataBuf, sizeof(Settings.state_text[0]));
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, GetStateText(index -1));
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, GetStateText(index -1));
|
||||||
}
|
}
|
||||||
#ifdef USE_MQTT_TLS
|
#ifdef USE_MQTT_TLS
|
||||||
else if ((CMND_MQTTFINGERPRINT == command_code) && (index > 0) && (index <= 2)) {
|
else if ((CMND_MQTTFINGERPRINT == command_code) && (index > 0) && (index <= 2)) {
|
||||||
|
@ -554,7 +559,7 @@ bool MqttCommand(void)
|
||||||
for (uint8_t i = 0; i < sizeof(Settings.mqtt_fingerprint[index -1]); i++) {
|
for (uint8_t i = 0; i < sizeof(Settings.mqtt_fingerprint[index -1]); i++) {
|
||||||
snprintf_P(fingerprint, sizeof(fingerprint), PSTR("%s%s%02X"), fingerprint, (i) ? " " : "", Settings.mqtt_fingerprint[index -1][i]);
|
snprintf_P(fingerprint, sizeof(fingerprint), PSTR("%s%s%02X"), fingerprint, (i) ? " " : "", Settings.mqtt_fingerprint[index -1][i]);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, fingerprint);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, fingerprint);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (CMND_MQTTCLIENT == command_code) {
|
else if (CMND_MQTTCLIENT == command_code) {
|
||||||
|
@ -562,22 +567,22 @@ bool MqttCommand(void)
|
||||||
strlcpy(Settings.mqtt_client, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_CLIENT_ID : dataBuf, sizeof(Settings.mqtt_client));
|
strlcpy(Settings.mqtt_client, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_CLIENT_ID : dataBuf, sizeof(Settings.mqtt_client));
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_client);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_client);
|
||||||
}
|
}
|
||||||
else if (CMND_MQTTUSER == command_code) {
|
else if (CMND_MQTTUSER == command_code) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_user))) {
|
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_user))) {
|
||||||
strlcpy(Settings.mqtt_user, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_USER : dataBuf, sizeof(Settings.mqtt_user));
|
strlcpy(Settings.mqtt_user, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_USER : dataBuf, sizeof(Settings.mqtt_user));
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_user);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_user);
|
||||||
}
|
}
|
||||||
else if (CMND_MQTTPASSWORD == command_code) {
|
else if (CMND_MQTTPASSWORD == command_code) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_pwd))) {
|
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_pwd))) {
|
||||||
strlcpy(Settings.mqtt_pwd, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_PASS : dataBuf, sizeof(Settings.mqtt_pwd));
|
strlcpy(Settings.mqtt_pwd, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_PASS : dataBuf, sizeof(Settings.mqtt_pwd));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_pwd);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_pwd);
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_ASTERIX, command);
|
Response_P(S_JSON_COMMAND_ASTERIX, command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_FULLTOPIC == command_code) {
|
else if (CMND_FULLTOPIC == command_code) {
|
||||||
|
@ -586,13 +591,13 @@ bool MqttCommand(void)
|
||||||
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
|
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
|
||||||
strlcpy(stemp1, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1));
|
strlcpy(stemp1, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1));
|
||||||
if (strcmp(stemp1, Settings.mqtt_fulltopic)) {
|
if (strcmp(stemp1, Settings.mqtt_fulltopic)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
|
||||||
strlcpy(Settings.mqtt_fulltopic, stemp1, sizeof(Settings.mqtt_fulltopic));
|
strlcpy(Settings.mqtt_fulltopic, stemp1, sizeof(Settings.mqtt_fulltopic));
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_fulltopic);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_fulltopic);
|
||||||
}
|
}
|
||||||
else if ((CMND_PREFIX == command_code) && (index > 0) && (index <= 3)) {
|
else if ((CMND_PREFIX == command_code) && (index > 0) && (index <= 3)) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_prefix[0]))) {
|
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_prefix[0]))) {
|
||||||
|
@ -601,21 +606,21 @@ bool MqttCommand(void)
|
||||||
// if (Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] == '/') Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] = 0;
|
// if (Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] == '/') Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] = 0;
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mqtt_prefix[index -1]);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mqtt_prefix[index -1]);
|
||||||
}
|
}
|
||||||
else if (CMND_PUBLISH == command_code) {
|
else if (CMND_PUBLISH == command_code) {
|
||||||
if (data_len > 0) {
|
if (data_len > 0) {
|
||||||
char *mqtt_part = strtok(dataBuf, " ");
|
char *mqtt_part = strtok(dataBuf, " ");
|
||||||
if (mqtt_part) {
|
if (mqtt_part) {
|
||||||
strlcpy(stemp1, mqtt_part, sizeof(stemp1));
|
strlcpy(stemp1, mqtt_part, sizeof(stemp1));
|
||||||
mqtt_part = strtok(NULL, " ");
|
mqtt_part = strtok(nullptr, " ");
|
||||||
if (mqtt_part) {
|
if (mqtt_part) {
|
||||||
strlcpy(mqtt_data, mqtt_part, sizeof(mqtt_data));
|
strlcpy(mqtt_data, mqtt_part, sizeof(mqtt_data));
|
||||||
} else {
|
} else {
|
||||||
mqtt_data[0] = '\0';
|
mqtt_data[0] = '\0';
|
||||||
}
|
}
|
||||||
MqttPublishDirect(stemp1, (index == 2));
|
MqttPublishDirect(stemp1, (index == 2));
|
||||||
// snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
// Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
mqtt_data[0] = '\0';
|
mqtt_data[0] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -627,7 +632,7 @@ bool MqttCommand(void)
|
||||||
strlcpy(Settings.mqtt_grptopic, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_GRPTOPIC : dataBuf, sizeof(Settings.mqtt_grptopic));
|
strlcpy(Settings.mqtt_grptopic, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_GRPTOPIC : dataBuf, sizeof(Settings.mqtt_grptopic));
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_grptopic);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_grptopic);
|
||||||
}
|
}
|
||||||
else if (CMND_TOPIC == command_code) {
|
else if (CMND_TOPIC == command_code) {
|
||||||
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.mqtt_topic))) {
|
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.mqtt_topic))) {
|
||||||
|
@ -635,13 +640,13 @@ bool MqttCommand(void)
|
||||||
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
|
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
|
||||||
strlcpy(stemp1, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_TOPIC : dataBuf, sizeof(stemp1));
|
strlcpy(stemp1, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_TOPIC : dataBuf, sizeof(stemp1));
|
||||||
if (strcmp(stemp1, Settings.mqtt_topic)) {
|
if (strcmp(stemp1, Settings.mqtt_topic)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
|
||||||
strlcpy(Settings.mqtt_topic, stemp1, sizeof(Settings.mqtt_topic));
|
strlcpy(Settings.mqtt_topic, stemp1, sizeof(Settings.mqtt_topic));
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_topic);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_topic);
|
||||||
}
|
}
|
||||||
else if (CMND_BUTTONTOPIC == command_code) {
|
else if (CMND_BUTTONTOPIC == command_code) {
|
||||||
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.button_topic))) {
|
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.button_topic))) {
|
||||||
|
@ -654,7 +659,7 @@ bool MqttCommand(void)
|
||||||
default: strlcpy(Settings.button_topic, dataBuf, sizeof(Settings.button_topic));
|
default: strlcpy(Settings.button_topic, dataBuf, sizeof(Settings.button_topic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.button_topic);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.button_topic);
|
||||||
}
|
}
|
||||||
else if (CMND_SWITCHTOPIC == command_code) {
|
else if (CMND_SWITCHTOPIC == command_code) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(Settings.switch_topic))) {
|
if ((data_len > 0) && (data_len < sizeof(Settings.switch_topic))) {
|
||||||
|
@ -667,7 +672,7 @@ bool MqttCommand(void)
|
||||||
default: strlcpy(Settings.switch_topic, dataBuf, sizeof(Settings.switch_topic));
|
default: strlcpy(Settings.switch_topic, dataBuf, sizeof(Settings.switch_topic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.switch_topic);
|
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.switch_topic);
|
||||||
}
|
}
|
||||||
else if (CMND_BUTTONRETAIN == command_code) {
|
else if (CMND_BUTTONRETAIN == command_code) {
|
||||||
if ((payload >= 0) && (payload <= 1)) {
|
if ((payload >= 0) && (payload <= 1)) {
|
||||||
|
@ -678,7 +683,7 @@ bool MqttCommand(void)
|
||||||
}
|
}
|
||||||
Settings.flag.mqtt_button_retain = payload;
|
Settings.flag.mqtt_button_retain = payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_button_retain));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_button_retain));
|
||||||
}
|
}
|
||||||
else if (CMND_SWITCHRETAIN == command_code) {
|
else if (CMND_SWITCHRETAIN == command_code) {
|
||||||
if ((payload >= 0) && (payload <= 1)) {
|
if ((payload >= 0) && (payload <= 1)) {
|
||||||
|
@ -689,7 +694,7 @@ bool MqttCommand(void)
|
||||||
}
|
}
|
||||||
Settings.flag.mqtt_switch_retain = payload;
|
Settings.flag.mqtt_switch_retain = payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_switch_retain));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_switch_retain));
|
||||||
}
|
}
|
||||||
else if (CMND_POWERRETAIN == command_code) {
|
else if (CMND_POWERRETAIN == command_code) {
|
||||||
if ((payload >= 0) && (payload <= 1)) {
|
if ((payload >= 0) && (payload <= 1)) {
|
||||||
|
@ -702,7 +707,7 @@ bool MqttCommand(void)
|
||||||
}
|
}
|
||||||
Settings.flag.mqtt_power_retain = payload;
|
Settings.flag.mqtt_power_retain = payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_power_retain));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_power_retain));
|
||||||
}
|
}
|
||||||
else if (CMND_SENSORRETAIN == command_code) {
|
else if (CMND_SENSORRETAIN == command_code) {
|
||||||
if ((payload >= 0) && (payload <= 1)) {
|
if ((payload >= 0) && (payload <= 1)) {
|
||||||
|
@ -713,7 +718,7 @@ bool MqttCommand(void)
|
||||||
}
|
}
|
||||||
Settings.flag.mqtt_sensor_retain = payload;
|
Settings.flag.mqtt_sensor_retain = payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain));
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
|
@ -742,7 +747,7 @@ const char HTTP_FORM_MQTT1[] PROGMEM =
|
||||||
const char HTTP_FORM_MQTT2[] PROGMEM =
|
const char HTTP_FORM_MQTT2[] PROGMEM =
|
||||||
"<p><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' placeholder='" MQTT_USER "' value='%s'></p>"
|
"<p><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' placeholder='" MQTT_USER "' value='%s'></p>"
|
||||||
"<p><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' type='password' placeholder='" D_PASSWORD "' value='" D_ASTERISK_PWD "'></p>"
|
"<p><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' type='password' placeholder='" D_PASSWORD "' value='" D_ASTERISK_PWD "'></p>"
|
||||||
"<p><b>" D_TOPIC "</b> = %%topic%% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' placeholder='" MQTT_TOPIC "' value='%s'></p>"
|
"<p><b>" D_TOPIC "</b> = %%topic%% (%s)<br/><input id='mt' name='mt' placeholder='%s' value='%s'></p>"
|
||||||
"<p><b>" D_FULL_TOPIC "</b> (%s)<br/><input id='mf' name='mf' placeholder='%s' value='%s'></p>";
|
"<p><b>" D_FULL_TOPIC "</b> (%s)<br/><input id='mf' name='mf' placeholder='%s' value='%s'></p>";
|
||||||
|
|
||||||
void HandleMqttConfiguration(void)
|
void HandleMqttConfiguration(void)
|
||||||
|
@ -764,14 +769,11 @@ void HandleMqttConfiguration(void)
|
||||||
WSContentSend_P(HTTP_FORM_MQTT1,
|
WSContentSend_P(HTTP_FORM_MQTT1,
|
||||||
Settings.mqtt_host,
|
Settings.mqtt_host,
|
||||||
Settings.mqtt_port,
|
Settings.mqtt_port,
|
||||||
Format(str, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client)),
|
Format(str, MQTT_CLIENT_ID, sizeof(str)), MQTT_CLIENT_ID, Settings.mqtt_client);
|
||||||
MQTT_CLIENT_ID,
|
|
||||||
Settings.mqtt_client);
|
|
||||||
WSContentSend_P(HTTP_FORM_MQTT2,
|
WSContentSend_P(HTTP_FORM_MQTT2,
|
||||||
(Settings.mqtt_user[0] == '\0') ? "0" : Settings.mqtt_user,
|
(Settings.mqtt_user[0] == '\0') ? "0" : Settings.mqtt_user,
|
||||||
Settings.mqtt_topic,
|
Format(str, MQTT_TOPIC, sizeof(str)), MQTT_TOPIC, Settings.mqtt_topic,
|
||||||
MQTT_FULLTOPIC, MQTT_FULLTOPIC,
|
MQTT_FULLTOPIC, MQTT_FULLTOPIC, Settings.mqtt_fulltopic);
|
||||||
Settings.mqtt_fulltopic);
|
|
||||||
WSContentSend_P(HTTP_FORM_END);
|
WSContentSend_P(HTTP_FORM_END);
|
||||||
WSContentSpaceButton(BUTTON_CONFIGURATION);
|
WSContentSpaceButton(BUTTON_CONFIGURATION);
|
||||||
WSContentStop();
|
WSContentStop();
|
||||||
|
@ -790,7 +792,7 @@ void MqttSaveSettings(void)
|
||||||
strlcpy(stemp2, (!strlen(tmp)) ? MQTT_FULLTOPIC : tmp, sizeof(stemp2));
|
strlcpy(stemp2, (!strlen(tmp)) ? MQTT_FULLTOPIC : tmp, sizeof(stemp2));
|
||||||
MakeValidMqtt(1,stemp2);
|
MakeValidMqtt(1,stemp2);
|
||||||
if ((strcmp(stemp, Settings.mqtt_topic)) || (strcmp(stemp2, Settings.mqtt_fulltopic))) {
|
if ((strcmp(stemp, Settings.mqtt_topic)) || (strcmp(stemp2, Settings.mqtt_fulltopic))) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
||||||
MqttPublishPrefixTopic_P(TELE, S_LWT, true); // Offline or remove previous retained topic
|
MqttPublishPrefixTopic_P(TELE, S_LWT, true); // Offline or remove previous retained topic
|
||||||
}
|
}
|
||||||
strlcpy(Settings.mqtt_topic, stemp, sizeof(Settings.mqtt_topic));
|
strlcpy(Settings.mqtt_topic, stemp, sizeof(Settings.mqtt_topic));
|
||||||
|
@ -820,6 +822,9 @@ bool Xdrv02(uint8_t function)
|
||||||
|
|
||||||
if (Settings.flag.mqtt_enabled) {
|
if (Settings.flag.mqtt_enabled) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
|
case FUNC_EVERY_50_MSECOND: // https://github.com/knolleary/pubsubclient/issues/556
|
||||||
|
MqttClient.loop();
|
||||||
|
break;
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
case FUNC_WEB_ADD_BUTTON:
|
case FUNC_WEB_ADD_BUTTON:
|
||||||
WSContentSend_P(HTTP_BTN_MENU_MQTT);
|
WSContentSend_P(HTTP_BTN_MENU_MQTT);
|
||||||
|
@ -828,9 +833,6 @@ bool Xdrv02(uint8_t function)
|
||||||
WebServer->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration);
|
WebServer->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration);
|
||||||
break;
|
break;
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
case FUNC_LOOP:
|
|
||||||
if (!global_state.mqtt_down) { MqttLoop(); }
|
|
||||||
break;
|
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = MqttCommand();
|
result = MqttCommand();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -201,34 +201,34 @@ void EnergyMarginCheck(void)
|
||||||
|
|
||||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("NRG: W %d, U %d, I %d"), energy_power_u, energy_voltage_u, energy_current_u);
|
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("NRG: W %d, U %d, I %d"), energy_power_u, energy_voltage_u, energy_current_u);
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
|
Response_P(PSTR("{"));
|
||||||
jsonflg = false;
|
jsonflg = false;
|
||||||
if (EnergyMargin(false, Settings.energy_min_power, energy_power_u, flag, energy_min_power_flag)) {
|
if (EnergyMargin(false, Settings.energy_min_power, energy_power_u, flag, energy_min_power_flag)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_POWERLOW "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
|
ResponseAppend_P(PSTR("%s\"" D_CMND_POWERLOW "\":\"%s\""), (jsonflg)?",":"", GetStateText(flag));
|
||||||
jsonflg = true;
|
jsonflg = true;
|
||||||
}
|
}
|
||||||
if (EnergyMargin(true, Settings.energy_max_power, energy_power_u, flag, energy_max_power_flag)) {
|
if (EnergyMargin(true, Settings.energy_max_power, energy_power_u, flag, energy_max_power_flag)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_POWERHIGH "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
|
ResponseAppend_P(PSTR("%s\"" D_CMND_POWERHIGH "\":\"%s\""), (jsonflg)?",":"", GetStateText(flag));
|
||||||
jsonflg = true;
|
jsonflg = true;
|
||||||
}
|
}
|
||||||
if (EnergyMargin(false, Settings.energy_min_voltage, energy_voltage_u, flag, energy_min_voltage_flag)) {
|
if (EnergyMargin(false, Settings.energy_min_voltage, energy_voltage_u, flag, energy_min_voltage_flag)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_VOLTAGELOW "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
|
ResponseAppend_P(PSTR("%s\"" D_CMND_VOLTAGELOW "\":\"%s\""), (jsonflg)?",":"", GetStateText(flag));
|
||||||
jsonflg = true;
|
jsonflg = true;
|
||||||
}
|
}
|
||||||
if (EnergyMargin(true, Settings.energy_max_voltage, energy_voltage_u, flag, energy_max_voltage_flag)) {
|
if (EnergyMargin(true, Settings.energy_max_voltage, energy_voltage_u, flag, energy_max_voltage_flag)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_VOLTAGEHIGH "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
|
ResponseAppend_P(PSTR("%s\"" D_CMND_VOLTAGEHIGH "\":\"%s\""), (jsonflg)?",":"", GetStateText(flag));
|
||||||
jsonflg = true;
|
jsonflg = true;
|
||||||
}
|
}
|
||||||
if (EnergyMargin(false, Settings.energy_min_current, energy_current_u, flag, energy_min_current_flag)) {
|
if (EnergyMargin(false, Settings.energy_min_current, energy_current_u, flag, energy_min_current_flag)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_CURRENTLOW "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
|
ResponseAppend_P(PSTR("%s%s\"" D_CMND_CURRENTLOW "\":\"%s\""), (jsonflg)?",":"", GetStateText(flag));
|
||||||
jsonflg = true;
|
jsonflg = true;
|
||||||
}
|
}
|
||||||
if (EnergyMargin(true, Settings.energy_max_current, energy_current_u, flag, energy_max_current_flag)) {
|
if (EnergyMargin(true, Settings.energy_max_current, energy_current_u, flag, energy_max_current_flag)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_CURRENTHIGH "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
|
ResponseAppend_P(PSTR("%s%s\"" D_CMND_CURRENTHIGH "\":\"%s\""), (jsonflg)?",":"", GetStateText(flag));
|
||||||
jsonflg = true;
|
jsonflg = true;
|
||||||
}
|
}
|
||||||
if (jsonflg) {
|
if (jsonflg) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_MARGINS), MQTT_TELE_RETAIN);
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_MARGINS), MQTT_TELE_RETAIN);
|
||||||
EnergyMqttShow();
|
EnergyMqttShow();
|
||||||
}
|
}
|
||||||
|
@ -243,7 +243,7 @@ void EnergyMarginCheck(void)
|
||||||
} else {
|
} else {
|
||||||
energy_mplh_counter--;
|
energy_mplh_counter--;
|
||||||
if (!energy_mplh_counter) {
|
if (!energy_mplh_counter) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHED "\":\"%d%s\"}"), energy_power_u, (Settings.flag.value_units) ? " " D_UNIT_WATT : "");
|
Response_P(PSTR("{\"" D_JSON_MAXPOWERREACHED "\":\"%d%s\"}"), energy_power_u, (Settings.flag.value_units) ? " " D_UNIT_WATT : "");
|
||||||
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
||||||
EnergyMqttShow();
|
EnergyMqttShow();
|
||||||
ExecuteCommandPower(1, POWER_OFF, SRC_MAXPOWER);
|
ExecuteCommandPower(1, POWER_OFF, SRC_MAXPOWER);
|
||||||
|
@ -266,11 +266,11 @@ void EnergyMarginCheck(void)
|
||||||
if (energy_mplr_counter) {
|
if (energy_mplr_counter) {
|
||||||
energy_mplr_counter--;
|
energy_mplr_counter--;
|
||||||
if (energy_mplr_counter) {
|
if (energy_mplr_counter) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_POWERMONITOR "\":\"%s\"}"), GetStateText(1));
|
Response_P(PSTR("{\"" D_JSON_POWERMONITOR "\":\"%s\"}"), GetStateText(1));
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_POWERMONITOR));
|
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_POWERMONITOR));
|
||||||
ExecuteCommandPower(1, POWER_ON, SRC_MAXPOWER);
|
ExecuteCommandPower(1, POWER_ON, SRC_MAXPOWER);
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHEDRETRY "\":\"%s\"}"), GetStateText(0));
|
Response_P(PSTR("{\"" D_JSON_MAXPOWERREACHEDRETRY "\":\"%s\"}"), GetStateText(0));
|
||||||
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
||||||
EnergyMqttShow();
|
EnergyMqttShow();
|
||||||
}
|
}
|
||||||
|
@ -284,14 +284,14 @@ void EnergyMarginCheck(void)
|
||||||
energy_daily_u = (uint16_t)(energy_daily * 1000);
|
energy_daily_u = (uint16_t)(energy_daily * 1000);
|
||||||
if (!energy_max_energy_state && (RtcTime.hour == Settings.energy_max_energy_start)) {
|
if (!energy_max_energy_state && (RtcTime.hour == Settings.energy_max_energy_start)) {
|
||||||
energy_max_energy_state = 1;
|
energy_max_energy_state = 1;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_ENERGYMONITOR "\":\"%s\"}"), GetStateText(1));
|
Response_P(PSTR("{\"" D_JSON_ENERGYMONITOR "\":\"%s\"}"), GetStateText(1));
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_ENERGYMONITOR));
|
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_ENERGYMONITOR));
|
||||||
ExecuteCommandPower(1, POWER_ON, SRC_MAXENERGY);
|
ExecuteCommandPower(1, POWER_ON, SRC_MAXENERGY);
|
||||||
}
|
}
|
||||||
else if ((1 == energy_max_energy_state) && (energy_daily_u >= Settings.energy_max_energy)) {
|
else if ((1 == energy_max_energy_state) && (energy_daily_u >= Settings.energy_max_energy)) {
|
||||||
energy_max_energy_state = 2;
|
energy_max_energy_state = 2;
|
||||||
dtostrfd(energy_daily, 3, mqtt_data);
|
dtostrfd(energy_daily, 3, mqtt_data);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXENERGYREACHED "\":\"%s%s\"}"), mqtt_data, (Settings.flag.value_units) ? " " D_UNIT_KILOWATTHOUR : "");
|
Response_P(PSTR("{\"" D_JSON_MAXENERGYREACHED "\":\"%s%s\"}"), mqtt_data, (Settings.flag.value_units) ? " " D_UNIT_KILOWATTHOUR : "");
|
||||||
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
||||||
EnergyMqttShow();
|
EnergyMqttShow();
|
||||||
ExecuteCommandPower(1, POWER_OFF, SRC_MAXENERGY);
|
ExecuteCommandPower(1, POWER_OFF, SRC_MAXENERGY);
|
||||||
|
@ -305,12 +305,12 @@ void EnergyMarginCheck(void)
|
||||||
void EnergyMqttShow(void)
|
void EnergyMqttShow(void)
|
||||||
{
|
{
|
||||||
// {"Time":"2017-12-16T11:48:55","ENERGY":{"Total":0.212,"Yesterday":0.000,"Today":0.014,"Period":2.0,"Power":22.0,"Factor":1.00,"Voltage":213.6,"Current":0.100}}
|
// {"Time":"2017-12-16T11:48:55","ENERGY":{"Total":0.212,"Yesterday":0.000,"Today":0.014,"Period":2.0,"Power":22.0,"Factor":1.00,"Voltage":213.6,"Current":0.100}}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str());
|
Response_P(PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str());
|
||||||
int tele_period_save = tele_period;
|
int tele_period_save = tele_period;
|
||||||
tele_period = 2;
|
tele_period = 2;
|
||||||
EnergyShow(true);
|
EnergyShow(true);
|
||||||
tele_period = tele_period_save;
|
tele_period = tele_period_save;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||||
energy_power_delta = 0;
|
energy_power_delta = 0;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +414,7 @@ bool EnergyCommand(void)
|
||||||
char energy_yesterday_chr[33];
|
char energy_yesterday_chr[33];
|
||||||
dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr);
|
dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr);
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s}}"),
|
Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s}}"),
|
||||||
command, energy_total_chr, energy_yesterday_chr, energy_daily_chr);
|
command, energy_total_chr, energy_yesterday_chr, energy_daily_chr);
|
||||||
status_flag = true;
|
status_flag = true;
|
||||||
}
|
}
|
||||||
|
@ -519,9 +519,9 @@ bool EnergyCommand(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.flag.value_units) {
|
if (Settings.flag.value_units) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE_SPACE_UNIT, command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames));
|
Response_P(S_JSON_COMMAND_LVALUE_SPACE_UNIT, command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames));
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, nvalue);
|
Response_P(S_JSON_COMMAND_LVALUE, command, nvalue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,13 +637,13 @@ void EnergyShow(bool json)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s%s,\"" D_JSON_POWERUSAGE "\":%s"),
|
ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s%s,\"" D_JSON_POWERUSAGE "\":%s"),
|
||||||
mqtt_data, GetDateAndTime(DT_ENERGY).c_str(), energy_total_chr, energy_yesterday_chr, energy_daily_chr, (show_energy_period) ? speriod : "", active_power_chr);
|
GetDateAndTime(DT_ENERGY).c_str(), energy_total_chr, energy_yesterday_chr, energy_daily_chr, (show_energy_period) ? speriod : "", active_power_chr);
|
||||||
if (!energy_type_dc) {
|
if (!energy_type_dc) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_POWERFACTOR "\":%s%s"),
|
ResponseAppend_P(PSTR(",\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_POWERFACTOR "\":%s%s"),
|
||||||
mqtt_data, apparent_power_chr, reactive_power_chr, power_factor_chr, (!isnan(energy_frequency)) ? sfrequency : "");
|
apparent_power_chr, reactive_power_chr, power_factor_chr, (!isnan(energy_frequency)) ? sfrequency : "");
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"), mqtt_data, voltage_chr, current_chr);
|
ResponseAppend_P(PSTR(",\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"), voltage_chr, current_chr);
|
||||||
|
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (show_energy_period) { // Only send if telemetry
|
if (show_energy_period) { // Only send if telemetry
|
||||||
|
@ -689,15 +689,15 @@ bool Xdrv03(uint8_t function)
|
||||||
}
|
}
|
||||||
else if (energy_flg) {
|
else if (energy_flg) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
|
case FUNC_LOOP:
|
||||||
|
XnrgCall(FUNC_LOOP);
|
||||||
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = EnergyCommand();
|
result = EnergyCommand();
|
||||||
break;
|
break;
|
||||||
case FUNC_SET_POWER:
|
case FUNC_SET_POWER:
|
||||||
EnergySetPowerSteadyCounter();
|
EnergySetPowerSteadyCounter();
|
||||||
break;
|
break;
|
||||||
case FUNC_LOOP:
|
|
||||||
XnrgCall(FUNC_LOOP);
|
|
||||||
break;
|
|
||||||
case FUNC_SERIAL:
|
case FUNC_SERIAL:
|
||||||
result = XnrgCall(FUNC_SERIAL);
|
result = XnrgCall(FUNC_SERIAL);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
#define XDRV_04 4
|
#define XDRV_04 4
|
||||||
|
|
||||||
#define WS2812_SCHEMES 7 // Number of additional WS2812 schemes supported by xdrv_ws2812.ino
|
const uint8_t WS2812_SCHEMES = 7; // Number of additional WS2812 schemes supported by xdrv_ws2812.ino
|
||||||
|
|
||||||
enum LightCommands {
|
enum LightCommands {
|
||||||
CMND_COLOR, CMND_COLORTEMPERATURE, CMND_DIMMER, CMND_LED, CMND_LEDTABLE, CMND_FADE,
|
CMND_COLOR, CMND_COLORTEMPERATURE, CMND_DIMMER, CMND_LED, CMND_LEDTABLE, CMND_FADE,
|
||||||
|
@ -70,23 +70,23 @@ const char kLightCommands[] PROGMEM =
|
||||||
struct LRgbColor {
|
struct LRgbColor {
|
||||||
uint8_t R, G, B;
|
uint8_t R, G, B;
|
||||||
};
|
};
|
||||||
#define MAX_FIXED_COLOR 12
|
const uint8_t MAX_FIXED_COLOR = 12;
|
||||||
const LRgbColor kFixedColor[MAX_FIXED_COLOR] PROGMEM =
|
const LRgbColor kFixedColor[MAX_FIXED_COLOR] PROGMEM =
|
||||||
{ 255,0,0, 0,255,0, 0,0,255, 228,32,0, 0,228,32, 0,32,228, 188,64,0, 0,160,96, 160,32,240, 255,255,0, 255,0,170, 255,255,255 };
|
{ 255,0,0, 0,255,0, 0,0,255, 228,32,0, 0,228,32, 0,32,228, 188,64,0, 0,160,96, 160,32,240, 255,255,0, 255,0,170, 255,255,255 };
|
||||||
|
|
||||||
struct LWColor {
|
struct LWColor {
|
||||||
uint8_t W;
|
uint8_t W;
|
||||||
};
|
};
|
||||||
#define MAX_FIXED_WHITE 4
|
const uint8_t MAX_FIXED_WHITE = 4;
|
||||||
const LWColor kFixedWhite[MAX_FIXED_WHITE] PROGMEM = { 0, 255, 128, 32 };
|
const LWColor kFixedWhite[MAX_FIXED_WHITE] PROGMEM = { 0, 255, 128, 32 };
|
||||||
|
|
||||||
struct LCwColor {
|
struct LCwColor {
|
||||||
uint8_t C, W;
|
uint8_t C, W;
|
||||||
};
|
};
|
||||||
#define MAX_FIXED_COLD_WARM 4
|
const uint8_t MAX_FIXED_COLD_WARM = 4;
|
||||||
const LCwColor kFixedColdWarm[MAX_FIXED_COLD_WARM] PROGMEM = { 0,0, 255,0, 0,255, 128,128 };
|
const LCwColor kFixedColdWarm[MAX_FIXED_COLD_WARM] PROGMEM = { 0,0, 255,0, 0,255, 128,128 };
|
||||||
|
|
||||||
uint8_t ledTable[] = {
|
const uint8_t ledTable[] = {
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4,
|
1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4,
|
||||||
|
@ -132,11 +132,11 @@ unsigned long strip_timer_counter = 0; // Bars and Gradient
|
||||||
* Arilux LC11 Rf support stripped from RCSwitch library
|
* Arilux LC11 Rf support stripped from RCSwitch library
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define ARILUX_RF_TIME_AVOID_DUPLICATE 1000 // Milliseconds
|
const uint32_t ARILUX_RF_TIME_AVOID_DUPLICATE = 1000; // Milliseconds
|
||||||
|
|
||||||
#define ARILUX_RF_MAX_CHANGES 51 // Pulses (sync + 2 x 24 bits)
|
const uint8_t ARILUX_RF_MAX_CHANGES = 51; // Pulses (sync + 2 x 24 bits)
|
||||||
#define ARILUX_RF_SEPARATION_LIMIT 4300 // Microseconds
|
const uint32_t ARILUX_RF_SEPARATION_LIMIT = 4300; // Microseconds
|
||||||
#define ARILUX_RF_RECEIVE_TOLERANCE 60 // Percentage
|
const uint32_t ARILUX_RF_RECEIVE_TOLERANCE = 60; // Percentage
|
||||||
|
|
||||||
unsigned int arilux_rf_timings[ARILUX_RF_MAX_CHANGES];
|
unsigned int arilux_rf_timings[ARILUX_RF_MAX_CHANGES];
|
||||||
|
|
||||||
|
@ -740,43 +740,42 @@ void LightState(uint8_t append)
|
||||||
int16_t h,s,b;
|
int16_t h,s,b;
|
||||||
|
|
||||||
if (append) {
|
if (append) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
ResponseAppend_P(PSTR(","));
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
|
Response_P(PSTR("{"));
|
||||||
}
|
}
|
||||||
GetPowerDevice(scommand, light_device, sizeof(scommand), Settings.flag.device_index_enable);
|
GetPowerDevice(scommand, light_device, sizeof(scommand), Settings.flag.device_index_enable);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"),
|
ResponseAppend_P(PSTR("\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"), scommand, GetStateText(light_power), Settings.light_dimmer);
|
||||||
mqtt_data, scommand, GetStateText(light_power), Settings.light_dimmer);
|
|
||||||
if (light_subtype > LST_SINGLE) {
|
if (light_subtype > LST_SINGLE) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor));
|
ResponseAppend_P(PSTR(",\"" D_CMND_COLOR "\":\"%s\""), LightGetColor(0, scolor));
|
||||||
// Add status for HSB
|
// Add status for HSB
|
||||||
LightGetHsb(&hsb[0],&hsb[1],&hsb[2], false);
|
LightGetHsb(&hsb[0],&hsb[1],&hsb[2], false);
|
||||||
// Scale these percentages up to the numbers expected by the client
|
// Scale these percentages up to the numbers expected by the client
|
||||||
h = round(hsb[0] * 360);
|
h = round(hsb[0] * 360);
|
||||||
s = round(hsb[1] * 100);
|
s = round(hsb[1] * 100);
|
||||||
b = round(hsb[2] * 100);
|
b = round(hsb[2] * 100);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_HSBCOLOR "\":\"%d,%d,%d\""), mqtt_data, h,s,b);
|
ResponseAppend_P(PSTR(",\"" D_CMND_HSBCOLOR "\":\"%d,%d,%d\""), h,s,b);
|
||||||
// Add status for each channel
|
// Add status for each channel
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_CHANNEL "\":[" ), mqtt_data);
|
ResponseAppend_P(PSTR(",\"" D_CMND_CHANNEL "\":[" ));
|
||||||
for (uint8_t i = 0; i < light_subtype; i++) {
|
for (uint8_t i = 0; i < light_subtype; i++) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d" ), mqtt_data, (i > 0 ? "," : ""), light_current_color[i] * 100 / 255);
|
ResponseAppend_P(PSTR("%s%d" ), (i > 0 ? "," : ""), light_current_color[i] * 100 / 255);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]" ), mqtt_data);
|
ResponseAppend_P(PSTR("]"));
|
||||||
}
|
}
|
||||||
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLORTEMPERATURE "\":%d"), mqtt_data, LightGetColorTemp());
|
ResponseAppend_P(PSTR(",\"" D_CMND_COLORTEMPERATURE "\":%d"), LightGetColorTemp());
|
||||||
}
|
}
|
||||||
if (append) {
|
if (append) {
|
||||||
if (light_subtype >= LST_RGB) {
|
if (light_subtype >= LST_RGB) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_SCHEME "\":%d"), mqtt_data, Settings.light_scheme);
|
ResponseAppend_P(PSTR(",\"" D_CMND_SCHEME "\":%d"), Settings.light_scheme);
|
||||||
}
|
}
|
||||||
if (LT_WS2812 == light_type) {
|
if (LT_WS2812 == light_type) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_WIDTH "\":%d"), mqtt_data, Settings.light_width);
|
ResponseAppend_P(PSTR(",\"" D_CMND_WIDTH "\":%d"), Settings.light_width);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_FADE "\":\"%s\",\"" D_CMND_SPEED "\":%d,\"" D_CMND_LEDTABLE "\":\"%s\""),
|
ResponseAppend_P(PSTR(",\"" D_CMND_FADE "\":\"%s\",\"" D_CMND_SPEED "\":%d,\"" D_CMND_LEDTABLE "\":\"%s\""),
|
||||||
mqtt_data, GetStateText(Settings.light_fade), Settings.light_speed, GetStateText(Settings.light_correction));
|
GetStateText(Settings.light_fade), Settings.light_speed, GetStateText(Settings.light_correction));
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,7 +948,7 @@ void LightAnimate(void)
|
||||||
light_new_color[i] = light_current_color[i];
|
light_new_color[i] = light_current_color[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WAKEUP "\":\"" D_JSON_DONE "\"}"));
|
Response_P(PSTR("{\"" D_CMND_WAKEUP "\":\"" D_JSON_DONE "\"}"));
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_CMND_WAKEUP));
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_CMND_WAKEUP));
|
||||||
light_wakeup_active = 0;
|
light_wakeup_active = 0;
|
||||||
Settings.light_scheme = LS_POWER;
|
Settings.light_scheme = LS_POWER;
|
||||||
|
@ -1232,9 +1231,9 @@ bool LightColorEntry(char *buffer, uint8_t buffer_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&light_entry_color, 0x00, sizeof(light_entry_color));
|
memset(&light_entry_color, 0x00, sizeof(light_entry_color));
|
||||||
if (strstr(buffer, ",")) { // Decimal entry
|
if (strstr(buffer, ",") != nullptr) { // Decimal entry
|
||||||
int8_t i = 0;
|
int8_t i = 0;
|
||||||
for (str = strtok_r(buffer, ",", &p); str && i < 6; str = strtok_r(NULL, ",", &p)) {
|
for (str = strtok_r(buffer, ",", &p); str && i < 6; str = strtok_r(nullptr, ",", &p)) {
|
||||||
if (i < 5) {
|
if (i < 5) {
|
||||||
light_entry_color[i++] = atoi(str);
|
light_entry_color[i++] = atoi(str);
|
||||||
}
|
}
|
||||||
|
@ -1319,7 +1318,7 @@ bool LightCommand(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!valid_entry && (XdrvMailbox.index <= 2)) {
|
if (!valid_entry && (XdrvMailbox.index <= 2)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, LightGetColor(0, scolor));
|
Response_P(S_JSON_COMMAND_SVALUE, command, LightGetColor(0, scolor));
|
||||||
}
|
}
|
||||||
if (XdrvMailbox.index >= 3) {
|
if (XdrvMailbox.index >= 3) {
|
||||||
scolor[0] = '\0';
|
scolor[0] = '\0';
|
||||||
|
@ -1330,7 +1329,7 @@ bool LightCommand(void)
|
||||||
snprintf_P(scolor, 25, PSTR("%s%02X"), scolor, Settings.ws_color[XdrvMailbox.index -3][i]);
|
snprintf_P(scolor, 25, PSTR("%s%02X"), scolor, Settings.ws_color[XdrvMailbox.index -3][i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((CMND_CHANNEL == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= light_subtype ) ) {
|
else if ((CMND_CHANNEL == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= light_subtype ) ) {
|
||||||
|
@ -1340,22 +1339,22 @@ bool LightCommand(void)
|
||||||
LightSetColor();
|
LightSetColor();
|
||||||
coldim = true;
|
coldim = true;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, light_current_color[XdrvMailbox.index -1] * 100 / 255);
|
Response_P(S_JSON_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, light_current_color[XdrvMailbox.index -1] * 100 / 255);
|
||||||
}
|
}
|
||||||
else if ((CMND_HSBCOLOR == command_code) && ( light_subtype >= LST_RGB)) {
|
else if ((CMND_HSBCOLOR == command_code) && ( light_subtype >= LST_RGB)) {
|
||||||
bool validHSB = (XdrvMailbox.data_len > 0);
|
bool validHSB = (XdrvMailbox.data_len > 0);
|
||||||
if (validHSB) {
|
if (validHSB) {
|
||||||
uint16_t HSB[3];
|
uint16_t HSB[3];
|
||||||
if (strstr(XdrvMailbox.data, ",")) { // Command with 3 comma separated parameters, Hue (0<H<360), Saturation (0<S<100) AND Brightness (0<B<100)
|
if (strstr(XdrvMailbox.data, ",") != nullptr) { // Command with 3 comma separated parameters, Hue (0<H<360), Saturation (0<S<100) AND Brightness (0<B<100)
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
char *substr;
|
char *substr;
|
||||||
|
|
||||||
if (0 == i) {
|
if (0 == i) {
|
||||||
substr = strtok(XdrvMailbox.data, ",");
|
substr = strtok(XdrvMailbox.data, ",");
|
||||||
} else {
|
} else {
|
||||||
substr = strtok(NULL, ",");
|
substr = strtok(nullptr, ",");
|
||||||
}
|
}
|
||||||
if (substr != NULL) {
|
if (substr != nullptr) {
|
||||||
HSB[i] = atoi(substr);
|
HSB[i] = atoi(substr);
|
||||||
} else {
|
} else {
|
||||||
validHSB = false;
|
validHSB = false;
|
||||||
|
@ -1393,7 +1392,7 @@ bool LightCommand(void)
|
||||||
char *p;
|
char *p;
|
||||||
uint16_t idx = XdrvMailbox.index;
|
uint16_t idx = XdrvMailbox.index;
|
||||||
Ws2812ForceSuspend();
|
Ws2812ForceSuspend();
|
||||||
for (char *color = strtok_r(XdrvMailbox.data, " ", &p); color; color = strtok_r(NULL, " ", &p)) {
|
for (char *color = strtok_r(XdrvMailbox.data, " ", &p); color; color = strtok_r(nullptr, " ", &p)) {
|
||||||
if (LightColorEntry(color, strlen(color))) {
|
if (LightColorEntry(color, strlen(color))) {
|
||||||
Ws2812SetColor(idx, light_entry_color[0], light_entry_color[1], light_entry_color[2], light_entry_color[3]);
|
Ws2812SetColor(idx, light_entry_color[0], light_entry_color[1], light_entry_color[2], light_entry_color[3]);
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -1405,7 +1404,7 @@ bool LightCommand(void)
|
||||||
|
|
||||||
Ws2812ForceUpdate();
|
Ws2812ForceUpdate();
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, Ws2812GetColor(XdrvMailbox.index, scolor));
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, Ws2812GetColor(XdrvMailbox.index, scolor));
|
||||||
}
|
}
|
||||||
else if ((CMND_PIXELS == command_code) && (LT_WS2812 == light_type)) {
|
else if ((CMND_PIXELS == command_code) && (LT_WS2812 == light_type)) {
|
||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= WS2812_MAX_LEDS)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= WS2812_MAX_LEDS)) {
|
||||||
|
@ -1414,25 +1413,25 @@ bool LightCommand(void)
|
||||||
Ws2812Clear();
|
Ws2812Clear();
|
||||||
light_update = 1;
|
light_update = 1;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.light_pixels);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.light_pixels);
|
||||||
}
|
}
|
||||||
else if ((CMND_ROTATION == command_code) && (LT_WS2812 == light_type)) {
|
else if ((CMND_ROTATION == command_code) && (LT_WS2812 == light_type)) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < Settings.light_pixels)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < Settings.light_pixels)) {
|
||||||
Settings.light_rotation = XdrvMailbox.payload;
|
Settings.light_rotation = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.light_rotation);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.light_rotation);
|
||||||
}
|
}
|
||||||
else if ((CMND_WIDTH == command_code) && (LT_WS2812 == light_type) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) {
|
else if ((CMND_WIDTH == command_code) && (LT_WS2812 == light_type) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) {
|
||||||
if (1 == XdrvMailbox.index) {
|
if (1 == XdrvMailbox.index) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 4)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 4)) {
|
||||||
Settings.light_width = XdrvMailbox.payload;
|
Settings.light_width = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.light_width);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.light_width);
|
||||||
} else {
|
} else {
|
||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 32)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 32)) {
|
||||||
Settings.ws_width[XdrvMailbox.index -2] = XdrvMailbox.payload;
|
Settings.ws_width[XdrvMailbox.index -2] = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.ws_width[XdrvMailbox.index -2]);
|
Response_P(S_JSON_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.ws_width[XdrvMailbox.index -2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_WS2812 ************************************************************************
|
#endif // USE_WS2812 ************************************************************************
|
||||||
|
@ -1454,7 +1453,7 @@ bool LightCommand(void)
|
||||||
// Publish state message for Hass
|
// Publish state message for Hass
|
||||||
if (Settings.flag3.hass_tele_on_power) { MqttPublishTeleState(); }
|
if (Settings.flag3.hass_tele_on_power) { MqttPublishTeleState(); }
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.light_scheme);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.light_scheme);
|
||||||
}
|
}
|
||||||
else if (CMND_WAKEUP == command_code) {
|
else if (CMND_WAKEUP == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
||||||
|
@ -1463,7 +1462,7 @@ bool LightCommand(void)
|
||||||
light_wakeup_active = 3;
|
light_wakeup_active = 3;
|
||||||
Settings.light_scheme = LS_WAKEUP;
|
Settings.light_scheme = LS_WAKEUP;
|
||||||
LightPowerOn();
|
LightPowerOn();
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_STARTED);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_STARTED);
|
||||||
}
|
}
|
||||||
else if ((CMND_COLORTEMPERATURE == command_code) && ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype))) { // ColorTemp
|
else if ((CMND_COLORTEMPERATURE == command_code) && ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype))) { // ColorTemp
|
||||||
if (option != '\0') {
|
if (option != '\0') {
|
||||||
|
@ -1479,7 +1478,7 @@ bool LightCommand(void)
|
||||||
LightSetColorTemp(XdrvMailbox.payload);
|
LightSetColorTemp(XdrvMailbox.payload);
|
||||||
coldim = true;
|
coldim = true;
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, LightGetColorTemp());
|
Response_P(S_JSON_COMMAND_NVALUE, command, LightGetColorTemp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_DIMMER == command_code) {
|
else if (CMND_DIMMER == command_code) {
|
||||||
|
@ -1494,7 +1493,7 @@ bool LightCommand(void)
|
||||||
light_update = 1;
|
light_update = 1;
|
||||||
coldim = true;
|
coldim = true;
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.light_dimmer);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.light_dimmer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_LEDTABLE == command_code) {
|
else if (CMND_LEDTABLE == command_code) {
|
||||||
|
@ -1510,22 +1509,22 @@ bool LightCommand(void)
|
||||||
}
|
}
|
||||||
light_update = 1;
|
light_update = 1;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.light_correction));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.light_correction));
|
||||||
}
|
}
|
||||||
else if (CMND_RGBWWTABLE == command_code) {
|
else if (CMND_RGBWWTABLE == command_code) {
|
||||||
bool validtable = (XdrvMailbox.data_len > 0);
|
bool validtable = (XdrvMailbox.data_len > 0);
|
||||||
char scolor[25];
|
char scolor[25];
|
||||||
if (validtable) {
|
if (validtable) {
|
||||||
if (strstr(XdrvMailbox.data, ",")) { // Command with up to 5 comma separated parameters
|
if (strstr(XdrvMailbox.data, ",") != nullptr) { // Command with up to 5 comma separated parameters
|
||||||
for (int i = 0; i < LST_RGBWC; i++) {
|
for (int i = 0; i < LST_RGBWC; i++) {
|
||||||
char *substr;
|
char *substr;
|
||||||
|
|
||||||
if (0 == i) {
|
if (0 == i) {
|
||||||
substr = strtok(XdrvMailbox.data, ",");
|
substr = strtok(XdrvMailbox.data, ",");
|
||||||
} else {
|
} else {
|
||||||
substr = strtok(NULL, ",");
|
substr = strtok(nullptr, ",");
|
||||||
}
|
}
|
||||||
if (substr != NULL) {
|
if (substr != nullptr) {
|
||||||
Settings.rgbwwTable[i] = atoi(substr);
|
Settings.rgbwwTable[i] = atoi(substr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1536,7 +1535,7 @@ bool LightCommand(void)
|
||||||
for (uint8_t i = 0; i < LST_RGBWC; i++) {
|
for (uint8_t i = 0; i < LST_RGBWC; i++) {
|
||||||
snprintf_P(scolor, 25, PSTR("%s%s%d"), scolor, (i > 0) ? "," : "", Settings.rgbwwTable[i]);
|
snprintf_P(scolor, 25, PSTR("%s%s%d"), scolor, (i > 0) ? "," : "", Settings.rgbwwTable[i]);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
|
||||||
}
|
}
|
||||||
else if (CMND_FADE == command_code) {
|
else if (CMND_FADE == command_code) {
|
||||||
switch (XdrvMailbox.payload) {
|
switch (XdrvMailbox.payload) {
|
||||||
|
@ -1548,7 +1547,7 @@ bool LightCommand(void)
|
||||||
Settings.light_fade ^= 1;
|
Settings.light_fade ^= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.light_fade));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.light_fade));
|
||||||
}
|
}
|
||||||
else if (CMND_SPEED == command_code) { // 1 - fast, 20 - very slow
|
else if (CMND_SPEED == command_code) { // 1 - fast, 20 - very slow
|
||||||
if (('+' == option) && (Settings.light_speed > 1)) {
|
if (('+' == option) && (Settings.light_speed > 1)) {
|
||||||
|
@ -1560,20 +1559,19 @@ bool LightCommand(void)
|
||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= STATES)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= STATES)) {
|
||||||
Settings.light_speed = XdrvMailbox.payload;
|
Settings.light_speed = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.light_speed);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.light_speed);
|
||||||
}
|
}
|
||||||
else if (CMND_WAKEUPDURATION == command_code) {
|
else if (CMND_WAKEUPDURATION == command_code) {
|
||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 3001)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 3001)) {
|
||||||
Settings.light_wakeup = XdrvMailbox.payload;
|
Settings.light_wakeup = XdrvMailbox.payload;
|
||||||
light_wakeup_active = 0;
|
light_wakeup_active = 0;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.light_wakeup);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.light_wakeup);
|
||||||
}
|
}
|
||||||
else if (CMND_UNDOCA == command_code) { // Theos legacy status
|
else if (CMND_UNDOCA == command_code) { // Theos legacy status
|
||||||
LightGetColor(1, scolor);
|
LightGetColor(1, scolor);
|
||||||
scolor[6] = '\0'; // RGB only
|
scolor[6] = '\0'; // RGB only
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,%d,%d,%d,%d,%d"),
|
Response_P(PSTR("%s,%d,%d,%d,%d,%d"), scolor, Settings.light_fade, Settings.light_correction, Settings.light_scheme, Settings.light_speed, Settings.light_width);
|
||||||
scolor, Settings.light_fade, Settings.light_correction, Settings.light_scheme, Settings.light_speed, Settings.light_width);
|
|
||||||
MqttPublishPrefixTopic_P(STAT, XdrvMailbox.topic);
|
MqttPublishPrefixTopic_P(STAT, XdrvMailbox.topic);
|
||||||
mqtt_data[0] = '\0';
|
mqtt_data[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include <IRremoteESP8266.h>
|
#include <IRremoteESP8266.h>
|
||||||
|
|
||||||
|
enum IrErrors { IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND, IE_SYNTAX_IRHVAC };
|
||||||
|
|
||||||
enum IrRemoteCommands { CMND_IRSEND, CMND_IRHVAC };
|
enum IrRemoteCommands { CMND_IRSEND, CMND_IRHVAC };
|
||||||
const char kIrRemoteCommands[] PROGMEM = D_CMND_IRSEND "|" D_CMND_IRHVAC ;
|
const char kIrRemoteCommands[] PROGMEM = D_CMND_IRSEND "|" D_CMND_IRHVAC ;
|
||||||
|
|
||||||
|
@ -42,19 +44,19 @@ enum IrHvacVendors { VNDR_TOSHIBA, VNDR_MITSUBISHI, VNDR_LG, VNDR_FUJITSU };
|
||||||
const char kIrHvacVendors[] PROGMEM = "Toshiba|Mitsubishi|LG|Fujitsu" ;
|
const char kIrHvacVendors[] PROGMEM = "Toshiba|Mitsubishi|LG|Fujitsu" ;
|
||||||
|
|
||||||
// HVAC TOSHIBA_
|
// HVAC TOSHIBA_
|
||||||
#define HVAC_TOSHIBA_HDR_MARK 4400
|
const uint16_t HVAC_TOSHIBA_HDR_MARK = 4400;
|
||||||
#define HVAC_TOSHIBA_HDR_SPACE 4300
|
const uint16_t HVAC_TOSHIBA_HDR_SPACE = 4300;
|
||||||
#define HVAC_TOSHIBA_BIT_MARK 543
|
const uint16_t HVAC_TOSHIBA_BIT_MARK = 543;
|
||||||
#define HVAC_TOSHIBA_ONE_SPACE 1623
|
const uint16_t HVAC_TOSHIBA_ONE_SPACE = 1623;
|
||||||
#define HVAC_MISTUBISHI_ZERO_SPACE 472
|
const uint16_t HVAC_MISTUBISHI_ZERO_SPACE = 472;
|
||||||
#define HVAC_TOSHIBA_RPT_MARK 440
|
const uint16_t HVAC_TOSHIBA_RPT_MARK = 440;
|
||||||
#define HVAC_TOSHIBA_RPT_SPACE 7048 // Above original iremote limit
|
const uint16_t HVAC_TOSHIBA_RPT_SPACE = 7048; // Above original iremote limit
|
||||||
#define HVAC_TOSHIBA_DATALEN 9
|
const uint8_t HVAC_TOSHIBA_DATALEN = 9;
|
||||||
|
|
||||||
// HVAC LG
|
// HVAC LG
|
||||||
#define HVAC_LG_DATALEN 7
|
const uint8_t HVAC_LG_DATALEN = 7;
|
||||||
|
|
||||||
IRMitsubishiAC *mitsubir = NULL;
|
IRMitsubishiAC *mitsubir = nullptr;
|
||||||
|
|
||||||
const char kFanSpeedOptions[] = "A12345S";
|
const char kFanSpeedOptions[] = "A12345S";
|
||||||
const char kHvacModeOptions[] = "HDCA";
|
const char kHvacModeOptions[] = "HDCA";
|
||||||
|
@ -66,7 +68,7 @@ const char kHvacModeOptions[] = "HDCA";
|
||||||
|
|
||||||
#include <IRsend.h>
|
#include <IRsend.h>
|
||||||
|
|
||||||
IRsend *irsend = NULL;
|
IRsend *irsend = nullptr;
|
||||||
bool irsend_active = false;
|
bool irsend_active = false;
|
||||||
|
|
||||||
void IrSendInit(void)
|
void IrSendInit(void)
|
||||||
|
@ -79,18 +81,38 @@ void IrSendInit(void)
|
||||||
#endif //USE_IR_HVAC
|
#endif //USE_IR_HVAC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* IrUint64toHex(uint64_t value, char *str, uint16_t bits)
|
||||||
|
{
|
||||||
|
ulltoa(value, str, 16); // Get 64bit value
|
||||||
|
|
||||||
|
int fill = 8;
|
||||||
|
if ((bits > 3) && (bits < 65)) {
|
||||||
|
fill = bits / 4; // Max 16
|
||||||
|
if (bits % 4) { fill++; }
|
||||||
|
}
|
||||||
|
int len = strlen(str);
|
||||||
|
fill -= len;
|
||||||
|
if (fill > 0) {
|
||||||
|
memmove(str + fill, str, len +1);
|
||||||
|
memset(str, '0', fill);
|
||||||
|
}
|
||||||
|
memmove(str + 2, str, strlen(str) +1);
|
||||||
|
str[0] = '0';
|
||||||
|
str[1] = 'x';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_IR_RECEIVE
|
#ifdef USE_IR_RECEIVE
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* IR Receive
|
* IR Receive
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define IR_RCV_SAVE_BUFFER 0 // 0 = do not use buffer, 1 = use buffer for decoding
|
const bool IR_RCV_SAVE_BUFFER = false; // false = do not use buffer, true = use buffer for decoding
|
||||||
|
const uint32_t IR_TIME_AVOID_DUPLICATE = 500; // Milliseconds
|
||||||
#define IR_TIME_AVOID_DUPLICATE 500 // Milliseconds
|
|
||||||
|
|
||||||
#include <IRrecv.h>
|
#include <IRrecv.h>
|
||||||
|
|
||||||
IRrecv *irrecv = NULL;
|
IRrecv *irrecv = nullptr;
|
||||||
|
|
||||||
unsigned long ir_lasttime = 0;
|
unsigned long ir_lasttime = 0;
|
||||||
|
|
||||||
|
@ -107,15 +129,16 @@ void IrReceiveInit(void)
|
||||||
void IrReceiveCheck(void)
|
void IrReceiveCheck(void)
|
||||||
{
|
{
|
||||||
char sirtype[14]; // Max is AIWA_RC_T501
|
char sirtype[14]; // Max is AIWA_RC_T501
|
||||||
char stemp[16];
|
|
||||||
int8_t iridx = 0;
|
int8_t iridx = 0;
|
||||||
|
|
||||||
decode_results results;
|
decode_results results;
|
||||||
|
|
||||||
if (irrecv->decode(&results)) {
|
if (irrecv->decode(&results)) {
|
||||||
|
char hvalue[64];
|
||||||
|
IrUint64toHex(results.value, hvalue, results.bits); // Get 64bit value as hex 0x00123456
|
||||||
|
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_IRR "Echo %d, RawLen %d, Overflow %d, Bits %d, Value 0x%08X, Decode %d"),
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_IRR "Echo %d, RawLen %d, Overflow %d, Bits %d, Value %s, Decode %d"),
|
||||||
irsend_active, results.rawlen, results.overflow, results.bits, results.value, results.decode_type);
|
irsend_active, results.rawlen, results.overflow, results.bits, hvalue, results.decode_type);
|
||||||
|
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
// if ((now - ir_lasttime > IR_TIME_AVOID_DUPLICATE) && (UNKNOWN != results.decode_type) && (results.bits > 0)) {
|
// if ((now - ir_lasttime > IR_TIME_AVOID_DUPLICATE) && (UNKNOWN != results.decode_type) && (results.bits > 0)) {
|
||||||
|
@ -123,27 +146,26 @@ void IrReceiveCheck(void)
|
||||||
ir_lasttime = now;
|
ir_lasttime = now;
|
||||||
|
|
||||||
iridx = results.decode_type;
|
iridx = results.decode_type;
|
||||||
if ((iridx < 0) || (iridx > 14)) {
|
if ((iridx < 0) || (iridx > 14)) { iridx = 0; } // UNKNOWN
|
||||||
iridx = 0; // UNKNOWN
|
char svalue[64];
|
||||||
}
|
|
||||||
if (Settings.flag.ir_receive_decimal) {
|
if (Settings.flag.ir_receive_decimal) {
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("%u"), (uint32_t)results.value);
|
ulltoa(results.value, svalue, 10);
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("\"0x%lX\""), (uint32_t)results.value);
|
snprintf_P(svalue, sizeof(svalue), PSTR("\"%s\""), hvalue);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_IRRECEIVED "\":{\"" D_JSON_IR_PROTOCOL "\":\"%s\",\"" D_JSON_IR_BITS "\":%d,\"" D_JSON_IR_DATA "\":%s"),
|
Response_P(PSTR("{\"" D_JSON_IRRECEIVED "\":{\"" D_JSON_IR_PROTOCOL "\":\"%s\",\"" D_JSON_IR_BITS "\":%d,\"" D_JSON_IR_DATA "\":%s"),
|
||||||
GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, stemp);
|
GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, svalue);
|
||||||
|
|
||||||
if (Settings.flag3.receive_raw) {
|
if (Settings.flag3.receive_raw) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_IR_RAWDATA "\":["), mqtt_data);
|
ResponseAppend_P(PSTR(",\"" D_JSON_IR_RAWDATA "\":["));
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
for (i = 1; i < results.rawlen; i++) {
|
for (i = 1; i < results.rawlen; i++) {
|
||||||
if (i > 1) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data); }
|
if (i > 1) { ResponseAppend_P(PSTR(",")); }
|
||||||
uint32_t usecs;
|
uint32_t usecs;
|
||||||
for (usecs = results.rawbuf[i] * kRawTick; usecs > UINT16_MAX; usecs -= UINT16_MAX) {
|
for (usecs = results.rawbuf[i] * kRawTick; usecs > UINT16_MAX; usecs -= UINT16_MAX) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%d,0,"), mqtt_data, UINT16_MAX);
|
ResponseAppend_P(PSTR("%d,0,"), UINT16_MAX);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%d"), mqtt_data, usecs);
|
ResponseAppend_P(PSTR("%d"), usecs);
|
||||||
if (strlen(mqtt_data) > sizeof(mqtt_data) - 40) { break; } // Quit if char string becomes too long
|
if (strlen(mqtt_data) > sizeof(mqtt_data) - 40) { break; } // Quit if char string becomes too long
|
||||||
}
|
}
|
||||||
uint16_t extended_length = results.rawlen - 1;
|
uint16_t extended_length = results.rawlen - 1;
|
||||||
|
@ -152,10 +174,10 @@ void IrReceiveCheck(void)
|
||||||
// Add two extra entries for multiple larger than UINT16_MAX it is.
|
// Add two extra entries for multiple larger than UINT16_MAX it is.
|
||||||
extended_length += (usecs / (UINT16_MAX + 1)) * 2;
|
extended_length += (usecs / (UINT16_MAX + 1)) * 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_IR_RAWDATA "Info\":[%d,%d,%d]"), mqtt_data, extended_length, i -1, results.overflow);
|
ResponseAppend_P(PSTR("],\"" D_JSON_IR_RAWDATA "Info\":[%d,%d,%d]"), extended_length, i -1, results.overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}}"), mqtt_data);
|
ResponseAppend_P(PSTR("}}"));
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED));
|
||||||
|
|
||||||
if (iridx) {
|
if (iridx) {
|
||||||
|
@ -181,7 +203,7 @@ void IrReceiveCheck(void)
|
||||||
TOSHIBA
|
TOSHIBA
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
uint8_t IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||||
{
|
{
|
||||||
uint16_t rawdata[2 + 2 * 8 * HVAC_TOSHIBA_DATALEN + 2];
|
uint16_t rawdata[2 + 2 * 8 * HVAC_TOSHIBA_DATALEN + 2];
|
||||||
uint8_t data[HVAC_TOSHIBA_DATALEN] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00};
|
uint8_t data[HVAC_TOSHIBA_DATALEN] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
@ -189,14 +211,14 @@ bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
|
||||||
char *p;
|
char *p;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
|
|
||||||
if (HVAC_Mode == NULL) {
|
if (HVAC_Mode == nullptr) {
|
||||||
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
||||||
}
|
}
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return true;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
data[6] = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
|
data[6] = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
|
||||||
|
|
||||||
|
@ -204,14 +226,14 @@ bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
|
||||||
data[6] = (uint8_t)0x07; // Turn OFF HVAC
|
data[6] = (uint8_t)0x07; // Turn OFF HVAC
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HVAC_FanMode == NULL) {
|
if (HVAC_FanMode == nullptr) {
|
||||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
||||||
}
|
}
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return true;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
mode = p - kFanSpeedOptions + 1;
|
mode = p - kFanSpeedOptions + 1;
|
||||||
if ((1 == mode) || (7 == mode)) {
|
if ((1 == mode) || (7 == mode)) {
|
||||||
|
@ -268,7 +290,7 @@ bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
|
||||||
irsend->sendRaw(rawdata, i, 38);
|
irsend->sendRaw(rawdata, i, 38);
|
||||||
// interrupts();
|
// interrupts();
|
||||||
|
|
||||||
return false;
|
return IE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,35 +298,35 @@ bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
|
||||||
MITSUBISHI
|
MITSUBISHI
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
bool IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
|
|
||||||
mitsubir->stateReset();
|
mitsubir->stateReset();
|
||||||
|
|
||||||
if (HVAC_Mode == NULL) {
|
if (HVAC_Mode == nullptr) {
|
||||||
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
||||||
}
|
}
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return true;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
mode = (p - kHvacModeOptions + 1) << 3; // HOT = 0x08, DRY = 0x10, COOL = 0x18, AUTO = 0x20
|
mode = (p - kHvacModeOptions + 1) << 3; // HOT = 0x08, DRY = 0x10, COOL = 0x18, AUTO = 0x20
|
||||||
mitsubir->setMode(mode);
|
mitsubir->setMode(mode);
|
||||||
|
|
||||||
mitsubir->setPower(HVAC_Power);
|
mitsubir->setPower(HVAC_Power);
|
||||||
|
|
||||||
if (HVAC_FanMode == NULL) {
|
if (HVAC_FanMode == nullptr) {
|
||||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
||||||
}
|
}
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return true;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
mode = p - kFanSpeedOptions; // AUTO = 0, SPEED = 1 .. 5, SILENT = 6
|
mode = p - kFanSpeedOptions; // AUTO = 0, SPEED = 1 .. 5, SILENT = 6
|
||||||
mitsubir->setFan(mode);
|
mitsubir->setFan(mode);
|
||||||
|
@ -316,7 +338,7 @@ bool IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
|
||||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"),
|
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"),
|
||||||
// mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane());
|
// mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane());
|
||||||
|
|
||||||
return false;
|
return IE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,7 +346,7 @@ bool IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
|
||||||
LG
|
LG
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
uint8_t IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||||
{
|
{
|
||||||
uint32_t LG_Code;
|
uint32_t LG_Code;
|
||||||
uint8_t data[HVAC_LG_DATALEN];
|
uint8_t data[HVAC_LG_DATALEN];
|
||||||
|
@ -350,14 +372,14 @@ bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power,
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// Set code for HVAC Mode - data[3]
|
// Set code for HVAC Mode - data[3]
|
||||||
if (HVAC_Mode == NULL) {
|
if (HVAC_Mode == nullptr) {
|
||||||
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
||||||
}
|
}
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return true;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
mode = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
|
mode = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
@ -394,14 +416,14 @@ bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power,
|
||||||
data[4] = (uint8_t)(Temp - 15);
|
data[4] = (uint8_t)(Temp - 15);
|
||||||
|
|
||||||
// Set code for HVAC fan mode - data[5]
|
// Set code for HVAC fan mode - data[5]
|
||||||
if (HVAC_FanMode == NULL) {
|
if (HVAC_FanMode == nullptr) {
|
||||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
||||||
}
|
}
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return true;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
mode = p - kFanSpeedOptions;
|
mode = p - kFanSpeedOptions;
|
||||||
if ((mode == 0) || (mode > 3)) {
|
if ((mode == 0) || (mode > 3)) {
|
||||||
|
@ -432,7 +454,7 @@ bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power,
|
||||||
irsend->sendLG(LG_Code, 28);
|
irsend->sendLG(LG_Code, 28);
|
||||||
// interrupts();
|
// interrupts();
|
||||||
|
|
||||||
return false;
|
return IE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -440,7 +462,7 @@ bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power,
|
||||||
Fujitsu
|
Fujitsu
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
bool IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
uint8_t IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||||
{
|
{
|
||||||
const char kFujitsuHvacModeOptions[] = "HDCAF";
|
const char kFujitsuHvacModeOptions[] = "HDCAF";
|
||||||
|
|
||||||
|
@ -453,7 +475,7 @@ bool IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
|
||||||
if (0 == HVAC_Power) {
|
if (0 == HVAC_Power) {
|
||||||
ac.off();
|
ac.off();
|
||||||
ac.send();
|
ac.send();
|
||||||
return false;
|
return IE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t modes[5] = {FUJITSU_AC_MODE_HEAT, FUJITSU_AC_MODE_DRY, FUJITSU_AC_MODE_COOL, FUJITSU_AC_MODE_AUTO, FUJITSU_AC_MODE_FAN};
|
uint8_t modes[5] = {FUJITSU_AC_MODE_HEAT, FUJITSU_AC_MODE_DRY, FUJITSU_AC_MODE_COOL, FUJITSU_AC_MODE_AUTO, FUJITSU_AC_MODE_FAN};
|
||||||
|
@ -462,32 +484,32 @@ bool IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
|
||||||
ac.setSwing(FUJITSU_AC_SWING_VERT);
|
ac.setSwing(FUJITSU_AC_SWING_VERT);
|
||||||
|
|
||||||
char *p;
|
char *p;
|
||||||
if (NULL == HVAC_Mode) {
|
if (nullptr == HVAC_Mode) {
|
||||||
p = (char *)kFujitsuHvacModeOptions;
|
p = (char *)kFujitsuHvacModeOptions;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = strchr(kFujitsuHvacModeOptions, toupper(HVAC_Mode[0]));
|
p = strchr(kFujitsuHvacModeOptions, toupper(HVAC_Mode[0]));
|
||||||
}
|
}
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return true;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
ac.setMode(modes[p - kFujitsuHvacModeOptions]);
|
ac.setMode(modes[p - kFujitsuHvacModeOptions]);
|
||||||
|
|
||||||
if (HVAC_FanMode == NULL) {
|
if (HVAC_FanMode == nullptr) {
|
||||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
||||||
}
|
}
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return true;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
ac.setFanSpeed(fanModes[p - kFanSpeedOptions]);
|
ac.setFanSpeed(fanModes[p - kFanSpeedOptions]);
|
||||||
|
|
||||||
ac.setTemp(HVAC_Temp);
|
ac.setTemp(HVAC_Temp);
|
||||||
ac.send();
|
ac.send();
|
||||||
|
|
||||||
return false;
|
return IE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_IR_HVAC
|
#endif // USE_IR_HVAC
|
||||||
|
@ -499,6 +521,7 @@ bool IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
|
||||||
/*
|
/*
|
||||||
* ArduinoJSON entry used to calculate jsonBuf: JSON_OBJECT_SIZE(3) + 40 = 96
|
* ArduinoJSON entry used to calculate jsonBuf: JSON_OBJECT_SIZE(3) + 40 = 96
|
||||||
IRsend:
|
IRsend:
|
||||||
|
{ "protocol": "RC5", "bits": 12, "data":"0xC86" }
|
||||||
{ "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
|
{ "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
|
||||||
IRhvac:
|
IRhvac:
|
||||||
{ "Vendor": "<Toshiba|Mitsubishi>", "Power": <0|1>, "Mode": "<Hot|Cold|Dry|Auto>", "FanSpeed": "<1|2|3|4|5|Auto|Silence>", "Temp": <17..30> }
|
{ "Vendor": "<Toshiba|Mitsubishi>", "Power": <0|1>, "Mode": "<Hot|Cold|Dry|Auto>", "FanSpeed": "<1|2|3|4|5|Auto|Silence>", "Temp": <17..30> }
|
||||||
|
@ -508,7 +531,7 @@ bool IrSendCommand(void)
|
||||||
{
|
{
|
||||||
char command [CMDSZ];
|
char command [CMDSZ];
|
||||||
bool serviced = true;
|
bool serviced = true;
|
||||||
bool error = false;
|
uint8_t error = IE_NO_ERROR;
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kIrRemoteCommands);
|
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kIrRemoteCommands);
|
||||||
if (-1 == command_code) {
|
if (-1 == command_code) {
|
||||||
|
@ -516,57 +539,134 @@ bool IrSendCommand(void)
|
||||||
}
|
}
|
||||||
else if (CMND_IRSEND == command_code) {
|
else if (CMND_IRSEND == command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
|
|
||||||
if (!strstr(XdrvMailbox.data, "{")) { // If no JSON it must be rawdata
|
if (strstr(XdrvMailbox.data, "{") == nullptr) { // If no JSON it must be rawdata
|
||||||
// IRSend frequency, rawdata, rawdata ...
|
// IRsend <freq>,<rawdata>,<rawdata> ...
|
||||||
|
// or
|
||||||
|
// IRsend raw,<freq>,<zero space>,<bit stream> (one space = zero space *2)
|
||||||
|
// IRsend raw,<freq>,<zero space>,<zero space multiplier becoming one space>,<bit stream>
|
||||||
|
// IRsend raw,<freq>,<zero space>,<one space>,<bit stream>
|
||||||
|
// IRsend raw,<freq>,<header mark>,<header space>,<bit mark>,<zero space>,<one space>,<bit stream>
|
||||||
char *p;
|
char *p;
|
||||||
char *str = strtok_r(XdrvMailbox.data, ", ", &p);
|
char *str = strtok_r(XdrvMailbox.data, ", ", &p);
|
||||||
|
if (p == nullptr) {
|
||||||
|
error = IE_INVALID_RAWDATA;
|
||||||
|
} else {
|
||||||
uint16_t freq = atoi(str);
|
uint16_t freq = atoi(str);
|
||||||
|
if (!freq && (*str != '0')) { // First parameter is any string
|
||||||
|
uint16_t count = 0;
|
||||||
|
char *q = p;
|
||||||
|
for (; *q; count += (*q++ == ','));
|
||||||
|
if (count < 2) { // Parameters must be at least 3
|
||||||
|
error = IE_INVALID_RAWDATA;
|
||||||
|
} else {
|
||||||
|
uint16_t parm[count];
|
||||||
|
for (uint8_t i = 0; i < count; i++) {
|
||||||
|
parm[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0);
|
||||||
|
if (!parm[i]) {
|
||||||
|
if (!i) {
|
||||||
|
parm[0] = 38000; // Frequency default to 38kHz
|
||||||
|
} else {
|
||||||
|
error = IE_INVALID_RAWDATA; // Other parameters may not be 0
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IE_NO_ERROR == error) {
|
||||||
|
uint16_t i = 0;
|
||||||
|
if (count < 4) {
|
||||||
|
// IRsend raw,0,889,000000100110000001001
|
||||||
|
uint16_t mark = parm[1] *2; // Protocol where 0 = t, 1 = 2t (RC5)
|
||||||
|
if (3 == count) {
|
||||||
|
if (parm[2] < parm[1]) {
|
||||||
|
// IRsend raw,0,889,2,000000100110000001001
|
||||||
|
mark = parm[1] * parm[2]; // Protocol where 0 = t1, 1 = t1*t2 (Could be RC5)
|
||||||
|
} else {
|
||||||
|
// IRsend raw,0,889,1778,000000100110000001001
|
||||||
|
mark = parm[2]; // Protocol where 0 = t1, 1 = t2 (Could be RC5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint16_t raw_array[strlen(p)]; // Bits
|
||||||
|
for (; *p; *p++) {
|
||||||
|
if (*p == '0') {
|
||||||
|
raw_array[i++] = parm[1]; // Space
|
||||||
|
}
|
||||||
|
else if (*p == '1') {
|
||||||
|
raw_array[i++] = mark; // Mark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
irsend_active = true;
|
||||||
|
irsend->sendRaw(raw_array, i, parm[0]);
|
||||||
|
}
|
||||||
|
else if (6 == count) { // NEC Protocol
|
||||||
|
// IRsend raw,0,8620,4260,544,411,1496,010101101000111011001110000000001100110000000001100000000000000010001100
|
||||||
|
uint16_t raw_array[strlen(p)*2+3]; // Header + bits + end
|
||||||
|
raw_array[i++] = parm[1]; // Header mark
|
||||||
|
raw_array[i++] = parm[2]; // Header space
|
||||||
|
for (; *p; *p++) {
|
||||||
|
if (*p == '0') {
|
||||||
|
raw_array[i++] = parm[3]; // Bit mark
|
||||||
|
raw_array[i++] = parm[4]; // Zero space
|
||||||
|
}
|
||||||
|
else if (*p == '1') {
|
||||||
|
raw_array[i++] = parm[3]; // Bit mark
|
||||||
|
raw_array[i++] = parm[5]; // One space
|
||||||
|
}
|
||||||
|
}
|
||||||
|
raw_array[i++] = parm[3]; // Trailing mark
|
||||||
|
irsend_active = true;
|
||||||
|
irsend->sendRaw(raw_array, i, parm[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error = IE_INVALID_RAWDATA; // Invalid number of parameters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (!freq) { freq = 38000; } // Default to 38kHz
|
if (!freq) { freq = 38000; } // Default to 38kHz
|
||||||
uint16_t count = 0;
|
uint16_t count = 0;
|
||||||
char *q = p;
|
char *q = p;
|
||||||
for (; *q; count += (*q++ == ','));
|
for (; *q; count += (*q++ == ','));
|
||||||
if (count) { // At least two raw data values
|
if (0 == count) {
|
||||||
|
error = IE_INVALID_RAWDATA;
|
||||||
|
} else { // At least two raw data values
|
||||||
|
// IRsend 0,896,876,900,888,894,876,1790,874,872,1810,1736,948,872,880,872,936,872,1792,900,888,1734
|
||||||
count++;
|
count++;
|
||||||
uint16_t raw_array[count]; // It's safe to use stack for up to 240 packets (limited by mqtt_data length)
|
uint16_t raw_array[count]; // It's safe to use stack for up to 240 packets (limited by mqtt_data length)
|
||||||
uint8_t i = 0;
|
for (uint16_t i = 0; i < count; i++) {
|
||||||
for (str = strtok_r(NULL, ", ", &p); str && i < count; str = strtok_r(NULL, ", ", &p)) {
|
raw_array[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); // Allow decimal (20496) and hexadecimal (0x5010) input
|
||||||
raw_array[i++] = strtoul(str, NULL, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRS: Count %d, Freq %d, Arr[0] %d, Arr[count -1] %d"), count, freq, raw_array[0], raw_array[count -1]);
|
|
||||||
|
|
||||||
irsend_active = true;
|
irsend_active = true;
|
||||||
irsend->sendRaw(raw_array, count, freq);
|
irsend->sendRaw(raw_array, count, freq);
|
||||||
if (!count) {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_FAILED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_RAWDATA);
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
char dataBufUc[XdrvMailbox.data_len];
|
char dataBufUc[XdrvMailbox.data_len];
|
||||||
UpperCase(dataBufUc, XdrvMailbox.data);
|
UpperCase(dataBufUc, XdrvMailbox.data);
|
||||||
|
RemoveSpace(dataBufUc);
|
||||||
|
if (strlen(dataBufUc) < 8) {
|
||||||
|
error = IE_INVALID_JSON;
|
||||||
|
} else {
|
||||||
StaticJsonBuffer<128> jsonBuf;
|
StaticJsonBuffer<128> jsonBuf;
|
||||||
JsonObject &root = jsonBuf.parseObject(dataBufUc);
|
JsonObject &root = jsonBuf.parseObject(dataBufUc);
|
||||||
if (!root.success()) {
|
if (!root.success()) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON);
|
error = IE_INVALID_JSON;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
|
// IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
|
||||||
char parm_uc[10];
|
char parm_uc[10];
|
||||||
const char *protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_PROTOCOL))];
|
const char *protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_PROTOCOL))];
|
||||||
uint32_t bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_BITS))];
|
uint16_t bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_BITS))];
|
||||||
uint32_t data = strtoul(root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_DATA))], NULL, 0);
|
uint64_t data = strtoull(root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_DATA))], nullptr, 0);
|
||||||
if (protocol && bits) {
|
if (protocol && bits) {
|
||||||
char protocol_text[20];
|
char protocol_text[20];
|
||||||
int protocol_code = GetCommandCode(protocol_text, sizeof(protocol_text), protocol, kIrRemoteProtocols);
|
int protocol_code = GetCommandCode(protocol_text, sizeof(protocol_text), protocol, kIrRemoteProtocols);
|
||||||
|
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %u (0x%lX), protocol_code %d"),
|
char dvalue[64];
|
||||||
protocol_text, protocol, bits, data, data, protocol_code);
|
char hvalue[64];
|
||||||
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %s (%s), protocol_code %d"),
|
||||||
|
protocol_text, protocol, bits, ulltoa(data, dvalue, 10), IrUint64toHex(data, hvalue, bits), protocol_code);
|
||||||
|
|
||||||
irsend_active = true;
|
irsend_active = true;
|
||||||
switch (protocol_code) {
|
switch (protocol_code) {
|
||||||
|
@ -585,23 +685,20 @@ bool IrSendCommand(void)
|
||||||
case SAMSUNG:
|
case SAMSUNG:
|
||||||
irsend->sendSAMSUNG(data, (bits > SAMSUNG_BITS) ? SAMSUNG_BITS : bits); break;
|
irsend->sendSAMSUNG(data, (bits > SAMSUNG_BITS) ? SAMSUNG_BITS : bits); break;
|
||||||
case PANASONIC:
|
case PANASONIC:
|
||||||
irsend->sendPanasonic(bits, data); break;
|
// irsend->sendPanasonic(bits, data); break;
|
||||||
|
irsend->sendPanasonic64(data, bits); break;
|
||||||
default:
|
default:
|
||||||
irsend_active = false;
|
irsend_active = false;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_PROTOCOL_NOT_SUPPORTED);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_PROTOCOL_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
error = IE_SYNTAX_IRSEND;
|
||||||
error = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
error = true;
|
error = IE_SYNTAX_IRSEND;
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_NO " " D_JSON_IR_PROTOCOL ", " D_JSON_IR_BITS " " D_JSON_OR " " D_JSON_IR_DATA "\"}"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef USE_IR_HVAC
|
#ifdef USE_IR_HVAC
|
||||||
|
@ -615,13 +712,16 @@ bool IrSendCommand(void)
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
char dataBufUc[XdrvMailbox.data_len];
|
char dataBufUc[XdrvMailbox.data_len];
|
||||||
UpperCase(dataBufUc, XdrvMailbox.data);
|
UpperCase(dataBufUc, XdrvMailbox.data);
|
||||||
|
RemoveSpace(dataBufUc);
|
||||||
|
if (strlen(dataBufUc) < 8) {
|
||||||
|
error = IE_INVALID_JSON;
|
||||||
|
} else {
|
||||||
StaticJsonBuffer<164> jsonBufer;
|
StaticJsonBuffer<164> jsonBufer;
|
||||||
JsonObject &root = jsonBufer.parseObject(dataBufUc);
|
JsonObject &root = jsonBufer.parseObject(dataBufUc);
|
||||||
if (!root.success()) {
|
if (!root.success()) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON);
|
error = IE_INVALID_JSON;
|
||||||
}
|
} else {
|
||||||
else {
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
|
||||||
HVAC_Vendor = root[D_JSON_IRHVAC_VENDOR];
|
HVAC_Vendor = root[D_JSON_IRHVAC_VENDOR];
|
||||||
HVAC_Power = root[D_JSON_IRHVAC_POWER];
|
HVAC_Power = root[D_JSON_IRHVAC_POWER];
|
||||||
HVAC_Mode = root[D_JSON_IRHVAC_MODE];
|
HVAC_Mode = root[D_JSON_IRHVAC_MODE];
|
||||||
|
@ -642,20 +742,35 @@ bool IrSendCommand(void)
|
||||||
case VNDR_FUJITSU:
|
case VNDR_FUJITSU:
|
||||||
error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
|
error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
|
||||||
default:
|
default:
|
||||||
error = true;
|
error = IE_SYNTAX_IRHVAC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error = true;
|
error = IE_SYNTAX_IRHVAC;
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRHVAC "\":\"" D_JSON_WRONG " " D_JSON_IRHVAC_VENDOR ", " D_JSON_IRHVAC_MODE " " D_JSON_OR " " D_JSON_IRHVAC_FANSPEED "\"}"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_IR_HVAC
|
#endif // USE_IR_HVAC
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
|
switch (error) {
|
||||||
|
case IE_INVALID_RAWDATA:
|
||||||
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_RAWDATA);
|
||||||
|
break;
|
||||||
|
case IE_INVALID_JSON:
|
||||||
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON);
|
||||||
|
break;
|
||||||
|
case IE_SYNTAX_IRSEND:
|
||||||
|
Response_P(PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_NO " " D_JSON_IR_PROTOCOL ", " D_JSON_IR_BITS " " D_JSON_OR " " D_JSON_IR_DATA "\"}"));
|
||||||
|
break;
|
||||||
|
#ifdef USE_IR_HVAC
|
||||||
|
case IE_SYNTAX_IRHVAC:
|
||||||
|
Response_P(PSTR("{\"" D_CMND_IRHVAC "\":\"" D_JSON_WRONG " " D_JSON_IRHVAC_VENDOR ", " D_JSON_IRHVAC_MODE " " D_JSON_OR " " D_JSON_IRHVAC_FANSPEED "\"}"));
|
||||||
|
break;
|
||||||
|
#endif // USE_IR_HVAC
|
||||||
|
}
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#define XDRV_06 6
|
#define XDRV_06 6
|
||||||
|
|
||||||
#define SFB_TIME_AVOID_DUPLICATE 2000 // Milliseconds
|
const uint32_t SFB_TIME_AVOID_DUPLICATE = 2000; // Milliseconds
|
||||||
|
|
||||||
enum SonoffBridgeCommands {
|
enum SonoffBridgeCommands {
|
||||||
CMND_RFSYNC, CMND_RFLOW, CMND_RFHIGH, CMND_RFHOST, CMND_RFCODE, CMND_RFKEY, CMND_RFRAW };
|
CMND_RFSYNC, CMND_RFLOW, CMND_RFHIGH, CMND_RFHOST, CMND_RFCODE, CMND_RFKEY, CMND_RFRAW };
|
||||||
|
@ -51,8 +51,8 @@ unsigned long sonoff_bridge_last_learn_time = 0;
|
||||||
#include "ihx.h"
|
#include "ihx.h"
|
||||||
#include "c2.h"
|
#include "c2.h"
|
||||||
|
|
||||||
#define RF_RECORD_NO_START_FOUND -1
|
const ssize_t RF_RECORD_NO_START_FOUND = -1;
|
||||||
#define RF_RECORD_NO_END_FOUND -2
|
const ssize_t RF_RECORD_NO_END_FOUND = -2;
|
||||||
|
|
||||||
ssize_t rf_find_hex_record_start(uint8_t *buf, size_t size)
|
ssize_t rf_find_hex_record_start(uint8_t *buf, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -98,7 +98,7 @@ ssize_t rf_glue_remnant_with_new_data_and_write(const uint8_t *remnant_data, uin
|
||||||
glue_record_sz = strlen((const char *) remnant_data) + record_end;
|
glue_record_sz = strlen((const char *) remnant_data) + record_end;
|
||||||
|
|
||||||
glue_buf = (uint8_t *) malloc(glue_record_sz);
|
glue_buf = (uint8_t *) malloc(glue_record_sz);
|
||||||
if (glue_buf == NULL) { return -2; } // Not enough space
|
if (glue_buf == nullptr) { return -2; } // Not enough space
|
||||||
|
|
||||||
// Assemble new glue buffer
|
// Assemble new glue buffer
|
||||||
memcpy(glue_buf, remnant_data, strlen((const char *) remnant_data));
|
memcpy(glue_buf, remnant_data, strlen((const char *) remnant_data));
|
||||||
|
@ -208,17 +208,17 @@ void SonoffBridgeReceivedRaw(void)
|
||||||
|
|
||||||
if (0xB1 == serial_in_buffer[1]) { buckets = serial_in_buffer[2] << 1; } // Bucket sniffing
|
if (0xB1 == serial_in_buffer[1]) { buckets = serial_in_buffer[2] << 1; } // Bucket sniffing
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFRAW "\":{\"" D_JSON_DATA "\":\""));
|
Response_P(PSTR("{\"" D_CMND_RFRAW "\":{\"" D_JSON_DATA "\":\""));
|
||||||
for (int i = 0; i < serial_in_byte_counter; i++) {
|
for (int i = 0; i < serial_in_byte_counter; i++) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%02X"), mqtt_data, serial_in_buffer[i]);
|
ResponseAppend_P(PSTR("%02X"), serial_in_buffer[i]);
|
||||||
if (0xB1 == serial_in_buffer[1]) {
|
if (0xB1 == serial_in_buffer[1]) {
|
||||||
if ((i > 3) && buckets) { buckets--; }
|
if ((i > 3) && buckets) { buckets--; }
|
||||||
if ((i < 3) || (buckets % 2) || (i == serial_in_byte_counter -2)) {
|
if ((i < 3) || (buckets % 2) || (i == serial_in_byte_counter -2)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s "), mqtt_data);
|
ResponseAppend_P(PSTR(" "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"}}"), mqtt_data);
|
ResponseAppend_P(PSTR("\"}}"));
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_CMND_RFRAW));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_CMND_RFRAW));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ void SonoffBridgeReceivedRaw(void)
|
||||||
void SonoffBridgeLearnFailed(void)
|
void SonoffBridgeLearnFailed(void)
|
||||||
{
|
{
|
||||||
sonoff_bridge_learn_active = 0;
|
sonoff_bridge_learn_active = 0;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, sonoff_bridge_learn_key, D_JSON_LEARN_FAILED);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, sonoff_bridge_learn_key, D_JSON_LEARN_FAILED);
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY));
|
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ void SonoffBridgeReceived(void)
|
||||||
for (uint8_t i = 0; i < 9; i++) {
|
for (uint8_t i = 0; i < 9; i++) {
|
||||||
Settings.rf_code[sonoff_bridge_learn_key][i] = serial_in_buffer[i +1];
|
Settings.rf_code[sonoff_bridge_learn_key][i] = serial_in_buffer[i +1];
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, sonoff_bridge_learn_key, D_JSON_LEARNED);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, sonoff_bridge_learn_key, D_JSON_LEARNED);
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY));
|
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY));
|
||||||
} else {
|
} else {
|
||||||
SonoffBridgeLearnFailed();
|
SonoffBridgeLearnFailed();
|
||||||
|
@ -288,7 +288,7 @@ void SonoffBridgeReceived(void)
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("\"%06X\""), received_id);
|
snprintf_P(stemp, sizeof(stemp), PSTR("\"%06X\""), received_id);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":%s,\"" D_CMND_RFKEY "\":%s}}"),
|
Response_P(PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":%s,\"" D_CMND_RFKEY "\":%s}}"),
|
||||||
sync_time, low_time, high_time, stemp, rfkey);
|
sync_time, low_time, high_time, stemp, rfkey);
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
|
@ -470,7 +470,7 @@ bool SonoffBridgeCommand(void)
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("\"#%X\""), code);
|
snprintf_P(stemp, sizeof(stemp), PSTR("\"#%X\""), code);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_XVALUE, command, stemp);
|
Response_P(S_JSON_COMMAND_XVALUE, command, stemp);
|
||||||
}
|
}
|
||||||
else if ((CMND_RFKEY == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 16)) {
|
else if ((CMND_RFKEY == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 16)) {
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
|
@ -478,11 +478,11 @@ bool SonoffBridgeCommand(void)
|
||||||
sonoff_bridge_learn_active = 0;
|
sonoff_bridge_learn_active = 0;
|
||||||
if (2 == XdrvMailbox.payload) { // Learn RF data
|
if (2 == XdrvMailbox.payload) { // Learn RF data
|
||||||
SonoffBridgeLearn(XdrvMailbox.index);
|
SonoffBridgeLearn(XdrvMailbox.index);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_START_LEARNING);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_START_LEARNING);
|
||||||
}
|
}
|
||||||
else if (3 == XdrvMailbox.payload) { // Unlearn RF data
|
else if (3 == XdrvMailbox.payload) { // Unlearn RF data
|
||||||
Settings.rf_code[XdrvMailbox.index][0] = 0; // Reset sync_time MSB
|
Settings.rf_code[XdrvMailbox.index][0] = 0; // Reset sync_time MSB
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_SET_TO_DEFAULT);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_SET_TO_DEFAULT);
|
||||||
}
|
}
|
||||||
else if (4 == XdrvMailbox.payload) { // Save RF data provided by RFSync, RfLow, RfHigh and last RfCode
|
else if (4 == XdrvMailbox.payload) { // Save RF data provided by RFSync, RfLow, RfHigh and last RfCode
|
||||||
for (uint8_t i = 0; i < 6; i++) {
|
for (uint8_t i = 0; i < 6; i++) {
|
||||||
|
@ -491,7 +491,7 @@ bool SonoffBridgeCommand(void)
|
||||||
Settings.rf_code[XdrvMailbox.index][6] = (sonoff_bridge_last_send_code >> 16) & 0xff;
|
Settings.rf_code[XdrvMailbox.index][6] = (sonoff_bridge_last_send_code >> 16) & 0xff;
|
||||||
Settings.rf_code[XdrvMailbox.index][7] = (sonoff_bridge_last_send_code >> 8) & 0xff;
|
Settings.rf_code[XdrvMailbox.index][7] = (sonoff_bridge_last_send_code >> 8) & 0xff;
|
||||||
Settings.rf_code[XdrvMailbox.index][8] = sonoff_bridge_last_send_code & 0xff;
|
Settings.rf_code[XdrvMailbox.index][8] = sonoff_bridge_last_send_code & 0xff;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_SAVED);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_SAVED);
|
||||||
} else if (5 == XdrvMailbox.payload) { // Show default or learned RF data
|
} else if (5 == XdrvMailbox.payload) { // Show default or learned RF data
|
||||||
uint8_t key = XdrvMailbox.index;
|
uint8_t key = XdrvMailbox.index;
|
||||||
uint8_t index = (0 == Settings.rf_code[key][0]) ? 0 : key; // Use default if sync_time MSB = 0
|
uint8_t index = (0 == Settings.rf_code[key][0]) ? 0 : key; // Use default if sync_time MSB = 0
|
||||||
|
@ -505,19 +505,19 @@ bool SonoffBridgeCommand(void)
|
||||||
} else {
|
} else {
|
||||||
code |= Settings.rf_code[index][8];
|
code |= Settings.rf_code[index][8];
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":\"%06X\"}}"),
|
Response_P(PSTR("{\"%s%d\":{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":\"%06X\"}}"),
|
||||||
command, XdrvMailbox.index, sync_time, low_time, high_time, code);
|
command, XdrvMailbox.index, sync_time, low_time, high_time, code);
|
||||||
} else {
|
} else {
|
||||||
if ((1 == XdrvMailbox.payload) || (0 == Settings.rf_code[XdrvMailbox.index][0])) { // Test sync_time MSB
|
if ((1 == XdrvMailbox.payload) || (0 == Settings.rf_code[XdrvMailbox.index][0])) { // Test sync_time MSB
|
||||||
SonoffBridgeSend(0, XdrvMailbox.index); // Send default RF data
|
SonoffBridgeSend(0, XdrvMailbox.index); // Send default RF data
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_DEFAULT_SENT);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_DEFAULT_SENT);
|
||||||
} else {
|
} else {
|
||||||
SonoffBridgeSend(XdrvMailbox.index, 0); // Send learned RF data
|
SonoffBridgeSend(XdrvMailbox.index, 0); // Send learned RF data
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_LEARNED_SENT);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, D_JSON_LEARNED_SENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, sonoff_bridge_learn_key, D_JSON_LEARNING_ACTIVE);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, sonoff_bridge_learn_key, D_JSON_LEARNING_ACTIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_RFRAW == command_code) {
|
else if (CMND_RFRAW == command_code) {
|
||||||
|
@ -548,7 +548,7 @@ bool SonoffBridgeCommand(void)
|
||||||
sonoff_bridge_receive_raw_flag = 1;
|
sonoff_bridge_receive_raw_flag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(sonoff_bridge_receive_raw_flag));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(sonoff_bridge_receive_raw_flag));
|
||||||
} else serviced = false; // Unknown command
|
} else serviced = false; // Unknown command
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
|
|
|
@ -79,8 +79,7 @@ void MqttPublishDomoticzFanState()
|
||||||
|
|
||||||
int fan_speed = GetFanspeed();
|
int fan_speed = GetFanspeed();
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fan_speed * 10);
|
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fan_speed * 10);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE,
|
Response_P(DOMOTICZ_MESSAGE, (int)Settings.domoticz_relay_idx[1], (0 == fan_speed) ? 0 : 2, svalue, DomoticzBatteryQuality(), DomoticzRssiQuality());
|
||||||
(int)Settings.domoticz_relay_idx[1], (0 == fan_speed) ? 0 : 2, svalue, DomoticzBatteryQuality(), DomoticzRssiQuality());
|
|
||||||
MqttPublish(domoticz_in_topic);
|
MqttPublish(domoticz_in_topic);
|
||||||
|
|
||||||
fan_debounce = millis();
|
fan_debounce = millis();
|
||||||
|
@ -106,8 +105,7 @@ void MqttPublishDomoticzPowerState(uint8_t device)
|
||||||
char svalue[8]; // Dimmer value
|
char svalue[8]; // Dimmer value
|
||||||
|
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), Settings.light_dimmer);
|
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), Settings.light_dimmer);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE,
|
Response_P(DOMOTICZ_MESSAGE, (int)Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? svalue : "", DomoticzBatteryQuality(), DomoticzRssiQuality());
|
||||||
(int)Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? svalue : "", DomoticzBatteryQuality(), DomoticzRssiQuality());
|
|
||||||
MqttPublish(domoticz_in_topic);
|
MqttPublish(domoticz_in_topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,31 +299,31 @@ bool DomoticzCommand(void)
|
||||||
Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_LVALUE, command, XdrvMailbox.index, Settings.domoticz_relay_idx[XdrvMailbox.index -1]);
|
Response_P(S_JSON_DOMOTICZ_COMMAND_INDEX_LVALUE, command, XdrvMailbox.index, Settings.domoticz_relay_idx[XdrvMailbox.index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_KEYIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
else if ((CMND_KEYIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
||||||
if (XdrvMailbox.payload >= 0) {
|
if (XdrvMailbox.payload >= 0) {
|
||||||
Settings.domoticz_key_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
Settings.domoticz_key_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_LVALUE, command, XdrvMailbox.index, Settings.domoticz_key_idx[XdrvMailbox.index -1]);
|
Response_P(S_JSON_DOMOTICZ_COMMAND_INDEX_LVALUE, command, XdrvMailbox.index, Settings.domoticz_key_idx[XdrvMailbox.index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_SWITCHIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
else if ((CMND_SWITCHIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
||||||
if (XdrvMailbox.payload >= 0) {
|
if (XdrvMailbox.payload >= 0) {
|
||||||
Settings.domoticz_switch_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
Settings.domoticz_switch_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.domoticz_switch_idx[XdrvMailbox.index -1]);
|
Response_P(S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.domoticz_switch_idx[XdrvMailbox.index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_SENSORIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= DZ_MAX_SENSORS)) {
|
else if ((CMND_SENSORIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= DZ_MAX_SENSORS)) {
|
||||||
if (XdrvMailbox.payload >= 0) {
|
if (XdrvMailbox.payload >= 0) {
|
||||||
Settings.domoticz_sensor_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
Settings.domoticz_sensor_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.domoticz_sensor_idx[XdrvMailbox.index -1]);
|
Response_P(S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.domoticz_sensor_idx[XdrvMailbox.index -1]);
|
||||||
}
|
}
|
||||||
else if (CMND_UPDATETIMER == command_code) {
|
else if (CMND_UPDATETIMER == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) {
|
||||||
Settings.domoticz_update_timer = XdrvMailbox.payload;
|
Settings.domoticz_update_timer = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ "%s\":%d}"), command, Settings.domoticz_update_timer);
|
Response_P(PSTR("{\"" D_CMND_DOMOTICZ "%s\":%d}"), command, Settings.domoticz_update_timer);
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
}
|
}
|
||||||
|
@ -340,7 +338,7 @@ bool DomoticzSendKey(uint8_t key, uint8_t device, uint8_t state, uint8_t svalflg
|
||||||
|
|
||||||
if (device <= MAX_DOMOTICZ_IDX) {
|
if (device <= MAX_DOMOTICZ_IDX) {
|
||||||
if ((Settings.domoticz_key_idx[device -1] || Settings.domoticz_switch_idx[device -1]) && (svalflg)) {
|
if ((Settings.domoticz_key_idx[device -1] || Settings.domoticz_switch_idx[device -1]) && (svalflg)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"),
|
Response_P(PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"),
|
||||||
(key) ? Settings.domoticz_switch_idx[device -1] : Settings.domoticz_key_idx[device -1], (state) ? (2 == state) ? "Toggle" : "On" : "Off");
|
(key) ? Settings.domoticz_switch_idx[device -1] : Settings.domoticz_key_idx[device -1], (state) ? (2 == state) ? "Toggle" : "On" : "Off");
|
||||||
MqttPublish(domoticz_in_topic);
|
MqttPublish(domoticz_in_topic);
|
||||||
result = 1;
|
result = 1;
|
||||||
|
@ -375,14 +373,14 @@ uint8_t DomoticzHumidityState(char *hum)
|
||||||
void DomoticzSensor(uint8_t idx, char *data)
|
void DomoticzSensor(uint8_t idx, char *data)
|
||||||
{
|
{
|
||||||
if (Settings.domoticz_sensor_idx[idx]) {
|
if (Settings.domoticz_sensor_idx[idx]) {
|
||||||
char dmess[90];
|
char dmess[100];
|
||||||
|
|
||||||
memcpy(dmess, mqtt_data, sizeof(dmess));
|
memcpy(dmess, mqtt_data, sizeof(dmess));
|
||||||
if (DZ_AIRQUALITY == idx) {
|
if (DZ_AIRQUALITY == idx) {
|
||||||
snprintf_P(mqtt_data, sizeof(dmess), PSTR("{\"idx\":%d,\"nvalue\":%s,\"Battery\":%d,\"RSSI\":%d}"),
|
Response_P(PSTR("{\"idx\":%d,\"nvalue\":%s,\"Battery\":%d,\"RSSI\":%d}"),
|
||||||
Settings.domoticz_sensor_idx[idx], data, DomoticzBatteryQuality(), DomoticzRssiQuality());
|
Settings.domoticz_sensor_idx[idx], data, DomoticzBatteryQuality(), DomoticzRssiQuality());
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(dmess), DOMOTICZ_MESSAGE,
|
Response_P(DOMOTICZ_MESSAGE,
|
||||||
Settings.domoticz_sensor_idx[idx], 0, data, DomoticzBatteryQuality(), DomoticzRssiQuality());
|
Settings.domoticz_sensor_idx[idx], 0, data, DomoticzBatteryQuality(), DomoticzRssiQuality());
|
||||||
}
|
}
|
||||||
MqttPublish(domoticz_in_topic);
|
MqttPublish(domoticz_in_topic);
|
||||||
|
|
|
@ -24,17 +24,17 @@
|
||||||
|
|
||||||
#define XDRV_08 8
|
#define XDRV_08 8
|
||||||
|
|
||||||
#define SERIAL_BRIDGE_BUFFER_SIZE 130
|
const uint8_t SERIAL_BRIDGE_BUFFER_SIZE = 130;
|
||||||
|
|
||||||
#include <TasmotaSerial.h>
|
#include <TasmotaSerial.h>
|
||||||
|
|
||||||
enum SerialBridgeCommands { CMND_SSERIALSEND, CMND_SBAUDRATE };
|
enum SerialBridgeCommands { CMND_SSERIALSEND, CMND_SBAUDRATE };
|
||||||
const char kSerialBridgeCommands[] PROGMEM = D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE;
|
const char kSerialBridgeCommands[] PROGMEM = D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE;
|
||||||
|
|
||||||
TasmotaSerial *SerialBridgeSerial = NULL;
|
TasmotaSerial *SerialBridgeSerial = nullptr;
|
||||||
|
|
||||||
unsigned long serial_bridge_polling_window = 0;
|
unsigned long serial_bridge_polling_window = 0;
|
||||||
char *serial_bridge_buffer = NULL;
|
char *serial_bridge_buffer = nullptr;
|
||||||
int serial_bridge_in_byte_counter = 0;
|
int serial_bridge_in_byte_counter = 0;
|
||||||
bool serial_bridge_active = true;
|
bool serial_bridge_active = true;
|
||||||
bool serial_bridge_raw = false;
|
bool serial_bridge_raw = false;
|
||||||
|
@ -68,16 +68,16 @@ void SerialBridgeInput(void)
|
||||||
if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) {
|
if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) {
|
||||||
serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed
|
serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed
|
||||||
if (!serial_bridge_raw) {
|
if (!serial_bridge_raw) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\"%s\"}"), serial_bridge_buffer);
|
Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\"%s\"}"), serial_bridge_buffer);
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\""));
|
Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\""));
|
||||||
for (int i = 0; i < serial_bridge_in_byte_counter; i++) {
|
for (int i = 0; i < serial_bridge_in_byte_counter; i++) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%02x"), mqtt_data, serial_bridge_buffer[i]);
|
ResponseAppend_P(PSTR("%02x"), serial_bridge_buffer[i]);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"}"), mqtt_data);
|
ResponseAppend_P(PSTR("\"}"));
|
||||||
}
|
}
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
|
||||||
// XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
serial_bridge_in_byte_counter = 0;
|
serial_bridge_in_byte_counter = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ bool SerialBridgeCommand(void)
|
||||||
codes += 2;
|
codes += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_SBAUDRATE == command_code) {
|
else if (CMND_SBAUDRATE == command_code) {
|
||||||
|
@ -155,7 +155,7 @@ bool SerialBridgeCommand(void)
|
||||||
Settings.sbaudrate = (1 == XdrvMailbox.payload) ? SOFT_BAUDRATE / 1200 : baud;
|
Settings.sbaudrate = (1 == XdrvMailbox.payload) ? SOFT_BAUDRATE / 1200 : baud;
|
||||||
SerialBridgeSerial->begin(Settings.sbaudrate * 1200); // Reinitialize serial port with new baud rate
|
SerialBridgeSerial->begin(Settings.sbaudrate * 1200); // Reinitialize serial port with new baud rate
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.sbaudrate * 1200);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.sbaudrate * 1200);
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
|
@ -172,12 +172,12 @@ bool Xdrv08(uint8_t function)
|
||||||
|
|
||||||
if (serial_bridge_active) {
|
if (serial_bridge_active) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case FUNC_PRE_INIT:
|
|
||||||
SerialBridgeInit();
|
|
||||||
break;
|
|
||||||
case FUNC_LOOP:
|
case FUNC_LOOP:
|
||||||
if (SerialBridgeSerial) { SerialBridgeInput(); }
|
if (SerialBridgeSerial) { SerialBridgeInput(); }
|
||||||
break;
|
break;
|
||||||
|
case FUNC_PRE_INIT:
|
||||||
|
SerialBridgeInit();
|
||||||
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = SerialBridgeCommand();
|
result = SerialBridgeCommand();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -287,7 +287,7 @@ void TimerEverySecond(void)
|
||||||
Settings.timer[i].arm = xtimer.repeat;
|
Settings.timer[i].arm = xtimer.repeat;
|
||||||
#ifdef USE_RULES
|
#ifdef USE_RULES
|
||||||
if (3 == xtimer.power) { // Blink becomes Rule disregarding device and allowing use of Backlog commands
|
if (3 == xtimer.power) { // Blink becomes Rule disregarding device and allowing use of Backlog commands
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Clock\":{\"Timer\":%d}}"), i +1);
|
Response_P(PSTR("{\"Clock\":{\"Timer\":%d}}"), i +1);
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
} else
|
} else
|
||||||
#endif // USE_RULES
|
#endif // USE_RULES
|
||||||
|
@ -325,11 +325,11 @@ void PrepShowTimer(uint8_t index)
|
||||||
sign[0] = '-';
|
sign[0] = '-';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_TIMER "%d\":{\"" D_JSON_TIMER_ARM "\":%d,\"" D_JSON_TIMER_MODE "\":%d,\"" D_JSON_TIMER_TIME "\":\"%s%02d:%02d\",\"" D_JSON_TIMER_WINDOW "\":%d,\"" D_JSON_TIMER_DAYS "\":\"%s\",\"" D_JSON_TIMER_REPEAT "\":%d%s,\"" D_JSON_TIMER_ACTION "\":%d}"),
|
ResponseAppend_P(PSTR("\"" D_CMND_TIMER "%d\":{\"" D_JSON_TIMER_ARM "\":%d,\"" D_JSON_TIMER_MODE "\":%d,\"" D_JSON_TIMER_TIME "\":\"%s%02d:%02d\",\"" D_JSON_TIMER_WINDOW "\":%d,\"" D_JSON_TIMER_DAYS "\":\"%s\",\"" D_JSON_TIMER_REPEAT "\":%d%s,\"" D_JSON_TIMER_ACTION "\":%d}"),
|
||||||
mqtt_data, index, xtimer.arm, xtimer.mode, sign, hour, xtimer.time % 60, xtimer.window, days, xtimer.repeat, soutput, xtimer.power);
|
index, xtimer.arm, xtimer.mode, sign, hour, xtimer.time % 60, xtimer.window, days, xtimer.repeat, soutput, xtimer.power);
|
||||||
#else
|
#else
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_TIMER "%d\":{\"" D_JSON_TIMER_ARM "\":%d,\"" D_JSON_TIMER_TIME "\":\"%02d:%02d\",\"" D_JSON_TIMER_WINDOW "\":%d,\"" D_JSON_TIMER_DAYS "\":\"%s\",\"" D_JSON_TIMER_REPEAT "\":%d%s,\"" D_JSON_TIMER_ACTION "\":%d}"),
|
ResponseAppend_P(PSTR("\"" D_CMND_TIMER "%d\":{\"" D_JSON_TIMER_ARM "\":%d,\"" D_JSON_TIMER_TIME "\":\"%02d:%02d\",\"" D_JSON_TIMER_WINDOW "\":%d,\"" D_JSON_TIMER_DAYS "\":\"%s\",\"" D_JSON_TIMER_REPEAT "\":%d%s,\"" D_JSON_TIMER_ACTION "\":%d}"),
|
||||||
mqtt_data, index, xtimer.arm, xtimer.time / 60, xtimer.time % 60, xtimer.window, days, xtimer.repeat, soutput, xtimer.power);
|
index, xtimer.arm, xtimer.time / 60, xtimer.time % 60, xtimer.window, days, xtimer.repeat, soutput, xtimer.power);
|
||||||
#endif // USE_SUNRISE
|
#endif // USE_SUNRISE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ bool TimerCommand(void)
|
||||||
StaticJsonBuffer<256> jsonBuffer;
|
StaticJsonBuffer<256> jsonBuffer;
|
||||||
JsonObject& root = jsonBuffer.parseObject(dataBufUc);
|
JsonObject& root = jsonBuffer.parseObject(dataBufUc);
|
||||||
if (!root.success()) {
|
if (!root.success()) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_INVALID_JSON "\"}"), index); // JSON decode failed
|
Response_P(PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_INVALID_JSON "\"}"), index); // JSON decode failed
|
||||||
error = 1;
|
error = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -387,7 +387,7 @@ bool TimerCommand(void)
|
||||||
|
|
||||||
strlcpy(time_str, root[parm_uc], sizeof(time_str));
|
strlcpy(time_str, root[parm_uc], sizeof(time_str));
|
||||||
const char *substr = strtok(time_str, ":");
|
const char *substr = strtok(time_str, ":");
|
||||||
if (substr != NULL) {
|
if (substr != nullptr) {
|
||||||
if (strchr(substr, '-')) {
|
if (strchr(substr, '-')) {
|
||||||
sign = 1;
|
sign = 1;
|
||||||
substr++;
|
substr++;
|
||||||
|
@ -396,8 +396,8 @@ bool TimerCommand(void)
|
||||||
if (sign) { value += 12; } // Allow entering timer offset from -11:59 to -00:01 converted to 12:01 to 23:59
|
if (sign) { value += 12; } // Allow entering timer offset from -11:59 to -00:01 converted to 12:01 to 23:59
|
||||||
if (value > 23) { value = 23; }
|
if (value > 23) { value = 23; }
|
||||||
itime = value * 60;
|
itime = value * 60;
|
||||||
substr = strtok(NULL, ":");
|
substr = strtok(nullptr, ":");
|
||||||
if (substr != NULL) {
|
if (substr != nullptr) {
|
||||||
value = atoi(substr);
|
value = atoi(substr);
|
||||||
if (value < 0) { value = 0; }
|
if (value < 0) { value = 0; }
|
||||||
if (value > 59) { value = 59; }
|
if (value > 59) { value = 59; }
|
||||||
|
@ -439,16 +439,16 @@ bool TimerCommand(void)
|
||||||
}
|
}
|
||||||
#ifndef USE_RULES
|
#ifndef USE_RULES
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_TIMER_NO_DEVICE "\"}"), index); // No outputs defined so nothing to control
|
Response_P(PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_TIMER_NO_DEVICE "\"}"), index); // No outputs defined so nothing to control
|
||||||
error = 1;
|
error = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!error) {
|
if (!error) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
|
Response_P(PSTR("{"));
|
||||||
PrepShowTimer(index);
|
PrepShowTimer(index);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_TIMERS == command_code) {
|
else if (CMND_TIMERS == command_code) {
|
||||||
|
@ -461,21 +461,21 @@ bool TimerCommand(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag3.timers_enable));
|
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag3.timers_enable));
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, command);
|
MqttPublishPrefixTopic_P(RESULT_OR_STAT, command);
|
||||||
|
|
||||||
uint8_t jsflg = 0;
|
uint8_t jsflg = 0;
|
||||||
uint8_t lines = 1;
|
uint8_t lines = 1;
|
||||||
for (uint8_t i = 0; i < MAX_TIMERS; i++) {
|
for (uint8_t i = 0; i < MAX_TIMERS; i++) {
|
||||||
if (!jsflg) {
|
if (!jsflg) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMERS "%d\":{"), lines++);
|
Response_P(PSTR("{\"" D_CMND_TIMERS "%d\":{"), lines++);
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
ResponseAppend_P(PSTR(","));
|
||||||
}
|
}
|
||||||
jsflg++;
|
jsflg++;
|
||||||
PrepShowTimer(i +1);
|
PrepShowTimer(i +1);
|
||||||
if (jsflg > 3) {
|
if (jsflg > 3) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}}"), mqtt_data);
|
ResponseAppend_P(PSTR("}}"));
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_TIMERS));
|
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_TIMERS));
|
||||||
jsflg = 0;
|
jsflg = 0;
|
||||||
}
|
}
|
||||||
|
@ -489,7 +489,7 @@ bool TimerCommand(void)
|
||||||
}
|
}
|
||||||
char lbuff[33];
|
char lbuff[33];
|
||||||
dtostrfd(((double)Settings.longitude) /1000000, 6, lbuff);
|
dtostrfd(((double)Settings.longitude) /1000000, 6, lbuff);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, lbuff);
|
Response_P(S_JSON_COMMAND_SVALUE, command, lbuff);
|
||||||
}
|
}
|
||||||
else if (CMND_LATITUDE == command_code) {
|
else if (CMND_LATITUDE == command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
|
@ -497,7 +497,7 @@ bool TimerCommand(void)
|
||||||
}
|
}
|
||||||
char lbuff[33];
|
char lbuff[33];
|
||||||
dtostrfd(((double)Settings.latitude) /1000000, 6, lbuff);
|
dtostrfd(((double)Settings.latitude) /1000000, 6, lbuff);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, lbuff);
|
Response_P(S_JSON_COMMAND_SVALUE, command, lbuff);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
@ -596,8 +596,8 @@ const char HTTP_TIMER_SCRIPT4[] PROGMEM =
|
||||||
"if(ct<99){st();}" // Save changes
|
"if(ct<99){st();}" // Save changes
|
||||||
"ct=t;"
|
"ct=t;"
|
||||||
"o=document.getElementsByClassName('tl');" // Restore style to all tabs/buttons
|
"o=document.getElementsByClassName('tl');" // Restore style to all tabs/buttons
|
||||||
"for(i=0;i<o.length;i++){o[i].style.cssText=\"background-color:#999;color:#fff;font-weight:normal;\"}"
|
"for(i=0;i<o.length;i++){o[i].style.cssText=\"background:#%06x;color:#%06x;font-weight:normal;\"}" // COLOR_TIMER_TAB_BACKGROUND, COLOR_TIMER_TAB_TEXT
|
||||||
"e.style.cssText=\"background-color:transparent;color:#000;font-weight:bold;\";" // Change style to tab/button used to open content
|
"e.style.cssText=\"background:#%06x;color:#%06x;font-weight:bold;\";" // COLOR_FORM, COLOR_TEXT, Change style to tab/button used to open content
|
||||||
"s=pt[ct];" // Get parameters from array
|
"s=pt[ct];" // Get parameters from array
|
||||||
#ifdef USE_SUNRISE
|
#ifdef USE_SUNRISE
|
||||||
"p=(s>>29)&3;eb('b'+p).checked=1;" // Set mode
|
"p=(s>>29)&3;eb('b'+p).checked=1;" // Set mode
|
||||||
|
@ -620,7 +620,12 @@ const char HTTP_TIMER_SCRIPT5[] PROGMEM =
|
||||||
"function it(){" // Initialize elements and select first tab
|
"function it(){" // Initialize elements and select first tab
|
||||||
"var b,i,o,s;"
|
"var b,i,o,s;"
|
||||||
"pt=eb('t0').value.split(',').map(Number);" // Get parameters from hidden area to array
|
"pt=eb('t0').value.split(',').map(Number);" // Get parameters from hidden area to array
|
||||||
"s='';for(i=0;i<" STR(MAX_TIMERS) ";i++){b='';if(0==i){b=\" id='dP'\";}s+=\"<button type='button' class='tl' onclick='ot(\"+i+\",this)'\"+b+\">\"+(i+1)+\"</button>\"}"
|
"s='';"
|
||||||
|
"for(i=0;i<%d;i++){"
|
||||||
|
"b='';"
|
||||||
|
"if(0==i){b=\" id='dP'\";}"
|
||||||
|
"s+=\"<button type='button' class='tl' onclick='ot(\"+i+\",this)'\"+b+\">\"+(i+1)+\"</button>\""
|
||||||
|
"}"
|
||||||
"eb('bt').innerHTML=s;" // Create tabs
|
"eb('bt').innerHTML=s;" // Create tabs
|
||||||
"if(%d>0){" // Create Output and Action drop down boxes
|
"if(%d>0){" // Create Output and Action drop down boxes
|
||||||
"eb('oa').innerHTML=\"<b>" D_TIMER_OUTPUT "</b> <span><select style='width:60px;' id='d1' name='d1'></select></span> <b>" D_TIMER_ACTION "</b> <select style='width:99px;' id='p1' name='p1'></select>\";"
|
"eb('oa').innerHTML=\"<b>" D_TIMER_OUTPUT "</b> <span><select style='width:60px;' id='d1' name='d1'></select></span> <b>" D_TIMER_ACTION "</b> <select style='width:99px;' id='p1' name='p1'></select>\";"
|
||||||
|
@ -648,7 +653,7 @@ const char HTTP_TIMER_SCRIPT6[] PROGMEM =
|
||||||
"}"
|
"}"
|
||||||
"window.onload=it;";
|
"window.onload=it;";
|
||||||
const char HTTP_TIMER_STYLE[] PROGMEM =
|
const char HTTP_TIMER_STYLE[] PROGMEM =
|
||||||
".tl{float:left;border-radius:0;border:1px solid #f2f2f2;padding:1px;width:6.25%%;}"; // Border color needs to be the same as Fieldset background color from HTTP_HEAD_STYLE1 (transparent won't work)
|
".tl{float:left;border-radius:0;border:1px solid #%06x;padding:1px;width:6.25%%;}"; // COLOR_FORM, Border color needs to be the same as Fieldset background color from HTTP_HEAD_STYLE1 (transparent won't work)
|
||||||
const char HTTP_FORM_TIMER1[] PROGMEM =
|
const char HTTP_FORM_TIMER1[] PROGMEM =
|
||||||
"<fieldset style='min-width:470px;text-align:center;'>"
|
"<fieldset style='min-width:470px;text-align:center;'>"
|
||||||
"<legend style='text-align:left;'><b> " D_TIMER_PARAMETERS " </b></legend>"
|
"<legend style='text-align:left;'><b> " D_TIMER_PARAMETERS " </b></legend>"
|
||||||
|
@ -704,10 +709,10 @@ void HandleTimerConfiguration(void)
|
||||||
WSContentSend_P(HTTP_TIMER_SCRIPT2);
|
WSContentSend_P(HTTP_TIMER_SCRIPT2);
|
||||||
#endif // USE_SUNRISE
|
#endif // USE_SUNRISE
|
||||||
WSContentSend_P(HTTP_TIMER_SCRIPT3, devices_present);
|
WSContentSend_P(HTTP_TIMER_SCRIPT3, devices_present);
|
||||||
WSContentSend_P(HTTP_TIMER_SCRIPT4, devices_present);
|
WSContentSend_P(HTTP_TIMER_SCRIPT4, WebColor(COL_TIMER_TAB_BACKGROUND), WebColor(COL_TIMER_TAB_TEXT), WebColor(COL_FORM), WebColor(COL_TEXT), devices_present);
|
||||||
WSContentSend_P(HTTP_TIMER_SCRIPT5, devices_present);
|
WSContentSend_P(HTTP_TIMER_SCRIPT5, MAX_TIMERS, devices_present);
|
||||||
WSContentSend_P(HTTP_TIMER_SCRIPT6, devices_present);
|
WSContentSend_P(HTTP_TIMER_SCRIPT6, devices_present);
|
||||||
WSContentSendStyle_P(HTTP_TIMER_STYLE);
|
WSContentSendStyle_P(HTTP_TIMER_STYLE, WebColor(COL_FORM));
|
||||||
WSContentSend_P(HTTP_FORM_TIMER1, (Settings.flag3.timers_enable) ? " checked" : "");
|
WSContentSend_P(HTTP_FORM_TIMER1, (Settings.flag3.timers_enable) ? " checked" : "");
|
||||||
for (uint8_t i = 0; i < MAX_TIMERS; i++) {
|
for (uint8_t i = 0; i < MAX_TIMERS; i++) {
|
||||||
WSContentSend_P(PSTR("%s%u"), (i > 0) ? "," : "", Settings.timer[i].data);
|
WSContentSend_P(PSTR("%s%u"), (i > 0) ? "," : "", Settings.timer[i].data);
|
||||||
|
|
|
@ -369,7 +369,7 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved)
|
||||||
|
|
||||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: %s performs \"%s\""), event_trigger.c_str(), command);
|
AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: %s performs \"%s\""), event_trigger.c_str(), command);
|
||||||
|
|
||||||
// snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, D_CMND_RULE, D_JSON_INITIATED);
|
// Response_P(S_JSON_COMMAND_SVALUE, D_CMND_RULE, D_JSON_INITIATED);
|
||||||
// MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RULE));
|
// MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RULE));
|
||||||
|
|
||||||
ExecuteCommand(command, SRC_RULE);
|
ExecuteCommand(command, SRC_RULE);
|
||||||
|
@ -486,8 +486,9 @@ void RulesEvery50ms(void)
|
||||||
event_data[0] ='\0';
|
event_data[0] ='\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (vars_event) {
|
else if (vars_event || mems_event){
|
||||||
for (uint8_t i = 0; i < MAX_RULE_VARS-1; i++) {
|
if (vars_event) {
|
||||||
|
for (uint8_t i = 0; i < MAX_RULE_VARS; i++) {
|
||||||
if (bitRead(vars_event, i)) {
|
if (bitRead(vars_event, i)) {
|
||||||
bitClear(vars_event, i);
|
bitClear(vars_event, i);
|
||||||
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Var%d\":{\"State\":%s}}"), i+1, vars[i]);
|
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Var%d\":{\"State\":%s}}"), i+1, vars[i]);
|
||||||
|
@ -496,8 +497,8 @@ void RulesEvery50ms(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mems_event) {
|
if (mems_event) {
|
||||||
for (uint8_t i = 0; i < MAX_RULE_MEMS-1; i++) {
|
for (uint8_t i = 0; i < MAX_RULE_MEMS; i++) {
|
||||||
if (bitRead(mems_event, i)) {
|
if (bitRead(mems_event, i)) {
|
||||||
bitClear(mems_event, i);
|
bitClear(mems_event, i);
|
||||||
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Mem%d\":{\"State\":%s}}"), i+1, Settings.mems[i]);
|
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Mem%d\":{\"State\":%s}}"), i+1, Settings.mems[i]);
|
||||||
|
@ -506,6 +507,7 @@ void RulesEvery50ms(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (rules_flag.data) {
|
else if (rules_flag.data) {
|
||||||
uint16_t mask = 1;
|
uint16_t mask = 1;
|
||||||
for (uint8_t i = 0; i < MAX_RULES_FLAG; i++) {
|
for (uint8_t i = 0; i < MAX_RULES_FLAG; i++) {
|
||||||
|
@ -520,6 +522,7 @@ void RulesEvery50ms(void)
|
||||||
case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||||
case 5: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
case 5: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||||
case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||||
|
case 7: strncpy_P(json_event, PSTR("{\"HTTP\":{\"Initialized\":1}}"), sizeof(json_event)); break;
|
||||||
}
|
}
|
||||||
if (json_event[0]) {
|
if (json_event[0]) {
|
||||||
RulesProcessEvent(json_event);
|
RulesProcessEvent(json_event);
|
||||||
|
@ -544,7 +547,7 @@ void RulesEvery100ms(void)
|
||||||
tele_period = tele_period_save;
|
tele_period = tele_period_save;
|
||||||
if (strlen(mqtt_data)) {
|
if (strlen(mqtt_data)) {
|
||||||
mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
RulesProcess();
|
RulesProcess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,10 +675,10 @@ String RulesSubscribe(const char *data, int data_len)
|
||||||
char * pos = strtok(parameters, ",");
|
char * pos = strtok(parameters, ",");
|
||||||
if (pos) {
|
if (pos) {
|
||||||
event_name = Trim(pos);
|
event_name = Trim(pos);
|
||||||
pos = strtok(NULL, ",");
|
pos = strtok(nullptr, ",");
|
||||||
if (pos) {
|
if (pos) {
|
||||||
topic = Trim(pos);
|
topic = Trim(pos);
|
||||||
pos = strtok(NULL, ",");
|
pos = strtok(nullptr, ",");
|
||||||
if (pos) {
|
if (pos) {
|
||||||
key = Trim(pos);
|
key = Trim(pos);
|
||||||
}
|
}
|
||||||
|
@ -1139,15 +1142,15 @@ bool RulesCommand(void)
|
||||||
}
|
}
|
||||||
mqtt_data[0] = '\0';
|
mqtt_data[0] = '\0';
|
||||||
for (uint8_t i = 0; i < MAX_RULE_TIMERS; i++) {
|
for (uint8_t i = 0; i < MAX_RULE_TIMERS; i++) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%c\"T%d\":%d"), mqtt_data, (i) ? ',' : '{', i +1, (rules_timer[i]) ? (rules_timer[i] - millis()) / 1000 : 0);
|
ResponseAppend_P(PSTR("%c\"T%d\":%d"), (i) ? ',' : '{', i +1, (rules_timer[i]) ? (rules_timer[i] - millis()) / 1000 : 0);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
else if (CMND_EVENT == command_code) {
|
else if (CMND_EVENT == command_code) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
strlcpy(event_data, XdrvMailbox.data, sizeof(event_data));
|
strlcpy(event_data, XdrvMailbox.data, sizeof(event_data));
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
else if ((CMND_VAR == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
else if ((CMND_VAR == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
@ -1158,7 +1161,7 @@ bool RulesCommand(void)
|
||||||
#endif //USE_EXPRESSION
|
#endif //USE_EXPRESSION
|
||||||
bitSet(vars_event, index -1);
|
bitSet(vars_event, index -1);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_MEM == command_code) && (index > 0) && (index <= MAX_RULE_MEMS)) {
|
else if ((CMND_MEM == command_code) && (index > 0) && (index <= MAX_RULE_MEMS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
@ -1169,13 +1172,13 @@ bool RulesCommand(void)
|
||||||
#endif //USE_EXPRESSION
|
#endif //USE_EXPRESSION
|
||||||
bitSet(mems_event, index -1);
|
bitSet(mems_event, index -1);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mems[index -1]);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mems[index -1]);
|
||||||
}
|
}
|
||||||
else if (CMND_CALC_RESOLUTION == command_code) {
|
else if (CMND_CALC_RESOLUTION == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 7)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 7)) {
|
||||||
Settings.flag2.calc_resolution = XdrvMailbox.payload;
|
Settings.flag2.calc_resolution = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.calc_resolution);
|
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.flag2.calc_resolution);
|
||||||
}
|
}
|
||||||
else if ((CMND_ADD == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
else if ((CMND_ADD == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
@ -1183,7 +1186,7 @@ bool RulesCommand(void)
|
||||||
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
||||||
bitSet(vars_event, index -1);
|
bitSet(vars_event, index -1);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_SUB == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
else if ((CMND_SUB == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
@ -1191,7 +1194,7 @@ bool RulesCommand(void)
|
||||||
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
||||||
bitSet(vars_event, index -1);
|
bitSet(vars_event, index -1);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_MULT == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
else if ((CMND_MULT == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
@ -1199,11 +1202,11 @@ bool RulesCommand(void)
|
||||||
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
||||||
bitSet(vars_event, index -1);
|
bitSet(vars_event, index -1);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_SCALE == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
else if ((CMND_SCALE == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry
|
if (strstr(XdrvMailbox.data, ",") != nullptr) { // Process parameter entry
|
||||||
char sub_string[XdrvMailbox.data_len +1];
|
char sub_string[XdrvMailbox.data_len +1];
|
||||||
|
|
||||||
double valueIN = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
double valueIN = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
||||||
|
@ -1216,14 +1219,14 @@ bool RulesCommand(void)
|
||||||
bitSet(vars_event, index -1);
|
bitSet(vars_event, index -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||||
#ifdef SUPPORT_MQTT_EVENT
|
#ifdef SUPPORT_MQTT_EVENT
|
||||||
} else if (CMND_SUBSCRIBE == command_code) { //MQTT Subscribe command. Subscribe <Event>, <Topic> [, <Key>]
|
} else if (CMND_SUBSCRIBE == command_code) { //MQTT Subscribe command. Subscribe <Event>, <Topic> [, <Key>]
|
||||||
String result = RulesSubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
|
String result = RulesSubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, result.c_str());
|
Response_P(S_JSON_COMMAND_SVALUE, command, result.c_str());
|
||||||
} else if (CMND_UNSUBSCRIBE == command_code) { //MQTT Un-subscribe command. UnSubscribe <Event>
|
} else if (CMND_UNSUBSCRIBE == command_code) { //MQTT Un-subscribe command. UnSubscribe <Event>
|
||||||
String result = RulesUnsubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
|
String result = RulesUnsubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, result.c_str());
|
Response_P(S_JSON_COMMAND_SVALUE, command, result.c_str());
|
||||||
#endif //SUPPORT_MQTT_EVENT
|
#endif //SUPPORT_MQTT_EVENT
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
|
@ -880,6 +880,7 @@ void HandleKNXConfiguration(void)
|
||||||
"}"
|
"}"
|
||||||
"}"));
|
"}"));
|
||||||
WSContentSendStyle();
|
WSContentSendStyle();
|
||||||
|
KNX_physs_addr.value = Settings.knx_physsical_addr;
|
||||||
WSContentSend_P(HTTP_FORM_KNX, KNX_physs_addr.pa.area, KNX_physs_addr.pa.line, KNX_physs_addr.pa.member);
|
WSContentSend_P(HTTP_FORM_KNX, KNX_physs_addr.pa.area, KNX_physs_addr.pa.line, KNX_physs_addr.pa.member);
|
||||||
if ( Settings.flag.knx_enabled ) { WSContentSend_P(PSTR(" checked")); }
|
if ( Settings.flag.knx_enabled ) { WSContentSend_P(PSTR(" checked")); }
|
||||||
WSContentSend_P(HTTP_FORM_KNX1);
|
WSContentSend_P(HTTP_FORM_KNX1);
|
||||||
|
@ -1086,7 +1087,7 @@ bool KnxCommand(void)
|
||||||
|
|
||||||
else if (CMND_KNX_PA == command_code) {
|
else if (CMND_KNX_PA == command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if (strstr(XdrvMailbox.data, ".")) { // Process parameter entry
|
if (strstr(XdrvMailbox.data, ".") != nullptr) { // Process parameter entry
|
||||||
char sub_string[XdrvMailbox.data_len];
|
char sub_string[XdrvMailbox.data_len];
|
||||||
|
|
||||||
int pa_area = atoi(subStr(sub_string, XdrvMailbox.data, ".", 1));
|
int pa_area = atoi(subStr(sub_string, XdrvMailbox.data, ".", 1));
|
||||||
|
@ -1113,7 +1114,7 @@ bool KnxCommand(void)
|
||||||
|
|
||||||
else if ((CMND_KNX_GA == command_code) && (index > 0) && (index <= MAX_KNX_GA)) {
|
else if ((CMND_KNX_GA == command_code) && (index > 0) && (index <= MAX_KNX_GA)) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry
|
if (strstr(XdrvMailbox.data, ",") != nullptr) { // Process parameter entry
|
||||||
char sub_string[XdrvMailbox.data_len];
|
char sub_string[XdrvMailbox.data_len];
|
||||||
|
|
||||||
int ga_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
int ga_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
||||||
|
@ -1162,7 +1163,7 @@ bool KnxCommand(void)
|
||||||
|
|
||||||
else if ((CMND_KNX_CB == command_code) && (index > 0) && (index <= MAX_KNX_CB)) {
|
else if ((CMND_KNX_CB == command_code) && (index > 0) && (index <= MAX_KNX_CB)) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry
|
if (strstr(XdrvMailbox.data, ",") != nullptr) { // Process parameter entry
|
||||||
char sub_string[XdrvMailbox.data_len];
|
char sub_string[XdrvMailbox.data_len];
|
||||||
|
|
||||||
int cb_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
int cb_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
||||||
|
@ -1223,6 +1224,9 @@ bool Xdrv11(uint8_t function)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
switch (function) {
|
switch (function) {
|
||||||
|
case FUNC_LOOP:
|
||||||
|
if (!global_state.wifi_down) { knx.loop(); } // Process knx events
|
||||||
|
break;
|
||||||
case FUNC_PRE_INIT:
|
case FUNC_PRE_INIT:
|
||||||
KNX_INIT();
|
KNX_INIT();
|
||||||
break;
|
break;
|
||||||
|
@ -1236,9 +1240,6 @@ bool Xdrv11(uint8_t function)
|
||||||
break;
|
break;
|
||||||
#endif // USE_KNX_WEB_MENU
|
#endif // USE_KNX_WEB_MENU
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
case FUNC_LOOP:
|
|
||||||
if (!global_state.wifi_down) { knx.loop(); } // Process knx events
|
|
||||||
break;
|
|
||||||
case FUNC_EVERY_50_MSECOND:
|
case FUNC_EVERY_50_MSECOND:
|
||||||
if (toggle_inhibit) {
|
if (toggle_inhibit) {
|
||||||
toggle_inhibit--;
|
toggle_inhibit--;
|
||||||
|
|
|
@ -44,38 +44,37 @@ const char HASS_DISCOVER_BUTTON_SWITCH[] PROGMEM =
|
||||||
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
|
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
|
||||||
|
|
||||||
const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE[] PROGMEM =
|
const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE[] PROGMEM =
|
||||||
"%s,\"off_delay\":1"; // Hass has no support for TOGGLE, fake it by resetting to OFF after 1s
|
",\"off_delay\":1"; // Hass has no support for TOGGLE, fake it by resetting to OFF after 1s
|
||||||
|
|
||||||
const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF[] PROGMEM =
|
const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF[] PROGMEM =
|
||||||
"%s,\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work
|
",\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work
|
||||||
"\"pl_off\":\"%s\""; // OFF
|
"\"pl_off\":\"%s\""; // OFF
|
||||||
|
|
||||||
|
|
||||||
const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM =
|
const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM =
|
||||||
"%s,\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer
|
",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer
|
||||||
"\"bri_stat_t\":\"%s\"," // stat/led2/RESULT
|
"\"bri_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||||
"\"bri_scl\":100," // 100%
|
"\"bri_scl\":100," // 100%
|
||||||
"\"on_cmd_type\":\"brightness\"," // power on (first), power on (last), no power on (brightness)
|
"\"on_cmd_type\":\"brightness\"," // power on (first), power on (last), no power on (brightness)
|
||||||
"\"bri_val_tpl\":\"{{value_json." D_CMND_DIMMER "}}\"";
|
"\"bri_val_tpl\":\"{{value_json." D_CMND_DIMMER "}}\"";
|
||||||
|
|
||||||
const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM =
|
const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM =
|
||||||
"%s,\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2
|
",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2
|
||||||
"\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT
|
"\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||||
"\"rgb_val_tpl\":\"{{value_json." D_CMND_COLOR ".split(',')[0:3]|join(',')}}\"";
|
"\"rgb_val_tpl\":\"{{value_json." D_CMND_COLOR ".split(',')[0:3]|join(',')}}\"";
|
||||||
|
|
||||||
const char HASS_DISCOVER_LIGHT_WHITE[] PROGMEM =
|
const char HASS_DISCOVER_LIGHT_WHITE[] PROGMEM =
|
||||||
"%s,\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White
|
",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White
|
||||||
"\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT
|
"\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||||
"\"white_value_scale\":100," // (No abbreviation defined)
|
"\"white_value_scale\":100," // (No abbreviation defined)
|
||||||
"\"whit_val_tpl\":\"{{value_json.Channel[3]}}\"";
|
"\"whit_val_tpl\":\"{{value_json.Channel[3]}}\"";
|
||||||
|
|
||||||
const char HASS_DISCOVER_LIGHT_CT[] PROGMEM =
|
const char HASS_DISCOVER_LIGHT_CT[] PROGMEM =
|
||||||
"%s,\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT
|
",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT
|
||||||
"\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT
|
"\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||||
"\"clr_temp_val_tpl\":\"{{value_json." D_CMND_COLORTEMPERATURE "}}\"";
|
"\"clr_temp_val_tpl\":\"{{value_json." D_CMND_COLORTEMPERATURE "}}\"";
|
||||||
|
|
||||||
const char HASS_DISCOVER_LIGHT_SCHEME[] PROGMEM =
|
const char HASS_DISCOVER_LIGHT_SCHEME[] PROGMEM =
|
||||||
"%s,\"fx_cmd_t\":\"%s\"," // cmnd/led2/Scheme
|
",\"fx_cmd_t\":\"%s\"," // cmnd/led2/Scheme
|
||||||
"\"fx_stat_t\":\"%s\"," // stat/led2/RESULT
|
"\"fx_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||||
"\"fx_val_tpl\":\"{{value_json." D_CMND_SCHEME "}}\","
|
"\"fx_val_tpl\":\"{{value_json." D_CMND_SCHEME "}}\","
|
||||||
"\"fx_list\":[\"0\",\"1\",\"2\",\"3\",\"4\"]"; // string list with reference to scheme parameter.
|
"\"fx_list\":[\"0\",\"1\",\"2\",\"3\",\"4\"]"; // string list with reference to scheme parameter.
|
||||||
|
@ -88,47 +87,47 @@ const char HASS_DISCOVER_SENSOR[] PROGMEM =
|
||||||
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
|
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
|
||||||
|
|
||||||
const char HASS_DISCOVER_SENSOR_TEMP[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_TEMP[] PROGMEM =
|
||||||
"%s,\"unit_of_meas\":\"°%c\"," // °C / °F
|
",\"unit_of_meas\":\"°%c\"," // °C / °F
|
||||||
"\"val_tpl\":\"{{value_json['%s'].Temperature}}\""; // "SI7021-14":{"Temperature":null,"Humidity":null} -> {{ value_json['SI7021-14'].Temperature }}
|
"\"val_tpl\":\"{{value_json['%s'].Temperature}}\""; // "SI7021-14":{"Temperature":null,"Humidity":null} -> {{ value_json['SI7021-14'].Temperature }}
|
||||||
|
|
||||||
const char HASS_DISCOVER_SENSOR_HUM[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_HUM[] PROGMEM =
|
||||||
"%s,\"unit_of_meas\":\"%%\"," // %
|
",\"unit_of_meas\":\"%%\"," // %
|
||||||
"\"val_tpl\":\"{{value_json['%s'].Humidity}}\"," // "SI7021-14":{"Temperature":null,"Humidity":null} -> {{ value_json['SI7021-14'].Humidity }}
|
"\"val_tpl\":\"{{value_json['%s'].Humidity}}\"," // "SI7021-14":{"Temperature":null,"Humidity":null} -> {{ value_json['SI7021-14'].Humidity }}
|
||||||
"\"dev_cla\":\"humidity\""; // humidity
|
"\"dev_cla\":\"humidity\""; // humidity
|
||||||
|
|
||||||
const char HASS_DISCOVER_SENSOR_PRESS[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_PRESS[] PROGMEM =
|
||||||
"%s,\"unit_of_meas\":\"%s\"," // PressureUnit() setting
|
",\"unit_of_meas\":\"%s\"," // PressureUnit() setting
|
||||||
"\"val_tpl\":\"{{value_json['%s'].Pressure}}\"," // "BME280":{"Temperature":19.7,"Humidity":27.8,"Pressure":990.1} -> {{ value_json['BME280'].Pressure }}
|
"\"val_tpl\":\"{{value_json['%s'].Pressure}}\"," // "BME280":{"Temperature":19.7,"Humidity":27.8,"Pressure":990.1} -> {{ value_json['BME280'].Pressure }}
|
||||||
"\"dev_cla\":\"pressure\""; // pressure
|
"\"dev_cla\":\"pressure\""; // pressure
|
||||||
|
|
||||||
//ENERGY
|
//ENERGY
|
||||||
const char HASS_DISCOVER_SENSOR_KWH[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_KWH[] PROGMEM =
|
||||||
"%s,\"unit_of_meas\":\"kWh\"," // kWh
|
",\"unit_of_meas\":\"kWh\"," // kWh
|
||||||
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "ENERGY":{"TotalStartTime":null,"Total":null,"Yesterday":null,"Today":null,"Power":null,"ApparentPower":null,"ReactivePower":null,"Factor":null,"Voltage":null,"Current":null} -> {{ value_json['ENERGY'].Total/Yesterday/Today }}
|
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "ENERGY":{"TotalStartTime":null,"Total":null,"Yesterday":null,"Today":null,"Power":null,"ApparentPower":null,"ReactivePower":null,"Factor":null,"Voltage":null,"Current":null} -> {{ value_json['ENERGY'].Total/Yesterday/Today }}
|
||||||
|
|
||||||
const char HASS_DISCOVER_SENSOR_WATT[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_WATT[] PROGMEM =
|
||||||
"%s,\"unit_of_meas\":\"W\"," // W
|
",\"unit_of_meas\":\"W\"," // W
|
||||||
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "ENERGY":{"TotalStartTime":null,"Total":null,"Yesterday":null,"Today":null,"Power":null,"ApparentPower":null,"ReactivePower":null,"Factor":null,"Voltage":null,"Current":null} -> {{ value_json['ENERGY'].POWER }}
|
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "ENERGY":{"TotalStartTime":null,"Total":null,"Yesterday":null,"Today":null,"Power":null,"ApparentPower":null,"ReactivePower":null,"Factor":null,"Voltage":null,"Current":null} -> {{ value_json['ENERGY'].POWER }}
|
||||||
|
|
||||||
const char HASS_DISCOVER_SENSOR_VOLTAGE[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_VOLTAGE[] PROGMEM =
|
||||||
"%s,\"unit_of_meas\":\"V\"," // V
|
",\"unit_of_meas\":\"V\"," // V
|
||||||
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "ENERGY":{"TotalStartTime":null,"Total":null,"Yesterday":null,"Today":null,"Power":null,"ApparentPower":null,"ReactivePower":null,"Factor":null,"Voltage":null,"Current":null} -> {{ value_json['ENERGY'].Voltage }}
|
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "ENERGY":{"TotalStartTime":null,"Total":null,"Yesterday":null,"Today":null,"Power":null,"ApparentPower":null,"ReactivePower":null,"Factor":null,"Voltage":null,"Current":null} -> {{ value_json['ENERGY'].Voltage }}
|
||||||
|
|
||||||
const char HASS_DISCOVER_SENSOR_AMPERE[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_AMPERE[] PROGMEM =
|
||||||
"%s,\"unit_of_meas\":\"A\"," // A
|
",\"unit_of_meas\":\"A\"," // A
|
||||||
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "ENERGY":{"TotalStartTime":null,"Total":null,"Yesterday":null,"Today":null,"Power":null,"ApparentPower":null,"ReactivePower":null,"Factor":null,"Voltage":null,"Current":null} -> {{ value_json['ENERGY'].Current }}
|
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "ENERGY":{"TotalStartTime":null,"Total":null,"Yesterday":null,"Today":null,"Power":null,"ApparentPower":null,"ReactivePower":null,"Factor":null,"Voltage":null,"Current":null} -> {{ value_json['ENERGY'].Current }}
|
||||||
|
|
||||||
const char HASS_DISCOVER_SENSOR_ANY[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_ANY[] PROGMEM =
|
||||||
"%s,\"unit_of_meas\":\" \"," // " " As unit of measurement to get a value graph in Hass
|
",\"unit_of_meas\":\" \"," // " " As unit of measurement to get a value graph in Hass
|
||||||
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER'].C1 }}
|
"\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER'].C1 }}
|
||||||
|
|
||||||
const char HASS_DISCOVER_SENSOR_HASS_STATUS[] PROGMEM =
|
const char HASS_DISCOVER_SENSOR_HASS_STATUS[] PROGMEM =
|
||||||
"%s,\"json_attributes_topic\":\"%s\","
|
",\"json_attributes_topic\":\"%s\","
|
||||||
"\"unit_of_meas\":\" \"," // " " As unit of measurement to get a value graph in Hass
|
"\"unit_of_meas\":\" \"," // " " As unit of measurement to get a value graph in Hass
|
||||||
"\"val_tpl\":\"{{value_json['" D_JSON_RSSI "']}}\"";// "COUNTER":{"C1":0} -> {{ value_json['COUNTER'].C1 }}
|
"\"val_tpl\":\"{{value_json['" D_JSON_RSSI "']}}\"";// "COUNTER":{"C1":0} -> {{ value_json['COUNTER'].C1 }}
|
||||||
|
|
||||||
const char HASS_DISCOVER_DEVICE_INFO[] PROGMEM =
|
const char HASS_DISCOVER_DEVICE_INFO[] PROGMEM =
|
||||||
"%s,\"uniq_id\":\"%s\","
|
",\"uniq_id\":\"%s\","
|
||||||
"\"device\":{\"identifiers\":[\"%06X\"],"
|
"\"device\":{\"identifiers\":[\"%06X\"],"
|
||||||
"\"name\":\"%s\","
|
"\"name\":\"%s\","
|
||||||
"\"model\":\"%s\","
|
"\"model\":\"%s\","
|
||||||
|
@ -136,11 +135,11 @@ const char HASS_DISCOVER_DEVICE_INFO[] PROGMEM =
|
||||||
"\"manufacturer\":\"Tasmota\"}";
|
"\"manufacturer\":\"Tasmota\"}";
|
||||||
|
|
||||||
const char HASS_DISCOVER_DEVICE_INFO_SHORT[] PROGMEM =
|
const char HASS_DISCOVER_DEVICE_INFO_SHORT[] PROGMEM =
|
||||||
"%s,\"uniq_id\":\"%s\","
|
",\"uniq_id\":\"%s\","
|
||||||
"\"device\":{\"identifiers\":[\"%06X\"]}";
|
"\"device\":{\"identifiers\":[\"%06X\"]}";
|
||||||
|
|
||||||
const char HASS_DISCOVER_TOPIC_PREFIX[] PROGMEM =
|
const char HASS_DISCOVER_TOPIC_PREFIX[] PROGMEM =
|
||||||
"%s, \"~\":\"%s\"";
|
",\"~\":\"%s\"";
|
||||||
|
|
||||||
uint8_t hass_init_step = 0;
|
uint8_t hass_init_step = 0;
|
||||||
uint8_t hass_mode = 0;
|
uint8_t hass_mode = 0;
|
||||||
|
@ -166,21 +165,24 @@ static void Shorten(char** s, char *prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void try_snprintf_P(char *s, int n, const char *format, ... )
|
void TryResponseAppend_P(const char *format, ... )
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
char dummy[2];
|
char dummy[2];
|
||||||
int len = vsnprintf_P(dummy, 1, format, args);
|
int dlen = vsnprintf_P(dummy, 1, format, args);
|
||||||
if (len >= n) {
|
|
||||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("ERROR: MQTT discovery failed due to too long topic or friendly name. "
|
int mlen = strlen(mqtt_data);
|
||||||
"Please shorten topic and friendly name. Failed to format(%u/%u):"), len, n);
|
int slen = sizeof(mqtt_data) -1 -mlen;
|
||||||
|
if (dlen >= slen) {
|
||||||
|
AddLog_P2(LOG_LEVEL_ERROR, PSTR("HASS: MQTT discovery failed due to too long topic or friendly name. "
|
||||||
|
"Please shorten topic and friendly name. Failed to format(%u/%u):"), dlen, slen);
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vsnprintf_P(log_data, sizeof(log_data), format, args);
|
vsnprintf_P(log_data, sizeof(log_data), format, args);
|
||||||
AddLog(LOG_LEVEL_ERROR);
|
AddLog(LOG_LEVEL_ERROR);
|
||||||
} else {
|
} else {
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vsnprintf_P(s, n, format, args);
|
vsnprintf_P(mqtt_data + mlen, slen, format, args);
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
@ -234,30 +236,28 @@ void HAssAnnounceRelayLight(void)
|
||||||
Shorten(&state_topic, prefix);
|
Shorten(&state_topic, prefix);
|
||||||
Shorten(&availability_topic, prefix);
|
Shorten(&availability_topic, prefix);
|
||||||
|
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_RELAY,
|
Response_P(HASS_DISCOVER_RELAY, name, command_topic, state_topic, value_template, Settings.state_text[0], Settings.state_text[1], availability_topic);
|
||||||
name, command_topic, state_topic, value_template, Settings.state_text[0], Settings.state_text[1], availability_topic);
|
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP.getChipId());
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data,
|
TryResponseAppend_P(HASS_DISCOVER_TOPIC_PREFIX, prefix);
|
||||||
unique_id, ESP.getChipId());
|
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix);
|
|
||||||
|
|
||||||
if (is_light) {
|
if (is_light) {
|
||||||
char *brightness_command_topic = stemp1;
|
char *brightness_command_topic = stemp1;
|
||||||
|
|
||||||
GetTopic_P(brightness_command_topic, CMND, mqtt_topic, D_CMND_DIMMER);
|
GetTopic_P(brightness_command_topic, CMND, mqtt_topic, D_CMND_DIMMER);
|
||||||
Shorten(&brightness_command_topic, prefix);
|
Shorten(&brightness_command_topic, prefix);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_DIMMER, mqtt_data, brightness_command_topic, state_topic);
|
TryResponseAppend_P(HASS_DISCOVER_LIGHT_DIMMER, brightness_command_topic, state_topic);
|
||||||
|
|
||||||
if (light_subtype >= LST_RGB) {
|
if (light_subtype >= LST_RGB) {
|
||||||
char *rgb_command_topic = stemp1;
|
char *rgb_command_topic = stemp1;
|
||||||
|
|
||||||
GetTopic_P(rgb_command_topic, CMND, mqtt_topic, D_CMND_COLOR);
|
GetTopic_P(rgb_command_topic, CMND, mqtt_topic, D_CMND_COLOR);
|
||||||
Shorten(&rgb_command_topic, prefix);
|
Shorten(&rgb_command_topic, prefix);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_COLOR, mqtt_data, rgb_command_topic, state_topic);
|
TryResponseAppend_P(HASS_DISCOVER_LIGHT_COLOR, rgb_command_topic, state_topic);
|
||||||
|
|
||||||
char *effect_command_topic = stemp1;
|
char *effect_command_topic = stemp1;
|
||||||
GetTopic_P(effect_command_topic, CMND, mqtt_topic, D_CMND_SCHEME);
|
GetTopic_P(effect_command_topic, CMND, mqtt_topic, D_CMND_SCHEME);
|
||||||
Shorten(&effect_command_topic, prefix);
|
Shorten(&effect_command_topic, prefix);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_SCHEME, mqtt_data, effect_command_topic, state_topic);
|
TryResponseAppend_P(HASS_DISCOVER_LIGHT_SCHEME, effect_command_topic, state_topic);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (LST_RGBW == light_subtype) {
|
if (LST_RGBW == light_subtype) {
|
||||||
|
@ -265,17 +265,17 @@ void HAssAnnounceRelayLight(void)
|
||||||
|
|
||||||
GetTopic_P(white_temp_command_topic, CMND, mqtt_topic, D_CMND_WHITE);
|
GetTopic_P(white_temp_command_topic, CMND, mqtt_topic, D_CMND_WHITE);
|
||||||
Shorten(&white_temp_command_topic, prefix);
|
Shorten(&white_temp_command_topic, prefix);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_WHITE, mqtt_data, white_temp_command_topic, state_topic);
|
TryResponseAppend_P(HASS_DISCOVER_LIGHT_WHITE, white_temp_command_topic, state_topic);
|
||||||
}
|
}
|
||||||
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
||||||
char *color_temp_command_topic = stemp1;
|
char *color_temp_command_topic = stemp1;
|
||||||
|
|
||||||
GetTopic_P(color_temp_command_topic, CMND, mqtt_topic, D_CMND_COLORTEMPERATURE);
|
GetTopic_P(color_temp_command_topic, CMND, mqtt_topic, D_CMND_COLORTEMPERATURE);
|
||||||
Shorten(&color_temp_command_topic, prefix);
|
Shorten(&color_temp_command_topic, prefix);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_CT, mqtt_data, color_temp_command_topic, state_topic);
|
TryResponseAppend_P(HASS_DISCOVER_LIGHT_CT, color_temp_command_topic, state_topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
TryResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
MqttPublish(stopic, true);
|
MqttPublish(stopic, true);
|
||||||
}
|
}
|
||||||
|
@ -315,15 +315,13 @@ void HAssAnnounceButtonSwitch(uint8_t device, char* topic, uint8_t present, uint
|
||||||
FindPrefix(state_topic, availability_topic, prefix);
|
FindPrefix(state_topic, availability_topic, prefix);
|
||||||
Shorten(&state_topic, prefix);
|
Shorten(&state_topic, prefix);
|
||||||
Shorten(&availability_topic, prefix);
|
Shorten(&availability_topic, prefix);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_BUTTON_SWITCH,
|
Response_P(HASS_DISCOVER_BUTTON_SWITCH, name, state_topic, Settings.state_text[toggle?2:1], availability_topic);
|
||||||
name, state_topic, Settings.state_text[toggle?2:1], availability_topic);
|
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP.getChipId());
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data,
|
if (strlen(prefix) > 0 ) TryResponseAppend_P(HASS_DISCOVER_TOPIC_PREFIX, prefix);
|
||||||
unique_id, ESP.getChipId());
|
if (toggle) TryResponseAppend_P(HASS_DISCOVER_BUTTON_SWITCH_TOGGLE);
|
||||||
if (strlen(prefix) > 0 ) try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix);
|
else TryResponseAppend_P(HASS_DISCOVER_BUTTON_SWITCH_ONOFF, Settings.state_text[0]);
|
||||||
if (toggle) try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_BUTTON_SWITCH_TOGGLE, mqtt_data);
|
|
||||||
else try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_BUTTON_SWITCH_ONOFF, mqtt_data, Settings.state_text[0]);
|
|
||||||
|
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
TryResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
MqttPublish(stopic, true);
|
MqttPublish(stopic, true);
|
||||||
}
|
}
|
||||||
|
@ -416,40 +414,30 @@ void HAssAnnounceSensor(const char* sensorname, const char* subsensortype)
|
||||||
Shorten(&state_topic, prefix);
|
Shorten(&state_topic, prefix);
|
||||||
Shorten(&availability_topic, prefix);
|
Shorten(&availability_topic, prefix);
|
||||||
|
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR,
|
Response_P(HASS_DISCOVER_SENSOR, name, state_topic, availability_topic);
|
||||||
name, state_topic, availability_topic);
|
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP.getChipId());
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data,
|
TryResponseAppend_P(HASS_DISCOVER_TOPIC_PREFIX, prefix);
|
||||||
unique_id, ESP.getChipId());
|
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix);
|
|
||||||
if (!strcmp_P(subsensortype, PSTR(D_JSON_TEMPERATURE))) {
|
if (!strcmp_P(subsensortype, PSTR(D_JSON_TEMPERATURE))) {
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_TEMP,
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_TEMP, TempUnit(), sensorname);
|
||||||
mqtt_data, TempUnit(), sensorname);
|
|
||||||
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_HUMIDITY))) {
|
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_HUMIDITY))) {
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_HUM,
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_HUM, sensorname);
|
||||||
mqtt_data, sensorname);
|
|
||||||
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_PRESSURE))) {
|
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_PRESSURE))) {
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_PRESS,
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_PRESS, PressureUnit().c_str(), sensorname);
|
||||||
mqtt_data, PressureUnit().c_str(), sensorname);
|
|
||||||
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_TOTAL))
|
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_TOTAL))
|
||||||
|| !strcmp_P(subsensortype, PSTR(D_JSON_TODAY))
|
|| !strcmp_P(subsensortype, PSTR(D_JSON_TODAY))
|
||||||
|| !strcmp_P(subsensortype, PSTR(D_JSON_YESTERDAY))){
|
|| !strcmp_P(subsensortype, PSTR(D_JSON_YESTERDAY))){
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_KWH,
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_KWH, sensorname, subsensortype);
|
||||||
mqtt_data, sensorname, subsensortype);
|
|
||||||
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_POWERUSAGE))){
|
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_POWERUSAGE))){
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_WATT,
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_WATT, sensorname, subsensortype);
|
||||||
mqtt_data, sensorname, subsensortype);
|
|
||||||
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_VOLTAGE))){
|
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_VOLTAGE))){
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_VOLTAGE,
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_VOLTAGE, sensorname, subsensortype);
|
||||||
mqtt_data, sensorname, subsensortype);
|
|
||||||
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_CURRENT))){
|
} else if (!strcmp_P(subsensortype, PSTR(D_JSON_CURRENT))){
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_AMPERE,
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_AMPERE, sensorname, subsensortype);
|
||||||
mqtt_data, sensorname, subsensortype);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_ANY,
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_ANY, sensorname, subsensortype);
|
||||||
mqtt_data, sensorname, subsensortype);
|
|
||||||
}
|
}
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
TryResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
MqttPublish(stopic, true);
|
MqttPublish(stopic, true);
|
||||||
}
|
}
|
||||||
|
@ -509,7 +497,7 @@ void HAssAnnounceStatusSensor(void)
|
||||||
mqtt_data[0] = '\0'; // Clear retained message
|
mqtt_data[0] = '\0'; // Clear retained message
|
||||||
|
|
||||||
// Clear or Set topic
|
// Clear or Set topic
|
||||||
snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s"), ESP.getChipId(), "status");
|
snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_status"), ESP.getChipId());
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id);
|
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id);
|
||||||
|
|
||||||
if (Settings.flag.hass_discovery) {
|
if (Settings.flag.hass_discovery) {
|
||||||
|
@ -518,30 +506,26 @@ void HAssAnnounceStatusSensor(void)
|
||||||
char *state_topic = stemp1;
|
char *state_topic = stemp1;
|
||||||
char *availability_topic = stemp2;
|
char *availability_topic = stemp2;
|
||||||
|
|
||||||
snprintf_P(name, sizeof(name), PSTR("%s %s"), Settings.friendlyname[0], "status");
|
snprintf_P(name, sizeof(name), PSTR("%s status"), Settings.friendlyname[0]);
|
||||||
GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_HASS_STATE));
|
GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_HASS_STATE));
|
||||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||||
FindPrefix(state_topic, availability_topic, prefix);
|
FindPrefix(state_topic, availability_topic, prefix);
|
||||||
Shorten(&state_topic, prefix);
|
Shorten(&state_topic, prefix);
|
||||||
Shorten(&availability_topic, prefix);
|
Shorten(&availability_topic, prefix);
|
||||||
|
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR,
|
Response_P(HASS_DISCOVER_SENSOR, name, state_topic, availability_topic);
|
||||||
name, state_topic, availability_topic);
|
TryResponseAppend_P(HASS_DISCOVER_SENSOR_HASS_STATUS, state_topic);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_HASS_STATUS,
|
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO, unique_id, ESP.getChipId(),
|
||||||
mqtt_data, state_topic);
|
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_DEVICE_INFO, mqtt_data,
|
|
||||||
unique_id, ESP.getChipId(),
|
|
||||||
Settings.friendlyname[0], ModuleName().c_str(), my_version, my_image);
|
Settings.friendlyname[0], ModuleName().c_str(), my_version, my_image);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix);
|
TryResponseAppend_P(HASS_DISCOVER_TOPIC_PREFIX, prefix);
|
||||||
try_snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
TryResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
MqttPublish(stopic, true);
|
MqttPublish(stopic, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAssPublishStatus(void)
|
void HAssPublishStatus(void)
|
||||||
{
|
{
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data),
|
Response_P(PSTR("{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\","
|
||||||
PSTR("{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\","
|
|
||||||
"\"" D_JSON_COREVERSION "\":\"" ARDUINO_ESP8266_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\","
|
"\"" D_JSON_COREVERSION "\":\"" ARDUINO_ESP8266_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\","
|
||||||
"\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\","
|
"\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\","
|
||||||
"\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,"
|
"\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,"
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
|
|
||||||
#define XDRV_13 13
|
#define XDRV_13 13
|
||||||
|
|
||||||
#define DISPLAY_MAX_DRIVERS 16 // Max number of display drivers/models supported by xdsp_interface.ino
|
const uint8_t DISPLAY_MAX_DRIVERS = 16; // Max number of display drivers/models supported by xdsp_interface.ino
|
||||||
#define DISPLAY_MAX_COLS 44 // Max number of columns allowed with command DisplayCols
|
const uint8_t DISPLAY_MAX_COLS = 44; // Max number of columns allowed with command DisplayCols
|
||||||
#define DISPLAY_MAX_ROWS 32 // Max number of lines allowed with command DisplayRows
|
const uint8_t DISPLAY_MAX_ROWS = 32; // Max number of lines allowed with command DisplayRows
|
||||||
|
|
||||||
#define DISPLAY_LOG_ROWS 32 // Number of lines in display log buffer
|
const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log buffer
|
||||||
|
|
||||||
#define D_CMND_DISPLAY "Display"
|
#define D_CMND_DISPLAY "Display"
|
||||||
#define D_CMND_DISP_ADDRESS "Address"
|
#define D_CMND_DISP_ADDRESS "Address"
|
||||||
|
@ -465,7 +465,7 @@ void DisplayText(void)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// unknown escape
|
// unknown escape
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("Unknown Escape"));
|
Response_P(PSTR("Unknown Escape"));
|
||||||
goto exit;
|
goto exit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -503,9 +503,9 @@ void DisplayClearScreenBuffer(void)
|
||||||
|
|
||||||
void DisplayFreeScreenBuffer(void)
|
void DisplayFreeScreenBuffer(void)
|
||||||
{
|
{
|
||||||
if (disp_screen_buffer != NULL) {
|
if (disp_screen_buffer != nullptr) {
|
||||||
for (uint8_t i = 0; i < disp_screen_buffer_rows; i++) {
|
for (uint8_t i = 0; i < disp_screen_buffer_rows; i++) {
|
||||||
if (disp_screen_buffer[i] != NULL) { free(disp_screen_buffer[i]); }
|
if (disp_screen_buffer[i] != nullptr) { free(disp_screen_buffer[i]); }
|
||||||
}
|
}
|
||||||
free(disp_screen_buffer);
|
free(disp_screen_buffer);
|
||||||
disp_screen_buffer_cols = 0;
|
disp_screen_buffer_cols = 0;
|
||||||
|
@ -518,16 +518,16 @@ void DisplayAllocScreenBuffer(void)
|
||||||
if (!disp_screen_buffer_cols) {
|
if (!disp_screen_buffer_cols) {
|
||||||
disp_screen_buffer_rows = Settings.display_rows;
|
disp_screen_buffer_rows = Settings.display_rows;
|
||||||
disp_screen_buffer = (char**)malloc(sizeof(*disp_screen_buffer) * disp_screen_buffer_rows);
|
disp_screen_buffer = (char**)malloc(sizeof(*disp_screen_buffer) * disp_screen_buffer_rows);
|
||||||
if (disp_screen_buffer != NULL) {
|
if (disp_screen_buffer != nullptr) {
|
||||||
for (uint8_t i = 0; i < disp_screen_buffer_rows; i++) {
|
for (uint8_t i = 0; i < disp_screen_buffer_rows; i++) {
|
||||||
disp_screen_buffer[i] = (char*)malloc(sizeof(*disp_screen_buffer[i]) * (Settings.display_cols[0] +1));
|
disp_screen_buffer[i] = (char*)malloc(sizeof(*disp_screen_buffer[i]) * (Settings.display_cols[0] +1));
|
||||||
if (disp_screen_buffer[i] == NULL) {
|
if (disp_screen_buffer[i] == nullptr) {
|
||||||
DisplayFreeScreenBuffer();
|
DisplayFreeScreenBuffer();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (disp_screen_buffer != NULL) {
|
if (disp_screen_buffer != nullptr) {
|
||||||
disp_screen_buffer_cols = Settings.display_cols[0] +1;
|
disp_screen_buffer_cols = Settings.display_cols[0] +1;
|
||||||
DisplayClearScreenBuffer();
|
DisplayClearScreenBuffer();
|
||||||
}
|
}
|
||||||
|
@ -562,9 +562,9 @@ void DisplayClearLogBuffer(void)
|
||||||
|
|
||||||
void DisplayFreeLogBuffer(void)
|
void DisplayFreeLogBuffer(void)
|
||||||
{
|
{
|
||||||
if (disp_log_buffer != NULL) {
|
if (disp_log_buffer != nullptr) {
|
||||||
for (uint8_t i = 0; i < DISPLAY_LOG_ROWS; i++) {
|
for (uint8_t i = 0; i < DISPLAY_LOG_ROWS; i++) {
|
||||||
if (disp_log_buffer[i] != NULL) { free(disp_log_buffer[i]); }
|
if (disp_log_buffer[i] != nullptr) { free(disp_log_buffer[i]); }
|
||||||
}
|
}
|
||||||
free(disp_log_buffer);
|
free(disp_log_buffer);
|
||||||
disp_log_buffer_cols = 0;
|
disp_log_buffer_cols = 0;
|
||||||
|
@ -575,16 +575,16 @@ void DisplayAllocLogBuffer(void)
|
||||||
{
|
{
|
||||||
if (!disp_log_buffer_cols) {
|
if (!disp_log_buffer_cols) {
|
||||||
disp_log_buffer = (char**)malloc(sizeof(*disp_log_buffer) * DISPLAY_LOG_ROWS);
|
disp_log_buffer = (char**)malloc(sizeof(*disp_log_buffer) * DISPLAY_LOG_ROWS);
|
||||||
if (disp_log_buffer != NULL) {
|
if (disp_log_buffer != nullptr) {
|
||||||
for (uint8_t i = 0; i < DISPLAY_LOG_ROWS; i++) {
|
for (uint8_t i = 0; i < DISPLAY_LOG_ROWS; i++) {
|
||||||
disp_log_buffer[i] = (char*)malloc(sizeof(*disp_log_buffer[i]) * (Settings.display_cols[0] +1));
|
disp_log_buffer[i] = (char*)malloc(sizeof(*disp_log_buffer[i]) * (Settings.display_cols[0] +1));
|
||||||
if (disp_log_buffer[i] == NULL) {
|
if (disp_log_buffer[i] == nullptr) {
|
||||||
DisplayFreeLogBuffer();
|
DisplayFreeLogBuffer();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (disp_log_buffer != NULL) {
|
if (disp_log_buffer != nullptr) {
|
||||||
disp_log_buffer_cols = Settings.display_cols[0] +1;
|
disp_log_buffer_cols = Settings.display_cols[0] +1;
|
||||||
DisplayClearLogBuffer();
|
DisplayClearLogBuffer();
|
||||||
}
|
}
|
||||||
|
@ -608,7 +608,7 @@ void DisplayLogBufferAdd(char* txt)
|
||||||
|
|
||||||
char* DisplayLogBuffer(char temp_code)
|
char* DisplayLogBuffer(char temp_code)
|
||||||
{
|
{
|
||||||
char* result = NULL;
|
char* result = nullptr;
|
||||||
if (disp_log_buffer_cols) {
|
if (disp_log_buffer_cols) {
|
||||||
if (disp_log_buffer_idx != disp_log_buffer_ptr) {
|
if (disp_log_buffer_idx != disp_log_buffer_ptr) {
|
||||||
result = disp_log_buffer[disp_log_buffer_ptr];
|
result = disp_log_buffer[disp_log_buffer_ptr];
|
||||||
|
@ -616,7 +616,7 @@ char* DisplayLogBuffer(char temp_code)
|
||||||
if (DISPLAY_LOG_ROWS == disp_log_buffer_ptr) { disp_log_buffer_ptr = 0; }
|
if (DISPLAY_LOG_ROWS == disp_log_buffer_ptr) { disp_log_buffer_ptr = 0; }
|
||||||
|
|
||||||
char *pch = strchr(result, '~'); // = 0x7E (~) Replace degrees character (276 octal)
|
char *pch = strchr(result, '~'); // = 0x7E (~) Replace degrees character (276 octal)
|
||||||
if (pch != NULL) { result[pch - result] = temp_code; }
|
if (pch != nullptr) { result[pch - result] = temp_code; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -829,12 +829,12 @@ void DisplayMqttSubscribe(void)
|
||||||
ntopic[0] = '\0';
|
ntopic[0] = '\0';
|
||||||
strlcpy(stopic, Settings.mqtt_fulltopic, sizeof(stopic));
|
strlcpy(stopic, Settings.mqtt_fulltopic, sizeof(stopic));
|
||||||
char *tp = strtok(stopic, "/");
|
char *tp = strtok(stopic, "/");
|
||||||
while (tp != NULL) {
|
while (tp != nullptr) {
|
||||||
if (!strcmp_P(tp, PSTR(MQTT_TOKEN_PREFIX))) {
|
if (!strcmp_P(tp, MQTT_TOKEN_PREFIX)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
strncat_P(ntopic, PSTR("+/"), sizeof(ntopic) - strlen(ntopic) -1); // Add single-level wildcards
|
strncat_P(ntopic, PSTR("+/"), sizeof(ntopic) - strlen(ntopic) -1); // Add single-level wildcards
|
||||||
tp = strtok(NULL, "/");
|
tp = strtok(nullptr, "/");
|
||||||
}
|
}
|
||||||
strncat(ntopic, Settings.mqtt_prefix[2], sizeof(ntopic) - strlen(ntopic) -1); // Subscribe to tele messages
|
strncat(ntopic, Settings.mqtt_prefix[2], sizeof(ntopic) - strlen(ntopic) -1); // Subscribe to tele messages
|
||||||
strncat_P(ntopic, PSTR("/#"), sizeof(ntopic) - strlen(ntopic) -1); // Add multi-level wildcard
|
strncat_P(ntopic, PSTR("/#"), sizeof(ntopic) - strlen(ntopic) -1); // Add multi-level wildcard
|
||||||
|
@ -921,7 +921,7 @@ bool DisplayCommand(void)
|
||||||
serviced = false; // Unknown command
|
serviced = false; // Unknown command
|
||||||
}
|
}
|
||||||
else if (CMND_DISPLAY == command_code) {
|
else if (CMND_DISPLAY == command_code) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DISPLAY "\":{\"" D_CMND_DISP_MODEL "\":%d,\"" D_CMND_DISP_MODE "\":%d,\"" D_CMND_DISP_DIMMER "\":%d,\""
|
Response_P(PSTR("{\"" D_CMND_DISPLAY "\":{\"" D_CMND_DISP_MODEL "\":%d,\"" D_CMND_DISP_MODE "\":%d,\"" D_CMND_DISP_DIMMER "\":%d,\""
|
||||||
D_CMND_DISP_SIZE "\":%d,\"" D_CMND_DISP_FONT "\":%d,\"" D_CMND_DISP_ROTATE "\":%d,\"" D_CMND_DISP_REFRESH "\":%d,\"" D_CMND_DISP_COLS "\":[%d,%d],\"" D_CMND_DISP_ROWS "\":%d}}"),
|
D_CMND_DISP_SIZE "\":%d,\"" D_CMND_DISP_FONT "\":%d,\"" D_CMND_DISP_ROTATE "\":%d,\"" D_CMND_DISP_REFRESH "\":%d,\"" D_CMND_DISP_COLS "\":[%d,%d],\"" D_CMND_DISP_ROWS "\":%d}}"),
|
||||||
Settings.display_model, Settings.display_mode, Settings.display_dimmer, Settings.display_size, Settings.display_font, Settings.display_rotate, Settings.display_refresh,
|
Settings.display_model, Settings.display_mode, Settings.display_dimmer, Settings.display_size, Settings.display_font, Settings.display_rotate, Settings.display_refresh,
|
||||||
Settings.display_cols[0], Settings.display_cols[1], Settings.display_rows);
|
Settings.display_cols[0], Settings.display_cols[1], Settings.display_rows);
|
||||||
|
@ -936,7 +936,7 @@ bool DisplayCommand(void)
|
||||||
Settings.display_model = last_display_model;
|
Settings.display_model = last_display_model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_model);
|
Response_P(S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_model);
|
||||||
}
|
}
|
||||||
else if (CMND_DISP_MODE == command_code) {
|
else if (CMND_DISP_MODE == command_code) {
|
||||||
#ifdef USE_DISPLAY_MODES1TO5
|
#ifdef USE_DISPLAY_MODES1TO5
|
||||||
|
@ -964,7 +964,7 @@ bool DisplayCommand(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_DISPLAY_MODES1TO5
|
#endif // USE_DISPLAY_MODES1TO5
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_mode);
|
Response_P(S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_mode);
|
||||||
}
|
}
|
||||||
else if (CMND_DISP_DIMMER == command_code) {
|
else if (CMND_DISP_DIMMER == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
||||||
|
@ -976,19 +976,19 @@ bool DisplayCommand(void)
|
||||||
ExecuteCommandPower(disp_device, POWER_OFF, SRC_DISPLAY);
|
ExecuteCommandPower(disp_device, POWER_OFF, SRC_DISPLAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_dimmer);
|
Response_P(S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_dimmer);
|
||||||
}
|
}
|
||||||
else if (CMND_DISP_SIZE == command_code) {
|
else if (CMND_DISP_SIZE == command_code) {
|
||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) {
|
||||||
Settings.display_size = XdrvMailbox.payload;
|
Settings.display_size = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_size);
|
Response_P(S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_size);
|
||||||
}
|
}
|
||||||
else if (CMND_DISP_FONT == command_code) {
|
else if (CMND_DISP_FONT == command_code) {
|
||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) {
|
||||||
Settings.display_font = XdrvMailbox.payload;
|
Settings.display_font = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_font);
|
Response_P(S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_font);
|
||||||
}
|
}
|
||||||
else if (CMND_DISP_ROTATE == command_code) {
|
else if (CMND_DISP_ROTATE == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 4)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 4)) {
|
||||||
|
@ -1011,7 +1011,7 @@ bool DisplayCommand(void)
|
||||||
#endif // USE_DISPLAY_MODES1TO5
|
#endif // USE_DISPLAY_MODES1TO5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_rotate);
|
Response_P(S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_rotate);
|
||||||
}
|
}
|
||||||
else if (CMND_DISP_TEXT == command_code) {
|
else if (CMND_DISP_TEXT == command_code) {
|
||||||
mqtt_data[0] = '\0';
|
mqtt_data[0] = '\0';
|
||||||
|
@ -1026,23 +1026,23 @@ bool DisplayCommand(void)
|
||||||
}
|
}
|
||||||
#endif // USE_DISPLAY_MODES1TO5
|
#endif // USE_DISPLAY_MODES1TO5
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("No Text"));
|
Response_P(PSTR("No Text"));
|
||||||
}
|
}
|
||||||
if (mqtt_data[0] == '\0') {
|
if (mqtt_data[0] == '\0') {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_VALUE, command, XdrvMailbox.data);
|
Response_P(S_JSON_DISPLAY_COMMAND_VALUE, command, XdrvMailbox.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((CMND_DISP_ADDRESS == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 8)) {
|
else if ((CMND_DISP_ADDRESS == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 8)) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) {
|
||||||
Settings.display_address[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
Settings.display_address[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.display_address[XdrvMailbox.index -1]);
|
Response_P(S_JSON_DISPLAY_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.display_address[XdrvMailbox.index -1]);
|
||||||
}
|
}
|
||||||
else if (CMND_DISP_REFRESH == command_code) {
|
else if (CMND_DISP_REFRESH == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 7)) {
|
if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 7)) {
|
||||||
Settings.display_refresh = XdrvMailbox.payload;
|
Settings.display_refresh = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_refresh);
|
Response_P(S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_refresh);
|
||||||
}
|
}
|
||||||
else if ((CMND_DISP_COLS == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
|
else if ((CMND_DISP_COLS == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
|
||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= DISPLAY_MAX_COLS)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= DISPLAY_MAX_COLS)) {
|
||||||
|
@ -1054,7 +1054,7 @@ bool DisplayCommand(void)
|
||||||
}
|
}
|
||||||
#endif // USE_DISPLAY_MODES1TO5
|
#endif // USE_DISPLAY_MODES1TO5
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.display_cols[XdrvMailbox.index -1]);
|
Response_P(S_JSON_DISPLAY_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.display_cols[XdrvMailbox.index -1]);
|
||||||
}
|
}
|
||||||
else if (CMND_DISP_ROWS == command_code) {
|
else if (CMND_DISP_ROWS == command_code) {
|
||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= DISPLAY_MAX_ROWS)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= DISPLAY_MAX_ROWS)) {
|
||||||
|
@ -1064,7 +1064,7 @@ bool DisplayCommand(void)
|
||||||
DisplayReAllocScreenBuffer();
|
DisplayReAllocScreenBuffer();
|
||||||
#endif // USE_DISPLAY_MODES1TO5
|
#endif // USE_DISPLAY_MODES1TO5
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_rows);
|
Response_P(S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_rows);
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,7 @@ bool MP3PlayerCmd(void) {
|
||||||
if (command_code == CMND_MP3_DEVICE) { MP3_CMD(MP3_CMD_DEVICE, XdrvMailbox.payload); }
|
if (command_code == CMND_MP3_DEVICE) { MP3_CMD(MP3_CMD_DEVICE, XdrvMailbox.payload); }
|
||||||
if (command_code == CMND_MP3_DAC) { MP3_CMD(MP3_CMD_DAC, XdrvMailbox.payload); }
|
if (command_code == CMND_MP3_DAC) { MP3_CMD(MP3_CMD_DAC, XdrvMailbox.payload); }
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND_NVALUE, command, XdrvMailbox.payload);
|
Response_P(S_JSON_MP3_COMMAND_NVALUE, command, XdrvMailbox.payload);
|
||||||
break;
|
break;
|
||||||
case CMND_MP3_PLAY:
|
case CMND_MP3_PLAY:
|
||||||
case CMND_MP3_PAUSE:
|
case CMND_MP3_PAUSE:
|
||||||
|
@ -211,7 +211,7 @@ bool MP3PlayerCmd(void) {
|
||||||
if (command_code == CMND_MP3_PAUSE) { MP3_CMD(MP3_CMD_PAUSE, 0); }
|
if (command_code == CMND_MP3_PAUSE) { MP3_CMD(MP3_CMD_PAUSE, 0); }
|
||||||
if (command_code == CMND_MP3_STOP) { MP3_CMD(MP3_CMD_STOP, 0); }
|
if (command_code == CMND_MP3_STOP) { MP3_CMD(MP3_CMD_STOP, 0); }
|
||||||
if (command_code == CMND_MP3_RESET) { MP3_CMD(MP3_CMD_RESET, 0); }
|
if (command_code == CMND_MP3_RESET) { MP3_CMD(MP3_CMD_RESET, 0); }
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND, command, XdrvMailbox.payload);
|
Response_P(S_JSON_MP3_COMMAND, command, XdrvMailbox.payload);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// else for Unknown command
|
// else for Unknown command
|
||||||
|
|
|
@ -60,7 +60,7 @@ void PCA9685_Reset(void)
|
||||||
PCA9685_SetPWM(pin,0,false);
|
PCA9685_SetPWM(pin,0,false);
|
||||||
pca9685_pin_pwm_value[pin] = 0;
|
pca9685_pin_pwm_value[pin] = 0;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"RESET\":\"OK\"}}"));
|
Response_P(PSTR("{\"PCA9685\":{\"RESET\":\"OK\"}}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCA9685_SetPWMfreq(double freq) {
|
void PCA9685_SetPWMfreq(double freq) {
|
||||||
|
@ -127,11 +127,11 @@ bool PCA9685_Command(void)
|
||||||
uint16_t new_freq = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
uint16_t new_freq = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||||
if ((new_freq >= 24) && (new_freq <= 1526)) {
|
if ((new_freq >= 24) && (new_freq <= 1526)) {
|
||||||
PCA9685_SetPWMfreq(new_freq);
|
PCA9685_SetPWMfreq(new_freq);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"PWMF\":%i, \"Result\":\"OK\"}}"),new_freq);
|
Response_P(PSTR("{\"PCA9685\":{\"PWMF\":%i, \"Result\":\"OK\"}}"),new_freq);
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
} else { // No parameter was given for setfreq, so we return current setting
|
} else { // No parameter was given for setfreq, so we return current setting
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"PWMF\":%i}}"),pca9685_freq);
|
Response_P(PSTR("{\"PCA9685\":{\"PWMF\":%i}}"),pca9685_freq);
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,20 +141,20 @@ bool PCA9685_Command(void)
|
||||||
if (paramcount > 2) {
|
if (paramcount > 2) {
|
||||||
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 3), "ON")) {
|
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 3), "ON")) {
|
||||||
PCA9685_SetPWM(pin, 4096, false);
|
PCA9685_SetPWM(pin, 4096, false);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"PIN\":%i,\"PWM\":%i}}"),pin,4096);
|
Response_P(PSTR("{\"PCA9685\":{\"PIN\":%i,\"PWM\":%i}}"),pin,4096);
|
||||||
serviced = true;
|
serviced = true;
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 3), "OFF")) {
|
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 3), "OFF")) {
|
||||||
PCA9685_SetPWM(pin, 0, false);
|
PCA9685_SetPWM(pin, 0, false);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"PIN\":%i,\"PWM\":%i}}"),pin,0);
|
Response_P(PSTR("{\"PCA9685\":{\"PIN\":%i,\"PWM\":%i}}"),pin,0);
|
||||||
serviced = true;
|
serviced = true;
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
uint16_t pwm = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3));
|
uint16_t pwm = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3));
|
||||||
if ((pin >= 0 && pin <= 15) && (pwm >= 0 && pwm <= 4096)) {
|
if ((pin >= 0 && pin <= 15) && (pwm >= 0 && pwm <= 4096)) {
|
||||||
PCA9685_SetPWM(pin, pwm, false);
|
PCA9685_SetPWM(pin, pwm, false);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"PIN\":%i,\"PWM\":%i}}"),pin,pwm);
|
Response_P(PSTR("{\"PCA9685\":{\"PIN\":%i,\"PWM\":%i}}"),pin,pwm);
|
||||||
serviced = true;
|
serviced = true;
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
@ -166,12 +166,12 @@ bool PCA9685_Command(void)
|
||||||
|
|
||||||
void PCA9685_OutputTelemetry(bool telemetry) {
|
void PCA9685_OutputTelemetry(bool telemetry) {
|
||||||
if (0 == pca9685_detected) { return; } // We do not do this if the PCA9685 has not been detected
|
if (0 == pca9685_detected) { return; } // We do not do this if the PCA9685 has not been detected
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"PCA9685\": {"), GetDateAndTime(DT_LOCAL).c_str());
|
Response_P(PSTR("{\"" D_JSON_TIME "\":\"%s\",\"PCA9685\": {"), GetDateAndTime(DT_LOCAL).c_str());
|
||||||
snprintf_P(mqtt_data,sizeof(mqtt_data), PSTR("%s\"PWM_FREQ\":%i,"),mqtt_data,pca9685_freq);
|
ResponseAppend_P(PSTR("\"PWM_FREQ\":%i,"),pca9685_freq);
|
||||||
for (uint8_t pin=0;pin<16;pin++) {
|
for (uint8_t pin=0;pin<16;pin++) {
|
||||||
snprintf_P(mqtt_data,sizeof(mqtt_data), PSTR("%s\"PWM%i\":%i,"),mqtt_data,pin,pca9685_pin_pwm_value[pin]);
|
ResponseAppend_P(PSTR("\"PWM%i\":%i,"),pin,pca9685_pin_pwm_value[pin]);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data,sizeof(mqtt_data),PSTR("%s\"END\":1}}"),mqtt_data);
|
ResponseAppend_P(PSTR("\"END\":1}}"));
|
||||||
if (telemetry) {
|
if (telemetry) {
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||||
}
|
}
|
||||||
|
@ -189,9 +189,9 @@ bool Xdrv15(uint8_t function)
|
||||||
PCA9685_OutputTelemetry(true);
|
PCA9685_OutputTelemetry(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND_DRIVER:
|
||||||
if (XDRV_15 == XdrvMailbox.index) {
|
if (XDRV_15 == XdrvMailbox.index) {
|
||||||
PCA9685_Command();
|
result = PCA9685_Command();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -53,7 +53,7 @@ uint8_t tuya_cmd_checksum = 0; // Checksum of tuya command
|
||||||
uint8_t tuya_data_len = 0; // Data lenght of command
|
uint8_t tuya_data_len = 0; // Data lenght of command
|
||||||
int8_t tuya_wifi_state = -2; // Keep MCU wifi-status in sync with WifiState()
|
int8_t tuya_wifi_state = -2; // Keep MCU wifi-status in sync with WifiState()
|
||||||
|
|
||||||
char *tuya_buffer = NULL; // Serial receive buffer
|
char *tuya_buffer = nullptr; // Serial receive buffer
|
||||||
int tuya_byte_counter = 0; // Index in serial receive buffer
|
int tuya_byte_counter = 0; // Index in serial receive buffer
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -284,7 +284,7 @@ void TuyaInit(void)
|
||||||
Settings.param[P_TUYA_DIMMER_ID] = TUYA_DIMMER_ID;
|
Settings.param[P_TUYA_DIMMER_ID] = TUYA_DIMMER_ID;
|
||||||
}
|
}
|
||||||
tuya_buffer = (char*)(malloc(TUYA_BUFFER_SIZE));
|
tuya_buffer = (char*)(malloc(TUYA_BUFFER_SIZE));
|
||||||
if (tuya_buffer != NULL) {
|
if (tuya_buffer != nullptr) {
|
||||||
TuyaSerial = new TasmotaSerial(pin[GPIO_TUYA_RX], pin[GPIO_TUYA_TX], 2);
|
TuyaSerial = new TasmotaSerial(pin[GPIO_TUYA_RX], pin[GPIO_TUYA_TX], 2);
|
||||||
if (TuyaSerial->begin(9600)) {
|
if (TuyaSerial->begin(9600)) {
|
||||||
if (TuyaSerial->hardwareSerial()) { ClaimSerial(); }
|
if (TuyaSerial->hardwareSerial()) { ClaimSerial(); }
|
||||||
|
@ -393,15 +393,15 @@ bool Xdrv16(uint8_t function)
|
||||||
|
|
||||||
if (TUYA_DIMMER == my_module_type) {
|
if (TUYA_DIMMER == my_module_type) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
|
case FUNC_LOOP:
|
||||||
|
if (TuyaSerial) { TuyaSerialInput(); }
|
||||||
|
break;
|
||||||
case FUNC_MODULE_INIT:
|
case FUNC_MODULE_INIT:
|
||||||
result = TuyaModuleSelected();
|
result = TuyaModuleSelected();
|
||||||
break;
|
break;
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
TuyaInit();
|
TuyaInit();
|
||||||
break;
|
break;
|
||||||
case FUNC_LOOP:
|
|
||||||
if (TuyaSerial) { TuyaSerialInput(); }
|
|
||||||
break;
|
|
||||||
case FUNC_SET_DEVICE_POWER:
|
case FUNC_SET_DEVICE_POWER:
|
||||||
result = TuyaSetPower();
|
result = TuyaSetPower();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -61,7 +61,7 @@ void RfReceiveCheck(void)
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("\"0x%lX\""), (uint32_t)data);
|
snprintf_P(stemp, sizeof(stemp), PSTR("\"0x%lX\""), (uint32_t)data);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_RF_DATA "\":%s,\"" D_JSON_RF_BITS "\":%d,\"" D_JSON_RF_PROTOCOL "\":%d,\"" D_JSON_RF_PULSE "\":%d}}"),
|
Response_P(PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_RF_DATA "\":%s,\"" D_JSON_RF_BITS "\":%d,\"" D_JSON_RF_PROTOCOL "\":%d,\"" D_JSON_RF_PULSE "\":%d}}"),
|
||||||
stemp, bits, protocol, delay);
|
stemp, bits, protocol, delay);
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
|
@ -107,7 +107,7 @@ bool RfSendCommand(void)
|
||||||
if (root.success()) {
|
if (root.success()) {
|
||||||
// RFsend {"data":0x501014,"bits":24,"protocol":1,"repeat":10,"pulse":350}
|
// RFsend {"data":0x501014,"bits":24,"protocol":1,"repeat":10,"pulse":350}
|
||||||
char parm_uc[10];
|
char parm_uc[10];
|
||||||
data = strtoul(root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_DATA))], NULL, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
|
data = strtoul(root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_DATA))], nullptr, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
|
||||||
bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_BITS))];
|
bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_BITS))];
|
||||||
protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_PROTOCOL))];
|
protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_PROTOCOL))];
|
||||||
repeat = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_REPEAT))];
|
repeat = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_REPEAT))];
|
||||||
|
@ -116,10 +116,10 @@ bool RfSendCommand(void)
|
||||||
// RFsend data, bits, protocol, repeat, pulse
|
// RFsend data, bits, protocol, repeat, pulse
|
||||||
char *p;
|
char *p;
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 5; str = strtok_r(NULL, ", ", &p)) {
|
for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 5; str = strtok_r(nullptr, ", ", &p)) {
|
||||||
switch (i++) {
|
switch (i++) {
|
||||||
case 0:
|
case 0:
|
||||||
data = strtoul(str, NULL, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
|
data = strtoul(str, nullptr, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
bits = atoi(str);
|
bits = atoi(str);
|
||||||
|
@ -145,7 +145,7 @@ bool RfSendCommand(void)
|
||||||
if (!bits) { bits = 24; } // Default 24 bits
|
if (!bits) { bits = 24; } // Default 24 bits
|
||||||
if (data) {
|
if (data) {
|
||||||
mySwitch.send(data, bits);
|
mySwitch.send(data, bits);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_DONE "\"}"));
|
Response_P(PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_DONE "\"}"));
|
||||||
} else {
|
} else {
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ bool RfSendCommand(void)
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_NO " " D_JSON_RF_DATA ", " D_JSON_RF_BITS ", " D_JSON_RF_PROTOCOL ", " D_JSON_RF_REPEAT " " D_JSON_OR " " D_JSON_RF_PULSE "\"}"));
|
Response_P(PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_NO " " D_JSON_RF_DATA ", " D_JSON_RF_BITS ", " D_JSON_RF_PROTOCOL ", " D_JSON_RF_REPEAT " " D_JSON_OR " " D_JSON_RF_PULSE "\"}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
|
@ -170,15 +170,15 @@ bool Xdrv18(uint8_t function)
|
||||||
|
|
||||||
if (ARMTRONIX_DIMMERS == my_module_type) {
|
if (ARMTRONIX_DIMMERS == my_module_type) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
|
case FUNC_LOOP:
|
||||||
|
if (ArmtronixSerial) { ArmtronixSerialInput(); }
|
||||||
|
break;
|
||||||
case FUNC_MODULE_INIT:
|
case FUNC_MODULE_INIT:
|
||||||
result = ArmtronixModuleSelected();
|
result = ArmtronixModuleSelected();
|
||||||
break;
|
break;
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
ArmtronixInit();
|
ArmtronixInit();
|
||||||
break;
|
break;
|
||||||
case FUNC_LOOP:
|
|
||||||
if (ArmtronixSerial) { ArmtronixSerialInput(); }
|
|
||||||
break;
|
|
||||||
case FUNC_EVERY_SECOND:
|
case FUNC_EVERY_SECOND:
|
||||||
if (ArmtronixSerial) {
|
if (ArmtronixSerial) {
|
||||||
if (armtronix_wifi_state!=WifiState()) { ArmtronixSetWifiLed(); }
|
if (armtronix_wifi_state!=WifiState()) { ArmtronixSetWifiLed(); }
|
||||||
|
|
|
@ -35,8 +35,8 @@ bool ps16dz_ignore_dim = false; // Flag to skip serial send to preven
|
||||||
|
|
||||||
//uint64_t ps16dz_seq = 0;
|
//uint64_t ps16dz_seq = 0;
|
||||||
|
|
||||||
char *ps16dz_tx_buffer = NULL; // Serial transmit buffer
|
char *ps16dz_tx_buffer = nullptr; // Serial transmit buffer
|
||||||
char *ps16dz_rx_buffer = NULL; // Serial receive buffer
|
char *ps16dz_rx_buffer = nullptr; // Serial receive buffer
|
||||||
int ps16dz_byte_counter = 0;
|
int ps16dz_byte_counter = 0;
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -135,9 +135,9 @@ bool PS16DZModuleSelected(void)
|
||||||
void PS16DZInit(void)
|
void PS16DZInit(void)
|
||||||
{
|
{
|
||||||
ps16dz_tx_buffer = (char*)(malloc(PS16DZ_BUFFER_SIZE));
|
ps16dz_tx_buffer = (char*)(malloc(PS16DZ_BUFFER_SIZE));
|
||||||
if (ps16dz_tx_buffer != NULL) {
|
if (ps16dz_tx_buffer != nullptr) {
|
||||||
ps16dz_rx_buffer = (char*)(malloc(PS16DZ_BUFFER_SIZE));
|
ps16dz_rx_buffer = (char*)(malloc(PS16DZ_BUFFER_SIZE));
|
||||||
if (ps16dz_rx_buffer != NULL) {
|
if (ps16dz_rx_buffer != nullptr) {
|
||||||
PS16DZSerial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 2);
|
PS16DZSerial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 2);
|
||||||
if (PS16DZSerial->begin(19200)) {
|
if (PS16DZSerial->begin(19200)) {
|
||||||
if (PS16DZSerial->hardwareSerial()) { ClaimSerial(); }
|
if (PS16DZSerial->hardwareSerial()) { ClaimSerial(); }
|
||||||
|
@ -168,10 +168,10 @@ void PS16DZSerialInput(void)
|
||||||
char *end_str;
|
char *end_str;
|
||||||
char *string = ps16dz_rx_buffer+10;
|
char *string = ps16dz_rx_buffer+10;
|
||||||
char* token = strtok_r(string, ",", &end_str);
|
char* token = strtok_r(string, ",", &end_str);
|
||||||
while (token != NULL) {
|
while (token != nullptr) {
|
||||||
char* end_token;
|
char* end_token;
|
||||||
char* token2 = strtok_r(token, ":", &end_token);
|
char* token2 = strtok_r(token, ":", &end_token);
|
||||||
char* token3 = strtok_r(NULL, ":", &end_token);
|
char* token3 = strtok_r(nullptr, ":", &end_token);
|
||||||
if(!strncmp(token2, "\"switch\"", 8)){
|
if(!strncmp(token2, "\"switch\"", 8)){
|
||||||
bool ps16dz_power = !strncmp(token3, "\"on\"", 4)?true:false;
|
bool ps16dz_power = !strncmp(token3, "\"on\"", 4)?true:false;
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: power received: %s"), token3);
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: power received: %s"), token3);
|
||||||
|
@ -193,10 +193,10 @@ void PS16DZSerialInput(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!strncmp(token2, "\"sequence\"", 10)){
|
else if(!strncmp(token2, "\"sequence\"", 10)){
|
||||||
//ps16dz_seq = strtoull(token3+1, NULL, 10);
|
//ps16dz_seq = strtoull(token3+1, nullptr, 10);
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: sequence received: %s"), token3);
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: sequence received: %s"), token3);
|
||||||
}
|
}
|
||||||
token = strtok_r(NULL, ",", &end_str);
|
token = strtok_r(nullptr, ",", &end_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!strncmp(ps16dz_rx_buffer+3, "SETTING", 7)) {
|
else if(!strncmp(ps16dz_rx_buffer+3, "SETTING", 7)) {
|
||||||
|
@ -223,15 +223,15 @@ bool Xdrv19(uint8_t function)
|
||||||
|
|
||||||
if (PS_16_DZ == my_module_type) {
|
if (PS_16_DZ == my_module_type) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
|
case FUNC_LOOP:
|
||||||
|
if (PS16DZSerial) { PS16DZSerialInput(); }
|
||||||
|
break;
|
||||||
case FUNC_MODULE_INIT:
|
case FUNC_MODULE_INIT:
|
||||||
result = PS16DZModuleSelected();
|
result = PS16DZModuleSelected();
|
||||||
break;
|
break;
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
PS16DZInit();
|
PS16DZInit();
|
||||||
break;
|
break;
|
||||||
case FUNC_LOOP:
|
|
||||||
if (PS16DZSerial) { PS16DZSerialInput(); }
|
|
||||||
break;
|
|
||||||
case FUNC_SET_DEVICE_POWER:
|
case FUNC_SET_DEVICE_POWER:
|
||||||
result = PS16DZSetPower();
|
result = PS16DZSetPower();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -419,28 +419,28 @@ bool DebugCommand(void)
|
||||||
}
|
}
|
||||||
else if (CMND_HELP == command_code) {
|
else if (CMND_HELP == command_code) {
|
||||||
AddLog_P(LOG_LEVEL_INFO, kDebugCommands);
|
AddLog_P(LOG_LEVEL_INFO, kDebugCommands);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
else if (CMND_RTCDUMP == command_code) {
|
else if (CMND_RTCDUMP == command_code) {
|
||||||
DebugRtcDump(XdrvMailbox.data);
|
DebugRtcDump(XdrvMailbox.data);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
else if (CMND_CFGDUMP == command_code) {
|
else if (CMND_CFGDUMP == command_code) {
|
||||||
DebugCfgDump(XdrvMailbox.data);
|
DebugCfgDump(XdrvMailbox.data);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
else if (CMND_CFGPEEK == command_code) {
|
else if (CMND_CFGPEEK == command_code) {
|
||||||
DebugCfgPeek(XdrvMailbox.data);
|
DebugCfgPeek(XdrvMailbox.data);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
else if (CMND_CFGPOKE == command_code) {
|
else if (CMND_CFGPOKE == command_code) {
|
||||||
DebugCfgPoke(XdrvMailbox.data);
|
DebugCfgPoke(XdrvMailbox.data);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
#ifdef USE_DEBUG_SETTING_NAMES
|
#ifdef USE_DEBUG_SETTING_NAMES
|
||||||
else if (CMND_CFGSHOW == command_code) {
|
else if (CMND_CFGSHOW == command_code) {
|
||||||
DebugCfgShow(XdrvMailbox.payload);
|
DebugCfgShow(XdrvMailbox.payload);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
#endif // USE_DEBUG_SETTING_NAMES
|
#endif // USE_DEBUG_SETTING_NAMES
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
|
@ -448,13 +448,13 @@ bool DebugCommand(void)
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
config_xor_on_set = XdrvMailbox.payload;
|
config_xor_on_set = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, config_xor_on_set);
|
Response_P(S_JSON_COMMAND_NVALUE, command, config_xor_on_set);
|
||||||
}
|
}
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
#ifdef DEBUG_THEO
|
#ifdef DEBUG_THEO
|
||||||
else if (CMND_EXCEPTION == command_code) {
|
else if (CMND_EXCEPTION == command_code) {
|
||||||
if (XdrvMailbox.data_len > 0) ExceptionTest(XdrvMailbox.payload);
|
if (XdrvMailbox.data_len > 0) ExceptionTest(XdrvMailbox.payload);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
#endif // DEBUG_THEO
|
#endif // DEBUG_THEO
|
||||||
else if (CMND_CPUCHECK == command_code) {
|
else if (CMND_CPUCHECK == command_code) {
|
||||||
|
@ -462,26 +462,26 @@ bool DebugCommand(void)
|
||||||
CPU_load_check = XdrvMailbox.payload;
|
CPU_load_check = XdrvMailbox.payload;
|
||||||
CPU_last_millis = CPU_last_loop_time;
|
CPU_last_millis = CPU_last_loop_time;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, CPU_load_check);
|
Response_P(S_JSON_COMMAND_NVALUE, command, CPU_load_check);
|
||||||
}
|
}
|
||||||
else if (CMND_FREEMEM == command_code) {
|
else if (CMND_FREEMEM == command_code) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
CPU_show_freemem = XdrvMailbox.payload;
|
CPU_show_freemem = XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, CPU_show_freemem);
|
Response_P(S_JSON_COMMAND_NVALUE, command, CPU_show_freemem);
|
||||||
}
|
}
|
||||||
else if ((CMND_SETSENSOR == command_code) && (XdrvMailbox.index < MAX_XSNS_DRIVERS)) {
|
else if ((CMND_SETSENSOR == command_code) && (XdrvMailbox.index < MAX_XSNS_DRIVERS)) {
|
||||||
if ((XdrvMailbox.payload >= 0) && XsnsPresent(XdrvMailbox.index)) {
|
if ((XdrvMailbox.payload >= 0) && XsnsPresent(XdrvMailbox.index)) {
|
||||||
bitWrite(Settings.sensors[XdrvMailbox.index / 32], XdrvMailbox.index % 32, XdrvMailbox.payload &1);
|
bitWrite(Settings.sensors[XdrvMailbox.index / 32], XdrvMailbox.index % 32, XdrvMailbox.payload &1);
|
||||||
if (1 == XdrvMailbox.payload) { restart_flag = 2; } // To safely re-enable a sensor currently most sensor need to follow complete restart init cycle
|
if (1 == XdrvMailbox.payload) { restart_flag = 2; } // To safely re-enable a sensor currently most sensor need to follow complete restart init cycle
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_XVALUE, command, XsnsGetSensors().c_str());
|
Response_P(S_JSON_COMMAND_XVALUE, command, XsnsGetSensors().c_str());
|
||||||
}
|
}
|
||||||
else if (CMND_FLASHMODE == command_code) {
|
else if (CMND_FLASHMODE == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) {
|
||||||
SetFlashMode(XdrvMailbox.payload);
|
SetFlashMode(XdrvMailbox.payload);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, ESP.getFlashChipMode());
|
Response_P(S_JSON_COMMAND_NVALUE, command, ESP.getFlashChipMode());
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
|
@ -497,12 +497,12 @@ bool Xdrv99(uint8_t function)
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case FUNC_PRE_INIT:
|
|
||||||
CPU_last_millis = millis();
|
|
||||||
break;
|
|
||||||
case FUNC_LOOP:
|
case FUNC_LOOP:
|
||||||
CpuLoadLoop();
|
CpuLoadLoop();
|
||||||
break;
|
break;
|
||||||
|
case FUNC_PRE_INIT:
|
||||||
|
CPU_last_millis = millis();
|
||||||
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = DebugCommand();
|
result = DebugCommand();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -210,7 +210,7 @@ bool XdrvRulesProcess(void)
|
||||||
#ifdef USE_DEBUG_DRIVER
|
#ifdef USE_DEBUG_DRIVER
|
||||||
void ShowFreeMem(const char *where)
|
void ShowFreeMem(const char *where)
|
||||||
{
|
{
|
||||||
char stemp[20];
|
char stemp[30];
|
||||||
snprintf_P(stemp, sizeof(stemp), where);
|
snprintf_P(stemp, sizeof(stemp), where);
|
||||||
XdrvMailbox.data = stemp;
|
XdrvMailbox.data = stemp;
|
||||||
XdrvCall(FUNC_FREE_MEM);
|
XdrvCall(FUNC_FREE_MEM);
|
||||||
|
|
|
@ -127,7 +127,7 @@ bool LcdPrintLog(void)
|
||||||
if (!disp_screen_buffer_cols) { DisplayAllocScreenBuffer(); }
|
if (!disp_screen_buffer_cols) { DisplayAllocScreenBuffer(); }
|
||||||
|
|
||||||
char* txt = DisplayLogBuffer('\337');
|
char* txt = DisplayLogBuffer('\337');
|
||||||
if (txt != NULL) {
|
if (txt != nullptr) {
|
||||||
uint8_t last_row = Settings.display_rows -1;
|
uint8_t last_row = Settings.display_rows -1;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < last_row; i++) {
|
for (uint8_t i = 0; i < last_row; i++) {
|
||||||
|
|
|
@ -141,7 +141,7 @@ void Ssd1306PrintLog(void)
|
||||||
if (!disp_screen_buffer_cols) { DisplayAllocScreenBuffer(); }
|
if (!disp_screen_buffer_cols) { DisplayAllocScreenBuffer(); }
|
||||||
|
|
||||||
char* txt = DisplayLogBuffer('\370');
|
char* txt = DisplayLogBuffer('\370');
|
||||||
if (txt != NULL) {
|
if (txt != nullptr) {
|
||||||
uint8_t last_row = Settings.display_rows -1;
|
uint8_t last_row = Settings.display_rows -1;
|
||||||
|
|
||||||
oled->clearDisplay();
|
oled->clearDisplay();
|
||||||
|
|
|
@ -37,7 +37,7 @@ int16_t mtx_x = 0;
|
||||||
int16_t mtx_y = 0;
|
int16_t mtx_y = 0;
|
||||||
|
|
||||||
//char mtx_buffer[MTX_MAX_SCREEN_BUFFER];
|
//char mtx_buffer[MTX_MAX_SCREEN_BUFFER];
|
||||||
char *mtx_buffer = NULL;
|
char *mtx_buffer = nullptr;
|
||||||
|
|
||||||
uint8_t mtx_mode = 0;
|
uint8_t mtx_mode = 0;
|
||||||
uint8_t mtx_loop = 0;
|
uint8_t mtx_loop = 0;
|
||||||
|
@ -140,9 +140,9 @@ void MatrixScrollUp(char* txt, int loop)
|
||||||
disp_refresh = Settings.display_refresh;
|
disp_refresh = Settings.display_refresh;
|
||||||
strlcpy(tmpbuf, txt, sizeof(tmpbuf));
|
strlcpy(tmpbuf, txt, sizeof(tmpbuf));
|
||||||
char *p = strtok(tmpbuf, separators);
|
char *p = strtok(tmpbuf, separators);
|
||||||
while (p != NULL && wordcounter < 40) {
|
while (p != nullptr && wordcounter < 40) {
|
||||||
words[wordcounter++] = p;
|
words[wordcounter++] = p;
|
||||||
p = strtok(NULL, separators);
|
p = strtok(nullptr, separators);
|
||||||
}
|
}
|
||||||
for (uint8_t i = 0; i < mtx_matrices; i++) {
|
for (uint8_t i = 0; i < mtx_matrices; i++) {
|
||||||
matrix[i]->clear();
|
matrix[i]->clear();
|
||||||
|
@ -196,7 +196,7 @@ void MatrixInit(uint8_t mode)
|
||||||
void MatrixInitDriver(void)
|
void MatrixInitDriver(void)
|
||||||
{
|
{
|
||||||
mtx_buffer = (char*)(malloc(MTX_MAX_SCREEN_BUFFER));
|
mtx_buffer = (char*)(malloc(MTX_MAX_SCREEN_BUFFER));
|
||||||
if (mtx_buffer != NULL) {
|
if (mtx_buffer != nullptr) {
|
||||||
if (!Settings.display_model) {
|
if (!Settings.display_model) {
|
||||||
if (I2cDevice(Settings.display_address[1])) {
|
if (I2cDevice(Settings.display_address[1])) {
|
||||||
Settings.display_model = XDSP_03;
|
Settings.display_model = XDSP_03;
|
||||||
|
@ -239,7 +239,7 @@ void MatrixDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8
|
||||||
void MatrixPrintLog(uint8_t direction)
|
void MatrixPrintLog(uint8_t direction)
|
||||||
{
|
{
|
||||||
char* txt = (!mtx_done) ? DisplayLogBuffer('\370') : mtx_buffer;
|
char* txt = (!mtx_done) ? DisplayLogBuffer('\370') : mtx_buffer;
|
||||||
if (txt != NULL) {
|
if (txt != nullptr) {
|
||||||
if (!mtx_state) { mtx_state = 1; }
|
if (!mtx_state) { mtx_state = 1; }
|
||||||
|
|
||||||
if (!mtx_done) {
|
if (!mtx_done) {
|
||||||
|
|
|
@ -147,7 +147,7 @@ void Ili9341PrintLog(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
char* txt = DisplayLogBuffer('\370');
|
char* txt = DisplayLogBuffer('\370');
|
||||||
if (txt != NULL) {
|
if (txt != nullptr) {
|
||||||
uint8_t size = Settings.display_size;
|
uint8_t size = Settings.display_size;
|
||||||
uint16_t theight = size * TFT_FONT_HEIGTH;
|
uint16_t theight = size * TFT_FONT_HEIGTH;
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,7 @@ void EpdPrintLog(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
char* txt = DisplayLogBuffer('\040');
|
char* txt = DisplayLogBuffer('\040');
|
||||||
if (txt != NULL) {
|
if (txt != nullptr) {
|
||||||
uint8_t size = Settings.display_size;
|
uint8_t size = Settings.display_size;
|
||||||
uint16_t theight = size * EPD_FONT_HEIGTH;
|
uint16_t theight = size * EPD_FONT_HEIGTH;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
#include <TasmotaSerial.h>
|
#include <TasmotaSerial.h>
|
||||||
|
|
||||||
TasmotaSerial *PzemSerial = NULL;
|
TasmotaSerial *PzemSerial = nullptr;
|
||||||
|
|
||||||
#define PZEM_VOLTAGE (uint8_t)0xB0
|
#define PZEM_VOLTAGE (uint8_t)0xB0
|
||||||
#define RESP_VOLTAGE (uint8_t)0xA0
|
#define RESP_VOLTAGE (uint8_t)0xA0
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
#define MCP_BUFFER_SIZE 60
|
#define MCP_BUFFER_SIZE 60
|
||||||
|
|
||||||
#include <TasmotaSerial.h>
|
#include <TasmotaSerial.h>
|
||||||
TasmotaSerial *McpSerial = NULL;
|
TasmotaSerial *McpSerial = nullptr;
|
||||||
|
|
||||||
typedef struct mcp_cal_registers_type {
|
typedef struct mcp_cal_registers_type {
|
||||||
uint16_t gain_current_rms;
|
uint16_t gain_current_rms;
|
||||||
|
@ -92,7 +92,7 @@ typedef struct mcp_cal_registers_type {
|
||||||
uint16_t accumulation_interval;
|
uint16_t accumulation_interval;
|
||||||
} mcp_cal_registers_type;
|
} mcp_cal_registers_type;
|
||||||
|
|
||||||
char *mcp_buffer = NULL;
|
char *mcp_buffer = nullptr;
|
||||||
unsigned long mcp_window = 0;
|
unsigned long mcp_window = 0;
|
||||||
unsigned long mcp_kWhcounter = 0;
|
unsigned long mcp_kWhcounter = 0;
|
||||||
uint32_t mcp_system_configuration = 0x03000000;
|
uint32_t mcp_system_configuration = 0x03000000;
|
||||||
|
@ -652,12 +652,12 @@ int Xnrg04(uint8_t function)
|
||||||
}
|
}
|
||||||
else if (XNRG_04 == energy_flg) {
|
else if (XNRG_04 == energy_flg) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case FUNC_INIT:
|
|
||||||
McpSnsInit();
|
|
||||||
break;
|
|
||||||
case FUNC_LOOP:
|
case FUNC_LOOP:
|
||||||
if (McpSerial) { McpSerialInput(); }
|
if (McpSerial) { McpSerialInput(); }
|
||||||
break;
|
break;
|
||||||
|
case FUNC_INIT:
|
||||||
|
McpSnsInit();
|
||||||
|
break;
|
||||||
case FUNC_EVERY_SECOND:
|
case FUNC_EVERY_SECOND:
|
||||||
if (McpSerial) { McpEverySecond(); }
|
if (McpSerial) { McpEverySecond(); }
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -31,16 +31,21 @@
|
||||||
#include <Ticker.h>
|
#include <Ticker.h>
|
||||||
Ticker TickerMSearch;
|
Ticker TickerMSearch;
|
||||||
|
|
||||||
bool udp_connected = false;
|
|
||||||
|
|
||||||
char packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP packet
|
|
||||||
IPAddress ipMulticast(239,255,255,250); // Simple Service Discovery Protocol (SSDP)
|
|
||||||
uint32_t port_multicast = 1900; // Multicast address and port
|
|
||||||
|
|
||||||
bool udp_response_mutex = false; // M-Search response mutex to control re-entry
|
|
||||||
IPAddress udp_remote_ip; // M-Search remote IP address
|
IPAddress udp_remote_ip; // M-Search remote IP address
|
||||||
uint16_t udp_remote_port; // M-Search remote port
|
uint16_t udp_remote_port; // M-Search remote port
|
||||||
|
|
||||||
|
bool udp_connected = false;
|
||||||
|
bool udp_response_mutex = false; // M-Search response mutex to control re-entry
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* UPNP search targets
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
const char URN_BELKIN_DEVICE[] PROGMEM = "urn:belkin:device:**";
|
||||||
|
const char UPNP_ROOTDEVICE[] PROGMEM = "upnp:rootdevice";
|
||||||
|
const char SSDPSEARCH_ALL[] PROGMEM = "ssdpsearch:all";
|
||||||
|
const char SSDP_ALL[] PROGMEM = "ssdp:all";
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* WeMo UPNP support routines
|
* WeMo UPNP support routines
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -50,12 +55,12 @@ const char WEMO_MSEARCH[] PROGMEM =
|
||||||
"CACHE-CONTROL: max-age=86400\r\n"
|
"CACHE-CONTROL: max-age=86400\r\n"
|
||||||
"DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n"
|
"DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n"
|
||||||
"EXT:\r\n"
|
"EXT:\r\n"
|
||||||
"LOCATION: http://{r1:80/setup.xml\r\n"
|
"LOCATION: http://%s:80/setup.xml\r\n"
|
||||||
"OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
|
"OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
|
||||||
"01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n"
|
"01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n"
|
||||||
"SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
|
"SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
|
||||||
"ST: {r3\r\n" // type1 = urn:Belkin:device:**, type2 = upnp:rootdevice
|
"ST: %s\r\n" // type1 = urn:Belkin:device:**, type2 = upnp:rootdevice
|
||||||
"USN: uuid:{r2::{r3\r\n" // type1 = urn:Belkin:device:**, type2 = upnp:rootdevice
|
"USN: uuid:%s::%s\r\n" // type1 = urn:Belkin:device:**, type2 = upnp:rootdevice
|
||||||
"X-User-Agent: redsonic\r\n"
|
"X-User-Agent: redsonic\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
|
@ -81,15 +86,15 @@ void WemoRespondToMSearch(int echo_type)
|
||||||
|
|
||||||
TickerMSearch.detach();
|
TickerMSearch.detach();
|
||||||
if (PortUdp.beginPacket(udp_remote_ip, udp_remote_port)) {
|
if (PortUdp.beginPacket(udp_remote_ip, udp_remote_port)) {
|
||||||
String response = FPSTR(WEMO_MSEARCH);
|
char type[24];
|
||||||
response.replace("{r1", WiFi.localIP().toString());
|
|
||||||
response.replace("{r2", WemoUuid());
|
|
||||||
if (1 == echo_type) { // type1 echo 1g & dot 2g
|
if (1 == echo_type) { // type1 echo 1g & dot 2g
|
||||||
response.replace("{r3", F("urn:Belkin:device:**"));
|
strcpy_P(type, URN_BELKIN_DEVICE);
|
||||||
} else { // type2 echo 2g (echo, plus, show)
|
} else { // type2 echo 2g (echo, plus, show)
|
||||||
response.replace("{r3", F("upnp:rootdevice"));
|
strcpy_P(type, UPNP_ROOTDEVICE);
|
||||||
}
|
}
|
||||||
PortUdp.write(response.c_str());
|
char response[400];
|
||||||
|
snprintf_P(response, sizeof(response), WEMO_MSEARCH, WiFi.localIP().toString().c_str(), type, WemoUuid().c_str(), type);
|
||||||
|
PortUdp.write(response);
|
||||||
PortUdp.endPacket();
|
PortUdp.endPacket();
|
||||||
snprintf_P(message, sizeof(message), PSTR(D_RESPONSE_SENT));
|
snprintf_P(message, sizeof(message), PSTR(D_RESPONSE_SENT));
|
||||||
} else {
|
} else {
|
||||||
|
@ -114,20 +119,20 @@ const char HUE_RESPONSE[] PROGMEM =
|
||||||
"HOST: 239.255.255.250:1900\r\n"
|
"HOST: 239.255.255.250:1900\r\n"
|
||||||
"CACHE-CONTROL: max-age=100\r\n"
|
"CACHE-CONTROL: max-age=100\r\n"
|
||||||
"EXT:\r\n"
|
"EXT:\r\n"
|
||||||
"LOCATION: http://{r1:80/description.xml\r\n"
|
"LOCATION: http://%s:80/description.xml\r\n"
|
||||||
"SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.17.0\r\n"
|
"SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.17.0\r\n"
|
||||||
"hue-bridgeid: {r2\r\n";
|
"hue-bridgeid: %s\r\n";
|
||||||
const char HUE_ST1[] PROGMEM =
|
const char HUE_ST1[] PROGMEM =
|
||||||
"ST: upnp:rootdevice\r\n"
|
"ST: upnp:rootdevice\r\n"
|
||||||
"USN: uuid:{r3::upnp:rootdevice\r\n"
|
"USN: uuid:%s::upnp:rootdevice\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
const char HUE_ST2[] PROGMEM =
|
const char HUE_ST2[] PROGMEM =
|
||||||
"ST: uuid:{r3\r\n"
|
"ST: uuid:%s\r\n"
|
||||||
"USN: uuid:{r3\r\n"
|
"USN: uuid:%s\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
const char HUE_ST3[] PROGMEM =
|
const char HUE_ST3[] PROGMEM =
|
||||||
"ST: urn:schemas-upnp-org:device:basic:1\r\n"
|
"ST: urn:schemas-upnp-org:device:basic:1\r\n"
|
||||||
"USN: uuid:{r3\r\n"
|
"USN: uuid:%s\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
String HueBridgeId(void)
|
String HueBridgeId(void)
|
||||||
|
@ -159,26 +164,20 @@ void HueRespondToMSearch(void)
|
||||||
|
|
||||||
TickerMSearch.detach();
|
TickerMSearch.detach();
|
||||||
if (PortUdp.beginPacket(udp_remote_ip, udp_remote_port)) {
|
if (PortUdp.beginPacket(udp_remote_ip, udp_remote_port)) {
|
||||||
String response1 = FPSTR(HUE_RESPONSE);
|
char response[320];
|
||||||
response1.replace("{r1", WiFi.localIP().toString());
|
snprintf_P(response, sizeof(response), HUE_RESPONSE, WiFi.localIP().toString().c_str(), HueBridgeId().c_str());
|
||||||
response1.replace("{r2", HueBridgeId());
|
int len = strlen(response);
|
||||||
|
|
||||||
String response = response1;
|
snprintf_P(response + len, sizeof(response) - len, HUE_ST1, HueUuid().c_str());
|
||||||
response += FPSTR(HUE_ST1);
|
PortUdp.write(response);
|
||||||
response.replace("{r3", HueUuid());
|
|
||||||
PortUdp.write(response.c_str());
|
|
||||||
PortUdp.endPacket();
|
PortUdp.endPacket();
|
||||||
|
|
||||||
response = response1;
|
snprintf_P(response + len, sizeof(response) - len, HUE_ST2, HueUuid().c_str(), HueUuid().c_str());
|
||||||
response += FPSTR(HUE_ST2);
|
PortUdp.write(response);
|
||||||
response.replace("{r3", HueUuid());
|
|
||||||
PortUdp.write(response.c_str());
|
|
||||||
PortUdp.endPacket();
|
PortUdp.endPacket();
|
||||||
|
|
||||||
response = response1;
|
snprintf_P(response + len, sizeof(response) - len, HUE_ST3, HueUuid().c_str());
|
||||||
response += FPSTR(HUE_ST3);
|
PortUdp.write(response);
|
||||||
response.replace("{r3", HueUuid());
|
|
||||||
PortUdp.write(response.c_str());
|
|
||||||
PortUdp.endPacket();
|
PortUdp.endPacket();
|
||||||
|
|
||||||
snprintf_P(message, sizeof(message), PSTR(D_3_RESPONSE_PACKETS_SENT));
|
snprintf_P(message, sizeof(message), PSTR(D_3_RESPONSE_PACKETS_SENT));
|
||||||
|
@ -198,6 +197,7 @@ void HueRespondToMSearch(void)
|
||||||
bool UdpDisconnect(void)
|
bool UdpDisconnect(void)
|
||||||
{
|
{
|
||||||
if (udp_connected) {
|
if (udp_connected) {
|
||||||
|
PortUdp.flush();
|
||||||
WiFiUDP::stopAll();
|
WiFiUDP::stopAll();
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP D_MULTICAST_DISABLED));
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP D_MULTICAST_DISABLED));
|
||||||
udp_connected = false;
|
udp_connected = false;
|
||||||
|
@ -208,7 +208,8 @@ bool UdpDisconnect(void)
|
||||||
bool UdpConnect(void)
|
bool UdpConnect(void)
|
||||||
{
|
{
|
||||||
if (!udp_connected) {
|
if (!udp_connected) {
|
||||||
if (PortUdp.beginMulticast(WiFi.localIP(), ipMulticast, port_multicast)) {
|
// Simple Service Discovery Protocol (SSDP)
|
||||||
|
if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), 1900)) {
|
||||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED));
|
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED));
|
||||||
udp_response_mutex = false;
|
udp_response_mutex = false;
|
||||||
udp_connected = true;
|
udp_connected = true;
|
||||||
|
@ -222,48 +223,53 @@ bool UdpConnect(void)
|
||||||
|
|
||||||
void PollUdp(void)
|
void PollUdp(void)
|
||||||
{
|
{
|
||||||
if (udp_connected && !udp_response_mutex) {
|
if (udp_connected) {
|
||||||
if (PortUdp.parsePacket()) {
|
if (PortUdp.parsePacket()) {
|
||||||
|
char packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet
|
||||||
|
|
||||||
int len = PortUdp.read(packet_buffer, UDP_BUFFER_SIZE -1);
|
int len = PortUdp.read(packet_buffer, UDP_BUFFER_SIZE -1);
|
||||||
if (len > 0) {
|
|
||||||
packet_buffer[len] = 0;
|
packet_buffer[len] = 0;
|
||||||
}
|
|
||||||
String request = packet_buffer;
|
|
||||||
|
|
||||||
// AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet received"));
|
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d)"), len);
|
||||||
// AddLog_P(LOG_LEVEL_DEBUG_MORE, packet_buffer);
|
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), packet_buffer);
|
||||||
|
|
||||||
if (request.indexOf("M-SEARCH") >= 0) {
|
if (devices_present && !udp_response_mutex && (strstr_P(packet_buffer, PSTR("M-SEARCH")) != nullptr)) {
|
||||||
request.toLowerCase();
|
udp_response_mutex = true;
|
||||||
request.replace(" ", "");
|
|
||||||
|
|
||||||
// AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet received"));
|
|
||||||
// AddLog_P(LOG_LEVEL_DEBUG_MORE, request.c_str());
|
|
||||||
|
|
||||||
udp_remote_ip = PortUdp.remoteIP();
|
udp_remote_ip = PortUdp.remoteIP();
|
||||||
udp_remote_port = PortUdp.remotePort();
|
udp_remote_port = PortUdp.remotePort();
|
||||||
|
|
||||||
|
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet from %s:%d\n%s"),
|
||||||
|
// udp_remote_ip.toString().c_str(), udp_remote_port, packet_buffer);
|
||||||
|
|
||||||
|
uint32_t response_delay = UDP_MSEARCH_SEND_DELAY + ((millis() &0x7) * 100); // 1500 - 2200 msec
|
||||||
|
|
||||||
|
LowerCase(packet_buffer, packet_buffer);
|
||||||
|
RemoveSpace(packet_buffer);
|
||||||
if (EMUL_WEMO == Settings.flag2.emulation) {
|
if (EMUL_WEMO == Settings.flag2.emulation) {
|
||||||
if (request.indexOf(F("urn:belkin:device:**")) > 0) { // type1 echo dot 2g, echo 1g's
|
if (strstr_P(packet_buffer, URN_BELKIN_DEVICE) != nullptr) { // type1 echo dot 2g, echo 1g's
|
||||||
udp_response_mutex = true;
|
TickerMSearch.attach_ms(response_delay, WemoRespondToMSearch, 1);
|
||||||
TickerMSearch.attach_ms(UDP_MSEARCH_SEND_DELAY, WemoRespondToMSearch, 1);
|
return;
|
||||||
}
|
}
|
||||||
else if ((request.indexOf(F("upnp:rootdevice")) > 0) || // type2 Echo 2g (echo & echo plus)
|
else if ((strstr_P(packet_buffer, UPNP_ROOTDEVICE) != nullptr) || // type2 Echo 2g (echo & echo plus)
|
||||||
(request.indexOf(F("ssdpsearch:all")) > 0) ||
|
(strstr_P(packet_buffer, SSDPSEARCH_ALL) != nullptr) ||
|
||||||
(request.indexOf(F("ssdp:all")) > 0)) {
|
(strstr_P(packet_buffer, SSDP_ALL) != nullptr)) {
|
||||||
udp_response_mutex = true;
|
TickerMSearch.attach_ms(response_delay, WemoRespondToMSearch, 2);
|
||||||
TickerMSearch.attach_ms(UDP_MSEARCH_SEND_DELAY, WemoRespondToMSearch, 2);
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((strstr_P(packet_buffer, PSTR(":device:basic:1")) != nullptr) ||
|
||||||
|
(strstr_P(packet_buffer, UPNP_ROOTDEVICE) != nullptr) ||
|
||||||
|
(strstr_P(packet_buffer, SSDPSEARCH_ALL) != nullptr) ||
|
||||||
|
(strstr_P(packet_buffer, SSDP_ALL) != nullptr)) {
|
||||||
|
TickerMSearch.attach_ms(response_delay, HueRespondToMSearch);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((EMUL_HUE == Settings.flag2.emulation) &&
|
udp_response_mutex = false;
|
||||||
((request.indexOf(F("urn:schemas-upnp-org:device:basic:1")) > 0) ||
|
|
||||||
(request.indexOf(F("upnp:rootdevice")) > 0) ||
|
|
||||||
(request.indexOf(F("ssdpsearch:all")) > 0) ||
|
|
||||||
(request.indexOf(F("ssdp:all")) > 0))) {
|
|
||||||
udp_response_mutex = true;
|
|
||||||
TickerMSearch.attach_ms(UDP_MSEARCH_SEND_DELAY, HueRespondToMSearch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delay(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,9 +346,9 @@ const char WEMO_METASERVICE_XML[] PROGMEM =
|
||||||
const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM =
|
const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM =
|
||||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
|
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
|
||||||
"<s:Body>"
|
"<s:Body>"
|
||||||
"<u:SetBinaryStateResponse xmlns:u=\"urn:Belkin:service:basicevent:1\">"
|
"<u:%cetBinaryStateResponse xmlns:u=\"urn:Belkin:service:basicevent:1\">"
|
||||||
"<BinaryState>{x1</BinaryState>"
|
"<BinaryState>%d</BinaryState>"
|
||||||
"</u:SetBinaryStateResponse>"
|
"</u:%cetBinaryStateResponse>"
|
||||||
"</s:Body>"
|
"</s:Body>"
|
||||||
"</s:Envelope>\r\n";
|
"</s:Envelope>\r\n";
|
||||||
|
|
||||||
|
@ -383,15 +389,20 @@ void HandleUpnpEvent(void)
|
||||||
{
|
{
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT));
|
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT));
|
||||||
|
|
||||||
String request = WebServer->arg(0);
|
char event[500];
|
||||||
String state_xml = FPSTR(WEMO_RESPONSE_STATE_SOAP);
|
strlcpy(event, WebServer->arg(0).c_str(), sizeof(event));
|
||||||
|
|
||||||
|
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), event);
|
||||||
|
|
||||||
//differentiate get and set state
|
//differentiate get and set state
|
||||||
if (request.indexOf(F("SetBinaryState")) > 0) {
|
char state = 'G';
|
||||||
|
if (strstr_P(event, PSTR("SetBinaryState")) != nullptr) {
|
||||||
|
state = 'S';
|
||||||
uint8_t power = POWER_TOGGLE;
|
uint8_t power = POWER_TOGGLE;
|
||||||
if (request.indexOf(F("State>1</Binary")) > 0) {
|
if (strstr_P(event, PSTR("State>1</Binary")) != nullptr) {
|
||||||
power = POWER_ON;
|
power = POWER_ON;
|
||||||
}
|
}
|
||||||
else if (request.indexOf(F("State>0</Binary")) > 0) {
|
else if (strstr_P(event, PSTR("State>0</Binary")) != nullptr) {
|
||||||
power = POWER_OFF;
|
power = POWER_OFF;
|
||||||
}
|
}
|
||||||
if (power != POWER_TOGGLE) {
|
if (power != POWER_TOGGLE) {
|
||||||
|
@ -399,11 +410,9 @@ void HandleUpnpEvent(void)
|
||||||
ExecuteCommandPower(device, power, SRC_WEMO);
|
ExecuteCommandPower(device, power, SRC_WEMO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(request.indexOf(F("GetBinaryState")) > 0){
|
|
||||||
state_xml.replace(F("Set"), F("Get"));
|
snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(power, devices_present -1), state);
|
||||||
}
|
WSSend(200, CT_XML, event);
|
||||||
state_xml.replace("{x1", String(bitRead(power, devices_present -1)));
|
|
||||||
WSSend(200, CT_XML, state_xml);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleUpnpService(void)
|
void HandleUpnpService(void)
|
||||||
|
@ -837,6 +846,7 @@ void HandleHueApi(String *path)
|
||||||
|
|
||||||
void HueWemoAddHandlers(void)
|
void HueWemoAddHandlers(void)
|
||||||
{
|
{
|
||||||
|
if (devices_present) {
|
||||||
if (EMUL_WEMO == Settings.flag2.emulation) {
|
if (EMUL_WEMO == Settings.flag2.emulation) {
|
||||||
WebServer->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent);
|
WebServer->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent);
|
||||||
WebServer->on("/eventservice.xml", HandleUpnpService);
|
WebServer->on("/eventservice.xml", HandleUpnpService);
|
||||||
|
@ -847,5 +857,6 @@ void HueWemoAddHandlers(void)
|
||||||
WebServer->on("/description.xml", HandleUpnpSetupHue);
|
WebServer->on("/description.xml", HandleUpnpSetupHue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // USE_WEBSERVER && USE_EMULATION
|
#endif // USE_WEBSERVER && USE_EMULATION
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#else // USE_WS2812_DMA
|
#else // USE_WS2812_DMA
|
||||||
typedef NeoEsp8266BitBang800KbpsMethod selectedNeoSpeedType;
|
typedef NeoEsp8266BitBang800KbpsMethod selectedNeoSpeedType;
|
||||||
#endif // USE_WS2812_DMA
|
#endif // USE_WS2812_DMA
|
||||||
NeoPixelBus<selectedNeoFeatureType, selectedNeoSpeedType> *strip = NULL;
|
NeoPixelBus<selectedNeoFeatureType, selectedNeoSpeedType> *strip = nullptr;
|
||||||
|
|
||||||
struct WsColor {
|
struct WsColor {
|
||||||
uint8_t red, green, blue;
|
uint8_t red, green, blue;
|
||||||
|
|
|
@ -107,11 +107,11 @@ void CounterShow(bool json)
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
if (!header) {
|
if (!header) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"COUNTER\":{"), mqtt_data);
|
ResponseAppend_P(PSTR(",\"COUNTER\":{"));
|
||||||
stemp[0] = '\0';
|
stemp[0] = '\0';
|
||||||
}
|
}
|
||||||
header++;
|
header++;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"C%d\":%s"), mqtt_data, stemp, i +1, counter);
|
ResponseAppend_P(PSTR("%s\"C%d\":%s"), stemp, i +1, counter);
|
||||||
strlcpy(stemp, ",", sizeof(stemp));
|
strlcpy(stemp, ",", sizeof(stemp));
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if ((0 == tele_period) && (1 == dsxflg)) {
|
if ((0 == tele_period) && (1 == dsxflg)) {
|
||||||
|
@ -131,7 +131,7 @@ void CounterShow(bool json)
|
||||||
}
|
}
|
||||||
if (json) {
|
if (json) {
|
||||||
if (header) {
|
if (header) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,15 @@
|
||||||
|
|
||||||
#define XSNS_02 2
|
#define XSNS_02 2
|
||||||
|
|
||||||
|
#define TO_CELSIUS(x) ((x) - 273.15)
|
||||||
|
#define TO_KELVIN(x) ((x) + 273.15)
|
||||||
|
|
||||||
|
#define ANALOG_V33 3.3
|
||||||
|
#define ANALOG_R21 32000.0
|
||||||
|
#define ANALOG_R0 10000.0
|
||||||
|
#define ANALOG_T0 TO_KELVIN(25.0)
|
||||||
|
#define ANALOG_B 3350.0
|
||||||
|
|
||||||
uint16_t adc_last_value = 0;
|
uint16_t adc_last_value = 0;
|
||||||
|
|
||||||
uint16_t AdcRead(void)
|
uint16_t AdcRead(void)
|
||||||
|
@ -40,28 +49,60 @@ uint16_t AdcRead(void)
|
||||||
#ifdef USE_RULES
|
#ifdef USE_RULES
|
||||||
void AdcEvery250ms(void)
|
void AdcEvery250ms(void)
|
||||||
{
|
{
|
||||||
|
if (my_module_flag.adc0) {
|
||||||
uint16_t new_value = AdcRead();
|
uint16_t new_value = AdcRead();
|
||||||
if ((new_value < adc_last_value -10) || (new_value > adc_last_value +10)) {
|
if ((new_value < adc_last_value -10) || (new_value > adc_last_value +10)) {
|
||||||
adc_last_value = new_value;
|
adc_last_value = new_value;
|
||||||
uint16_t value = adc_last_value / 10;
|
uint16_t value = adc_last_value / 10;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"ANALOG\":{\"A0div10\":%d}}"), (value > 99) ? 100 : value);
|
Response_P(PSTR("{\"ANALOG\":{\"A0div10\":%d}}"), (value > 99) ? 100 : value);
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif // USE_RULES
|
#endif // USE_RULES
|
||||||
|
|
||||||
void AdcShow(bool json)
|
void AdcShow(bool json)
|
||||||
{
|
{
|
||||||
|
if (my_module_flag.adc0) {
|
||||||
uint16_t analog = AdcRead();
|
uint16_t analog = AdcRead();
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"ANALOG\":{\"A0\":%d}"), mqtt_data, analog);
|
ResponseAppend_P(PSTR(",\"ANALOG\":{\"A0\":%d}"), analog);
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
} else {
|
} else {
|
||||||
WSContentSend_PD(HTTP_SNS_ANALOG, "", 0, analog);
|
WSContentSend_PD(HTTP_SNS_ANALOG, "", 0, analog);
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (my_module_flag.adc0_temp) {
|
||||||
|
int adc = analogRead(A0);
|
||||||
|
// Formule used by Shelly 2.5 analog temperature sensor
|
||||||
|
double Rt = (adc * ANALOG_R21) / (1024.0 * ANALOG_V33 - (double)adc);
|
||||||
|
double T = ANALOG_B / (ANALOG_B/ANALOG_T0 + log(Rt/ANALOG_R0));
|
||||||
|
double temp = ConvertTemp(TO_CELSIUS(T));
|
||||||
|
|
||||||
|
char temperature[33];
|
||||||
|
dtostrfd(temp, Settings.flag2.temperature_resolution, temperature);
|
||||||
|
|
||||||
|
if (json) {
|
||||||
|
ResponseAppend_P(JSON_SNS_TEMP, "ANALOG", temperature);
|
||||||
|
#ifdef USE_DOMOTICZ
|
||||||
|
if (0 == tele_period) {
|
||||||
|
DomoticzSensor(DZ_TEMP, temperature);
|
||||||
|
}
|
||||||
|
#endif // USE_DOMOTICZ
|
||||||
|
#ifdef USE_KNX
|
||||||
|
if (0 == tele_period) {
|
||||||
|
KnxSensor(KNX_TEMPERATURE, temp);
|
||||||
|
}
|
||||||
|
#endif // USE_KNX
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
} else {
|
||||||
|
WSContentSend_PD(HTTP_SNS_TEMP, "", temperature, TempUnit());
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Interface
|
* Interface
|
||||||
|
@ -71,7 +112,7 @@ bool Xsns02(uint8_t function)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if (my_module_flag.adc0) {
|
if (my_module_flag.adc0 || my_module_flag.adc0_temp) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
#ifdef USE_RULES
|
#ifdef USE_RULES
|
||||||
case FUNC_EVERY_250_MSECOND:
|
case FUNC_EVERY_250_MSECOND:
|
||||||
|
|
|
@ -81,7 +81,7 @@ void SonoffScSerialInput(char *rcvstat)
|
||||||
|
|
||||||
if (!strncasecmp_P(rcvstat, PSTR("AT+UPDATE="), 10)) {
|
if (!strncasecmp_P(rcvstat, PSTR("AT+UPDATE="), 10)) {
|
||||||
int8_t i = -1;
|
int8_t i = -1;
|
||||||
for (str = strtok_r(rcvstat, ":", &p); str && i < 5; str = strtok_r(NULL, ":", &p)) {
|
for (str = strtok_r(rcvstat, ":", &p); str && i < 5; str = strtok_r(nullptr, ":", &p)) {
|
||||||
value[i++] = atoi(str);
|
value[i++] = atoi(str);
|
||||||
}
|
}
|
||||||
if (value[0] > 0) {
|
if (value[0] > 0) {
|
||||||
|
@ -120,8 +120,8 @@ void SonoffScShow(bool json)
|
||||||
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SonoffSC\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s,\"" D_JSON_LIGHT "\":%d,\"" D_JSON_NOISE "\":%d,\"" D_JSON_AIRQUALITY "\":%d}"),
|
ResponseAppend_P(PSTR(",\"SonoffSC\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s,\"" D_JSON_LIGHT "\":%d,\"" D_JSON_NOISE "\":%d,\"" D_JSON_AIRQUALITY "\":%d}"),
|
||||||
mqtt_data, temperature, humidity, sc_value[2], sc_value[3], sc_value[4]);
|
temperature, humidity, sc_value[2], sc_value[3], sc_value[4]);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzTempHumSensor(temperature, humidity);
|
DomoticzTempHumSensor(temperature, humidity);
|
||||||
|
|
|
@ -205,7 +205,7 @@ void Ds18b20Show(bool json)
|
||||||
char temperature[33];
|
char temperature[33];
|
||||||
dtostrfd(ds18b20_temperature, Settings.flag2.temperature_resolution, temperature);
|
dtostrfd(ds18b20_temperature, Settings.flag2.temperature_resolution, temperature);
|
||||||
if(json) {
|
if(json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMP, mqtt_data, ds18b20_types, temperature);
|
ResponseAppend_P(JSON_SNS_TEMP, ds18b20_types, temperature);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzSensor(DZ_TEMP, temperature);
|
DomoticzSensor(DZ_TEMP, temperature);
|
||||||
|
|
|
@ -432,13 +432,13 @@ void Ds18x20Show(bool json)
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
if (1 == ds18x20_sensors) {
|
if (1 == ds18x20_sensors) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, ds18x20_types, temperature);
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), ds18x20_types, temperature);
|
||||||
} else {
|
} else {
|
||||||
char address[17];
|
char address[17];
|
||||||
for (uint8_t j = 0; j < 6; j++) {
|
for (uint8_t j = 0; j < 6; j++) {
|
||||||
sprintf(address+2*j, "%02X", ds18x20_sensor[index].address[6-j]); // Skip sensor type and crc
|
sprintf(address+2*j, "%02X", ds18x20_sensor[index].address[6-j]); // Skip sensor type and crc
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_ID "\":\"%s\",\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, ds18x20_types, address, temperature);
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_ID "\":\"%s\",\"" D_JSON_TEMPERATURE "\":%s}"), ds18x20_types, address, temperature);
|
||||||
}
|
}
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if ((0 == tele_period) && (0 == i)) {
|
if ((0 == tele_period) && (0 == i)) {
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
#include <OneWire.h>
|
#include <OneWire.h>
|
||||||
|
|
||||||
OneWire *ds = NULL;
|
OneWire *ds = nullptr;
|
||||||
|
|
||||||
uint8_t ds18x20_address[DS18X20_MAX_SENSORS][8];
|
uint8_t ds18x20_address[DS18X20_MAX_SENSORS][8];
|
||||||
uint8_t ds18x20_index[DS18X20_MAX_SENSORS];
|
uint8_t ds18x20_index[DS18X20_MAX_SENSORS];
|
||||||
|
@ -178,12 +178,12 @@ void Ds18x20Show(bool json)
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
if (!dsxflg) {
|
if (!dsxflg) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"DS18x20\":{"), mqtt_data);
|
ResponseAppend_P(PSTR(",\"DS18x20\":{"));
|
||||||
stemp[0] = '\0';
|
stemp[0] = '\0';
|
||||||
}
|
}
|
||||||
dsxflg++;
|
dsxflg++;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"DS%d\":{\"" D_JSON_TYPE "\":\"%s\",\"" D_JSON_ADDRESS "\":\"%s\",\"" D_JSON_TEMPERATURE "\":%s}"),
|
ResponseAppend_P(PSTR("%s\"DS%d\":{\"" D_JSON_TYPE "\":\"%s\",\"" D_JSON_ADDRESS "\":\"%s\",\"" D_JSON_TEMPERATURE "\":%s}"),
|
||||||
mqtt_data, stemp, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), temperature);
|
stemp, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), temperature);
|
||||||
strlcpy(stemp, ",", sizeof(stemp));
|
strlcpy(stemp, ",", sizeof(stemp));
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if ((0 == tele_period) && (1 == dsxflg)) {
|
if ((0 == tele_period) && (1 == dsxflg)) {
|
||||||
|
@ -205,7 +205,7 @@ void Ds18x20Show(bool json)
|
||||||
}
|
}
|
||||||
if (json) {
|
if (json) {
|
||||||
if (dsxflg) {
|
if (dsxflg) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ds18x20Search(); // Check for changes in sensors number
|
Ds18x20Search(); // Check for changes in sensors number
|
||||||
|
|
|
@ -213,7 +213,7 @@ void DhtShow(bool json)
|
||||||
dtostrfd(Dht[i].h, Settings.flag2.humidity_resolution, humidity);
|
dtostrfd(Dht[i].h, Settings.flag2.humidity_resolution, humidity);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, temperature, humidity);
|
ResponseAppend_P(JSON_SNS_TEMPHUM, Dht[i].stype, temperature, humidity);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if ((0 == tele_period) && (0 == i)) {
|
if ((0 == tele_period) && (0 == i)) {
|
||||||
DomoticzTempHumSensor(temperature, humidity);
|
DomoticzTempHumSensor(temperature, humidity);
|
||||||
|
|
|
@ -194,7 +194,7 @@ void ShtShow(bool json)
|
||||||
dtostrfd(sht_humidity, Settings.flag2.humidity_resolution, humidity);
|
dtostrfd(sht_humidity, Settings.flag2.humidity_resolution, humidity);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, sht_types, temperature, humidity);
|
ResponseAppend_P(JSON_SNS_TEMPHUM, sht_types, temperature, humidity);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzTempHumSensor(temperature, humidity);
|
DomoticzTempHumSensor(temperature, humidity);
|
||||||
|
|
|
@ -254,7 +254,7 @@ void HtuShow(bool json)
|
||||||
dtostrfd(htu_humidity, Settings.flag2.humidity_resolution, humidity);
|
dtostrfd(htu_humidity, Settings.flag2.humidity_resolution, humidity);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, htu_types, temperature, humidity);
|
ResponseAppend_P(JSON_SNS_TEMPHUM, htu_types, temperature, humidity);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzTempHumSensor(temperature, humidity);
|
DomoticzTempHumSensor(temperature, humidity);
|
||||||
|
|
|
@ -61,7 +61,7 @@ uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 };
|
||||||
uint8_t bmp_count = 0;
|
uint8_t bmp_count = 0;
|
||||||
uint8_t bmp_once = 1;
|
uint8_t bmp_once = 1;
|
||||||
|
|
||||||
bmp_sensors_t *bmp_sensors = NULL;
|
bmp_sensors_t *bmp_sensors = nullptr;
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* BMP085 and BME180
|
* BMP085 and BME180
|
||||||
|
@ -99,7 +99,7 @@ typedef struct {
|
||||||
uint16_t cal_ac6;
|
uint16_t cal_ac6;
|
||||||
} bmp180_cal_data_t;
|
} bmp180_cal_data_t;
|
||||||
|
|
||||||
bmp180_cal_data_t *bmp180_cal_data = NULL;
|
bmp180_cal_data_t *bmp180_cal_data = nullptr;
|
||||||
|
|
||||||
bool Bmp180Calibration(uint8_t bmp_idx)
|
bool Bmp180Calibration(uint8_t bmp_idx)
|
||||||
{
|
{
|
||||||
|
@ -244,7 +244,7 @@ typedef struct {
|
||||||
int8_t dig_H6;
|
int8_t dig_H6;
|
||||||
} Bme280CalibrationData_t;
|
} Bme280CalibrationData_t;
|
||||||
|
|
||||||
Bme280CalibrationData_t *Bme280CalibrationData = NULL;
|
Bme280CalibrationData_t *Bme280CalibrationData = nullptr;
|
||||||
|
|
||||||
bool Bmx280Calibrate(uint8_t bmp_idx)
|
bool Bmx280Calibrate(uint8_t bmp_idx)
|
||||||
{
|
{
|
||||||
|
@ -344,7 +344,7 @@ void Bme280Read(uint8_t bmp_idx)
|
||||||
|
|
||||||
#include <bme680.h>
|
#include <bme680.h>
|
||||||
|
|
||||||
struct bme680_dev *gas_sensor = NULL;
|
struct bme680_dev *gas_sensor = nullptr;
|
||||||
|
|
||||||
static void BmeDelayMs(uint32_t ms)
|
static void BmeDelayMs(uint32_t ms)
|
||||||
{
|
{
|
||||||
|
@ -566,8 +566,7 @@ void BmpShow(bool json)
|
||||||
char json_gas[40];
|
char json_gas[40];
|
||||||
snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance);
|
snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance);
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"),
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"),
|
||||||
mqtt_data,
|
|
||||||
name,
|
name,
|
||||||
temperature,
|
temperature,
|
||||||
(bmp_sensors[bmp_idx].bmp_model >= 2) ? json_humidity : "",
|
(bmp_sensors[bmp_idx].bmp_model >= 2) ? json_humidity : "",
|
||||||
|
@ -575,8 +574,8 @@ void BmpShow(bool json)
|
||||||
(Settings.altitude != 0) ? json_sealevel : "",
|
(Settings.altitude != 0) ? json_sealevel : "",
|
||||||
(bmp_sensors[bmp_idx].bmp_model >= 3) ? json_gas : "");
|
(bmp_sensors[bmp_idx].bmp_model >= 3) ? json_gas : "");
|
||||||
#else
|
#else
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"),
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"),
|
||||||
mqtt_data, name, temperature, (bmp_sensors[bmp_idx].bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : "");
|
name, temperature, (bmp_sensors[bmp_idx].bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : "");
|
||||||
#endif // USE_BME680
|
#endif // USE_BME680
|
||||||
|
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
|
|
|
@ -92,7 +92,7 @@ void Bh1750Show(bool json)
|
||||||
{
|
{
|
||||||
if (bh1750_valid) {
|
if (bh1750_valid) {
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d}"), mqtt_data, bh1750_types, bh1750_illuminance);
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d}"), bh1750_types, bh1750_illuminance);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzSensor(DZ_ILLUMINANCE, bh1750_illuminance);
|
DomoticzSensor(DZ_ILLUMINANCE, bh1750_illuminance);
|
||||||
|
|
|
@ -277,11 +277,11 @@ void Veml6070Show(bool json)
|
||||||
dtostrfd(uvpower, 3, str_uvpower);
|
dtostrfd(uvpower, 3, str_uvpower);
|
||||||
if (json) {
|
if (json) {
|
||||||
#ifdef USE_VEML6070_SHOW_RAW
|
#ifdef USE_VEML6070_SHOW_RAW
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_UV_LEVEL "\":%s,\"" D_JSON_UV_INDEX "\":%s,\"" D_JSON_UV_INDEX_TEXT "\":\"%s\",\"" D_JSON_UV_POWER "\":%s}"),
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_UV_LEVEL "\":%s,\"" D_JSON_UV_INDEX "\":%s,\"" D_JSON_UV_INDEX_TEXT "\":\"%s\",\"" D_JSON_UV_POWER "\":%s}"),
|
||||||
mqtt_data, veml6070_name, str_uvlevel, str_uvrisk, str_uvrisk_text, str_uvpower);
|
veml6070_name, str_uvlevel, str_uvrisk, str_uvrisk_text, str_uvpower);
|
||||||
#else
|
#else
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_UV_INDEX "\":%s,\"" D_JSON_UV_INDEX_TEXT "\":\"%s\",\"" D_JSON_UV_POWER "\":%s}"),
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_UV_INDEX "\":%s,\"" D_JSON_UV_INDEX_TEXT "\":\"%s\",\"" D_JSON_UV_POWER "\":%s}"),
|
||||||
mqtt_data, veml6070_name, str_uvrisk, str_uvrisk_text, str_uvpower);
|
veml6070_name, str_uvrisk, str_uvrisk_text, str_uvpower);
|
||||||
#endif // USE_VEML6070_SHOW_RAW
|
#endif // USE_VEML6070_SHOW_RAW
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) { DomoticzSensor(DZ_ILLUMINANCE, uvlevel); }
|
if (0 == tele_period) { DomoticzSensor(DZ_ILLUMINANCE, uvlevel); }
|
||||||
|
|
|
@ -188,13 +188,13 @@ void Ads1115GetValues(uint8_t address)
|
||||||
|
|
||||||
void Ads1115toJSON(char *comma_j)
|
void Ads1115toJSON(char *comma_j)
|
||||||
{
|
{
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s{"), mqtt_data,comma_j);
|
ResponseAppend_P(PSTR("%s{"), comma_j);
|
||||||
char *comma = (char*)"";
|
char *comma = (char*)"";
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, comma, i, ads1115_values[i]);
|
ResponseAppend_P(PSTR("%s\"A%d\":%d"), comma, i, ads1115_values[i]);
|
||||||
comma = (char*)",";
|
comma = (char*)",";
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ads1115toString(uint8_t address)
|
void Ads1115toString(uint8_t address)
|
||||||
|
@ -212,7 +212,7 @@ void Ads1115Show(bool json)
|
||||||
if (!ads1115_type) { return; }
|
if (!ads1115_type) { return; }
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"ADS1115\":["), mqtt_data);
|
ResponseAppend_P(PSTR(",\"ADS1115\":["));
|
||||||
}
|
}
|
||||||
|
|
||||||
char *comma = (char*)"";
|
char *comma = (char*)"";
|
||||||
|
@ -234,7 +234,7 @@ void Ads1115Show(bool json)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]"), mqtt_data);
|
ResponseAppend_P(PSTR("]"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,6 @@ void Ads1115Detect(void)
|
||||||
void Ads1115Show(bool json)
|
void Ads1115Show(bool json)
|
||||||
{
|
{
|
||||||
if (ads1115_type) {
|
if (ads1115_type) {
|
||||||
char stemp[10];
|
|
||||||
|
|
||||||
uint8_t dsxflg = 0;
|
uint8_t dsxflg = 0;
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
@ -107,12 +106,10 @@ void Ads1115Show(bool json)
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
if (!dsxflg ) {
|
if (!dsxflg ) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"ADS1115\":{"), mqtt_data);
|
ResponseAppend_P(PSTR(",\"ADS1115\":{"));
|
||||||
stemp[0] = '\0';
|
|
||||||
}
|
}
|
||||||
|
ResponseAppend_P(PSTR("%s\"A%d\":%d"), (dsxflg) ? "," : "", i, adc_value);
|
||||||
dsxflg++;
|
dsxflg++;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value);
|
|
||||||
strlcpy(stemp, ",", sizeof(stemp));
|
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
} else {
|
} else {
|
||||||
WSContentSend_PD(HTTP_SNS_ANALOG, "ADS1115", i, adc_value);
|
WSContentSend_PD(HTTP_SNS_ANALOG, "ADS1115", i, adc_value);
|
||||||
|
@ -121,7 +118,7 @@ void Ads1115Show(bool json)
|
||||||
}
|
}
|
||||||
if (json) {
|
if (json) {
|
||||||
if (dsxflg) {
|
if (dsxflg) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ bool Ina219CommandSensor(void)
|
||||||
Settings.ina219_mode = XdrvMailbox.payload;
|
Settings.ina219_mode = XdrvMailbox.payload;
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_NVALUE, XSNS_13, Settings.ina219_mode);
|
Response_P(S_JSON_SENSOR_INDEX_NVALUE, XSNS_13, Settings.ina219_mode);
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
@ -240,8 +240,8 @@ void Ina219Show(bool json)
|
||||||
dtostrfd(ina219_current, Settings.flag2.current_resolution, current);
|
dtostrfd(ina219_current, Settings.flag2.current_resolution, current);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_POWERUSAGE "\":%s}"),
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_POWERUSAGE "\":%s}"),
|
||||||
mqtt_data, ina219_types, voltage, current, power);
|
ina219_types, voltage, current, power);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzSensor(DZ_VOLTAGE, voltage);
|
DomoticzSensor(DZ_VOLTAGE, voltage);
|
||||||
|
|
|
@ -110,7 +110,7 @@ void Sht3xShow(bool json)
|
||||||
snprintf_P(types, sizeof(types), PSTR("%s-0x%02X"), sht3x_sensors[i].types, sht3x_sensors[i].address); // "SHT3X-0xXX"
|
snprintf_P(types, sizeof(types), PSTR("%s-0x%02X"), sht3x_sensors[i].types, sht3x_sensors[i].address); // "SHT3X-0xXX"
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, types, temperature, humidity);
|
ResponseAppend_P(JSON_SNS_TEMPHUM, types, temperature, humidity);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if ((0 == tele_period) && (0 == i)) { // We want the same first sensor to report to Domoticz in case a read is missed
|
if ((0 == tele_period) && (0 == i)) { // We want the same first sensor to report to Domoticz in case a read is missed
|
||||||
DomoticzTempHumSensor(temperature, humidity);
|
DomoticzTempHumSensor(temperature, humidity);
|
||||||
|
|
|
@ -71,8 +71,8 @@ TasmotaSerial *MhzSerial;
|
||||||
|
|
||||||
const char kMhzModels[] PROGMEM = "|B";
|
const char kMhzModels[] PROGMEM = "|B";
|
||||||
|
|
||||||
const char ABC_ENABLED[] PROGMEM = "ABC is Enabled";
|
const char ABC_ENABLED[] = "ABC is Enabled";
|
||||||
const char ABC_DISABLED[] PROGMEM = "ABC is Enabled";
|
const char ABC_DISABLED[] = "ABC is Disabled";
|
||||||
|
|
||||||
enum MhzCommands { MHZ_CMND_READPPM, MHZ_CMND_ABCENABLE, MHZ_CMND_ABCDISABLE, MHZ_CMND_ZEROPOINT, MHZ_CMND_RESET, MHZ_CMND_RANGE_1000, MHZ_CMND_RANGE_2000, MHZ_CMND_RANGE_3000, MHZ_CMND_RANGE_5000 };
|
enum MhzCommands { MHZ_CMND_READPPM, MHZ_CMND_ABCENABLE, MHZ_CMND_ABCDISABLE, MHZ_CMND_ZEROPOINT, MHZ_CMND_RESET, MHZ_CMND_RANGE_1000, MHZ_CMND_RANGE_2000, MHZ_CMND_RANGE_3000, MHZ_CMND_RANGE_5000 };
|
||||||
const uint8_t kMhzCommands[][4] PROGMEM = {
|
const uint8_t kMhzCommands[][4] PROGMEM = {
|
||||||
|
@ -276,42 +276,42 @@ bool MhzCommandSensor(void)
|
||||||
case 0:
|
case 0:
|
||||||
Settings.SensorBits1.mhz19b_abc_disable = true;
|
Settings.SensorBits1.mhz19b_abc_disable = true;
|
||||||
MhzSendCmd(MHZ_CMND_ABCDISABLE);
|
MhzSendCmd(MHZ_CMND_ABCDISABLE);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_DISABLED);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_DISABLED);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
Settings.SensorBits1.mhz19b_abc_disable = false;
|
Settings.SensorBits1.mhz19b_abc_disable = false;
|
||||||
MhzSendCmd(MHZ_CMND_ABCENABLE);
|
MhzSendCmd(MHZ_CMND_ABCENABLE);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_ENABLED);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_ENABLED);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
MhzSendCmd(MHZ_CMND_ZEROPOINT);
|
MhzSendCmd(MHZ_CMND_ZEROPOINT);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_ZERO_POINT_CALIBRATION);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_ZERO_POINT_CALIBRATION);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
MhzSendCmd(MHZ_CMND_RESET);
|
MhzSendCmd(MHZ_CMND_RESET);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RESET);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RESET);
|
||||||
break;
|
break;
|
||||||
case 1000:
|
case 1000:
|
||||||
MhzSendCmd(MHZ_CMND_RANGE_1000);
|
MhzSendCmd(MHZ_CMND_RANGE_1000);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_1000);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_1000);
|
||||||
break;
|
break;
|
||||||
case 2000:
|
case 2000:
|
||||||
MhzSendCmd(MHZ_CMND_RANGE_2000);
|
MhzSendCmd(MHZ_CMND_RANGE_2000);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_2000);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_2000);
|
||||||
break;
|
break;
|
||||||
case 3000:
|
case 3000:
|
||||||
MhzSendCmd(MHZ_CMND_RANGE_3000);
|
MhzSendCmd(MHZ_CMND_RANGE_3000);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_3000);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_3000);
|
||||||
break;
|
break;
|
||||||
case 5000:
|
case 5000:
|
||||||
MhzSendCmd(MHZ_CMND_RANGE_5000);
|
MhzSendCmd(MHZ_CMND_RANGE_5000);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_5000);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_5000);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!Settings.SensorBits1.mhz19b_abc_disable) {
|
if (!Settings.SensorBits1.mhz19b_abc_disable) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_ENABLED);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_ENABLED);
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_DISABLED);
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_DISABLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ void MhzShow(bool json)
|
||||||
GetTextIndexed(model, sizeof(model), mhz_type -1, kMhzModels);
|
GetTextIndexed(model, sizeof(model), mhz_type -1, kMhzModels);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_MODEL "\":\"%s\",\"" D_JSON_CO2 "\":%d,\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, types, model, mhz_last_ppm, temperature);
|
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_MODEL "\":\"%s\",\"" D_JSON_CO2 "\":%d,\"" D_JSON_TEMPERATURE "\":%s}"), types, model, mhz_last_ppm, temperature);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzSensor(DZ_AIRQUALITY, mhz_last_ppm);
|
DomoticzSensor(DZ_AIRQUALITY, mhz_last_ppm);
|
||||||
|
|
|
@ -102,8 +102,8 @@ void Tsl2561Show(bool json)
|
||||||
{
|
{
|
||||||
if (tsl2561_valid) {
|
if (tsl2561_valid) {
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"TSL2561\":{\"" D_JSON_ILLUMINANCE "\":%u.%03u}"),
|
ResponseAppend_P(PSTR(",\"TSL2561\":{\"" D_JSON_ILLUMINANCE "\":%u.%03u}"),
|
||||||
mqtt_data, tsl2561_milliLux / 1000, tsl2561_milliLux % 1000);
|
tsl2561_milliLux / 1000, tsl2561_milliLux % 1000);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) { DomoticzSensor(DZ_ILLUMINANCE, (tsl2561_milliLux + 500) / 1000); }
|
if (0 == tele_period) { DomoticzSensor(DZ_ILLUMINANCE, (tsl2561_milliLux + 500) / 1000); }
|
||||||
#endif // USE_DOMOTICZ
|
#endif // USE_DOMOTICZ
|
||||||
|
|
|
@ -149,11 +149,11 @@ void SenseairShow(bool json)
|
||||||
GetTextIndexed(senseair_types, sizeof(senseair_types), senseair_type -1, kSenseairTypes);
|
GetTextIndexed(senseair_types, sizeof(senseair_types), senseair_type -1, kSenseairTypes);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_CO2 "\":%d"), mqtt_data, senseair_types, senseair_co2);
|
ResponseAppend_P(PSTR("%s,\"%s\":{\"" D_JSON_CO2 "\":%d"), senseair_types, senseair_co2);
|
||||||
if (senseair_type != 2) {
|
if (senseair_type != 2) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s"), mqtt_data, temperature, humidity);
|
ResponseAppend_P(PSTR("%s,\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s"), temperature, humidity);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
ResponseAppend_P(PSTR("}"));
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, senseair_co2);
|
if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, senseair_co2);
|
||||||
#endif // USE_DOMOTICZ
|
#endif // USE_DOMOTICZ
|
||||||
|
|
|
@ -132,7 +132,7 @@ void PmsShow(bool json)
|
||||||
{
|
{
|
||||||
if (pms_valid) {
|
if (pms_valid) {
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PMS5003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d,\"PB0.3\":%d,\"PB0.5\":%d,\"PB1\":%d,\"PB2.5\":%d,\"PB5\":%d,\"PB10\":%d}"), mqtt_data,
|
ResponseAppend_P(PSTR(",\"PMS5003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d,\"PB0.3\":%d,\"PB0.5\":%d,\"PB1\":%d,\"PB2.5\":%d,\"PB5\":%d,\"PB10\":%d}"),
|
||||||
pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
|
pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
|
||||||
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env,
|
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env,
|
||||||
pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um, pms_data.particles_50um, pms_data.particles_100um);
|
pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um, pms_data.particles_50um, pms_data.particles_100um);
|
||||||
|
|
|
@ -64,14 +64,14 @@ void MGSShow(bool json)
|
||||||
{
|
{
|
||||||
char buffer[33];
|
char buffer[33];
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"MGS\":{\"NH3\":%s"), mqtt_data, measure_gas(NH3, buffer));
|
ResponseAppend_P(PSTR(",\"MGS\":{\"NH3\":%s"), measure_gas(NH3, buffer));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"CO\":%s"), mqtt_data, measure_gas(CO, buffer));
|
ResponseAppend_P(PSTR(",\"CO\":%s"), measure_gas(CO, buffer));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"NO2\":%s"), mqtt_data, measure_gas(NO2, buffer));
|
ResponseAppend_P(PSTR(",\"NO2\":%s"), measure_gas(NO2, buffer));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"C3H8\":%s"), mqtt_data, measure_gas(C3H8, buffer));
|
ResponseAppend_P(PSTR(",\"C3H8\":%s"), measure_gas(C3H8, buffer));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"C4H10\":%s"), mqtt_data, measure_gas(C4H10, buffer));
|
ResponseAppend_P(PSTR(",\"C4H10\":%s"), measure_gas(C4H10, buffer));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"CH4\":%s"), mqtt_data, measure_gas(GAS_CH4, buffer));
|
ResponseAppend_P(PSTR(",\"CH4\":%s"), measure_gas(GAS_CH4, buffer));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"H2\":%s"), mqtt_data, measure_gas(H2, buffer));
|
ResponseAppend_P(PSTR(",\"H2\":%s"), measure_gas(H2, buffer));
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"C2H5OH\":%s}"), mqtt_data, measure_gas(C2H5OH, buffer));
|
ResponseAppend_P(PSTR(",\"C2H5OH\":%s}"), measure_gas(C2H5OH, buffer));
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
} else {
|
} else {
|
||||||
WSContentSend_PD(HTTP_MGS_GAS, "NH3", measure_gas(NH3, buffer));
|
WSContentSend_PD(HTTP_MGS_GAS, "NH3", measure_gas(NH3, buffer));
|
||||||
|
|
|
@ -47,13 +47,11 @@
|
||||||
#define NOVA_SDS_DEVICE_ID 0xFFFF // NodaSDS all sensor response
|
#define NOVA_SDS_DEVICE_ID 0xFFFF // NodaSDS all sensor response
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
TasmotaSerial *NovaSdsSerial;
|
TasmotaSerial *NovaSdsSerial;
|
||||||
|
|
||||||
uint8_t novasds_type = 1;
|
uint8_t novasds_type = 1;
|
||||||
uint8_t novasds_valid = 0;
|
uint8_t novasds_valid = 0;
|
||||||
|
|
||||||
|
|
||||||
struct sds011data {
|
struct sds011data {
|
||||||
uint16_t pm100;
|
uint16_t pm100;
|
||||||
uint16_t pm25;
|
uint16_t pm25;
|
||||||
|
@ -109,7 +107,7 @@ bool NovaSdsCommand(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint16_t sensor
|
||||||
NovaSdsSerial->readBytes(&recbuf[1], 9);
|
NovaSdsSerial->readBytes(&recbuf[1], 9);
|
||||||
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, recbuf, sizeof(recbuf));
|
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, recbuf, sizeof(recbuf));
|
||||||
|
|
||||||
if ( NULL != buffer ) {
|
if ( nullptr != buffer ) {
|
||||||
// return data to buffer
|
// return data to buffer
|
||||||
memcpy(buffer, recbuf, sizeof(recbuf));
|
memcpy(buffer, recbuf, sizeof(recbuf));
|
||||||
}
|
}
|
||||||
|
@ -126,9 +124,9 @@ bool NovaSdsCommand(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint16_t sensor
|
||||||
void NovaSdsSetWorkPeriod(void)
|
void NovaSdsSetWorkPeriod(void)
|
||||||
{
|
{
|
||||||
// set sensor working period
|
// set sensor working period
|
||||||
NovaSdsCommand(NOVA_SDS_WORKING_PERIOD, NOVA_SDS_SET_MODE, WORKING_PERIOD, NOVA_SDS_DEVICE_ID, NULL);
|
NovaSdsCommand(NOVA_SDS_WORKING_PERIOD, NOVA_SDS_SET_MODE, Settings.novasds_period, NOVA_SDS_DEVICE_ID, nullptr);
|
||||||
// set sensor report only on query
|
// set sensor report only on query
|
||||||
NovaSdsCommand(NOVA_SDS_REPORTING_MODE, NOVA_SDS_SET_MODE, NOVA_SDS_REPORT_QUERY, NOVA_SDS_DEVICE_ID, NULL);
|
NovaSdsCommand(NOVA_SDS_REPORTING_MODE, NOVA_SDS_SET_MODE, NOVA_SDS_REPORT_QUERY, NOVA_SDS_DEVICE_ID, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NovaSdsReadData(void)
|
bool NovaSdsReadData(void)
|
||||||
|
@ -162,7 +160,22 @@ void NovaSdsSecond(void) // Every second
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************\
|
||||||
|
* Command Sensor20
|
||||||
|
*
|
||||||
|
* 1 .. 255 - Set working period in minutes
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
bool NovaSdsCommandSensor(void)
|
||||||
|
{
|
||||||
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 256)) {
|
||||||
|
Settings.novasds_period = XdrvMailbox.payload;
|
||||||
|
NovaSdsSetWorkPeriod();
|
||||||
|
}
|
||||||
|
Response_P(S_JSON_SENSOR_INDEX_NVALUE, XSNS_20, Settings.novasds_period);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void NovaSdsInit(void)
|
void NovaSdsInit(void)
|
||||||
{
|
{
|
||||||
|
@ -195,7 +208,7 @@ void NovaSdsShow(bool json)
|
||||||
char pm2_5[33];
|
char pm2_5[33];
|
||||||
dtostrfd(pm2_5f, 1, pm2_5);
|
dtostrfd(pm2_5f, 1, pm2_5);
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SDS0X1\":{\"PM2.5\":%s,\"PM10\":%s}"), mqtt_data, pm2_5, pm10);
|
ResponseAppend_P(PSTR(",\"SDS0X1\":{\"PM2.5\":%s,\"PM10\":%s}"), pm2_5, pm10);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzSensor(DZ_VOLTAGE, pm2_5); // PM2.5
|
DomoticzSensor(DZ_VOLTAGE, pm2_5); // PM2.5
|
||||||
|
@ -226,6 +239,11 @@ bool Xsns20(uint8_t function)
|
||||||
case FUNC_EVERY_SECOND:
|
case FUNC_EVERY_SECOND:
|
||||||
NovaSdsSecond();
|
NovaSdsSecond();
|
||||||
break;
|
break;
|
||||||
|
case FUNC_COMMAND_SENSOR:
|
||||||
|
if (XSNS_20 == XdrvMailbox.index) {
|
||||||
|
result = NovaSdsCommandSensor();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case FUNC_JSON_APPEND:
|
case FUNC_JSON_APPEND:
|
||||||
NovaSdsShow(1);
|
NovaSdsShow(1);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -71,7 +71,7 @@ void Sgp30Show(bool json)
|
||||||
{
|
{
|
||||||
if (sgp30_ready) {
|
if (sgp30_ready) {
|
||||||
if (json) {
|
if (json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SGP30\":{\"" D_JSON_ECO2 "\":%d,\"" D_JSON_TVOC "\":%d}"), mqtt_data, sgp.eCO2, sgp.TVOC);
|
ResponseAppend_P(PSTR(",\"SGP30\":{\"" D_JSON_ECO2 "\":%d,\"" D_JSON_TVOC "\":%d}"), sgp.eCO2, sgp.TVOC);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, sgp.eCO2);
|
if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, sgp.eCO2);
|
||||||
#endif // USE_DOMOTICZ
|
#endif // USE_DOMOTICZ
|
||||||
|
|
|
@ -34,7 +34,7 @@ uint8_t sr04_echo_pin = 0;
|
||||||
uint8_t sr04_trig_pin = 0;
|
uint8_t sr04_trig_pin = 0;
|
||||||
real64_t distance;
|
real64_t distance;
|
||||||
|
|
||||||
NewPing* sonar = NULL;
|
NewPing* sonar = nullptr;
|
||||||
|
|
||||||
void Sr04Init(void)
|
void Sr04Init(void)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ void Sr04Show(bool json)
|
||||||
dtostrfd(distance, 3, distance_chr);
|
dtostrfd(distance, 3, distance_chr);
|
||||||
|
|
||||||
if(json) {
|
if(json) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SR04\":{\"" D_JSON_DISTANCE "\":%s}"), mqtt_data, distance_chr);
|
ResponseAppend_P(PSTR(",\"SR04\":{\"" D_JSON_DISTANCE "\":%s}"), distance_chr);
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
DomoticzSensor(DZ_COUNT, distance_chr); // Send distance as Domoticz Counter value
|
DomoticzSensor(DZ_COUNT, distance_chr); // Send distance as Domoticz Counter value
|
||||||
|
|
|
@ -314,11 +314,11 @@ void SDM120Show(bool json)
|
||||||
#endif // USE_SDM220
|
#endif // USE_SDM220
|
||||||
if (json) {
|
if (json) {
|
||||||
#ifdef USE_SDM220
|
#ifdef USE_SDM220
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_PHASE_ANGLE "\":%s,\"" D_JSON_IMPORT_ACTIVE "\":%s,\"" D_JSON_EXPORT_ACTIVE "\":%s,\"" D_JSON_IMPORT_REACTIVE "\":%s,\"" D_JSON_EXPORT_REACTIVE "\":%s,\"" D_JSON_TOTAL_REACTIVE "\":%s}"),
|
ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_PHASE_ANGLE "\":%s,\"" D_JSON_IMPORT_ACTIVE "\":%s,\"" D_JSON_EXPORT_ACTIVE "\":%s,\"" D_JSON_IMPORT_REACTIVE "\":%s,\"" D_JSON_EXPORT_REACTIVE "\":%s,\"" D_JSON_TOTAL_REACTIVE "\":%s}"),
|
||||||
mqtt_data, energy_total, active_power, apparent_power, reactive_power, frequency, power_factor, voltage, current, phase_angle, import_active, export_active, import_reactive, export_reactive, total_reactive);
|
energy_total, active_power, apparent_power, reactive_power, frequency, power_factor, voltage, current, phase_angle, import_active, export_active, import_reactive, export_reactive, total_reactive);
|
||||||
#else
|
#else
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"),
|
ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"),
|
||||||
mqtt_data, energy_total, active_power, apparent_power, reactive_power, frequency, power_factor, voltage, current);
|
energy_total, active_power, apparent_power, reactive_power, frequency, power_factor, voltage, current);
|
||||||
#endif // USE_SDM220
|
#endif // USE_SDM220
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (0 == tele_period) {
|
if (0 == tele_period) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue