v5.9.1b - Add INA219 support

5.9.1b
 * Remove spaces in JSON messages
 * Add support for INA219
Voltage and Current sensor to be enabled in user_config.h
This commit is contained in:
arendst 2017-11-11 12:33:30 +01:00
parent 7098d058b1
commit 83a9c0693a
32 changed files with 605 additions and 269 deletions

View File

@ -1,7 +1,7 @@
## Sonoff-Tasmota ## 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. 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.9.1a** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. Current version is **5.9.1b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
### ATTENTION All versions ### ATTENTION All versions

View File

@ -1,4 +1,8 @@
/* 5.9.1a /* 5.9.1b
* Remove spaces in JSON messages
* Add support for INA219 Voltage and Current sensor to be enabled in user_config.h
*
* 5.9.1a
* Fix PWM watchdog timeout if Dimmer is set to 100 or Color set to 0xFF (#1146) * Fix PWM watchdog timeout if Dimmer is set to 100 or Color set to 0xFF (#1146)
* *
* 5.9.1 20171107 * 5.9.1 20171107

View File

@ -77,7 +77,7 @@ const char S_JSON_COMMAND_INDEX_NVALUE[] PROGMEM = "{\"%s%d\":%d}";
const char S_JSON_COMMAND_INDEX_SVALUE[] PROGMEM = "{\"%s%d\":\"%s\"}"; const char S_JSON_COMMAND_INDEX_SVALUE[] PROGMEM = "{\"%s%d\":\"%s\"}";
const char S_JSON_COMMAND_INDEX_SVALUE_SVALUE[] PROGMEM = "{\"%s%d\":\"%s%s\"}"; const char S_JSON_COMMAND_INDEX_SVALUE_SVALUE[] PROGMEM = "{\"%s%d\":\"%s%s\"}";
const char JSON_SNS_TEMPHUM[] PROGMEM = "%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s}"; const char JSON_SNS_TEMPHUM[] PROGMEM = "%s,\"%s\":{\"" D_TEMPERATURE "\":%s,\"" D_HUMIDITY "\":%s}";
const char S_LOG_I2C_FOUND_AT[] PROGMEM = D_LOG_I2C "%s " D_FOUND_AT " 0x%x"; const char S_LOG_I2C_FOUND_AT[] PROGMEM = D_LOG_I2C "%s " D_FOUND_AT " 0x%x";

View File

@ -573,6 +573,7 @@
#define D_CMND_PRESSURE_RESOLUTION "PressRes" #define D_CMND_PRESSURE_RESOLUTION "PressRes"
#define D_CMND_POWER_RESOLUTION "WattRes" #define D_CMND_POWER_RESOLUTION "WattRes"
#define D_CMND_VOLTAGE_RESOLUTION "VoltRes" #define D_CMND_VOLTAGE_RESOLUTION "VoltRes"
#define D_CMND_CURRENT_RESOLUTION "AmpRes"
#define D_CMND_ENERGY_RESOLUTION "EnergyRes" #define D_CMND_ENERGY_RESOLUTION "EnergyRes"
#define D_CMND_MODULE "Module" #define D_CMND_MODULE "Module"
#define D_CMND_MODULES "Modules" #define D_CMND_MODULES "Modules"
@ -629,6 +630,7 @@
#define D_CMND_LEDSTATE "LedState" #define D_CMND_LEDSTATE "LedState"
#define D_CMND_CFGDUMP "CfgDump" #define D_CMND_CFGDUMP "CfgDump"
#define D_CMND_I2CSCAN "I2CScan" #define D_CMND_I2CSCAN "I2CScan"
#define D_CMND_INA219MODE "Ina219Mode"
#define D_CMND_EXCEPTION "Exception" #define D_CMND_EXCEPTION "Exception"
// Commands xdrv_domoticz.ino // Commands xdrv_domoticz.ino

View File

@ -573,6 +573,7 @@
#define D_CMND_PRESSURE_RESOLUTION "PressRes" #define D_CMND_PRESSURE_RESOLUTION "PressRes"
#define D_CMND_POWER_RESOLUTION "WattRes" #define D_CMND_POWER_RESOLUTION "WattRes"
#define D_CMND_VOLTAGE_RESOLUTION "VoltRes" #define D_CMND_VOLTAGE_RESOLUTION "VoltRes"
#define D_CMND_CURRENT_RESOLUTION "AmpRes"
#define D_CMND_ENERGY_RESOLUTION "EnergyRes" #define D_CMND_ENERGY_RESOLUTION "EnergyRes"
#define D_CMND_MODULE "Module" #define D_CMND_MODULE "Module"
#define D_CMND_MODULES "Modules" #define D_CMND_MODULES "Modules"
@ -629,6 +630,7 @@
#define D_CMND_LEDSTATE "LedState" #define D_CMND_LEDSTATE "LedState"
#define D_CMND_CFGDUMP "CfgDump" #define D_CMND_CFGDUMP "CfgDump"
#define D_CMND_I2CSCAN "I2CScan" #define D_CMND_I2CSCAN "I2CScan"
#define D_CMND_INA219MODE "Ina219Mode"
#define D_CMND_EXCEPTION "Exception" #define D_CMND_EXCEPTION "Exception"
// Commands xdrv_domoticz.ino // Commands xdrv_domoticz.ino

View File

@ -573,6 +573,7 @@
#define D_CMND_PRESSURE_RESOLUTION "PressRes" #define D_CMND_PRESSURE_RESOLUTION "PressRes"
#define D_CMND_POWER_RESOLUTION "WattRes" #define D_CMND_POWER_RESOLUTION "WattRes"
#define D_CMND_VOLTAGE_RESOLUTION "VoltRes" #define D_CMND_VOLTAGE_RESOLUTION "VoltRes"
#define D_CMND_CURRENT_RESOLUTION "AmpRes"
#define D_CMND_ENERGY_RESOLUTION "EnergyRes" #define D_CMND_ENERGY_RESOLUTION "EnergyRes"
#define D_CMND_MODULE "Module" #define D_CMND_MODULE "Module"
#define D_CMND_MODULES "Modules" #define D_CMND_MODULES "Modules"
@ -629,6 +630,7 @@
#define D_CMND_LEDSTATE "LedState" #define D_CMND_LEDSTATE "LedState"
#define D_CMND_CFGDUMP "CfgDump" #define D_CMND_CFGDUMP "CfgDump"
#define D_CMND_I2CSCAN "I2CScan" #define D_CMND_I2CSCAN "I2CScan"
#define D_CMND_INA219MODE "Ina219Mode"
#define D_CMND_EXCEPTION "Exception" #define D_CMND_EXCEPTION "Exception"
// Commands xdrv_domoticz.ino // Commands xdrv_domoticz.ino

View File

@ -573,6 +573,7 @@
#define D_CMND_PRESSURE_RESOLUTION "PressRes" #define D_CMND_PRESSURE_RESOLUTION "PressRes"
#define D_CMND_POWER_RESOLUTION "WattRes" #define D_CMND_POWER_RESOLUTION "WattRes"
#define D_CMND_VOLTAGE_RESOLUTION "VoltRes" #define D_CMND_VOLTAGE_RESOLUTION "VoltRes"
#define D_CMND_CURRENT_RESOLUTION "AmpRes"
#define D_CMND_ENERGY_RESOLUTION "EnergyRes" #define D_CMND_ENERGY_RESOLUTION "EnergyRes"
#define D_CMND_MODULE "Module" #define D_CMND_MODULE "Module"
#define D_CMND_MODULES "Modules" #define D_CMND_MODULES "Modules"
@ -629,6 +630,7 @@
#define D_CMND_LEDSTATE "LedState" #define D_CMND_LEDSTATE "LedState"
#define D_CMND_CFGDUMP "CfgDump" #define D_CMND_CFGDUMP "CfgDump"
#define D_CMND_I2CSCAN "I2CScan" #define D_CMND_I2CSCAN "I2CScan"
#define D_CMND_INA219MODE "Ina219Mode"
#define D_CMND_EXCEPTION "Exception" #define D_CMND_EXCEPTION "Exception"
// Commands xdrv_domoticz.ino // Commands xdrv_domoticz.ino

View File

@ -44,6 +44,20 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t ws_clock_reverse : 1; // bit 16 (v5.8.1) uint32_t ws_clock_reverse : 1; // bit 16 (v5.8.1)
uint32_t decimal_text : 1; // bit 17 (v5.8.1) uint32_t decimal_text : 1; // bit 17 (v5.8.1)
uint32_t spare18 : 1; uint32_t spare18 : 1;
uint32_t spare19 : 1;
uint32_t voltage_resolution : 1;
uint32_t spare21 : 1;
uint32_t spare22 : 1;
uint32_t spare23 : 1;
uint32_t spare24 : 1;
uint32_t spare25 : 1;
uint32_t spare26 : 1;
uint32_t spare27 : 1;
uint32_t spare28 : 1;
uint32_t spare29 : 1;
uint32_t spare30 : 1;
uint32_t spare31 : 1;
/*
uint32_t wattage_resolution : 1; uint32_t wattage_resolution : 1;
uint32_t voltage_resolution : 1; uint32_t voltage_resolution : 1;
uint32_t emulation : 2; uint32_t emulation : 2;
@ -51,9 +65,39 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t pressure_resolution : 2; uint32_t pressure_resolution : 2;
uint32_t humidity_resolution : 2; uint32_t humidity_resolution : 2;
uint32_t temperature_resolution : 2; uint32_t temperature_resolution : 2;
*/
}; };
} SysBitfield; } SysBitfield;
typedef union {
uint32_t data; // Allow bit manipulation using SetOption
struct {
uint32_t spare00 : 1;
uint32_t spare01 : 1;
uint32_t spare02 : 1;
uint32_t spare03 : 1;
uint32_t spare04 : 1;
uint32_t spare05 : 1;
uint32_t spare06 : 1;
uint32_t spare07 : 1;
uint32_t spare08 : 1;
uint32_t spare09 : 1;
uint32_t spare10 : 1;
uint32_t spare11 : 1;
uint32_t spare12 : 1;
uint32_t spare13 : 1;
uint32_t spare14 : 1;
uint32_t current_resolution : 2;
uint32_t voltage_resolution : 2;
uint32_t wattage_resolution : 2;
uint32_t emulation : 2;
uint32_t energy_resolution : 3;
uint32_t pressure_resolution : 2;
uint32_t humidity_resolution : 2;
uint32_t temperature_resolution : 2;
};
} SysBitfield2;
struct SYSCFG { struct SYSCFG {
unsigned long cfg_holder; // 000 unsigned long cfg_holder; // 000
unsigned long save_flag; // 004 unsigned long save_flag; // 004
@ -188,7 +232,7 @@ struct SYSCFG {
uint8_t switchmode[MAX_SWITCHES]; // 4CA uint8_t switchmode[MAX_SWITCHES]; // 4CA
char ntp_server[3][33]; // 4CE char ntp_server[3][33]; // 4CE
byte free_531[1]; // 531 byte ina219_mode; // 531
uint16_t pulse_timer[MAX_PULSETIMERS]; // 532 uint16_t pulse_timer[MAX_PULSETIMERS]; // 532
@ -196,9 +240,9 @@ struct SYSCFG {
uint32_t ip_address[4]; // 544 uint32_t ip_address[4]; // 544
unsigned long hlw_kWhtotal; // 554 unsigned long hlw_kWhtotal; // 554
char mqtt_fulltopic[101]; // 558 char mqtt_fulltopic[100]; // 558
byte free_5BD[3]; // 5BD SysBitfield2 flag2; // 5BC Add flag2 since 5.9.2
unsigned long pulse_counter[MAX_COUNTERS]; // 5C0 unsigned long pulse_counter[MAX_COUNTERS]; // 5C0
uint16_t pulse_counter_type; // 5D0 uint16_t pulse_counter_type; // 5D0

View File

@ -391,7 +391,7 @@ void SettingsDefaultSet2()
Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN; Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
Settings.flag.emulation = EMULATION; Settings.flag2.emulation = EMULATION;
Settings.save_data = SAVE_DATA; Settings.save_data = SAVE_DATA;
Settings.timezone = APP_TIMEZONE; Settings.timezone = APP_TIMEZONE;
@ -513,6 +513,9 @@ void SettingsDefaultSet2()
Settings.pwm_frequency = PWM_FREQ; Settings.pwm_frequency = PWM_FREQ;
Settings.pwm_range = PWM_RANGE; Settings.pwm_range = PWM_RANGE;
SettingsDefaultSet_5_8_1(); SettingsDefaultSet_5_8_1();
// 5.9.2
Settings.flag2.current_resolution = 3;
} }
/********************************************************************************************/ /********************************************************************************************/
@ -599,10 +602,10 @@ void SettingsDefaultSet_4_1_1()
void SettingsDefaultSet_5_0_2() void SettingsDefaultSet_5_0_2()
{ {
Settings.flag.temperature_conversion = TEMP_CONVERSION; Settings.flag.temperature_conversion = TEMP_CONVERSION;
Settings.flag.temperature_resolution = TEMP_RESOLUTION; Settings.flag2.temperature_resolution = TEMP_RESOLUTION;
Settings.flag.humidity_resolution = HUMIDITY_RESOLUTION; Settings.flag2.humidity_resolution = HUMIDITY_RESOLUTION;
Settings.flag.pressure_resolution = PRESSURE_RESOLUTION; Settings.flag2.pressure_resolution = PRESSURE_RESOLUTION;
Settings.flag.energy_resolution = ENERGY_RESOLUTION; Settings.flag2.energy_resolution = ENERGY_RESOLUTION;
} }
void SettingsDefaultSet_5_8_1() void SettingsDefaultSet_5_8_1()
@ -688,7 +691,7 @@ void SettingsDelta()
// Settings.flag.mqtt_power_retain = 0; // Settings.flag.mqtt_power_retain = 0;
// Settings.flag.mqtt_button_retain = 0; // Settings.flag.mqtt_button_retain = 0;
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
Settings.flag.emulation = EMULATION; Settings.flag2.emulation = EMULATION;
SettingsDefaultSet_5_0_2(); SettingsDefaultSet_5_0_2();
@ -773,6 +776,13 @@ void SettingsDelta()
if (Settings.version < 0x0508000E) { if (Settings.version < 0x0508000E) {
SettingsDefaultSet_5_8_1(); SettingsDefaultSet_5_8_1();
} }
if (Settings.version < 0x05090102) {
Settings.flag2.data = Settings.flag.data;
Settings.flag2.data &= 0xFFE80000;
Settings.flag2.voltage_resolution = Settings.flag.voltage_resolution;
Settings.flag2.current_resolution = 3;
Settings.ina219_mode = 0;
}
Settings.version = VERSION; Settings.version = VERSION;
SettingsSave(1); SettingsSave(1);

View File

@ -25,7 +25,7 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)" - Select IDE Tools - Flash Size: "1M (no SPIFFS)"
====================================================*/ ====================================================*/
#define VERSION 0x05090101 // 5.9.1a #define VERSION 0x05090102 // 5.9.1b
// Location specific includes // Location specific includes
#include "sonoff.h" // Enumaration used in user_config.h #include "sonoff.h" // Enumaration used in user_config.h
@ -67,23 +67,23 @@
enum TasmotaCommands { enum TasmotaCommands {
CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_STATUS, CMND_POWERONSTATE, CMND_PULSETIME, CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_STATUS, CMND_POWERONSTATE, CMND_PULSETIME,
CMND_BLINKTIME, CMND_BLINKCOUNT, CMND_SAVEDATA, CMND_SETOPTION, CMND_TEMPERATURE_RESOLUTION, CMND_HUMIDITY_RESOLUTION, CMND_BLINKTIME, CMND_BLINKCOUNT, CMND_SAVEDATA, CMND_SETOPTION, CMND_TEMPERATURE_RESOLUTION, CMND_HUMIDITY_RESOLUTION,
CMND_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_ENERGY_RESOLUTION, CMND_MODULE, CMND_MODULES, 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, CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE,
CMND_COUNTERDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG, CMND_COUNTERDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG,
CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME, CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME,
CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_EMULATION, CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_EMULATION,
CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE, CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE,
CMND_CFGDUMP, CMND_I2CSCAN, CMND_EXCEPTION }; CMND_CFGDUMP, CMND_I2CSCAN, CMND_INA219MODE, CMND_EXCEPTION };
const char kTasmotaCommands[] PROGMEM = 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_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_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_ENERGY_RESOLUTION "|" D_CMND_MODULE "|" D_CMND_MODULES "|" 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 "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|"
D_CMND_COUNTERDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|" D_CMND_COUNTERDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|"
D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|"
D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_EMULATION "|" D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_EMULATION "|"
D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|"
D_CMND_CFGDUMP "|" D_CMND_I2CSCAN D_CMND_CFGDUMP "|" D_CMND_I2CSCAN "|" D_CMND_INA219MODE
#ifdef DEBUG_THEO #ifdef DEBUG_THEO
"|" D_CMND_EXCEPTION "|" D_CMND_EXCEPTION
#endif #endif
@ -419,7 +419,7 @@ void MqttPublishPowerState(byte device)
} }
GetPowerDevice(scommand, device, sizeof(scommand)); GetPowerDevice(scommand, device, sizeof(scommand));
GetTopic_P(stopic, 1, Settings.mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); GetTopic_P(stopic, 1, Settings.mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\"}"), scommand, GetStateText(bitRead(power, device -1))); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(power, device -1)));
MqttPublish(stopic); MqttPublish(stopic);
GetTopic_P(stopic, 1, Settings.mqtt_topic, scommand); GetTopic_P(stopic, 1, Settings.mqtt_topic, scommand);
@ -466,12 +466,12 @@ void MqttConnected()
} }
if (mqtt_connection_flag) { if (mqtt_connection_flag) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULE "\":\"%s\", \"" D_VERSION "\":\"%s\", \"" D_FALLBACKTOPIC "\":\"%s\", \"" D_CMND_GROUPTOPIC "\":\"%s\"}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_VERSION "\":\"%s\",\"" D_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"),
my_module.name, version, mqtt_client, Settings.mqtt_grptopic); my_module.name, version, mqtt_client, Settings.mqtt_grptopic);
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_INFO "1")); MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_INFO "1"));
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
if (Settings.webserver) { if (Settings.webserver) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_WEBSERVER_MODE "\":\"%s\", \"" D_CMND_HOSTNAME "\":\"%s\", \"" D_CMND_IPADDRESS "\":\"%s\"}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"),
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str()); (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_INFO "2")); MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_INFO "2"));
} }
@ -1044,39 +1044,45 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
} }
else if (CMND_TEMPERATURE_RESOLUTION == command_code) { else if (CMND_TEMPERATURE_RESOLUTION == command_code) {
if ((payload >= 0) && (payload <= 3)) { if ((payload >= 0) && (payload <= 3)) {
Settings.flag.temperature_resolution = payload; Settings.flag2.temperature_resolution = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag.temperature_resolution); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.temperature_resolution);
} }
else if (CMND_HUMIDITY_RESOLUTION == command_code) { else if (CMND_HUMIDITY_RESOLUTION == command_code) {
if ((payload >= 0) && (payload <= 3)) { if ((payload >= 0) && (payload <= 3)) {
Settings.flag.humidity_resolution = payload; Settings.flag2.humidity_resolution = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag.humidity_resolution); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.humidity_resolution);
} }
else if (CMND_PRESSURE_RESOLUTION == command_code) { else if (CMND_PRESSURE_RESOLUTION == command_code) {
if ((payload >= 0) && (payload <= 3)) { if ((payload >= 0) && (payload <= 3)) {
Settings.flag.pressure_resolution = payload; Settings.flag2.pressure_resolution = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag.pressure_resolution); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.pressure_resolution);
} }
else if (CMND_POWER_RESOLUTION == command_code) { else if (CMND_POWER_RESOLUTION == command_code) {
if ((payload >= 0) && (payload <= 1)) { if ((payload >= 0) && (payload <= 3)) {
Settings.flag.wattage_resolution = payload; Settings.flag2.wattage_resolution = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag.wattage_resolution); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.wattage_resolution);
} }
else if (CMND_VOLTAGE_RESOLUTION == command_code) { else if (CMND_VOLTAGE_RESOLUTION == command_code) {
if ((payload >= 0) && (payload <= 1)) { if ((payload >= 0) && (payload <= 3)) {
Settings.flag.voltage_resolution = payload; Settings.flag2.voltage_resolution = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag.voltage_resolution); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.voltage_resolution);
}
else if (CMND_CURRENT_RESOLUTION == command_code) {
if ((payload >= 0) && (payload <= 3)) {
Settings.flag2.current_resolution = payload;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.current_resolution);
} }
else if (CMND_ENERGY_RESOLUTION == command_code) { else if (CMND_ENERGY_RESOLUTION == command_code) {
if ((payload >= 0) && (payload <= 5)) { if ((payload >= 0) && (payload <= 5)) {
Settings.flag.energy_resolution = payload; Settings.flag2.energy_resolution = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag.energy_resolution); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.energy_resolution);
} }
else if (CMND_MODULE == command_code) { else if (CMND_MODULE == command_code) {
if ((payload > 0) && (payload <= MAXMODULE)) { if ((payload > 0) && (payload <= MAXMODULE)) {
@ -1098,7 +1104,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
if (!jsflg) { if (!jsflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULES "%d\":\""), lines); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULES "%d\":\""), lines);
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, "), mqtt_data); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
} }
jsflg = 1; jsflg = 1;
snprintf_P(stemp1, sizeof(stemp1), kModules[i].name); snprintf_P(stemp1, sizeof(stemp1), kModules[i].name);
@ -1129,7 +1135,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
for (byte i = 0; i < MAX_GPIO_PIN; i++) { for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if (GPIO_USER == cmodule.gp.io[i]) { if (GPIO_USER == cmodule.gp.io[i]) {
if (jsflg) { if (jsflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, "), mqtt_data); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
} }
jsflg = 1; jsflg = 1;
snprintf_P(stemp1, sizeof(stemp1), kSensors[Settings.my_gp.io[i]]); snprintf_P(stemp1, sizeof(stemp1), kSensors[Settings.my_gp.io[i]]);
@ -1147,7 +1153,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
if (!jsflg) { if (!jsflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_GPIOS "%d\":\""), lines); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_GPIOS "%d\":\""), lines);
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, "), mqtt_data); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
} }
jsflg = 1; jsflg = 1;
snprintf_P(stemp1, sizeof(stemp1), kSensors[i]); snprintf_P(stemp1, sizeof(stemp1), kSensors[i]);
@ -1170,7 +1176,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
bool first = true; bool first = true;
for (byte i = 0; i < MAX_PWMS; i++) { for (byte i = 0; i < MAX_PWMS; i++) {
if(pin[GPIO_PWM1 + i] < 99) { if(pin[GPIO_PWM1 + i] < 99) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), mqtt_data, first ? "" : ", ", i+1, Settings.pwm_value[i]); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), mqtt_data, first ? "" : ",", i+1, Settings.pwm_value[i]);
first = false; first = false;
} }
} }
@ -1254,7 +1260,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
else if (CMND_SYSLOG == command_code) { else if (CMND_SYSLOG == command_code) {
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
Settings.syslog_level = payload; Settings.syslog_level = payload;
syslog_level = (Settings.flag.emulation) ? 0 : payload; syslog_level = (Settings.flag2.emulation) ? 0 : payload;
syslog_timer = 0; syslog_timer = 0;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, command, Settings.syslog_level, syslog_level); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, command, Settings.syslog_level, syslog_level);
@ -1390,10 +1396,10 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
#ifdef USE_EMULATION #ifdef USE_EMULATION
else if (CMND_EMULATION == command_code) { else if (CMND_EMULATION == command_code) {
if ((payload >= EMUL_NONE) && (payload < EMUL_MAX)) { if ((payload >= EMUL_NONE) && (payload < EMUL_MAX)) {
Settings.flag.emulation = payload; Settings.flag2.emulation = payload;
restart_flag = 2; restart_flag = 2;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag.emulation); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.emulation);
} }
#endif // USE_EMULATION #endif // USE_EMULATION
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
@ -1477,6 +1483,20 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
SettingsDump(dataBuf); SettingsDump(dataBuf);
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_DONE); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_DONE);
} }
#ifdef USE_I2C
else if ((CMND_I2CSCAN == command_code) && i2c_flg) {
I2cScan(mqtt_data, sizeof(mqtt_data));
}
#endif // USE_I2C
#ifdef USE_INA219
else if (CMND_INA219MODE == command_code) {
if ((payload >= 0) && (payload <= 2)) {
Settings.ina219_mode = payload;
restart_flag = 2;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.ina219_mode);
}
#endif // USE_INA219
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 // Serviced
} }
@ -1486,11 +1506,6 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
else if ((SONOFF_BRIDGE == Settings.module) && SonoffBridgeCommand(type, index, dataBuf, data_len, payload)) { else if ((SONOFF_BRIDGE == Settings.module) && SonoffBridgeCommand(type, index, dataBuf, data_len, payload)) {
// Serviced // Serviced
} }
#ifdef USE_I2C
else if ((CMND_I2CSCAN == command_code) && i2c_flg) {
I2cScan(mqtt_data, sizeof(mqtt_data));
}
#endif // USE_I2C
#ifdef USE_IR_REMOTE #ifdef USE_IR_REMOTE
else if ((pin[GPIO_IRSEND] < 99) && IrSendCommand(type, index, dataBuf, data_len, payload)) { else if ((pin[GPIO_IRSEND] < 99) && IrSendCommand(type, index, dataBuf, data_len, payload)) {
// Serviced // Serviced
@ -1697,50 +1712,50 @@ void PublishStatus(uint8_t payload)
} }
if ((0 == payload) || (99 == payload)) { if ((0 == payload) || (99 == payload)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d, \"" D_CMND_FRIENDLYNAME "\":\"%s\", \"" D_CMND_TOPIC "\":\"%s\", \"" D_CMND_BUTTONTOPIC "\":\"%s\", \"" D_CMND_POWER "\":%d, \"" D_CMND_POWERONSTATE "\":%d, \"" D_CMND_LEDSTATE "\":%d, \"" D_CMND_SAVEDATA "\":%d, \"" D_SAVESTATE "\":%d, \"" D_CMND_BUTTONRETAIN "\":%d, \"" D_CMND_POWERRETAIN "\":%d}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":\"%s\",\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_SAVESTATE "\":%d,\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"),
Settings.module +1, Settings.friendlyname[0], Settings.mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_power_retain); Settings.module +1, Settings.friendlyname[0], Settings.mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_power_retain);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS)); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS));
} }
if ((0 == payload) || (1 == payload)) { if ((0 == payload) || (1 == payload)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_BAUDRATE "\":%d, \"" D_CMND_GROUPTOPIC "\":\"%s\", \"" D_CMND_OTAURL "\":\"%s\", \"" D_UPTIME "\":%d, \"" D_CMND_SLEEP "\":%d, \"" D_BOOTCOUNT "\":%d, \"" D_SAVECOUNT "\":%d, \"" D_SAVEADDRESS "\":\"%X\"}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_BAUDRATE "\":%d,\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_UPTIME "\":%d,\"" D_CMND_SLEEP "\":%d,\"" D_BOOTCOUNT "\":%d,\"" D_SAVECOUNT "\":%d,\"" D_SAVEADDRESS "\":\"%X\"}}"),
baudrate, Settings.mqtt_grptopic, Settings.ota_url, uptime, Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress()); baudrate, Settings.mqtt_grptopic, Settings.ota_url, uptime, Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
} }
if ((0 == payload) || (2 == payload)) { if ((0 == payload) || (2 == payload)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_VERSION "\":\"%s\", \"" D_BUILDDATETIME "\":\"%s\", \"" D_BOOTVERSION "\":%d, \"" D_COREVERSION "\":\"%s\", \"" D_SDKVERSION "\":\"%s\"}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_VERSION "\":\"%s\",\"" D_BUILDDATETIME "\":\"%s\",\"" D_BOOTVERSION "\":%d,\"" D_COREVERSION "\":\"%s\",\"" D_SDKVERSION "\":\"%s\"}}"),
version, GetBuildDateAndTime().c_str(), ESP.getBootVersion(), ESP.getCoreVersion().c_str(), ESP.getSdkVersion()); version, GetBuildDateAndTime().c_str(), ESP.getBootVersion(), ESP.getCoreVersion().c_str(), ESP.getSdkVersion());
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "2")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "2"));
} }
if ((0 == payload) || (3 == payload)) { if ((0 == payload) || (3 == payload)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d, \"" D_CMND_WEBLOG "\":%d, \"" D_CMND_SYSLOG "\":%d, \"" D_CMND_LOGHOST "\":\"%s\", \"" D_CMND_LOGPORT "\":%d, \"" D_CMND_SSID "1\":\"%s\", \"" D_CMND_SSID "2\":\"%s\", \"" D_CMND_TELEPERIOD "\":%d, \"" D_CMND_SETOPTION "\":\"%08X\"}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d,\"" D_CMND_WEBLOG "\":%d,\"" D_CMND_SYSLOG "\":%d,\"" D_CMND_LOGHOST "\":\"%s\",\"" D_CMND_LOGPORT "\":%d,\"" D_CMND_SSID "1\":\"%s\",\"" D_CMND_SSID "2\":\"%s\",\"" D_CMND_TELEPERIOD "\":%d,\"" D_CMND_SETOPTION "\":\"%08X\"}}"),
Settings.seriallog_level, Settings.weblog_level, Settings.syslog_level, Settings.syslog_host, Settings.syslog_port, Settings.sta_ssid[0], Settings.sta_ssid[1], Settings.tele_period, Settings.flag.data); Settings.seriallog_level, Settings.weblog_level, Settings.syslog_level, Settings.syslog_host, Settings.syslog_port, Settings.sta_ssid[0], Settings.sta_ssid[1], Settings.tele_period, Settings.flag.data);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "3")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "3"));
} }
if ((0 == payload) || (4 == payload)) { if ((0 == payload) || (4 == payload)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_PROGRAMSIZE "\":%d, \"" D_FREEMEMORY "\":%d, \"" D_HEAPSIZE "\":%d, \"" D_PROGRAMFLASHSIZE "\":%d, \"" D_FLASHSIZE "\":%d, \"" D_FLASHMODE "\":%d}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_PROGRAMSIZE "\":%d,\"" D_FREEMEMORY "\":%d,\"" D_HEAPSIZE "\":%d,\"" D_PROGRAMFLASHSIZE "\":%d,\"" D_FLASHSIZE "\":%d,\"" D_FLASHMODE "\":%d}}"),
ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipMode()); ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipMode());
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "4")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "4"));
} }
if ((0 == payload) || (5 == payload)) { if ((0 == payload) || (5 == payload)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\", \"" D_CMND_IPADDRESS "\":\"%s\", \"" D_GATEWAY "\":\"%s\", \"" D_SUBNETMASK "\":\"%s\", \"" D_DNSSERVER "\":\"%s\", \"" D_MAC "\":\"%s\", \"" D_CMND_WEBSERVER "\":%d, \"" D_CMND_WIFICONFIG "\":%d}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_GATEWAY "\":\"%s\",\"" D_SUBNETMASK "\":\"%s\",\"" D_DNSSERVER "\":\"%s\",\"" D_MAC "\":\"%s\",\"" D_CMND_WEBSERVER "\":%d,\"" D_CMND_WIFICONFIG "\":%d}}"),
my_hostname, WiFi.localIP().toString().c_str(), IPAddress(Settings.ip_address[1]).toString().c_str(), IPAddress(Settings.ip_address[2]).toString().c_str(), IPAddress(Settings.ip_address[3]).toString().c_str(), my_hostname, WiFi.localIP().toString().c_str(), IPAddress(Settings.ip_address[1]).toString().c_str(), IPAddress(Settings.ip_address[2]).toString().c_str(), IPAddress(Settings.ip_address[3]).toString().c_str(),
WiFi.macAddress().c_str(), Settings.webserver, Settings.sta_config); WiFi.macAddress().c_str(), Settings.webserver, Settings.sta_config);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "5")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "5"));
} }
if (((0 == payload) || (6 == payload)) && Settings.flag.mqtt_enabled) { if (((0 == payload) || (6 == payload)) && Settings.flag.mqtt_enabled) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\", \"" D_CMND_MQTTPORT "\":%d, \"" D_CMND_MQTTCLIENT D_MASK "\":\"%s\", \"" D_CMND_MQTTCLIENT "\":\"%s\", \"" D_CMND_MQTTUSER "\":\"%s\", \"MAX_PACKET_SIZE\":%d, \"KEEPALIVE\":%d}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\",\"" D_CMND_MQTTPORT "\":%d,\"" D_CMND_MQTTCLIENT D_MASK "\":\"%s\",\"" D_CMND_MQTTCLIENT "\":\"%s\",\"" D_CMND_MQTTUSER "\":\"%s\",\"MAX_PACKET_SIZE\":%d,\"KEEPALIVE\":%d}}"),
Settings.mqtt_host, Settings.mqtt_port, Settings.mqtt_client, mqtt_client, Settings.mqtt_user, MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE); Settings.mqtt_host, Settings.mqtt_port, Settings.mqtt_client, mqtt_client, Settings.mqtt_user, MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "6")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "6"));
} }
if ((0 == payload) || (7 == payload)) { if ((0 == payload) || (7 == payload)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_UTC_TIME "\":\"%s\", \"" D_LOCAL_TIME "\":\"%s\", \"" D_STARTDST "\":\"%s\", \"" D_ENDDST "\":\"%s\", \"" D_CMND_TIMEZONE "\":%d}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_UTC_TIME "\":\"%s\",\"" D_LOCAL_TIME "\":\"%s\",\"" D_STARTDST "\":\"%s\",\"" D_ENDDST "\":\"%s\",\"" D_CMND_TIMEZONE "\":%d}}"),
GetTime(0).c_str(), GetTime(1).c_str(), GetTime(2).c_str(), GetTime(3).c_str(), Settings.timezone); GetTime(0).c_str(), GetTime(1).c_str(), GetTime(2).c_str(), GetTime(3).c_str(), Settings.timezone);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "7")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "7"));
} }
@ -1752,7 +1767,7 @@ void PublishStatus(uint8_t payload)
} }
if ((0 == payload) || (9 == payload)) { if ((0 == payload) || (9 == payload)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS9_MARGIN "\":{\"" D_CMND_POWERLOW "\":%d, \"" D_CMND_POWERHIGH "\":%d, \"" D_CMND_VOLTAGELOW "\":%d, \"" D_CMND_VOLTAGEHIGH "\":%d, \"" D_CMND_CURRENTLOW "\":%d, \"" D_CMND_CURRENTHIGH "\":%d}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS9_MARGIN "\":{\"" D_CMND_POWERLOW "\":%d,\"" D_CMND_POWERHIGH "\":%d,\"" D_CMND_VOLTAGELOW "\":%d,\"" D_CMND_VOLTAGEHIGH "\":%d,\"" D_CMND_CURRENTLOW "\":%d,\"" D_CMND_CURRENTHIGH "\":%d}}"),
Settings.hlw_pmin, Settings.hlw_pmax, Settings.hlw_umin, Settings.hlw_umax, Settings.hlw_imin, Settings.hlw_imax); Settings.hlw_pmin, Settings.hlw_pmax, Settings.hlw_umin, Settings.hlw_umax, Settings.hlw_imin, Settings.hlw_imax);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "9")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "9"));
} }
@ -1778,15 +1793,15 @@ void MqttShowState()
{ {
char stemp1[16]; char stemp1[16];
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_TIME "\":\"%s\", \"" D_UPTIME "\":%d"), mqtt_data, GetDateAndTime().c_str(), uptime); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_TIME "\":\"%s\",\"" D_UPTIME "\":%d"), mqtt_data, GetDateAndTime().c_str(), uptime);
#ifdef USE_ADC_VCC #ifdef USE_ADC_VCC
dtostrfd((double)ESP.getVcc()/1000, 3, stemp1); dtostrfd((double)ESP.getVcc()/1000, 3, stemp1);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_VCC "\":%s"), mqtt_data, stemp1); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_VCC "\":%s"), mqtt_data, stemp1);
#endif #endif
for (byte i = 0; i < devices_present; i++) { 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))); 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_WIFI "\":{\"" D_AP "\":%d, \"" D_SSID "\":\"%s\", \"" D_RSSI "\":%d, \"" D_APMAC_ADDRESS "\":\"%s\"}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_WIFI "\":{\"" D_AP "\":%d,\"" D_SSID "\":\"%s\",\"" D_RSSI "\":%d,\"" D_APMAC_ADDRESS "\":\"%s\"}}"),
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str()); mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str());
} }
@ -1797,13 +1812,13 @@ boolean MqttShowSensor()
for (byte i = 0; i < MAX_SWITCHES; i++) { for (byte i = 0; i < MAX_SWITCHES; i++) {
if (pin[GPIO_SWT1 +i] < 99) { if (pin[GPIO_SWT1 +i] < 99) {
boolean swm = ((FOLLOW_INV == Settings.switchmode[i]) || (PUSHBUTTON_INV == Settings.switchmode[i]) || (PUSHBUTTONHOLD_INV == Settings.switchmode[i])); boolean swm = ((FOLLOW_INV == Settings.switchmode[i]) || (PUSHBUTTON_INV == Settings.switchmode[i]) || (PUSHBUTTONHOLD_INV == Settings.switchmode[i]));
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_SWITCH "%d\":\"%s\""), mqtt_data, i +1, GetStateText(swm ^ lastwallswitch[i])); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_SWITCH "%d\":\"%s\""), mqtt_data, i +1, GetStateText(swm ^ lastwallswitch[i]));
} }
} }
XsnsCall(FUNC_XSNS_JSON_APPEND); XsnsCall(FUNC_XSNS_JSON_APPEND);
boolean json_data_available = (strlen(mqtt_data) - json_data_start); boolean json_data_available = (strlen(mqtt_data) - json_data_start);
if (strstr_P(mqtt_data, PSTR(D_TEMPERATURE))) { if (strstr_P(mqtt_data, PSTR(D_TEMPERATURE))) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE_UNIT "\":\"%c\""), mqtt_data, TempUnit()); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_TEMPERATURE_UNIT "\":\"%c\""), mqtt_data, TempUnit());
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
return json_data_available; return json_data_available;
@ -1836,7 +1851,7 @@ void PerformEverySecond()
if (syslog_timer) { // Restore syslog level if (syslog_timer) { // Restore syslog level
syslog_timer--; syslog_timer--;
if (!syslog_timer) { if (!syslog_timer) {
syslog_level = (Settings.flag.emulation) ? 0 : Settings.syslog_level; syslog_level = (Settings.flag2.emulation) ? 0 : Settings.syslog_level;
if (Settings.syslog_level) { if (Settings.syslog_level) {
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SYSLOG_LOGGING_REENABLED)); // Might trigger disable again (on purpose) AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SYSLOG_LOGGING_REENABLED)); // Might trigger disable again (on purpose)
} }
@ -1884,7 +1899,7 @@ void PerformEverySecond()
if ((2 == RtcTime.minute) && latest_uptime_flag) { if ((2 == RtcTime.minute) && latest_uptime_flag) {
latest_uptime_flag = false; latest_uptime_flag = false;
uptime++; uptime++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_TIME "\":\"%s\", \"" D_UPTIME "\":%d}"), GetDateAndTime().c_str(), uptime); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_TIME "\":\"%s\",\"" D_UPTIME "\":%d}"), GetDateAndTime().c_str(), uptime);
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_UPTIME)); MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_UPTIME));
} }
if ((3 == RtcTime.minute) && !latest_uptime_flag) { if ((3 == RtcTime.minute) && !latest_uptime_flag) {
@ -2611,8 +2626,6 @@ void GpioInit()
#endif // USE_IR_REMOTE #endif // USE_IR_REMOTE
hlw_flg = ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99)); hlw_flg = ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99));
// XSnsInit();
} }
extern "C" { extern "C" {
@ -2642,9 +2655,9 @@ void setup()
seriallog_level = Settings.seriallog_level; seriallog_level = Settings.seriallog_level;
seriallog_timer = SERIALLOG_TIMER; seriallog_timer = SERIALLOG_TIMER;
#ifndef USE_EMULATION #ifndef USE_EMULATION
Settings.flag.emulation = 0; Settings.flag2.emulation = 0;
#endif // USE_EMULATION #endif // USE_EMULATION
syslog_level = (Settings.flag.emulation) ? 0 : Settings.syslog_level; syslog_level = (Settings.flag2.emulation) ? 0 : Settings.syslog_level;
stop_flash_rotate = Settings.flag.stop_flash_rotate; stop_flash_rotate = Settings.flag.stop_flash_rotate;
save_data_counter = Settings.save_data; save_data_counter = Settings.save_data;
sleep = Settings.sleep; sleep = Settings.sleep;
@ -2726,11 +2739,7 @@ void setup()
blink_powersave = power; blink_powersave = power;
// if (SONOFF_SC == Settings.module) {
// SonoffScInit();
// }
XSnsInit(); XSnsInit();
RtcInit(); RtcInit();
snprintf_P(log_data, sizeof(log_data), PSTR(D_PROJECT " %s %s (" D_CMND_TOPIC " %s, " D_FALLBACK " %s, " D_CMND_GROUPTOPIC " %s) " D_VERSION " %s"), snprintf_P(log_data, sizeof(log_data), PSTR(D_PROJECT " %s %s (" D_CMND_TOPIC " %s, " D_FALLBACK " %s, " D_CMND_GROUPTOPIC " %s) " D_VERSION " %s"),
@ -2747,7 +2756,7 @@ void loop()
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
#ifdef USE_EMULATION #ifdef USE_EMULATION
if (Settings.flag.emulation) { if (Settings.flag2.emulation) {
PollUdp(); PollUdp();
} }
#endif // USE_EMULATION #endif // USE_EMULATION

View File

@ -629,7 +629,7 @@ void WifiCheck(uint8_t param)
StopWebserver(); StopWebserver();
} }
#ifdef USE_EMULATION #ifdef USE_EMULATION
if (Settings.flag.emulation) { if (Settings.flag2.emulation) {
UdpConnect(); UdpConnect();
} }
#endif // USE_EMULATION #endif // USE_EMULATION
@ -756,14 +756,34 @@ int32_t I2cRead24(uint8_t addr, uint8_t reg)
{ {
return I2cRead(addr, reg, 3); return I2cRead(addr, reg, 3);
} }
/*
void I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size)
{
byte x = I2C_RETRY_COUNTER;
int32_t data = val;
do {
Wire.beginTransmission((uint8_t)addr); // start transmission to device
Wire.write(reg); // sends register address to read from
for (byte i = 0; i < size; i++) {
}
Wire.write((val >> 8) & 0xFF); // write data
Wire.write(val); // write data
x--;
} while (Wire.endTransmission(true) != 0 && x != 0); // end transmission
}
*/
void I2cWrite8v(uint8_t addr, uint8_t val) void I2cWrite8v(uint8_t addr, uint8_t val)
{ {
byte x = I2C_RETRY_COUNTER; byte x = I2C_RETRY_COUNTER;
do { do {
Wire.beginTransmission((uint8_t)addr); // start transmission to device Wire.beginTransmission((uint8_t)addr); // start transmission to device
Wire.write(val); // write data Wire.write(val); // write data
x--; x--;
} while (Wire.endTransmission(true) != 0 && x != 0); // end transmission } while (Wire.endTransmission(true) != 0 && x != 0); // end transmission
} }
@ -774,12 +794,26 @@ void I2cWrite8(uint8_t addr, uint8_t reg, uint8_t val)
do { do {
Wire.beginTransmission((uint8_t)addr); // start transmission to device Wire.beginTransmission((uint8_t)addr); // start transmission to device
Wire.write(reg); // sends register address to read from Wire.write(reg); // sends register address to write to
Wire.write(val); // write data Wire.write(val); // write data
x--; x--;
} while (Wire.endTransmission(true) != 0 && x != 0); // end transmission } while (Wire.endTransmission(true) != 0 && x != 0); // end transmission
} }
bool I2cWrite16(uint8_t addr, uint8_t reg, uint16_t val)
{
byte x = I2C_RETRY_COUNTER;
do {
Wire.beginTransmission((uint8_t)addr); // start transmission to device
Wire.write(reg); // sends register address to write to
Wire.write((val >> 8) & 0xFF); // write data
Wire.write(val & 0xFF); // write data
x--;
} while (Wire.endTransmission(true) != 0 && x != 0); // end transmission
return (x);
}
void I2cScan(char *devs, unsigned int devs_len) void I2cScan(char *devs, unsigned int devs_len)
{ {
byte error; byte error;
@ -1249,7 +1283,7 @@ void AdcShow(boolean json)
analog >>= 5; analog >>= 5;
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_ANALOG_INPUT "0\":%d"), mqtt_data, analog); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_ANALOG_INPUT "0\":%d"), mqtt_data, analog);
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "", 0, analog); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "", 0, analog);

View File

@ -172,6 +172,7 @@
#define USE_BH1750 // Add I2C code for BH1750 sensor #define USE_BH1750 // Add I2C code for BH1750 sensor
// #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0.5k code) // #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0.5k code)
// #define USE_ADS1115 // Add I2C code for ADS1x15 16 bit A/D converter using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code) // #define USE_ADS1115 // Add I2C code for ADS1x15 16 bit A/D converter using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code)
#define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code)
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+3k code, 0.3k mem) #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+3k code, 0.3k mem)
// #define USE_IR_HVAC // Support for HVAC system using IR (+2k code) // #define USE_IR_HVAC // Support for HVAC system using IR (+2k code)

View File

@ -332,12 +332,12 @@ void StartWebserver(int type, IPAddress ipweb)
WebServer->on("/rb", HandleRestart); WebServer->on("/rb", HandleRestart);
WebServer->on("/fwlink", HandleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler. WebServer->on("/fwlink", HandleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler.
#ifdef USE_EMULATION #ifdef USE_EMULATION
if (EMUL_WEMO == Settings.flag.emulation) { if (EMUL_WEMO == Settings.flag2.emulation) {
WebServer->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent); WebServer->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent);
WebServer->on("/eventservice.xml", HandleUpnpService); WebServer->on("/eventservice.xml", HandleUpnpService);
WebServer->on("/setup.xml", HandleUpnpSetupWemo); WebServer->on("/setup.xml", HandleUpnpSetupWemo);
} }
if (EMUL_HUE == Settings.flag.emulation) { if (EMUL_HUE == Settings.flag2.emulation) {
WebServer->on("/description.xml", HandleUpnpSetupHue); WebServer->on("/description.xml", HandleUpnpSetupHue);
} }
#endif // USE_EMULATION #endif // USE_EMULATION
@ -890,7 +890,7 @@ void HandleOtherConfiguration()
for (byte i = 0; i < EMUL_MAX; i++) { for (byte i = 0; i < EMUL_MAX; i++) {
page += FPSTR(HTTP_FORM_OTHER3b); page += FPSTR(HTTP_FORM_OTHER3b);
page.replace(F("{1"), String(i)); page.replace(F("{1"), String(i));
page.replace(F("{2"), (i == Settings.flag.emulation) ? F(" checked") : F("")); page.replace(F("{2"), (i == Settings.flag2.emulation) ? F(" checked") : F(""));
page.replace(F("{3"), (i == EMUL_NONE) ? F(D_NONE) : (i == EMUL_WEMO) ? F(D_BELKIN_WEMO) : F(D_HUE_BRIDGE)); page.replace(F("{3"), (i == EMUL_NONE) ? F(D_NONE) : (i == EMUL_WEMO) ? F(D_BELKIN_WEMO) : F(D_HUE_BRIDGE));
page.replace(F("{4"), (i == EMUL_NONE) ? F("") : (i == EMUL_WEMO) ? F(" " D_SINGLE_DEVICE) : F(" " D_MULTI_DEVICE)); page.replace(F("{4"), (i == EMUL_NONE) ? F("") : (i == EMUL_WEMO) ? F(" " D_SINGLE_DEVICE) : F(" " D_MULTI_DEVICE));
} }
@ -1015,14 +1015,14 @@ snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D
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())) ? WEB_PASSWORD : (!strcmp(WebServer->arg("p1").c_str(),"0")) ? "" : WebServer->arg("p1").c_str(), sizeof(Settings.web_password));
Settings.flag.mqtt_enabled = WebServer->hasArg("b1"); Settings.flag.mqtt_enabled = WebServer->hasArg("b1");
#ifdef USE_EMULATION #ifdef USE_EMULATION
Settings.flag.emulation = (!strlen(WebServer->arg("b2").c_str())) ? 0 : atoi(WebServer->arg("b2").c_str()); Settings.flag2.emulation = (!strlen(WebServer->arg("b2").c_str())) ? 0 : atoi(WebServer->arg("b2").c_str());
#endif // USE_EMULATION #endif // USE_EMULATION
strlcpy(Settings.friendlyname[0], (!strlen(WebServer->arg("a1").c_str())) ? FRIENDLY_NAME : WebServer->arg("a1").c_str(), sizeof(Settings.friendlyname[0])); strlcpy(Settings.friendlyname[0], (!strlen(WebServer->arg("a1").c_str())) ? FRIENDLY_NAME : WebServer->arg("a1").c_str(), sizeof(Settings.friendlyname[0]));
strlcpy(Settings.friendlyname[1], (!strlen(WebServer->arg("a2").c_str())) ? FRIENDLY_NAME"2" : WebServer->arg("a2").c_str(), sizeof(Settings.friendlyname[1])); strlcpy(Settings.friendlyname[1], (!strlen(WebServer->arg("a2").c_str())) ? FRIENDLY_NAME"2" : WebServer->arg("a2").c_str(), sizeof(Settings.friendlyname[1]));
strlcpy(Settings.friendlyname[2], (!strlen(WebServer->arg("a3").c_str())) ? FRIENDLY_NAME"3" : WebServer->arg("a3").c_str(), sizeof(Settings.friendlyname[2])); strlcpy(Settings.friendlyname[2], (!strlen(WebServer->arg("a3").c_str())) ? FRIENDLY_NAME"3" : WebServer->arg("a3").c_str(), sizeof(Settings.friendlyname[2]));
strlcpy(Settings.friendlyname[3], (!strlen(WebServer->arg("a4").c_str())) ? FRIENDLY_NAME"4" : WebServer->arg("a4").c_str(), sizeof(Settings.friendlyname[3])); strlcpy(Settings.friendlyname[3], (!strlen(WebServer->arg("a4").c_str())) ? FRIENDLY_NAME"4" : WebServer->arg("a4").c_str(), sizeof(Settings.friendlyname[3]));
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME " %s, %s, %s, %s"), snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME " %s, %s, %s, %s"),
GetStateText(Settings.flag.mqtt_enabled), Settings.flag.emulation, Settings.friendlyname[0], Settings.friendlyname[1], Settings.friendlyname[2], Settings.friendlyname[3]); GetStateText(Settings.flag.mqtt_enabled), Settings.flag2.emulation, Settings.friendlyname[0], Settings.friendlyname[1], Settings.friendlyname[2], Settings.friendlyname[3]);
AddLog(LOG_LEVEL_INFO); AddLog(LOG_LEVEL_INFO);
break; break;
case 6: case 6:
@ -1522,10 +1522,10 @@ void HandleInformation()
func += F("}1}2&nbsp;"); // Empty line func += F("}1}2&nbsp;"); // Empty line
func += F("}1" D_EMULATION "}2"); func += F("}1" D_EMULATION "}2");
#ifdef USE_EMULATION #ifdef USE_EMULATION
if (EMUL_WEMO == Settings.flag.emulation) { if (EMUL_WEMO == Settings.flag2.emulation) {
func += F(D_BELKIN_WEMO); func += F(D_BELKIN_WEMO);
} }
else if (EMUL_HUE == Settings.flag.emulation) { else if (EMUL_HUE == Settings.flag2.emulation) {
func += F(D_HUE_BRIDGE); func += F(D_HUE_BRIDGE);
} }
else { else {
@ -1596,7 +1596,7 @@ void HandleNotFound()
#ifdef USE_EMULATION #ifdef USE_EMULATION
String path = WebServer->uri(); String path = WebServer->uri();
if ((EMUL_HUE == Settings.flag.emulation) && (path.startsWith("/api"))) { if ((EMUL_HUE == Settings.flag2.emulation) && (path.startsWith("/api"))) {
HandleHueApi(&path); HandleHueApi(&path);
} else } else
#endif // USE_EMULATION #endif // USE_EMULATION

View File

@ -45,6 +45,8 @@ enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, D
const char kDomoticzSensors[] PROGMEM = const char kDomoticzSensors[] PROGMEM =
D_DOMOTICZ_TEMP "|" D_DOMOTICZ_TEMP_HUM "|" D_DOMOTICZ_TEMP_HUM_BARO "|" D_DOMOTICZ_POWER_ENERGY "|" D_DOMOTICZ_ILLUMINANCE "|" D_DOMOTICZ_COUNT "|" D_DOMOTICZ_VOLTAGE "|" D_DOMOTICZ_CURRENT ; D_DOMOTICZ_TEMP "|" D_DOMOTICZ_TEMP_HUM "|" D_DOMOTICZ_TEMP_HUM_BARO "|" D_DOMOTICZ_POWER_ENERGY "|" D_DOMOTICZ_ILLUMINANCE "|" D_DOMOTICZ_COUNT "|" D_DOMOTICZ_VOLTAGE "|" D_DOMOTICZ_CURRENT ;
const char S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE[] PROGMEM = "{\"" D_CMND_DOMOTICZ "%s%d\":%d}";
char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC; char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC;
char domoticz_out_topic[] = DOMOTICZ_OUT_TOPIC; char domoticz_out_topic[] = DOMOTICZ_OUT_TOPIC;
@ -206,25 +208,25 @@ boolean DomoticzCommand(const char *type, uint16_t index, char *dataBuf, uint16_
Settings.domoticz_relay_idx[index -1] = payload; Settings.domoticz_relay_idx[index -1] = payload;
restart_flag = 2; restart_flag = 2;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ "%s%d\":%d}"), command, index, Settings.domoticz_relay_idx[index -1]); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, index, Settings.domoticz_relay_idx[index -1]);
} }
else if ((CMND_KEYIDX == command_code) && (index > 0) && (index <= MAX_DOMOTICZ_IDX)) { else if ((CMND_KEYIDX == command_code) && (index > 0) && (index <= MAX_DOMOTICZ_IDX)) {
if (payload >= 0) { if (payload >= 0) {
Settings.domoticz_key_idx[index -1] = payload; Settings.domoticz_key_idx[index -1] = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ "%s%d\":%d}"), command, index, Settings.domoticz_key_idx[index -1]); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, index, Settings.domoticz_key_idx[index -1]);
} }
else if ((CMND_SWITCHIDX == command_code) && (index > 0) && (index <= MAX_DOMOTICZ_IDX)) { else if ((CMND_SWITCHIDX == command_code) && (index > 0) && (index <= MAX_DOMOTICZ_IDX)) {
if (payload >= 0) { if (payload >= 0) {
Settings.domoticz_switch_idx[index -1] = payload; Settings.domoticz_switch_idx[index -1] = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ "%s%d\":%d}"), command, index, Settings.domoticz_key_idx[index -1]); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, index, Settings.domoticz_key_idx[index -1]);
} }
else if ((CMND_SENSORIDX == command_code) && (index > 0) && (index <= DZ_MAX_SENSORS)) { else if ((CMND_SENSORIDX == command_code) && (index > 0) && (index <= DZ_MAX_SENSORS)) {
if (payload >= 0) { if (payload >= 0) {
Settings.domoticz_sensor_idx[index -1] = payload; Settings.domoticz_sensor_idx[index -1] = payload;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ "%s%d\":%d}"), command, index, Settings.domoticz_sensor_idx[index -1]); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, index, Settings.domoticz_sensor_idx[index -1]);
} }
else if (CMND_UPDATETIMER == command_code) { else if (CMND_UPDATETIMER == command_code) {
if ((payload >= 0) && (payload < 3601)) { if ((payload >= 0) && (payload < 3601)) {

View File

@ -102,7 +102,7 @@ void IrReceiveCheck()
if ((iridx < 0) || (iridx > 14)) { if ((iridx < 0) || (iridx > 14)) {
iridx = 0; iridx = 0;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_IRRECEIVED "\":{\"" D_IR_PROTOCOL "\":\"%s\", \"" D_IR_BITS "\":%d, \"" D_IR_DATA "\":\"%X\"}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_IRRECEIVED "\":{\"" D_IR_PROTOCOL "\":\"%s\",\"" D_IR_BITS "\":%d,\"" D_IR_DATA "\":\"%X\"}}"),
GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, results.value); GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, results.value);
MqttPublishPrefixTopic_P(6, PSTR(D_IRRECEIVED)); MqttPublishPrefixTopic_P(6, PSTR(D_IRRECEIVED));
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ

View File

@ -90,7 +90,7 @@ void SonoffBridgeReceived()
} }
} }
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_RFRECEIVED "\":{\"" D_SYNC "\":%d, \"" D_LOW "\":%d, \"" D_HIGH "\":%d, \"" D_DATA "\":\"%06X\", \"" D_CMND_RFKEY "\":%s}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_RFRECEIVED "\":{\"" D_SYNC "\":%d,\"" D_LOW "\":%d,\"" D_HIGH "\":%d,\"" D_DATA "\":\"%06X\",\"" D_CMND_RFKEY "\":%s}}"),
sync_time, low_time, high_time, received_id, rfkey); sync_time, low_time, high_time, received_id, rfkey);
MqttPublishPrefixTopic_P(6, PSTR(D_RFRECEIVED)); MqttPublishPrefixTopic_P(6, PSTR(D_RFRECEIVED));
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ

View File

@ -336,10 +336,10 @@ void LightPreparePower()
GetPowerDevice(scommand, devices_present, sizeof(scommand)); GetPowerDevice(scommand, devices_present, sizeof(scommand));
if (light_subtype > LST_SINGLE) { if (light_subtype > LST_SINGLE) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\", \"" D_CMND_DIMMER "\":%d, \"" D_CMND_COLOR "\":\"%s\"}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d,\"" D_CMND_COLOR "\":\"%s\"}"),
scommand, GetStateText(light_power), Settings.light_dimmer, LightGetColor(0, scolor)); scommand, GetStateText(light_power), Settings.light_dimmer, LightGetColor(0, scolor));
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\", \"" D_CMND_DIMMER "\":%d}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d}"),
scommand, GetStateText(light_power), Settings.light_dimmer); scommand, GetStateText(light_power), Settings.light_dimmer);
} }
} }
@ -782,7 +782,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
} }
} }
if (!valid_entry && (1 == index)) { if (!valid_entry && (1 == index)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\"}"), command, LightGetColor(0, scolor)); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, LightGetColor(0, scolor));
} }
if (index > 1) { if (index > 1) {
scolor[0] = '\0'; scolor[0] = '\0';
@ -908,7 +908,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
else if (CMND_UNDOCA == command_code) { // Theos legacy status else if (CMND_UNDOCA == command_code) { // Theos legacy status
LightGetColor(1, scolor); LightGetColor(1, scolor);
scolor[6] = '\0'; // RGB only scolor[6] = '\0'; // RGB only
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, %d, %d, %d, %d, %d"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,%d,%d,%d,%d,%d"),
scolor, Settings.light_fade, Settings.light_correction, Settings.light_scheme, Settings.light_speed, Settings.light_width); scolor, Settings.light_fade, Settings.light_correction, Settings.light_scheme, Settings.light_speed, Settings.light_width);
MqttPublishPrefixTopic_P(1, type); MqttPublishPrefixTopic_P(1, type);
mqtt_data[0] = '\0'; mqtt_data[0] = '\0';

View File

@ -28,7 +28,7 @@
boolean udp_connected = false; boolean udp_connected = false;
char packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP packet char packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP packet
IPAddress ipMulticast(239, 255, 255, 250); // Simple Service Discovery Protocol (SSDP) IPAddress ipMulticast(239,255,255,250); // Simple Service Discovery Protocol (SSDP)
uint32_t port_multicast = 1900; // Multicast address and port uint32_t port_multicast = 1900; // Multicast address and port
/*********************************************************************************************\ /*********************************************************************************************\
@ -220,10 +220,10 @@ void PollUdp()
// AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet received")); // AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet received"));
// AddLog_P(LOG_LEVEL_DEBUG_MORE, request.c_str()); // AddLog_P(LOG_LEVEL_DEBUG_MORE, request.c_str());
if ((EMUL_WEMO == Settings.flag.emulation) && (request.indexOf(F("urn:belkin:device:**")) > 0)) { if ((EMUL_WEMO == Settings.flag2.emulation) && (request.indexOf(F("urn:belkin:device:**")) > 0)) {
WemoRespondToMSearch(); WemoRespondToMSearch();
} }
else if ((EMUL_HUE == Settings.flag.emulation) && else if ((EMUL_HUE == Settings.flag2.emulation) &&
((request.indexOf(F("st:urn:schemas-upnp-org:device:basic:1")) > 0) || ((request.indexOf(F("st:urn:schemas-upnp-org:device:basic:1")) > 0) ||
(request.indexOf(F("st:upnp:rootdevice")) > 0) || (request.indexOf(F("st:upnp:rootdevice")) > 0) ||
(request.indexOf(F("st:ssdpsearch:all")) > 0) || (request.indexOf(F("st:ssdpsearch:all")) > 0) ||

View File

@ -47,13 +47,13 @@ struct ColorScheme {
uint8_t count; uint8_t count;
}; };
WsColor kIncandescent[2] = { 255, 140, 20, 0, 0, 0 }; WsColor kIncandescent[2] = { 255,140,20, 0,0,0 };
WsColor kRgb[3] = { 255, 0, 0, 0, 255, 0, 0, 0, 255 }; WsColor kRgb[3] = { 255,0,0, 0,255,0, 0,0,255 };
WsColor kChristmas[2] = { 255, 0, 0, 0, 255, 0 }; WsColor kChristmas[2] = { 255,0,0, 0,255,0 };
WsColor kHanukkah[2] = { 0, 0, 255, 255, 255, 255 }; WsColor kHanukkah[2] = { 0,0,255, 255,255,255 };
WsColor kwanzaa[3] = { 255, 0, 0, 0, 0, 0, 0, 255, 0 }; WsColor kwanzaa[3] = { 255,0,0, 0,0,0, 0,255,0 };
WsColor kRainbow[7] = { 255, 0, 0, 255, 128, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 128, 0, 255, 255, 0, 255 }; WsColor kRainbow[7] = { 255,0,0, 255,128,0, 255,255,0, 0,255,0, 0,0,255, 128,0,255, 255,0,255 };
WsColor kFire[3] = { 255, 0, 0, 255, 102, 0, 255, 192, 0 }; WsColor kFire[3] = { 255,0,0, 255,102,0, 255,192,0 };
ColorScheme kSchemes[7] = { ColorScheme kSchemes[7] = {
kIncandescent, 2, kIncandescent, 2,
kRgb, 3, kRgb, 3,

View File

@ -103,7 +103,7 @@ void CounterShow(boolean json)
} }
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_COUNTER "%d\":%s"), mqtt_data, i +1, counter); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_COUNTER "%d\":%s"), mqtt_data, i +1, counter);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
if (1 == dsxflg) { if (1 == dsxflg) {
DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]); DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]);

View File

@ -354,27 +354,27 @@ void HlwMarginCheck()
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{")); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
jsonflg = 0; jsonflg = 0;
if (HlwMargin(0, Settings.hlw_pmin, uwatts, flag, hlw_pmin_flag)) { if (HlwMargin(0, Settings.hlw_pmin, uwatts, flag, hlw_pmin_flag)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_POWERLOW "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", GetStateText(flag)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_POWERLOW "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
jsonflg = 1; jsonflg = 1;
} }
if (HlwMargin(1, Settings.hlw_pmax, uwatts, flag, hlw_pmax_flag)) { if (HlwMargin(1, Settings.hlw_pmax, uwatts, flag, hlw_pmax_flag)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_POWERHIGH "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", GetStateText(flag)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_POWERHIGH "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
jsonflg = 1; jsonflg = 1;
} }
if (HlwMargin(0, Settings.hlw_umin, uvoltage, flag, hlw_umin_flag)) { if (HlwMargin(0, Settings.hlw_umin, uvoltage, flag, hlw_umin_flag)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_VOLTAGELOW "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", GetStateText(flag)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_VOLTAGELOW "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
jsonflg = 1; jsonflg = 1;
} }
if (HlwMargin(1, Settings.hlw_umax, uvoltage, flag, hlw_umax_flag)) { if (HlwMargin(1, Settings.hlw_umax, uvoltage, flag, hlw_umax_flag)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_VOLTAGEHIGH "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", GetStateText(flag)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_VOLTAGEHIGH "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
jsonflg = 1; jsonflg = 1;
} }
if (HlwMargin(0, Settings.hlw_imin, ucurrent, flag, hlw_imin_flag)) { if (HlwMargin(0, Settings.hlw_imin, ucurrent, flag, hlw_imin_flag)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_CURRENTLOW "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", GetStateText(flag)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_CURRENTLOW "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
jsonflg = 1; jsonflg = 1;
} }
if (HlwMargin(1, Settings.hlw_imax, ucurrent, flag, hlw_imax_flag)) { if (HlwMargin(1, Settings.hlw_imax, ucurrent, flag, hlw_imax_flag)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_CURRENTHIGH "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", GetStateText(flag)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_CURRENTHIGH "\":\"%s\""), mqtt_data, (jsonflg)?",":"", GetStateText(flag));
jsonflg = 1; jsonflg = 1;
} }
if (jsonflg) { if (jsonflg) {
@ -526,10 +526,10 @@ boolean HlwCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_len,
char syesterday_energy[10]; char syesterday_energy[10];
char stoday_energy[10]; char stoday_energy[10];
char stotal_energy[10]; char stotal_energy[10];
dtostrfd((float)Settings.hlw_kWhyesterday / 100000000, Settings.flag.energy_resolution, syesterday_energy); dtostrfd((float)Settings.hlw_kWhyesterday / 100000000, Settings.flag2.energy_resolution, syesterday_energy);
dtostrfd((float)RtcSettings.hlw_kWhtoday / 100000000, Settings.flag.energy_resolution, stoday_energy); dtostrfd((float)RtcSettings.hlw_kWhtoday / 100000000, Settings.flag2.energy_resolution, stoday_energy);
dtostrfd((float)(RtcSettings.hlw_kWhtotal + (hlw_kWhtoday / 1000)) / 100000, Settings.flag.energy_resolution, stotal_energy); dtostrfd((float)(RtcSettings.hlw_kWhtotal + (hlw_kWhtoday / 1000)) / 100000, Settings.flag2.energy_resolution, stotal_energy);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":{\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":{\"" D_TOTAL "\":%s,\"" D_YESTERDAY "\":%s,\"" D_TODAY "\":%s}}"),
command, stotal_energy, syesterday_energy, stoday_energy); command, stotal_energy, syesterday_energy, stoday_energy);
status_flag = 1; status_flag = 1;
} }
@ -686,18 +686,18 @@ void HlwShow(boolean json, boolean option)
char speriod[20]; char speriod[20];
HlwReadEnergy(option, total_energy, daily_energy, energy, watts, voltage, current, power_factor); HlwReadEnergy(option, total_energy, daily_energy, energy, watts, voltage, current, power_factor);
dtostrfd(total_energy, Settings.flag.energy_resolution, stotal_energy); dtostrfd(total_energy, Settings.flag2.energy_resolution, stotal_energy);
dtostrfd(daily_energy, Settings.flag.energy_resolution, sdaily_energy); dtostrfd(daily_energy, Settings.flag2.energy_resolution, sdaily_energy);
dtostrfd(energy, Settings.flag.wattage_resolution, senergy); dtostrfd(energy, Settings.flag2.wattage_resolution, senergy);
dtostrfd(watts, Settings.flag.wattage_resolution, swatts); dtostrfd(watts, Settings.flag2.wattage_resolution, swatts);
dtostrfd(voltage, Settings.flag.voltage_resolution, svoltage); dtostrfd(voltage, Settings.flag2.voltage_resolution, svoltage);
dtostrfd(current, 3, scurrent); dtostrfd(current, Settings.flag2.current_resolution, scurrent);
dtostrfd(power_factor, 2, spower_factor); dtostrfd(power_factor, 2, spower_factor);
dtostrfd((float)Settings.hlw_kWhyesterday / 100000000, Settings.flag.energy_resolution, syesterday_energy); dtostrfd((float)Settings.hlw_kWhyesterday / 100000000, Settings.flag2.energy_resolution, syesterday_energy);
if (json) { if (json) {
snprintf_P(speriod, sizeof(speriod), PSTR(", \"" D_PERIOD "\":%s"), senergy); snprintf_P(speriod, sizeof(speriod), PSTR(",\"" D_PERIOD "\":%s"), senergy);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s%s, \"" D_POWERUSAGE "\":%s, \"" D_POWERFACTOR "\":%s, \"" D_VOLTAGE "\":%s, \"" D_CURRENT "\":%s}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_TOTAL "\":%s,\"" D_YESTERDAY "\":%s,\"" D_TODAY "\":%s%s,\"" D_POWERUSAGE "\":%s,\"" D_POWERFACTOR "\":%s,\"" D_VOLTAGE "\":%s,\"" D_CURRENT "\":%s}"),
mqtt_data, stotal_energy, syesterday_energy, sdaily_energy, (option) ? speriod : "", swatts, spower_factor, svoltage, scurrent); mqtt_data, stotal_energy, syesterday_energy, sdaily_energy, (option) ? speriod : "", swatts, spower_factor, svoltage, scurrent);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
if (option) { // Only send if telemetry if (option) { // Only send if telemetry
@ -720,7 +720,7 @@ void MqttShowHlw8012(byte option)
* option 1 = show period energy usage * option 1 = show period energy usage
*/ */
// {"Time":"2017-03-04T13:37:24", "Total":0.013, "Yesterday":0.013, "Today":0.000, "Period":0, "Power":0, "Factor":0.00, "Voltage":0, "Current":0.000} // {"Time":"2017-03-04T13:37:24", "Total":0.013, "Yesterday":0.013, "Today":0.000, "Period":0, "Power":0, "Factor":0.00, "Voltage":0, "Current":0.000}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_TIME "\":\"%s\", "), GetDateAndTime().c_str()); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_TIME "\":\"%s\","), GetDateAndTime().c_str());
HlwShow(1, option); HlwShow(1, option);
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain); MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain);
} }

View File

@ -116,11 +116,11 @@ void SonoffScShow(boolean json)
float t = ConvertTemp(sc_value[1]); float t = ConvertTemp(sc_value[1]);
float h = sc_value[0]; float h = sc_value[0];
dtostrfd(t, Settings.flag.temperature_resolution, temperature); dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
dtostrfd(h, Settings.flag.humidity_resolution, humidity); dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_LIGHT "\":%d, \"" D_NOISE "\":%d, \"" D_AIRQUALITY "\":%d"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_TEMPERATURE "\":%s,\"" D_HUMIDITY "\":%s,\"" D_LIGHT "\":%d,\"" D_NOISE "\":%d,\"" D_AIRQUALITY "\":%d"),
mqtt_data, temperature, humidity, sc_value[2], sc_value[3], sc_value[4]); mqtt_data, temperature, humidity, sc_value[2], sc_value[3], sc_value[4]);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
DomoticzTempHumSensor(temperature, humidity); DomoticzTempHumSensor(temperature, humidity);

View File

@ -190,10 +190,10 @@ void Ds18b20Show(boolean json)
if (Ds18b20ReadTemperature(t)) { // Check if read failed if (Ds18b20ReadTemperature(t)) { // Check if read failed
char temperature[10]; char temperature[10];
dtostrfi(t, Settings.flag.temperature_resolution, temperature); dtostrfi(t, Settings.flag2.temperature_resolution, temperature);
if(json) { if(json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18B20\":{\"" D_TEMPERATURE "\":%s}"), mqtt_data, temperature); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"DS18B20\":{\"" D_TEMPERATURE "\":%s}"), mqtt_data, temperature);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
DomoticzSensor(DZ_TEMP, temperature); DomoticzSensor(DZ_TEMP, temperature);
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ

View File

@ -171,17 +171,17 @@ void Ds18x20Show(boolean json)
for (byte i = 0; i < Ds18x20Sensors(); i++) { for (byte i = 0; i < Ds18x20Sensors(); i++) {
if (Ds18x20Read(i, t)) { // Check if read failed if (Ds18x20Read(i, t)) { // Check if read failed
Ds18x20Type(i); Ds18x20Type(i);
dtostrfd(t, Settings.flag.temperature_resolution, temperature); dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
if (json) { if (json) {
if (!dsxflg) { if (!dsxflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18x20\":{"), mqtt_data); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"DS18x20\":{"), mqtt_data);
stemp[0] = '\0'; stemp[0] = '\0';
} }
dsxflg++; dsxflg++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"DS%d\":{\"" D_TYPE "\":\"%s\", \"" D_ADDRESS "\":\"%s\", \"" D_TEMPERATURE "\":%s}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"DS%d\":{\"" D_TYPE "\":\"%s\",\"" D_ADDRESS "\":\"%s\",\"" D_TEMPERATURE "\":%s}"),
mqtt_data, stemp, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), temperature); mqtt_data, stemp, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), temperature);
strcpy(stemp, ", "); strcpy(stemp, ",");
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
if (1 == dsxflg) { if (1 == dsxflg) {
DomoticzSensor(DZ_TEMP, temperature); DomoticzSensor(DZ_TEMP, temperature);

View File

@ -37,7 +37,7 @@ byte dht_sensors = 0;
struct DHTSTRUCT { struct DHTSTRUCT {
byte pin; byte pin;
byte type; byte type;
char stype[10]; char stype[12];
uint32_t lastreadtime; uint32_t lastreadtime;
uint8_t lastresult; uint8_t lastresult;
float t; float t;
@ -204,16 +204,7 @@ void DhtInit()
pinMode(Dht[i].pin, INPUT_PULLUP); pinMode(Dht[i].pin, INPUT_PULLUP);
Dht[i].lastreadtime = 0; Dht[i].lastreadtime = 0;
Dht[i].lastresult = 0; Dht[i].lastresult = 0;
switch (Dht[i].type) { strcpy_P(Dht[i].stype, kSensors[Dht[i].type]);
case GPIO_DHT11:
strcpy_P(Dht[i].stype, PSTR("DHT11"));
break;
case GPIO_DHT21:
strcpy_P(Dht[i].stype, PSTR("AM2301"));
break;
case GPIO_DHT22:
strcpy_P(Dht[i].stype, PSTR("DHT22"));
}
if (dht_sensors > 1) { if (dht_sensors > 1) {
snprintf_P(Dht[i].stype, sizeof(Dht[i].stype), PSTR("%s-%02d"), Dht[i].stype, Dht[i].pin); snprintf_P(Dht[i].stype, sizeof(Dht[i].stype), PSTR("%s-%02d"), Dht[i].stype, Dht[i].pin);
} }
@ -230,8 +221,8 @@ void DhtShow(boolean json)
byte dsxflg = 0; byte dsxflg = 0;
for (byte i = 0; i < dht_sensors; i++) { for (byte i = 0; i < dht_sensors; i++) {
if (DhtReadTempHum(i, t, h)) { // Read temperature if (DhtReadTempHum(i, t, h)) { // Read temperature
dtostrfd(t, Settings.flag.temperature_resolution, temperature); dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
dtostrfd(h, Settings.flag.humidity_resolution, humidity); dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, temperature, humidity); snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, temperature, humidity);

View File

@ -24,6 +24,8 @@
* *
* Reading temperature and humidity takes about 320 milliseconds! * Reading temperature and humidity takes about 320 milliseconds!
* Source: Marinus vd Broek https://github.com/ESP8266nu/ESPEasy * Source: Marinus vd Broek https://github.com/ESP8266nu/ESPEasy
*
* I2C Address: None
\*********************************************************************************************/ \*********************************************************************************************/
enum { enum {
@ -161,10 +163,10 @@ boolean ShtReadTempHum(float &t, float &h)
/********************************************************************************************/ /********************************************************************************************/
boolean ShtDetect() void ShtDetect()
{ {
if (sht_type) { if (sht_type) {
return true; return;
} }
float t; float t;
@ -179,7 +181,6 @@ boolean ShtDetect()
Wire.begin(sht_sda_pin, sht_scl_pin); Wire.begin(sht_sda_pin, sht_scl_pin);
sht_type = 0; sht_type = 0;
} }
return sht_type;
} }
void ShtShow(boolean json) void ShtShow(boolean json)
@ -192,8 +193,8 @@ void ShtShow(boolean json)
char temperature[10]; char temperature[10];
char humidity[10]; char humidity[10];
dtostrfd(t, Settings.flag.temperature_resolution, temperature); dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
dtostrfd(h, Settings.flag.humidity_resolution, humidity); dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, "SHT1X", temperature, humidity); snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, "SHT1X", temperature, humidity);

View File

@ -23,6 +23,8 @@
* HTU21 - Temperature and Humidy * HTU21 - Temperature and Humidy
* *
* Source: Heiko Krupp * Source: Heiko Krupp
*
* I2C Address: 0x40
\*********************************************************************************************/ \*********************************************************************************************/
#define HTU21_ADDR 0x40 #define HTU21_ADDR 0x40
@ -52,6 +54,8 @@
#define HTU21_CRC8_POLYNOM 0x13100 #define HTU21_CRC8_POLYNOM 0x13100
const char kHtuTypes[] PROGMEM = "HTU21|SI7013|SI7020|SI7021|T/RH?";
uint8_t htu_address; uint8_t htu_address;
uint8_t htu_type = 0; uint8_t htu_type = 0;
uint8_t delay_temp; uint8_t delay_temp;
@ -95,8 +99,8 @@ uint8_t HtuReadDeviceId(void)
void HtuSetResolution(uint8_t resolution) void HtuSetResolution(uint8_t resolution)
{ {
uint8_t current = I2cRead8(HTU21_ADDR, HTU21_READREG); uint8_t current = I2cRead8(HTU21_ADDR, HTU21_READREG);
current &= 0x7E; // Replace current resolution bits with 0 current &= 0x7E; // Replace current resolution bits with 0
current |= resolution; // Add new resolution bits to register current |= resolution; // Add new resolution bits to register
I2cWrite8(HTU21_ADDR, HTU21_WRITEREG, current); I2cWrite8(HTU21_ADDR, HTU21_WRITEREG, current);
} }
@ -124,12 +128,11 @@ void HtuHeater(uint8_t heater)
I2cWrite8(HTU21_ADDR, HTU21_WRITEREG, current); I2cWrite8(HTU21_ADDR, HTU21_WRITEREG, current);
} }
boolean HtuInit() void HtuInit()
{ {
HtuReset(); HtuReset();
HtuHeater(HTU21_HEATER_OFF); HtuHeater(HTU21_HEATER_OFF);
HtuSetResolution(HTU21_RES_RH12_T14); HtuSetResolution(HTU21_RES_RH12_T14);
return true;
} }
float HtuReadHumidity(void) float HtuReadHumidity(void)
@ -207,50 +210,40 @@ float HtuCompensatedHumidity(float humidity, float temperature)
/********************************************************************************************/ /********************************************************************************************/
uint8_t HtuDetect() void HtuDetect()
{ {
if (htu_type) { if (htu_type) {
return true; return;
} }
boolean success = false;
htu_address = HTU21_ADDR; htu_address = HTU21_ADDR;
htu_type = HtuReadDeviceId(); htu_type = HtuReadDeviceId();
success = HtuInit(); if (htu_type) {
switch (htu_type) { uint8_t index = 0;
case HTU21_CHIPID: HtuInit();
strcpy_P(htu_types, PSTR("HTU21")); switch (htu_type) {
delay_temp=50; case HTU21_CHIPID:
delay_humidity=16; delay_temp = 50;
break; delay_humidity = 16;
case SI7013_CHIPID: break;
strcpy_P(htu_types, PSTR("SI7013")); case SI7021_CHIPID:
delay_temp=12; index++; // 3
delay_humidity=23; case SI7020_CHIPID:
break; index++; // 2
case SI7020_CHIPID: case SI7013_CHIPID:
strcpy_P(htu_types, PSTR("SI7020")); index++; // 1
delay_temp=12; delay_temp = 12;
delay_humidity=23; delay_humidity = 23;
break; break;
case SI7021_CHIPID: default:
strcpy_P(htu_types, PSTR("SI7021")); index = 4;
delay_temp=12; delay_temp = 50;
delay_humidity=23; delay_humidity = 23;
break; }
default: GetTextIndexed(htu_types, sizeof(htu_types), index, kHtuTypes);
strcpy_P(htu_types, PSTR("T/RH?"));
delay_temp=50;
delay_humidity=23;
}
if (success) {
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, htu_types, htu_address); snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, htu_types, htu_address);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
} else {
htu_type = 0;
} }
return success;
} }
void HtuShow(boolean json) void HtuShow(boolean json)
@ -262,8 +255,8 @@ void HtuShow(boolean json)
float t = HtuReadTemperature(); float t = HtuReadTemperature();
float h = HtuReadHumidity(); float h = HtuReadHumidity();
h = HtuCompensatedHumidity(h, t); h = HtuCompensatedHumidity(h, t);
dtostrfd(t, Settings.flag.temperature_resolution, temperature); dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
dtostrfd(h, Settings.flag.humidity_resolution, humidity); dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, htu_types, temperature, humidity); snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, htu_types, temperature, humidity);

View File

@ -23,9 +23,12 @@
* BMP085, BMP180, BMP280, BME280 - Pressure and Temperature and Humidy (BME280 only) * BMP085, BMP180, BMP280, BME280 - Pressure and Temperature and Humidy (BME280 only)
* *
* Source: Heiko Krupp and Adafruit Industries * Source: Heiko Krupp and Adafruit Industries
*
* I2C Address: 0x76 or 0x77
\*********************************************************************************************/ \*********************************************************************************************/
#define BMP_ADDR 0x77 #define BMP_ADDR1 0x77
#define BMP_ADDR2 0x76
#define BMP180_CHIPID 0x55 #define BMP180_CHIPID 0x55
#define BMP280_CHIPID 0x58 #define BMP280_CHIPID 0x58
@ -33,11 +36,15 @@
#define BMP_REGISTER_CHIPID 0xD0 #define BMP_REGISTER_CHIPID 0xD0
double bmp_sealevel = 0.0; const char kBmpTypes[] PROGMEM = "BMP180|BMP280|BME280";
uint8_t bmp_address;
uint8_t bmp_type = 0; uint8_t bmp_type = 0;
uint8_t bmp_address;
uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 };
char bmp_types[7]; char bmp_types[7];
double bmp_sealevel = 0.0;
/*********************************************************************************************\ /*********************************************************************************************\
* BMP085 and BME180 * BMP085 and BME180
\*********************************************************************************************/ \*********************************************************************************************/
@ -371,42 +378,41 @@ double BmpReadHumidity(void)
/********************************************************************************************/ /********************************************************************************************/
boolean BmpDetect() void BmpDetect()
{ {
if (bmp_type) { if (bmp_type) {
return true; return;
} }
boolean success = false; for (byte i = 0; i < sizeof(bmp_addresses); i++) {
bmp_address = bmp_addresses[i];
bmp_address = BMP_ADDR;
bmp_type = I2cRead8(bmp_address, BMP_REGISTER_CHIPID);
if (!bmp_type) {
bmp_address--;
bmp_type = I2cRead8(bmp_address, BMP_REGISTER_CHIPID); bmp_type = I2cRead8(bmp_address, BMP_REGISTER_CHIPID);
if (bmp_type) {
break;
}
} }
strcpy_P(bmp_types, PSTR("BMP")); if (bmp_type) {
switch (bmp_type) { boolean success = false;
case BMP180_CHIPID: uint8_t index = 0;
success = Bmp180Calibration(); switch (bmp_type) {
strcpy_P(bmp_types, PSTR("BMP180")); case BMP180_CHIPID:
break; success = Bmp180Calibration();
case BMP280_CHIPID: break;
success = Bmx280Calibrate(); case BME280_CHIPID:
strcpy_P(bmp_types, PSTR("BMP280")); index++; // 2
break; case BMP280_CHIPID:
case BME280_CHIPID: index++; // 1
success = Bmx280Calibrate(); success = Bmx280Calibrate();
strcpy_P(bmp_types, PSTR("BME280")); }
if (success) {
GetTextIndexed(bmp_types, sizeof(bmp_types), index, kBmpTypes);
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp_types, bmp_address);
AddLog(LOG_LEVEL_DEBUG);
}
else {
bmp_type = 0;
}
} }
if (success) {
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp_types, bmp_address);
AddLog(LOG_LEVEL_DEBUG);
}
else {
bmp_type = 0;
}
return success;
} }
void BmpShow(boolean json) void BmpShow(boolean json)
@ -421,19 +427,19 @@ void BmpShow(boolean json)
double t = BmpReadTemperature(); double t = BmpReadTemperature();
double p = BmpReadPressure(); double p = BmpReadPressure();
double h = BmpReadHumidity(); double h = BmpReadHumidity();
dtostrfd(t, Settings.flag.temperature_resolution, temperature); dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
dtostrfd(p, Settings.flag.pressure_resolution, pressure); dtostrfd(p, Settings.flag2.pressure_resolution, pressure);
dtostrfd(h, Settings.flag.humidity_resolution, humidity); dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
dtostrfd(bmp_sealevel, Settings.flag.pressure_resolution, sea_pressure); dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure);
if (json) { if (json) {
snprintf_P(sealevel, sizeof(sealevel), PSTR(", \"" D_PRESSUREATSEALEVEL "\":%s"), sea_pressure); snprintf_P(sealevel, sizeof(sealevel), PSTR(",\"" D_PRESSUREATSEALEVEL "\":%s"), sea_pressure);
if (BME280_CHIPID == bmp_type) { if (BME280_CHIPID == bmp_type) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_PRESSURE "\":%s%s}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_TEMPERATURE "\":%s,\"" D_HUMIDITY "\":%s,\"" D_PRESSURE "\":%s%s}"),
mqtt_data, bmp_types, temperature, humidity, pressure, (Settings.altitude != 0) ? sealevel : ""); mqtt_data, bmp_types, temperature, humidity, pressure, (Settings.altitude != 0) ? sealevel : "");
} }
else { else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_PRESSURE "\":%s%s}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_TEMPERATURE "\":%s,\"" D_PRESSURE "\":%s%s}"),
mqtt_data, bmp_types, temperature, pressure, (Settings.altitude != 0) ? sealevel : ""); mqtt_data, bmp_types, temperature, pressure, (Settings.altitude != 0) ? sealevel : "");
} }
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ

View File

@ -21,6 +21,8 @@
#ifdef USE_BH1750 #ifdef USE_BH1750
/*********************************************************************************************\ /*********************************************************************************************\
* BH1750 - Ambient Light Intensity * BH1750 - Ambient Light Intensity
*
* I2C Address: 0x23 or 0x5C
\*********************************************************************************************/ \*********************************************************************************************/
#define BH1750_ADDR1 0x23 #define BH1750_ADDR1 0x23
@ -28,8 +30,9 @@
#define BH1750_CONTINUOUS_HIGH_RES_MODE 0x10 // Start measurement at 1lx resolution. Measurement time is approx 120ms. #define BH1750_CONTINUOUS_HIGH_RES_MODE 0x10 // Start measurement at 1lx resolution. Measurement time is approx 120ms.
uint8_t bh1750_address;
uint8_t bh1750_type = 0; uint8_t bh1750_type = 0;
uint8_t bh1750_address;
uint8_t bh1750_addresses[] = { BH1750_ADDR1, BH1750_ADDR2 };
uint16_t Bh1750ReadLux() uint16_t Bh1750ReadLux()
{ {
@ -42,36 +45,25 @@ uint16_t Bh1750ReadLux()
/********************************************************************************************/ /********************************************************************************************/
boolean Bh1750Detect() void Bh1750Detect()
{ {
if (bh1750_type) { if (bh1750_type) {
return true; return;
} }
uint8_t status; for (byte i = 0; i < sizeof(bh1750_addresses); i++) {
boolean success = false; bh1750_address = bh1750_addresses[i];
bh1750_address = BH1750_ADDR1;
Wire.beginTransmission(bh1750_address);
Wire.write(BH1750_CONTINUOUS_HIGH_RES_MODE);
status = Wire.endTransmission();
if (status) {
bh1750_address = BH1750_ADDR2;
Wire.beginTransmission(bh1750_address); Wire.beginTransmission(bh1750_address);
Wire.write(BH1750_CONTINUOUS_HIGH_RES_MODE); Wire.write(BH1750_CONTINUOUS_HIGH_RES_MODE);
status = Wire.endTransmission(); if (!Wire.endTransmission()) {
bh1750_type = 1;
break;
}
} }
if (!status) { if (bh1750_type) {
success = true;
bh1750_type = 1;
}
if (success) {
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "BH1750", bh1750_address); snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "BH1750", bh1750_address);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
} else {
bh1750_type = 0;
} }
return success;
} }
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
@ -85,7 +77,7 @@ void Bh1750Show(boolean json)
uint16_t illuminance = Bh1750ReadLux(); uint16_t illuminance = Bh1750ReadLux();
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"BH1750\":{\"" D_ILLUMINANCE "\":%d}"), mqtt_data, illuminance); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"BH1750\":{\"" D_ILLUMINANCE "\":%d}"), mqtt_data, illuminance);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
DomoticzSensor(DZ_ILLUMINANCE, illuminance); DomoticzSensor(DZ_ILLUMINANCE, illuminance);
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ

View File

@ -21,6 +21,8 @@
#ifdef USE_VEML6070 #ifdef USE_VEML6070
/*********************************************************************************************\ /*********************************************************************************************\
* VEML6070 - Ultra Violet Light Intensity * VEML6070 - Ultra Violet Light Intensity
*
* I2C Address: 0x38 and 0x39
\*********************************************************************************************/ \*********************************************************************************************/
#define VEML6070_ADDR_H 0x39 #define VEML6070_ADDR_H 0x39
@ -88,7 +90,7 @@ void Veml6070Show(boolean json)
uint16_t uvlevel = Veml6070ReadUv(); uint16_t uvlevel = Veml6070ReadUv();
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_UV_LEVEL "\":%d}"), mqtt_data, veml6070_types, uvlevel); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_UV_LEVEL "\":%d}"), mqtt_data, veml6070_types, uvlevel);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
DomoticzSensor(DZ_ILLUMINANCE, uvlevel); DomoticzSensor(DZ_ILLUMINANCE, uvlevel);
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ

View File

@ -24,6 +24,8 @@
* *
* Required library: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/ADS1115 * Required library: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/ADS1115
* *
* I2C Address: 0x48, 0x49, 0x4A or 0x4B
*
* The ADC input range (or gain) can be changed via the following * The ADC input range (or gain) can be changed via the following
* functions, but be careful never to exceed VDD +0.3V max, or to * functions, but be careful never to exceed VDD +0.3V max, or to
* exceed the upper and lower limits if you adjust the input range! * exceed the upper and lower limits if you adjust the input range!
@ -42,9 +44,8 @@
ADS1115 adc0; ADS1115 adc0;
uint8_t ads1115_address;
uint8_t ads1115_type = 0; uint8_t ads1115_type = 0;
uint8_t ads1115_address;
uint8_t ads1115_addresses[] = { uint8_t ads1115_addresses[] = {
ADS1115_ADDRESS_ADDR_GND, // address pin low (GND) ADS1115_ADDRESS_ADDR_GND, // address pin low (GND)
ADS1115_ADDRESS_ADDR_VDD, // address pin high (VCC) ADS1115_ADDRESS_ADDR_VDD, // address pin high (VCC)
@ -72,16 +73,13 @@ int16_t Ads1115GetConversion(byte channel)
/********************************************************************************************/ /********************************************************************************************/
boolean Ads1115Detect() void Ads1115Detect()
{ {
if (ads1115_type) { if (ads1115_type) {
return true; return;
} }
uint8_t status; for (byte i = 0; i < sizeof(ads1115_addresses); i++) {
boolean success = false;
for (byte i = 0; i < 4; i++) {
ads1115_address = ads1115_addresses[i]; ads1115_address = ads1115_addresses[i];
ADS1115 adc0(ads1115_address); ADS1115 adc0(ads1115_address);
if (adc0.testConnection()) { if (adc0.testConnection()) {
@ -89,16 +87,14 @@ boolean Ads1115Detect()
adc0.setGain(ADS1115_PGA_2P048); // Set the gain (PGA) +/-4.096V adc0.setGain(ADS1115_PGA_2P048); // Set the gain (PGA) +/-4.096V
adc0.setRate(ADS1115_RATE_860); adc0.setRate(ADS1115_RATE_860);
adc0.setMode(ADS1115_MODE_CONTINUOUS); adc0.setMode(ADS1115_MODE_CONTINUOUS);
success = true;
ads1115_type = 1; ads1115_type = 1;
break; break;
} }
} }
if (success) { if (ads1115_type) {
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "ADS1115", ads1115_address); snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "ADS1115", ads1115_address);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
} }
return success;
} }
void Ads1115Show(boolean json) void Ads1115Show(boolean json)
@ -112,12 +108,12 @@ void Ads1115Show(boolean json)
if (json) { if (json) {
if (!dsxflg ) { if (!dsxflg ) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"ADS1115\":{"), mqtt_data); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"ADS1115\":{"), mqtt_data);
stemp[0] = '\0'; stemp[0] = '\0';
} }
dsxflg++; dsxflg++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_ANALOG_INPUT "%d\":%d"), mqtt_data, stemp, i, adc_value); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_ANALOG_INPUT "%d\":%d"), mqtt_data, stemp, i, adc_value);
strcpy(stemp, ", "); strcpy(stemp, ",");
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value);

243
sonoff/xsns_13_ina219.ino Normal file
View File

@ -0,0 +1,243 @@
/*
xsns_13_ina219.ino - INA219 Current Sensor support for Sonoff-Tasmota
Copyright (C) 2017 Stefan Bode and Theo Arends
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_I2C
#ifdef USE_INA219
/*********************************************************************************************\
* INA219 - Low voltage (max 32V!) Current sensor
*
* Source: Adafruit Industries
*
* I2C Address: 0x40, 0x41 0x44 or 0x45
\*********************************************************************************************/
#define INA219_ADDRESS1 (0x40) // 1000000 (A0+A1=GND)
#define INA219_ADDRESS2 (0x41) // 1000000 (A0=Vcc, A1=GND)
#define INA219_ADDRESS3 (0x44) // 1000000 (A0=GND, A1=Vcc)
#define INA219_ADDRESS4 (0x45) // 1000000 (A0+A1=Vcc)
#define INA219_READ (0x01)
#define INA219_REG_CONFIG (0x00)
#define INA219_CONFIG_RESET (0x8000) // Reset Bit
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask
#define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
#define INA219_CONFIG_BVOLTAGERANGE_32V (0x2000) // 0-32V Range
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
#define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range
#define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
#define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
#define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range
#define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask
#define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511
#define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023
#define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047
#define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097
#define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask
#define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
#define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
#define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
#define INA219_CONFIG_MODE_POWERDOWN (0x0000)
#define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001)
#define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002)
#define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003)
#define INA219_CONFIG_MODE_ADCOFF (0x0004)
#define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005)
#define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006)
#define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007)
#define INA219_REG_SHUNTVOLTAGE (0x01)
#define INA219_REG_BUSVOLTAGE (0x02)
#define INA219_REG_POWER (0x03)
#define INA219_REG_CURRENT (0x04)
#define INA219_REG_CALIBRATION (0x05)
uint8_t ina219_type = 0;
uint8_t ina219_address;
uint8_t ina219_addresses[] = { INA219_ADDRESS1, INA219_ADDRESS2, INA219_ADDRESS3, INA219_ADDRESS4 };
uint32_t ina219_cal_value = 0;
// The following multiplier is used to convert raw current values to mA, taking into account the current config settings
uint32_t ina219_current_divider_ma = 0;
bool Ina219SetCalibration(uint8_t mode)
{
uint16_t config = 0;
switch (mode &3) {
case 0: // 32V 2A
case 3:
ina219_cal_value = 4096;
ina219_current_divider_ma = 10; // Current LSB = 100uA per bit (1000/100 = 10)
config = INA219_CONFIG_BVOLTAGERANGE_32V | INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT | INA219_CONFIG_SADCRES_12BIT_1S_532US | INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
break;
case 1: // 32V 1A
ina219_cal_value = 10240;
ina219_current_divider_ma = 25; // Current LSB = 40uA per bit (1000/40 = 25)
config |= INA219_CONFIG_BVOLTAGERANGE_32V | INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT | INA219_CONFIG_SADCRES_12BIT_1S_532US | INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
break;
case 2: // 16V 0.4A
ina219_cal_value = 8192;
ina219_current_divider_ma = 20; // Current LSB = 50uA per bit (1000/50 = 20)
config |= INA219_CONFIG_BVOLTAGERANGE_16V | INA219_CONFIG_GAIN_1_40MV | INA219_CONFIG_BADCRES_12BIT | INA219_CONFIG_SADCRES_12BIT_1S_532US | INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
break;
}
// Set Calibration register to 'Cal' calculated above
bool success = I2cWrite16(ina219_address, INA219_REG_CALIBRATION, ina219_cal_value);
if (success) {
// Set Config register to take into account the settings above
I2cWrite16(ina219_address, INA219_REG_CONFIG, config);
}
return success;
}
float Ina219GetShuntVoltage_mV()
{
// raw shunt voltage (16-bit signed integer, so +-32767)
int16_t value = I2cReadS16(ina219_address, INA219_REG_SHUNTVOLTAGE);
// shunt voltage in mV (so +-327mV)
return value * 0.01;
}
float Ina219GetBusVoltage_V()
{
// Shift to the right 3 to drop CNVR and OVF and multiply by LSB
// raw bus voltage (16-bit signed integer, so +-32767)
int16_t value = (int16_t)(((uint16_t)I2cReadS16(ina219_address, INA219_REG_BUSVOLTAGE) >> 3) * 4);
// bus voltage in volts
return value * 0.001;
}
float Ina219GetCurrent_mA()
{
// Sometimes a sharp load will reset the INA219, which will reset the cal register,
// meaning CURRENT and POWER will not be available ... avoid this by always setting
// a cal value even if it's an unfortunate extra step
I2cWrite16(ina219_address, INA219_REG_CALIBRATION, ina219_cal_value);
// Now we can safely read the CURRENT register!
// raw current value (16-bit signed integer, so +-32767)
float value = I2cReadS16(ina219_address, INA219_REG_CURRENT);
value /= ina219_current_divider_ma;
// current value in mA, taking into account the config settings and current LSB
return value;
}
/********************************************************************************************/
void Ina219Detect()
{
if (ina219_type) {
return;
}
for (byte i = 0; i < sizeof(ina219_addresses); i++) {
ina219_address = ina219_addresses[i];
if (Ina219SetCalibration(Settings.ina219_mode)) {
ina219_type = 1;
break;
}
}
if (ina219_type) {
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "INA219", ina219_address);
AddLog(LOG_LEVEL_DEBUG);
}
}
#ifdef USE_WEBSERVER
const char HTTP_SNS_INA219_DATA[] PROGMEM = "%s"
"{s}INA219 " D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
"{s}INA219 " D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
"{s}INA219 " D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}";
#endif // USE_WEBSERVER
void Ina219Show(boolean json)
{
if (ina219_type) {
char voltage[10];
char current[10];
char power[10];
float fvoltage = Ina219GetBusVoltage_V() + (Ina219GetShuntVoltage_mV() / 1000);
float fcurrent = Ina219GetCurrent_mA() / 1000;
float fpower = fvoltage * fcurrent;
dtostrfd(fvoltage, Settings.flag2.voltage_resolution, voltage);
dtostrfd(fpower, Settings.flag2.wattage_resolution, power);
dtostrfd(fcurrent, Settings.flag2.current_resolution, current);
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"INA219\":{\"" D_VOLTAGE "\":%s,\"" D_CURRENT "\":%s,\"" D_POWERUSAGE "\":%s}"),
mqtt_data, voltage, current, power);
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_VOLTAGE, voltage);
DomoticzSensor(DZ_CURRENT, current);
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_INA219_DATA, mqtt_data, voltage, current, power);
#endif // USE_WEBSERVER
}
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_13
boolean Xsns13(byte function)
{
boolean result = false;
if (i2c_flg) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
Ina219Detect();
break;
case FUNC_XSNS_JSON_APPEND:
Ina219Show(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
Ina219Show(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_INA219
#endif // USE_I2C