diff --git a/README.md b/README.md
index 77ed35fc1..264e899a0 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
## Sonoff-Tasmota
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
-Current version is **5.8.0i** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
+Current version is **5.8.0j** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
### ATTENTION All versions
diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino
index e7c357674..ed75ef40d 100644
--- a/sonoff/_releasenotes.ino
+++ b/sonoff/_releasenotes.ino
@@ -1,4 +1,13 @@
-/* 5.8.0i
+/* 5.8.0j
+ * Set default altitude to 0 to be used with pressure sensors
+ * Document flash settings area for future use
+ * Prepare for 32-bit power control (#995)
+ * Introduce sonoff.h master header
+ * Fix TLS MQTT SSL fingerprint test (#808, #970)
+ * Fix pressure calculation for some BMP versions regression introduced with version 5.8.0i (#974)
+ * Fix Domoticz Dimmer set to same level not powering on (#945)
+ *
+ * 5.8.0i
* Add Domoticz counter sensor to IrReceive representing Received IR Protocol and Data
* Fix Southern Hemisphere TIME_STD/TIME_DST (#968)
* Add Sea level pressure calculation (#974)
diff --git a/sonoff/settings.h b/sonoff/settings.h
index 90f2ddce4..2bfbda85f 100644
--- a/sonoff/settings.h
+++ b/sonoff/settings.h
@@ -52,172 +52,166 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
} sysBitfield;
struct SYSCFG {
- unsigned long cfg_holder;
- unsigned long saveFlag;
- unsigned long version;
- unsigned long bootcount;
- sysBitfield flag; // Add flag since 5.0.2
- int16_t savedata;
+ unsigned long cfg_holder; // 000
+ unsigned long saveFlag; // 004
+ unsigned long version; // 008
+ unsigned long bootcount; // 00C
+ sysBitfield flag; // 010 Add flag since 5.0.2
+ int16_t savedata; // 014
+ int8_t timezone; // 016
+ char otaUrl[101]; // 017
+ char mqtt_prefix[3][11]; // 07C
- int8_t timezone;
- char otaUrl[101];
+ byte free_09D[1]; // 09D
- char mqtt_prefix[3][11]; // was ex_friendlyname[33] until 3.2.5
+ byte seriallog_level; // 09E
+ uint8_t sta_config; // 09F
+ byte sta_active; // 0A0
+ char sta_ssid[2][33]; // 0A1
+ char sta_pwd[2][65]; // 0E3
+ char hostname[33]; // 165
+ char syslog_host[33]; // 186
- byte serial_enable; // Not used (ever)
- byte seriallog_level;
- uint8_t sta_config;
- byte sta_active;
- char sta_ssid[2][33];
- char sta_pwd[2][65];
- char hostname[33];
- char syslog_host[33];
- uint16_t syslog_port;
- byte syslog_level;
- uint8_t webserver;
- byte weblog_level;
+ byte free_1A7[1]; // 1A7
- char mqtt_fingerprint[60];
- char mqtt_host[33];
- uint16_t mqtt_port;
- char mqtt_client[33];
- char mqtt_user[33];
- char mqtt_pwd[33];
- char mqtt_topic[33];
- char button_topic[33];
- char mqtt_grptopic[33];
- char ex_state_text[3][11]; // was state_text until 5.1.6, was ex_mqtt_subtopic[33] until 4.1.1
- byte ex_mqtt_button_retain; // Not used since 5.0.2
- byte ex_mqtt_power_retain; // Not used since 5.0.2
- //byte ex_value_units; // Not used since 5.0.2
- //byte ex_button_restrict; // Not used since 5.0.2
- int16_t altitude; // Add since 5.8.0i
- uint16_t tele_period;
+ uint16_t syslog_port; // 1A8
+ byte syslog_level; // 1AA
+ uint8_t webserver; // 1AB
+ byte weblog_level; // 1AC
+ char mqtt_fingerprint[60]; // 1AD To be freed by binary fingerprint
+ char mqtt_host[33]; // 1E9
+ uint16_t mqtt_port; // 20A
+ char mqtt_client[33]; // 20C
+ char mqtt_user[33]; // 22D
+ char mqtt_pwd[33]; // 24E
+ char mqtt_topic[33]; // 26F
+ char button_topic[33]; // 290
+ char mqtt_grptopic[33]; // 2B1
+ uint8_t mqtt_fingerprinth[20]; // 2D2 Reserved for binary fingerprint
- uint8_t power;
- uint8_t ledstate;
+ byte free_2E6[2]; // 2E6
- uint8_t param[PARAM8_SIZE]; // was domoticz_in_topic until 5.1.6
- char state_text[4][11]; // was domoticz_out_topic until 5.1.6
+ power_t power; // 2E8
- uint16_t domoticz_update_timer;
- unsigned long domoticz_relay_idx[4];
- unsigned long domoticz_key_idx[4];
+ byte free_2EC[10]; // 2EC
- unsigned long hlw_pcal;
- unsigned long hlw_ucal;
- unsigned long hlw_ical;
- unsigned long hlw_kWhtoday;
- unsigned long hlw_kWhyesterday;
- uint16_t hlw_kWhdoy;
- uint16_t hlw_pmin;
- uint16_t hlw_pmax;
- uint16_t hlw_umin;
- uint16_t hlw_umax;
- uint16_t hlw_imin;
- uint16_t hlw_imax;
- uint16_t hlw_mpl; // MaxPowerLimit
- uint16_t hlw_mplh; // MaxPowerLimitHold
- uint16_t hlw_mplw; // MaxPowerLimitWindow
- uint16_t hlw_mspl; // MaxSafePowerLimit
- uint16_t hlw_msplh; // MaxSafePowerLimitHold
- uint16_t hlw_msplw; // MaxSafePowerLimitWindow
- uint16_t hlw_mkwh; // MaxEnergy
- uint16_t hlw_mkwhs; // MaxEnergyStart
+ int16_t altitude; // 2F6 Add since 5.8.0i
+ uint16_t tele_period; // 2F8
+ uint8_t ex_power; // 2FA Not used since 5.8.0j
+ uint8_t ledstate; // 2FB
+ uint8_t param[PARAM8_SIZE]; // 2FC was domoticz_in_topic until 5.1.6
+ char state_text[4][11]; // 313
- // 3.0.6
- uint16_t mqtt_retry; // was ex_pulsetime until 4.0.4
+ byte free_33F[1]; // 33F
- // 3.1.1
- uint8_t poweronstate;
+ uint16_t domoticz_update_timer; // 340
- // 3.1.6
- uint16_t blinktime;
- uint16_t blinkcount;
+ byte free_342[2]; // 342
- // 3.2.4
- uint16_t ws_pixels;
- uint8_t ws_red;
- uint8_t ws_green;
- uint8_t ws_blue;
- uint8_t ws_ledtable;
- uint8_t ws_dimmer;
- uint8_t ws_fade;
- uint8_t ws_speed;
- uint8_t ws_scheme;
- uint8_t ws_width;
- uint16_t ws_wakeup;
+ unsigned long domoticz_relay_idx[4]; // 344
+ unsigned long domoticz_key_idx[4]; // 354
- // 3.2.5
- char friendlyname[4][33];
+ unsigned long hlw_pcal; // 364
+ unsigned long hlw_ucal; // 368
+ unsigned long hlw_ical; // 36C
+ unsigned long hlw_kWhtoday; // 370
+ unsigned long hlw_kWhyesterday; // 374
+ uint16_t hlw_kWhdoy; // 378
+ uint16_t hlw_pmin; // 37A
+ uint16_t hlw_pmax; // 37C
+ uint16_t hlw_umin; // 37E
+ uint16_t hlw_umax; // 380
+ uint16_t hlw_imin; // 382
+ uint16_t hlw_imax; // 384
+ uint16_t hlw_mpl; // 386 MaxPowerLimit
+ uint16_t hlw_mplh; // 388 MaxPowerLimitHold
+ uint16_t hlw_mplw; // 38A MaxPowerLimitWindow
+ uint16_t hlw_mspl; // 38C MaxSafePowerLimit
+ uint16_t hlw_msplh; // 38E MaxSafePowerLimitHold
+ uint16_t hlw_msplw; // 390 MaxSafePowerLimitWindow
+ uint16_t hlw_mkwh; // 392 MaxEnergy
+ uint16_t hlw_mkwhs; // 394 MaxEnergyStart
+ uint16_t mqtt_retry; // 396
+ uint8_t poweronstate; // 398
- // 3.2.8
- char switch_topic[33];
- byte ex_mqtt_switch_retain; // Not used since 5.0.2
- uint8_t ex_mqtt_enabled; // Not used since 5.0.2
+ byte free_399[1]; // 399
- // 3.2.12
- uint8_t sleep;
+ uint16_t blinktime; // 39A
+ uint16_t blinkcount; // 39C
+ uint16_t ws_pixels; // 39E Not used since 5.8.0
+ uint8_t ws_red; // 3A0 Not used since 5.8.0
+ uint8_t ws_green; // 3A1 Not used since 5.8.0
+ uint8_t ws_blue; // 3A2 Not used since 5.8.0
+ uint8_t ws_ledtable; // 3A3 Not used since 5.8.0
+ uint8_t ws_dimmer; // 3A4 Not used since 5.8.0
+ uint8_t ws_fade; // 3A5 Not used since 5.8.0
+ uint8_t ws_speed; // 3A6 Not used since 5.8.0
+ uint8_t ws_scheme; // 3A7 Not used since 5.8.0
+ uint8_t ws_width; // 3A8 Not used since 5.8.0
- // 3.9.3
- uint16_t domoticz_switch_idx[4];
- uint16_t domoticz_sensor_idx[12];
- uint8_t module;
- mytmplt my_module;
- uint16_t led_pixels;
- uint8_t led_color[5];
- uint8_t led_table;
- uint8_t led_dimmer;
- uint8_t ex_led_dimmer1; // Never used
- uint8_t ex_led_dimmer2; // Never used
- uint8_t led_fade;
- uint8_t led_speed;
- uint8_t led_scheme;
- uint8_t led_width;
- uint16_t led_wakeup;
+ byte free_3A9[1]; // 3A9
- // 3.9.7
- uint8_t ex_emulation; // Not used since 5.0.2
+ uint16_t ws_wakeup; // 3AA Not used since 5.8.0
+ char friendlyname[4][33]; // 3AC
+ char switch_topic[33]; // 430
- // 3.9.20
- char web_password[33];
+ byte free_451[2]; // 451
- // 3.9.21
- uint8_t switchmode[4];
+ uint8_t sleep; // 453
+ uint16_t domoticz_switch_idx[4]; // 454
+ uint16_t domoticz_sensor_idx[12]; // 45C
+ uint8_t module; // 474
- // 4.0.4
- char ntp_server[3][33];
- uint16_t pulsetime[MAX_PULSETIMERS];
+ byte free_475[15]; // 475
- // 4.0.7
- uint16_t pwmvalue[5];
+ myio my_gp; // 484
+ uint16_t led_pixels; // 496
+ uint8_t led_color[5]; // 498
+ uint8_t led_table; // 49D
+ uint8_t led_dimmer; // 49E
- // 4.0.9
- uint32_t ip_address[4];
+ byte free_49F[2]; // 49F
- // 5.0.4
- unsigned long hlw_kWhtotal;
+ uint8_t led_fade; // 4A1
+ uint8_t led_speed; // 4A2
+ uint8_t led_scheme; // 4A3
+ uint8_t led_width; // 4A4
- // 5.0.4a
- char mqtt_fulltopic[101];
+ byte free_4A5[1]; // 4A5
- // 5.1.1
- unsigned long pCounter[MAX_COUNTERS];
- uint16_t pCounterType;
- uint16_t pCounterDebounce;
+ uint16_t led_wakeup; // 4A6
- // 5.4.1
- uint8_t sfb_code[17][9];
+ byte free_4A8[1]; // 4A8
+
+ char web_password[33]; // 4A9
+ uint8_t switchmode[4]; // 4CA
+ char ntp_server[3][33]; // 4CE
+
+ byte free_531[1]; // 531
+
+ uint16_t pulsetime[MAX_PULSETIMERS]; // 532
+ uint16_t pwmvalue[5]; // 53A
+ uint32_t ip_address[4]; // 544
+ unsigned long hlw_kWhtotal; // 554
+ char mqtt_fulltopic[101]; // 558
+
+ byte free_5BD[3]; // 5BD
+
+ unsigned long pCounter[MAX_COUNTERS]; // 5C0
+ uint16_t pCounterType; // 5D0
+ uint16_t pCounterDebounce; // 5D2
+ uint8_t sfb_code[17][9]; // 5D4
} sysCfg;
struct RTCMEM {
- uint16_t valid;
- byte osw_flag;
- uint8_t power;
- unsigned long hlw_kWhtoday;
- unsigned long hlw_kWhtotal;
- unsigned long pCounter[MAX_COUNTERS];
+ uint16_t valid; // 000
+ byte osw_flag; // 002
+ uint8_t unused; // 003
+ unsigned long hlw_kWhtoday; // 004
+ unsigned long hlw_kWhtotal; // 008
+ unsigned long pCounter[MAX_COUNTERS]; // 00C
+ power_t power; // 01C
} rtcMem;
// See issue https://github.com/esp8266/Arduino/issues/2913
diff --git a/sonoff/settings.ino b/sonoff/settings.ino
index 775c5c695..eb8ab58a6 100644
--- a/sonoff/settings.ino
+++ b/sonoff/settings.ino
@@ -63,14 +63,14 @@ void RTC_Load()
RTC_Dump();
#endif // DEBUG_THEO
if (rtcMem.valid != RTC_MEM_VALID) {
- memset(&rtcMem, 0x00, sizeof(RTCMEM));
+ memset(&rtcMem, 0, sizeof(RTCMEM));
rtcMem.valid = RTC_MEM_VALID;
- rtcMem.power = sysCfg.power;
rtcMem.hlw_kWhtoday = sysCfg.hlw_kWhtoday;
rtcMem.hlw_kWhtotal = sysCfg.hlw_kWhtotal;
- for (byte i = 0; i < 4; i++) {
+ for (byte i = 0; i < MAX_COUNTERS; i++) {
rtcMem.pCounter[i] = sysCfg.pCounter[i];
}
+ rtcMem.power = sysCfg.power;
RTC_Save();
}
_rtcHash = getRtcHash();
@@ -384,6 +384,16 @@ void CFG_DefaultSet2()
memset((char*)&sysCfg +16, 0x00, sizeof(SYSCFG) -16);
sysCfg.flag.savestate = SAVE_STATE;
+ //sysCfg.flag.button_restrict = 0;
+ //sysCfg.flag.value_units = 0;
+ sysCfg.flag.mqtt_enabled = MQTT_USE;
+ //sysCfg.flag.mqtt_response = 0;
+ sysCfg.flag.mqtt_power_retain = MQTT_POWER_RETAIN;
+ sysCfg.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
+ sysCfg.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
+
+ sysCfg.flag.emulation = EMULATION;
+
sysCfg.savedata = SAVE_DATA;
sysCfg.timezone = APP_TIMEZONE;
strlcpy(sysCfg.otaUrl, OTA_URL, sizeof(sysCfg.otaUrl));
@@ -411,10 +421,6 @@ void CFG_DefaultSet2()
strlcpy(sysCfg.mqtt_topic, MQTT_TOPIC, sizeof(sysCfg.mqtt_topic));
strlcpy(sysCfg.button_topic, "0", sizeof(sysCfg.button_topic));
strlcpy(sysCfg.mqtt_grptopic, MQTT_GRPTOPIC, sizeof(sysCfg.mqtt_grptopic));
- sysCfg.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
- sysCfg.flag.mqtt_power_retain = MQTT_POWER_RETAIN;
-// sysCfg.flag.value_units = 0;
-// sysCfg.flag.button_restrict = 0;
sysCfg.tele_period = TELE_PERIOD;
sysCfg.power = APP_POWER;
@@ -463,10 +469,6 @@ void CFG_DefaultSet2()
CFG_DefaultSet_3_9_3();
strlcpy(sysCfg.switch_topic, "0", sizeof(sysCfg.switch_topic));
- sysCfg.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
- sysCfg.flag.mqtt_enabled = MQTT_USE;
-
- sysCfg.flag.emulation = EMULATION;
strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password));
@@ -536,7 +538,7 @@ void CFG_DefaultSet_3_9_3()
sysCfg.module = MODULE;
for (byte i = 0; i < MAX_GPIO_PIN; i++){
- sysCfg.my_module.gp.io[i] = 0;
+ sysCfg.my_gp.io[i] = 0;
}
sysCfg.led_pixels = WS2812_LEDS;
@@ -621,8 +623,6 @@ void CFG_Delta()
}
if (sysCfg.version < 0x03020800) { // 3.2.8 - Add parameter
strlcpy(sysCfg.switch_topic, sysCfg.button_topic, sizeof(sysCfg.switch_topic));
- sysCfg.ex_mqtt_switch_retain = MQTT_SWITCH_RETAIN;
- sysCfg.ex_mqtt_enabled = MQTT_USE;
}
if (sysCfg.version < 0x03020C00) { // 3.2.12 - Add parameter
sysCfg.sleep = APP_SLEEP;
@@ -630,9 +630,6 @@ void CFG_Delta()
if (sysCfg.version < 0x03090300) { // 3.9.2d - Add parameter
CFG_DefaultSet_3_9_3();
}
- if (sysCfg.version < 0x03090700) { // 3.9.7 - Add parameter
- sysCfg.ex_emulation = EMULATION;
- }
if (sysCfg.version < 0x03091400) {
strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password));
}
@@ -643,8 +640,8 @@ void CFG_Delta()
CFG_DefaultSet_4_0_4();
}
if (sysCfg.version < 0x04000500) {
- memmove(sysCfg.my_module.gp.io, sysCfg.my_module.gp.io +1, MAX_GPIO_PIN -1); // move myio 1 byte to front
- sysCfg.my_module.gp.io[MAX_GPIO_PIN -1] = 0; // Clear ADC0
+ memmove(sysCfg.my_gp.io, sysCfg.my_gp.io +1, MAX_GPIO_PIN -1); // move myio 1 byte to front
+ sysCfg.my_gp.io[MAX_GPIO_PIN -1] = 0; // Clear ADC0
}
if (sysCfg.version < 0x04000700) {
for (byte i = 0; i < 5; i++) {
@@ -660,14 +657,14 @@ void CFG_Delta()
if (sysCfg.version < 0x05000105) {
sysCfg.flag = { 0 };
sysCfg.flag.savestate = SAVE_STATE;
- sysCfg.flag.button_restrict = 0;
- sysCfg.flag.value_units = 0;
- sysCfg.flag.mqtt_enabled = sysCfg.ex_mqtt_enabled;
+// sysCfg.flag.button_restrict = 0;
+// sysCfg.flag.value_units = 0;
+ sysCfg.flag.mqtt_enabled = MQTT_USE;
// sysCfg.flag.mqtt_response = 0;
- sysCfg.flag.mqtt_power_retain = sysCfg.ex_mqtt_power_retain;
- sysCfg.flag.mqtt_button_retain = sysCfg.ex_mqtt_button_retain;
- sysCfg.flag.mqtt_switch_retain = sysCfg.ex_mqtt_switch_retain;
- sysCfg.flag.emulation = sysCfg.ex_emulation;
+// sysCfg.flag.mqtt_power_retain = 0;
+// sysCfg.flag.mqtt_button_retain = 0;
+ sysCfg.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
+ sysCfg.flag.emulation = EMULATION;
CFG_DefaultSet_5_0_2();
@@ -692,10 +689,7 @@ void CFG_Delta()
}
}
if (sysCfg.version < 0x05010600) {
- if (sysCfg.version > 0x04010100) {
- memcpy(sysCfg.state_text, sysCfg.ex_state_text, 33);
- }
- strlcpy(sysCfg.state_text[3], MQTT_CMND_HOLD, sizeof(sysCfg.state_text[3]));
+ CFG_DefaultSet_4_1_1();
}
if (sysCfg.version < 0x05010700) {
sysCfg.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time
@@ -712,7 +706,7 @@ void CFG_Delta()
if (sysCfg.version < 0x05080000) {
uint8_t cfg_wsflg = 0;
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
- if (GPIO_WS2812 == sysCfg.my_module.gp.io[i]) {
+ if (GPIO_WS2812 == sysCfg.my_gp.io[i]) {
cfg_wsflg = 1;
}
}
@@ -733,6 +727,10 @@ void CFG_Delta()
sysCfg.led_width = 1;
}
}
+ if (sysCfg.version < 0x0508000A) {
+ sysCfg.power = sysCfg.ex_power;
+ sysCfg.altitude = 0;
+ }
sysCfg.version = VERSION;
CFG_Save(1);
diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h
new file mode 100644
index 000000000..05f556495
--- /dev/null
+++ b/sonoff/sonoff.h
@@ -0,0 +1,102 @@
+/*
+ sonoff.h - Sonoff-Tasmota master header
+
+ Copyright (C) 2017 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 .
+*/
+
+/*********************************************************************************************\
+ * Power Type
+\*********************************************************************************************/
+
+typedef unsigned long power_t; // Power (Relay) type
+#define POWER_MASK 0xFFFFFFFF // Power (Relay) full mask
+
+/*********************************************************************************************\
+ * Defines
+\*********************************************************************************************/
+
+#define MAX_RELAYS 4 // Max number of relays
+#define MAX_BUTTONS 4 // Max number of buttons or keys
+#define MAX_SWITCHES 4 // Max number of switches
+#define MAX_LEDS 4 // Max number of leds
+#define MAX_PWMS 5 // Max number of PWM channels
+#define MAX_COUNTERS 4 // Max number of counter sensors
+#define MAX_PULSETIMERS 4 // Max number of supported pulse timers
+
+#define MODULE SONOFF_BASIC // [Module] Select default model
+
+#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
+#define MQTT_TOKEN_TOPIC "%topic%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
+
+#define WIFI_HOSTNAME "%s-%04d" // Expands to -
+
+#define CONFIG_FILE_SIGN 0xA5 // Configuration file signature
+#define CONFIG_FILE_XOR 0x5A // Configuration file xor (0 = No Xor)
+
+#define HLW_PREF_PULSE 12530 // was 4975us = 201Hz = 1000W
+#define HLW_UREF_PULSE 1950 // was 1666us = 600Hz = 220V
+#define HLW_IREF_PULSE 3500 // was 1666us = 600Hz = 4.545A
+
+#define MQTT_RETRY_SECS 10 // Minimum seconds to retry MQTT connection
+#define APP_POWER 0 // Default saved power state Off
+#define WS2812_MAX_LEDS 512 // Max number of LEDs
+
+#define PWM_RANGE 1023 // 255..1023 needs to be devisible by 256
+//#define PWM_FREQ 1000 // 100..1000 Hz led refresh
+//#define PWM_FREQ 910 // 100..1000 Hz led refresh (iTead value)
+#define PWM_FREQ 880 // 100..1000 Hz led refresh (BN-SZ01 value)
+
+#define MAX_POWER_HOLD 10 // Time in SECONDS to allow max agreed power (Pow)
+#define MAX_POWER_WINDOW 30 // Time in SECONDS to disable allow max agreed power (Pow)
+#define SAFE_POWER_HOLD 10 // Time in SECONDS to allow max unit safe power (Pow)
+#define SAFE_POWER_WINDOW 30 // Time in MINUTES to disable allow max unit safe power (Pow)
+#define MAX_POWER_RETRY 5 // Retry count allowing agreed power limit overflow (Pow)
+
+#define STATES 20 // State loops per second
+#define SYSLOG_TIMER 600 // Seconds to restore syslog_level
+#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
+#define OTA_ATTEMPTS 10 // Number of times to try fetching the new firmware
+
+#define INPUT_BUFFER_SIZE 250 // Max number of characters in (serial) command buffer
+#define CMDSZ 20 // Max number of characters in command
+#define TOPSZ 100 // Max number of characters in topic string
+#ifdef USE_MQTT_TLS
+ #define MAX_LOG_LINES 10 // Max number of lines in weblog
+#else
+ #define MAX_LOG_LINES 20 // Max number of lines in weblog
+#endif
+#define MAX_BACKLOG 16 // Max number of commands in backlog (chk blogidx and blogptr code)
+#define MIN_BACKLOG_DELAY 2 // Minimal backlog delay in 0.1 seconds
+
+#define APP_BAUDRATE 115200 // Default serial baudrate
+#define MAX_STATUS 11 // Max number of status lines
+
+/*********************************************************************************************\
+ * Enumeration
+\*********************************************************************************************/
+
+enum week_t {Last, First, Second, Third, Fourth};
+enum dow_t {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat};
+enum month_t {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
+enum hemis_t {North, South};
+enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; // SerialLog, Syslog, Weblog
+enum wifi_t {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, MAX_WIFI_OPTION}; // WifiConfig
+enum swtch_t {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, MAX_SWITCH_OPTION}; // SwitchMode
+enum led_t {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION}; // LedState
+enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; // Emulation
+
+enum butt_t {PRESSED, NOT_PRESSED};
+enum opt_t {P_HOLD_TIME, P_MAX_POWER_RETRY, P_MAX_PARAM8}; // Index in sysCfg.param
diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino
index 241c2d79f..c88d48f4b 100644
--- a/sonoff/sonoff.ino
+++ b/sonoff/sonoff.ino
@@ -25,18 +25,9 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
====================================================*/
-#define VERSION 0x05080009 // 5.8.0i
-
-enum week_t {Last, First, Second, Third, Fourth};
-enum dow_t {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat};
-enum month_t {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
-enum hemis_t {North, South};
-enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; // SerialLog, Syslog, Weblog
-enum wifi_t {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, MAX_WIFI_OPTION}; // WifiConfig
-enum swtch_t {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, MAX_SWITCH_OPTION}; // SwitchMode
-enum led_t {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION}; // LedState
-enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; // Emulation
+#define VERSION 0x0508000A // 5.8.0j
+#include "sonoff.h"
#include "user_config.h"
#include "user_config_override.h"
#include "i18n.h"
@@ -46,8 +37,6 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; // Emulation
* No user configurable items below
\*********************************************************************************************/
-#define MODULE SONOFF_BASIC // [Module] Select default model
-
#define USE_DHT // Default DHT11 sensor needs no external library
#ifndef USE_DS18x20
#define USE_DS18B20 // Default DS18B20 sensor needs no external library
@@ -108,56 +97,6 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; // Emulation
#define WS2812_LEDS 30 // [Pixels] Number of LEDs
#endif
-#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
-#define MQTT_TOKEN_TOPIC "%topic%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
-
-#define WIFI_HOSTNAME "%s-%04d" // Expands to -
-#define CONFIG_FILE_SIGN 0xA5 // Configuration file signature
-#define CONFIG_FILE_XOR 0x5A // Configuration file xor (0 = No Xor)
-
-#define HLW_PREF_PULSE 12530 // was 4975us = 201Hz = 1000W
-#define HLW_UREF_PULSE 1950 // was 1666us = 600Hz = 220V
-#define HLW_IREF_PULSE 3500 // was 1666us = 600Hz = 4.545A
-
-#define MQTT_RETRY_SECS 10 // Minimum seconds to retry MQTT connection
-#define APP_POWER 0 // Default saved power state Off
-#define MAX_COUNTERS 4 // Max number of counter sensors
-#define MAX_PULSETIMERS 4 // Max number of supported pulse timers
-#define WS2812_MAX_LEDS 512 // Max number of LEDs
-
-#define PWM_RANGE 1023 // 255..1023 needs to be devisible by 256
-//#define PWM_FREQ 1000 // 100..1000 Hz led refresh
-//#define PWM_FREQ 910 // 100..1000 Hz led refresh (iTead value)
-#define PWM_FREQ 880 // 100..1000 Hz led refresh (BN-SZ01 value)
-
-#define MAX_POWER_HOLD 10 // Time in SECONDS to allow max agreed power (Pow)
-#define MAX_POWER_WINDOW 30 // Time in SECONDS to disable allow max agreed power (Pow)
-#define SAFE_POWER_HOLD 10 // Time in SECONDS to allow max unit safe power (Pow)
-#define SAFE_POWER_WINDOW 30 // Time in MINUTES to disable allow max unit safe power (Pow)
-#define MAX_POWER_RETRY 5 // Retry count allowing agreed power limit overflow (Pow)
-
-#define STATES 20 // State loops per second
-#define SYSLOG_TIMER 600 // Seconds to restore syslog_level
-#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
-#define OTA_ATTEMPTS 10 // Number of times to try fetching the new firmware
-
-#define INPUT_BUFFER_SIZE 250 // Max number of characters in (serial) command buffer
-#define CMDSZ 20 // Max number of characters in command
-#define TOPSZ 100 // Max number of characters in topic string
-#ifdef USE_MQTT_TLS
- #define MAX_LOG_LINES 10 // Max number of lines in weblog
-#else
- #define MAX_LOG_LINES 20 // Max number of lines in weblog
-#endif
-#define MAX_BACKLOG 16 // Max number of commands in backlog (chk blogidx and blogptr code)
-#define MIN_BACKLOG_DELAY 2 // Minimal backlog delay in 0.1 seconds
-
-#define APP_BAUDRATE 115200 // Default serial baudrate
-#define MAX_STATUS 11 // Max number of status lines
-
-enum butt_t {PRESSED, NOT_PRESSED};
-enum opt_t {P_HOLD_TIME, P_MAX_POWER_RETRY, P_MAX_PARAM8}; // Index in sysCfg.param
-
#include "support.h" // Global support
#include // MQTT
@@ -244,11 +183,11 @@ int status_update_timer = 0; // Refresh initial status
uint16_t pulse_timer[MAX_PULSETIMERS] = { 0 }; // Power off timer
uint16_t blink_timer = 0; // Power cycle timer
uint16_t blink_counter = 0; // Number of blink cycles
-uint8_t blink_power; // Blink power state
-uint8_t blink_mask = 0; // Blink relay active mask
-uint8_t blink_powersave; // Blink start power save state
+power_t blink_power; // Blink power state
+power_t blink_mask = 0; // Blink relay active mask
+power_t blink_powersave; // Blink start power save state
uint16_t mqtt_cmnd_publish = 0; // ignore flag for publish command
-uint8_t latching_power = 0; // Power state at latching start
+power_t latching_power = 0; // Power state at latching start
uint8_t latching_relay_pulse = 0; // Latching relay pulse timer
uint8_t blogidx = 0; // Command backlog index
uint8_t blogptr = 0; // Command backlog pointer
@@ -264,7 +203,7 @@ uint8_t interlockmutex = 0; // Interlock power command pending
PubSubClient mqttClient(espClient); // MQTT Client
WiFiUDP portUDP; // UDP Syslog and Alexa
-uint8_t power; // Current copy of sysCfg.power
+power_t power = 0; // Current copy of sysCfg.power
byte syslog_level; // Current copy of sysCfg.syslog_level
uint16_t syslog_timer = 0; // Timer to re-enable syslog_level
byte seriallog_level; // Current copy of sysCfg.seriallog_level
@@ -275,19 +214,19 @@ uint8_t stop_flash_rotate = 0; // Allow flash configuration rotation
int blinks = 201; // Number of LED blinks
uint8_t blinkstate = 0; // LED state
-uint8_t lastbutton[4] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states
-uint8_t holdbutton[4] = { 0 }; // Timer for button hold
-uint8_t multiwindow[4] = { 0 }; // Max time between button presses to record press count
-uint8_t multipress[4] = { 0 }; // Number of button presses within multiwindow
-uint8_t lastwallswitch[4]; // Last wall switch states
-uint8_t holdwallswitch[4] = { 0 }; // Timer for wallswitch push button hold
uint8_t blockgpio0 = 4; // Block GPIO0 for 4 seconds after poweron to workaround Wemos D1 RTS circuit
+uint8_t lastbutton[MAX_BUTTONS] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states
+uint8_t holdbutton[MAX_BUTTONS] = { 0 }; // Timer for button hold
+uint8_t multiwindow[MAX_BUTTONS] = { 0 }; // Max time between button presses to record press count
+uint8_t multipress[MAX_BUTTONS] = { 0 }; // Number of button presses within multiwindow
+uint8_t lastwallswitch[MAX_SWITCHES]; // Last wall switch states
+uint8_t holdwallswitch[MAX_SWITCHES] = { 0 }; // Timer for wallswitch push button hold
mytmplt my_module; // Active copy of GPIOs
uint8_t pin[GPIO_MAX]; // Possible pin configurations
-uint8_t rel_inverted[4] = { 0 }; // Relay inverted flag (1 = (0 = On, 1 = Off))
-uint8_t led_inverted[4] = { 0 }; // LED inverted flag (1 = (0 = On, 1 = Off))
-uint8_t pwm_inverted[5] = { 0 }; // PWM inverted flag (1 = inverted)
+power_t rel_inverted = 0; // Relay inverted flag (1 = (0 = On, 1 = Off))
+uint8_t led_inverted = 0; // LED inverted flag (1 = (0 = On, 1 = Off))
+uint8_t pwm_inverted = 0; // PWM inverted flag (1 = inverted)
uint8_t dht_flg = 0; // DHT configured
uint8_t hlw_flg = 0; // Power monitor configured
uint8_t i2c_flg = 0; // I2C configured
@@ -374,7 +313,7 @@ char* getStateText(byte state)
/********************************************************************************************/
-void setLatchingRelay(uint8_t power, uint8_t state)
+void setLatchingRelay(power_t power, uint8_t state)
{
power &= 1;
if (2 == state) { // Reset relay
@@ -387,11 +326,11 @@ void setLatchingRelay(uint8_t power, uint8_t state)
latching_relay_pulse = 2; // max 200mS (initiated by stateloop())
}
if (pin[GPIO_REL1 +latching_power] < 99) {
- digitalWrite(pin[GPIO_REL1 +latching_power], rel_inverted[latching_power] ? !state : state);
+ digitalWrite(pin[GPIO_REL1 +latching_power], bitRead(rel_inverted, latching_power) ? !state : state);
}
}
-void setRelay(uint8_t rpower)
+void setRelay(power_t rpower)
{
uint8_t state;
@@ -400,7 +339,7 @@ void setRelay(uint8_t rpower)
rpower = power;
}
if (sysCfg.flag.interlock) { // Allow only one or no relay set
- uint8_t mask = 0x01;
+ power_t mask = 1;
uint8_t count = 0;
for (byte i = 0; i < Maxdevice; i++) {
if (rpower & mask) {
@@ -416,7 +355,7 @@ void setRelay(uint8_t rpower)
if ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module)) {
Serial.write(0xA0);
Serial.write(0x04);
- Serial.write(rpower);
+ Serial.write(rpower &0xFF);
Serial.write(0xA1);
Serial.write('\n');
Serial.flush();
@@ -431,7 +370,7 @@ void setRelay(uint8_t rpower)
for (byte i = 0; i < Maxdevice; i++) {
state = rpower &1;
if (pin[GPIO_REL1 +i] < 99) {
- digitalWrite(pin[GPIO_REL1 +i], rel_inverted[i] ? !state : state);
+ digitalWrite(pin[GPIO_REL1 +i], bitRead(rel_inverted, i) ? !state : state);
}
rpower >>= 1;
}
@@ -444,7 +383,7 @@ void setLed(uint8_t state)
if (state) {
state = 1;
}
- digitalWrite(pin[GPIO_LED1], (led_inverted[0]) ? !state : state);
+ digitalWrite(pin[GPIO_LED1], (bitRead(led_inverted, 0)) ? !state : state);
}
/********************************************************************************************/
@@ -628,6 +567,8 @@ void mqtt_reconnect()
} else {
addLog_P(LOG_LEVEL_DEBUG, S_LOG_MQTT, PSTR(D_INSECURE));
}
+ espClient.stop();
+ yield();
#endif // USE_MQTT_TLS
mqttClient.setCallback(mqttDataCb);
mqttflag = 1;
@@ -820,7 +761,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
if ((payload >= 0) && (payload <= 1)) {
strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic));
if (!payload) {
- for(i = 1; i <= 4; i++) {
+ for(i = 1; i <= MAX_SWITCHES; i++) {
send_button_power(1, i, 9); // Clear MQTT retain in broker
}
}
@@ -1175,7 +1116,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
sysCfg.module = payload;
if (new_modflg) {
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
- sysCfg.my_module.gp.io[i] = 0;
+ sysCfg.my_gp.io[i] = 0;
}
}
restartflag = 2;
@@ -1207,11 +1148,11 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
if ((GPIO_USER == cmodule.gp.io[index]) && (payload >= 0) && (payload < GPIO_SENSOR_END)) {
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
- if ((GPIO_USER == cmodule.gp.io[i]) && (sysCfg.my_module.gp.io[i] == payload)) {
- sysCfg.my_module.gp.io[i] = 0;
+ if ((GPIO_USER == cmodule.gp.io[i]) && (sysCfg.my_gp.io[i] == payload)) {
+ sysCfg.my_gp.io[i] = 0;
}
}
- sysCfg.my_module.gp.io[index] = payload;
+ sysCfg.my_gp.io[index] = payload;
restartflag = 2;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
@@ -1222,8 +1163,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, "), mqtt_data);
}
jsflg = 1;
- snprintf_P(stemp1, sizeof(stemp1), sensors[sysCfg.my_module.gp.io[i]]);
- snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_GPIO "%d\":\"%d (%s)\""), mqtt_data, i, sysCfg.my_module.gp.io[i], stemp1);
+ snprintf_P(stemp1, sizeof(stemp1), sensors[sysCfg.my_gp.io[i]]);
+ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_GPIO "%d\":\"%d (%s)\""), mqtt_data, i, sysCfg.my_gp.io[i], stemp1);
}
}
if (jsflg) {
@@ -1251,14 +1192,14 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
mqtt_data[0] = '\0';
}
- else if (!sfl_flg && !strcasecmp_P(type, PSTR(D_CMND_PWM)) && (index > 0) && (index <= 5)) {
+ else if (!sfl_flg && !strcasecmp_P(type, PSTR(D_CMND_PWM)) && (index > 0) && (index <= MAX_PWMS)) {
if ((payload >= 0) && (payload <= PWM_RANGE) && (pin[GPIO_PWM1 + index -1] < 99)) {
sysCfg.pwmvalue[index -1] = payload;
- analogWrite(pin[GPIO_PWM1 + index -1], pwm_inverted[index -1] ? PWM_RANGE - payload : payload);
+ analogWrite(pin[GPIO_PWM1 + index -1], bitRead(pwm_inverted, index -1) ? PWM_RANGE - payload : payload);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PWM "\":{"));
bool first = true;
- for (byte i = 0; i < 5; i++) {
+ for (byte i = 0; i < MAX_PWMS; i++) {
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, sysCfg.pwmvalue[i]);
first = false;
@@ -1428,7 +1369,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_FRIENDLYNAME "%d\":\"%s\"}"), index, sysCfg.friendlyname[index -1]);
}
- else if (!strcasecmp_P(type, PSTR(D_CMND_SWITCHMODE)) && (index > 0) && (index <= 4)) {
+ else if (!strcasecmp_P(type, PSTR(D_CMND_SWITCHMODE)) && (index > 0) && (index <= MAX_SWITCHES)) {
if ((payload >= 0) && (payload < MAX_SWITCH_OPTION)) {
sysCfg.switchmode[index -1] = payload;
}
@@ -1624,7 +1565,7 @@ boolean send_button_power(byte key, byte device, byte state)
mqtt_data[0] = '\0';
} else {
if ((!strcmp(sysCfg.mqtt_topic, key_topic) || !strcmp(sysCfg.mqtt_grptopic, key_topic)) && (2 == state)) {
- state = ~(power >> (device -1)) & 0x01;
+ state = ~(power >> (device -1)) &1;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), getStateText(state));
}
@@ -1660,17 +1601,19 @@ void do_cmnd_power(byte device, byte state)
if ((device < 1) || (device > Maxdevice)) {
device = 1;
}
- byte mask = 0x01 << (device -1);
- pulse_timer[(device -1)&3] = 0;
+ if (device <= MAX_PULSETIMERS) {
+ pulse_timer[(device -1)] = 0;
+ }
+ power_t mask = 1 << (device -1);
if (state <= 2) {
if ((blink_mask & mask)) {
- blink_mask &= (0xFF ^ mask); // Clear device mask
+ blink_mask &= (POWER_MASK ^ mask); // Clear device mask
mqtt_publishPowerBlinkState(device);
}
if (sysCfg.flag.interlock && !interlockmutex) { // Clear all but masked relay
interlockmutex = 1;
for (byte i = 0; i < Maxdevice; i++) {
- byte imask = 0x01 << i;
+ power_t imask = 1 << i;
if ((power & imask) && (mask != imask)) {
do_cmnd_power(i +1, 0);
}
@@ -1679,7 +1622,7 @@ void do_cmnd_power(byte device, byte state)
}
switch (state) {
case 0: { // Off
- power &= (0xFF ^ mask);
+ power &= (POWER_MASK ^ mask);
break; }
case 1: // On
power |= mask;
@@ -1691,11 +1634,13 @@ void do_cmnd_power(byte device, byte state)
#ifdef USE_DOMOTICZ
domoticz_updatePowerState(device);
#endif // USE_DOMOTICZ
- pulse_timer[(device -1)&3] = (power & mask) ? sysCfg.pulsetime[(device -1)&3] : 0;
+ if (device <= MAX_PULSETIMERS) {
+ pulse_timer[(device -1)] = (power & mask) ? sysCfg.pulsetime[(device -1)] : 0;
+ }
}
else if (3 == state) { // Blink
if (!(blink_mask & mask)) {
- blink_powersave = (blink_powersave & (0xFF ^ mask)) | (power & mask); // Save state
+ blink_powersave = (blink_powersave & (POWER_MASK ^ mask)) | (power & mask); // Save state
blink_power = (power >> (device -1))&1; // Prep to Toggle
}
blink_timer = 1;
@@ -1706,7 +1651,7 @@ void do_cmnd_power(byte device, byte state)
}
else if (4 == state) { // No Blink
byte flag = (blink_mask & mask);
- blink_mask &= (0xFF ^ mask); // Clear device mask
+ blink_mask &= (POWER_MASK ^ mask); // Clear device mask
mqtt_publishPowerBlinkState(device);
if (flag) {
do_cmnd_power(device, (blink_powersave >> (device -1))&1); // Restore state
@@ -1720,12 +1665,12 @@ void do_cmnd_power(byte device, byte state)
void stop_all_power_blink()
{
- byte mask;
+ power_t mask;
for (byte i = 1; i <= Maxdevice; i++) {
- mask = 0x01 << (i -1);
+ mask = 1 << (i -1);
if (blink_mask & mask) {
- blink_mask &= (0xFF ^ mask); // Clear device mask
+ blink_mask &= (POWER_MASK ^ mask); // Clear device mask
mqtt_publishPowerBlinkState(i);
do_cmnd_power(i, (blink_powersave >> (i -1))&1); // Restore state
}
@@ -2181,7 +2126,7 @@ void switch_handler()
uint8_t button = NOT_PRESSED;
uint8_t switchflag;
- for (byte i = 0; i < 4; i++) {
+ for (byte i = 0; i < MAX_SWITCHES; i++) {
if (pin[GPIO_SWT1 +i] < 99) {
if (holdwallswitch[i]) {
@@ -2196,13 +2141,13 @@ void switch_handler()
switchflag = 3;
switch (sysCfg.switchmode[i]) {
case TOGGLE:
- switchflag = 2; // Toggle
+ switchflag = 2; // Toggle
break;
case FOLLOW:
- switchflag = button & 0x01; // Follow wall switch state
+ switchflag = button &1; // Follow wall switch state
break;
case FOLLOW_INV:
- switchflag = ~button & 0x01; // Follow inverted wall switch state
+ switchflag = ~button &1; // Follow inverted wall switch state
break;
case PUSHBUTTON:
if ((PRESSED == button) && (NOT_PRESSED == lastwallswitch[i])) {
@@ -2252,7 +2197,7 @@ void switch_handler()
void stateloop()
{
- uint8_t power_now;
+ power_t power_now;
timerxs = millis() + (1000 / STATES);
state++;
@@ -2301,7 +2246,7 @@ void stateloop()
stop_all_power_blink();
} else {
blink_power ^= 1;
- power_now = (power & (0xFF ^ blink_mask)) | ((blink_power) ? blink_mask : 0);
+ power_now = (power & (POWER_MASK ^ blink_mask)) | ((blink_power) ? blink_mask : 0);
setRelay(power_now);
}
}
@@ -2365,7 +2310,7 @@ void stateloop()
}
}
} else {
- if (sysCfg.ledstate &0x01) {
+ if (sysCfg.ledstate &1) {
boolean tstate = power;
if ((SONOFF_TOUCH == sysCfg.module) || (SONOFF_T11 == sysCfg.module) || (SONOFF_T12 == sysCfg.module) || (SONOFF_T13 == sysCfg.module)) {
tstate = (!power) ? 1 : 0;
@@ -2427,7 +2372,7 @@ void stateloop()
savedatacounter--;
if (savedatacounter <= 0) {
if (sysCfg.flag.savestate) {
- byte mask = 0xFF;
+ power_t mask = POWER_MASK;
for (byte i = 0; i < MAX_PULSETIMERS; i++) {
if ((sysCfg.pulsetime[i] > 0) && (sysCfg.pulsetime[i] < 30)) {
mask &= ~(1 << i);
@@ -2587,11 +2532,10 @@ void GPIO_init()
}
memcpy_P(&def_module, &modules[sysCfg.module], sizeof(def_module));
-// sysCfg.my_module.flag = def_module.flag;
strlcpy(my_module.name, def_module.name, sizeof(my_module.name));
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
- if (sysCfg.my_module.gp.io[i] > GPIO_NONE) {
- my_module.gp.io[i] = sysCfg.my_module.gp.io[i];
+ if (sysCfg.my_gp.io[i] > GPIO_NONE) {
+ my_module.gp.io[i] = sysCfg.my_gp.io[i];
}
if ((def_module.gp.io[i] > GPIO_NONE) && (def_module.gp.io[i] < GPIO_USER)) {
my_module.gp.io[i] = def_module.gp.io[i];
@@ -2608,16 +2552,16 @@ void GPIO_init()
// addLog(LOG_LEVEL_DEBUG);
if (mpin) {
- if ((mpin >= GPIO_REL1_INV) && (mpin <= GPIO_REL4_INV)) {
- rel_inverted[mpin - GPIO_REL1_INV] = 1;
+ if ((mpin >= GPIO_REL1_INV) && (mpin < (GPIO_REL1_INV + MAX_RELAYS))) {
+ bitSet(rel_inverted, mpin - GPIO_REL1_INV);
mpin -= (GPIO_REL1_INV - GPIO_REL1);
}
- else if ((mpin >= GPIO_LED1_INV) && (mpin <= GPIO_LED4_INV)) {
- led_inverted[mpin - GPIO_LED1_INV] = 1;
+ else if ((mpin >= GPIO_LED1_INV) && (mpin < (GPIO_LED1_INV + MAX_LEDS))) {
+ bitSet(led_inverted, mpin - GPIO_LED1_INV);
mpin -= (GPIO_LED1_INV - GPIO_LED1);
}
- else if ((mpin >= GPIO_PWM1_INV) && (mpin <= GPIO_PWM5_INV)) {
- pwm_inverted[mpin - GPIO_PWM1_INV] = 1;
+ else if ((mpin >= GPIO_PWM1_INV) && (mpin < (GPIO_PWM1_INV + MAX_PWMS))) {
+ bitSet(pwm_inverted, mpin - GPIO_PWM1_INV);
mpin -= (GPIO_PWM1_INV - GPIO_PWM1);
}
#ifdef USE_DHT
@@ -2643,10 +2587,17 @@ void GPIO_init()
analogWriteRange(PWM_RANGE); // Default is 1023 (Arduino.h)
analogWriteFreq(PWM_FREQ); // Default is 1000 (core_esp8266_wiring_pwm.c)
+#ifdef USE_I2C
+ i2c_flg = ((pin[GPIO_I2C_SCL] < 99) && (pin[GPIO_I2C_SDA] < 99));
+ if (i2c_flg) {
+ Wire.begin(pin[GPIO_I2C_SDA], pin[GPIO_I2C_SCL]);
+ }
+#endif // USE_I2C
+
Maxdevice = 1;
if (sysCfg.flag.pwm_control) {
sfl_flg = 0;
- for (byte i = 0; i < 5; i++) {
+ for (byte i = 0; i < MAX_PWMS; i++) {
if (pin[GPIO_PWM1 +i] < 99) {
sfl_flg++; // Use Dimmer/Color control for all PWM as SetOption15 = 1
}
@@ -2688,7 +2639,7 @@ void GPIO_init()
if (!sfl_flg) {
Maxdevice = 0;
}
- for (byte i = 0; i < 4; i++) {
+ for (byte i = 0; i < MAX_RELAYS; i++) {
if (pin[GPIO_REL1 +i] < 99) {
pinMode(pin[GPIO_REL1 +i], OUTPUT);
Maxdevice++;
@@ -2698,14 +2649,18 @@ void GPIO_init()
// }
}
}
- for (byte i = 0; i < 4; i++) {
+ for (byte i = 0; i < MAX_BUTTONS; i++) {
if (pin[GPIO_KEY1 +i] < 99) {
pinMode(pin[GPIO_KEY1 +i], (16 == pin[GPIO_KEY1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP);
}
+ }
+ for (byte i = 0; i < MAX_LEDS; i++) {
if (pin[GPIO_LED1 +i] < 99) {
pinMode(pin[GPIO_LED1 +i], OUTPUT);
- digitalWrite(pin[GPIO_LED1 +i], led_inverted[i]);
+ digitalWrite(pin[GPIO_LED1 +i], bitRead(led_inverted, i));
}
+ }
+ for (byte i = 0; i < MAX_SWITCHES; i++) {
if (pin[GPIO_SWT1 +i] < 99) {
pinMode(pin[GPIO_SWT1 +i], (16 == pin[GPIO_SWT1 +i]) ? INPUT_PULLDOWN_16 :INPUT_PULLUP);
lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // set global now so doesn't change the saved power state on first switch check
@@ -2721,10 +2676,10 @@ void GPIO_init()
if (sfl_flg) { // Any Led light under Dimmer/Color control
sl_init();
} else {
- for (byte i = 0; i < 5; i++) {
+ for (byte i = 0; i < MAX_PWMS; i++) {
if (pin[GPIO_PWM1 +i] < 99) {
pinMode(pin[GPIO_PWM1 +i], OUTPUT);
- analogWrite(pin[GPIO_PWM1 +i], pwm_inverted[i] ? PWM_RANGE - sysCfg.pwmvalue[i] : sysCfg.pwmvalue[i]);
+ analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? PWM_RANGE - sysCfg.pwmvalue[i] : sysCfg.pwmvalue[i]);
}
}
}
@@ -2764,13 +2719,6 @@ void GPIO_init()
ds18x20_init();
}
#endif // USE_DS18x20
-
-#ifdef USE_I2C
- i2c_flg = ((pin[GPIO_I2C_SCL] < 99) && (pin[GPIO_I2C_SDA] < 99));
- if (i2c_flg) {
- Wire.begin(pin[GPIO_I2C_SDA], pin[GPIO_I2C_SCL]);
- }
-#endif // USE_I2C
}
extern "C" {
@@ -2852,7 +2800,7 @@ void setup()
setRelay(power);
break;
case 2: // All saved state toggle
- power = sysCfg.power & ((1 << Maxdevice) -1) ^ 0xFF;
+ power = sysCfg.power & ((1 << Maxdevice) -1) ^ POWER_MASK;
if (sysCfg.flag.savestate) {
setRelay(power);
}
@@ -2874,7 +2822,7 @@ void setup()
// Issue #526
for (byte i = 0; i < Maxdevice; i++) {
- if ((pin[GPIO_REL1 +i] < 99) && (digitalRead(pin[GPIO_REL1 +i]) ^ rel_inverted[i])) {
+ if ((pin[GPIO_REL1 +i] < 99) && (digitalRead(pin[GPIO_REL1 +i]) ^ bitRead(rel_inverted, i))) {
bitSet(power, i);
pulse_timer[i] = sysCfg.pulsetime[i];
}
diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino
index a2b66caaf..9d4304cf1 100644
--- a/sonoff/webserver.ino
+++ b/sonoff/webserver.ino
@@ -1058,12 +1058,12 @@ void handleSave()
String gpios = "";
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if (new_modflg) {
- sysCfg.my_module.gp.io[i] = 0;
+ sysCfg.my_gp.io[i] = 0;
} else {
if (GPIO_USER == cmodule.gp.io[i]) {
snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i);
- sysCfg.my_module.gp.io[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
- gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(sysCfg.my_module.gp.io[i]);
+ sysCfg.my_gp.io[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
+ gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(sysCfg.my_gp.io[i]);
}
}
}
diff --git a/sonoff/xdrv_domoticz.ino b/sonoff/xdrv_domoticz.ino
index bcf330861..b791cc09e 100644
--- a/sonoff/xdrv_domoticz.ino
+++ b/sonoff/xdrv_domoticz.ino
@@ -70,12 +70,12 @@ void mqtt_publishDomoticzPowerState(byte device)
}
if (sysCfg.flag.mqtt_enabled && sysCfg.domoticz_relay_idx[device -1]) {
if (sfl_flg) {
- snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":2,\"svalue\":\"%d\"}"),
- sysCfg.domoticz_relay_idx[device -1], sysCfg.led_dimmer);
- mqtt_publish(domoticz_in_topic);
+ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%d\"}"),
+ sysCfg.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, sysCfg.led_dimmer);
+ } else {
+ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"\"}"),
+ sysCfg.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0);
}
- snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"\"}"),
- sysCfg.domoticz_relay_idx[device -1], (power & (0x01 << (device -1))) ? 1 : 0);
mqtt_publish(domoticz_in_topic);
}
}
@@ -175,8 +175,7 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), i +1);
if (2 == nvalue) {
nvalue = domoticz["svalue1"];
-// if (sfl_flg && (sysCfg.led_dimmer == nvalue) && ((power >> i) &1)) { // Unable to power off using webpage due to Domoticz re-sends dimmer state
- if (sfl_flg && (sysCfg.led_dimmer == nvalue)) {
+ if (sfl_flg && (sysCfg.led_dimmer == nvalue) && ((power >> i) &1)) {
return 1;
}
snprintf_P(topicBuf, stopicBuf, PSTR("/" D_CMND_DIMMER));
diff --git a/sonoff/xdrv_ir_send.ino b/sonoff/xdrv_ir_send.ino
index 1827b291f..282552b9e 100644
--- a/sonoff/xdrv_ir_send.ino
+++ b/sonoff/xdrv_ir_send.ino
@@ -114,8 +114,8 @@ void ir_recv_check()
mqtt_publish_topic_P(6, PSTR(D_IRRECEIVED));
#ifdef USE_DOMOTICZ
unsigned long value = results.value | (diridx << 28); // [Protocol:4, Data:28]
- domoticz_sensor(DZ_COUNT, value); // Send data as Domoticz Counter value
-#endif // USE_DOMOTICZ
+ domoticz_sensor(DZ_COUNT, value); // Send data as Domoticz Counter value
+#endif // USE_DOMOTICZ
}
irrecv->resume();
diff --git a/sonoff/xdrv_snfbridge.ino b/sonoff/xdrv_snfbridge.ino
index 70fdb008d..58d643137 100644
--- a/sonoff/xdrv_snfbridge.ino
+++ b/sonoff/xdrv_snfbridge.ino
@@ -135,7 +135,7 @@ void sb_send(uint8_t idx, uint8_t key)
Serial.write(sysCfg.sfb_code[idx][i]);
}
if (0 == idx) {
- code = (0x10 << (key >> 2)) | (0x01 << (key & 3)); // 11,12,14,18,21,22,24,28,41,42,44,48,81,82,84,88
+ code = (0x10 << (key >> 2)) | (1 << (key & 3)); // 11,12,14,18,21,22,24,28,41,42,44,48,81,82,84,88
} else {
code = sysCfg.sfb_code[idx][8];
}
diff --git a/sonoff/xdrv_snfled.ino b/sonoff/xdrv_snfled.ino
index dcd8be6a5..baf41c9c4 100644
--- a/sonoff/xdrv_snfled.ino
+++ b/sonoff/xdrv_snfled.ino
@@ -317,9 +317,9 @@ void sl_prepPower()
}
}
-void sl_setPower(uint8_t mpower)
+void sl_setPower(power_t mpower)
{
- sl_power = ((mpower & (0x01 << (Maxdevice -1))) != 0);
+ sl_power = ((mpower & (1 << (Maxdevice -1))) != 0);
if (sl_wakeupActive) {
sl_wakeupActive--;
}
@@ -416,7 +416,7 @@ void sl_animate()
uint16_t curcol = cur_col[i] * (PWM_RANGE / 255);
// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "Cur_Col%d %d, CurCol %d"), i, cur_col[i], curcol);
// addLog(LOG_LEVEL_DEBUG);
- analogWrite(pin[GPIO_PWM1 +i], pwm_inverted[i] ? PWM_RANGE - curcol : curcol);
+ analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? PWM_RANGE - curcol : curcol);
}
}
}
diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino
index 140303c5e..b8a86ce84 100755
--- a/sonoff/xdrv_wemohue.ino
+++ b/sonoff/xdrv_wemohue.ino
@@ -460,7 +460,7 @@ void hue_config(String *path)
void hue_light_status(byte device, String *response)
{
*response += FPSTR(HUE_LIGHT_STATUS_JSON);
- response->replace("{state}", (power & (0x01 << (device-1))) ? "true" : "false");
+ response->replace("{state}", (power & (1 << (device-1))) ? "true" : "false");
if (sfl_flg) {
sl_replaceHSB(response);
@@ -566,7 +566,7 @@ void hue_lights(String *path)
case true : do_cmnd_power(device, 1);
response.replace("{res}", "true");
break;
- default : response.replace("{res}", (power & (0x01 << (device-1))) ? "true" : "false");
+ default : response.replace("{res}", (power & (1 << (device-1))) ? "true" : "false");
break;
}
resp = true;
diff --git a/sonoff/xsns_bmp.ino b/sonoff/xsns_bmp.ino
index e1bcd7ac8..e86a980dd 100644
--- a/sonoff/xsns_bmp.ino
+++ b/sonoff/xsns_bmp.ino
@@ -404,6 +404,7 @@ double bmp_readPressure(void)
switch (bmptype) {
case BMP180_CHIPID:
pressure = bmp180_readPressure();
+ break;
case BMP280_CHIPID:
case BME280_CHIPID:
pressure = bmp280_readPressure();
diff --git a/sonoff/xsns_ds18b20.ino b/sonoff/xsns_ds18b20.ino
index f859ce743..c5cfc55d2 100644
--- a/sonoff/xsns_ds18b20.ino
+++ b/sonoff/xsns_ds18b20.ino
@@ -68,7 +68,7 @@ uint8_t dsb_read(void)
uint8_t bitMask;
uint8_t r = 0;
- for (bitMask = 0x01; bitMask; bitMask <<= 1) {
+ for (bitMask = 1; bitMask; bitMask <<= 1) {
if (dsb_read_bit()) {
r |= bitMask;
}
@@ -97,7 +97,7 @@ void dsb_write(uint8_t ByteToWrite)
{
uint8_t bitMask;
- for (bitMask = 0x01; bitMask; bitMask <<= 1) {
+ for (bitMask = 1; bitMask; bitMask <<= 1) {
dsb_write_bit((bitMask & ByteToWrite) ? 1 : 0);
}
}