mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Merge branch 'development' into patch-4
This commit is contained in:
commit
17a0cb6982
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@ -29,7 +29,7 @@ _Make sure your have performed every step and checked the applicable boxes befor
|
||||
|
||||
- [ ] Read the [Contributing Guide and Policy](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md) and [the Code of Conduct](https://github.com/arendst/Tasmota/blob/development/CODE_OF_CONDUCT.md)
|
||||
- [ ] Searched the problem in [issues](https://github.com/arendst/Tasmota/issues)
|
||||
- [ ] Searched the problem in the [wiki](https://github.com/arendst/Tasmota/wiki/Troubleshooting)
|
||||
- [ ] Searched the problem in the [docs](https://tasmota.github.io/docs/#/help/FAQ)
|
||||
- [ ] Searched the problem in the [forum](https://groups.google.com/d/forum/sonoffusers)
|
||||
- [ ] Searched the problem in the [chat](https://discord.gg/Ks2Kzd4)
|
||||
- [ ] Device used (e.g., Sonoff Basic): _____
|
||||
|
2
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
@ -10,7 +10,7 @@ Please take a few minutes to complete the requested information below. Our abili
|
||||
DO NOT DELETE ANY TEXT from this template! Otherwise the issue will be auto-closed.
|
||||
-->
|
||||
|
||||
**Have you looked for this feature in other issues and in the wiki?**
|
||||
**Have you looked for this feature in other issues and in the docs?**
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
_A clear and concise description of what the problem is._
|
||||
|
2
.github/issue-close-app.yml
vendored
2
.github/issue-close-app.yml
vendored
@ -39,7 +39,7 @@ issueConfigs:
|
||||
- "EXPECTED BEHAVIOUR"
|
||||
- content:
|
||||
# template 2: feature request
|
||||
- "Have you looked for this feature in other issues and in the wiki"
|
||||
- "Have you looked for this feature in other issues and in the docs"
|
||||
- "Describe the solution you'd like"
|
||||
|
||||
# Optional configuration:
|
||||
|
@ -12,7 +12,7 @@ cache: false
|
||||
env:
|
||||
- ENV=tasmota
|
||||
- ENV=tasmota-minimal
|
||||
- ENV=tasmota-basic
|
||||
- ENV=tasmota-lite
|
||||
- ENV=tasmota-knx
|
||||
- ENV=tasmota-sensors
|
||||
- ENV=tasmota-display
|
||||
|
13
BUILDS.md
13
BUILDS.md
@ -1,6 +1,6 @@
|
||||
## Available Features and Sensors
|
||||
|
||||
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
|-----------------------|---------|-------|--------|-----|---------|----|---------|--------
|
||||
| MY_LANGUAGE en-GB | x | x | x | x | x | x | x |
|
||||
| USE_ARDUINO_OTA | - | - | - | - | - | - | - |
|
||||
@ -27,7 +27,7 @@
|
||||
| USE_EXPRESSION | - | - | - | - | - | - | - |
|
||||
| SUPPORT_IF_STATEMENT | - | - | - | - | - | - | - |
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
| ROTARY_V1 | - | - | - | - | - | - | - |
|
||||
| USE_SONOFF_RF | - | - | x | x | x | - | - |
|
||||
| USE_RF_FLASH | - | - | x | x | x | - | - |
|
||||
@ -42,7 +42,7 @@
|
||||
| USE_DEEPSLEEP | - | - | x | - | x | - | - |
|
||||
| USE_EXS_DIMMER | - | - | x | x | - | - | - |
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
| USE_LIGHT | - | x | x | x | x | x | x |
|
||||
| USE_WS2812 | - | - | x | x | x | - | x |
|
||||
| USE_WS2812_DMA | - | - | - | - | - | - | - |
|
||||
@ -69,7 +69,7 @@
|
||||
| USE_MAX31855 | - | - | - | - | x | - | - |
|
||||
| USE_MAX31865 | - | - | - | - | - | - | - |
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
| USE_I2C | - | - | x | x | x | - | x |
|
||||
| USE_SHT | - | - | x | x | x | - | x |
|
||||
| USE_HTU | - | - | x | x | x | - | x |
|
||||
@ -106,8 +106,9 @@
|
||||
| USE_PAJ7620 | - | - | - | - | - | - | - |
|
||||
| USE_PCF8574 | - | - | - | - | - | - | - |
|
||||
| USE_HIH6 | - | - | - | - | x | - | - |
|
||||
| USE_DHT12 | - | - | - | - | x | - | - |
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
| USE_SPI | - | - | - | - | - | - | x |
|
||||
| USE_MHZ19 | - | - | x | x | x | - | x |
|
||||
| USE_SENSEAIR | - | - | x | x | x | - | x |
|
||||
@ -133,7 +134,7 @@
|
||||
| USE_A4988_STEPPER | - | - | - | - | - | - | - |
|
||||
| USE_TASMOTA_SLAVE | - | - | - | - | - | - | - | Experimental
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
| USE_DISPLAY | - | - | - | - | - | - | x |
|
||||
| USE_DISPLAY_LCD | - | - | - | - | - | - | x |
|
||||
| USE_DISPLAY_SSD1306 | - | - | - | - | - | - | x |
|
||||
|
@ -61,4 +61,5 @@ Index | Define | Driver | Device | Address(es) | Description
|
||||
38 | USE_DISPLAY_ILI9488 | xdsp_08 | FT6236 | 0x38 | Touch panel controller
|
||||
39 | USE_DISPLAY_RA8876 | xdsp_10 | FT5316 | 0x38 | Touch panel controller
|
||||
40 | USE_TSL2591 | xsns_57 | TLS2591 | 0x29 | Light intensity sensor
|
||||
41 | USE_DHT12 | xsns_58 | DHT12 | 0x5C | Temperature and humidity sensor
|
||||
|
||||
|
@ -20,7 +20,7 @@ In addition to the [release webpage](https://github.com/arendst/Tasmota/releases
|
||||
|
||||
## Development
|
||||
|
||||
[](https://github.com/arendst/Tasmota)
|
||||
[](https://github.com/arendst/Tasmota)
|
||||
[](http://thehackbox.org/tasmota/)
|
||||
[](https://travis-ci.org/arendst/Tasmota)
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
# RELEASE NOTES
|
||||
|
||||
### Sonoff-Tasmota is now Tasmota
|
||||
|
||||
## Migration Information
|
||||
|
||||
See [migration path](https://tasmota.github.io/docs/#/Upgrading?id=migration-path) for instructions how to migrate to a major version. Pay attention to the following version breaks due to dynamic settings updates:
|
||||
@ -13,6 +11,7 @@ See [migration path](https://tasmota.github.io/docs/#/Upgrading?id=migration-pat
|
||||
3. Migrate to **Sonoff-Tasmota 5.14**
|
||||
4. Migrate to **Sonoff-Tasmota 6.x**
|
||||
5. Migrate to **Tasmota 7.x**
|
||||
6. Migrate to **Tasmota 8.x**
|
||||
|
||||
## Supported Core versions
|
||||
|
||||
@ -34,7 +33,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
||||
|
||||
- **tasmota.bin** = The Tasmota version with sensors. **RECOMMENDED RELEASE BINARY**
|
||||
- **tasmota-BG.bin** to **tasmota-TW.bin** = The Tasmota version in different languages.
|
||||
- **tasmota-basic.bin** = The Basic version without most sensors.
|
||||
- **tasmota-lite.bin** = The Lite version without most sensors.
|
||||
- **tasmota-knx.bin** = The Knx version without some features but adds KNX support.
|
||||
- **tasmota-sensors.bin** = The Sensors version adds more useful sensors.
|
||||
- **tasmota-ir** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features.
|
||||
@ -47,27 +46,6 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 7.1.2.6
|
||||
### Version 8.0.0.1
|
||||
|
||||
- Change Exception reporting removing exception details from ``Status 1`` and consolidated in ``Status 12`` if available
|
||||
- Change HTTP CORS from command ``SetOption73 0/1`` to ``Cors <cors_domain>`` allowing user control of specific CORS domain by Shantur Rathore (#7066)
|
||||
- Change GUI Shutter button text to Up and Down Arrows based on PR by Xavier Muller (#7166)
|
||||
- Change amount of supported DHT sensors from 3 to 4 by Xavier Muller (#7167)
|
||||
- Change some Settings locations freeing up space for future single char allowing variable length text
|
||||
- Fix flashing H801 led at boot by Stefan Hadinger (#7165, #649)
|
||||
- Fix duplicated ``Backlog`` when using Event inside a Backlog by Adrian Scillato (#7178, #7147)
|
||||
- Fix Gui Timer when using a negative zero offset of -00:00 by Peter Ooms (#7174)
|
||||
- Add command ``SerialConfig 0..23`` or ``SerialConfig 8N1`` to select Serial Config based in PR by Luis Teixeira (#7108)
|
||||
- Add command ``Sensor34 9 <weight code>`` to set minimum delta to trigger JSON message by @tobox (#7188)
|
||||
- Add rule var ``%topic%`` by Adrian Scillato (#5522)
|
||||
- Add rule triggers ``tele-wifi1#xxx`` by Adrian Scillato (#7093)
|
||||
- Add SML bus decoder syntax support for byte order by Gerhard Mutz (#7112)
|
||||
- Add experimental support for stepper motor shutter control by Stefan Bode
|
||||
- Add optional USE_MQTT_TLS to tasmota-minimal.bin by Bohdan Kmit (#7115)
|
||||
- Add save call stack in RTC memory in case of crash, command ``Status 12`` to dump the stack by Stefan Hadinger
|
||||
- Add Home Assistant force update by Frederico Leoni (#7140, #7074)
|
||||
- Add Wifi Signal Strength in dBm in addition to RSSI Wifi Experience by Andreas Schultz (#7145)
|
||||
- Add Yaw, Pitch and Roll support for MPU6050 by Philip Barclay (#7058)
|
||||
- Add reporting of raw weight to JSON from HX711 to overcome auto-tare functionality by @tobox (#7171)
|
||||
- Add Zigbee support for Xiaomi Aqara Vibration Sensor and Presence Sensor by Stefan Hadinger
|
||||
- Add Shutter functions ramp up/down and MQTT reporting by Stefan Bode
|
||||
- Change Settings text handling allowing variable length text within a total text pool of 699 characters
|
||||
|
@ -20,7 +20,7 @@ default_envs =
|
||||
; tasmota
|
||||
; tasmota-ircustom ; alternative to 'tasmota' with full IR protocols activated, you will need to disable some features to keep code not too big
|
||||
; tasmota-minimal
|
||||
; tasmota-basic
|
||||
; tasmota-lite
|
||||
; tasmota-knx
|
||||
; tasmota-sensors
|
||||
; tasmota-display
|
||||
|
@ -19,7 +19,7 @@ default_envs =
|
||||
; tasmota-debug
|
||||
; tasmota-ircustom ; alternative to 'tasmota' with full IR protocols activated, you will need to disable some features to keep code not too big
|
||||
; tasmota-minimal
|
||||
; tasmota-basic
|
||||
; tasmota-lite
|
||||
; tasmota-knx
|
||||
; tasmota-sensors
|
||||
; tasmota-display
|
||||
@ -36,7 +36,7 @@ build_flags = ${core_active.build_flags}
|
||||
; *** Optional Firmware configurations
|
||||
; -DFIRMWARE_MINIMAL
|
||||
; -DFIRMWARE_SENSORS
|
||||
; -DFIRMWARE_BASIC
|
||||
; -DFIRMWARE_LITE
|
||||
; -DFIRMWARE_KNX_NO_EMULATION
|
||||
; -DFIRMWARE_DISPLAYS
|
||||
; -DFIRMWARE_IR
|
||||
|
@ -18,8 +18,8 @@ extra_scripts = ${common.extra_scripts}
|
||||
[env:tasmota-minimal]
|
||||
build_flags = ${common.build_flags} -DFIRMWARE_MINIMAL
|
||||
|
||||
[env:tasmota-basic]
|
||||
build_flags = ${common.build_flags} -DFIRMWARE_BASIC
|
||||
[env:tasmota-lite]
|
||||
build_flags = ${common.build_flags} -DFIRMWARE_LITE
|
||||
|
||||
[env:tasmota-knx]
|
||||
build_flags = ${common.build_flags} -DFIRMWARE_KNX_NO_EMULATION
|
||||
|
@ -1,11 +1,30 @@
|
||||
## Unreleased (development)
|
||||
|
||||
### 8.0.0.1 20191221
|
||||
|
||||
- Change Settings text handling allowing variable length text within a total text pool of 699 characters
|
||||
- Change Smoother ``Fade`` using 100Hz instead of 20Hz animation (#7179)
|
||||
|
||||
## Released
|
||||
|
||||
### 7.2.0 20191221
|
||||
|
||||
- Release
|
||||
- Fix Arduino IDE compile error (#7277)
|
||||
- Fix restore ShutterAccuracy, MqttLog, WifiConfig, WifiPower and SerialConfig (#7281)
|
||||
- Fix no AP on initial install (#7282)
|
||||
|
||||
### 7.1.2.6 20191214
|
||||
|
||||
- Change some more Settings locations freeing up space for future single char allowing variable length text
|
||||
- Change tasmota-basic.bin and FIRMWARE_BASIC to tasmota-lite.bin and FIRMWARE_LITE
|
||||
- Fix DeepSleep in case there is no wifi by Stefan Bode (#7213)
|
||||
- Fix Fade would ignore ``savedata 0`` and store to flash anyways (#7262)
|
||||
- Add Zigbee send automatic ZigbeeRead after sending a command
|
||||
- Add Zigbee improving Occupancy:false detection for Aqara sensor
|
||||
- Add fallback functionality from next version 7.1.2.7
|
||||
- Add fallback support from version 8.x
|
||||
- Add restriction if fallback firmware is incompatible with settings resulting in unreachable device
|
||||
- Add support for DHT12 Temperature and Humidity sensor by Stefan Oskamp
|
||||
|
||||
### 7.1.2.5 20191213
|
||||
|
||||
@ -46,8 +65,6 @@
|
||||
- Add experimental support for stepper motor shutter control by Stefan Bode
|
||||
- Add optional USE_MQTT_TLS to tasmota-minimal.bin by Bohdan Kmit (#7115)
|
||||
|
||||
## Released
|
||||
|
||||
### 7.1.2 20191206
|
||||
|
||||
- Maintenance Release
|
||||
|
@ -635,4 +635,8 @@ const char S_INFORMATION[] PROGMEM = D_INFORMATION;
|
||||
const char S_RESTART[] PROGMEM = D_RESTART;
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
const uint32_t MARKER_START = 0x5AA55AA5;
|
||||
const uint32_t MARKER_END = 0xA55AA55A;
|
||||
const uint32_t VERSION_MARKER[] PROGMEM = { MARKER_START, VERSION, MARKER_END };
|
||||
|
||||
#endif // _I18N_H_
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Грешка при изтриване на RF чипа"
|
||||
#define D_UPLOAD_ERR_12 "Грешка при записване в RF чипа"
|
||||
#define D_UPLOAD_ERR_13 "Грешка при декодиране на RF фърмуера"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Код на грешка при зареждането"
|
||||
|
||||
#define D_ENTER_COMMAND "Въвеждане на команда"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Chyba smazání RF chipu"
|
||||
#define D_UPLOAD_ERR_12 "Chyba při zápisu do RF chipu"
|
||||
#define D_UPLOAD_ERR_13 "Chyba dekódování RF firmwaru"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Chyba nahrávání"
|
||||
|
||||
#define D_ENTER_COMMAND "Vlož příkaz"
|
||||
|
@ -28,7 +28,7 @@
|
||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||
* Use online command Prefix to translate cmnd, stat and tele.
|
||||
*
|
||||
* Updated until v6.6.0.21
|
||||
* Updated until v8.0.0
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "RF Chip löschen fehlgeschlagen"
|
||||
#define D_UPLOAD_ERR_12 "RF Chip beschreiben fehlgeschlagen"
|
||||
#define D_UPLOAD_ERR_13 "RF Firmware ungültig"
|
||||
#define D_UPLOAD_ERR_14 "Nicht kompatibel"
|
||||
#define D_UPLOAD_ERROR_CODE "Upload Fehler Nummer"
|
||||
|
||||
#define D_ENTER_COMMAND "Befehl eingeben"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Αποτυχία σβησίματος στο RF chip"
|
||||
#define D_UPLOAD_ERR_12 "Αποτυχία εγγραφής στο RF chip"
|
||||
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Κωδικός λάθους στη μεταφόρτωση"
|
||||
|
||||
#define D_ENTER_COMMAND "Εισαγωγή εντολής"
|
||||
|
@ -28,7 +28,7 @@
|
||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||
* Use online command Prefix to translate cmnd, stat and tele.
|
||||
*
|
||||
* Updated until v6.2.1.11
|
||||
* Updated until v8.0.0.0
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
|
||||
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
|
||||
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Upload error code"
|
||||
|
||||
#define D_ENTER_COMMAND "Enter command"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "No se pudo borrar en el chip RF"
|
||||
#define D_UPLOAD_ERR_12 "No se puedo escribir en el chip RF"
|
||||
#define D_UPLOAD_ERR_13 "No se pudo decodificar firmware RF"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Código de error de carga"
|
||||
|
||||
#define D_ENTER_COMMAND "Ingresar comando"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Erreur d'effacement du chip RF"
|
||||
#define D_UPLOAD_ERR_12 "Erreur d'accès en écriture au chip RF"
|
||||
#define D_UPLOAD_ERR_13 "Erreur de décodage du firmware RF"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Code d'erreur téléchargement"
|
||||
|
||||
#define D_ENTER_COMMAND "Saisir une commande"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "נכשלה RF מחיקת שבב"
|
||||
#define D_UPLOAD_ERR_12 "נכשלה RF כתיבת שבב"
|
||||
#define D_UPLOAD_ERR_13 "נכשלה RF קידוד קושחת שבב"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "שגיאת קוד העלאה"
|
||||
|
||||
#define D_ENTER_COMMAND "הקש פקודה"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Az RF chip törlése sikertelen"
|
||||
#define D_UPLOAD_ERR_12 "Az RF chip írása sikertelen"
|
||||
#define D_UPLOAD_ERR_13 "Az RF firmware dekódolása sikertelen"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Feltöltési hibakód"
|
||||
|
||||
#define D_ENTER_COMMAND "Kérem a parancsot..."
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Cancellazione fallita del chip RF"
|
||||
#define D_UPLOAD_ERR_12 "Scrittura fallita del chip RF"
|
||||
#define D_UPLOAD_ERR_13 "Decodifica fallita del firmware RF"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Codice errore invio"
|
||||
|
||||
#define D_ENTER_COMMAND "Inserire comando"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "RF 칩 삭제 실패"
|
||||
#define D_UPLOAD_ERR_12 "RF 칩 쓰기 실패"
|
||||
#define D_UPLOAD_ERR_13 "RF 펌웨어 decode 실패"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "업로드 에러 코드"
|
||||
|
||||
#define D_ENTER_COMMAND "커맨드 입력"
|
||||
|
@ -28,7 +28,7 @@
|
||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||
* Use online command Prefix to translate cmnd, stat and tele.
|
||||
*
|
||||
* Updated until v6.7.0
|
||||
* Updated until v8.0.0
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Wissen RF chip mislukt"
|
||||
#define D_UPLOAD_ERR_12 "Opwaarderen RF chip mislukt"
|
||||
#define D_UPLOAD_ERR_13 "Decoderen RF bestand mislukt"
|
||||
#define D_UPLOAD_ERR_14 "Niet geschikt"
|
||||
#define D_UPLOAD_ERROR_CODE "Opwaardeer foutcode"
|
||||
|
||||
#define D_ENTER_COMMAND "Geef opdracht"
|
||||
@ -478,12 +479,12 @@
|
||||
#define D_PARTICALS_BEYOND "Stofdeeltjes"
|
||||
|
||||
// xsns_32_mpu6050.ino
|
||||
#define D_AX_AXIS "Accel. X-Axis"
|
||||
#define D_AY_AXIS "Accel. Y-Axis"
|
||||
#define D_AZ_AXIS "Accel. Z-Axis"
|
||||
#define D_GX_AXIS "Gyro X-Axis"
|
||||
#define D_GY_AXIS "Gyro Y-Axis"
|
||||
#define D_GZ_AXIS "Gyro Z-Axis"
|
||||
#define D_AX_AXIS "Versn. X-as"
|
||||
#define D_AY_AXIS "Versn. Y-as"
|
||||
#define D_AZ_AXIS "Versn. Z-as"
|
||||
#define D_GX_AXIS "Gyro X-as"
|
||||
#define D_GY_AXIS "Gyro Y-as"
|
||||
#define D_GZ_AXIS "Gyro Z-as"
|
||||
|
||||
// xsns_34_hx711.ino
|
||||
#define D_HX_CAL_REMOVE "Verwijder gewicht"
|
||||
@ -626,9 +627,9 @@
|
||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Błąd kasowania układu RF"
|
||||
#define D_UPLOAD_ERR_12 "Błąd zapisu układu RF"
|
||||
#define D_UPLOAD_ERR_13 "Błąd dekodowania oprrogramowania układu RF"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Błąd wgrywania"
|
||||
|
||||
#define D_ENTER_COMMAND "Wprowadź polecenie"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Falha ao apagar o chip RF"
|
||||
#define D_UPLOAD_ERR_12 "Falha ao escrever o chip RF"
|
||||
#define D_UPLOAD_ERR_13 "Falha ao decodificar o firmware de RF"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Código de erro do envio"
|
||||
|
||||
#define D_ENTER_COMMAND "Inserir comando"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Falha ao apagar o chip de RF"
|
||||
#define D_UPLOAD_ERR_12 "Falha ao escrever no chip de RF"
|
||||
#define D_UPLOAD_ERR_13 "Falha ao descodificar o firmware RF"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Código de erro do envio"
|
||||
|
||||
#define D_ENTER_COMMAND "Inserir comando"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
|
||||
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
|
||||
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Код ошибки загрузки"
|
||||
|
||||
#define D_ENTER_COMMAND "Введите команду"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Chyba zmazania RF chipu"
|
||||
#define D_UPLOAD_ERR_12 "Chyba pri zápise do RF chipu"
|
||||
#define D_UPLOAD_ERR_13 "Chyba dekódovania RF firmwaru"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Chyba nahrávania"
|
||||
|
||||
#define D_ENTER_COMMAND "Vlož príkaz"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Misslyckades rensa RF chip"
|
||||
#define D_UPLOAD_ERR_12 "Misslyckades skriva till RF chip"
|
||||
#define D_UPLOAD_ERR_13 "Misslyckades avkoda RF firmware"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Uppladdningsfelkod"
|
||||
|
||||
#define D_ENTER_COMMAND "Ange kommando"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
|
||||
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
|
||||
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Upload error code"
|
||||
|
||||
#define D_ENTER_COMMAND "Komut girişi"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Помилка стирання чипу RF"
|
||||
#define D_UPLOAD_ERR_12 "Помилка запису чипу RF"
|
||||
#define D_UPLOAD_ERR_13 "Помилка розкодування прошивки RF"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "Код помилки завантаження"
|
||||
|
||||
#define D_ENTER_COMMAND "Уведіть команду"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "擦除 RF 芯片失败"
|
||||
#define D_UPLOAD_ERR_12 "写入 RF 芯片失败"
|
||||
#define D_UPLOAD_ERR_13 "解码 RF 固件失败"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "上传错误代码"
|
||||
|
||||
#define D_ENTER_COMMAND "输入命令"
|
||||
|
@ -353,6 +353,7 @@
|
||||
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
|
||||
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
|
||||
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
|
||||
#define D_UPLOAD_ERR_14 "Not compatible"
|
||||
#define D_UPLOAD_ERROR_CODE "上傳錯誤代碼"
|
||||
|
||||
#define D_ENTER_COMMAND "輸入命令"
|
||||
|
@ -418,6 +418,7 @@
|
||||
// #define USE_PAJ7620 // [I2cDriver34] Enable PAJ7620 gesture sensor (I2C address 0x73) (+2.5k code)
|
||||
// #define USE_PCF8574 // [I2cDriver2] Enable PCF8574 I/O Expander (I2C addresses 0x20 - 0x26 and 0x39 - 0x3F) (+1k9 code)
|
||||
// #define USE_HIH6 // [I2cDriver36] Enable Honeywell HIH Humidity and Temperature sensor (I2C address 0x27) (+0k6)
|
||||
// #define USE_DHT12 // [I2cDriver41] Enable DHT12 humidity and temperature sensor (I2C address 0x5C) (+0k7 code)
|
||||
|
||||
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
|
||||
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
|
||||
@ -572,7 +573,7 @@
|
||||
* See RELEASENOTES.md for selected features
|
||||
\*********************************************************************************************/
|
||||
|
||||
//#define FIRMWARE_BASIC // Create tasmota-basic with no sensors
|
||||
//#define FIRMWARE_LITE // Create tasmota-lite with no sensors
|
||||
//#define FIRMWARE_SENSORS // Create tasmota-sensors with useful sensors enabled
|
||||
//#define FIRMWARE_KNX_NO_EMULATION // Create tasmota-knx with KNX but without Emulation
|
||||
//#define FIRMWARE_DISPLAYS // Create tasmota-display with display drivers enabled
|
||||
|
@ -91,7 +91,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
uint32_t grouptopic_mode : 1; // bit 25 (v7.0.0.1) - SetOption75 - GroupTopic replaces %topic% (0) or fixed topic cmnd/grouptopic (1)
|
||||
uint32_t bootcount_update : 1; // bit 26 (v7.0.0.4) - SetOption76 - Enable incrementing bootcount when deepsleep is enabled
|
||||
uint32_t slider_dimmer_stay_on : 1; // bit 27 (v7.0.0.6) - SetOption77 - Do not power off if slider moved to far left
|
||||
uint32_t spare28 : 1;
|
||||
uint32_t compatibility_check : 1; // bit 28 (v7.1.2.6) - SetOption78 - Disable OTA compatibility check
|
||||
uint32_t spare29 : 1;
|
||||
uint32_t shutter_mode : 1; // bit 30 (v6.6.0.14) - SetOption80 - Enable shutter support
|
||||
uint32_t pcf8574_ports_inverted : 1; // bit 31 (v6.6.0.14) - SetOption81 - Invert all ports on PCF8574 devices
|
||||
@ -231,13 +231,6 @@ typedef struct {
|
||||
|
||||
const uint8_t MAX_TUYA_FUNCTIONS = 16;
|
||||
|
||||
/*
|
||||
struct SYSCFG {
|
||||
unsigned long cfg_holder; // 000 Pre v6 header
|
||||
unsigned long save_flag; // 004
|
||||
unsigned long version; // 008
|
||||
unsigned long bootcount; // 00C
|
||||
*/
|
||||
struct SYSCFG {
|
||||
uint16_t cfg_holder; // 000 v6 header
|
||||
uint16_t cfg_size; // 002
|
||||
@ -274,8 +267,6 @@ struct SYSCFG {
|
||||
|
||||
uint8_t ex_free_1d6[10]; // 1D6
|
||||
|
||||
// End of single char array of 456 chars max (phase 3)
|
||||
|
||||
SysBitfield4 ex_flag4; // 1E0
|
||||
uint8_t ex_serial_config; // 1E4
|
||||
uint8_t ex_wifi_output_power; // 1E5
|
||||
@ -428,7 +419,7 @@ struct SYSCFG {
|
||||
unsigned long weight_calibration; // 7C4
|
||||
unsigned long energy_frequency_calibration; // 7C8 also used by HX711 to save last weight
|
||||
uint16_t web_refresh; // 7CC
|
||||
char mems[MAX_RULE_MEMS][10]; // 7CE
|
||||
char mems[MAX_RULE_MEMS][10]; // 7CE - Used by scripter as script_pram
|
||||
|
||||
char rules[MAX_RULE_SETS][MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m, 3 x 512 bytes in v5.14.0b
|
||||
|
||||
|
@ -343,6 +343,48 @@ void SetFlashModeDout(void)
|
||||
delete[] _buffer;
|
||||
}
|
||||
|
||||
uint32_t OtaVersion(void)
|
||||
{
|
||||
if (Settings.flag3.compatibility_check) {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
eboot_command ebcmd;
|
||||
eboot_command_read(&ebcmd);
|
||||
uint32_t start_address = ebcmd.args[0];
|
||||
uint32_t end_address = start_address + (ebcmd.args[2] & 0xFFFFF000) + FLASH_SECTOR_SIZE;
|
||||
uint32_t* buffer = new uint32_t[FLASH_SECTOR_SIZE / 4];
|
||||
|
||||
uint32_t version[3] = { 0 };
|
||||
bool found = false;
|
||||
for (uint32_t address = start_address; address < end_address; address = address + FLASH_SECTOR_SIZE) {
|
||||
ESP.flashRead(address, (uint32_t*)buffer, FLASH_SECTOR_SIZE);
|
||||
for (uint32_t i = 0; i < (FLASH_SECTOR_SIZE / 4); i++) {
|
||||
version[0] = version[1];
|
||||
version[1] = version[2];
|
||||
version[2] = buffer[i];
|
||||
if ((version[0] == MARKER_START) && (version[2] == MARKER_END)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) { break; }
|
||||
}
|
||||
delete[] buffer;
|
||||
|
||||
if (!found) { version[1] = 0; }
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("OTA: Version 0x%08X, Compatible 0x%08X"), version[1], VERSION_COMPATIBLE);
|
||||
|
||||
return version[1];
|
||||
}
|
||||
|
||||
void AbandonOta(void)
|
||||
{
|
||||
uint32_t eboot_magic = 0;
|
||||
ESP.rtcUserMemoryWrite(0, (uint32_t*)&eboot_magic, sizeof(eboot_magic));
|
||||
}
|
||||
|
||||
void SettingsBufferFree(void)
|
||||
{
|
||||
if (settings_buffer != nullptr) {
|
||||
@ -446,10 +488,7 @@ void UpdateQuickPowerCycle(bool update)
|
||||
* Config Settings.text char array support
|
||||
\*********************************************************************************************/
|
||||
|
||||
char aws_mqtt_host[66];
|
||||
char aws_mqtt_user[1] { 0 };
|
||||
|
||||
const uint32_t settings_text_size = 457; // Settings.flag4 (1E0) - Settings.ota_url (017)
|
||||
const uint32_t settings_text_size = 699; // Settings.flag4 (2D2) - Settings.ota_url (017)
|
||||
|
||||
uint32_t GetSettingsTextLen(void)
|
||||
{
|
||||
@ -471,98 +510,43 @@ bool SettingsUpdateText(uint32_t index, const char* replace_me)
|
||||
char replace[replace_len +1];
|
||||
memcpy(replace, replace_me, sizeof(replace));
|
||||
|
||||
if (Settings.version < 0x07010207) {
|
||||
uint32_t idx = 0;
|
||||
switch (index) {
|
||||
case SET_OTAURL: strlcpy(Settings.ota_url, replace, sizeof(Settings.ota_url)); break;
|
||||
case SET_MQTTPREFIX3: idx++;
|
||||
case SET_MQTTPREFIX2: idx++;
|
||||
case SET_MQTTPREFIX1: strlcpy(Settings.mqtt_prefix[idx], replace, sizeof(Settings.mqtt_prefix[idx])); break;
|
||||
case SET_STASSID2: idx++;
|
||||
case SET_STASSID1: strlcpy(Settings.sta_ssid[idx], replace, sizeof(Settings.sta_ssid[idx])); break;
|
||||
case SET_STAPWD2: idx++;
|
||||
case SET_STAPWD1: strlcpy(Settings.sta_pwd[idx], replace, sizeof(Settings.sta_pwd[idx])); break;
|
||||
case SET_HOSTNAME: strlcpy(Settings.hostname, replace, sizeof(Settings.hostname)); break;
|
||||
case SET_SYSLOG_HOST: strlcpy(Settings.syslog_host, replace, sizeof(Settings.syslog_host)); break;
|
||||
case SET_WEBPWD: strlcpy(Settings.web_password, replace, sizeof(Settings.web_password)); break;
|
||||
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
||||
case SET_MQTT_HOST:
|
||||
if (strlen(replace) <= sizeof(Settings.mqtt_host)) {
|
||||
strlcpy(Settings.mqtt_host, replace, sizeof(Settings.mqtt_host));
|
||||
Settings.mqtt_user[0] = 0;
|
||||
} else {
|
||||
// need to split in mqtt_user first then mqtt_host
|
||||
strlcpy(Settings.mqtt_user, replace, sizeof(Settings.mqtt_user));
|
||||
strlcpy(Settings.mqtt_host, &replace[sizeof(Settings.mqtt_user)-1], sizeof(Settings.mqtt_host));
|
||||
}
|
||||
break;
|
||||
case SET_MQTT_USER: break;
|
||||
#else
|
||||
case SET_MQTT_HOST: strlcpy(Settings.mqtt_host, replace, sizeof(Settings.mqtt_host)); break;
|
||||
case SET_MQTT_USER: strlcpy(Settings.mqtt_user, replace, sizeof(Settings.mqtt_user)); break;
|
||||
#endif
|
||||
case SET_MQTT_CLIENT: strlcpy(Settings.mqtt_client, replace, sizeof(Settings.mqtt_client)); break;
|
||||
case SET_MQTT_PWD: strlcpy(Settings.mqtt_pwd, replace, sizeof(Settings.mqtt_pwd)); break;
|
||||
case SET_MQTT_FULLTOPIC: strlcpy(Settings.mqtt_fulltopic, replace, sizeof(Settings.mqtt_fulltopic)); break;
|
||||
case SET_MQTT_TOPIC: strlcpy(Settings.mqtt_topic, replace, sizeof(Settings.mqtt_topic)); break;
|
||||
case SET_MQTT_BUTTON_TOPIC: strlcpy(Settings.button_topic, replace, sizeof(Settings.button_topic)); break;
|
||||
case SET_MQTT_SWITCH_TOPIC: strlcpy(Settings.switch_topic, replace, sizeof(Settings.switch_topic)); break;
|
||||
case SET_MQTT_GRP_TOPIC: strlcpy(Settings.mqtt_grptopic, replace, sizeof(Settings.mqtt_grptopic)); break;
|
||||
case SET_STATE_TXT4: idx++;
|
||||
case SET_STATE_TXT3: idx++;
|
||||
case SET_STATE_TXT2: idx++;
|
||||
case SET_STATE_TXT1: strlcpy(Settings.state_text[idx], replace, sizeof(Settings.state_text[idx])); break;
|
||||
case SET_NTPSERVER3: idx++;
|
||||
case SET_NTPSERVER2: idx++;
|
||||
case SET_NTPSERVER1: strlcpy(Settings.ntp_server[idx], replace, sizeof(Settings.ntp_server[idx])); break;
|
||||
case SET_MEM5: idx++;
|
||||
case SET_MEM4: idx++;
|
||||
case SET_MEM3: idx++;
|
||||
case SET_MEM2: idx++;
|
||||
case SET_MEM1: strlcpy(Settings.mems[idx], replace, sizeof(Settings.mems[idx])); break;
|
||||
case SET_CORS: strlcpy(Settings.cors_domain, replace, sizeof(Settings.cors_domain)); break;
|
||||
case SET_FRIENDLYNAME4: idx++;
|
||||
case SET_FRIENDLYNAME3: idx++;
|
||||
case SET_FRIENDLYNAME2: idx++;
|
||||
case SET_FRIENDLYNAME1: strlcpy(Settings.friendlyname[idx], replace, sizeof(Settings.friendlyname[idx])); break;
|
||||
uint32_t start_pos = 0;
|
||||
uint32_t end_pos = 0;
|
||||
char* position = Settings.ota_url;
|
||||
for (uint32_t size = 0; size < SET_MAX; size++) {
|
||||
while (*position++ != '\0') { }
|
||||
if (1 == index) {
|
||||
start_pos = position - Settings.ota_url;
|
||||
}
|
||||
} else {
|
||||
uint32_t start_pos = 0;
|
||||
uint32_t end_pos = 0;
|
||||
char* position = Settings.ota_url;
|
||||
for (uint32_t size = 0; size < SET_MAX; size++) {
|
||||
while (*position++ != '\0') { }
|
||||
if (1 == index) {
|
||||
start_pos = position - Settings.ota_url;
|
||||
}
|
||||
else if (0 == index) {
|
||||
end_pos = position - Settings.ota_url -1;
|
||||
}
|
||||
index--;
|
||||
else if (0 == index) {
|
||||
end_pos = position - Settings.ota_url -1;
|
||||
}
|
||||
uint32_t char_len = position - Settings.ota_url;
|
||||
|
||||
uint32_t current_len = end_pos - start_pos;
|
||||
int diff = replace_len - current_len;
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TST: start %d, end %d, len %d, current %d, replace %d, diff %d"),
|
||||
// start_pos, end_pos, char_len, current_len, replace_len, diff);
|
||||
|
||||
int too_long = (char_len + diff) - settings_text_size;
|
||||
if (too_long > 0) {
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR("CFG: Text too long by %d char(s)"), too_long);
|
||||
return false; // Replace text too long
|
||||
}
|
||||
|
||||
if (diff != 0) {
|
||||
// Shift Settings.text up or down
|
||||
memmove_P(Settings.ota_url + start_pos + replace_len, Settings.ota_url + end_pos, char_len - end_pos);
|
||||
}
|
||||
// Replace text
|
||||
memmove_P(Settings.ota_url + start_pos, replace, replace_len);
|
||||
// Fill for future use
|
||||
memset(Settings.ota_url + char_len + diff, 0x00, settings_text_size - char_len - diff);
|
||||
index--;
|
||||
}
|
||||
uint32_t char_len = position - Settings.ota_url;
|
||||
|
||||
uint32_t current_len = end_pos - start_pos;
|
||||
int diff = replace_len - current_len;
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TST: start %d, end %d, len %d, current %d, replace %d, diff %d"),
|
||||
// start_pos, end_pos, char_len, current_len, replace_len, diff);
|
||||
|
||||
int too_long = (char_len + diff) - settings_text_size;
|
||||
if (too_long > 0) {
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_CONFIG "Text too long by %d char(s)"), too_long);
|
||||
return false; // Replace text too long
|
||||
}
|
||||
|
||||
if (diff != 0) {
|
||||
// Shift Settings.text up or down
|
||||
memmove_P(Settings.ota_url + start_pos + replace_len, Settings.ota_url + end_pos, char_len - end_pos);
|
||||
}
|
||||
// Replace text
|
||||
memmove_P(Settings.ota_url + start_pos, replace, replace_len);
|
||||
// Fill for future use
|
||||
memset(Settings.ota_url + char_len + diff, 0x00, settings_text_size - char_len - diff);
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG "CR %d/%d"), GetSettingsTextLen(), settings_text_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -574,62 +558,9 @@ char* SettingsText(uint32_t index)
|
||||
}
|
||||
|
||||
char* position = Settings.ota_url;
|
||||
|
||||
if (Settings.version < 0x07010207) {
|
||||
uint32_t idx = 0;
|
||||
switch (index) {
|
||||
case SET_MQTTPREFIX3: idx++;
|
||||
case SET_MQTTPREFIX2: idx++;
|
||||
case SET_MQTTPREFIX1: position = Settings.mqtt_prefix[idx]; break;
|
||||
case SET_STASSID2: idx++;
|
||||
case SET_STASSID1: position = Settings.sta_ssid[idx]; break;
|
||||
case SET_STAPWD2: idx++;
|
||||
case SET_STAPWD1: position = Settings.sta_pwd[idx]; break;
|
||||
case SET_HOSTNAME: position = Settings.hostname; break;
|
||||
case SET_SYSLOG_HOST: position = Settings.syslog_host; break;
|
||||
case SET_WEBPWD: position = Settings.web_password; break;
|
||||
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
||||
case SET_MQTT_HOST:
|
||||
strlcpy(aws_mqtt_host, Settings.mqtt_user, strlen(Settings.mqtt_user));
|
||||
strlcpy(&aws_mqtt_host[strlen(Settings.mqtt_user)], Settings.mqtt_host, sizeof(Settings.mqtt_host));
|
||||
position = aws_mqtt_host; break;
|
||||
case SET_MQTT_USER: position = aws_mqtt_user; break;
|
||||
#else
|
||||
case SET_MQTT_HOST: position = Settings.mqtt_host; break;
|
||||
case SET_MQTT_USER: position = Settings.mqtt_user; break;
|
||||
#endif
|
||||
case SET_MQTT_CLIENT: position = Settings.mqtt_client; break;
|
||||
case SET_MQTT_PWD: position = Settings.mqtt_pwd; break;
|
||||
case SET_MQTT_FULLTOPIC: position = Settings.mqtt_fulltopic; break;
|
||||
case SET_MQTT_TOPIC: position = Settings.mqtt_topic; break;
|
||||
case SET_MQTT_BUTTON_TOPIC: position = Settings.button_topic; break;
|
||||
case SET_MQTT_SWITCH_TOPIC: position = Settings.switch_topic; break;
|
||||
case SET_MQTT_GRP_TOPIC: position = Settings.mqtt_grptopic; break;
|
||||
case SET_STATE_TXT4: idx++;
|
||||
case SET_STATE_TXT3: idx++;
|
||||
case SET_STATE_TXT2: idx++;
|
||||
case SET_STATE_TXT1: position = Settings.state_text[idx]; break;
|
||||
case SET_NTPSERVER3: idx++;
|
||||
case SET_NTPSERVER2: idx++;
|
||||
case SET_NTPSERVER1: position = Settings.ntp_server[idx]; break;
|
||||
case SET_MEM5: idx++;
|
||||
case SET_MEM4: idx++;
|
||||
case SET_MEM3: idx++;
|
||||
case SET_MEM2: idx++;
|
||||
case SET_MEM1: position = Settings.mems[idx]; break;
|
||||
case SET_CORS: position = Settings.cors_domain; break;
|
||||
case SET_FRIENDLYNAME4: idx++;
|
||||
case SET_FRIENDLYNAME3: idx++;
|
||||
case SET_FRIENDLYNAME2: idx++;
|
||||
case SET_FRIENDLYNAME1: position = Settings.friendlyname[idx]; break;
|
||||
}
|
||||
|
||||
} else {
|
||||
for (;index > 0; index--) {
|
||||
while (*position++ != '\0') { }
|
||||
}
|
||||
for (;index > 0; index--) {
|
||||
while (*position++ != '\0') { }
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
@ -1309,8 +1240,8 @@ void SettingsDelta(void)
|
||||
memset((char*)&Settings +0x1D6, 0x00, 16);
|
||||
}
|
||||
if (Settings.version < 0x0606000F) {
|
||||
Settings.shutter_accuracy = 0;
|
||||
Settings.mqttlog_level = MQTT_LOG_LEVEL;
|
||||
Settings.ex_shutter_accuracy = 0;
|
||||
Settings.ex_mqttlog_level = MQTT_LOG_LEVEL;
|
||||
}
|
||||
if (Settings.version < 0x06060011) {
|
||||
Settings.param[P_BACKLOG_DELAY] = MIN_BACKLOG_DELAY;
|
||||
@ -1350,7 +1281,7 @@ void SettingsDelta(void)
|
||||
}
|
||||
if (Settings.version < 0x06060015) {
|
||||
if ((EX_WIFI_SMARTCONFIG == Settings.sta_config) || (EX_WIFI_WPSCONFIG == Settings.sta_config)) {
|
||||
Settings.sta_config = WIFI_MANAGER;
|
||||
Settings.ex_sta_config = WIFI_MANAGER;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1363,10 +1294,10 @@ void SettingsDelta(void)
|
||||
SettingsEnableAllI2cDrivers();
|
||||
}
|
||||
if (Settings.version < 0x07000004) {
|
||||
Settings.wifi_output_power = 170;
|
||||
Settings.ex_wifi_output_power = 170;
|
||||
}
|
||||
if (Settings.version < 0x07010202) {
|
||||
Settings.serial_config = TS_SERIAL_8N1;
|
||||
Settings.ex_serial_config = TS_SERIAL_8N1;
|
||||
}
|
||||
if (Settings.version < 0x07010204) {
|
||||
if (Settings.flag3.ex_cors_enabled == 1) {
|
||||
@ -1387,20 +1318,26 @@ void SettingsDelta(void)
|
||||
memcpy((char*)&Settings.serial_config, (char*)&Settings.ex_serial_config, 5); // 1E4 -> EFE
|
||||
}
|
||||
|
||||
if ((VERSION < 0x7010207) && (Settings.version > VERSION)) {
|
||||
char temp[strlen(SettingsText(SET_OTAURL)) +1]; strncpy(temp, SettingsText(SET_OTAURL), sizeof(temp));
|
||||
char temp21[strlen(SettingsText(SET_MQTTPREFIX1)) +1]; strncpy(temp21, SettingsText(SET_MQTTPREFIX1), sizeof(temp21));
|
||||
char temp22[strlen(SettingsText(SET_MQTTPREFIX2)) +1]; strncpy(temp22, SettingsText(SET_MQTTPREFIX2), sizeof(temp22));
|
||||
char temp23[strlen(SettingsText(SET_MQTTPREFIX3)) +1]; strncpy(temp23, SettingsText(SET_MQTTPREFIX3), sizeof(temp23));
|
||||
char temp31[strlen(SettingsText(SET_STASSID1)) +1]; strncpy(temp31, SettingsText(SET_STASSID1), sizeof(temp31));
|
||||
char temp32[strlen(SettingsText(SET_STASSID2)) +1]; strncpy(temp32, SettingsText(SET_STASSID2), sizeof(temp32));
|
||||
char temp41[strlen(SettingsText(SET_STAPWD1)) +1]; strncpy(temp41, SettingsText(SET_STAPWD1), sizeof(temp41));
|
||||
char temp42[strlen(SettingsText(SET_STAPWD2)) +1]; strncpy(temp42, SettingsText(SET_STAPWD2), sizeof(temp42));
|
||||
char temp5[strlen(SettingsText(SET_HOSTNAME)) +1]; strncpy(temp5, SettingsText(SET_HOSTNAME), sizeof(temp5));
|
||||
char temp6[strlen(SettingsText(SET_SYSLOG_HOST)) +1]; strncpy(temp6, SettingsText(SET_SYSLOG_HOST), sizeof(temp5));
|
||||
if (Settings.version < 0x08000000) {
|
||||
char temp[strlen(Settings.ota_url) +1]; strncpy(temp, Settings.ota_url, sizeof(temp));
|
||||
char temp21[strlen(Settings.mqtt_prefix[0]) +1]; strncpy(temp21, Settings.mqtt_prefix[0], sizeof(temp21));
|
||||
char temp22[strlen(Settings.mqtt_prefix[1]) +1]; strncpy(temp22, Settings.mqtt_prefix[1], sizeof(temp22));
|
||||
char temp23[strlen(Settings.mqtt_prefix[2]) +1]; strncpy(temp23, Settings.mqtt_prefix[2], sizeof(temp23));
|
||||
char temp31[strlen(Settings.sta_ssid[0]) +1]; strncpy(temp31, Settings.sta_ssid[0], sizeof(temp31));
|
||||
char temp32[strlen(Settings.sta_ssid[1]) +1]; strncpy(temp32, Settings.sta_ssid[1], sizeof(temp32));
|
||||
char temp41[strlen(Settings.sta_pwd[0]) +1]; strncpy(temp41, Settings.sta_pwd[0], sizeof(temp41));
|
||||
char temp42[strlen(Settings.sta_pwd[1]) +1]; strncpy(temp42, Settings.sta_pwd[1], sizeof(temp42));
|
||||
char temp5[strlen(Settings.hostname) +1]; strncpy(temp5, Settings.hostname, sizeof(temp5));
|
||||
char temp6[strlen(Settings.syslog_host) +1]; strncpy(temp6, Settings.syslog_host, sizeof(temp6));
|
||||
char temp7[strlen(Settings.mqtt_host) +1]; strncpy(temp7, Settings.mqtt_host, sizeof(temp7));
|
||||
char temp8[strlen(Settings.mqtt_client) +1]; strncpy(temp8, Settings.mqtt_client, sizeof(temp8));
|
||||
char temp9[strlen(Settings.mqtt_user) +1]; strncpy(temp9, Settings.mqtt_user, sizeof(temp9));
|
||||
char temp10[strlen(Settings.mqtt_pwd) +1]; strncpy(temp10, Settings.mqtt_pwd, sizeof(temp10));
|
||||
char temp11[strlen(Settings.mqtt_topic) +1]; strncpy(temp11, Settings.mqtt_topic, sizeof(temp11));
|
||||
char temp12[strlen(Settings.button_topic) +1]; strncpy(temp12, Settings.button_topic, sizeof(temp12));
|
||||
char temp13[strlen(Settings.mqtt_grptopic) +1]; strncpy(temp13, Settings.mqtt_grptopic, sizeof(temp13));
|
||||
|
||||
uint32_t version = Settings.version;
|
||||
Settings.version = VERSION;
|
||||
memset(Settings.ota_url, 0x00, settings_text_size);
|
||||
SettingsUpdateText(SET_OTAURL, temp);
|
||||
SettingsUpdateText(SET_MQTTPREFIX1, temp21);
|
||||
SettingsUpdateText(SET_MQTTPREFIX2, temp22);
|
||||
@ -1411,7 +1348,46 @@ void SettingsDelta(void)
|
||||
SettingsUpdateText(SET_STAPWD2, temp42);
|
||||
SettingsUpdateText(SET_HOSTNAME, temp5);
|
||||
SettingsUpdateText(SET_SYSLOG_HOST, temp6);
|
||||
Settings.version = version;
|
||||
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
||||
if (!strlen(Settings.mqtt_user)) {
|
||||
SettingsUpdateText(SET_MQTT_HOST, temp7);
|
||||
SettingsUpdateText(SET_MQTT_USER, temp9);
|
||||
} else {
|
||||
char aws_mqtt_host[66];
|
||||
snprintf_P(aws_mqtt_host, sizeof(aws_mqtt_host), PSTR("%s%s"), temp9, temp7);
|
||||
SettingsUpdateText(SET_MQTT_HOST, aws_mqtt_host);
|
||||
SettingsUpdateText(SET_MQTT_USER, "");
|
||||
}
|
||||
#else
|
||||
SettingsUpdateText(SET_MQTT_HOST, temp7);
|
||||
SettingsUpdateText(SET_MQTT_USER, temp9);
|
||||
#endif
|
||||
SettingsUpdateText(SET_MQTT_CLIENT, temp8);
|
||||
SettingsUpdateText(SET_MQTT_PWD, temp10);
|
||||
SettingsUpdateText(SET_MQTT_TOPIC, temp11);
|
||||
SettingsUpdateText(SET_MQTT_BUTTON_TOPIC, temp12);
|
||||
SettingsUpdateText(SET_MQTT_GRP_TOPIC, temp13);
|
||||
|
||||
SettingsUpdateText(SET_WEBPWD, Settings.web_password);
|
||||
SettingsUpdateText(SET_CORS, Settings.cors_domain);
|
||||
SettingsUpdateText(SET_MQTT_FULLTOPIC, Settings.mqtt_fulltopic);
|
||||
SettingsUpdateText(SET_MQTT_SWITCH_TOPIC, Settings.switch_topic);
|
||||
SettingsUpdateText(SET_STATE_TXT1, Settings.state_text[0]);
|
||||
SettingsUpdateText(SET_STATE_TXT2, Settings.state_text[1]);
|
||||
SettingsUpdateText(SET_STATE_TXT3, Settings.state_text[2]);
|
||||
SettingsUpdateText(SET_STATE_TXT4, Settings.state_text[3]);
|
||||
SettingsUpdateText(SET_NTPSERVER1, Settings.ntp_server[0]);
|
||||
SettingsUpdateText(SET_NTPSERVER2, Settings.ntp_server[1]);
|
||||
SettingsUpdateText(SET_NTPSERVER3, Settings.ntp_server[2]);
|
||||
SettingsUpdateText(SET_MEM1, Settings.mems[0]);
|
||||
SettingsUpdateText(SET_MEM2, Settings.mems[1]);
|
||||
SettingsUpdateText(SET_MEM3, Settings.mems[2]);
|
||||
SettingsUpdateText(SET_MEM4, Settings.mems[3]);
|
||||
SettingsUpdateText(SET_MEM5, Settings.mems[4]);
|
||||
SettingsUpdateText(SET_FRIENDLYNAME1, Settings.friendlyname[0]);
|
||||
SettingsUpdateText(SET_FRIENDLYNAME2, Settings.friendlyname[1]);
|
||||
SettingsUpdateText(SET_FRIENDLYNAME3, Settings.friendlyname[2]);
|
||||
SettingsUpdateText(SET_FRIENDLYNAME4, Settings.friendlyname[3]);
|
||||
}
|
||||
|
||||
Settings.version = VERSION;
|
||||
|
@ -995,6 +995,13 @@ int ResponseJsonEndEnd(void)
|
||||
* GPIO Module and Template management
|
||||
\*********************************************************************************************/
|
||||
|
||||
void DigitalWrite(uint32_t gpio_pin, uint32_t state)
|
||||
{
|
||||
if (pin[gpio_pin] < 99) {
|
||||
digitalWrite(pin[gpio_pin], state &1);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ModuleNr(void)
|
||||
{
|
||||
// 0 = User module (255)
|
||||
|
@ -489,7 +489,9 @@ void GetFeatures(void)
|
||||
#ifdef USE_TSL2591
|
||||
feature5 |= 0x00080000;
|
||||
#endif
|
||||
// feature5 |= 0x00100000;
|
||||
#ifdef USE_DHT12
|
||||
feature5 |= 0x00100000;
|
||||
#endif
|
||||
// feature5 |= 0x00200000;
|
||||
// feature5 |= 0x00400000;
|
||||
// feature5 |= 0x00800000;
|
||||
|
@ -108,7 +108,7 @@ char* GetTopic_P(char *stopic, uint32_t prefix, char *topic, const char* subtopi
|
||||
fulltopic += FPSTR(MQTT_TOKEN_PREFIX); // Need prefix for commands to handle mqtt topic loops
|
||||
}
|
||||
for (uint32_t i = 0; i < 3; i++) {
|
||||
if ('\0' == SettingsText(SET_MQTTPREFIX1 + i)) {
|
||||
if (!strlen(SettingsText(SET_MQTTPREFIX1 + i))) {
|
||||
char temp[TOPSZ];
|
||||
SettingsUpdateText(SET_MQTTPREFIX1 + i, GetTextIndexed(temp, sizeof(temp), i, kPrefixes));
|
||||
}
|
||||
@ -166,9 +166,7 @@ void SetLatchingRelay(power_t lpower, uint32_t state)
|
||||
|
||||
for (uint32_t i = 0; i < devices_present; i++) {
|
||||
uint32_t port = (i << 1) + ((latching_power >> i) &1);
|
||||
if (pin[GPIO_REL1 +port] < 99) {
|
||||
digitalWrite(pin[GPIO_REL1 +port], bitRead(rel_inverted, port) ? !state : state);
|
||||
}
|
||||
DigitalWrite(GPIO_REL1 +port, bitRead(rel_inverted, port) ? !state : state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,8 +224,8 @@ void SetDevicePower(power_t rpower, uint32_t source)
|
||||
else {
|
||||
for (uint32_t i = 0; i < devices_present; i++) {
|
||||
power_t state = rpower &1;
|
||||
if ((i < MAX_RELAYS) && (pin[GPIO_REL1 +i] < 99)) {
|
||||
digitalWrite(pin[GPIO_REL1 +i], bitRead(rel_inverted, i) ? !state : state);
|
||||
if (i < MAX_RELAYS) {
|
||||
DigitalWrite(GPIO_REL1 +i, bitRead(rel_inverted, i) ? !state : state);
|
||||
}
|
||||
rpower >>= 1;
|
||||
}
|
||||
@ -293,7 +291,7 @@ void SetLedPowerIdx(uint32_t led, uint32_t state)
|
||||
} else {
|
||||
led_power &= (0xFF ^ mask);
|
||||
}
|
||||
digitalWrite(pin[GPIO_LED1 + led], bitRead(led_inverted, led) ? !state : state);
|
||||
DigitalWrite(GPIO_LED1 + led, bitRead(led_inverted, led) ? !state : state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -868,13 +866,21 @@ void Every250mSeconds(void)
|
||||
}
|
||||
if (90 == ota_state_flag) { // Allow MQTT to reconnect
|
||||
ota_state_flag = 0;
|
||||
Response_P(PSTR("{\"" D_CMND_UPGRADE "\":\""));
|
||||
if (ota_result) {
|
||||
// SetFlashModeDout(); // Force DOUT for both ESP8266 and ESP8285
|
||||
Response_P(PSTR(D_JSON_SUCCESSFUL ". " D_JSON_RESTARTING));
|
||||
if (OtaVersion() < VERSION_COMPATIBLE) {
|
||||
AbandonOta();
|
||||
ResponseAppend_P(PSTR(D_JSON_FAILED " " D_UPLOAD_ERR_14));
|
||||
} else {
|
||||
ResponseAppend_P(PSTR(D_JSON_SUCCESSFUL ". " D_JSON_RESTARTING));
|
||||
restart_flag = 2;
|
||||
}
|
||||
} else {
|
||||
Response_P(PSTR(D_JSON_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str());
|
||||
ResponseAppend_P(PSTR(D_JSON_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str());
|
||||
}
|
||||
restart_flag = 2; // Restart anyway to keep memory clean webserver
|
||||
ResponseAppend_P(PSTR("\"}"));
|
||||
// restart_flag = 2; // Restart anyway to keep memory clean webserver
|
||||
MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_UPGRADE));
|
||||
}
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ void WifiBegin(uint8_t flag, uint8_t channel)
|
||||
case 2: // Toggle
|
||||
Settings.sta_active ^= 1;
|
||||
} // 3: Current AP
|
||||
if ('\0' == SettingsText(SET_STASSID1 + Settings.sta_active)) {
|
||||
if (!strlen(SettingsText(SET_STASSID1 + Settings.sta_active))) {
|
||||
Settings.sta_active ^= 1; // Skip empty SSID
|
||||
}
|
||||
if (Settings.ip_address[0]) {
|
||||
@ -436,7 +436,7 @@ void WifiCheckIp(void)
|
||||
if (!Wifi.retry || ((Wifi.retry_init / 2) == Wifi.retry)) {
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_AP_TIMEOUT));
|
||||
} else {
|
||||
if (('\0' == SettingsText(SET_STASSID1)) && ('\0' == SettingsText(SET_STASSID2))) {
|
||||
if (!strlen(SettingsText(SET_STASSID1)) && !strlen(SettingsText(SET_STASSID2))) {
|
||||
wifi_config_tool = WIFI_MANAGER; // Skip empty SSIDs and start Wifi config tool
|
||||
Wifi.retry = 0;
|
||||
} else {
|
||||
|
@ -277,15 +277,15 @@ enum SettingsTextIndex { SET_OTAURL,
|
||||
SET_STASSID1, SET_STASSID2,
|
||||
SET_STAPWD1, SET_STAPWD2,
|
||||
SET_HOSTNAME, SET_SYSLOG_HOST,
|
||||
SET_WEBPWD,
|
||||
SET_WEBPWD, SET_CORS,
|
||||
SET_MQTT_HOST, SET_MQTT_CLIENT,
|
||||
SET_MQTT_USER, SET_MQTT_PWD,
|
||||
SET_MQTT_FULLTOPIC, SET_MQTT_TOPIC,
|
||||
SET_MQTT_BUTTON_TOPIC, SET_MQTT_SWITCH_TOPIC, SET_MQTT_GRP_TOPIC,
|
||||
SET_STATE_TXT1, SET_STATE_TXT2, SET_STATE_TXT3, SET_STATE_TXT4,
|
||||
SET_NTPSERVER1, SET_NTPSERVER2, SET_NTPSERVER3,
|
||||
SET_MEM1, SET_MEM2, SET_MEM3, SET_MEM4, SET_MEM5,
|
||||
SET_CORS,
|
||||
SET_MEM1, SET_MEM2, SET_MEM3, SET_MEM4, SET_MEM5, SET_MEM6, SET_MEM7, SET_MEM8,
|
||||
SET_MEM9, SET_MEM10, SET_MEM11, SET_MEM12, SET_MEM13, SET_MEM14, SET_MEM15, SET_MEM16,
|
||||
SET_FRIENDLYNAME1, SET_FRIENDLYNAME2, SET_FRIENDLYNAME3, SET_FRIENDLYNAME4,
|
||||
|
||||
// SET_FRIENDLYNAME5, SET_FRIENDLYNAME6, SET_FRIENDLYNAME7, SET_FRIENDLYNAME8, // Future extension
|
||||
|
@ -334,6 +334,8 @@ void setup(void)
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_WARNING_MINIMAL_VERSION));
|
||||
#endif // FIRMWARE_MINIMAL
|
||||
|
||||
memcpy_P(log_data, VERSION_MARKER, 1); // Dummy for compiler saving VERSION_MARKER
|
||||
|
||||
RtcInit();
|
||||
|
||||
#ifdef USE_ARDUINO_OTA
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define _TASMOTA_POST_H_
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Function declarations
|
||||
* Function prototypes
|
||||
\*********************************************************************************************/
|
||||
|
||||
// Needed for core 2.3.0 compilation (#6721)
|
||||
@ -39,6 +39,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||
//#endif // USE_KNX
|
||||
|
||||
char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0');
|
||||
extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end);
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Default global defines
|
||||
@ -135,6 +136,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
|
||||
#define USE_SGP30 // Add I2C code for SGP30 sensor (+1k1 code)
|
||||
//#define USE_SI1145 // Add I2C code for SI1145/46/47 sensor (+1k code)
|
||||
#define USE_LM75AD // Add I2C code for LM75AD sensor (+0k5 code)
|
||||
#define USE_DHT12 // Add I2C code for DHT12 temperature and humidity sensor (+0k7 code)
|
||||
//#define USE_APDS9960 // Add I2C code for APDS9960 Proximity Sensor. Disables SHT and VEML6070 (+4k7 code)
|
||||
//#define USE_MCP230xx // Enable MCP23008/MCP23017 - Must define I2C Address in #define USE_MCP230xx_ADDR below - range 0x20 - 0x27 (+4k7 code)
|
||||
// #define USE_MCP230xx_ADDR 0x20 // Enable MCP23008/MCP23017 I2C Address to use (Must be within range 0x20 through 0x27 - set according to your wired setup)
|
||||
@ -390,17 +392,17 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
|
||||
#endif // FIRMWARE_IR
|
||||
|
||||
/*********************************************************************************************\
|
||||
* [tasmota-basic.bin]
|
||||
* [tasmota-lite.bin]
|
||||
* Provide an image without sensors
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef FIRMWARE_BASIC
|
||||
#ifdef FIRMWARE_LITE
|
||||
|
||||
#undef CODE_IMAGE
|
||||
#define CODE_IMAGE 4
|
||||
|
||||
#undef APP_SLEEP
|
||||
#define APP_SLEEP 1 // Default to sleep = 1 for FIRMWARE_BASIC
|
||||
#define APP_SLEEP 1 // Default to sleep = 1 for FIRMWARE_LITE
|
||||
|
||||
#undef USE_ARDUINO_OTA // Disable support for Arduino OTA
|
||||
#undef USE_DOMOTICZ // Disable Domoticz
|
||||
@ -502,7 +504,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
|
||||
#undef CODE_IMAGE
|
||||
#define CODE_IMAGE 1
|
||||
|
||||
#undef FIRMWARE_BASIC // Disable tasmota-basic with no sensors
|
||||
#undef FIRMWARE_LITE // Disable tasmota-lite with no sensors
|
||||
#undef FIRMWARE_SENSORS // Disable tasmota-sensors with useful sensors enabled
|
||||
#undef FIRMWARE_KNX_NO_EMULATION // Disable tasmota-knx with KNX but without Emulation
|
||||
#undef FIRMWARE_DISPLAYS // Disable tasmota-display with display drivers enabled
|
||||
|
@ -20,6 +20,9 @@
|
||||
#ifndef _TASMOTA_VERSION_H_
|
||||
#define _TASMOTA_VERSION_H_
|
||||
|
||||
const uint32_t VERSION = 0x07010206;
|
||||
const uint32_t VERSION = 0x08000001;
|
||||
|
||||
// Lowest compatible version
|
||||
const uint32_t VERSION_COMPATIBLE = 0x07010006;
|
||||
|
||||
#endif // _TASMOTA_VERSION_H_
|
||||
|
@ -512,6 +512,7 @@ const char kUploadErrors[] PROGMEM =
|
||||
#ifdef USE_RF_FLASH
|
||||
"|" D_UPLOAD_ERR_10 "|" D_UPLOAD_ERR_11 "|" D_UPLOAD_ERR_12 "|" D_UPLOAD_ERR_13
|
||||
#endif
|
||||
"|" D_UPLOAD_ERR_14
|
||||
;
|
||||
|
||||
const uint16_t DNS_PORT = 53;
|
||||
@ -2137,12 +2138,12 @@ void HandleUploadDone(void)
|
||||
WSContentSendStyle();
|
||||
WSContentSend_P(PSTR("<div style='text-align:center;'><b>" D_UPLOAD " <font color='#"));
|
||||
if (Web.upload_error) {
|
||||
// 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
|
||||
if (Web.upload_error < 14) {
|
||||
if (Web.upload_error < 15) {
|
||||
#else
|
||||
if (Web.upload_error < 10) {
|
||||
if ((Web.upload_error < 10) || (14 == Web.upload_error)) {
|
||||
if (14 == Web.upload_error) { Web.upload_error = 10; }
|
||||
#endif
|
||||
GetTextIndexed(error, sizeof(error), Web.upload_error -1, kUploadErrors);
|
||||
} else {
|
||||
@ -2237,7 +2238,7 @@ void HandleUploadLoop(void)
|
||||
Update.end(); // End esp8266 update session
|
||||
Web.upload_file_type = UPL_EFM8BB1;
|
||||
|
||||
Web.upload_error = SnfBrUpdateInit();
|
||||
Web.upload_error = SnfBrUpdateInit(); // 10, 11
|
||||
if (Web.upload_error != 0) { return; }
|
||||
} else
|
||||
#endif // USE_RF_FLASH
|
||||
@ -2245,7 +2246,7 @@ void HandleUploadLoop(void)
|
||||
if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO SLAVE hex file
|
||||
Update.end(); // End esp8266 update session
|
||||
Web.upload_file_type = UPL_TASMOTASLAVE;
|
||||
Web.upload_error = TasmotaSlave_UpdateInit();
|
||||
Web.upload_error = TasmotaSlave_UpdateInit(); // 0
|
||||
if (Web.upload_error != 0) { return; }
|
||||
} else
|
||||
#endif
|
||||
@ -2280,13 +2281,13 @@ void HandleUploadLoop(void)
|
||||
free(efm8bb1_update);
|
||||
efm8bb1_update = nullptr;
|
||||
if (result != 0) {
|
||||
Web.upload_error = abs(result); // 2 = Not enough space, 8 = File invalid
|
||||
Web.upload_error = abs(result); // 2 = Not enough space, 8 = File invalid, 12, 13
|
||||
return;
|
||||
}
|
||||
}
|
||||
ssize_t result = rf_search_and_write(upload.buf, upload.currentSize);
|
||||
if (result < 0) {
|
||||
Web.upload_error = abs(result);
|
||||
Web.upload_error = abs(result); // 8, 12, 13
|
||||
return;
|
||||
} else if (result > 0) {
|
||||
if ((size_t)result > upload.currentSize) {
|
||||
@ -2376,6 +2377,11 @@ void HandleUploadLoop(void)
|
||||
Web.upload_error = 6; // Upload failed. Enable logging 3
|
||||
return;
|
||||
}
|
||||
if (OtaVersion() < VERSION_COMPATIBLE) {
|
||||
AbandonOta();
|
||||
Web.upload_error = 14; // Not compatible
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!Web.upload_error) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_UPLOAD D_SUCCESSFUL " %u bytes. " D_RESTARTING), upload.totalSize);
|
||||
|
@ -262,8 +262,8 @@ struct LIGHT {
|
||||
uint16_t fade_start_10[LST_MAX] = {0,0,0,0,0};
|
||||
uint16_t fade_cur_10[LST_MAX];
|
||||
uint16_t fade_end_10[LST_MAX]; // 10 bits resolution target channel values
|
||||
uint16_t fade_counter = 0; // fade timer in ticks (50ms)
|
||||
uint16_t fade_duration = 0; // duration of fade in ticks (50ms)
|
||||
uint16_t fade_duration = 0; // duration of fade in milliseconds
|
||||
uint32_t fade_start = 0; // fade start time in milliseconds, compared to millis()
|
||||
} Light;
|
||||
|
||||
power_t LightPower(void)
|
||||
@ -1574,20 +1574,25 @@ void LightAnimate(void)
|
||||
bool power_off = false;
|
||||
|
||||
Light.strip_timer_counter++;
|
||||
if (!Light.power) { // All channels powered off
|
||||
Light.strip_timer_counter = 0;
|
||||
if (!Light.fade_running) {
|
||||
sleep = Settings.sleep;
|
||||
}
|
||||
if (Settings.light_scheme >= LS_MAX) {
|
||||
power_off = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
// set sleep parameter: either settings,
|
||||
// or set a maximum of PWM_MAX_SLEEP if light is on or Fade is running
|
||||
if (Light.power || Light.fade_running) {
|
||||
if (Settings.sleep > PWM_MAX_SLEEP) {
|
||||
sleep = PWM_MAX_SLEEP; // set a maxumum value of 50 milliseconds to ensure that animations are smooth
|
||||
} else {
|
||||
sleep = Settings.sleep; // or keep the current sleep if it's lower than 50
|
||||
}
|
||||
} else {
|
||||
sleep = Settings.sleep;
|
||||
}
|
||||
|
||||
if (!Light.power) { // All channels powered off
|
||||
Light.strip_timer_counter = 0;
|
||||
if (Settings.light_scheme >= LS_MAX) {
|
||||
power_off = true;
|
||||
}
|
||||
} else {
|
||||
switch (Settings.light_scheme) {
|
||||
case LS_POWER:
|
||||
light_controller.calcLevels(Light.new_color);
|
||||
@ -1733,27 +1738,35 @@ void LightAnimate(void)
|
||||
memcpy(Light.fade_end_8, cur_col, sizeof(Light.fade_start_8));
|
||||
memcpy(Light.fade_end_10, cur_col_10bits, sizeof(Light.fade_start_10));
|
||||
Light.fade_running = true;
|
||||
Light.fade_counter = 0;
|
||||
Light.fade_duration = 0; // set the value to zero to force a recompute
|
||||
Light.fade_start = 0;
|
||||
// Fade will applied immediately below
|
||||
}
|
||||
}
|
||||
if (Light.fade_running) {
|
||||
LightApplyFade();
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR("LightApplyFade %d %d %d %d %d - %d %d %d %d %d"),
|
||||
// Light.fade_cur_8[0], Light.fade_cur_8[1], Light.fade_cur_8[2], Light.fade_cur_8[3], Light.fade_cur_8[4],
|
||||
// Light.fade_cur_10[0], Light.fade_cur_10[1], Light.fade_cur_10[2], Light.fade_cur_10[3], Light.fade_cur_10[4]);
|
||||
if (LightApplyFade()) {
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR("LightApplyFade %d %d %d %d %d - %d %d %d %d %d"),
|
||||
// Light.fade_cur_8[0], Light.fade_cur_8[1], Light.fade_cur_8[2], Light.fade_cur_8[3], Light.fade_cur_8[4],
|
||||
// Light.fade_cur_10[0], Light.fade_cur_10[1], Light.fade_cur_10[2], Light.fade_cur_10[3], Light.fade_cur_10[4]);
|
||||
|
||||
LightSetOutputs(Light.fade_cur_8, Light.fade_cur_10);
|
||||
LightSetOutputs(Light.fade_cur_8, Light.fade_cur_10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LightApplyFade(void) {
|
||||
bool LightApplyFade(void) { // did the value chanegd and needs to be applied
|
||||
static uint32_t last_millis = 0;
|
||||
uint32_t now = millis();
|
||||
|
||||
if ((now - last_millis) <= 5) {
|
||||
return false; // the value was not changed in the last 5 milliseconds, ignore
|
||||
}
|
||||
last_millis = now;
|
||||
|
||||
// Check if we need to calculate the duration
|
||||
if (0 == Light.fade_duration) {
|
||||
Light.fade_counter = 0;
|
||||
Light.fade_start = now;
|
||||
// compute the distance between start and and color (max of distance for each channel)
|
||||
uint32_t distance = 0;
|
||||
for (uint32_t i = 0; i < Light.subtype; i++) {
|
||||
@ -1764,26 +1777,30 @@ void LightApplyFade(void) {
|
||||
if (distance > 0) {
|
||||
// compute the duration of the animation
|
||||
// Note: Settings.light_speed is the number of half-seconds for a 100% fade,
|
||||
// i.e. light_speed=1 means 1024 steps in 10 ticks (500ms)
|
||||
Light.fade_duration = (distance * Settings.light_speed * 10) / 1024;
|
||||
// Also postpone the save_data for the duration of the Fade (in seconds)
|
||||
uint32_t delay_seconds = 1 + (Light.fade_duration + 19) / 20; // add one more second
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR("delay_seconds %d, save_data_counter %d"), delay_seconds, save_data_counter);
|
||||
if (save_data_counter < delay_seconds) {
|
||||
save_data_counter = delay_seconds; // pospone
|
||||
// i.e. light_speed=1 means 1024 steps in 500ms
|
||||
Light.fade_duration = (distance * Settings.light_speed * 500) / 1023;
|
||||
if (Settings.save_data) {
|
||||
// Also postpone the save_data for the duration of the Fade (in seconds)
|
||||
uint32_t delay_seconds = 1 + (Light.fade_duration + 999) / 1000; // add one more second
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR("delay_seconds %d, save_data_counter %d"), delay_seconds, save_data_counter);
|
||||
if (save_data_counter < delay_seconds) {
|
||||
save_data_counter = delay_seconds; // pospone
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no fade needed, we keep the duration at zero, it will fallback directly to end of fade
|
||||
Light.fade_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
Light.fade_counter++;
|
||||
if (Light.fade_counter <= Light.fade_duration) { // fade not finished
|
||||
uint16_t fade_current = now - Light.fade_start; // number of milliseconds since start of fade
|
||||
if (fade_current <= Light.fade_duration) { // fade not finished
|
||||
//Serial.printf("Fade: %d / %d - ", fade_current, Light.fade_duration);
|
||||
for (uint32_t i = 0; i < Light.subtype; i++) {
|
||||
Light.fade_cur_8[i] = changeUIntScale(Light.fade_counter,
|
||||
Light.fade_cur_8[i] = changeUIntScale(fade_current,
|
||||
0, Light.fade_duration,
|
||||
Light.fade_start_8[i], Light.fade_end_8[i]);
|
||||
Light.fade_cur_10[i] = changeUIntScale(Light.fade_counter,
|
||||
Light.fade_cur_10[i] = changeUIntScale(fade_current,
|
||||
0, Light.fade_duration,
|
||||
Light.fade_start_10[i], Light.fade_end_10[i]);
|
||||
}
|
||||
@ -1791,7 +1808,7 @@ void LightApplyFade(void) {
|
||||
// stop fade
|
||||
//AddLop_P2(LOG_LEVEL_DEBUG, PSTR("Stop fade"));
|
||||
Light.fade_running = false;
|
||||
Light.fade_counter = 0;
|
||||
Light.fade_start = 0;
|
||||
Light.fade_duration = 0;
|
||||
// set light to target value
|
||||
memcpy(Light.fade_cur_8, Light.fade_end_8, sizeof(Light.fade_end_8));
|
||||
@ -1800,7 +1817,7 @@ void LightApplyFade(void) {
|
||||
memcpy(Light.fade_start_8, Light.fade_end_8, sizeof(Light.fade_start_8));
|
||||
memcpy(Light.fade_start_10, Light.fade_end_10, sizeof(Light.fade_start_10));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// On entry we take the 5 channels 8 bits entry, and we apply Power modifiers
|
||||
@ -2426,6 +2443,13 @@ bool Xdrv04(uint8_t function)
|
||||
case FUNC_SERIAL:
|
||||
result = XlgtCall(FUNC_SERIAL);
|
||||
break;
|
||||
case FUNC_LOOP:
|
||||
if (Light.fade_running) {
|
||||
if (LightApplyFade()) {
|
||||
LightSetOutputs(Light.fade_cur_8, Light.fade_cur_10);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
LightAnimate();
|
||||
break;
|
||||
|
@ -499,6 +499,7 @@ void KNX_INIT(void)
|
||||
if (GetUsedInModule(GPIO_DHT22, my_module.io)) { device_param[KNX_HUMIDITY-1].show = true; }
|
||||
if (GetUsedInModule(GPIO_SI7021, my_module.io)) { device_param[KNX_HUMIDITY-1].show = true; }
|
||||
|
||||
#if defined(USE_ENERGY_SENSOR)
|
||||
// Any device with a Power Monitoring
|
||||
if ( energy_flg != ENERGY_NONE ) {
|
||||
device_param[KNX_ENERGY_POWER-1].show = true;
|
||||
@ -509,6 +510,7 @@ void KNX_INIT(void)
|
||||
device_param[KNX_ENERGY_CURRENT-1].show = true;
|
||||
device_param[KNX_ENERGY_POWERFACTOR-1].show = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_RULES
|
||||
device_param[KNX_SLOT1-1].show = true;
|
||||
|
@ -340,10 +340,10 @@ void HAssAnnounceButtonSwitch(uint8_t device, char* topic, uint8_t present, uint
|
||||
if (strlen(prefix) > 0 ) TryResponseAppend_P(HASS_DISCOVER_TOPIC_PREFIX, prefix);
|
||||
if (toggle) {
|
||||
if (!key) {
|
||||
TryResponseAppend_P(HASS_DISCOVER_BUTTON_TOGGLE, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT1 + toggle?2:1));
|
||||
TryResponseAppend_P(HASS_DISCOVER_BUTTON_TOGGLE, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT3));
|
||||
} else {TryResponseAppend_P(HASS_DISCOVER_SWITCH_TOGGLE);}
|
||||
}
|
||||
else TryResponseAppend_P(HASS_DISCOVER_BUTTON_SWITCH_ONOFF, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT1 + toggle?2:1), SettingsText(SET_STATE_TXT1));
|
||||
else TryResponseAppend_P(HASS_DISCOVER_BUTTON_SWITCH_ONOFF, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT2), SettingsText(SET_STATE_TXT1));
|
||||
|
||||
TryResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
|
@ -511,6 +511,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
||||
|
||||
// On/off cluster
|
||||
{ 0x0006, 0x0000, "Power", &Z_Copy },
|
||||
{ 0x0006, 0x8000, "Power", &Z_Copy }, // See 7280
|
||||
|
||||
// On/Off Switch Configuration cluster
|
||||
{ 0x0007, 0x0000, "SwitchType", &Z_Copy },
|
||||
|
@ -39,7 +39,7 @@ struct BUZZER {
|
||||
|
||||
void BuzzerOff(void)
|
||||
{
|
||||
digitalWrite(pin[GPIO_BUZZER], Buzzer.inverted); // Buzzer Off
|
||||
DigitalWrite(GPIO_BUZZER, Buzzer.inverted); // Buzzer Off
|
||||
}
|
||||
|
||||
//void BuzzerBeep(uint32_t count = 1, uint32_t on = 1, uint32_t off = 1, uint32_t tune = 0);
|
||||
@ -124,7 +124,7 @@ void BuzzerEvery100mSec(void)
|
||||
Buzzer.duration = Buzzer.set[Buzzer.state];
|
||||
}
|
||||
}
|
||||
digitalWrite(pin[GPIO_BUZZER], (Buzzer.inverted) ? !Buzzer.state : Buzzer.state);
|
||||
DigitalWrite(GPIO_BUZZER, (Buzzer.inverted) ? !Buzzer.state : Buzzer.state);
|
||||
} else {
|
||||
Buzzer.enable = false;
|
||||
}
|
||||
|
@ -27,11 +27,13 @@
|
||||
#define D_SHUTTER "SHUTTER"
|
||||
|
||||
const uint16_t MOTOR_STOP_TIME = 500; // in mS
|
||||
const uint8_t steps_per_second = 20; // FUNC_EVERY_50_MSECOND
|
||||
|
||||
uint8_t calibrate_pos[6] = {0,30,50,70,90,100};
|
||||
uint16_t messwerte[5] = {30,50,70,90,100};
|
||||
uint16_t last_execute_step;
|
||||
|
||||
enum ShutterModes { SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_OPEN__PULSE_CLOSE };
|
||||
enum ShutterModes { SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_OPEN__PULSE_CLOSE, SHT_OFF_ON__OPEN_CLOSE_STEPPER,};
|
||||
|
||||
const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|"
|
||||
D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|"
|
||||
@ -68,43 +70,51 @@ struct SHUTTER {
|
||||
uint8_t mode = 0; // operation mode definition. see enum type above SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_OPEN__PULSE_CLOSE
|
||||
int16_t motordelay[MAX_SHUTTERS]; // initial motorstarttime in 0.05sec.
|
||||
int16_t pwm_frequency; // frequency of PWN for stepper motors
|
||||
uint16_t max_pwm_frequency = 1000; // maximum of PWM frequency that can be used. depend on the motor and drivers
|
||||
uint16_t max_pwm_frequency = 1000; // maximum of PWM frequency for openig the shutter. depend on the motor and drivers
|
||||
uint16_t max_close_pwm_frequency[MAX_SHUTTERS];// maximum of PWM frequency for closeing the shutter. depend on the motor and drivers
|
||||
uint8_t skip_relay_change; // avoid overrun at endstops
|
||||
int32_t accelerator[MAX_SHUTTERS]; // speed of ramp-up, ramp down of shutter
|
||||
} Shutter;
|
||||
|
||||
void ShutterRtc50mS(void)
|
||||
{
|
||||
for (uint32_t i = 0; i < shutters_present; i++) {
|
||||
Shutter.time[i]++;
|
||||
if (Shutter.accelerator[i]) {
|
||||
Shutter.pwm_frequency += Shutter.accelerator[i];
|
||||
Shutter.pwm_frequency = tmax(0,tmin(Shutter.direction[i]==1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i],Shutter.pwm_frequency));
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+i], 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ShutterPercentToRealPosition(uint8_t percent,uint8_t index)
|
||||
int32_t ShutterPercentToRealPosition(uint8_t percent,uint8_t i)
|
||||
{
|
||||
if (Settings.shutter_set50percent[index] != 50) {
|
||||
return percent <= 5 ? Settings.shuttercoeff[2][index] * percent : Settings.shuttercoeff[1][index] * percent + Settings.shuttercoeff[0][index];
|
||||
if (Settings.shutter_set50percent[i] != 50) {
|
||||
return percent <= 5 ? Settings.shuttercoeff[2][i] * percent : Settings.shuttercoeff[1][i] * percent + Settings.shuttercoeff[0][i];
|
||||
} else {
|
||||
int32_t realpos;
|
||||
// check against DIV 0
|
||||
for (uint8_t j=0 ; j < 5 ; j++) {
|
||||
if (Settings.shuttercoeff[j][index] == 0) {
|
||||
if (Settings.shuttercoeff[j][i] == 0) {
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("SHT: RESET/INIT CALIBRATION MATRIX DIV 0"));
|
||||
for (uint8_t k=0 ; k < 5 ; k++) {
|
||||
Settings.shuttercoeff[k][index] = messwerte[k] * 1000 / messwerte[4];
|
||||
Settings.shuttercoeff[k][i] = messwerte[k] * 1000 / messwerte[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (uint8_t i=0 ; i < 5 ; i++) {
|
||||
if (percent*10 > Settings.shuttercoeff[i][index]) {
|
||||
realpos = Shutter.open_max[index] * calibrate_pos[i+1] / 100;
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Realposition TEMP1: %d, %% %d, coeff %d"), realpos, percent, Settings.shuttercoeff[i][index]);
|
||||
for (uint8_t l=0 ; l < 5 ; l++) {
|
||||
if (percent*10 > Settings.shuttercoeff[l][i]) {
|
||||
realpos = Shutter.open_max[i] * calibrate_pos[l+1] / 100;
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Realposition TEMP1: %d, %% %d, coeff %d"), realpos, percent, Settings.shuttercoeff[l][i]);
|
||||
} else {
|
||||
if ( i == 0) {
|
||||
realpos = percent * Shutter.open_max[index] * calibrate_pos[i+1] / Settings.shuttercoeff[i][index] / 10;
|
||||
if ( l == 0) {
|
||||
realpos = percent * Shutter.open_max[i] * calibrate_pos[l+1] / Settings.shuttercoeff[l][i] / 10;
|
||||
} else {
|
||||
//uint16_t addon = ( percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter_Open_Max[index] * (calibrate_pos[i+1] - calibrate_pos[i]) / (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]) / 100;
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Realposition TEMP2: %d, %% %d, coeff %d"), addon, (calibrate_pos[i+1] - calibrate_pos[i]), (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]));
|
||||
realpos += ( percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter.open_max[index] * (calibrate_pos[i+1] - calibrate_pos[i]) / (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]) / 100;
|
||||
//uint16_t addon = ( percent*10 - Settings.shuttercoeff[i-1][i] ) * Shutter_Open_Max[i] * (calibrate_pos[l+1] - calibrate_pos[l]) / (Settings.shuttercoeff[l][i] -Settings.shuttercoeff[l-1][l]) / 100;
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Realposition TEMP2: %d, %% %d, coeff %d"), addon, (calibrate_pos[l+1] - calibrate_pos[l]), (Settings.shuttercoeff[l][i] -Settings.shuttercoeff[l-1][l]));
|
||||
realpos += ( percent*10 - Settings.shuttercoeff[l-1][i] ) * Shutter.open_max[i] * (calibrate_pos[l+1] - calibrate_pos[l]) / (Settings.shuttercoeff[l][i] -Settings.shuttercoeff[l-1][i]) / 100;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -113,25 +123,25 @@ int32_t ShutterPercentToRealPosition(uint8_t percent,uint8_t index)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ShutterRealToPercentPosition(int32_t realpos, uint8_t index)
|
||||
uint8_t ShutterRealToPercentPosition(int32_t realpos, uint8_t i)
|
||||
{
|
||||
if (Settings.shutter_set50percent[index] != 50) {
|
||||
return Settings.shuttercoeff[2][index] * 5 > realpos ? realpos / Settings.shuttercoeff[2][index] : (realpos-Settings.shuttercoeff[0][index]) / Settings.shuttercoeff[1][index];
|
||||
if (Settings.shutter_set50percent[i] != 50) {
|
||||
return Settings.shuttercoeff[2][i] * 5 > realpos ? realpos / Settings.shuttercoeff[2][i] : (realpos-Settings.shuttercoeff[0][i]) / Settings.shuttercoeff[1][i];
|
||||
} else {
|
||||
int16_t realpercent;
|
||||
|
||||
for (uint8_t i=0 ; i < 5 ; i++) {
|
||||
if (realpos > Shutter.open_max[index] * calibrate_pos[i+1] / 100) {
|
||||
realpercent = Settings.shuttercoeff[i][index] /10;
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Realpercent TEMP1: %d, %% %d, coeff %d"), realpercent, realpos, Shutter_Open_Max[index] * calibrate_pos[i+1] / 100);
|
||||
for (uint8_t j=0 ; j < 5 ; j++) {
|
||||
if (realpos > Shutter.open_max[i] * calibrate_pos[j+1] / 100) {
|
||||
realpercent = Settings.shuttercoeff[j][i] /10;
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Realpercent TEMP1: %d, %% %d, coeff %d"), realpercent, realpos, Shutter_Open_Max[i] * calibrate_pos[i+1] / 100);
|
||||
} else {
|
||||
if ( i == 0) {
|
||||
realpercent = ( realpos - (Shutter.open_max[index] * calibrate_pos[i] / 100) ) * 10 * Settings.shuttercoeff[i][index] / calibrate_pos[i+1] / Shutter.open_max[index];
|
||||
realpercent = ( realpos - (Shutter.open_max[i] * calibrate_pos[j] / 100) ) * 10 * Settings.shuttercoeff[j][i] / calibrate_pos[j+1] / Shutter.open_max[i];
|
||||
} else {
|
||||
//uint16_t addon = ( realpos - (Shutter_Open_Max[index] * calibrate_pos[i] / 100) ) * 10 * (Settings.shuttercoeff[i][index] - Settings.shuttercoeff[i-1][index]) / (calibrate_pos[i+1] - calibrate_pos[i])/ Shutter_Open_Max[index];
|
||||
//uint16_t addon = ( percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter_Open_Max[index] * (calibrate_pos[i+1] - calibrate_pos[i]) / (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]) / 100;
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Realpercent TEMP2: %d, delta %d, %% %d, coeff %d"), addon,( realpos - (Shutter_Open_Max[index] * calibrate_pos[i] / 100) ) , (calibrate_pos[i+1] - calibrate_pos[i])* Shutter_Open_Max[index]/100, (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]));
|
||||
realpercent += ( realpos - (Shutter.open_max[index] * calibrate_pos[i] / 100) ) * 10 * (Settings.shuttercoeff[i][index] - Settings.shuttercoeff[i-1][index]) / (calibrate_pos[i+1] - calibrate_pos[i]) / Shutter.open_max[index] ;
|
||||
//uint16_t addon = ( realpos - (Shutter_Open_Max[i] * calibrate_pos[i] / 100) ) * 10 * (Settings.shuttercoeff[i][i] - Settings.shuttercoeff[i-1][i]) / (calibrate_pos[i+1] - calibrate_pos[i])/ Shutter_Open_Max[i];
|
||||
//uint16_t addon = ( percent*10 - Settings.shuttercoeff[i-1][i] ) * Shutter_Open_Max[i] * (calibrate_pos[i+1] - calibrate_pos[i]) / (Settings.shuttercoeff[i][i] -Settings.shuttercoeff[i-1][i]) / 100;
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Realpercent TEMP2: %d, delta %d, %% %d, coeff %d"), addon,( realpos - (Shutter_Open_Max[i] * calibrate_pos[i] / 100) ) , (calibrate_pos[i+1] - calibrate_pos[i])* Shutter_Open_Max[i]/100, (Settings.shuttercoeff[i][i] -Settings.shuttercoeff[i-1][i]));
|
||||
realpercent += ( realpos - (Shutter.open_max[i] * calibrate_pos[j] / 100) ) * 10 * (Settings.shuttercoeff[j][i] - Settings.shuttercoeff[j-1][i]) / (calibrate_pos[j+1] - calibrate_pos[j]) / Shutter.open_max[i] ;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -148,12 +158,11 @@ void ShutterInit(void)
|
||||
Shutter.old_power = power;
|
||||
bool relay_in_interlock = false;
|
||||
|
||||
// if shutter 4 is unused
|
||||
if (Settings.shutter_startrelay[MAX_SHUTTERS] == 0) {
|
||||
Shutter.max_pwm_frequency = Settings.shuttercoeff[4][3] > 0 ? Settings.shuttercoeff[4][3] : Shutter.max_pwm_frequency;
|
||||
}
|
||||
for (uint32_t i = 0; i < MAX_SHUTTERS; i++) {
|
||||
// upgrade to 0.1sec calculation base.
|
||||
if ( Settings.shutter_accuracy == 0) {
|
||||
Settings.shutter_closetime[i] = Settings.shutter_closetime[i] * 10;
|
||||
Settings.shutter_opentime[i] = Settings.shutter_opentime[i] * 10;
|
||||
}
|
||||
// set startrelay to 1 on first init, but only to shutter 1. 90% usecase
|
||||
Settings.shutter_startrelay[i] = (Settings.shutter_startrelay[i] == 0 && i == 0? 1 : Settings.shutter_startrelay[i]);
|
||||
if (Settings.shutter_startrelay[i] && Settings.shutter_startrelay[i] <9) {
|
||||
@ -177,7 +186,8 @@ void ShutterInit(void)
|
||||
}
|
||||
} else {
|
||||
Shutter.mode = SHT_OFF_ON__OPEN_CLOSE;
|
||||
if (pin[GPIO_PWM1+i] < 99) {
|
||||
if (pin[GPIO_PWM1+i] < 99 && pin[GPIO_CNTR1+i]) {
|
||||
Shutter.mode = SHT_OFF_ON__OPEN_CLOSE_STEPPER;
|
||||
Shutter.pwm_frequency = 0;
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+i], 50);
|
||||
@ -195,6 +205,8 @@ void ShutterInit(void)
|
||||
// Update Calculation 20 because time interval is 0.05 sec
|
||||
Shutter.open_max[i] = 200 * Shutter.open_time[i];
|
||||
Shutter.close_velocity[i] = Shutter.open_max[i] / Shutter.close_time[i] / 2 ;
|
||||
Shutter.max_close_pwm_frequency[i] = Shutter.max_pwm_frequency*Shutter.open_time[i]/Shutter.close_time[i];
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d Closefreq: %d"),i, Shutter.max_close_pwm_frequency[i]);
|
||||
|
||||
// calculate a ramp slope at the first 5 percent to compensate that shutters move with down part later than the upper part
|
||||
if (Settings.shutter_set50percent[i] != 50) {
|
||||
@ -222,43 +234,54 @@ void ShutterInit(void)
|
||||
// terminate loop at first INVALID shutter.
|
||||
break;
|
||||
}
|
||||
if (shutters_present < 4) {
|
||||
Shutter.max_pwm_frequency = Settings.shuttercoeff[4][4] > 0 ? Settings.shuttercoeff[4][4] : Shutter.max_pwm_frequency;
|
||||
}
|
||||
|
||||
Settings.shutter_accuracy = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ShutterUpdatePosition(void)
|
||||
{
|
||||
|
||||
char scommand[CMDSZ];
|
||||
char stopic[TOPSZ];
|
||||
char stemp2[10];
|
||||
|
||||
for (uint32_t i = 0; i < shutters_present; i++) {
|
||||
if (Shutter.direction[i] != 0) {
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE && pin[GPIO_PWM1+i] < 99 && pin[GPIO_CNTR1+i] < 99 ) {
|
||||
int32_t stop_position_delta = 20;
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE_STEPPER) {
|
||||
// Calculate position with counter. Much more accurate and no need for motordelay workaround
|
||||
// adding some steps to stop early
|
||||
Shutter.real_position[i] = Shutter.direction[i] * 20 + ShutterCounterBasedPosition(i);;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: real %d, start %d, counter %d, max_freq %d, dir %d, freq %d"),Shutter.real_position[i], Shutter.start_position[i] ,RtcSettings.pulse_counter[i],Shutter.max_pwm_frequency , Shutter.direction[i] ,Shutter.max_pwm_frequency );
|
||||
Shutter.real_position[i] = ShutterCounterBasedPosition(i);
|
||||
|
||||
int32_t max_frequency = Shutter.direction[i] == 1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i];
|
||||
int32_t max_freq_change_per_sec = Shutter.max_pwm_frequency*steps_per_second / (Shutter.motordelay[i]>0 ? Shutter.motordelay[i] : 1);
|
||||
int32_t min_runtime_ms = Shutter.pwm_frequency*1000 / max_freq_change_per_sec;
|
||||
int32_t velocity = Shutter.direction[i] == 1 ? 100 : Shutter.close_velocity[i];
|
||||
int32_t minstopway = min_runtime_ms * velocity / 100 * Shutter.pwm_frequency / max_frequency * Shutter.direction[i] ;
|
||||
|
||||
int32_t next_possible_stop = Shutter.real_position[i] + minstopway ;
|
||||
stop_position_delta =200 * Shutter.pwm_frequency/max_frequency + Shutter.direction[i] * (next_possible_stop - Shutter.target_position[i]);
|
||||
//Shutter.accelerator[i] = tmin(tmax(max_freq_change_per_sec*(100-(Shutter.direction[i]*(Shutter.target_position[i]-next_possible_stop) ))/2000 , max_freq_change_per_sec*9/200), max_freq_change_per_sec*11/200);
|
||||
//int32_t act_freq_change = max_freq_change_per_sec/20;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: time: %d, velocity %d, minstopway %d,cur_freq %d, max_frequency %d, act_freq_change %d, min_runtime_ms %d, act.pos %d, next_stop %d, target: %d"),Shutter.time[i],velocity,minstopway,
|
||||
Shutter.pwm_frequency,max_frequency, Shutter.accelerator[i],min_runtime_ms,Shutter.real_position[i], next_possible_stop,Shutter.target_position[i]);
|
||||
|
||||
if (Shutter.accelerator[i] < 0 || next_possible_stop * Shutter.direction[i] > Shutter.target_position[i] * Shutter.direction[i] ) {
|
||||
|
||||
Shutter.accelerator[i] = - tmin(tmax(max_freq_change_per_sec*(100-(Shutter.direction[i]*(Shutter.target_position[i]-next_possible_stop) ))/2000 , max_freq_change_per_sec*9/200), max_freq_change_per_sec*12/200);
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Ramp down: acc: %d"), Shutter.accelerator[i]);
|
||||
} else if ( Shutter.accelerator[i] > 0 && Shutter.pwm_frequency == max_frequency) {
|
||||
Shutter.accelerator[i] = 0;
|
||||
}
|
||||
} else {
|
||||
Shutter.real_position[i] = Shutter.start_position[i] + ( (Shutter.time[i] - Shutter.motordelay[i]) * (Shutter.direction[i] > 0 ? 100 : -Shutter.close_velocity[i]));
|
||||
}
|
||||
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE && pin[GPIO_PWM1+i] < 99) {
|
||||
uint16_t freq_change = Shutter.max_pwm_frequency/(Shutter.motordelay[i]+1);
|
||||
// ramp up phase. calculate frequency
|
||||
Shutter.pwm_frequency = tmin(freq_change * Shutter.time[i],Shutter.max_pwm_frequency);
|
||||
// ramp down at the end of the movement time will not be exactly motordelay
|
||||
Shutter.pwm_frequency = tmax(tmin(freq_change * (Shutter.target_position[i]-Shutter.real_position[i])*Shutter.direction[i]/30, Shutter.pwm_frequency),10);
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+i], 50);
|
||||
}
|
||||
if (Shutter.real_position[i] * Shutter.direction[i] >= Shutter.target_position[i] * Shutter.direction[i] ) {
|
||||
if ( Shutter.real_position[i] * Shutter.direction[i] + stop_position_delta >= Shutter.target_position[i] * Shutter.direction[i] ) {
|
||||
// calculate relay number responsible for current movement.
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Stop Condition detected: real: %d, Target: %d, direction: %d"),Shutter.real_position[i], Shutter.target_position[i],Shutter.direction[i]);
|
||||
uint8_t cur_relay = Settings.shutter_startrelay[i] + (Shutter.direction[i] == 1 ? 0 : 1) ;
|
||||
int16_t missing_steps;
|
||||
|
||||
switch (Shutter.mode) {
|
||||
case SHT_PULSE_OPEN__PULSE_CLOSE:
|
||||
@ -269,29 +292,34 @@ void ShutterUpdatePosition(void)
|
||||
last_source = SRC_SHUTTER;
|
||||
}
|
||||
break;
|
||||
case SHT_OFF_ON__OPEN_CLOSE:
|
||||
// This is a failsafe configuration. Relay1 ON/OFF Relay2 -1/1 direction
|
||||
// Only allow PWM microstepping if PWM and COUNTER are defined.
|
||||
// see wiki to connect PWM and COUNTER
|
||||
if (pin[GPIO_PWM1+i] < 99 && pin[GPIO_CNTR1+i] < 99 ) {
|
||||
int16_t missing_steps = ((Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) - RtcSettings.pulse_counter[i];
|
||||
//prepare for stop PWM
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Remain steps %d, counter %d, freq %d"), missing_steps, RtcSettings.pulse_counter[i] ,Shutter.pwm_frequency);
|
||||
Shutter.pwm_frequency = 0;
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) {
|
||||
delay(1);
|
||||
}
|
||||
analogWrite(pin[GPIO_PWM1+i], 0);
|
||||
Shutter.real_position[i] = ShutterCounterBasedPosition(i);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT:Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]);
|
||||
|
||||
case SHT_OFF_ON__OPEN_CLOSE_STEPPER:
|
||||
missing_steps = ((Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) - RtcSettings.pulse_counter[i];
|
||||
//prepare for stop PWM
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Remain steps %d, counter %d, freq %d"), missing_steps, RtcSettings.pulse_counter[i] ,Shutter.pwm_frequency);
|
||||
Shutter.accelerator[i] = 0;
|
||||
Shutter.pwm_frequency = Shutter.pwm_frequency > 250 ? 250 : Shutter.pwm_frequency;
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+i], 50);
|
||||
Shutter.pwm_frequency = 0;
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) {
|
||||
delay(1);
|
||||
}
|
||||
analogWrite(pin[GPIO_PWM1+i], 0);
|
||||
Shutter.real_position[i] = ShutterCounterBasedPosition(i);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT:Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]);
|
||||
|
||||
if ((1 << (Settings.shutter_startrelay[i]-1)) & power) {
|
||||
ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER);
|
||||
ExecuteCommandPower(Settings.shutter_startrelay[i]+1, 0, SRC_SHUTTER);
|
||||
}
|
||||
break;
|
||||
case SHT_OFF_ON__OPEN_CLOSE:
|
||||
if ((1 << (Settings.shutter_startrelay[i]-1)) & power) {
|
||||
ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER);
|
||||
ExecuteCommandPower(Settings.shutter_startrelay[i]+1, 0, SRC_SHUTTER);
|
||||
}
|
||||
break;
|
||||
case SHT_OFF_OPEN__OFF_CLOSE:
|
||||
// avoid switching OFF a relay already OFF
|
||||
if ((1 << (cur_relay-1)) & power) {
|
||||
@ -302,7 +330,7 @@ void ShutterUpdatePosition(void)
|
||||
}
|
||||
Settings.shutter_position[i] = ShutterRealToPercentPosition(Shutter.real_position[i], i);
|
||||
|
||||
dtostrfd((float)Shutter.time[i] / 20, 1, stemp2);
|
||||
dtostrfd((float)Shutter.time[i] / steps_per_second, 1, stemp2);
|
||||
AddLog_P2(LOG_LEVEL_INFO, MSG_SHUTTER_POS, i+1, Shutter.real_position[i], Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i], Shutter.motordelay[i],stemp2,Shutter.pwm_frequency);
|
||||
Shutter.start_position[i] = Shutter.real_position[i];
|
||||
|
||||
@ -332,50 +360,51 @@ bool ShutterState(uint8_t device)
|
||||
(Shutter.mask & (1 << (Settings.shutter_startrelay[device]-1))) );
|
||||
}
|
||||
|
||||
void ShutterStartInit(uint8_t index, int8_t direction, int32_t target_pos)
|
||||
void ShutterStartInit(uint8_t i, int8_t direction, int32_t target_pos)
|
||||
{
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: dir %d, delta1 %d, delta2 %d, grant %d"),direction, (Shutter.open_max[index] - Shutter.real_position[index]) / Shutter.close_velocity[index], Shutter.real_position[index] / Shutter.close_velocity[index], 2+Shutter.motordelay[index]);
|
||||
if ( ( direction == 1 && (Shutter.open_max[index] - Shutter.real_position[index]) / 100 <= 2 )
|
||||
|| ( direction == -1 && Shutter.real_position[index] / Shutter.close_velocity[index] <= 2)) {
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: dir %d, delta1 %d, delta2 %d, grant %d"),direction, (Shutter.open_max[i] - Shutter.real_position[i]) / Shutter.close_velocity[i], Shutter.real_position[i] / Shutter.close_velocity[i], 2+Shutter.motordelay[i]);
|
||||
if ( ( direction == 1 && (Shutter.open_max[i] - Shutter.real_position[i]) / 100 <= 2 )
|
||||
|| ( direction == -1 && Shutter.real_position[i] / Shutter.close_velocity[i] <= 2)) {
|
||||
Shutter.skip_relay_change = 1 ;
|
||||
} else {
|
||||
if (pin[GPIO_PWM1+index] < 99) {
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE_STEPPER) {
|
||||
Shutter.pwm_frequency = 0;
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+index], 0);
|
||||
analogWrite(pin[GPIO_PWM1+i], 0);
|
||||
// can be operated without counter, but then not that acurate.
|
||||
if (pin[GPIO_CNTR1+index] < 99) {
|
||||
RtcSettings.pulse_counter[index] = 0;
|
||||
if (pin[GPIO_CNTR1+i] < 99) {
|
||||
RtcSettings.pulse_counter[i] = 0;
|
||||
}
|
||||
Shutter.accelerator[i] = Shutter.max_pwm_frequency / (Shutter.motordelay[i]>0 ? Shutter.motordelay[i] : 1);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Ramp up: %d"), Shutter.accelerator[i]);
|
||||
}
|
||||
Shutter.target_position[index] = target_pos;
|
||||
Shutter.start_position[index] = Shutter.real_position[index];
|
||||
Shutter.time[index] = 0;
|
||||
Shutter.target_position[i] = target_pos;
|
||||
Shutter.start_position[i] = Shutter.real_position[i];
|
||||
Shutter.time[i] = 0;
|
||||
Shutter.skip_relay_change = 0;
|
||||
Shutter.direction[index] = direction;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: real %d, start %d, counter %d, max_freq %d, dir %d, freq %d"),Shutter.real_position[index], Shutter.start_position[index] ,RtcSettings.pulse_counter[index],Shutter.max_pwm_frequency , Shutter.direction[index] ,Shutter.max_pwm_frequency );
|
||||
Shutter.direction[i] = direction;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: real %d, start %d, counter %d, max_freq %d, dir %d, freq %d"),Shutter.real_position[i], Shutter.start_position[i] ,RtcSettings.pulse_counter[i],Shutter.max_pwm_frequency , Shutter.direction[i] ,Shutter.max_pwm_frequency );
|
||||
}
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start shutter: %d from %d to %d in directin %d"), index, Shutter.start_position[index], Shutter.target_position[index], Shutter.direction[index]);
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start shutter: %d from %d to %d in directin %d"), i, Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i]);
|
||||
}
|
||||
|
||||
void ShutterWaitForMotorStop(uint8_t index)
|
||||
void ShutterWaitForMotorStop(uint8_t i)
|
||||
{
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Wait for Motorstop.."));
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE) {
|
||||
if (pin[GPIO_PWM1+index] < 99 && pin[GPIO_CNTR1+index] < 99 ) {
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE || Shutter.mode == SHT_OFF_ON__OPEN_CLOSE_STEPPER) {
|
||||
if ( Shutter.mode = SHT_OFF_ON__OPEN_CLOSE_STEPPER) {
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Frequency change %d"), Shutter.pwm_frequency);
|
||||
while (Shutter.pwm_frequency > 100) {
|
||||
Shutter.pwm_frequency = tmax(Shutter.pwm_frequency-(Shutter.max_pwm_frequency/(Shutter.motordelay[index]+1)) , 0);
|
||||
while (Shutter.pwm_frequency > 0) {
|
||||
Shutter.accelerator[i] = 0;
|
||||
Shutter.pwm_frequency = tmax(Shutter.pwm_frequency-((Shutter.direction[i] == 1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i])/(Shutter.motordelay[i]+1)) , 0);
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+index], 50);
|
||||
analogWrite(pin[GPIO_PWM1+i], 50);
|
||||
delay(50);
|
||||
}
|
||||
Shutter.pwm_frequency = 0;
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+index], 0);
|
||||
Shutter.real_position[index] = ShutterCounterBasedPosition(index);
|
||||
analogWrite(pin[GPIO_PWM1+i], 0);
|
||||
Shutter.real_position[i] = ShutterCounterBasedPosition(i);
|
||||
} else {
|
||||
ExecuteCommandPower(Settings.shutter_startrelay[index], 0, SRC_SHUTTER);
|
||||
ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER);
|
||||
delay(MOTOR_STOP_TIME);
|
||||
}
|
||||
} else {
|
||||
@ -391,7 +420,7 @@ void ShutterReportPosition(void)
|
||||
if (Shutter.direction[i] != 0) {
|
||||
char stemp2[10];
|
||||
uint8_t position = ShutterRealToPercentPosition(Shutter.real_position[i], i);
|
||||
dtostrfd((float)Shutter.time[i] / 20, 2, stemp2);
|
||||
dtostrfd((float)Shutter.time[i] / steps_per_second, 2, stemp2);
|
||||
shutter_moving = 1;
|
||||
//Settings.shutter_position[i] = Settings.shuttercoeff[2][i] * 5 > Shutter.real_position[i] ? Shutter.real_position[i] / Settings.shuttercoeff[2][i] : (Shutter.real_position[i]-Settings.shuttercoeff[0,i]) / Settings.shuttercoeff[1][i];
|
||||
AddLog_P2(LOG_LEVEL_INFO, MSG_SHUTTER_POS, i+1, Shutter.real_position[i], Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i], Shutter.motordelay[i],stemp2,Shutter.pwm_frequency);
|
||||
@ -430,7 +459,7 @@ void ShutterRelayChanged(void)
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed);
|
||||
if (manual_relays_changed) {
|
||||
//Shutter.skip_relay_change = true;
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE) {
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE || Shutter.mode == SHT_OFF_ON__OPEN_CLOSE_STEPPER) {
|
||||
ShutterWaitForMotorStop(i);
|
||||
switch (powerstate_local) {
|
||||
case 1:
|
||||
@ -478,7 +507,7 @@ void ShutterSetPosition(uint8_t device, uint8_t position)
|
||||
|
||||
void CmndShutterOpen(void)
|
||||
{
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload close: %d, index %d"), XdrvMailbox.payload, XdrvMailbox.index);
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload close: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.i);
|
||||
if ( XdrvMailbox.index == 1 && XdrvMailbox.payload != -99) {
|
||||
XdrvMailbox.index = XdrvMailbox.payload;
|
||||
}
|
||||
@ -489,7 +518,7 @@ void CmndShutterOpen(void)
|
||||
|
||||
void CmndShutterClose(void)
|
||||
{
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload open: %d, index %d"), XdrvMailbox.payload, XdrvMailbox.index);
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload open: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.i);
|
||||
if ( XdrvMailbox.index == 1 && XdrvMailbox.payload != -99) {
|
||||
XdrvMailbox.index = XdrvMailbox.payload;
|
||||
}
|
||||
@ -505,14 +534,14 @@ void CmndShutterStop(void)
|
||||
if ( XdrvMailbox.index == 1 && XdrvMailbox.payload != -99) {
|
||||
XdrvMailbox.index = XdrvMailbox.payload;
|
||||
}
|
||||
uint32_t index = XdrvMailbox.index -1;
|
||||
if (Shutter.direction[index] != 0) {
|
||||
uint32_t i = XdrvMailbox.index -1;
|
||||
if (Shutter.direction[i] != 0) {
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter.direction[index]);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter.direction[i]);
|
||||
// set stop position 10 steps ahead (0.5sec to allow normal stop)
|
||||
int32_t temp_realpos = Shutter.start_position[index] + ( (Shutter.time[index]+10) * (Shutter.direction[index] > 0 ? 100 : -Shutter.close_velocity[index]));
|
||||
XdrvMailbox.payload = ShutterRealToPercentPosition(temp_realpos, index);
|
||||
//XdrvMailbox.payload = Settings.shuttercoeff[2][index] * 5 > temp_realpos ? temp_realpos / Settings.shuttercoeff[2][index] : (temp_realpos-Settings.shuttercoeff[0,index]) / Settings.shuttercoeff[1][index];
|
||||
int32_t temp_realpos = Shutter.start_position[i] + ( (Shutter.time[i]+10) * (Shutter.direction[i] > 0 ? 100 : -Shutter.close_velocity[i]));
|
||||
XdrvMailbox.payload = ShutterRealToPercentPosition(temp_realpos, i);
|
||||
//XdrvMailbox.payload = Settings.shuttercoeff[2][i] * 5 > temp_realpos ? temp_realpos / Settings.shuttercoeff[2][i] : (temp_realpos-Settings.shuttercoeff[0,i]) / Settings.shuttercoeff[1][i];
|
||||
last_source = SRC_WEBGUI;
|
||||
CmndShutterPosition();
|
||||
} else {
|
||||
@ -524,7 +553,7 @@ void CmndShutterStop(void)
|
||||
void CmndShutterPosition(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
uint32_t index = XdrvMailbox.index -1;
|
||||
uint32_t index = XdrvMailbox.index-1;
|
||||
//limit the payload
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Pos. in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, last_source );
|
||||
|
||||
@ -542,6 +571,7 @@ void CmndShutterPosition(void)
|
||||
if (XdrvMailbox.payload != -99) {
|
||||
//target_pos_percent = Settings.shutter_invert[index] ? 100 - target_pos_percent : target_pos_percent;
|
||||
Shutter.target_position[index] = ShutterPercentToRealPosition(target_pos_percent, index);
|
||||
Shutter.accelerator[index] = Shutter.max_pwm_frequency / (Shutter.motordelay[index]>0 ? Shutter.motordelay[index] : 1);
|
||||
//Shutter.target_position[index] = XdrvMailbox.payload < 5 ? Settings.shuttercoeff[2][index] * XdrvMailbox.payload : Settings.shuttercoeff[1][index] * XdrvMailbox.payload + Settings.shuttercoeff[0,index];
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), last_source, Shutter.real_position[index] ,Shutter.target_position[index],target_pos_percent);
|
||||
}
|
||||
@ -561,7 +591,7 @@ void CmndShutterPosition(void)
|
||||
}
|
||||
}
|
||||
if (Shutter.direction[index] != new_shutterdirection ) {
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE) {
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE || Shutter.mode == SHT_OFF_ON__OPEN_CLOSE_STEPPER) {
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay5 5s, xdrv %d"), XdrvMailbox.payload);
|
||||
ShutterWaitForMotorStop(index);
|
||||
ExecuteCommandPower(Settings.shutter_startrelay[index], 0, SRC_SHUTTER);
|
||||
@ -617,11 +647,11 @@ void CmndShutterMotorDelay(void)
|
||||
{
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
Settings.shutter_motordelay[XdrvMailbox.index -1] = (uint16_t)(20 * CharToFloat(XdrvMailbox.data));
|
||||
Settings.shutter_motordelay[XdrvMailbox.index -1] = (uint16_t)(steps_per_second * CharToFloat(XdrvMailbox.data));
|
||||
ShutterInit();
|
||||
}
|
||||
char time_chr[10];
|
||||
dtostrfd((float)(Settings.shutter_motordelay[XdrvMailbox.index -1]) / 20, 2, time_chr);
|
||||
dtostrfd((float)(Settings.shutter_motordelay[XdrvMailbox.index -1]) / steps_per_second, 2, time_chr);
|
||||
ResponseCmndIdxChar(time_chr);
|
||||
}
|
||||
}
|
||||
@ -660,8 +690,9 @@ void CmndShutterFrequency(void)
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 20000)) {
|
||||
Shutter.max_pwm_frequency = XdrvMailbox.payload;
|
||||
if (shutters_present < 4) {
|
||||
Settings.shuttercoeff[4][4] = Shutter.max_pwm_frequency;
|
||||
Settings.shuttercoeff[4][3] = Shutter.max_pwm_frequency;
|
||||
}
|
||||
ShutterInit();
|
||||
ResponseCmndNumber(XdrvMailbox.payload); // ????
|
||||
} else {
|
||||
ResponseCmndNumber(Shutter.max_pwm_frequency);
|
||||
@ -707,8 +738,8 @@ void CmndShutterCalibration(void) // ????
|
||||
messwerte[i] = field;
|
||||
}
|
||||
for (i=0 ; i < 5 ; i++) {
|
||||
Settings.shuttercoeff[i][XdrvMailbox.index-1] = messwerte[i] * 1000 / messwerte[4];
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("Settings.shuttercoeff: %d, i: %d, value: %d, messwert %d"), i,XdrvMailbox.index-1,Settings.shuttercoeff[i][XdrvMailbox.index-1], messwerte[i]);
|
||||
Settings.shuttercoeff[i][XdrvMailbox.index -1] = messwerte[i] * 1000 / messwerte[4];
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("Settings.shuttercoeff: %d, i: %d, value: %d, messwert %d"), i,XdrvMailbox.index -1,Settings.shuttercoeff[i][XdrvMailbox.index -1], messwerte[i]);
|
||||
}
|
||||
ShutterInit();
|
||||
ResponseCmndIdxChar(XdrvMailbox.data);
|
||||
|
@ -103,7 +103,7 @@ void DeepSleepPrepare(void)
|
||||
// if more then 10% timeslip = 0 == non valid wakeup; maybe manual
|
||||
timeslip = (timeslip < -(int32_t)Settings.deepsleep) ? 0 : (timeslip > (int32_t)Settings.deepsleep) ? 0 : 1;
|
||||
if (timeslip) {
|
||||
RtcSettings.deepsleep_slip = (Settings.deepsleep + RtcSettings.nextwakeup - UtcTime()) * RtcSettings.deepsleep_slip / (Settings.deepsleep - (millis() / 1000));
|
||||
RtcSettings.deepsleep_slip = (Settings.deepsleep + RtcSettings.nextwakeup - UtcTime()) * RtcSettings.deepsleep_slip / tmax((Settings.deepsleep - (millis() / 1000)),5);
|
||||
// Avoid crazy numbers. Again maximum 10% deviation.
|
||||
RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000);
|
||||
RtcSettings.nextwakeup += Settings.deepsleep;
|
||||
|
@ -143,9 +143,7 @@ void HlwEvery200ms(void)
|
||||
if (Hlw.cf1_timer >= 8) {
|
||||
Hlw.cf1_timer = 0;
|
||||
Hlw.select_ui_flag = (Hlw.select_ui_flag) ? false : true;
|
||||
if (pin[GPIO_NRG_SEL] < 99) {
|
||||
digitalWrite(pin[GPIO_NRG_SEL], Hlw.select_ui_flag);
|
||||
}
|
||||
DigitalWrite(GPIO_NRG_SEL, Hlw.select_ui_flag);
|
||||
|
||||
if (Hlw.cf1_pulse_counter) {
|
||||
cf1_pulse_length = Hlw.cf1_summed_pulse_length / Hlw.cf1_pulse_counter;
|
||||
|
@ -570,9 +570,7 @@ void McpSnsInit(void)
|
||||
} else {
|
||||
mcp_buffer = (char*)(malloc(MCP_BUFFER_SIZE));
|
||||
}
|
||||
if (pin[GPIO_MCP39F5_RST] < 99) {
|
||||
digitalWrite(pin[GPIO_MCP39F5_RST], 1); // MCP enable
|
||||
}
|
||||
DigitalWrite(GPIO_MCP39F5_RST, 1); // MCP enable
|
||||
} else {
|
||||
energy_flg = ENERGY_NONE;
|
||||
}
|
||||
|
152
tasmota/xsns_58_dht12.ino
Normal file
152
tasmota/xsns_58_dht12.ino
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
xsns_58_dht12.ino - DHT12 I2C temperature and humidity sensor support for Tasmota
|
||||
|
||||
Copyright (C) 2019 Stefan Oskamp and Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_I2C
|
||||
#ifdef USE_DHT12
|
||||
/*********************************************************************************************\
|
||||
* DHT12 - Temperature and Humidity
|
||||
*
|
||||
* I2C Address: 0x5C
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XSNS_58 58
|
||||
#define XI2C_41 41 // See I2CDEVICES.md
|
||||
|
||||
#define DHT12_ADDR 0x5C
|
||||
|
||||
struct DHT12 {
|
||||
float temperature = NAN;
|
||||
float humidity = NAN;
|
||||
uint8_t valid = 0;
|
||||
uint8_t count = 0;
|
||||
char name[6] = "DHT12";
|
||||
} Dht12;
|
||||
|
||||
bool Dht12Read(void)
|
||||
{
|
||||
if (Dht12.valid) { Dht12.valid--; }
|
||||
|
||||
Wire.beginTransmission(DHT12_ADDR);
|
||||
Wire.write(0);
|
||||
if (Wire.endTransmission() != 0) { return false; }
|
||||
|
||||
delay(50);
|
||||
|
||||
Wire.requestFrom(DHT12_ADDR, 5);
|
||||
delay(5);
|
||||
uint8_t humidity = Wire.read();
|
||||
uint8_t humidityTenth = Wire.read();
|
||||
uint8_t temp = Wire.read();
|
||||
uint8_t tempTenth = Wire.read();
|
||||
uint8_t checksum = Wire.read();
|
||||
|
||||
Dht12.humidity = ConvertHumidity( (float) humidity + (float) humidityTenth/(float) 10.0 );
|
||||
Dht12.temperature = ConvertTemp( (float) temp + (float) tempTenth/(float) 10.0 );
|
||||
|
||||
if (isnan(Dht12.temperature) || isnan(Dht12.humidity)) { return false; }
|
||||
|
||||
Dht12.valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void Dht12Detect(void)
|
||||
{
|
||||
if (I2cActive(DHT12_ADDR)) { return; }
|
||||
|
||||
if (Dht12Read()) {
|
||||
I2cSetActiveFound(DHT12_ADDR, Dht12.name);
|
||||
Dht12.count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Dht12EverySecond(void)
|
||||
{
|
||||
if (uptime &1) {
|
||||
// DHT12: 55mS
|
||||
if (!Dht12Read()) {
|
||||
AddLogMissed(Dht12.name, Dht12.valid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Dht12Show(bool json)
|
||||
{
|
||||
if (Dht12.valid) {
|
||||
char temperature[33];
|
||||
dtostrfd(Dht12.temperature, Settings.flag2.temperature_resolution, temperature);
|
||||
char humidity[33];
|
||||
dtostrfd(Dht12.humidity, Settings.flag2.humidity_resolution, humidity);
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(JSON_SNS_TEMPHUM, Dht12.name, temperature, humidity);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if ((0 == tele_period)) {
|
||||
DomoticzTempHumSensor(temperature, humidity);
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
#ifdef USE_KNX
|
||||
if (0 == tele_period) {
|
||||
KnxSensor(KNX_TEMPERATURE, Dht12.temperature);
|
||||
KnxSensor(KNX_HUMIDITY, Dht12.humidity);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_SNS_TEMP, Dht12.name, temperature, TempUnit());
|
||||
WSContentSend_PD(HTTP_SNS_HUM, Dht12.name, humidity);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xsns58(uint8_t function)
|
||||
{
|
||||
if (!I2cEnabled(XI2C_41)) { return false; }
|
||||
|
||||
bool result = false;
|
||||
|
||||
if (FUNC_INIT == function) {
|
||||
Dht12Detect();
|
||||
}
|
||||
else if (Dht12.count) {
|
||||
switch (function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
Dht12EverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
Dht12Show(1);
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_SENSOR:
|
||||
Dht12Show(0);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_DHT12
|
||||
#endif // USE_I2C
|
@ -187,7 +187,7 @@ a_features = [[
|
||||
"USE_SHUTTER","USE_PCF8574","USE_DDSU666","USE_DEEPSLEEP",
|
||||
"USE_SONOFF_SC","USE_SONOFF_RF","USE_SONOFF_L1","USE_EXS_DIMMER",
|
||||
"USE_ARDUINO_SLAVE","USE_HIH6","USE_HPMA","USE_TSL2591",
|
||||
"","","","",
|
||||
"USE_DHT12","","","",
|
||||
"","","","",
|
||||
"","","",""
|
||||
]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user