From 9014ad3a8e9e0a91029fe073bbf834029d297cbb Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Tue, 27 Feb 2018 14:59:46 +0100 Subject: [PATCH] v5.12.0d - Adds and Fix 5.12.0d * Prep for optional MQTT drivers by separating mqtt code from sonoff.ino to file xdrv_00_mqtt.ino * Add compiler check for stable lwIP version v1.4 (#1940) * Add diacritics to Polish language file (#2005) * Add Hungarian language file (#2024) * Fix MQTT TLS fingerprint validation (#2033) --- README.md | 2 +- platformio.ini | 35 ++ sonoff/_releasenotes.ino | 10 +- sonoff/language/hu-HU.h | 457 ++++++++++++++++++++++++ sonoff/language/pl-PL.h | 222 ++++++------ sonoff/settings.h | 3 + sonoff/sonoff.h | 2 +- sonoff/sonoff.ino | 513 ++------------------------- sonoff/sonoff_post.h | 7 + sonoff/user_config.h | 3 +- sonoff/webserver.ino | 10 +- sonoff/xdrv_00_mqtt.ino | 730 ++++++++++++++++++++++++++++++++++++++ sonoff/xdrv_interface.ino | 8 +- 13 files changed, 1389 insertions(+), 613 deletions(-) create mode 100644 sonoff/language/hu-HU.h create mode 100644 sonoff/xdrv_00_mqtt.ino diff --git a/README.md b/README.md index 07372cdd6..1559bd7b5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **5.12.0c** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. +Current version is **5.12.0d** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/platformio.ini b/platformio.ini index 5c6aa2ae9..d93ecfea9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -17,6 +17,7 @@ src_dir = sonoff ;env_default = sonoff-DE ;env_default = sonoff-ES ;env_default = sonoff-FR +;env_default = sonoff-HU ;env_default = sonoff-IT ;env_default = sonoff-NL ;env_default = sonoff-PL @@ -24,6 +25,8 @@ src_dir = sonoff ;env_default = sonoff-CN [env:sonoff] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -49,6 +52,8 @@ monitor_baud = 115200 ;extra_scripts = pio/strip-floats.py, pio/http-uploader.py [env:sonoff-minimal] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -61,6 +66,8 @@ extra_scripts = pio/strip-floats.py monitor_baud = 115200 [env:sonoff-xxl] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -73,6 +80,8 @@ extra_scripts = pio/strip-floats.py monitor_baud = 115200 [env:sonoff-DE] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -85,6 +94,8 @@ extra_scripts = pio/strip-floats.py monitor_baud = 115200 [env:sonoff-ES] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -97,6 +108,8 @@ extra_scripts = pio/strip-floats.py monitor_baud = 115200 [env:sonoff-FR] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -108,7 +121,21 @@ extra_scripts = pio/strip-floats.py ; *** Serial Monitor options monitor_baud = 115200 +[env:sonoff-HU] +platform = espressif8266 +framework = arduino +board = esp01_1m +board_flash_mode = dout +build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=hu-HU +lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +extra_scripts = pio/strip-floats.py + +; *** Serial Monitor options +monitor_baud = 115200 + [env:sonoff-IT] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -121,6 +148,8 @@ extra_scripts = pio/strip-floats.py monitor_baud = 115200 [env:sonoff-NL] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -133,6 +162,8 @@ extra_scripts = pio/strip-floats.py monitor_baud = 115200 [env:sonoff-PL] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -145,6 +176,8 @@ extra_scripts = pio/strip-floats.py monitor_baud = 115200 [env:sonoff-RU] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m @@ -157,6 +190,8 @@ extra_scripts = pio/strip-floats.py monitor_baud = 115200 [env:sonoff-CN] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 platform = espressif8266 framework = arduino board = esp01_1m diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index c8a55101a..778bf4e0f 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,7 +1,15 @@ -/* 5.12.0c +/* 5.12.0d + * Prep for optional MQTT drivers by separating mqtt code from sonoff.ino to file xdrv_00_mqtt.ino + * Add compiler check for stable lwIP version v1.4 (#1940) + * Add diacritics to Polish language file (#2005) + * Add Hungarian language file (#2024) + * Fix MQTT TLS fingerprint validation (#2033) + * + * 5.12.0c * Fix intermittent exception when dns lookup is used while sleep is enabled * Fix 5.4.0 regression turning off single press after button hold during 4x hold time * Fix possible wifi connection problem by erasing sdk configuration parameters + * Change Polish language to using Diacritics (#2005) * * 5.12.0b * Add serial debug info diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h new file mode 100644 index 000000000..3f283f7e5 --- /dev/null +++ b/sonoff/language/hu-HU.h @@ -0,0 +1,457 @@ +/* + hu-HU.h - localization for Hungarian in Hungary for Sonoff-Tasmota + + Copyright (C) 2018 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 . +*/ + +#ifndef _LANGUAGE_HU_HU_H_ +#define _LANGUAGE_HU_HU_H_ + +/*************************** ATTENTION *******************************\ + * + * Due to memory constraints only UTF-8 is supported. + * To save code space keep text as short as possible. + * Time and Date provided by SDK can not be localized (yet). + * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. + * Use online command Prefix to translate cmnd, stat and tele. + * +\*********************************************************************/ + +//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) + +// "2017-03-07T11:08:02" - ISO8601:2004 +#define D_YEAR_MONTH_SEPARATOR "." +#define D_MONTH_DAY_SEPARATOR "." +#define D_DATE_TIME_SEPARATOR " " +#define D_HOUR_MINUTE_SEPARATOR ":" +#define D_MINUTE_SECOND_SEPARATOR ":" + +#define D_DAY3LIST "VasHétKedSzeCsüPénSzo" +#define D_MONTH3LIST "JanFebMárÁprMájJúnJúlAugSzeOktNovDec" + +// Non JSON decimal separator +#define D_DECIMAL_SEPARATOR "." + +// Common +#define D_ADMIN "Admin" +#define D_AIR_QUALITY "Levegő minőség" +#define D_AP "AP" // Access Point +#define D_AS "mint" +#define D_AUTO "AUTO" +#define D_BLINK "Villogás" +#define D_BLINKOFF "Villogás Ki" +#define D_BOOT_COUNT "Bootolások száma" +#define D_BRIGHTLIGHT "Max. fényerő" +#define D_BUTTON "Gomb" +#define D_BY "által" // Written by me +#define D_BYTES "Byte-ok" +#define D_CELSIUS "Celsius" +#define D_CO2 "Szén-dioxid" +#define D_CODE "kód" // Button code +#define D_COLDLIGHT "Hideg" +#define D_COMMAND "Parancs" +#define D_CONNECTED "Csatlakozva" +#define D_COUNT "Szám" +#define D_COUNTER "Számláló" +#define D_CURRENT "Áram" // As in Voltage and Current +#define D_DATA "Adat" +#define D_DARKLIGHT "Min. févnyerő" +#define D_DEBUG "Debug" +#define D_DISABLED "Letiltva" +#define D_DNS_SERVER "DNS Szerver" +#define D_DONE "Kész" +#define D_DST_TIME "DST" +#define D_EMULATION "Emuláció" +#define D_ENABLED "Engedélyezve" +#define D_ERASE "Törlés" +#define D_ERROR "Hiba" +#define D_FAHRENHEIT "Fahrenheit" +#define D_FAILED "Sikertelen" +#define D_FALLBACK "Fallback" +#define D_FALLBACK_TOPIC "Fallback Téma" +#define D_FALSE "Hamis" +#define D_FILE "File" +#define D_FREE_MEMORY "Szabad Memória" +#define D_GAS "Gáz" +#define D_GATEWAY "Gateway" +#define D_GROUP "Csoport" +#define D_HOST "Host" +#define D_HOSTNAME "Hostname" +#define D_HUMIDITY "Páratartalom" +#define D_ILLUMINANCE "Megvilágítás" +#define D_IMMEDIATE "azonnali" // Button immediate +#define D_INDEX "Index" +#define D_INFO "Info" +#define D_INITIALIZED "Inicializálva" +#define D_IP_ADDRESS "IP Cím" +#define D_LIGHT "Fény" +#define D_LWT "LWT" +#define D_MODULE "Modul" +#define D_MQTT "MQTT" +#define D_MULTI_PRESS "több lenyomás" +#define D_NOISE "Zaj" +#define D_NONE "nincs" +#define D_OFF "Ki" +#define D_OFFLINE "Offline" +#define D_OK "Ok" +#define D_ON "Be" +#define D_ONLINE "Online" +#define D_PASSWORD "Jelszó" +#define D_PORT "Port" +#define D_POWER_FACTOR "Teljesítmény tényező" +#define D_POWERUSAGE "Energiafelhasználás" +#define D_PRESSURE "Nyomás" +#define D_PRESSUREATSEALEVEL "Tengerszinti nyomás" +#define D_PROGRAM_FLASH_SIZE "Program Flash Méret" +#define D_PROGRAM_SIZE "Program Méret" +#define D_PROJECT "Projekt" +#define D_RECEIVED "Érkezett" +#define D_RESTART "Újraindítás" +#define D_RESTARTING "Újraindítás" +#define D_RESTART_REASON "Újraindítás oka:" +#define D_RESTORE "Visszaállítás" +#define D_RETAINED "mentve" +#define D_SAVE "Mentés" +#define D_SENSOR "Szenzor" +#define D_SSID "SSId" +#define D_START "" +#define D_STD_TIME "STD" +#define D_STOP "Leállítás" +#define D_SUBNET_MASK "Subnet Mask" +#define D_SUBSCRIBE_TO "Feliratkozás a" +#define D_SUCCESSFUL "Sikeres" +#define D_TEMPERATURE "Hőmérséklet" +#define D_TO "-nak" +#define D_TOGGLE "Toggle" +#define D_TOPIC "Téma" +#define D_TRANSMIT "Továbbít" +#define D_TRUE "Igaz" +#define D_UPGRADE "frissítés" +#define D_UPLOAD "Feltöltés" +#define D_UPTIME "Üzemidő" +#define D_USER "Felhasználó" +#define D_UTC_TIME "UTC" +#define D_UV_LEVEL "UV Szint" +#define D_VERSION "Verzió" +#define D_VOLTAGE "Feszültség" +#define D_WARMLIGHT "Meleg" +#define D_WEB_SERVER "Web Szerver" + +// sonoff.ino +#define D_WARNING_MINIMAL_VERSION "VIGYÁZZ Ez a verzió nem támogat tartós beállításokat" +#define D_LEVEL_10 "szint 1-0" +#define D_LEVEL_01 "szint 0-1" +#define D_SERIAL_LOGGING_DISABLED "Serial logolás kikapcsolva" +#define D_SYSLOG_LOGGING_REENABLED "Syslog logolás újra-engedélyezve" + +#define D_SET_BAUDRATE_TO "Baudrate beállítása" +#define D_RECEIVED_TOPIC "Érkezett Téma" +#define D_DATA_SIZE "Adat Méret" +#define D_ANALOG_INPUT "Analóg" + +#define D_FINGERPRINT "TLS fingerprint hitelesítése..." +#define D_TLS_CONNECT_FAILED_TO "TLS Csatlakozás sikertelen a" +#define D_RETRY_IN "Újrapróbálás" +#define D_VERIFIED "Hitelesítve" +#define D_INSECURE "Nem biztonságos kapcsolat érvénytelen Fingerprint miatt" +#define D_CONNECT_FAILED_TO "Sikertelen csatlakozás a" + +// support.ino +#define D_OSWATCH "osWatch" +#define D_BLOCKED_LOOP "Blocked Loop" +#define D_WPS_FAILED_WITH_STATUS "WPSconfig SIKERTELEN státusz:" +#define D_ACTIVE_FOR_3_MINUTES "aktválás 3 percre" +#define D_FAILED_TO_START "sikertelen indítás" +#define D_PATCH_ISSUE_2186 "Patch issue 2186" +#define D_CONNECTING_TO_AP "Csatlakozás az (AP): " +#define D_IN_MODE "be mód" +#define D_CONNECT_FAILED_NO_IP_ADDRESS "Sikertelen csatlakozás, nincs kiosztott IP cím" +#define D_CONNECT_FAILED_AP_NOT_REACHED "Sikertelen csatlakozás, AP nem elérhető" +#define D_CONNECT_FAILED_WRONG_PASSWORD "Sikertelen csatlakozás, hibás AP jelszó" +#define D_CONNECT_FAILED_AP_TIMEOUT "Sikertelen csatlakozás AP időtúllépés miatt" +#define D_ATTEMPTING_CONNECTION "Csatlakozás..." +#define D_CHECKING_CONNECTION "Kapcsolat ellenőrzése..." +#define D_QUERY_DONE "Lekérés kész. MQTT szolgáltatás aktív" +#define D_MQTT_SERVICE_FOUND "élő MQTT szolgáltatás a" +#define D_FOUND_AT "a" +#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host nem található" + +// settings.ino +#define D_SAVED_TO_FLASH_AT "Flash-re mentve a" +#define D_LOADED_FROM_FLASH_AT "Flash-ről betöltve a" +#define D_USE_DEFAULTS "Alapértelmezett beáll. használata" +#define D_ERASED_SECTOR "Szektor törlése" + +// webserver.ino +#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - frissítsd!" +#define D_WEBSERVER_ACTIVE_ON "Web szerver aktív a" +#define D_WITH_IP_ADDRESS "IP címe:" +#define D_WEBSERVER_STOPPED "Webs zerver leállítva" +#define D_FILE_NOT_FOUND "File Nem Található" +#define D_REDIRECTED "Átírányítás captive portálra" +#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager AccessPoint(AP) és Station(ST) beállítása" +#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager AccessPoint(AP) beállítása" +#define D_TRYING_TO_CONNECT "Csatlakozás a hálózatra..." + +#define D_RESTART_IN "Újraindítás..." +#define D_SECONDS "másodperc" +#define D_DEVICE_WILL_RESTART "Az eszköz hamarosan újraindul" +#define D_BUTTON_TOGGLE "Toggle" +#define D_CONFIGURATION "Konfigurációk" +#define D_INFORMATION "Információ" +#define D_FIRMWARE_UPGRADE "Firmware Frissítés" +#define D_CONSOLE "Konzol" +#define D_CONFIRM_RESTART "Újraindítés megerősítése" + +#define D_CONFIGURE_MODULE "Eszköz konfiguráció" +#define D_CONFIGURE_WIFI "WiFi konfiguráció" +#define D_CONFIGURE_MQTT "MQTT konfiguráció" +#define D_CONFIGURE_DOMOTICZ "Domoticz konfiguráció" +#define D_CONFIGURE_LOGGING "Logolás konfiguráció" +#define D_CONFIGURE_OTHER "Egyéb konfiguráció" +#define D_CONFIRM_RESET_CONFIGURATION "Konfig resetelés megerősítve?" +#define D_RESET_CONFIGURATION "Konfiguráció reset" +#define D_BACKUP_CONFIGURATION "Konfiguráció backup" +#define D_RESTORE_CONFIGURATION "Konfiguráció visszaállítás" +#define D_MAIN_MENU "Menü" + +#define D_MODULE_PARAMETERS "Modul paraméterek" +#define D_MODULE_TYPE "Modul típus" +#define D_GPIO "GPIO" +#define D_SERIAL_IN "Serial In" +#define D_SERIAL_OUT "Serial Out" + +#define D_WIFI_PARAMETERS "Wifi paraméterek" +#define D_SCAN_FOR_WIFI_NETWORKS "Wifi hálózat keresése" +#define D_SCAN_DONE "Keresés kész" +#define D_NO_NETWORKS_FOUND "Nincs elérhető hálózat" +#define D_REFRESH_TO_SCAN_AGAIN "Frissíts az újra kereséshez" +#define D_DUPLICATE_ACCESSPOINT "Duplicate AccessPoint" +#define D_SKIPPING_LOW_QUALITY "Kihagyás, alacsony jelminőség" +#define D_RSSI "RSSI" +#define D_WEP "WEP" +#define D_WPA_PSK "WPA PSK" +#define D_WPA2_PSK "WPA2 PSK" +#define D_AP1_SSID "AP1 SSID" +#define D_AP1_PASSWORD "AP1 Jelszó" +#define D_AP2_SSID "AP2 SSID" +#define D_AP2_PASSWORD "AP2 Jelszó" + +#define D_MQTT_PARAMETERS "MQTT paraméterek" +#define D_CLIENT "Kliens" +#define D_FULL_TOPIC "Teljes téma" + +#define D_LOGGING_PARAMETERS "Logolás paraméterek" +#define D_SERIAL_LOG_LEVEL "Serial logolás szint" +#define D_WEB_LOG_LEVEL "Web logolás szint" +#define D_SYS_LOG_LEVEL "Syslog szint" +#define D_MORE_DEBUG "Részletes debug" +#define D_SYSLOG_HOST "Syslog host" +#define D_SYSLOG_PORT "Syslog port" +#define D_TELEMETRY_PERIOD "Telemetria (sec)" + +#define D_OTHER_PARAMETERS "Egyéb paraméterek" +#define D_WEB_ADMIN_PASSWORD "Web Admin Jelszó" +#define D_MQTT_ENABLE "MQTT engedélyezés" +#define D_FRIENDLY_NAME "Név" +#define D_BELKIN_WEMO "Belkin WeMo" +#define D_HUE_BRIDGE "Hue Bridge" +#define D_SINGLE_DEVICE "single device" +#define D_MULTI_DEVICE "multi device" + +#define D_SAVE_CONFIGURATION "Konfiguráció mentése" +#define D_CONFIGURATION_SAVED "Konfiguráció elmentve" +#define D_CONFIGURATION_RESET "Konfiguráció visszaállítása" + +#define D_PROGRAM_VERSION "Program Verzió" +#define D_BUILD_DATE_AND_TIME "Build Dátum & Idő" +#define D_CORE_AND_SDK_VERSION "Core/SDK Verzió" +#define D_FLASH_WRITE_COUNT "Flashelések száma" +#define D_MAC_ADDRESS "MAC Cím" +#define D_MQTT_HOST "MQTT Host" +#define D_MQTT_PORT "MQTT Port" +#define D_MQTT_CLIENT "MQTT Cliens" +#define D_MQTT_USER "MQTT Felhasználó" +#define D_MQTT_TOPIC "MQTT Téma" +#define D_MQTT_GROUP_TOPIC "MQTT Csoport Téma" +#define D_MQTT_FULL_TOPIC "MQTT Teljes téma" +#define D_MDNS_DISCOVERY "mDNS Láthatóság" +#define D_MDNS_ADVERTISE "mDNS Hírdetés" +#define D_ESP_CHIP_ID "ESP Chip Id" +#define D_FLASH_CHIP_ID "Flash Chip Id" +#define D_FLASH_CHIP_SIZE "Flash Méret" +#define D_FREE_PROGRAM_SPACE "Szabad Program Hely" + +#define D_UPGRADE_BY_WEBSERVER "Frissítés web szerverrel" +#define D_OTA_URL "OTA Url" +#define D_START_UPGRADE "Frissítés" +#define D_UPGRADE_BY_FILE_UPLOAD "Frissítés file feltöltéssel" +#define D_UPLOAD_STARTED "Feltöltés elindítva" +#define D_UPGRADE_STARTED "Frissítés elindítva" +#define D_UPLOAD_DONE "Feltöltés kész" +#define D_UPLOAD_ERR_1 "Nincs file kijelölve" +#define D_UPLOAD_ERR_2 "Nincs elég memória" +#define D_UPLOAD_ERR_3 "Magic byte is not 0xE9" +#define D_UPLOAD_ERR_4 "Program flash méret nagyobb a valós flash méretnél" +#define D_UPLOAD_ERR_5 "Feltöltés buffer hiba" +#define D_UPLOAD_ERR_6 "Feltöltés sikertelen. Endegélyezz 3-mas logolást" +#define D_UPLOAD_ERR_7 "Feltöltés megszakítva" +#define D_UPLOAD_ERR_8 "Érvénytelen file" +#define D_UPLOAD_ERR_9 "File túl nagy" +#define D_UPLOAD_ERROR_CODE "Feltöltés hiba kód" + +#define D_ENTER_COMMAND "Parancsolj" +#define D_ENABLE_WEBLOG_FOR_RESPONSE "Engedélyezz 2-es weblogolást több információért" +#define D_NEED_USER_AND_PASSWORD "Kell felhasználó=&jelszó=" + +// xdrv_wemohue.ino +#define D_MULTICAST_DISABLED "Multicast kikapcsolva" +#define D_MULTICAST_REJOINED "Multicast (újra)csatlakozás" +#define D_MULTICAST_JOIN_FAILED "Multicast csatlakozás sikertelen" +#define D_FAILED_TO_SEND_RESPONSE "Nem sikerült választ küldeni" + +#define D_WEMO "WeMo" +#define D_WEMO_BASIC_EVENT "WeMo basic event" +#define D_WEMO_EVENT_SERVICE "WeMo event service" +#define D_WEMO_META_SERVICE "WeMo meta service" +#define D_WEMO_SETUP "WeMo beállítás" +#define D_RESPONSE_SENT "Válasz elküldve" + +#define D_HUE "Hue" +#define D_HUE_BRIDGE_SETUP "Hue beállítás" +#define D_HUE_API_NOT_IMPLEMENTED "Hue API nincs implementálva" +#define D_HUE_API "Hue API" +#define D_HUE_POST_ARGS "Hue POST args" +#define D_3_RESPONSE_PACKETS_SENT "3 válaszcsomagok elküldve" + +// xdrv_05_domoticz.ino +#define D_DOMOTICZ_PARAMETERS "Domoticz paraméterek" +#define D_DOMOTICZ_IDX "Idx" +#define D_DOMOTICZ_KEY_IDX "Key idx" +#define D_DOMOTICZ_SWITCH_IDX "Kapcsoló idx" +#define D_DOMOTICZ_SENSOR_IDX "Szenzor idx" + #define D_DOMOTICZ_TEMP "Temp" + #define D_DOMOTICZ_TEMP_HUM "Hőm,Párat" + #define D_DOMOTICZ_TEMP_HUM_BARO "Hőm,Párat,Légny" + #define D_DOMOTICZ_POWER_ENERGY "Teljesítmény,Energia" + #define D_DOMOTICZ_ILLUMINANCE "Fényerő" + #define D_DOMOTICZ_COUNT "Szám" + #define D_DOMOTICZ_VOLTAGE "Feszültség" + #define D_DOMOTICZ_CURRENT "Áram" + #define D_DOMOTICZ_AIRQUALITY "Légminőség" +#define D_DOMOTICZ_UPDATE_TIMER "Update időzítő" + +// xdrv_03_energy.ino +#define D_ENERGY_TODAY "Mai Energia" +#define D_ENERGY_YESTERDAY "Tegnapi Energia" +#define D_ENERGY_TOTAL "Összes Energia" + +// xsns_05_ds18b20.ino +#define D_SENSOR_BUSY "Szenzor elfoglalt" +#define D_SENSOR_CRC_ERROR "Szenzor CRC hiba" +#define D_SENSORS_FOUND "Szenzorok megtalálva" + +// xsns_06_dht.ino +#define D_TIMEOUT_WAITING_FOR "Timeout waiting for" +#define D_START_SIGNAL_LOW "start signal low" +#define D_START_SIGNAL_HIGH "start signal high" +#define D_PULSE "pulse" +#define D_CHECKSUM_FAILURE "Checksum failure" + +// xsns_07_sht1x.ino +#define D_SENSOR_DID_NOT_ACK_COMMAND "Szenzor nem ismerte el(ACK) a parancsot" +#define D_SHT1X_FOUND "SHT1X found" + +// xsns_18_pms5003.ino +#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter +#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter +#define D_PARTICALS_BEYOND "Részecskék" + +// sonoff_template.h +#define D_SENSOR_NONE "Nincs" +#define D_SENSOR_DHT11 "DHT11" +#define D_SENSOR_AM2301 "AM2301" +#define D_SENSOR_SI7021 "SI7021" +#define D_SENSOR_DS18X20 "DS18x20" +#define D_SENSOR_I2C_SCL "I2C SCL" +#define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_IRSEND "IRadó" +#define D_SENSOR_SWITCH "Kapcsoló" // Suffix "1" +#define D_SENSOR_BUTTON "Gomb" // Suffix "1" +#define D_SENSOR_RELAY "Relé" // Suffix "1i" +#define D_SENSOR_LED "Led" // Suffix "1i" +#define D_SENSOR_PWM "PWM" // Suffix "1" +#define D_SENSOR_COUNTER "Számláló" // Suffix "1" +#define D_SENSOR_IRRECV "IRvevő" +#define D_SENSOR_MHZ_RX "MHZ Rx" +#define D_SENSOR_MHZ_TX "MHZ Tx" +#define D_SENSOR_PZEM_RX "PZEM Rx" +#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_SAIR_RX "SAir Rx" +#define D_SENSOR_SAIR_TX "SAir Tx" +#define D_SENSOR_SPI_CS "SPI CS" +#define D_SENSOR_SPI_DC "SPI DC" +#define D_SENSOR_BACKLIGHT "Háttérvil" +#define D_SENSOR_PMS5003 "PMS5003" + +// Units +#define D_UNIT_AMPERE "A" +#define D_UNIT_HOUR "ó" +#define D_UNIT_KILOOHM "kOhm" +#define D_UNIT_KILOWATTHOUR "kWh" +#define D_UNIT_LUX "lx" +#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3" +#define D_UNIT_MICROMETER "um" +#define D_UNIT_MICROSECOND "µs" +#define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLISECOND "ms" +#define D_UNIT_MINUTE "p" +#define D_UNIT_PARTS_PER_DECILITER "ppd" +#define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PRESSURE "hPa" +#define D_UNIT_SECOND "m" +#define D_UNIT_SECTORS "szektorok" +#define D_UNIT_VOLT "V" +#define D_UNIT_WATT "W" +#define D_UNIT_WATTHOUR "Wh" + +// Log message prefix +#define D_LOG_APPLICATION "APP: " // Application +#define D_LOG_BRIDGE "BRG: " // Bridge +#define D_LOG_CONFIG "CFG: " // Settings +#define D_LOG_COMMAND "CMD: " // Command +#define D_LOG_DEBUG "DBG: " // Debug +#define D_LOG_DHT "DHT: " // DHT sensor +#define D_LOG_DOMOTICZ "DOM: " // Domoticz +#define D_LOG_DSB "DSB: " // DS18xB20 sensor +#define D_LOG_HTTP "HTP: " // HTTP webserver +#define D_LOG_I2C "I2C: " // I2C +#define D_LOG_IRR "IRR: " // Infra Red Received +#define D_LOG_LOG "LOG: " // Logging +#define D_LOG_MODULE "MOD: " // Module +#define D_LOG_MDNS "DNS: " // mDNS +#define D_LOG_MQTT "MQT: " // MQTT +#define D_LOG_OTHER "OTH: " // Other +#define D_LOG_RESULT "RSL: " // Result +#define D_LOG_RFR "RFR: " // RF Received +#define D_LOG_SERIAL "SER: " // Serial +#define D_LOG_SHT1 "SHT: " // SHT1x sensor +#define D_LOG_UPLOAD "UPL: " // Upload +#define D_LOG_UPNP "UPP: " // UPnP +#define D_LOG_WIFI "WIF: " // Wifi + +#endif // _LANGUAGE_EN_GB_H_ diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 97c0bf51f..12496e9a6 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -1,7 +1,7 @@ /* - pl-PL.h - localization for Polish without fonetick - Poland for Sonoff-Tasmota + pl-PL-d.h - localization for Polish with diacritics - Poland for Sonoff-Tasmota - Copyright (C) 2018 Theo Arends (translated by roblad - Robert L.) + Copyright (C) 2018 Theo Arends (translated by roblad - Robert L., upgraded by R. Turala) 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 @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#ifndef _LANGUAGE_PL_PL_H_ -#define _LANGUAGE_PL_PL_H_ +#ifndef _LANGUAGE_PL_PL_D_H_ +#define _LANGUAGE_PL_PL_D_H_ /*************************** ATTENTION *******************************\ * @@ -39,20 +39,20 @@ #define D_HOUR_MINUTE_SEPARATOR ":" #define D_MINUTE_SECOND_SEPARATOR ":" -#define D_DAY3LIST "PonWtoSroCzwPiaSobNie" -#define D_MONTH3LIST "StyLutMarKwiMajCzeLipSieWrzPazLisGru" +#define D_DAY3LIST "PonWtoŚroCzwPiąSobNie" +#define D_MONTH3LIST "StyLutMarKwiMajCzeLipSieWrzPaźLisGru" // Non JSON decimal separator #define D_DECIMAL_SEPARATOR "," // Common #define D_ADMIN "Admin" -#define D_AIR_QUALITY "Jakosc powietrza" +#define D_AIR_QUALITY "Jakość powietrza" #define D_AP "AP" // Access Point #define D_AS "jak" #define D_AUTO "AUTO" #define D_BLINK "Miganie" -#define D_BLINKOFF "MiganieWyl" +#define D_BLINKOFF "MiganieWył" #define D_BOOT_COUNT "Licznik uruchomienia" #define D_BRIGHTLIGHT "Jasny" #define D_BUTTON "Przycisk" @@ -63,10 +63,10 @@ #define D_CODE "kod" // Button code #define D_COLDLIGHT "Zimny" #define D_COMMAND "Komenda" -#define D_CONNECTED "Polaczony" +#define D_CONNECTED "Połączony" #define D_COUNT "Licz" #define D_COUNTER "Licznik" -#define D_CURRENT "Biezacy" // As in Voltage and Current +#define D_CURRENT "Bieżący" // As in Voltage and Current #define D_DATA "Data" #define D_DARKLIGHT "Ciemny" #define D_DEBUG "Debug" @@ -77,46 +77,46 @@ #define D_EMULATION "Emulacja" #define D_ENABLED "Otwarty" #define D_ERASE "Nadpisz" -#define D_ERROR "Blad" +#define D_ERROR "Błąd" #define D_FAHRENHEIT "Fahrenheita" -#define D_FAILED "Bledny" +#define D_FAILED "Błędny" #define D_FALLBACK "Awaryjny" -#define D_FALLBACK_TOPIC "Zastepczy temat" -#define D_FALSE "Falsz" +#define D_FALLBACK_TOPIC "Zastępczy temat" +#define D_FALSE "Fałsz" #define D_FILE "Plik" -#define D_FREE_MEMORY "Wolna pamiec" +#define D_FREE_MEMORY "Wolna pamięć" #define D_GAS "Gas" #define D_GATEWAY "Brama" #define D_GROUP "Grupa" #define D_HOST "Serwer" #define D_HOSTNAME "Nazwa serwera" -#define D_HUMIDITY "Wilgotnosc" -#define D_ILLUMINANCE "Oswietlenie" +#define D_HUMIDITY "Wilgotność" +#define D_ILLUMINANCE "Oświetlenie" #define D_IMMEDIATE "Natychmiastowe" // Button immediate #define D_INDEX "Indeks" #define D_INFO "Informacja" #define D_INITIALIZED "Zainicjowany" #define D_IP_ADDRESS "Adres IP" -#define D_LIGHT "Swiatlo" +#define D_LIGHT "Światło" #define D_LWT "LWT" -#define D_MODULE "Modul" +#define D_MODULE "Moduł" #define D_MQTT "MQTT" -#define D_MULTI_PRESS "wielokrotne-nacisniecie" -#define D_NOISE "Halas" +#define D_MULTI_PRESS "wielokrotne-naciśnięcie" +#define D_NOISE "Hałas" #define D_NONE "Brak" -#define D_OFF "Wylaczony" +#define D_OFF "Wyłączony" #define D_OFFLINE "Nieaktywny" #define D_OK "Ok" -#define D_ON "Wlaczony" +#define D_ON "Włączony" #define D_ONLINE "Aktywny" -#define D_PASSWORD "Haslo" +#define D_PASSWORD "Hasło" #define D_PORT "Port" -#define D_POWER_FACTOR "Wspolczynik mocy" +#define D_POWER_FACTOR "Współczynik mocy" #define D_POWERUSAGE "Moc" -#define D_PRESSURE "Cisnienie" -#define D_PRESSUREATSEALEVEL "Cisnienie na poziomie morza" -#define D_PROGRAM_FLASH_SIZE "Wielkosc programu flash" -#define D_PROGRAM_SIZE "Wielkosc programu" +#define D_PRESSURE "Ciśnienie" +#define D_PRESSUREATSEALEVEL "Ciśnienie na poziomie morza" +#define D_PROGRAM_FLASH_SIZE "Wielkość programu flash" +#define D_PROGRAM_SIZE "Wielkość programu" #define D_PROJECT "Projekt" #define D_RECEIVED "Otrzymany" #define D_RESTART "Restart" @@ -135,18 +135,18 @@ #define D_SUCCESSFUL "Powodzenie" #define D_TEMPERATURE "Temperatura" #define D_TO "do" -#define D_TOGGLE "Przelacz" +#define D_TOGGLE "Przełącz" #define D_TOPIC "Temat" -#define D_TRANSMIT "Wyslij" +#define D_TRANSMIT "Wyślij" #define D_TRUE "Prawda" #define D_UPGRADE "aktualizacji" #define D_UPLOAD "Wgraj" #define D_UPTIME "Uptime" -#define D_USER "Uzytkownik" +#define D_USER "Użytkownik" #define D_UTC_TIME "UTC" #define D_UV_LEVEL "Poziom UV" #define D_VERSION "Wersja" -#define D_VOLTAGE "Napiecie" +#define D_VOLTAGE "Napięcie" #define D_WARMLIGHT "Nagrzanie" #define D_WEB_SERVER "Web Server" @@ -154,82 +154,82 @@ #define D_WARNING_MINIMAL_VERSION "WARNING This version does not support persistent settings" #define D_LEVEL_10 "poziom 1-0" #define D_LEVEL_01 "poziom 0-1" -#define D_SERIAL_LOGGING_DISABLED "Wylaczony dziennik na porcie szeregowym" +#define D_SERIAL_LOGGING_DISABLED "Wyłączony dziennik na porcie szeregowym" #define D_SYSLOG_LOGGING_REENABLED "Wznowiono zapis do Syslog" -#define D_SET_BAUDRATE_TO "Ustaw szybkosc transmisji na" +#define D_SET_BAUDRATE_TO "Ustaw szybkość transmisji na" #define D_RECEIVED_TOPIC "Otrzymany temat" -#define D_DATA_SIZE "Wielkosc danych" +#define D_DATA_SIZE "Wielkość danych" #define D_ANALOG_INPUT "Wej_analogowe" #define D_FINGERPRINT "Weryfikuj odcisk TLS..." -#define D_TLS_CONNECT_FAILED_TO "Nieudane polaczenie TLS do" -#define D_RETRY_IN "Sprobuj ponownie" +#define D_TLS_CONNECT_FAILED_TO "Nieudane połączenie TLS do" +#define D_RETRY_IN "Spróbuj ponownie" #define D_VERIFIED "Zweryfikowano" -#define D_INSECURE "Nieprawidlowe polaczenie z powodu blednego odcisku TLS" -#define D_CONNECT_FAILED_TO "Nie udalo sie nawiazac polaczenia" +#define D_INSECURE "Nieprawidłowe połączenie z powodu błędnego odcisku TLS" +#define D_CONNECT_FAILED_TO "Nie udało się nawiązać połączenia" // support.ino #define D_OSWATCH "osWatch" -#define D_BLOCKED_LOOP "Petla zablokowana" -#define D_WPS_FAILED_WITH_STATUS "Blad WPSconfig ze statusem" +#define D_BLOCKED_LOOP "Pętla zablokowana" +#define D_WPS_FAILED_WITH_STATUS "Błąd WPSconfig ze statusem" #define D_ACTIVE_FOR_3_MINUTES "aktywny 3 minuty" -#define D_FAILED_TO_START "nie udalo sie uruchomic" -#define D_PATCH_ISSUE_2186 "Blad latki 2186" -#define D_CONNECTING_TO_AP "Laczenie z AP" +#define D_FAILED_TO_START "nie udało się uruchomić" +#define D_PATCH_ISSUE_2186 "Błąd łatki 2186" +#define D_CONNECTING_TO_AP "Łączenie z AP" #define D_IN_MODE "w trybie" -#define D_CONNECT_FAILED_NO_IP_ADDRESS "Polaczenie nie powiodlo sie, poniewaz nie otrzymano adresu IP" -#define D_CONNECT_FAILED_AP_NOT_REACHED "Polaczenie nie powiodlo sie jako AP nie mozna osiagnac" -#define D_CONNECT_FAILED_WRONG_PASSWORD "Polaczenie nie powiodlo sie z nieprawidlowym haslem dostepu AP" -#define D_CONNECT_FAILED_AP_TIMEOUT "Nie udalo sie nawiazac polaczenia, limit czasu AP przekroczony" -#define D_ATTEMPTING_CONNECTION "Proba polaczenia..." -#define D_CHECKING_CONNECTION "Sprawdzanie polaczenia..." +#define D_CONNECT_FAILED_NO_IP_ADDRESS "Połączenie nie powiodło sie, ponieważ nie otrzymano adresu IP" +#define D_CONNECT_FAILED_AP_NOT_REACHED "Połączenie nie powiodło sie jako AP nie można osiągnać" +#define D_CONNECT_FAILED_WRONG_PASSWORD "Połączenie nie powiodło sie z nieprawidlowym hasłem dostepu AP" +#define D_CONNECT_FAILED_AP_TIMEOUT "Nie udało się nawiązac połączenia, limit czasu AP przekroczony" +#define D_ATTEMPTING_CONNECTION "Próba połączenia..." +#define D_CHECKING_CONNECTION "Sprawdzanie połączenia..." #define D_QUERY_DONE "Wykonano zapytanie. Znaleziono uslugi MQTT" -#define D_MQTT_SERVICE_FOUND "Usluga MQTT została znaleziona" +#define D_MQTT_SERVICE_FOUND "Usługa MQTT została znaleziona" #define D_FOUND_AT "znalezione w" #define D_SYSLOG_HOST_NOT_FOUND "Syslog Host nie znaleziony" // settings.ino -#define D_SAVED_TO_FLASH_AT "Zapisane do pamieci flash w" -#define D_LOADED_FROM_FLASH_AT "Wczytane z pamieci flash z" -#define D_USE_DEFAULTS "Uzyj domyslnych" +#define D_SAVED_TO_FLASH_AT "Zapisane do pamięci flash w" +#define D_LOADED_FROM_FLASH_AT "Wczytane z pamięci flash z" +#define D_USE_DEFAULTS "Użyj domyślnych" #define D_ERASED_SECTOR "Wymazany sektor" // webserver.ino -#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Oprogramowanie MINIMAL - prosze uaktualnic" +#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Oprogramowanie MINIMAL - proszę uaktualnić" #define D_WEBSERVER_ACTIVE_ON "Aktywny serwer Web" #define D_WITH_IP_ADDRESS "z adresem IP" #define D_WEBSERVER_STOPPED "Serwer Web zatrzymany" #define D_FILE_NOT_FOUND "Plik nie odnaleziony" -#define D_REDIRECTED "Przekierowano do wlasnego portalu" -#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Menedzer Wifi ustawia punkt dostepowy i zachowuje stacje" -#define D_WIFIMANAGER_SET_ACCESSPOINT "Menedzer sieci Wi-Fi Access Point" -#define D_TRYING_TO_CONNECT "Probuje polaczyc urzadzenie z siecia" +#define D_REDIRECTED "Przekierowano do własnego portalu" +#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Menedżer Wifi ustawia punkt dostępowy i zachowuje stacje" +#define D_WIFIMANAGER_SET_ACCESSPOINT "Menedżer sieci Wi-Fi Access Point" +#define D_TRYING_TO_CONNECT "Próbuję połączyć urzadzenie z siecią" #define D_RESTART_IN "Zrestartuj" #define D_SECONDS "sekund" -#define D_DEVICE_WILL_RESTART "Urzadzenie zrestartuje sie za kilka sekund" -#define D_BUTTON_TOGGLE "Przelacznik" +#define D_DEVICE_WILL_RESTART "Urządzenie zrestartuje sie za kilka sekund" +#define D_BUTTON_TOGGLE "Przełącznik" #define D_CONFIGURATION "Konfiguracja" #define D_INFORMATION "Informacje" #define D_FIRMWARE_UPGRADE "Uaktualnienie oprogramowania" #define D_CONSOLE "Konsola" -#define D_CONFIRM_RESTART "Potwierdz restart" +#define D_CONFIRM_RESTART "Potwierdź restart" -#define D_CONFIGURE_MODULE "Konfiguruj modul" +#define D_CONFIGURE_MODULE "Konfiguruj moduł" #define D_CONFIGURE_WIFI "Konfiguruj WiFi" #define D_CONFIGURE_MQTT "Konfiguruj MQTT" #define D_CONFIGURE_DOMOTICZ "Konfiguruj Domoticz" #define D_CONFIGURE_LOGGING "Konfiguruj zapis dziennika" #define D_CONFIGURE_OTHER "Konfiguruj inne" -#define D_CONFIRM_RESET_CONFIGURATION "Potwierdz reset ustawien" -#define D_RESET_CONFIGURATION "Reset ustawien" -#define D_BACKUP_CONFIGURATION "Kopia ustawien" -#define D_RESTORE_CONFIGURATION "Przywrocenie ustawien" -#define D_MAIN_MENU "Menu glowne" +#define D_CONFIRM_RESET_CONFIGURATION "Potwierdź reset ustawień" +#define D_RESET_CONFIGURATION "Reset ustawień" +#define D_BACKUP_CONFIGURATION "Kopia ustawień" +#define D_RESTORE_CONFIGURATION "Przywrócenie ustawień" +#define D_MAIN_MENU "Menu główne" -#define D_MODULE_PARAMETERS "Parametery modulu" -#define D_MODULE_TYPE "Typ modulu" +#define D_MODULE_PARAMETERS "Parametery modułu" +#define D_MODULE_TYPE "Typ modułu" #define D_GPIO "GPIO" #define D_SERIAL_IN "Serial In" #define D_SERIAL_OUT "Serial Out" @@ -238,33 +238,33 @@ #define D_SCAN_FOR_WIFI_NETWORKS "Skanuj sieci WiFi" #define D_SCAN_DONE "Skan wykonany" #define D_NO_NETWORKS_FOUND "Nie znaleziono sieci" -#define D_REFRESH_TO_SCAN_AGAIN "Odswiez aby ponownie zeskanowac" +#define D_REFRESH_TO_SCAN_AGAIN "Odswież aby ponownie zeskanowac" #define D_DUPLICATE_ACCESSPOINT "Kopiuj AP" -#define D_SKIPPING_LOW_QUALITY "Pominieto z powodu niskiej jakości sygnalu" +#define D_SKIPPING_LOW_QUALITY "Pominięto z powodu niskiej jakości sygnału" #define D_RSSI "RSSI" #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" #define D_AP1_SSID "AP1 SSID" -#define D_AP1_PASSWORD "Haslo AP1" +#define D_AP1_PASSWORD "Hasło AP1" #define D_AP2_SSID "AP2 SSID" -#define D_AP2_PASSWORD "Haslo AP2" +#define D_AP2_PASSWORD "Hasło AP2" #define D_MQTT_PARAMETERS "Parametery MQTT" #define D_CLIENT "Klient" -#define D_FULL_TOPIC "Pelen temat" +#define D_FULL_TOPIC "Pełen temat" #define D_LOGGING_PARAMETERS "Opcje dziennika" #define D_SERIAL_LOG_LEVEL "Serial poziom dziennika" #define D_WEB_LOG_LEVEL "Web poziom dziennika" #define D_SYS_LOG_LEVEL "System poziom dziennika" -#define D_MORE_DEBUG "Wiecej informacji debugujacych" +#define D_MORE_DEBUG "Więcej informacji debugujacych" #define D_SYSLOG_HOST "Syslog host" #define D_SYSLOG_PORT "Syslog port" #define D_TELEMETRY_PERIOD "Okres telemetrii" #define D_OTHER_PARAMETERS "Inne parametery" -#define D_WEB_ADMIN_PASSWORD "Haslo administratora Web" +#define D_WEB_ADMIN_PASSWORD "Hasło administratora Web" #define D_MQTT_ENABLE "MQTT aktywne" #define D_FRIENDLY_NAME "Przyjazna nazwa" #define D_BELKIN_WEMO "Belkin WeMo" @@ -277,9 +277,9 @@ #define D_CONFIGURATION_RESET "Ustawienia zresetowane" #define D_PROGRAM_VERSION "Wersja programu" -#define D_BUILD_DATE_AND_TIME "Dzien i godzina kompilacji" +#define D_BUILD_DATE_AND_TIME "Dzień i godzina kompilacji" #define D_CORE_AND_SDK_VERSION "Wersja Core/SDK" -#define D_FLASH_WRITE_COUNT "Liczba zapisow do pamieci" +#define D_FLASH_WRITE_COUNT "Liczba zapisów do pamięci" #define D_MAC_ADDRESS "Adres Mac" #define D_MQTT_HOST "Host MQTT" #define D_MQTT_PORT "Port MQTT" @@ -287,11 +287,11 @@ #define D_MQTT_USER "Uzytkownik MQTT" #define D_MQTT_TOPIC "Temat MQTT" #define D_MQTT_GROUP_TOPIC "Temat grupy MQTT" -#define D_MQTT_FULL_TOPIC "Pelen temat MQTT" +#define D_MQTT_FULL_TOPIC "Pełen temat MQTT" #define D_MDNS_DISCOVERY "Wykrywanie mDNS" -#define D_MDNS_ADVERTISE "Rozglaszanie mDNS" +#define D_MDNS_ADVERTISE "Rozgłaszanie mDNS" #define D_ESP_CHIP_ID "ID ukladu ESP" -#define D_FLASH_CHIP_ID "ID ukladu pamieci flash" +#define D_FLASH_CHIP_ID "ID układu pamięci flash" #define D_FLASH_CHIP_SIZE "Rozmiar flash" #define D_FREE_PROGRAM_SPACE "Wolne miejsce programu" @@ -299,58 +299,58 @@ #define D_OTA_URL "URL OTA" #define D_START_UPGRADE "Start aktualizacji" #define D_UPGRADE_BY_FILE_UPLOAD "Aktualizacja poprzez wgranie pliku" -#define D_UPLOAD_STARTED "Wgrywanie rozpoczete" -#define D_UPGRADE_STARTED "Aktualizacja rozpoczeta" -#define D_UPLOAD_DONE "Wgrywanie zakonczone" +#define D_UPLOAD_STARTED "Wgrywanie rozpoczęte" +#define D_UPGRADE_STARTED "Aktualizacja rozpoczęta" +#define D_UPLOAD_DONE "Wgrywanie zakończone" #define D_UPLOAD_ERR_1 "Nie wybrano pliku" -#define D_UPLOAD_ERR_2 "Niewystarczajaca ilosc miejsca" +#define D_UPLOAD_ERR_2 "Niewystarczająca ilość miejsca" #define D_UPLOAD_ERR_3 "Magiczny bajt jest inny niz 0xE9" -#define D_UPLOAD_ERR_4 "Rozmiar programu jest wiekszy niz rzeczywisty rozmiar pamieci flash" -#define D_UPLOAD_ERR_5 "Wgrywanie, bufor niezgodnosci stanu porownywanych bitow" -#define D_UPLOAD_ERR_6 "Blad wgrywania. Uruchomiono zapis do dziennika na poziomie 3" +#define D_UPLOAD_ERR_4 "Rozmiar programu jest większy niż rzeczywisty rozmiar pamieci flash" +#define D_UPLOAD_ERR_5 "Wgrywanie, bufor niezgodnosci stanu porównywanych bitow" +#define D_UPLOAD_ERR_6 "Błąd wgrywania. Uruchomiono zapis do dziennika na poziomie 3" #define D_UPLOAD_ERR_7 "Wgrywanie przerwane" -#define D_UPLOAD_ERR_8 "Bledny plik" -#define D_UPLOAD_ERR_9 "Plik jest za duzy" -#define D_UPLOAD_ERROR_CODE "Blad wgrywania" +#define D_UPLOAD_ERR_8 "Błędny plik" +#define D_UPLOAD_ERR_9 "Plik jest za duży" +#define D_UPLOAD_ERROR_CODE "Błąd wgrywania" -#define D_ENTER_COMMAND "Wprowadz polecenie" -#define D_ENABLE_WEBLOG_FOR_RESPONSE "Wlacz poziom 2 zapisu Weblog, jesli oczekiwana jest odpowiedz" -#define D_NEED_USER_AND_PASSWORD "Wymagany uzytkownik=&haslo=" +#define D_ENTER_COMMAND "Wprowadź polecenie" +#define D_ENABLE_WEBLOG_FOR_RESPONSE "Włącz poziom 2 zapisu Weblog, jeśli oczekiwana jest odpowiedź" +#define D_NEED_USER_AND_PASSWORD "Wymagany użytkownik=&hasło=" // xdrv_wemohue.ino -#define D_MULTICAST_DISABLED "Multicast jest wylaczony" -#define D_MULTICAST_REJOINED "Multicast (re)dolaczony" -#define D_MULTICAST_JOIN_FAILED "Multicast nie powiodlo sie" -#define D_FAILED_TO_SEND_RESPONSE "Nie udalo sie wyslac odpowiedzi" +#define D_MULTICAST_DISABLED "Multicast jest wyłączony" +#define D_MULTICAST_REJOINED "Multicast (re)dołączony" +#define D_MULTICAST_JOIN_FAILED "Multicast nie powiodło się" +#define D_FAILED_TO_SEND_RESPONSE "Nie udało się wysłać odpowiedzi" #define D_WEMO "WeMo" #define D_WEMO_BASIC_EVENT "WeMo podstawowe zdarzenie" #define D_WEMO_EVENT_SERVICE "WeMo zdarzenie service" #define D_WEMO_META_SERVICE "WeMo meta service" #define D_WEMO_SETUP "WeMo setup" -#define D_RESPONSE_SENT "Odpowiedz wyslana" +#define D_RESPONSE_SENT "Odpowiedź wysłana" #define D_HUE "Hue" #define D_HUE_BRIDGE_SETUP "Hue setup" #define D_HUE_API_NOT_IMPLEMENTED "Hue API nie zaimplementowane" #define D_HUE_API "Hue API" #define D_HUE_POST_ARGS "Hue POST args" -#define D_3_RESPONSE_PACKETS_SENT "3 pakiety odpowiedzi wysylane" +#define D_3_RESPONSE_PACKETS_SENT "3 pakiety odpowiedzi wysyłane" // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Parametry Domoticz" #define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" -#define D_DOMOTICZ_SWITCH_IDX "Przelacznik idx" +#define D_DOMOTICZ_SWITCH_IDX "Przełącznik idx" #define D_DOMOTICZ_SENSOR_IDX "Sensor idx" #define D_DOMOTICZ_TEMP "Temp" #define D_DOMOTICZ_TEMP_HUM "Temp,Wilg" #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Wilg,Cis" #define D_DOMOTICZ_POWER_ENERGY "Moc,Energia" - #define D_DOMOTICZ_ILLUMINANCE "Oswietl." + #define D_DOMOTICZ_ILLUMINANCE "Oświetl." #define D_DOMOTICZ_COUNT "Licznik" - #define D_DOMOTICZ_VOLTAGE "Napiecie" - #define D_DOMOTICZ_CURRENT "Prad" + #define D_DOMOTICZ_VOLTAGE "Napięcie" + #define D_DOMOTICZ_CURRENT "Prąd" #define D_DOMOTICZ_AIRQUALITY "AirQuality" #define D_DOMOTICZ_UPDATE_TIMER "Zaktualizuj czasomierz" @@ -360,8 +360,8 @@ #define D_ENERGY_TOTAL "Energia suma" // xsns_05_ds18b20.ino -#define D_SENSOR_BUSY "Czujnik DS18x20 zajety" -#define D_SENSOR_CRC_ERROR "Czujnik DS18x20 blad CRC" +#define D_SENSOR_BUSY "Czujnik DS18x20 zajęty" +#define D_SENSOR_CRC_ERROR "Czujnik DS18x20 błąd CRC" #define D_SENSORS_FOUND "Znaleziono Czujnik DS18x20" // xsns_06_dht.ino @@ -369,10 +369,10 @@ #define D_START_SIGNAL_LOW "sygnał startowy niski" #define D_START_SIGNAL_HIGH "sygnał startowy wysoki" #define D_PULSE "pulse" -#define D_CHECKSUM_FAILURE "Bledna suma kontrolmna" +#define D_CHECKSUM_FAILURE "Błędna suma kontrolna" // xsns_07_sht1x.ino -#define D_SENSOR_DID_NOT_ACK_COMMAND "Czujnik nie otrzymal komendy ACK" +#define D_SENSOR_DID_NOT_ACK_COMMAND "Czujnik nie otrzymał komendy ACK" #define D_SHT1X_FOUND "SHT1X znaleziony" // xsns_18_pms5003.ino @@ -454,4 +454,4 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi -#endif // _LANGUAGE_PL_PL_H_ +#endif // _LANGUAGE_PL_PL_D_H_ diff --git a/sonoff/settings.h b/sonoff/settings.h index 4fe5f77d5..dab308503 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -291,7 +291,10 @@ struct XDRVMAILBOX { uint16_t valid; uint16_t index; uint16_t data_len; + uint16_t payload16; int16_t payload; + uint8_t grpflg; + uint8_t notused; char *topic; char *data; } XdrvMailbox; diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index a46044910..cfa72ffe6 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -144,7 +144,7 @@ enum LightTypes {LT_BASIC, LT_PWM1, LT_PWM2, LT_PWM3, LT_PWM4, LT_PWM5, LT_PWM6, enum LichtSubtypes {LST_NONE, LST_SINGLE, LST_COLDWARM, LST_RGB, LST_RGBW, LST_RGBWC}; enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX}; -enum XsnsFunctions {FUNC_INIT, FUNC_EVERY_50_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART, +enum XsnsFunctions {FUNC_INIT, FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART, FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR}; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 5a669cff0..973a9fca9 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x050C0003 // 5.12.0c +#define VERSION 0x050C0004 // 5.12.0d // Location specific includes #include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) @@ -36,14 +36,14 @@ #include "sonoff_template.h" // Hardware configuration #include "sonoff_post.h" // Configuration overrides for all previous includes -// Libraries -#include // MQTT - -// Max message size calculated by PubSubClient is (MQTT_MAX_PACKET_SIZE < 5 + 2 + strlen(topic) + plength) -#if (MQTT_MAX_PACKET_SIZE -TOPSZ -7) < MIN_MESSZ // If the max message size is too small, throw an error at compile time. See PubSubClient.cpp line 359 - #error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 1000" +#ifdef ARDUINO_ESP8266_RELEASE_2_4_0 +#include "lwip/init.h" +#if LWIP_VERSION_MAJOR != 1 + #error Please use stable lwIP v1.4 +#endif #endif +// Libraries #include // RTC, Energy, OSWatch #include // MQTT, Ota, WifiManager #include // MQTT, Ota @@ -92,15 +92,6 @@ const char kTasmotaCommands[] PROGMEM = #endif ; -enum MqttCommands { - CMND_MQTTHOST, CMND_MQTTPORT, CMND_MQTTRETRY, CMND_STATETEXT, CMND_MQTTFINGERPRINT, CMND_MQTTCLIENT, - CMND_MQTTUSER, CMND_MQTTPASSWORD, CMND_FULLTOPIC, CMND_PREFIX, CMND_GROUPTOPIC, CMND_TOPIC, - CMND_BUTTONTOPIC, CMND_SWITCHTOPIC, CMND_BUTTONRETAIN, CMND_SWITCHRETAIN, CMND_POWERRETAIN, CMND_SENSORRETAIN }; -const char kMqttCommands[] PROGMEM = - D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTFINGERPRINT "|" D_CMND_MQTTCLIENT "|" - D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" - D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ; - const char kOptionOff[] PROGMEM = "OFF|" D_OFF "|" D_FALSE "|" D_STOP "|" D_CELSIUS ; const char kOptionOn[] PROGMEM = "ON|" D_ON "|" D_TRUE "|" D_START "|" D_FAHRENHEIT "|" D_USER ; const char kOptionToggle[] PROGMEM = "TOGGLE|" D_TOGGLE "|" D_ADMIN ; @@ -115,18 +106,15 @@ int serial_in_byte_counter = 0; // Index in receive buffer byte dual_hex_code = 0; // Sonoff dual input flag uint16_t dual_button_code = 0; // Sonoff dual received code int16_t save_data_counter; // Counter and flag for config save to Flash -uint8_t mqtt_retry_counter = 0; // MQTT connection retry counter uint8_t fallback_topic_flag = 0; // Use Topic or FallbackTopic unsigned long state_loop_timer = 0; // State loop timer int state = 0; // State per second flag -int mqtt_connection_flag = 2; // MQTT connection messages flag int ota_state_flag = 0; // OTA state flag int ota_result = 0; // OTA result byte ota_retry_counter = OTA_ATTEMPTS; // OTA retry counter char *ota_url; // OTA url string int restart_flag = 0; // Sonoff restart flag int wifi_state_flag = WIFI_RESTART; // Wifi state flag -//int uptime = 0; // Current uptime in hours uint32_t uptime = 0; // Counting every second until 4294967295 = 130 year boolean latest_uptime_flag = true; // Signal latest uptime int tele_period = 0; // Tele period timer @@ -154,7 +142,7 @@ uint8_t interlock_mutex = 0; // Interlock power command pending #else WiFiClient EspClient; // Wifi Client #endif -PubSubClient MqttClient(EspClient); // MQTT Client + WiFiUDP PortUdp; // UDP Syslog and Alexa power_t power = 0; // Current copy of Settings.power @@ -372,439 +360,7 @@ void SetLedPower(uint8_t state) /********************************************************************************************/ -void MqttSubscribe(char *topic) -{ - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_SUBSCRIBE_TO " %s"), topic); - AddLog(LOG_LEVEL_DEBUG); - MqttClient.subscribe(topic); - MqttClient.loop(); // Solve LmacRxBlk:1 messages -} - -void MqttPublishDirect(const char* topic, boolean retained) -{ - char sretained[CMDSZ]; - char slog_type[10]; - - sretained[0] = '\0'; - snprintf_P(slog_type, sizeof(slog_type), PSTR(D_LOG_RESULT)); - - if (Settings.flag.mqtt_enabled) { - if (MqttClient.publish(topic, mqtt_data, retained)) { - snprintf_P(slog_type, sizeof(slog_type), PSTR(D_LOG_MQTT)); - if (retained) { - snprintf_P(sretained, sizeof(sretained), PSTR(" (" D_RETAINED ")")); - } - } - } - - snprintf_P(log_data, sizeof(log_data), PSTR("%s%s = %s"), slog_type, (Settings.flag.mqtt_enabled) ? topic : strrchr(topic,'/')+1, mqtt_data); - if (strlen(log_data) >= (sizeof(log_data) - strlen(sretained) -1)) { - log_data[sizeof(log_data) - strlen(sretained) -5] = '\0'; - snprintf_P(log_data, sizeof(log_data), PSTR("%s ..."), log_data); - } - snprintf_P(log_data, sizeof(log_data), PSTR("%s%s"), log_data, sretained); - - AddLog(LOG_LEVEL_INFO); - if (Settings.ledstate &0x04) { - blinks++; - } -} - -void MqttPublish(const char* topic, boolean retained) -{ - char *me; - - if (!strcmp(Settings.mqtt_prefix[0],Settings.mqtt_prefix[1])) { - me = strstr(topic,Settings.mqtt_prefix[0]); - if (me == topic) { - mqtt_cmnd_publish += 8; - } - } - MqttPublishDirect(topic, retained); -} - -void MqttPublish(const char* topic) -{ - MqttPublish(topic, false); -} - -void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic, boolean retained) -{ -/* prefix 0 = cmnd using subtopic - * prefix 1 = stat using subtopic - * prefix 2 = tele using subtopic - * prefix 4 = cmnd using subtopic or RESULT - * prefix 5 = stat using subtopic or RESULT - * prefix 6 = tele using subtopic or RESULT - */ - char romram[33]; - char stopic[TOPSZ]; - - snprintf_P(romram, sizeof(romram), ((prefix > 3) && !Settings.flag.mqtt_response) ? S_RSLT_RESULT : subtopic); - for (byte i = 0; i < strlen(romram); i++) { - romram[i] = toupper(romram[i]); - } - prefix &= 3; - GetTopic_P(stopic, prefix, mqtt_topic, romram); - MqttPublish(stopic, retained); -} - -void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic) -{ - MqttPublishPrefixTopic_P(prefix, subtopic, false); -} - -void MqttPublishPowerState(byte device) -{ - char stopic[TOPSZ]; - char scommand[33]; - - if ((device < 1) || (device > devices_present)) { - device = 1; - } - GetPowerDevice(scommand, device, sizeof(scommand)); - GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(power, device -1))); - MqttPublish(stopic); - - GetTopic_P(stopic, STAT, mqtt_topic, scommand); - snprintf_P(mqtt_data, sizeof(mqtt_data), GetStateText(bitRead(power, device -1))); - MqttPublish(stopic, Settings.flag.mqtt_power_retain); -} - -void MqttPublishPowerBlinkState(byte device) -{ - char scommand[33]; - - if ((device < 1) || (device > devices_present)) { - device = 1; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"" D_JSON_BLINK " %s\"}"), - GetPowerDevice(scommand, device, sizeof(scommand)), GetStateText(bitRead(blink_mask, device -1))); - - MqttPublishPrefixTopic_P(RESULT_OR_STAT, S_RSLT_POWER); -} - -void MqttConnected() -{ - char stopic[TOPSZ]; - - if (Settings.flag.mqtt_enabled) { - - // Satisfy iobroker (#299) - mqtt_data[0] = '\0'; - MqttPublishPrefixTopic_P(CMND, S_RSLT_POWER); - - GetTopic_P(stopic, CMND, mqtt_topic, PSTR("#")); - MqttSubscribe(stopic); - if (strstr(Settings.mqtt_fulltopic, MQTT_TOKEN_TOPIC) != NULL) { - GetTopic_P(stopic, CMND, Settings.mqtt_grptopic, PSTR("#")); - MqttSubscribe(stopic); - fallback_topic_flag = 1; - GetTopic_P(stopic, CMND, mqtt_client, PSTR("#")); - fallback_topic_flag = 0; - MqttSubscribe(stopic); - } - - XdrvCall(FUNC_MQTT_SUBSCRIBE); - } - - if (mqtt_connection_flag) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"%s\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"), - my_module.name, my_version, mqtt_client, Settings.mqtt_grptopic); - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "1")); -#ifdef USE_WEBSERVER - if (Settings.webserver) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"), - (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str()); - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2")); - } -#endif // USE_WEBSERVER - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"), - (GetResetReason() == "Exception") ? ESP.getResetInfo().c_str() : GetResetReason().c_str()); - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3")); - if (Settings.tele_period) { - tele_period = Settings.tele_period -9; - } - status_update_timer = 2; - - XdrvCall(FUNC_MQTT_INIT); - } - mqtt_connection_flag = 0; -} - -void MqttReconnect() -{ - char stopic[TOPSZ]; - - mqtt_retry_counter = Settings.mqtt_retry; - - if (!Settings.flag.mqtt_enabled) { - MqttConnected(); - return; - } -#ifdef USE_EMULATION - UdpDisconnect(); -#endif // USE_EMULATION - if (mqtt_connection_flag > 1) { -#ifdef USE_MQTT_TLS - AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_FINGERPRINT)); - if (!EspClient.connect(Settings.mqtt_host, Settings.mqtt_port)) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_TLS_CONNECT_FAILED_TO " %s:%d. " D_RETRY_IN " %d " D_UNIT_SECOND), - Settings.mqtt_host, Settings.mqtt_port, mqtt_retry_counter); - AddLog(LOG_LEVEL_DEBUG); - return; - } - if (EspClient.verify(Settings.mqtt_fingerprint, Settings.mqtt_host)) { - AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_VERIFIED)); - } else { - AddLog_P(LOG_LEVEL_DEBUG, S_LOG_MQTT, PSTR(D_INSECURE)); - } - EspClient.stop(); - yield(); -#endif // USE_MQTT_TLS - MqttClient.setCallback(MqttDataCallback); - mqtt_connection_flag = 1; - mqtt_retry_counter = 1; - return; - } - - AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_ATTEMPTING_CONNECTION)); -#ifndef USE_MQTT_TLS -#ifdef USE_DISCOVERY -#ifdef MQTT_HOST_DISCOVERY - if (!strlen(Settings.mqtt_host)) { - MdnsDiscoverMqttServer(); - } -#endif // MQTT_HOST_DISCOVERY -#endif // USE_DISCOVERY -#endif // USE_MQTT_TLS - MqttClient.setServer(Settings.mqtt_host, Settings.mqtt_port); - - GetTopic_P(stopic, TELE, mqtt_topic, S_LWT); - snprintf_P(mqtt_data, sizeof(mqtt_data), S_OFFLINE); - - char *mqtt_user = NULL; - char *mqtt_pwd = NULL; - if (strlen(Settings.mqtt_user) > 0) { - mqtt_user = Settings.mqtt_user; - } - if (strlen(Settings.mqtt_pwd) > 0) { - mqtt_pwd = Settings.mqtt_pwd; - } - if (MqttClient.connect(mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, true, mqtt_data)) { - AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_CONNECTED)); - mqtt_retry_counter = 0; - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_ONLINE)); - MqttPublish(stopic, true); - MqttConnected(); - } else { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND), - Settings.mqtt_host, Settings.mqtt_port, MqttClient.state(), mqtt_retry_counter); //status codes are documented here http://pubsubclient.knolleary.net/api.html#state - AddLog(LOG_LEVEL_INFO); - } -} - -/********************************************************************************************/ - -boolean MqttCommand(boolean grpflg, char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, uint16_t payload16) -{ - char command [CMDSZ]; - boolean serviced = true; - char stemp1[TOPSZ]; - char scommand[CMDSZ]; - uint16_t i; - - int command_code = GetCommandCode(command, sizeof(command), type, kMqttCommands); - if (CMND_MQTTHOST == command_code) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_host))) { - strlcpy(Settings.mqtt_host, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host)); - restart_flag = 2; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_host); - } - else if (CMND_MQTTPORT == command_code) { - if (payload16 > 0) { - Settings.mqtt_port = (1 == payload16) ? MQTT_PORT : payload16; - restart_flag = 2; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.mqtt_port); - } - else if (CMND_MQTTRETRY == command_code) { - if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) { - Settings.mqtt_retry = payload; - mqtt_retry_counter = Settings.mqtt_retry; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.mqtt_retry); - } - else if ((CMND_STATETEXT == command_code) && (index > 0) && (index <= 4)) { - if ((data_len > 0) && (data_len < sizeof(Settings.state_text[0]))) { - for(i = 0; i <= data_len; i++) { - if (dataBuf[i] == ' ') { - dataBuf[i] = '_'; - } - } - strlcpy(Settings.state_text[index -1], dataBuf, sizeof(Settings.state_text[0])); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, GetStateText(index -1)); - } -#ifdef USE_MQTT_TLS - else if (CMND_MQTTFINGERPRINT == command_code) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_fingerprint))) { - strlcpy(Settings.mqtt_fingerprint, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_FINGERPRINT : dataBuf, sizeof(Settings.mqtt_fingerprint)); - restart_flag = 2; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_fingerprint); - } -#endif - else if ((CMND_MQTTCLIENT == command_code) && !grpflg) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_client))) { - strlcpy(Settings.mqtt_client, (1 == payload) ? MQTT_CLIENT_ID : dataBuf, sizeof(Settings.mqtt_client)); - restart_flag = 2; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_client); - } - else if (CMND_MQTTUSER == command_code) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_user))) { - strlcpy(Settings.mqtt_user, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_USER : dataBuf, sizeof(Settings.mqtt_user)); - restart_flag = 2; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_user); - } - else if (CMND_MQTTPASSWORD == command_code) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_pwd))) { - strlcpy(Settings.mqtt_pwd, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_PASS : dataBuf, sizeof(Settings.mqtt_pwd)); - restart_flag = 2; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_pwd); - } - else if (CMND_FULLTOPIC == command_code) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_fulltopic))) { - MakeValidMqtt(1, dataBuf); - if (!strcmp(dataBuf, mqtt_client)) { - payload = 1; - } - strlcpy(stemp1, (1 == payload) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1)); - if (strcmp(stemp1, Settings.mqtt_fulltopic)) { - snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : ""); - MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic - strlcpy(Settings.mqtt_fulltopic, stemp1, sizeof(Settings.mqtt_fulltopic)); - restart_flag = 2; - } - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_fulltopic); - } - else if ((CMND_PREFIX == command_code) && (index > 0) && (index <= 3)) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_prefix[0]))) { - MakeValidMqtt(0, dataBuf); - strlcpy(Settings.mqtt_prefix[index -1], (1 == payload) ? (1==index)?SUB_PREFIX:(2==index)?PUB_PREFIX:PUB_PREFIX2 : dataBuf, sizeof(Settings.mqtt_prefix[0])); -// if (Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] == '/') Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] = 0; - restart_flag = 2; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mqtt_prefix[index -1]); - } - else if (CMND_GROUPTOPIC == command_code) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_grptopic))) { - MakeValidMqtt(0, dataBuf); - if (!strcmp(dataBuf, mqtt_client)) { - payload = 1; - } - strlcpy(Settings.mqtt_grptopic, (1 == payload) ? MQTT_GRPTOPIC : dataBuf, sizeof(Settings.mqtt_grptopic)); - restart_flag = 2; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_grptopic); - } - else if ((CMND_TOPIC == command_code) && !grpflg) { - if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_topic))) { - MakeValidMqtt(0, dataBuf); - if (!strcmp(dataBuf, mqtt_client)) { - payload = 1; - } - strlcpy(stemp1, (1 == payload) ? MQTT_TOPIC : dataBuf, sizeof(stemp1)); - if (strcmp(stemp1, Settings.mqtt_topic)) { - snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : ""); - MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic - strlcpy(Settings.mqtt_topic, stemp1, sizeof(Settings.mqtt_topic)); - restart_flag = 2; - } - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_topic); - } - else if ((CMND_BUTTONTOPIC == command_code) && !grpflg) { - if ((data_len > 0) && (data_len < sizeof(Settings.button_topic))) { - MakeValidMqtt(0, dataBuf); - if (!strcmp(dataBuf, mqtt_client)) { - payload = 1; - } - strlcpy(Settings.button_topic, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? mqtt_topic : dataBuf, sizeof(Settings.button_topic)); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.button_topic); - } - else if (CMND_SWITCHTOPIC == command_code) { - if ((data_len > 0) && (data_len < sizeof(Settings.switch_topic))) { - MakeValidMqtt(0, dataBuf); - if (!strcmp(dataBuf, mqtt_client)) { - payload = 1; - } - strlcpy(Settings.switch_topic, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? mqtt_topic : dataBuf, sizeof(Settings.switch_topic)); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.switch_topic); - } - else if (CMND_BUTTONRETAIN == command_code) { - if ((payload >= 0) && (payload <= 1)) { - strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); - if (!payload) { - for(i = 1; i <= MAX_KEYS; i++) { - send_button_power(0, i, 9); // Clear MQTT retain in broker - } - } - Settings.flag.mqtt_button_retain = payload; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_button_retain)); - } - else if (CMND_SWITCHRETAIN == command_code) { - if ((payload >= 0) && (payload <= 1)) { - strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); - if (!payload) { - for(i = 1; i <= MAX_SWITCHES; i++) { - send_button_power(1, i, 9); // Clear MQTT retain in broker - } - } - Settings.flag.mqtt_switch_retain = payload; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_switch_retain)); - } - else if (CMND_POWERRETAIN == command_code) { - if ((payload >= 0) && (payload <= 1)) { - if (!payload) { - for(i = 1; i <= devices_present; i++) { // Clear MQTT retain in broker - GetTopic_P(stemp1, STAT, mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand))); - mqtt_data[0] = '\0'; - MqttPublish(stemp1, Settings.flag.mqtt_power_retain); - } - } - Settings.flag.mqtt_power_retain = payload; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_power_retain)); - } - else if (CMND_SENSORRETAIN == command_code) { - if ((payload >= 0) && (payload <= 1)) { - if (!payload) { - mqtt_data[0] = '\0'; - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain); - } - Settings.flag.mqtt_sensor_retain = payload; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain)); - } - else serviced = false; - return serviced; -} - -/********************************************************************************************/ - -void MqttDataCallback(char* topic, byte* data, unsigned int data_len) +void MqttDataHandler(char* topic, byte* data, unsigned int data_len) { char *str; @@ -829,8 +385,8 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len) byte ptype = 0; byte jsflg = 0; byte lines = 1; + uint8_t grpflg = 0; uint16_t i = 0; - uint16_t grpflg = 0; uint16_t index; uint32_t address; @@ -849,9 +405,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len) AddLog(LOG_LEVEL_DEBUG_MORE); // if (LOG_LEVEL_DEBUG_MORE <= seriallog_level) Serial.println(dataBuf); - if (XdrvMqttData(topicBuf, sizeof(topicBuf), dataBuf, sizeof(dataBuf))) { - return; - } + if (XdrvMqttData(topicBuf, sizeof(topicBuf), dataBuf, sizeof(dataBuf))) return; grpflg = (strstr(topicBuf, Settings.mqtt_grptopic) != NULL); fallback_topic_flag = (strstr(topicBuf, mqtt_client) != NULL); @@ -1530,10 +1084,10 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len) I2cScan(mqtt_data, sizeof(mqtt_data)); } #endif // USE_I2C - else if (Settings.flag.mqtt_enabled && MqttCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) { +// else if (Settings.flag.mqtt_enabled && MqttCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) { // Serviced - } - else if (XdrvCommand(type, index, dataBuf, data_len, payload)) { +// } + else if (XdrvCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) { // Serviced } #ifdef DEBUG_THEO @@ -1577,7 +1131,7 @@ boolean send_button_power(byte key, byte device, byte state) boolean result = false; char *key_topic = (key) ? Settings.switch_topic : Settings.button_topic; - if (Settings.flag.mqtt_enabled && MqttClient.connected() && (strlen(key_topic) != 0) && strcmp(key_topic, "0")) { + if (Settings.flag.mqtt_enabled && MqttIsConnected() && (strlen(key_topic) != 0) && strcmp(key_topic, "0")) { if (!key && (device > devices_present)) { device = 1; } @@ -1717,7 +1271,7 @@ void ExecuteCommand(char *cmnd) token = strtok(NULL, ""); // snprintf_P(svalue, sizeof(svalue), (token == NULL) ? "" : token); // Fails with command FullTopic home/%prefix%/%topic% as it processes %p of %prefix% strlcpy(svalue, (token == NULL) ? "" : token, sizeof(svalue)); // Fixed 5.8.0b - MqttDataCallback(stopic, (byte*)svalue, strlen(svalue)); + MqttDataHandler(stopic, (byte*)svalue, strlen(svalue)); } void PublishStatus(uint8_t payload) @@ -2394,23 +1948,6 @@ void StateLoop() WifiCheck(wifi_state_flag); wifi_state_flag = WIFI_RESTART; break; - case (STATES/10)*8: - if (WL_CONNECTED == WiFi.status()) { - if (Settings.flag.mqtt_enabled) { - if (!MqttClient.connected()) { - if (!mqtt_retry_counter) { - MqttReconnect(); - } else { - mqtt_retry_counter--; - } - } - } else { - if (!mqtt_retry_counter) { - MqttReconnect(); - } - } - } - break; } } @@ -2814,6 +2351,8 @@ void setup() void loop() { + XdrvCall(FUNC_LOOP); + OsWatchLoop(); #ifdef USE_WEBSERVER @@ -2821,20 +2360,12 @@ void loop() #endif // USE_WEBSERVER #ifdef USE_EMULATION - if (Settings.flag2.emulation) { - PollUdp(); - } + if (Settings.flag2.emulation) PollUdp(); #endif // USE_EMULATION - if (millis() >= state_loop_timer) { - StateLoop(); - } - if (Settings.flag.mqtt_enabled) { - MqttClient.loop(); - } - if (Serial.available()){ - SerialInput(); - } + if (millis() >= state_loop_timer) StateLoop(); + + if (Serial.available()) SerialInput(); // yield(); // yield == delay(0), delay contains yield, auto yield in loop delay(sleep); // https://github.com/esp8266/Arduino/issues/2021 diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index 63d5e3c63..d7b55030a 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -152,6 +152,13 @@ void WifiWpsStatusCallback(wps_cb_status status); #define WS2812_LEDS 30 // [Pixels] Number of LEDs #endif +#ifndef MQTT_MAX_PACKET_SIZE +#define MQTT_MAX_PACKET_SIZE 1000 +#endif +#ifndef MQTT_KEEPALIVE +#define MQTT_KEEPALIVE 15 +#endif + #ifndef MESSZ //#define MESSZ 405 // Max number of characters in JSON message string (6 x DS18x20 sensors) //#define MESSZ 893 // Max number of characters in JSON message string (Hass discovery and nice MQTT_MAX_PACKET_SIZE = 1000) diff --git a/sonoff/user_config.h b/sonoff/user_config.h index de117b2fe..dc2c947cd 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -33,6 +33,7 @@ //#define MY_LANGUAGE en-GB // English in Great Britain. Enabled by Default //#define MY_LANGUAGE es-AR // Spanish in Argentina //#define MY_LANGUAGE fr-FR // French in France +//#define MY_LANGUAGE hu-HU // Hungarian in Hungary //#define MY_LANGUAGE it-IT // Italian in Italy //#define MY_LANGUAGE nl-NL // Dutch in the Netherlands //#define MY_LANGUAGE pl-PL // Polish in Poland @@ -73,7 +74,7 @@ // -- MQTT ---------------------------------------- #define MQTT_USE 1 // [SetOption3] Select default MQTT use (0 = Off, 1 = On) // !!! TLS uses a LOT OF MEMORY (20k) so be careful to enable other options at the same time !!! -//#define USE_MQTT_TLS // EXPERIMENTAL Use TLS for MQTT connection (+53k code, +20k mem) - Disable by // +//#define USE_MQTT_TLS // EXPERIMENTAL Use TLS for MQTT connection (+53k code, +15k mem) - Disable by // // Needs Fingerprint, TLS Port, UserId and Password #ifdef USE_MQTT_TLS // #define MQTT_HOST "m20.cloudmqtt.com" // [MqttHost] diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index 87766e73d..fb248a2a7 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -1262,7 +1262,7 @@ void HandleUploadDone() WifiConfigCounter(); restart_flag = 0; - mqtt_retry_counter = 0; + MqttRetryCounter(0); String page = FPSTR(HTTP_HEAD); page.replace(F("{v}"), FPSTR(S_INFORMATION)); @@ -1324,16 +1324,14 @@ void HandleUploadLoop() snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str()); AddLog(LOG_LEVEL_INFO); if (!upload_file_type) { - mqtt_retry_counter = 60; + MqttRetryCounter(60); #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION #ifdef USE_ARILUX_RF AriluxRfDisable(); // Prevent restart exception on Arilux Interrupt routine #endif // USE_ARILUX_RF - if (Settings.flag.mqtt_enabled) { - MqttClient.disconnect(); - } + if (Settings.flag.mqtt_enabled) MqttDisconnect(); uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; if (!Update.begin(maxSketchSpace)) { //start with max available size upload_error = 2; @@ -1409,7 +1407,7 @@ void HandleUploadLoop() } } else if (UPLOAD_FILE_ABORTED == upload.status) { restart_flag = 0; - mqtt_retry_counter = 0; + MqttRetryCounter(0); upload_error = 7; if (!upload_file_type) { Update.end(); diff --git a/sonoff/xdrv_00_mqtt.ino b/sonoff/xdrv_00_mqtt.ino new file mode 100644 index 000000000..670dcfe5e --- /dev/null +++ b/sonoff/xdrv_00_mqtt.ino @@ -0,0 +1,730 @@ +/* + xdrv_00_mqtt.ino - mqtt support for Sonoff-Tasmota + + Copyright (C) 2018 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 . +*/ + +/*********************************************************************************************\ + * Select only ONE of the defines below - Not supported yet +\*********************************************************************************************/ + +// Default MQTT driver for both non-TLS and TLS connections. Blocks network if MQTT server is unavailable. +#define USE_MQTT_CLIENT 1 // Use PubSubClient library + +// Replaces PubSubClient solving network hangs when MQTT server is unavailable. No TLS support +//#define USE_MQTT_CLIENT 2 // Use (patched) esp-mqtt-arduino library (+4k8 code) - non-TLS only + +// Only TLS support. Unstable due to lack of memory +//#define USE_MQTT_CLIENT 3 // Use ESP8266MQTTClient library (+52k code, +15k mem) - TLS only and unstable + +/*********************************************************************************************/ + +enum MqttCommands { + CMND_MQTTHOST, CMND_MQTTPORT, CMND_MQTTRETRY, CMND_STATETEXT, CMND_MQTTFINGERPRINT, CMND_MQTTCLIENT, + CMND_MQTTUSER, CMND_MQTTPASSWORD, CMND_FULLTOPIC, CMND_PREFIX, CMND_GROUPTOPIC, CMND_TOPIC, + CMND_BUTTONTOPIC, CMND_SWITCHTOPIC, CMND_BUTTONRETAIN, CMND_SWITCHRETAIN, CMND_POWERRETAIN, CMND_SENSORRETAIN }; +const char kMqttCommands[] PROGMEM = + D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTFINGERPRINT "|" D_CMND_MQTTCLIENT "|" + D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" + D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ; + +uint8_t mqtt_retry_counter = 0; // MQTT connection retry counter +uint8_t mqtt_connection_flag = 2; // MQTT connection messages flag + +/*********************************************************************************************\ + * MQTT driver specific code need to provide the following functions: + * + * bool MqttIsConnected() + * void MqttDisconnect() + * void MqttSubscribeLib(char *topic) + * bool MqttPublishLib(const char* topic, boolean retained) + * void MqttCheckConnection() + * void MqttLoop() +\*********************************************************************************************/ + +#if (1 == USE_MQTT_CLIENT) /*****************************************************************/ + +#include + +// Max message size calculated by PubSubClient is (MQTT_MAX_PACKET_SIZE < 5 + 2 + strlen(topic) + plength) +#if (MQTT_MAX_PACKET_SIZE -TOPSZ -7) < MIN_MESSZ // If the max message size is too small, throw an error at compile time. See PubSubClient.cpp line 359 + #error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 1000" +#endif + +PubSubClient MqttClient(EspClient); + +bool MqttIsConnected() +{ + return MqttClient.connected(); +} + +void MqttDisconnect() +{ + MqttClient.disconnect(); +} + +void MqttSubscribeLib(char *topic) +{ + MqttClient.subscribe(topic); + MqttClient.loop(); // Solve LmacRxBlk:1 messages +} + +bool MqttPublishLib(const char* topic, boolean retained) +{ + return MqttClient.publish(topic, mqtt_data, retained); +} + +void MqttCheckConnection() +{ + if (Settings.flag.mqtt_enabled) { + if (!MqttIsConnected()) { + if (!mqtt_retry_counter) { + MqttReconnect(); + } else { + mqtt_retry_counter--; + } + } + } else { + if (!mqtt_retry_counter) { + MqttReconnect(); + } + } +} + +void MqttLoop() +{ + MqttClient.loop(); +} + +#elif (2 == USE_MQTT_CLIENT) /***************************************************************/ + +#include +MQTT *MqttClient = NULL; + +bool MqttIsConnected() +{ + bool result = false; + if (MqttClient) result = (MqttClient->isConnected() && !mqtt_retry_counter); + return result; +} + +void MqttDisconnect() +{ + if (MqttClient) MqttClient->disconnect(); +} + +void MqttMyDataCb(const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) +{ + char topicCpy[topic_len]; + memcpy(topicCpy, topic, topic_len); + topicCpy[topic_len] = 0; + MqttDataHandler((char*)topicCpy, (byte*)data, data_len); +} + +void MqttMyNoneCb() +{ + // Do nothing +} + +void MqttSubscribeLib(char *topic) +{ + MqttClient->subscribe(topic); +} + +bool MqttPublishLib(const char* topic, boolean retained) +{ + return MqttClient->publish(topic, mqtt_data, strlen(mqtt_data), 0, retained); +} + +void MqttCheckConnection() +{ + if (Settings.flag.mqtt_enabled) { + if (!MqttIsConnected()) { + if (!mqtt_retry_counter) { + MqttReconnect(); + } else { + mqtt_retry_counter--; + } + } + MqttReconnect(); + } else { + if (!mqtt_retry_counter) { + MqttReconnect(); + } + } +} + +void MqttLoop() +{ + // No action +} + +#elif (3 == USE_MQTT_CLIENT) /***************************************************************/ + +#include +MQTTClient MqttClient; + +bool MqttIsConnected() +{ + return true; +} + +void MqttDisconnect() +{ + // No action +} + +void MqttSubscribeLib(char *topic) +{ + MqttClient.subscribe(topic, 0); +} + +bool MqttPublishLib(const char* topic, boolean retained) +{ + return MqttClient.publish(topic, mqtt_data, 0, retained); +} + +void MqttCheckConnection() +{ + if (Settings.flag.mqtt_enabled) { + MqttReconnect(); + } else { + if (!mqtt_retry_counter) { + MqttReconnect(); + } + } +} + +void MqttLoop() +{ + MqttClient.handle(); +} + +#endif // USE_MQTT_CLIENT + +/*********************************************************************************************/ + +void MqttRetryCounter(uint8_t value) +{ + mqtt_retry_counter = value; +} + +void MqttSubscribe(char *topic) +{ + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_SUBSCRIBE_TO " %s"), topic); + AddLog(LOG_LEVEL_DEBUG); + MqttSubscribeLib(topic); +} + +void MqttPublishDirect(const char* topic, boolean retained) +{ + char sretained[CMDSZ]; + char slog_type[10]; + + sretained[0] = '\0'; + snprintf_P(slog_type, sizeof(slog_type), PSTR(D_LOG_RESULT)); + + if (Settings.flag.mqtt_enabled) { + if (MqttPublishLib(topic, retained)) { + snprintf_P(slog_type, sizeof(slog_type), PSTR(D_LOG_MQTT)); + if (retained) { + snprintf_P(sretained, sizeof(sretained), PSTR(" (" D_RETAINED ")")); + } + } + } + + snprintf_P(log_data, sizeof(log_data), PSTR("%s%s = %s"), slog_type, (Settings.flag.mqtt_enabled) ? topic : strrchr(topic,'/')+1, mqtt_data); + if (strlen(log_data) >= (sizeof(log_data) - strlen(sretained) -1)) { + log_data[sizeof(log_data) - strlen(sretained) -5] = '\0'; + snprintf_P(log_data, sizeof(log_data), PSTR("%s ..."), log_data); + } + snprintf_P(log_data, sizeof(log_data), PSTR("%s%s"), log_data, sretained); + + AddLog(LOG_LEVEL_INFO); + if (Settings.ledstate &0x04) { + blinks++; + } +} + +void MqttPublish(const char* topic, boolean retained) +{ + char *me; + + if (!strcmp(Settings.mqtt_prefix[0],Settings.mqtt_prefix[1])) { + me = strstr(topic,Settings.mqtt_prefix[0]); + if (me == topic) { + mqtt_cmnd_publish += 8; + } + } + MqttPublishDirect(topic, retained); +} + +void MqttPublish(const char* topic) +{ + MqttPublish(topic, false); +} + +void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic, boolean retained) +{ +/* prefix 0 = cmnd using subtopic + * prefix 1 = stat using subtopic + * prefix 2 = tele using subtopic + * prefix 4 = cmnd using subtopic or RESULT + * prefix 5 = stat using subtopic or RESULT + * prefix 6 = tele using subtopic or RESULT + */ + char romram[33]; + char stopic[TOPSZ]; + + snprintf_P(romram, sizeof(romram), ((prefix > 3) && !Settings.flag.mqtt_response) ? S_RSLT_RESULT : subtopic); + for (byte i = 0; i < strlen(romram); i++) { + romram[i] = toupper(romram[i]); + } + prefix &= 3; + GetTopic_P(stopic, prefix, mqtt_topic, romram); + MqttPublish(stopic, retained); +} + +void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic) +{ + MqttPublishPrefixTopic_P(prefix, subtopic, false); +} + +void MqttPublishPowerState(byte device) +{ + char stopic[TOPSZ]; + char scommand[33]; + + if ((device < 1) || (device > devices_present)) { + device = 1; + } + GetPowerDevice(scommand, device, sizeof(scommand)); + GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(power, device -1))); + MqttPublish(stopic); + + GetTopic_P(stopic, STAT, mqtt_topic, scommand); + snprintf_P(mqtt_data, sizeof(mqtt_data), GetStateText(bitRead(power, device -1))); + MqttPublish(stopic, Settings.flag.mqtt_power_retain); +} + +void MqttPublishPowerBlinkState(byte device) +{ + char scommand[33]; + + if ((device < 1) || (device > devices_present)) { + device = 1; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"" D_JSON_BLINK " %s\"}"), + GetPowerDevice(scommand, device, sizeof(scommand)), GetStateText(bitRead(blink_mask, device -1))); + + MqttPublishPrefixTopic_P(RESULT_OR_STAT, S_RSLT_POWER); +} + +/*********************************************************************************************/ + +void MqttConnected() +{ + char stopic[TOPSZ]; + + if (Settings.flag.mqtt_enabled) { + + // Satisfy iobroker (#299) + mqtt_data[0] = '\0'; + MqttPublishPrefixTopic_P(CMND, S_RSLT_POWER); + + GetTopic_P(stopic, CMND, mqtt_topic, PSTR("#")); + MqttSubscribe(stopic); + if (strstr(Settings.mqtt_fulltopic, MQTT_TOKEN_TOPIC) != NULL) { + GetTopic_P(stopic, CMND, Settings.mqtt_grptopic, PSTR("#")); + MqttSubscribe(stopic); + fallback_topic_flag = 1; + GetTopic_P(stopic, CMND, mqtt_client, PSTR("#")); + fallback_topic_flag = 0; + MqttSubscribe(stopic); + } + + XdrvCall(FUNC_MQTT_SUBSCRIBE); + } + + if (mqtt_connection_flag) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"%s\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"), + my_module.name, my_version, mqtt_client, Settings.mqtt_grptopic); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "1")); +#ifdef USE_WEBSERVER + if (Settings.webserver) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"), + (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str()); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2")); + } +#endif // USE_WEBSERVER + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"), + (GetResetReason() == "Exception") ? ESP.getResetInfo().c_str() : GetResetReason().c_str()); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3")); + if (Settings.tele_period) { + tele_period = Settings.tele_period -9; + } + status_update_timer = 2; + + XdrvCall(FUNC_MQTT_INIT); + } + mqtt_connection_flag = 0; +} + +void MqttReconnect() +{ + char stopic[TOPSZ]; + + mqtt_retry_counter = Settings.mqtt_retry; + + if (!Settings.flag.mqtt_enabled) { + MqttConnected(); + return; + } +#ifdef USE_EMULATION + UdpDisconnect(); +#endif // USE_EMULATION + if (mqtt_connection_flag > 1) { // Executed once just after power on and wifi is connected - Initial TLS check +#ifdef USE_MQTT_TLS + AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_FINGERPRINT)); + if (!EspClient.connect(Settings.mqtt_host, Settings.mqtt_port)) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_TLS_CONNECT_FAILED_TO " %s:%d. " D_RETRY_IN " %d " D_UNIT_SECOND), + Settings.mqtt_host, Settings.mqtt_port, mqtt_retry_counter); + AddLog(LOG_LEVEL_DEBUG); + EspClient.stop(); + return; + } + if (EspClient.verify(Settings.mqtt_fingerprint, Settings.mqtt_host)) { + AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_VERIFIED)); + } else { + AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_INSECURE)); + EspClient.stop(); + return; + } + EspClient.stop(); + yield(); +#endif // USE_MQTT_TLS + mqtt_connection_flag = 1; +// mqtt_retry_counter = 1; +// return; + } + + AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_ATTEMPTING_CONNECTION)); +#ifndef USE_MQTT_TLS +#ifdef USE_DISCOVERY +#ifdef MQTT_HOST_DISCOVERY + if (!strlen(Settings.mqtt_host)) { + MdnsDiscoverMqttServer(); + } +#endif // MQTT_HOST_DISCOVERY +#endif // USE_DISCOVERY +#endif // USE_MQTT_TLS + + char *mqtt_user = NULL; + char *mqtt_pwd = NULL; + if (strlen(Settings.mqtt_user) > 0) mqtt_user = Settings.mqtt_user; + if (strlen(Settings.mqtt_pwd) > 0) mqtt_pwd = Settings.mqtt_pwd; + + GetTopic_P(stopic, TELE, mqtt_topic, S_LWT); + snprintf_P(mqtt_data, sizeof(mqtt_data), S_OFFLINE); + +#if (1 == USE_MQTT_CLIENT) + MqttClient.setCallback(MqttDataHandler); + MqttClient.setServer(Settings.mqtt_host, Settings.mqtt_port); + if (MqttClient.connect(mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, true, mqtt_data)) { + AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_CONNECTED)); + mqtt_retry_counter = 0; + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_ONLINE)); + MqttPublish(stopic, true); + MqttConnected(); + } else { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND), + Settings.mqtt_host, Settings.mqtt_port, MqttClient.state(), mqtt_retry_counter); //status codes are documented here http://pubsubclient.knolleary.net/api.html#state + AddLog(LOG_LEVEL_INFO); + } +#elif (2 == USE_MQTT_CLIENT) + if (!MqttClient) { + MqttClient = new MQTT(mqtt_client, Settings.mqtt_host, Settings.mqtt_port, stopic, 1, true, mqtt_data); +// MqttClient->onConnected(MqttMyNoneCb); +// MqttClient->onDisconnected(MqttMyNoneCb); +// MqttClient->onPublished(MqttMyNoneCb); + MqttClient->onData(MqttMyDataCb); + MqttClient->setUserPwd(mqtt_user, mqtt_pwd); + } + MqttClient->connect(); + uint16_t mqtt_timeout = 50; + while (!MqttClient->isConnected() && mqtt_timeout--) delay(1); + if (MqttClient->isConnected()) { + AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_CONNECTED)); + mqtt_retry_counter = 0; + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_ONLINE)); + MqttPublish(stopic, true); + MqttConnected(); + } else { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d. " D_RETRY_IN " %d " D_UNIT_SECOND), + Settings.mqtt_host, Settings.mqtt_port, mqtt_retry_counter); + AddLog(LOG_LEVEL_INFO); + } +#elif (3 == USE_MQTT_CLIENT) + //topic, data, data is continuing + MqttClient.onData([](String topic, String data, bool cont) { + MqttDataHandler((char*)topic.c_str(), (byte*)data.c_str(), strlen(data.c_str())); + }); + char uri[200]; + snprintf_P(uri, sizeof(uri), PSTR("mqtt://%s:%s@%s:%d#%s"), mqtt_user, mqtt_pwd, Settings.mqtt_host, Settings.mqtt_port, mqtt_client); + + if (MqttClient.begin(String(uri), {.lwtTopic = stopic, .lwtMsg = mqtt_data, .lwtQos = 1, .lwtRetain = 1}, MQTT_KEEPALIVE, true)) { + AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_CONNECTED)); + mqtt_retry_counter = 0; + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_ONLINE)); + MqttPublish(stopic, true); + MqttConnected(); + } else { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d. " D_RETRY_IN " %d " D_UNIT_SECOND), + Settings.mqtt_host, Settings.mqtt_port, mqtt_retry_counter); //status codes are documented here http://pubsubclient.knolleary.net/api.html#state + AddLog(LOG_LEVEL_INFO); + } +#endif // USE_MQTT_CLIENT +} + +/*********************************************************************************************/ + +bool MqttCommand() +{ + char command [CMDSZ]; + bool serviced = true; + char stemp1[TOPSZ]; + char scommand[CMDSZ]; + uint16_t i; + + uint16_t index = XdrvMailbox.index; + uint16_t data_len = XdrvMailbox.data_len; + uint16_t payload16 = XdrvMailbox.payload16; + int16_t payload = XdrvMailbox.payload; + uint8_t grpflg = XdrvMailbox.grpflg; + char *type = XdrvMailbox.topic; + char *dataBuf = XdrvMailbox.data; + + int command_code = GetCommandCode(command, sizeof(command), type, kMqttCommands); + if (CMND_MQTTHOST == command_code) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_host))) { + strlcpy(Settings.mqtt_host, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host)); + restart_flag = 2; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_host); + } + else if (CMND_MQTTPORT == command_code) { + if (payload16 > 0) { + Settings.mqtt_port = (1 == payload16) ? MQTT_PORT : payload16; + restart_flag = 2; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.mqtt_port); + } + else if (CMND_MQTTRETRY == command_code) { + if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) { + Settings.mqtt_retry = payload; + mqtt_retry_counter = Settings.mqtt_retry; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.mqtt_retry); + } + else if ((CMND_STATETEXT == command_code) && (index > 0) && (index <= 4)) { + if ((data_len > 0) && (data_len < sizeof(Settings.state_text[0]))) { + for(i = 0; i <= data_len; i++) { + if (dataBuf[i] == ' ') { + dataBuf[i] = '_'; + } + } + strlcpy(Settings.state_text[index -1], dataBuf, sizeof(Settings.state_text[0])); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, GetStateText(index -1)); + } +#ifdef USE_MQTT_TLS + else if (CMND_MQTTFINGERPRINT == command_code) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_fingerprint))) { + strlcpy(Settings.mqtt_fingerprint, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_FINGERPRINT : dataBuf, sizeof(Settings.mqtt_fingerprint)); + restart_flag = 2; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_fingerprint); + } +#endif + else if ((CMND_MQTTCLIENT == command_code) && !grpflg) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_client))) { + strlcpy(Settings.mqtt_client, (1 == payload) ? MQTT_CLIENT_ID : dataBuf, sizeof(Settings.mqtt_client)); + restart_flag = 2; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_client); + } + else if (CMND_MQTTUSER == command_code) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_user))) { + strlcpy(Settings.mqtt_user, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_USER : dataBuf, sizeof(Settings.mqtt_user)); + restart_flag = 2; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_user); + } + else if (CMND_MQTTPASSWORD == command_code) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_pwd))) { + strlcpy(Settings.mqtt_pwd, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_PASS : dataBuf, sizeof(Settings.mqtt_pwd)); + restart_flag = 2; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_pwd); + } + else if (CMND_FULLTOPIC == command_code) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_fulltopic))) { + MakeValidMqtt(1, dataBuf); + if (!strcmp(dataBuf, mqtt_client)) { + payload = 1; + } + strlcpy(stemp1, (1 == payload) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1)); + if (strcmp(stemp1, Settings.mqtt_fulltopic)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : ""); + MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic + strlcpy(Settings.mqtt_fulltopic, stemp1, sizeof(Settings.mqtt_fulltopic)); + restart_flag = 2; + } + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_fulltopic); + } + else if ((CMND_PREFIX == command_code) && (index > 0) && (index <= 3)) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_prefix[0]))) { + MakeValidMqtt(0, dataBuf); + strlcpy(Settings.mqtt_prefix[index -1], (1 == payload) ? (1==index)?SUB_PREFIX:(2==index)?PUB_PREFIX:PUB_PREFIX2 : dataBuf, sizeof(Settings.mqtt_prefix[0])); +// if (Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] == '/') Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] = 0; + restart_flag = 2; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mqtt_prefix[index -1]); + } + else if (CMND_GROUPTOPIC == command_code) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_grptopic))) { + MakeValidMqtt(0, dataBuf); + if (!strcmp(dataBuf, mqtt_client)) { + payload = 1; + } + strlcpy(Settings.mqtt_grptopic, (1 == payload) ? MQTT_GRPTOPIC : dataBuf, sizeof(Settings.mqtt_grptopic)); + restart_flag = 2; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_grptopic); + } + else if ((CMND_TOPIC == command_code) && !grpflg) { + if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_topic))) { + MakeValidMqtt(0, dataBuf); + if (!strcmp(dataBuf, mqtt_client)) { + payload = 1; + } + strlcpy(stemp1, (1 == payload) ? MQTT_TOPIC : dataBuf, sizeof(stemp1)); + if (strcmp(stemp1, Settings.mqtt_topic)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : ""); + MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic + strlcpy(Settings.mqtt_topic, stemp1, sizeof(Settings.mqtt_topic)); + restart_flag = 2; + } + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.mqtt_topic); + } + else if ((CMND_BUTTONTOPIC == command_code) && !grpflg) { + if ((data_len > 0) && (data_len < sizeof(Settings.button_topic))) { + MakeValidMqtt(0, dataBuf); + if (!strcmp(dataBuf, mqtt_client)) { + payload = 1; + } + strlcpy(Settings.button_topic, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? mqtt_topic : dataBuf, sizeof(Settings.button_topic)); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.button_topic); + } + else if (CMND_SWITCHTOPIC == command_code) { + if ((data_len > 0) && (data_len < sizeof(Settings.switch_topic))) { + MakeValidMqtt(0, dataBuf); + if (!strcmp(dataBuf, mqtt_client)) { + payload = 1; + } + strlcpy(Settings.switch_topic, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? mqtt_topic : dataBuf, sizeof(Settings.switch_topic)); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.switch_topic); + } + else if (CMND_BUTTONRETAIN == command_code) { + if ((payload >= 0) && (payload <= 1)) { + strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); + if (!payload) { + for(i = 1; i <= MAX_KEYS; i++) { + send_button_power(0, i, 9); // Clear MQTT retain in broker + } + } + Settings.flag.mqtt_button_retain = payload; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_button_retain)); + } + else if (CMND_SWITCHRETAIN == command_code) { + if ((payload >= 0) && (payload <= 1)) { + strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); + if (!payload) { + for(i = 1; i <= MAX_SWITCHES; i++) { + send_button_power(1, i, 9); // Clear MQTT retain in broker + } + } + Settings.flag.mqtt_switch_retain = payload; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_switch_retain)); + } + else if (CMND_POWERRETAIN == command_code) { + if ((payload >= 0) && (payload <= 1)) { + if (!payload) { + for(i = 1; i <= devices_present; i++) { // Clear MQTT retain in broker + GetTopic_P(stemp1, STAT, mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand))); + mqtt_data[0] = '\0'; + MqttPublish(stemp1, Settings.flag.mqtt_power_retain); + } + } + Settings.flag.mqtt_power_retain = payload; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_power_retain)); + } + else if (CMND_SENSORRETAIN == command_code) { + if ((payload >= 0) && (payload <= 1)) { + if (!payload) { + mqtt_data[0] = '\0'; + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain); + } + Settings.flag.mqtt_sensor_retain = payload; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain)); + } + else serviced = false; + return serviced; +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +#define XDRV_00 + +boolean Xdrv00(byte function) +{ + boolean result = false; + + switch (function) { + case FUNC_LOOP: + if (Settings.flag.mqtt_enabled) MqttLoop(); + break; + case FUNC_EVERY_SECOND: + if (WL_CONNECTED == WiFi.status()) MqttCheckConnection(); + break; + case FUNC_COMMAND: + if (Settings.flag.mqtt_enabled) result = MqttCommand(); + break; + } + return result; +} diff --git a/sonoff/xdrv_interface.ino b/sonoff/xdrv_interface.ino index bf65ed4f1..15df24a13 100644 --- a/sonoff/xdrv_interface.ino +++ b/sonoff/xdrv_interface.ino @@ -18,6 +18,10 @@ */ boolean (* const xdrv_func_ptr[])(byte) PROGMEM = { // Driver Function Pointers +#ifdef XDRV_00 + &Xdrv00, +#endif + #ifdef XDRV_01 &Xdrv01, #endif @@ -139,12 +143,14 @@ boolean (* const xdrv_func_ptr[])(byte) PROGMEM = { // Driver Function Pointer const uint8_t xdrv_present = sizeof(xdrv_func_ptr) / sizeof(xdrv_func_ptr[0]); // Number of drivers found -boolean XdrvCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload) +boolean XdrvCommand(uint8_t grpflg, char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, uint16_t payload16) { // XdrvMailbox.valid = 1; XdrvMailbox.index = index; XdrvMailbox.data_len = data_len; + XdrvMailbox.payload16 = payload16; XdrvMailbox.payload = payload; + XdrvMailbox.grpflg = grpflg; XdrvMailbox.topic = type; XdrvMailbox.data = dataBuf;