From c14234394abe33971799ee04abb486c590f3ed78 Mon Sep 17 00:00:00 2001 From: arendst Date: Sat, 20 Jan 2018 12:12:39 +0100 Subject: [PATCH] v5.11.1d - Add command State and fixes 5.11.1d * Add locale Decimal Separator to Web sensor page * Add command State to retrieve device state information (same data as teleperiod state and status 11 in slightly different JSON format) * Extent state information with Light parameters * Fix IRSend parameter translation (#1636) * Add optional login to Webserver AP mode (#1587, #1635) * Fix BME680 teleperiod resistance measuring (#1647) --- README.md | 2 +- sonoff/_releasenotes.ino | 10 ++++- sonoff/i18n.h | 12 ++++++ sonoff/language/de-DE.h | 13 ------- sonoff/language/en-GB.h | 13 ------- sonoff/language/es-AR.h | 13 ------- sonoff/language/fr-FR.h | 13 ------- sonoff/language/it-IT.h | 13 ------- sonoff/language/nl-NL.h | 13 ------- sonoff/language/pl-PL.h | 13 ------- sonoff/language/zh-CN.h | 13 ------- sonoff/sonoff.h | 8 +++- sonoff/sonoff.ino | 25 +++++++----- sonoff/support.ino | 78 +------------------------------------ sonoff/webserver.ino | 77 +++++++++++++++++++++++++++--------- sonoff/xdrv_01_light.ino | 56 ++++++++++++++++++-------- sonoff/xdrv_02_irremote.ino | 15 ++++--- sonoff/xdrv_interface.ino | 12 +++++- sonoff/xsns_09_bmp.ino | 6 ++- sonoff/xsns_15_mhz19.ino | 1 + sonoff/xsns_interface.ino | 8 ++++ 21 files changed, 180 insertions(+), 234 deletions(-) diff --git a/README.md b/README.md index 3e87b01cc..1a402bf58 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.11.1c** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. +Current version is **5.11.1d** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 7f23be9cc..ada35af7a 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,12 @@ -/* 5.11.1c +/* 5.11.1d + * Add locale Decimal Separator to Web sensor page + * Add command State to retrieve device state information (same data as teleperiod state and status 11 in slightly different JSON format) + * Extent state information with Light parameters + * Fix IRSend parameter translation (#1636) + * Add optional login to Webserver AP mode (#1587, #1635) + * Fix BME680 teleperiod resistance measuring (#1647) + * + * 5.11.1c * Make command color parameter input less strict to ease Hass support * Add ColorTemperature to light status message * Change PubSubClient.h define MQTT_MAX_PACKET_SIZE from 512 to 1000 for Hass support diff --git a/sonoff/i18n.h b/sonoff/i18n.h index bcdf337ac..cecb050d0 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -166,6 +166,7 @@ #define D_STATUS9_MARGIN "PTH" #define D_STATUS10_SENSOR "SNS" #define D_STATUS11_STATUS "STS" +#define D_CMND_STATE "State" #define D_CMND_POWER "Power" #define D_CMND_POWERONSTATE "PowerOnState" #define D_CMND_PULSETIME "PulseTime" @@ -255,7 +256,18 @@ // Commands xdrv_02_irremote.ino #define D_CMND_IRSEND "IRSend" + #define D_JSON_INVALID_JSON "Invalid JSON" + #define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocol not supported" + #define D_JSON_IR_PROTOCOL "PROTOCOL" + #define D_JSON_IR_BITS "BITS" + #define D_JSON_IR_DATA "DATA" #define D_CMND_IRHVAC "IRHVAC" + #define D_JSON_IRHVAC_VENDOR "VENDOR" + #define D_JSON_IRHVAC_POWER "POWER" + #define D_JSON_IRHVAC_MODE "MODE" + #define D_JSON_IRHVAC_FANSPEED "FANSPEED" + #define D_JSON_IRHVAC_TEMP "TEMP" +#define D_JSON_IRRECEIVED "IrReceived" // Commands xdrv_03_energy.ino #define D_CMND_POWERLOW "PowerLow" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 244a036b4..933f98c28 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -335,19 +335,6 @@ #define D_HUE_POST_ARGS "Hue POST args" #define D_3_RESPONSE_PACKETS_SENT "3 Antwortpakete gesendet" -// xdrv_02_irremote.ino -#define D_JSON_INVALID_JSON "ungültiger JSON" -#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protokoll nicht unterstützt" -#define D_JSON_IR_PROTOCOL "PROTOKOLL" -#define D_JSON_IR_BITS "BITS" -#define D_JSON_IR_DATA "DATEN" -#define D_JSON_IRHVAC_VENDOR "HERSTELLER" -#define D_JSON_IRHVAC_POWER "STROM" -#define D_JSON_IRHVAC_MODE "MODUS" -#define D_JSON_IRHVAC_FANSPEED "LÜFTERGESCHWINDIGKEIT" -#define D_JSON_IRHVAC_TEMP "TEMPERATUR" -#define D_JSON_IRRECEIVED "IR empfangen" - // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz parameters" #define D_DOMOTICZ_IDX "Idx" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index c8ef6f223..e1f301f7b 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -335,19 +335,6 @@ #define D_HUE_POST_ARGS "Hue POST args" #define D_3_RESPONSE_PACKETS_SENT "3 response packets sent" -// xdrv_02_irremote.ino -#define D_JSON_INVALID_JSON "Invalid JSON" -#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocol not supported" -#define D_JSON_IR_PROTOCOL "PROTOCOL" -#define D_JSON_IR_BITS "BITS" -#define D_JSON_IR_DATA "DATA" -#define D_JSON_IRHVAC_VENDOR "VENDOR" -#define D_JSON_IRHVAC_POWER "POWER" -#define D_JSON_IRHVAC_MODE "MODE" -#define D_JSON_IRHVAC_FANSPEED "FANSPEED" -#define D_JSON_IRHVAC_TEMP "TEMP" -#define D_JSON_IRRECEIVED "IrReceived" - // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz parameters" #define D_DOMOTICZ_IDX "Idx" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 99e142d4c..fbbbddd89 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -335,19 +335,6 @@ #define D_HUE_POST_ARGS "Hue POST args" #define D_3_RESPONSE_PACKETS_SENT "3 paquetes de respuesta enviados" -// xdrv_02_irremote.ino -#define D_JSON_INVALID_JSON "JSON no válido" -#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocolo no soportado" -#define D_JSON_IR_PROTOCOL "PROTOCOLO" -#define D_JSON_IR_BITS "BITS" -#define D_JSON_IR_DATA "DATA" -#define D_JSON_IRHVAC_VENDOR "VENDOR" -#define D_JSON_IRHVAC_POWER "POWER" -#define D_JSON_IRHVAC_MODE "MODE" -#define D_JSON_IRHVAC_FANSPEED "FANSPEED" -#define D_JSON_IRHVAC_TEMP "TEMP" -#define D_JSON_IRRECEIVED "IrReceived" - // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Parámetros Domoticz" #define D_DOMOTICZ_IDX "Idx" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index bfb31d519..1fb0ee418 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -335,19 +335,6 @@ #define D_HUE_POST_ARGS "Hue POST args" #define D_3_RESPONSE_PACKETS_SENT "3 paquets response envoyés" -// xdrv_02_irremote.ino -#define D_JSON_INVALID_JSON "JSON Invalide" -#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocole non supporté" -#define D_JSON_IR_PROTOCOL "PROTOCOL" -#define D_JSON_IR_BITS "BITS" -#define D_JSON_IR_DATA "DATA" -#define D_JSON_IRHVAC_VENDOR "VENDOR" -#define D_JSON_IRHVAC_POWER "POWER" -#define D_JSON_IRHVAC_MODE "MODE" -#define D_JSON_IRHVAC_FANSPEED "FANSPEED" -#define D_JSON_IRHVAC_TEMP "TEMP" -#define D_JSON_IRRECEIVED "IrReceived" - // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Paramètres Domoticz" #define D_DOMOTICZ_IDX "Idx" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index be9e97911..ae6a297f8 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -335,19 +335,6 @@ #define D_HUE_POST_ARGS "Hue POST argomenti" #define D_3_RESPONSE_PACKETS_SENT "3 pacchetti di risposta inviati" -// xdrv_02_irremote.ino -#define D_JSON_INVALID_JSON "JSON non valido" -#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocollo non supportato" -#define D_JSON_IR_PROTOCOL "PROTOCOL" -#define D_JSON_IR_BITS "BITS" -#define D_JSON_IR_DATA "DATA" -#define D_JSON_IRHVAC_VENDOR "VENDOR" -#define D_JSON_IRHVAC_POWER "POWER" -#define D_JSON_IRHVAC_MODE "MODE" -#define D_JSON_IRHVAC_FANSPEED "FANSPEED" -#define D_JSON_IRHVAC_TEMP "TEMP" -#define D_JSON_IRRECEIVED "IrReceived" - // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Parametri Domoticz" #define D_DOMOTICZ_IDX "Idx" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 9850c8b0e..41d204baa 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -335,19 +335,6 @@ #define D_HUE_POST_ARGS "Hue POST argumenten" #define D_3_RESPONSE_PACKETS_SENT "3 antwoord paketten verstuurd" -// xdrv_02_irremote.ino -#define D_JSON_INVALID_JSON "Ongeldig JSON" -#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocol wordt niet ondersteund" -#define D_JSON_IR_PROTOCOL "PROTOCOL" -#define D_JSON_IR_BITS "BITS" -#define D_JSON_IR_DATA "DATA" -#define D_JSON_IRHVAC_VENDOR "VENDOR" -#define D_JSON_IRHVAC_POWER "POWER" -#define D_JSON_IRHVAC_MODE "MODE" -#define D_JSON_IRHVAC_FANSPEED "FANSPEED" -#define D_JSON_IRHVAC_TEMP "TEMP" -#define D_JSON_IRRECEIVED "IrReceived" - // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz parameters" #define D_DOMOTICZ_IDX "Idx" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 79e2afbe5..84462cfe4 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -335,19 +335,6 @@ #define D_HUE_POST_ARGS "Hue POST args" #define D_3_RESPONSE_PACKETS_SENT "3 pakiety odpowiedzi wysylane" -// xdrv_02_irremote.ino -#define D_JSON_INVALID_JSON "Invalid JSON" -#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protokol nie jest obslugiwany" -#define D_JSON_IR_PROTOCOL "PROTOCOL" -#define D_JSON_IR_BITS "BITS" -#define D_JSON_IR_DATA "DATA" -#define D_JSON_IRHVAC_VENDOR "VENDOR" -#define D_JSON_IRHVAC_POWER "POWER" -#define D_JSON_IRHVAC_MODE "MODE" -#define D_JSON_IRHVAC_FANSPEED "FANSPEED" -#define D_JSON_IRHVAC_TEMP "TEMP" -#define D_JSON_IRRECEIVED "IrReceived" - // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Parametry Domoticz" #define D_DOMOTICZ_IDX "Idx" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index c1a5ec75b..cba6130d1 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -335,19 +335,6 @@ #define D_HUE_POST_ARGS "Hue POST 参数" #define D_3_RESPONSE_PACKETS_SENT "3 请求包发送" -// xdrv_02_irremote.ino -#define D_JSON_INVALID_JSON "无效的JSON" -#define D_JSON_PROTOCOL_NOT_SUPPORTED "协议不支持" -#define D_JSON_IR_PROTOCOL "协议" -#define D_JSON_IR_BITS "BITS" -#define D_JSON_IR_DATA "数据" -#define D_JSON_IRHVAC_VENDOR "供应商" -#define D_JSON_IRHVAC_POWER "电源" -#define D_JSON_IRHVAC_MODE "模式" -#define D_JSON_IRHVAC_FANSPEED "风扇转速" -#define D_JSON_IRHVAC_TEMP "温度" -#define D_JSON_IRRECEIVED "IrReceived" - // xdrv_05_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz 设置" #define D_DOMOTICZ_IDX "Idx" diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 2186a1aff..fa105ef93 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -86,7 +86,7 @@ typedef unsigned long power_t; // Power (Relay) type #define CMDSZ 24 // Max number of characters in command #define TOPSZ 100 // Max number of characters in topic string #define LOGSZ 400 // Max number of characters in log -#define MIN_MESSZ 893 // Min number of characters in MQTT message +#define MIN_MESSZ 893 // Min number of characters in MQTT message #ifdef USE_MQTT_TLS #define MAX_LOG_LINES 10 // Max number of lines in weblog #else @@ -145,4 +145,10 @@ enum XsnsFunctions {FUNC_INIT, FUNC_EVERY_50_MSECOND, FUNC_EVERY_SECOND, FUNC_PR const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; +/*********************************************************************************************\ + * Extern global variables +\*********************************************************************************************/ + +extern uint8_t light_device; // Light device number + #endif // _SONOFF_H_ \ No newline at end of file diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 51552591b..ead6053c1 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x050B0103 // 5.11.1c +#define VERSION 0x050B0104 // 5.11.1d // Location specific includes #include "sonoff.h" // Enumaration used in user_config.h @@ -67,7 +67,7 @@ #include "settings.h" enum TasmotaCommands { - CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_STATUS, CMND_POWERONSTATE, CMND_PULSETIME, + CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_STATUS, CMND_STATE, CMND_POWERONSTATE, CMND_PULSETIME, CMND_BLINKTIME, CMND_BLINKCOUNT, CMND_SAVEDATA, CMND_SETOPTION, CMND_TEMPERATURE_RESOLUTION, CMND_HUMIDITY_RESOLUTION, CMND_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_CURRENT_RESOLUTION, CMND_ENERGY_RESOLUTION, CMND_MODULE, CMND_MODULES, CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE, @@ -77,7 +77,7 @@ enum TasmotaCommands { CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE, CMND_CFGDUMP, CMND_I2CSCAN, CMND_INA219MODE, CMND_EXCEPTION }; const char kTasmotaCommands[] PROGMEM = - D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_STATUS "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|" + D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|" D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SAVEDATA "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|" D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" D_CMND_MODULE "|" D_CMND_MODULES "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|" @@ -194,13 +194,8 @@ char my_version[33]; // Composed version string char my_hostname[33]; // Composed Wifi hostname char mqtt_client[33]; // Composed MQTT Clientname char serial_in_buffer[INPUT_BUFFER_SIZE + 2]; // Receive buffer - -//char mqtt_data[MESSZ + TOPSZ]; // MQTT publish buffer (MESSZ) and web page ajax buffer (MESSZ + TOPSZ) char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer - -//char log_data[TOPSZ + MESSZ]; // Logging char log_data[LOGSZ]; // Logging - String web_log[MAX_LOG_LINES]; // Web log buffer String backlog[MAX_BACKLOG]; // Command backlog @@ -317,7 +312,7 @@ void SetDevicePower(power_t rpower) } } - XdrvSetPower(bitRead(rpower, devices_present -1)); + XdrvSetPower(rpower); if ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module)) { Serial.write(0xA0); @@ -938,6 +933,10 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len) fallback_topic_flag = 0; return; } + else if (CMND_STATE == command_code) { + mqtt_data[0] = '\0'; + MqttShowState(); + } else if ((CMND_POWERONSTATE == command_code) && (Settings.module != MOTOR)) { /* 0 = Keep relays off after power on * 1 = Turn relays on after power on, if PulseTime set wait for PulseTime seconds, and turn relays off @@ -1796,9 +1795,15 @@ void MqttShowState() dtostrfd((double)ESP.getVcc()/1000, 3, stemp1); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1); #endif + for (byte i = 0; i < devices_present; i++) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":\"%s\""), mqtt_data, GetPowerDevice(stemp1, i +1, sizeof(stemp1)), GetStateText(bitRead(power, i))); + if (i == light_device -1) { + LightState(1); + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":\"%s\""), mqtt_data, GetPowerDevice(stemp1, i +1, sizeof(stemp1)), GetStateText(bitRead(power, i))); + } } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_RSSI "\":%d,\"" D_JSON_APMAC_ADDRESS "\":\"%s\"}}"), mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str()); } diff --git a/sonoff/support.ino b/sonoff/support.ino index 3bf651662..48b218386 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -148,83 +148,9 @@ Decoding 14 results * General \*********************************************************************************************/ -char* _dtostrf(double number, unsigned char prec, char *s, bool i18n) +char* dtostrfd(double number, unsigned char prec, char *s) { - bool negative = false; - - if (isnan(number)) { - strcpy_P(s, PSTR("nan")); - return s; - } - if (isinf(number)) { - strcpy_P(s, PSTR("inf")); - return s; - } - char decimal = '.'; - if (i18n) { - decimal = D_DECIMAL_SEPARATOR[0]; - } - - char* out = s; - - // Handle negative numbers - if (number < 0.0) { - negative = true; - number = -number; - } - - // Round correctly so that print(1.999, 2) prints as "2.00" - // I optimized out most of the divisions - double rounding = 2.0; - for (uint8_t i = 0; i < prec; ++i) { - rounding *= 10.0; - } - rounding = 1.0 / rounding; - number += rounding; - - // Figure out how big our number really is - double tenpow = 1.0; - int digitcount = 1; - while (number >= 10.0 * tenpow) { - tenpow *= 10.0; - digitcount++; - } - number /= tenpow; - - // Handle negative sign - if (negative) { - *out++ = '-'; - } - - // Print the digits, and if necessary, the decimal point - digitcount += prec; - int8_t digit = 0; - while (digitcount-- > 0) { - digit = (int8_t)number; - if (digit > 9) { - digit = 9; // insurance - } - *out++ = (char)('0' | digit); - if ((digitcount == prec) && (prec > 0)) { - *out++ = decimal; - } - number -= digit; - number *= 10.0; - } - - // make sure the string is terminated - *out = 0; - return s; -} - -char* dtostrfd(double number, unsigned char prec, char *s) // Always decimal dot -{ - return _dtostrf(number, prec, s, 0); -} - -char* dtostrfi(double number, unsigned char prec, char *s) // Use localized decimal dot -{ - return _dtostrf(number, prec, s, 1); + return dtostrf(number, 1, prec, s); } boolean ParseIp(uint32_t* addr, const char* str) diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index fa0f7dec0..1af4f1ee4 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -96,7 +96,11 @@ const char HTTP_HEAD[] PROGMEM = #ifdef BE_MINIMAL "

" D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "

" #endif +#if MY_LANGUAGE == es-AR + "

" D_MODULE " {ha

{h}

"; +#else "

{ha " D_MODULE "

{h}

"; +#endif const char HTTP_SCRIPT_CONSOL[] PROGMEM = "var sn=0;" // Scroll position "var id=99;" // Get most of weblog initially @@ -190,6 +194,12 @@ const char HTTP_BTN_MENU4[] PROGMEM = "
"; const char HTTP_BTN_MAIN[] PROGMEM = "

"; +const char HTTP_FORM_LOGIN[] PROGMEM = + "
" + "
" D_USER "

" + "
" D_PASSWORD "

" + "
" + "
"; const char HTTP_BTN_CONF[] PROGMEM = "

"; const char HTTP_FORM_MODULE[] PROGMEM = @@ -204,9 +214,9 @@ const char HTTP_FORM_WIFI[] PROGMEM = "
 " D_WIFI_PARAMETERS " 
" "" "
" D_AP1_SSID " (" STA_SSID1 ")

" - "
" D_AP1_PASSWORD "

" + "
" D_AP1_PASSWORD "

" "
" D_AP2_SSID " (" STA_SSID2 ")

" - "
" D_AP2_PASSWORD "

" + "
" D_AP2_PASSWORD "

" "
" D_HOSTNAME " (" WIFI_HOSTNAME ")

"; const char HTTP_FORM_MQTT[] PROGMEM = "
 " D_MQTT_PARAMETERS " " @@ -236,7 +246,7 @@ const char HTTP_FORM_LOG3[] PROGMEM = const char HTTP_FORM_OTHER[] PROGMEM = "
 " D_OTHER_PARAMETERS " " "" - "
" D_WEB_ADMIN_PASSWORD "

" + "
" D_WEB_ADMIN_PASSWORD "

" "
" D_MQTT_ENABLE "
"; const char HTTP_FORM_OTHER2[] PROGMEM = "
" D_FRIENDLY_NAME " {1 ({2)

"; @@ -244,8 +254,8 @@ const char HTTP_FORM_OTHER[] PROGMEM = const char HTTP_FORM_OTHER3a[] PROGMEM = "
 " D_EMULATION " "; const char HTTP_FORM_OTHER3b[] PROGMEM = - "
{3{4"; - #endif // USE_EMULATION + "
{3{4"; // Different id only used for labels +#endif // USE_EMULATION const char HTTP_FORM_END[] PROGMEM = "
"; const char HTTP_FORM_RST[] PROGMEM = @@ -412,11 +422,17 @@ void SetHeader() #endif } -void ShowPage(String &page) +void ShowPage(String &page, bool auth = true) { - if((HTTP_ADMIN == webserver_state) && (Settings.web_password[0] != 0) && !WebServer->authenticate(WEB_USERNAME, Settings.web_password)) { +// if((HTTP_ADMIN == webserver_state) && (Settings.web_password[0] != 0) && !WebServer->authenticate(WEB_USERNAME, Settings.web_password)) { +// return WebServer->requestAuthentication(); +// } + + //Authentication + if (auth && (Settings.web_password[0] != 0) && !WebServer->authenticate(WEB_USERNAME, Settings.web_password)) { return WebServer->requestAuthentication(); } + page.replace(F("{ha"), my_module.name); page.replace(F("{h}"), Settings.friendlyname[0]); if (HTTP_MANAGER == webserver_state) { @@ -429,11 +445,20 @@ void ShowPage(String &page) page.replace(F("{mv"), my_version); SetHeader(); WebServer->send(200, FPSTR(HDR_CTYPE_HTML), page); +// WebServer->sendContent(""); +} + +//Authentication +void HandleWifiLogin() +{ + String page = FPSTR(HTTP_HEAD); + page.replace(F("{v}"), FPSTR( D_CONFIGURE_WIFI )); + page += FPSTR(HTTP_FORM_LOGIN); + ShowPage(page, false); // false means show page no matter if the client has or has not credentials } void HandleRoot() { -// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_MAIN_MENU)); AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_MAIN_MENU); if (CaptivePortal()) { // If captive portal redirect instead of displaying the page. @@ -441,7 +466,20 @@ void HandleRoot() } if (HTTP_MANAGER == webserver_state) { - HandleWifiConfiguration(); +// HandleWifiConfiguration(); + + //Authentication + if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1"))) { + HandleWifiLogin(); + } else { + if (!(Settings.web_password[0] != 0) || ((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == Settings.web_password ))) { + HandleWifiConfiguration(); + } else { + // wrong user and pass + HandleWifiLogin(); + } + } + } else { char stemp[10]; char line[160]; @@ -520,6 +558,7 @@ void HandleAjaxStatusRefresh() if (strlen(mqtt_data)) { page += FPSTR(HTTP_TABLE100); page += mqtt_data; + page.replace(F("."), F(D_DECIMAL_SEPARATOR)); page += F(""); } char line[80]; @@ -529,7 +568,6 @@ void HandleAjaxStatusRefresh() uint8_t fsize = (devices_present < 5) ? 70 - (devices_present * 8) : 32; for (byte idx = 1; idx <= devices_present; idx++) { snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(power, idx -1)); -// snprintf_P(line, sizeof(line), PSTR("
%s
"), snprintf_P(line, sizeof(line), PSTR("%s"), // {t} = %'>
arg("p1").c_str(), sizeof(Settings.sta_pwd[0])); + strlcpy(Settings.sta_pwd[1], (!strlen(WebServer->arg("p2").c_str())) ? "" : (strchr(WebServer->arg("p2").c_str(),'*')) ? Settings.sta_pwd[1] : WebServer->arg("p2").c_str(), sizeof(Settings.sta_pwd[1])); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_PASSWORD "1 %s, " D_CMND_SSID "2 %s, " D_CMND_PASSWORD "2 %s"), Settings.hostname, Settings.sta_ssid[0], Settings.sta_pwd[0], Settings.sta_ssid[1], Settings.sta_pwd[1]); AddLog(LOG_LEVEL_INFO); @@ -1014,7 +1053,7 @@ snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D break; #endif // USE_DOMOTICZ case 5: - strlcpy(Settings.web_password, (!strlen(WebServer->arg("p1").c_str())) ? WEB_PASSWORD : (!strcmp(WebServer->arg("p1").c_str(),"0")) ? "" : WebServer->arg("p1").c_str(), sizeof(Settings.web_password)); + strlcpy(Settings.web_password, (!strlen(WebServer->arg("p1").c_str())) ? "" : (strchr(WebServer->arg("p1").c_str(),'*')) ? Settings.web_password : WebServer->arg("p1").c_str(), sizeof(Settings.web_password)); Settings.flag.mqtt_enabled = WebServer->hasArg("b1"); #ifdef USE_EMULATION Settings.flag2.emulation = (!strlen(WebServer->arg("b2").c_str())) ? 0 : atoi(WebServer->arg("b2").c_str()); @@ -1376,6 +1415,7 @@ void HandleHttpCommand() } SetHeader(); WebServer->send(200, FPSTR(HDR_CTYPE_JSON), message); +// WebServer->sendContent(""); } void HandleConsole() @@ -1454,6 +1494,7 @@ void HandleAjaxConsoleRefresh() } message += F(""); WebServer->send(200, FPSTR(HDR_CTYPE_XML), message); +// WebServer->sendContent(""); } void HandleInformation() diff --git a/sonoff/xdrv_01_light.ino b/sonoff/xdrv_01_light.ino index 5b7dc0b7c..51e7ea061 100644 --- a/sonoff/xdrv_01_light.ino +++ b/sonoff/xdrv_01_light.ino @@ -99,6 +99,7 @@ uint8_t light_signal_color[5]; uint8_t light_wheel = 0; uint8_t light_subtype = 0; +uint8_t light_device = 0; uint8_t light_power = 0; uint8_t light_update = 1; uint8_t light_wakeup_active = 0; @@ -337,6 +338,7 @@ void LightInit() { uint8_t max_scheme = LS_MAX -1; + light_device = devices_present; light_subtype = light_type &7; if (light_type < LT_PWM6) { // PWM @@ -526,35 +528,56 @@ char* LightGetColor(uint8_t type, char* scolor) void LightPowerOn() { if (Settings.light_dimmer && !(light_power)) { - ExecuteCommandPower(devices_present, 1); + ExecuteCommandPower(light_device, 1); } } -void LightPreparePower() +void LightState(uint8_t append) { char scolor[25]; char scommand[33]; - if (Settings.light_dimmer && !(light_power)) { - ExecuteCommandPower(devices_present, 7); // No publishPowerState + if (append) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data); + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{")); } - else if (!Settings.light_dimmer && light_power) { - ExecuteCommandPower(devices_present, 6); // No publishPowerState - } -#ifdef USE_DOMOTICZ - DomoticzUpdatePowerState(devices_present); -#endif // USE_DOMOTICZ - - GetPowerDevice(scommand, devices_present, sizeof(scommand)); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"), - scommand, GetStateText(light_power), Settings.light_dimmer); + GetPowerDevice(scommand, light_device, sizeof(scommand)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"), + mqtt_data, scommand, GetStateText(light_power), Settings.light_dimmer); if (light_subtype > LST_SINGLE) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor)); } if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLORTEMPERATURE "\":%d"), mqtt_data, LightGetColorTemp()); } - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + if (append) { + if (light_subtype >= LST_RGB) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_SCHEME "\":%d"), mqtt_data, Settings.light_scheme); + } + if (LT_WS2812 == light_type) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_WIDTH "\":%d"), mqtt_data, Settings.light_width); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_FADE "\":\"%s\",\"" D_CMND_SPEED "\":%d,\"" D_CMND_LEDTABLE "\":\"%s\""), + mqtt_data, GetStateText(Settings.light_fade), Settings.light_speed, GetStateText(Settings.light_correction)); + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + } +} + +void LightPreparePower() +{ + if (Settings.light_dimmer && !(light_power)) { + ExecuteCommandPower(light_device, 7); // No publishPowerState + } + else if (!Settings.light_dimmer && light_power) { + ExecuteCommandPower(light_device, 6); // No publishPowerState + } +#ifdef USE_DOMOTICZ + DomoticzUpdatePowerState(light_device); +#endif // USE_DOMOTICZ + + LightState(0); } void LightFade() @@ -638,7 +661,8 @@ void LightRandomColor() void LightSetPower() { - light_power = XdrvMailbox.index; +// light_power = XdrvMailbox.index; + light_power = bitRead(XdrvMailbox.index, light_device -1); if (light_wakeup_active) { light_wakeup_active--; } diff --git a/sonoff/xdrv_02_irremote.ino b/sonoff/xdrv_02_irremote.ino index 11e95b7d8..3efca0ea3 100644 --- a/sonoff/xdrv_02_irremote.ino +++ b/sonoff/xdrv_02_irremote.ino @@ -309,21 +309,26 @@ boolean IrSendCommand() data = ir_json[D_JSON_IR_DATA]; if (protocol && bits && data) { int protocol_code = GetCommandCode(protocol_text, sizeof(protocol_text), protocol, kIrRemoteProtocols); + + snprintf_P(log_data, sizeof(log_data), PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %d, protocol_code %d"), + protocol_text, protocol, bits, data, protocol_code); + AddLog(LOG_LEVEL_DEBUG); + switch (protocol_code) { case NEC: - irsend->sendNEC(data, bits); break; + irsend->sendNEC(data, (bits > NEC_BITS) ? NEC_BITS : bits); break; case SONY: - irsend->sendSony(data, bits); break; + irsend->sendSony(data, (bits > SONY_20_BITS) ? SONY_20_BITS : bits, 2); break; case RC5: irsend->sendRC5(data, bits); break; case RC6: irsend->sendRC6(data, bits); break; case DISH: - irsend->sendDISH(data, bits); break; + irsend->sendDISH(data, (bits > DISH_BITS) ? DISH_BITS : bits); break; case JVC: - irsend->sendJVC(data, bits, 1); break; + irsend->sendJVC(data, (bits > JVC_BITS) ? JVC_BITS : bits, 1); break; case SAMSUNG: - irsend->sendSAMSUNG(data, bits); break; + irsend->sendSAMSUNG(data, (bits > SAMSUNG_BITS) ? SAMSUNG_BITS : bits); break; case PANASONIC: irsend->sendPanasonic(bits, data); break; default: diff --git a/sonoff/xdrv_interface.ino b/sonoff/xdrv_interface.ino index e8c3516f6..571b24cfb 100644 --- a/sonoff/xdrv_interface.ino +++ b/sonoff/xdrv_interface.ino @@ -82,7 +82,7 @@ boolean XdrvCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_len return XdrvCall(FUNC_COMMAND); } -void XdrvSetPower(uint8_t mpower) +void XdrvSetPower(power_t mpower) { // XdrvMailbox.valid = 1; XdrvMailbox.index = mpower; @@ -102,6 +102,16 @@ boolean XdrvMqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uint16_t /*********************************************************************************************\ * Function call to all xdrv + * + * FUNC_INIT + * FUNC_MQTT_SUBSCRIBE + * FUNC_MQTT_INIT + * return FUNC_MQTT_DATA + * return FUNC_COMMAND + * FUNC_SET_POWER + * FUNC_SHOW_SENSOR + * FUNC_EVERY_SECOND + * FUNC_EVERY_50_MSECOND \*********************************************************************************************/ boolean XdrvCall(byte Function) diff --git a/sonoff/xsns_09_bmp.ino b/sonoff/xsns_09_bmp.ino index a2776f82f..91f6d2d7a 100644 --- a/sonoff/xsns_09_bmp.ino +++ b/sonoff/xsns_09_bmp.ino @@ -504,8 +504,12 @@ boolean Xsns09(byte function) switch (function) { case FUNC_PREP_BEFORE_TELEPERIOD: BmpDetect(); + break; + case FUNC_EVERY_SECOND: #ifdef USE_BME680 - Bme680PerformReading(); + if (tele_period == Settings.tele_period -3) { + Bme680PerformReading(); + } #endif // USE_BME680 break; case FUNC_JSON_APPEND: diff --git a/sonoff/xsns_15_mhz19.ino b/sonoff/xsns_15_mhz19.ino index 26bea4fc3..3c3158d04 100644 --- a/sonoff/xsns_15_mhz19.ino +++ b/sonoff/xsns_15_mhz19.ino @@ -71,6 +71,7 @@ const char kMhzTypes[] PROGMEM = "MHZ19|MHZ19B"; const uint8_t mhz_cmnd_read_ppm[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; const uint8_t mhz_cmnd_abc_enable[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; const uint8_t mhz_cmnd_abc_disable[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; +//const uint8_t mhz_cmnd_zeropoint[9] = {0xff, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78}; uint8_t mhz_type = 1; uint16_t mhz_last_ppm = 0; diff --git a/sonoff/xsns_interface.ino b/sonoff/xsns_interface.ino index fc473d300..60cfac26e 100644 --- a/sonoff/xsns_interface.ino +++ b/sonoff/xsns_interface.ino @@ -112,6 +112,14 @@ void XSnsInit() /*********************************************************************************************\ * Function call to all xsns + * + * FUNC_INIT + * FUNC_PREP_BEFORE_TELEPERIOD + * FUNC_SAVE_BEFORE_RESTART + * FUNC_JSON_APPEND + * FUNC_WEB_APPEND + * FUNC_EVERY_SECOND + * FUNC_EVERY_50_MSECOND \*********************************************************************************************/ boolean XsnsCall(byte Function)