Merge branch 'development' of https://github.com/arendst/Sonoff-Tasmota into tuya-wifi-state

This commit is contained in:
Joel Stein 2018-10-29 23:35:13 +01:00
commit d8914906a8
30 changed files with 373 additions and 275 deletions

View File

@ -1,11 +1,17 @@
/* 6.2.1.19 20181023 /* 6.2.1.20 20181028
* Add command SetOption35 0..255 (seconds) to delay mDNS initialization to control possible Wifi connect problems
* Add command SetOption53 0/1 to toggle gui display of Hostname and IP address (#1006, #2091)
* Add token %hostname% to command FullTopic (#3018)
* Add support for two BMP/BME sensors (#4195)
*
* 6.2.1.19 20181023
* Fix header file execution order by renaming user_config.h to my_user_config.h * Fix header file execution order by renaming user_config.h to my_user_config.h
* Fix invalid JSON floating point result from nan (Not a Number) and inf (Infinity) into null (#4147) * Fix invalid JSON floating point result from nan (Not a Number) and inf (Infinity) into null (#4147)
* Fix rule mqtt#connected trigger when mqtt is disabled (#4149) * Fix rule mqtt#connected trigger when mqtt is disabled (#4149)
* Initial release of RF transceiving using library RcSwitch (#2702) * Initial release of RF transceiving using library RcSwitch (#2702)
* Change default OTA Url to http://thehackbox.org/tasmota/release/sonoff.bin (#4170) * Change default OTA Url to http://thehackbox.org/tasmota/release/sonoff.bin (#4170)
* Add Tuya Software Serial to support additional Tuya configurations (#4178) * Add Tuya Software Serial to support additional Tuya configurations (#4178)
* Add sonoff-basic.bin without most sensors * Add define USE_BASIC for selecting image sonoff-basic without most sensors
* *
* 6.2.1.18 20181019 * 6.2.1.18 20181019
* Add more API callbacks and document API.md * Add more API callbacks and document API.md

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "h" #define D_UNIT_HOUR "h"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ" #define D_UNIT_KILOOHM "kΩ"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "h" #define D_UNIT_HOUR "h"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -1,3 +1,4 @@
/* /*
el-GR.h - localization for Greek - Greece for Sonoff-Tasmota el-GR.h - localization for Greek - Greece for Sonoff-Tasmota
@ -537,7 +538,7 @@
#define D_UNIT_HOUR "Hr" #define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "Hr" #define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "Hr" #define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "h" #define D_UNIT_HOUR "h"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ" #define D_UNIT_KILOOHM "kΩ"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "Hr" #define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "ó" #define D_UNIT_HOUR "ó"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "Hr" #define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "h" #define D_UNIT_HOUR "h"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "Godz" #define D_UNIT_HOUR "Godz"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "H" #define D_UNIT_HOUR "H"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "Hr" #define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "Ч" #define D_UNIT_HOUR "Ч"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "кОм" #define D_UNIT_KILOOHM "кОм"
#define D_UNIT_KILOWATTHOUR "кВт" #define D_UNIT_KILOWATTHOUR "кВт"
#define D_UNIT_LUX "лк" #define D_UNIT_LUX "лк"

View File

@ -536,7 +536,7 @@
#define D_UNIT_HOUR "Hr" #define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx" #define D_UNIT_LUX "lx"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "Г" #define D_UNIT_HOUR "Г"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "кОм" #define D_UNIT_KILOOHM "кОм"
#define D_UNIT_KILOWATTHOUR "кВт" #define D_UNIT_KILOWATTHOUR "кВт"
#define D_UNIT_LUX "лк" #define D_UNIT_LUX "лк"

View File

@ -536,7 +536,7 @@
#define D_UNIT_HOUR "时" #define D_UNIT_HOUR "时"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "千欧" #define D_UNIT_KILOOHM "千欧"
#define D_UNIT_KILOWATTHOUR "千瓦时" #define D_UNIT_KILOWATTHOUR "千瓦时"
#define D_UNIT_LUX "勒克斯" #define D_UNIT_LUX "勒克斯"

View File

@ -537,7 +537,7 @@
#define D_UNIT_HOUR "時" #define D_UNIT_HOUR "時"
#define D_UNIT_INCREMENTS "inc" #define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "千歐" #define D_UNIT_KILOOHM "千歐"
#define D_UNIT_KILOWATTHOUR "千瓦時" #define D_UNIT_KILOWATTHOUR "千瓦時"
#define D_UNIT_LUX "勒克斯" #define D_UNIT_LUX "勒克斯"

View File

@ -281,7 +281,7 @@
#ifdef USE_I2C #ifdef USE_I2C
#define USE_SHT // Enable SHT1X sensor (+1k4 code) #define USE_SHT // Enable SHT1X sensor (+1k4 code)
#define USE_HTU // Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code) #define USE_HTU // Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code)
#define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address 0x76 or 0x77) (+4k code) #define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensors (I2C addresses 0x76 and 0x77) (+4k4 code)
// #define USE_BME680 // Enable support for BME680 sensor using Bosch BME680 library (+4k code) // #define USE_BME680 // Enable support for BME680 sensor using Bosch BME680 library (+4k code)
#define USE_BH1750 // Enable BH1750 sensor (I2C address 0x23 or 0x5C) (+0k5 code) #define USE_BH1750 // Enable BH1750 sensor (I2C address 0x23 or 0x5C) (+0k5 code)
// #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+1k5 code) // #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+1k5 code)

View File

@ -66,7 +66,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t timers_enable : 1; // bit 0 (v6.1.1b) uint32_t timers_enable : 1; // bit 0 (v6.1.1b)
uint32_t user_esp8285_enable : 1; // bit 1 (v6.1.1.14) uint32_t user_esp8285_enable : 1; // bit 1 (v6.1.1.14)
uint32_t time_append_timezone : 1; // bit 2 (v6.2.1.2) uint32_t time_append_timezone : 1; // bit 2 (v6.2.1.2)
uint32_t spare03 : 1; uint32_t gui_hostname_ip : 1; // bit 3 (v6.2.1.20)
uint32_t spare04 : 1; uint32_t spare04 : 1;
uint32_t spare05 : 1; uint32_t spare05 : 1;
uint32_t spare06 : 1; uint32_t spare06 : 1;

View File

@ -60,6 +60,7 @@ typedef unsigned long power_t; // Power (Relay) type
#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x] #define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
#define MQTT_TOKEN_TOPIC "%topic%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic #define MQTT_TOKEN_TOPIC "%topic%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
#define MQTT_TOKEN_HOSTNAME "%hostname%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
#define MQTT_TOKEN_ID "%id%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic #define MQTT_TOKEN_ID "%id%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
#define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address> #define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address>
@ -202,7 +203,7 @@ enum ButtonStates { PRESSED, NOT_PRESSED };
enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER }; enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER };
enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MAX_PARAM8}; enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MDNS_DELAYED_START, P_MAX_PARAM8}; // Max is PARAM8_SIZE (18)
enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_AIRQUALITY, DZ_MAX_SENSORS}; enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_AIRQUALITY, DZ_MAX_SENSORS};

View File

@ -186,6 +186,7 @@ byte reset_web_log_flag = 0; // Reset web console log
byte devices_present = 0; // Max number of devices supported byte devices_present = 0; // Max number of devices supported
byte seriallog_level; // Current copy of Settings.seriallog_level byte seriallog_level; // Current copy of Settings.seriallog_level
byte syslog_level; // Current copy of Settings.syslog_level byte syslog_level; // Current copy of Settings.syslog_level
byte mdns_delayed_start = 0; // mDNS delayed start
boolean latest_uptime_flag = true; // Signal latest uptime boolean latest_uptime_flag = true; // Signal latest uptime
boolean pwm_present = false; // Any PWM channel configured with SetOption15 0 boolean pwm_present = false; // Any PWM channel configured with SetOption15 0
boolean mdns_begun = false; // mDNS active boolean mdns_begun = false; // mDNS active
@ -278,6 +279,7 @@ void GetTopic_P(char *stopic, byte prefix, char *topic, const char* subtopic)
} }
fulltopic.replace(F(MQTT_TOKEN_PREFIX), Settings.mqtt_prefix[prefix]); fulltopic.replace(F(MQTT_TOKEN_PREFIX), Settings.mqtt_prefix[prefix]);
fulltopic.replace(F(MQTT_TOKEN_TOPIC), topic); fulltopic.replace(F(MQTT_TOKEN_TOPIC), topic);
fulltopic.replace(F(MQTT_TOKEN_HOSTNAME), my_hostname);
String token_id = WiFi.macAddress(); String token_id = WiFi.macAddress();
token_id.replace(":", ""); token_id.replace(":", "");
fulltopic.replace(F(MQTT_TOKEN_ID), token_id); fulltopic.replace(F(MQTT_TOKEN_ID), token_id);
@ -2580,6 +2582,7 @@ void setup()
} }
baudrate = Settings.baudrate * 1200; baudrate = Settings.baudrate * 1200;
mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
seriallog_level = Settings.seriallog_level; seriallog_level = Settings.seriallog_level;
seriallog_timer = SERIALLOG_TIMER; seriallog_timer = SERIALLOG_TIMER;
#ifndef USE_EMULATION #ifndef USE_EMULATION

View File

@ -20,7 +20,7 @@
#ifndef _SONOFF_VERSION_H_ #ifndef _SONOFF_VERSION_H_
#define _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_
#define VERSION 0x06020112 #define VERSION 0x06020114
#define D_PROGRAMNAME "Sonoff-Tasmota" #define D_PROGRAMNAME "Sonoff-Tasmota"
#define D_AUTHOR "Theo Arends" #define D_AUTHOR "Theo Arends"

View File

@ -715,7 +715,6 @@ boolean GetUsedInModule(byte val, uint8_t *arr)
if (GPIO_RFRECV == val) { return true; } if (GPIO_RFRECV == val) { return true; }
#endif #endif
if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) { if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) {
offset = (GPIO_REL1_INV - GPIO_REL1); offset = (GPIO_REL1_INV - GPIO_REL1);
} }
@ -1558,19 +1557,29 @@ void WifiCheck(uint8_t param)
ota_state_flag = 3; ota_state_flag = 3;
} }
#endif // BE_MINIMAL #endif // BE_MINIMAL
#ifdef USE_DISCOVERY #ifdef USE_DISCOVERY
if (!mdns_begun) { if (!mdns_begun) {
mdns_begun = MDNS.begin(my_hostname); if (mdns_delayed_start) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS "%s"), (mdns_begun) ? D_INITIALIZED : D_FAILED); AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION));
AddLog(LOG_LEVEL_INFO); mdns_delayed_start--;
} else {
mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
mdns_begun = MDNS.begin(my_hostname);
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS "%s"), (mdns_begun) ? D_INITIALIZED : D_FAILED);
AddLog(LOG_LEVEL_INFO);
}
} }
#endif // USE_DISCOVERY #endif // USE_DISCOVERY
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
if (Settings.webserver) { if (Settings.webserver) {
StartWebserver(Settings.webserver, WiFi.localIP()); StartWebserver(Settings.webserver, WiFi.localIP());
#ifdef USE_DISCOVERY #ifdef USE_DISCOVERY
#ifdef WEBSERVER_ADVERTISE #ifdef WEBSERVER_ADVERTISE
MDNS.addService("http", "tcp", WEB_PORT); if (mdns_begun) {
MDNS.addService("http", "tcp", WEB_PORT);
}
#endif // WEBSERVER_ADVERTISE #endif // WEBSERVER_ADVERTISE
#endif // USE_DISCOVERY #endif // USE_DISCOVERY
} else { } else {
@ -1580,12 +1589,14 @@ void WifiCheck(uint8_t param)
if (Settings.flag2.emulation) { UdpConnect(); } if (Settings.flag2.emulation) { UdpConnect(); }
#endif // USE_EMULATION #endif // USE_EMULATION
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
#ifdef USE_KNX #ifdef USE_KNX
if (!knx_started && Settings.flag.knx_enabled) { if (!knx_started && Settings.flag.knx_enabled) {
KNXStart(); KNXStart();
knx_started = true; knx_started = true;
} }
#endif // USE_KNX #endif // USE_KNX
} else { } else {
WifiState(0); WifiState(0);
#if defined(USE_WEBSERVER) && defined(USE_EMULATION) #if defined(USE_WEBSERVER) && defined(USE_EMULATION)
@ -1646,38 +1657,6 @@ void EspRestart()
ESP.restart(); ESP.restart();
} }
#ifdef USE_DISCOVERY
/*********************************************************************************************\
* mDNS
\*********************************************************************************************/
#ifdef MQTT_HOST_DISCOVERY
boolean MdnsDiscoverMqttServer()
{
if (!mdns_begun) {
return false;
}
int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
AddLog(LOG_LEVEL_INFO);
if (n > 0) {
// Note: current strategy is to get the first MQTT service (even when many are found)
snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(0).toString().c_str());
Settings.mqtt_port = MDNS.port(0);
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"),
MDNS.hostname(0).c_str(), Settings.mqtt_host, Settings.mqtt_port);
AddLog(LOG_LEVEL_INFO);
}
return n > 0;
}
#endif // MQTT_HOST_DISCOVERY
#endif // USE_DISCOVERY
/*********************************************************************************************\ /*********************************************************************************************\
* Basic I2C routines * Basic I2C routines
\*********************************************************************************************/ \*********************************************************************************************/

View File

@ -119,7 +119,7 @@ const char HTTP_HEAD_STYLE[] PROGMEM =
#else #else
"<h3>{ha " D_MODULE "</h3>" "<h3>{ha " D_MODULE "</h3>"
#endif #endif
"<h2>{h}</h2></div>"; "<h2>{h}</h2>{j}</div>";
const char HTTP_SCRIPT_CONSOL[] PROGMEM = const char HTTP_SCRIPT_CONSOL[] PROGMEM =
"var sn=0;" // Scroll position "var sn=0;" // Scroll position
"var id=0;" // Get most of weblog initially "var id=0;" // Get most of weblog initially
@ -453,6 +453,25 @@ void ShowPage(String &page, bool auth)
page.replace(F("{a}"), String(Settings.web_refresh)); page.replace(F("{a}"), String(Settings.web_refresh));
page.replace(F("{ha"), my_module.name); page.replace(F("{ha"), my_module.name);
page.replace(F("{h}"), Settings.friendlyname[0]); page.replace(F("{h}"), Settings.friendlyname[0]);
String info = "";
if (Settings.flag3.gui_hostname_ip) {
uint8_t more_ips = 0;
info += F("<h3>"); info += my_hostname;
if (mdns_begun) { info += F(".local"); }
info += F(" (");
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
info += WiFi.localIP().toString();
more_ips++;
}
if (static_cast<uint32_t>(WiFi.softAPIP()) != 0) {
if (more_ips) { info += F(", "); }
info += WiFi.softAPIP().toString();
}
info += F(")</h3>");
}
page.replace(F("{j}"), info);
if (HTTP_MANAGER == webserver_state) { if (HTTP_MANAGER == webserver_state) {
if (WifiConfigCounter()) { if (WifiConfigCounter()) {
page.replace(F("<body>"), F("<body onload='u()'>")); page.replace(F("<body>"), F("<body onload='u()'>"));
@ -1241,6 +1260,7 @@ void HandleInformation()
func += F("}1" D_AP); func += String(Settings.sta_active +1); func += F("}1" D_AP); func += String(Settings.sta_active +1);
func += F(" " D_SSID " (" D_RSSI ")}2"); func += Settings.sta_ssid[Settings.sta_active]; func += F(" ("); func += WifiGetRssiAsQuality(WiFi.RSSI()); func += F("%)"); func += F(" " D_SSID " (" D_RSSI ")}2"); func += Settings.sta_ssid[Settings.sta_active]; func += F(" ("); func += WifiGetRssiAsQuality(WiFi.RSSI()); func += F("%)");
func += F("}1" D_HOSTNAME "}2"); func += my_hostname; func += F("}1" D_HOSTNAME "}2"); func += my_hostname;
if (mdns_begun) { func += F(".local"); }
if (static_cast<uint32_t>(WiFi.localIP()) != 0) { if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
func += F("}1" D_IP_ADDRESS "}2"); func += WiFi.localIP().toString(); func += F("}1" D_IP_ADDRESS "}2"); func += WiFi.localIP().toString();
func += F("}1" D_GATEWAY "}2"); func += IPAddress(Settings.ip_address[1]).toString(); func += F("}1" D_GATEWAY "}2"); func += IPAddress(Settings.ip_address[1]).toString();

View File

@ -197,6 +197,32 @@ void MqttLoop()
/*********************************************************************************************/ /*********************************************************************************************/
#ifdef USE_DISCOVERY
#ifdef MQTT_HOST_DISCOVERY
boolean MqttDiscoverServer()
{
if (!mdns_begun) { return false; }
int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
AddLog(LOG_LEVEL_INFO);
if (n > 0) {
// Note: current strategy is to get the first MQTT service (even when many are found)
snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(0).toString().c_str());
Settings.mqtt_port = MDNS.port(0);
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"),
MDNS.hostname(0).c_str(), Settings.mqtt_host, Settings.mqtt_port);
AddLog(LOG_LEVEL_INFO);
}
return n > 0;
}
#endif // MQTT_HOST_DISCOVERY
#endif // USE_DISCOVERY
int MqttLibraryType() int MqttLibraryType()
{ {
return (int)MQTT_LIBRARY_TYPE; return (int)MQTT_LIBRARY_TYPE;
@ -468,9 +494,7 @@ void MqttReconnect()
#ifndef USE_MQTT_TLS #ifndef USE_MQTT_TLS
#ifdef USE_DISCOVERY #ifdef USE_DISCOVERY
#ifdef MQTT_HOST_DISCOVERY #ifdef MQTT_HOST_DISCOVERY
if (!strlen(Settings.mqtt_host)) { if (!strlen(Settings.mqtt_host) && !MqttDiscoverServer()) { return; }
MdnsDiscoverMqttServer();
}
#endif // MQTT_HOST_DISCOVERY #endif // MQTT_HOST_DISCOVERY
#endif // USE_DISCOVERY #endif // USE_DISCOVERY
#endif // USE_MQTT_TLS #endif // USE_MQTT_TLS
@ -539,6 +563,13 @@ void MqttCheck()
if (!MqttIsConnected()) { if (!MqttIsConnected()) {
global_state.mqtt_down = 1; global_state.mqtt_down = 1;
if (!mqtt_retry_counter) { if (!mqtt_retry_counter) {
#ifndef USE_MQTT_TLS
#ifdef USE_DISCOVERY
#ifdef MQTT_HOST_DISCOVERY
if (!strlen(Settings.mqtt_host) && !mdns_begun) { return; }
#endif // MQTT_HOST_DISCOVERY
#endif // USE_DISCOVERY
#endif // USE_MQTT_TLS
MqttReconnect(); MqttReconnect();
} else { } else {
mqtt_retry_counter--; mqtt_retry_counter--;

View File

@ -809,6 +809,11 @@ void HandleHueApi(String *path)
* user part and allow every caller as with Web or WeMo. * user part and allow every caller as with Web or WeMo.
* *
* (c) Heiko Krupp, 2017 * (c) Heiko Krupp, 2017
*
* Hue URL
* http://sonoff/api/username/lights/1/state with post data {"on":true,"hue":56100,"sat":254,"bri":254,"alert":"none","transitiontime":40}
* is converted by webserver to
* http://sonoff/api/username/lights/1/state with arg plain={"on":true,"hue":56100,"sat":254,"bri":254,"alert":"none","transitiontime":40}
*/ */
uint8_t args = 0; uint8_t args = 0;

View File

@ -27,8 +27,8 @@
* I2C Address: 0x76 or 0x77 * I2C Address: 0x76 or 0x77
\*********************************************************************************************/ \*********************************************************************************************/
#define BMP_ADDR1 0x77 #define BMP_ADDR1 0x76
#define BMP_ADDR2 0x76 #define BMP_ADDR2 0x77
#define BMP180_CHIPID 0x55 #define BMP180_CHIPID 0x55
#define BMP280_CHIPID 0x58 #define BMP280_CHIPID 0x58
@ -37,18 +37,27 @@
#define BMP_REGISTER_CHIPID 0xD0 #define BMP_REGISTER_CHIPID 0xD0
#define BMP_MAX_SENSORS 2
const char kBmpTypes[] PROGMEM = "BMP180|BMP280|BME280|BME680"; const char kBmpTypes[] PROGMEM = "BMP180|BMP280|BME280|BME680";
uint8_t bmp_address;
uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 }; uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 };
uint8_t bmp_type = 0; uint8_t bmp_count = 0;
uint8_t bmp_model = 0;
char bmp_name[7];
uint8_t bmp_valid = 0; struct BMPSTRUCT {
float bmp_temperature = 0.0; uint8_t bmp_address; // I2C bus address
float bmp_pressure = 0.0; char bmp_name[7]; // Sensor name - "BMPXXX"
float bmp_humidity = 0.0; uint8_t bmp_type = 0;
uint8_t bmp_model = 0;
uint8_t bmp_valid = 0;
#ifdef USE_BME680
uint8_t bme680_state = 0;
float bmp_gas_resistance = 0.0;
#endif // USE_BME680
float bmp_temperature = 0.0;
float bmp_pressure = 0.0;
float bmp_humidity = 0.0;
} bmp_sensors[BMP_MAX_SENSORS];
/*********************************************************************************************\ /*********************************************************************************************\
* BMP085 and BME180 * BMP085 and BME180
@ -84,18 +93,18 @@ uint16_t cal_ac4;
uint16_t cal_ac5; uint16_t cal_ac5;
uint16_t cal_ac6; uint16_t cal_ac6;
boolean Bmp180Calibration() boolean Bmp1802xCalibration(uint8_t bmp_idx)
{ {
cal_ac1 = I2cRead16(bmp_address, BMP180_AC1); cal_ac1 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC1);
cal_ac2 = I2cRead16(bmp_address, BMP180_AC2); cal_ac2 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC2);
cal_ac3 = I2cRead16(bmp_address, BMP180_AC3); cal_ac3 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC3);
cal_ac4 = I2cRead16(bmp_address, BMP180_AC4); cal_ac4 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC4);
cal_ac5 = I2cRead16(bmp_address, BMP180_AC5); cal_ac5 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC5);
cal_ac6 = I2cRead16(bmp_address, BMP180_AC6); cal_ac6 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC6);
cal_b1 = I2cRead16(bmp_address, BMP180_VB1); cal_b1 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_VB1);
cal_b2 = I2cRead16(bmp_address, BMP180_VB2); cal_b2 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_VB2);
cal_mc = I2cRead16(bmp_address, BMP180_MC); cal_mc = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_MC);
cal_md = I2cRead16(bmp_address, BMP180_MD); cal_md = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_MD);
// Check for Errors in calibration data. Value never is 0x0000 or 0xFFFF // Check for Errors in calibration data. Value never is 0x0000 or 0xFFFF
if (!cal_ac1 | !cal_ac2 | !cal_ac3 | !cal_ac4 | !cal_ac5 | !cal_ac6 | !cal_b1 | !cal_b2 | !cal_mc | !cal_md) { if (!cal_ac1 | !cal_ac2 | !cal_ac3 | !cal_ac4 | !cal_ac5 | !cal_ac6 | !cal_b1 | !cal_b2 | !cal_mc | !cal_md) {
@ -117,19 +126,20 @@ boolean Bmp180Calibration()
return true; return true;
} }
void Bmp180Read() void Bmp1802xRead(uint8_t bmp_idx)
{ {
I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE);
I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE);
delay(5); // 5ms conversion time delay(5); // 5ms conversion time
int ut = I2cRead16(bmp_address, BMP180_REG_RESULT); int ut = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT);
int32_t xt1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15; int32_t xt1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15;
int32_t xt2 = ((int32_t)cal_mc << 11) / (xt1 + (int32_t)cal_md); int32_t xt2 = ((int32_t)cal_mc << 11) / (xt1 + (int32_t)cal_md);
int32_t bmp180_b5 = xt1 + xt2; int32_t bmp180_b5 = xt1 + xt2;
bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0; bmp_sensors[bmp_idx].bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0;
I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution
delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution
uint32_t up = I2cRead24(bmp_address, BMP180_REG_RESULT); uint32_t up = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT);
up >>= (8 - BMP180_OSS); up >>= (8 - BMP180_OSS);
int32_t b6 = bmp180_b5 - 4000; int32_t b6 = bmp180_b5 - 4000;
@ -155,7 +165,7 @@ void Bmp180Read()
x1 = (x1 * 3038) >> 16; x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16; x2 = (-7357 * p) >> 16;
p += ((x1 + x2 + (int32_t)3791) >> 4); p += ((x1 + x2 + (int32_t)3791) >> 4);
bmp_pressure = (float)p / 100.0; // convert to mbar bmp_sensors[bmp_idx].bmp_pressure = (float)p / 100.0; // convert to mbar
} }
/*********************************************************************************************\ /*********************************************************************************************\
@ -212,45 +222,45 @@ struct BME280CALIBDATA
int8_t dig_H6; int8_t dig_H6;
} Bme280CalibrationData; } Bme280CalibrationData;
boolean Bmx280Calibrate() boolean Bmx2802xCalibrate(uint8_t bmp_idx)
{ {
// if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false; // if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false;
Bme280CalibrationData.dig_T1 = I2cRead16LE(bmp_address, BME280_REGISTER_DIG_T1); Bme280CalibrationData.dig_T1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T1);
Bme280CalibrationData.dig_T2 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_T2); Bme280CalibrationData.dig_T2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T2);
Bme280CalibrationData.dig_T3 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_T3); Bme280CalibrationData.dig_T3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T3);
Bme280CalibrationData.dig_P1 = I2cRead16LE(bmp_address, BME280_REGISTER_DIG_P1); Bme280CalibrationData.dig_P1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P1);
Bme280CalibrationData.dig_P2 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P2); Bme280CalibrationData.dig_P2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P2);
Bme280CalibrationData.dig_P3 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P3); Bme280CalibrationData.dig_P3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P3);
Bme280CalibrationData.dig_P4 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P4); Bme280CalibrationData.dig_P4 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P4);
Bme280CalibrationData.dig_P5 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P5); Bme280CalibrationData.dig_P5 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P5);
Bme280CalibrationData.dig_P6 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P6); Bme280CalibrationData.dig_P6 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P6);
Bme280CalibrationData.dig_P7 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P7); Bme280CalibrationData.dig_P7 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P7);
Bme280CalibrationData.dig_P8 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P8); Bme280CalibrationData.dig_P8 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P8);
Bme280CalibrationData.dig_P9 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P9); Bme280CalibrationData.dig_P9 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P9);
if (BME280_CHIPID == bmp_type) { // #1051 if (BME280_CHIPID == bmp_sensors[bmp_idx].bmp_type) { // #1051
Bme280CalibrationData.dig_H1 = I2cRead8(bmp_address, BME280_REGISTER_DIG_H1); Bme280CalibrationData.dig_H1 = I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H1);
Bme280CalibrationData.dig_H2 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_H2); Bme280CalibrationData.dig_H2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H2);
Bme280CalibrationData.dig_H3 = I2cRead8(bmp_address, BME280_REGISTER_DIG_H3); Bme280CalibrationData.dig_H3 = I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H3);
Bme280CalibrationData.dig_H4 = (I2cRead8(bmp_address, BME280_REGISTER_DIG_H4) << 4) | (I2cRead8(bmp_address, BME280_REGISTER_DIG_H4 + 1) & 0xF); Bme280CalibrationData.dig_H4 = (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H4) << 4) | (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H4 + 1) & 0xF);
Bme280CalibrationData.dig_H5 = (I2cRead8(bmp_address, BME280_REGISTER_DIG_H5 + 1) << 4) | (I2cRead8(bmp_address, BME280_REGISTER_DIG_H5) >> 4); Bme280CalibrationData.dig_H5 = (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H5 + 1) << 4) | (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H5) >> 4);
Bme280CalibrationData.dig_H6 = (int8_t)I2cRead8(bmp_address, BME280_REGISTER_DIG_H6); Bme280CalibrationData.dig_H6 = (int8_t)I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H6);
I2cWrite8(bmp_address, BME280_REGISTER_CONTROL, 0x00); // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27) I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0x00); // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27)
// Set before CONTROL_meas (DS 5.4.3) // Set before CONTROL_meas (DS 5.4.3)
I2cWrite8(bmp_address, BME280_REGISTER_CONTROLHUMID, 0x01); // 1x oversampling I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROLHUMID, 0x01); // 1x oversampling
I2cWrite8(bmp_address, BME280_REGISTER_CONFIG, 0xA0); // 1sec standby between measurements (to limit self heating), IIR filter off I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONFIG, 0xA0); // 1sec standby between measurements (to limit self heating), IIR filter off
I2cWrite8(bmp_address, BME280_REGISTER_CONTROL, 0x27); // 1x oversampling, normal mode I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0x27); // 1x oversampling, normal mode
} else { } else {
I2cWrite8(bmp_address, BME280_REGISTER_CONTROL, 0xB7); // 16x oversampling, normal mode (Adafruit) I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0xB7); // 16x oversampling, normal mode (Adafruit)
} }
return true; return true;
} }
void Bme280Read(void) void Bme2802xRead(uint8_t bmp_idx)
{ {
int32_t adc_T = I2cRead24(bmp_address, BME280_REGISTER_TEMPDATA); int32_t adc_T = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_TEMPDATA);
adc_T >>= 4; adc_T >>= 4;
int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11; int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11;
@ -258,9 +268,9 @@ void Bme280Read(void)
((int32_t)Bme280CalibrationData.dig_T3)) >> 14; ((int32_t)Bme280CalibrationData.dig_T3)) >> 14;
int32_t t_fine = vart1 + vart2; int32_t t_fine = vart1 + vart2;
float T = (t_fine * 5 + 128) >> 8; float T = (t_fine * 5 + 128) >> 8;
bmp_temperature = T / 100.0; bmp_sensors[bmp_idx].bmp_temperature = T / 100.0;
int32_t adc_P = I2cRead24(bmp_address, BME280_REGISTER_PRESSUREDATA); int32_t adc_P = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_PRESSUREDATA);
adc_P >>= 4; adc_P >>= 4;
int64_t var1 = ((int64_t)t_fine) - 128000; int64_t var1 = ((int64_t)t_fine) - 128000;
@ -277,11 +287,11 @@ void Bme280Read(void)
var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25; var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19; var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData.dig_P7) << 4); p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData.dig_P7) << 4);
bmp_pressure = (float)p / 25600.0; bmp_sensors[bmp_idx].bmp_pressure = (float)p / 25600.0;
if (BMP280_CHIPID == bmp_type) { return; } if (BMP280_CHIPID == bmp_sensors[bmp_idx].bmp_type) { return; }
int32_t adc_H = I2cRead16(bmp_address, BME280_REGISTER_HUMIDDATA); int32_t adc_H = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_HUMIDDATA);
int32_t v_x1_u32r = (t_fine - ((int32_t)76800)); int32_t v_x1_u32r = (t_fine - ((int32_t)76800));
v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) - v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) -
@ -294,7 +304,7 @@ void Bme280Read(void)
v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
float h = (v_x1_u32r >> 12); float h = (v_x1_u32r >> 12);
bmp_humidity = h / 1024.0; bmp_sensors[bmp_idx].bmp_humidity = h / 1024.0;
} }
#ifdef USE_BME680 #ifdef USE_BME680
@ -306,17 +316,14 @@ void Bme280Read(void)
struct bme680_dev gas_sensor; struct bme680_dev gas_sensor;
float bmp_gas_resistance = 0.0;
uint8_t bme680_state = 0;
static void BmeDelayMs(uint32_t ms) static void BmeDelayMs(uint32_t ms)
{ {
delay(ms); delay(ms);
} }
boolean Bme680Init() boolean Bme6802xInit(uint8_t bmp_idx)
{ {
gas_sensor.dev_id = bmp_address; gas_sensor.dev_id = bmp_sensors[bmp_idx].bmp_address;
gas_sensor.intf = BME680_I2C_INTF; gas_sensor.intf = BME680_I2C_INTF;
gas_sensor.read = &I2cReadBuffer; gas_sensor.read = &I2cReadBuffer;
gas_sensor.write = &I2cWriteBuffer; gas_sensor.write = &I2cWriteBuffer;
@ -353,17 +360,17 @@ boolean Bme680Init()
rslt = bme680_set_sensor_settings(set_required_settings,&gas_sensor); rslt = bme680_set_sensor_settings(set_required_settings,&gas_sensor);
if (rslt != BME680_OK) { return false; } if (rslt != BME680_OK) { return false; }
bme680_state = 0; bmp_sensors[bmp_idx].bme680_state = 0;
return true; return true;
} }
void Bme680Read() void Bme6802xRead(uint8_t bmp_idx)
{ {
int8_t rslt = BME680_OK; int8_t rslt = BME680_OK;
if (BME680_CHIPID == bmp_type) { if (BME680_CHIPID == bmp_sensors[bmp_idx].bmp_type) {
if (0 == bme680_state) { if (0 == bmp_sensors[bmp_idx].bme680_state) {
/* Trigger the next measurement if you would like to read data out continuously */ /* Trigger the next measurement if you would like to read data out continuously */
rslt = bme680_set_sensor_mode(&gas_sensor); rslt = bme680_set_sensor_mode(&gas_sensor);
if (rslt != BME680_OK) { return; } if (rslt != BME680_OK) { return; }
@ -374,22 +381,22 @@ void Bme680Read()
// bme680_get_profile_dur(&meas_period, &gas_sensor); // bme680_get_profile_dur(&meas_period, &gas_sensor);
// delay(meas_period); /* Delay till the measurement is ready */ // 183 mSec - we'll wait a second // delay(meas_period); /* Delay till the measurement is ready */ // 183 mSec - we'll wait a second
bme680_state = 1; bmp_sensors[bmp_idx].bme680_state = 1;
} else { } else {
bme680_state = 0; bmp_sensors[bmp_idx].bme680_state = 0;
struct bme680_field_data data; struct bme680_field_data data;
rslt = bme680_get_sensor_data(&data, &gas_sensor); rslt = bme680_get_sensor_data(&data, &gas_sensor);
if (rslt != BME680_OK) { return; } if (rslt != BME680_OK) { return; }
bmp_temperature = data.temperature / 100.0; bmp_sensors[bmp_idx].bmp_temperature = data.temperature / 100.0;
bmp_humidity = data.humidity / 1000.0; bmp_sensors[bmp_idx].bmp_humidity = data.humidity / 1000.0;
bmp_pressure = data.pressure / 100.0; bmp_sensors[bmp_idx].bmp_pressure = data.pressure / 100.0;
/* Avoid using measurements from an unstable heating setup */ /* Avoid using measurements from an unstable heating setup */
if (data.status & BME680_GASM_VALID_MSK) { if (data.status & BME680_GASM_VALID_MSK) {
bmp_gas_resistance = data.gas_resistance / 1000.0; bmp_sensors[bmp_idx].bmp_gas_resistance = data.gas_resistance / 1000.0;
} else { } else {
bmp_gas_resistance = 0; bmp_sensors[bmp_idx].bmp_gas_resistance = 0;
} }
} }
} }
@ -402,65 +409,66 @@ void Bme680Read()
void BmpDetect() void BmpDetect()
{ {
if (bmp_type) { return; } if (bmp_count) return;
for (byte i = 0; i < sizeof(bmp_addresses); i++) { for (byte i = 0; i < BMP_MAX_SENSORS; i++) {
bmp_address = bmp_addresses[i]; uint8_t bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID);
bmp_type = I2cRead8(bmp_address, BMP_REGISTER_CHIPID);
if (bmp_type) { if (bmp_type) {
break; bmp_sensors[bmp_count].bmp_address = bmp_addresses[i];
} bmp_sensors[bmp_count].bmp_type = bmp_type;
} bmp_sensors[bmp_count].bmp_model = 0;
if (bmp_type) {
bmp_model = 0; boolean success = false;
boolean success = false; switch (bmp_type) {
switch (bmp_type) { case BMP180_CHIPID:
case BMP180_CHIPID: success = Bmp1802xCalibration(bmp_count);
success = Bmp180Calibration(); break;
break; case BME280_CHIPID:
case BME280_CHIPID: bmp_sensors[bmp_count].bmp_model++; // 2
bmp_model++; // 2 case BMP280_CHIPID:
case BMP280_CHIPID: bmp_sensors[bmp_count].bmp_model++; // 1
bmp_model++; // 1 success = Bmx2802xCalibrate(bmp_count);
success = Bmx280Calibrate(); break;
break; #ifdef USE_BME680
#ifdef USE_BME680 case BME680_CHIPID:
case BME680_CHIPID: bmp_sensors[bmp_count].bmp_model = 3; // 3
bmp_model = 3; // 3 success = Bme6802xInit(bmp_count);
success = Bme680Init(); break;
break; #endif // USE_BME680
#endif // USE_BME680 }
} if (success) {
if (success) { GetTextIndexed(bmp_sensors[bmp_count].bmp_name, sizeof(bmp_sensors[bmp_count].bmp_name), bmp_sensors[bmp_count].bmp_model, kBmpTypes);
GetTextIndexed(bmp_name, sizeof(bmp_name), bmp_model, kBmpTypes); snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp_sensors[bmp_count].bmp_name, bmp_sensors[bmp_count].bmp_address);
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp_name, bmp_address); AddLog(LOG_LEVEL_DEBUG);
AddLog(LOG_LEVEL_DEBUG); bmp_count++;
} }
else {
bmp_type = 0;
} }
} }
} }
void BmpRead() void BmpRead()
{ {
switch (bmp_type) { for (byte bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) {
case BMP180_CHIPID: switch (bmp_sensors[bmp_idx].bmp_type) {
Bmp180Read(); case BMP180_CHIPID:
break; Bmp1802xRead(bmp_idx);
case BMP280_CHIPID: break;
case BME280_CHIPID: case BMP280_CHIPID:
Bme280Read(); case BME280_CHIPID:
break; Bme2802xRead(bmp_idx);
#ifdef USE_BME680 break;
case BME680_CHIPID: #ifdef USE_BME680
Bme680Read(); case BME680_CHIPID:
break; Bme6802xRead(bmp_idx);
#endif // USE_BME680 break;
#endif // USE_BME680
}
if (bmp_sensors[bmp_idx].bmp_temperature != 0.0) {
bmp_sensors[bmp_idx].bmp_temperature = ConvertTemp(bmp_sensors[bmp_idx].bmp_temperature);
}
} }
if (bmp_temperature != 0.0) { bmp_temperature = ConvertTemp(bmp_temperature); }
SetGlobalValues(bmp_temperature, bmp_humidity); SetGlobalValues(bmp_sensors[0].bmp_temperature, bmp_sensors[0].bmp_humidity);
} }
void BmpEverySecond() void BmpEverySecond()
@ -477,72 +485,91 @@ void BmpEverySecond()
void BmpShow(boolean json) void BmpShow(boolean json)
{ {
if (bmp_type) { for (byte bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) {
float bmp_sealevel = 0.0; if (bmp_sensors[bmp_idx].bmp_type) {
char temperature[10]; float bmp_sealevel = 0.0;
char pressure[10]; char temperature[10];
char sea_pressure[10]; char pressure[10];
char humidity[10]; char sea_pressure[10];
char humidity[10];
char name[10];
if (bmp_pressure != 0.0) { if (bmp_sensors[bmp_idx].bmp_pressure != 0.0) {
bmp_sealevel = (bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; bmp_sealevel = (bmp_sensors[bmp_idx].bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6;
}
dtostrfd(bmp_temperature, Settings.flag2.temperature_resolution, temperature);
dtostrfd(bmp_pressure, Settings.flag2.pressure_resolution, pressure);
dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure);
dtostrfd(bmp_humidity, Settings.flag2.humidity_resolution, humidity);
#ifdef USE_BME680
char gas_resistance[10];
dtostrfd(bmp_gas_resistance, 2, gas_resistance);
#endif // USE_BME680
if (json) {
char json_humidity[40];
snprintf_P(json_humidity, sizeof(json_humidity), PSTR(",\"" D_JSON_HUMIDITY "\":%s"), humidity);
char json_sealevel[40];
snprintf_P(json_sealevel, sizeof(json_sealevel), PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure);
#ifdef USE_BME680
char json_gas[40];
snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"),
mqtt_data, bmp_name, temperature, (bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : "", (bmp_model >= 3) ? json_gas : "");
#else
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"),
mqtt_data, bmp_name, temperature, (bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : "");
#endif // USE_BME680
#ifdef USE_DOMOTICZ
if (0 == tele_period) {
DomoticzTempHumPressureSensor(temperature, humidity, pressure);
#ifdef USE_BME680
if (bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp_gas_resistance); }
#endif // USE_BME680
} }
snprintf(name, sizeof(name), bmp_sensors[bmp_idx].bmp_name);
if (bmp_count > 1) {
snprintf_P(name, sizeof(name), PSTR("%s-%02X"), name, bmp_sensors[bmp_idx].bmp_address); // BMXXXX-XX
}
dtostrfd(bmp_sensors[bmp_idx].bmp_temperature, Settings.flag2.temperature_resolution, temperature);
dtostrfd(bmp_sensors[bmp_idx].bmp_pressure, Settings.flag2.pressure_resolution, pressure);
dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure);
dtostrfd(bmp_sensors[bmp_idx].bmp_humidity, Settings.flag2.humidity_resolution, humidity);
#ifdef USE_BME680
char gas_resistance[10];
dtostrfd(bmp_sensors[bmp_idx].bmp_gas_resistance, 2, gas_resistance);
#endif // USE_BME680
if (json) {
char json_humidity[40];
snprintf_P(json_humidity, sizeof(json_humidity), PSTR(",\"" D_JSON_HUMIDITY "\":%s"), humidity);
char json_sealevel[40];
snprintf_P(json_sealevel, sizeof(json_sealevel), PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure);
#ifdef USE_BME680
char json_gas[40];
snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance);
snprintf_P(mqtt_data,
sizeof(mqtt_data),
PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"),
mqtt_data,
name,
temperature,
(bmp_sensors[bmp_idx].bmp_model >= 2) ? json_humidity : "",
pressure,
(Settings.altitude != 0) ? json_sealevel : "",
(bmp_sensors[bmp_idx].bmp_model >= 3) ? json_gas : ""
);
#else
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"),
mqtt_data, name, temperature, (bmp_sensors[bmp_idx].bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : "");
#endif // USE_BME680
#ifdef USE_DOMOTICZ
if ((0 == tele_period) && (0 == bmp_idx)) { // We want the same first sensor to report to Domoticz in case a read is missed
DomoticzTempHumPressureSensor(temperature, humidity, pressure);
#ifdef USE_BME680
if (bmp_sensors[bmp_idx].bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp_sensors[bmp_idx].bmp_gas_resistance); }
#endif // USE_BME680
}
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
#ifdef USE_KNX #ifdef USE_KNX
if (0 == tele_period) { if (0 == tele_period) {
KnxSensor(KNX_TEMPERATURE, bmp_temperature); KnxSensor(KNX_TEMPERATURE, bmp_sensors[bmp_idx].bmp_temperature);
KnxSensor(KNX_HUMIDITY, bmp_humidity); KnxSensor(KNX_HUMIDITY, bmp_sensors[bmp_idx].bmp_humidity);
} }
#endif // USE_KNX #endif // USE_KNX
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, bmp_name, temperature, TempUnit()); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, name, temperature, TempUnit());
if (bmp_model >= 2) { if (bmp_sensors[bmp_idx].bmp_model >= 2) {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, bmp_name, humidity); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, name, humidity);
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PRESSURE, mqtt_data, bmp_name, pressure); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PRESSURE, mqtt_data, name, pressure);
if (Settings.altitude != 0) { if (Settings.altitude != 0) {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, bmp_name, sea_pressure); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, name, sea_pressure);
} }
#ifdef USE_BME680 #ifdef USE_BME680
if (bmp_model >= 3) { if (bmp_sensors[bmp_idx].bmp_model >= 3) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{s}%s " D_GAS "{m}%s " D_UNIT_KILOOHM "{e}"), mqtt_data, bmp_name, gas_resistance); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{s}%s " D_GAS "{m}%s " D_UNIT_KILOOHM "{e}"), mqtt_data, name, gas_resistance);
} }
#endif // USE_BME680 #endif // USE_BME680
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
VER = '2.0.0000' VER = '2.0.0001'
""" """
decode-config.py - Backup/Restore Sonoff-Tasmota configuration data decode-config.py - Backup/Restore Sonoff-Tasmota configuration data
@ -201,7 +201,7 @@ DEFAULTS = {
'jsonsort': True, 'jsonsort': True,
'jsonrawvalues':False, 'jsonrawvalues':False,
'jsonrawkeys': False, 'jsonrawkeys': False,
'jsonhidepw': True, 'jsonhidepw': False,
}, },
} }
args = {} args = {}
@ -250,21 +250,27 @@ Settings dictionary describes the config file fields definition:
negative <s> shift the result <s> left bits negative <s> shift the result <s> left bits
datadef datadef
Define the field interpretation different from simple Data definition, is either a array definition or a
standard types (like char, byte, int) e. g. lists or bit fields tuple containing an array definition and min/max values
Can be None, a single integer, a list or a dictionary Format: arraydef|(arraydef, min, max)
None: arraydef:
None must be given if the field contains a simple value None:
desrcibed by the <format> prefix None must be given if the field contains a
n: simple value desrcibed by the <format> prefix
Same as [n] below n:
[n]: [n]:
Defines a one-dimensional array of size <n> Defines a one-dimensional array of size <n>
[n, n <,n...>] [n, m <,o...>]
Defines a multi-dimensional array Defines a multi-dimensional array
min:
defines a minimum valid value or None if all values
for this format is allowed.
max:
defines a maximum valid value or None if all values
for this format is allowed.
converter (optional) converter (optional)
Conversion methode(s): ()|'xxx'|func Conversion methode(s): 'xxx'|func or ('xxx'|func, 'xxx'|func)
Read conversion is used if args.jsonrawvalues is False Read conversion is used if args.jsonrawvalues is False
Write conversion is used if jsonrawvalues from restore json Write conversion is used if jsonrawvalues from restore json
file is False or args.jsonrawvalues is False. file is False or args.jsonrawvalues is False.
@ -845,7 +851,19 @@ Setting_6_2_1_19.update({
'weight_max': ('<L', 0x7B8, None, ('float($) / 10', 'int($ * 10)')), 'weight_max': ('<L', 0x7B8, None, ('float($) / 10', 'int($ * 10)')),
}) })
Setting_6_2_1_20 = Setting_6_2_1_19
Setting_6_2_1_20.update({
'flag3': ({
'raw': ('<L', 0x3A0, None, ('"0x{:08x}".format($)', None)),
'timers_enable': ('<L', (0x3A0, 1, 0), None),
'user_esp8285_enable': ('<L', (0x3A0, 1, 1), None),
'time_append_timezone':('<L', (0x3A0, 1, 2), None),
'gui_hostname_ip': ('<L', (0x3A0, 1, 3), None),
}, 0x3A0, None),
})
Settings = [ Settings = [
(0x6020114, 0xe00, Setting_6_2_1_20),
(0x6020113, 0xe00, Setting_6_2_1_19), (0x6020113, 0xe00, Setting_6_2_1_19),
(0x602010E, 0xe00, Setting_6_2_1_14), (0x602010E, 0xe00, Setting_6_2_1_14),
(0x602010A, 0xe00, Setting_6_2_1_10), (0x602010A, 0xe00, Setting_6_2_1_10),
@ -892,21 +910,22 @@ def GetTemplateSetting(decode_cfg):
@return: @return:
version, template, size, settings to use; None if version is invalid version, template, size, settings to use; None if version is invalid
""" """
version = 0x0
template = size = setting = None
try: try:
version = GetField(decode_cfg, 'version', Setting_6_2_1['version'], raw=True) version = GetField(decode_cfg, 'version', Setting_6_2_1['version'], raw=True)
# search setting definition
template = None
setting = None
size = None
for cfg in Settings:
if version >= cfg[0]:
template = cfg
size = template[1]
setting = template[2]
break
except: except:
return None,None,None,None pass
# search setting definition
template = None
setting = None
size = None
for cfg in Settings:
if version >= cfg[0]:
template = cfg
size = template[1]
setting = template[2]
break
return version, template, size, setting return version, template, size, setting
@ -1652,6 +1671,9 @@ def GetField(dobj, fieldname, fielddef, raw=False, addroffset=0):
result = None result = None
if fieldname == 'raw' and not args.jsonrawkeys:
return result
# get field definition # get field definition
_format, baseaddr, bits, bitshift, datadef, convert = GetFieldDef(fielddef) _format, baseaddr, bits, bitshift, datadef, convert = GetFieldDef(fielddef)
@ -1662,7 +1684,7 @@ def GetField(dobj, fieldname, fielddef, raw=False, addroffset=0):
for i in range(0, datadef[0]): for i in range(0, datadef[0]):
subfielddef = GetSubfieldDef(fielddef) subfielddef = GetSubfieldDef(fielddef)
length = GetFieldLength(subfielddef) length = GetFieldLength(subfielddef)
if length != 0 and (fieldname != 'raw' or args.jsonrawkeys): if length != 0:
result.append(GetField(dobj, fieldname, subfielddef, raw=raw, addroffset=addroffset+offset)) result.append(GetField(dobj, fieldname, subfielddef, raw=raw, addroffset=addroffset+offset))
offset += length offset += length
@ -1722,6 +1744,9 @@ def SetField(dobj, fieldname, fielddef, restore, raw=False, addroffset=0, filena
_format, baseaddr, bits, bitshift, datadef, convert = GetFieldDef(fielddef) _format, baseaddr, bits, bitshift, datadef, convert = GetFieldDef(fielddef)
fieldname = str(fieldname) fieldname = str(fieldname)
if fieldname == 'raw' and not args.jsonrawkeys:
return dobj
# do not write readonly values # do not write readonly values
if isinstance(convert, (list,tuple)) and len(convert)>1 and convert[1]==None: if isinstance(convert, (list,tuple)) and len(convert)>1 and convert[1]==None:
if args.debug: if args.debug: