Skip to content

Commit

Permalink
v4.0.4
Browse files Browse the repository at this point in the history
4.0.4 20170312
* Add pulse timers for up to 4 relays (arendst#106)
* Fix Sonoff Led power state when dimmer or color is 0 (arendst#176)
* Add command NtpServer<x> to configure up to three NTP servers (arendst#177)
* Delete module User Test as module Wemos D1 mini has same/more user
configurable GPIO (arendst#178)
* Add more user configurable GPIO to module ElectroDragon (arendst#183)
  • Loading branch information
arendst committed Mar 12, 2017
1 parent 82a70fd commit d094e71
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 105 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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 **4.0.3** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
Current version is **4.0.4** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.

- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic.
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.
Expand Down
Binary file modified api/arduino/sonoff.ino.bin
Binary file not shown.
11 changes: 9 additions & 2 deletions sonoff/_releasenotes.ino
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
/* 4.0.3 20170309
/* 4.0.4 20170312
* Add pulse timers for up to 4 relays (#106)
* Fix Sonoff Led power state when dimmer or color is 0 (#176)
* Add command NtpServer<x> to configure up to three NTP servers (#177)
* Delete module User Test as module Wemos D1 mini has same/more user configurable GPIO (#178)
* Add more user configurable GPIO to module ElectroDragon (#183)
*
* 4.0.3 20170309
* Renamed Module NodeMCU to WeMos D1 mini
* Add GPIO1 as user option to some modules
* Add Buttons, Relays and Leds to user configurable options (#159)
* Add description on Module parameters web page to some well known GPIOs (#107, #171)
*
*
* 4.0.2 20170308
* Restore correct seriallog level after Serial logging was disabled
* Add simple dimmer slider to Sonoff Led web page
Expand Down
6 changes: 5 additions & 1 deletion sonoff/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ struct SYSCFG {
uint16_t hlw_mkwh; // MaxEnergy
uint16_t hlw_mkwhs; // MaxEnergyStart

uint16_t pulsetime;
uint16_t ex_pulsetime; // Not used since 4.0.4
uint8_t poweronstate;
uint16_t blinktime;
uint16_t blinkcount;
Expand Down Expand Up @@ -188,6 +188,10 @@ struct SYSCFG {

char web_password[33];
uint8_t switchmode[4];

char ntp_server[3][33];
uint16_t pulsetime[MAX_PULSETIMERS];

} sysCfg;

struct RTCMEM {
Expand Down
95 changes: 50 additions & 45 deletions sonoff/settings.ino
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,6 @@ void CFG_DefaultSet2()
{
sysCfg.savedata = SAVE_DATA;
sysCfg.savestate = SAVE_STATE;
sysCfg.module = MODULE;
sysCfg.model = 0;
sysCfg.timezone = APP_TIMEZONE;
strlcpy(sysCfg.otaUrl, OTA_URL, sizeof(sysCfg.otaUrl));
Expand Down Expand Up @@ -455,7 +454,7 @@ void CFG_DefaultSet2()

sysCfg.power = APP_POWER;
sysCfg.poweronstate = APP_POWERON_STATE;
sysCfg.pulsetime = APP_PULSETIME;
// sysCfg.pulsetime = APP_PULSETIME;
sysCfg.ledstate = APP_LEDSTATE;
// sysCfg.switchmode = SWITCH_MODE;
sysCfg.blinktime = APP_BLINKTIME;
Expand All @@ -471,7 +470,6 @@ void CFG_DefaultSet2()
sysCfg.domoticz_key_idx[i] = 0;
sysCfg.domoticz_switch_idx[i] = 0;
}
for (byte i = 0; i < 12; i++) sysCfg.domoticz_sensor_idx[i] = 0;

sysCfg.hlw_pcal = HLW_PREF_PULSE;
sysCfg.hlw_ucal = HLW_UREF_PULSE;
Expand All @@ -494,6 +492,29 @@ void CFG_DefaultSet2()
sysCfg.hlw_mkwh = 0; // MaxEnergy
sysCfg.hlw_mkwhs = 0; // MaxEnergyStart

CFG_DefaultSet_3_2_4();

strlcpy(sysCfg.friendlyname[0], FRIENDLY_NAME, sizeof(sysCfg.friendlyname[0]));
strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME"2", sizeof(sysCfg.friendlyname[1]));
strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME"3", sizeof(sysCfg.friendlyname[2]));
strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3]));

CFG_DefaultSet_3_9_3();

strlcpy(sysCfg.switch_topic, "0", sizeof(sysCfg.switch_topic));
sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
sysCfg.mqtt_enabled = MQTT_USE;

sysCfg.emulation = EMULATION;

strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password));

CFG_DefaultSet_4_0_4();
sysCfg.pulsetime[0] = APP_PULSETIME;
}

void CFG_DefaultSet_3_2_4()
{
sysCfg.ws_pixels = WS2812_LEDS;
sysCfg.ws_red = 255;
sysCfg.ws_green = 0;
Expand All @@ -505,14 +526,16 @@ void CFG_DefaultSet2()
sysCfg.ws_scheme = 0;
sysCfg.ws_width = 1;
sysCfg.ws_wakeup = 0;
}

strlcpy(sysCfg.friendlyname[0], FRIENDLY_NAME, sizeof(sysCfg.friendlyname[0]));
strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME"2", sizeof(sysCfg.friendlyname[1]));
strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME"3", sizeof(sysCfg.friendlyname[2]));
strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3]));
void CFG_DefaultSet_3_9_3()
{
for (byte i = 0; i < 4; i++) sysCfg.domoticz_switch_idx[i] = 0;
for (byte i = 0; i < 12; i++) sysCfg.domoticz_sensor_idx[i] = 0;

sysCfg.module = MODULE;
for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;

sysCfg.led_pixels = 0;
for (byte i = 0; i < 5; i++) sysCfg.led_color[i] = 255;
sysCfg.led_table = 0;
Expand All @@ -522,14 +545,18 @@ void CFG_DefaultSet2()
sysCfg.led_scheme = 0;
sysCfg.led_width = 0;
sysCfg.led_wakeup = 0;

strlcpy(sysCfg.switch_topic, "0", sizeof(sysCfg.switch_topic));
sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
sysCfg.mqtt_enabled = MQTT_USE;

sysCfg.emulation = EMULATION;
}

strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password));
void CFG_DefaultSet_4_0_4()
{
strlcpy(sysCfg.ntp_server[0], NTP_SERVER1, sizeof(sysCfg.ntp_server[0]));
strlcpy(sysCfg.ntp_server[1], NTP_SERVER2, sizeof(sysCfg.ntp_server[1]));
strlcpy(sysCfg.ntp_server[2], NTP_SERVER3, sizeof(sysCfg.ntp_server[2]));
for (byte j =0; j < 3; j++)
for (byte i = 0; i < strlen(sysCfg.ntp_server[j]); i++)
if (sysCfg.ntp_server[j][i] == ',') sysCfg.ntp_server[j][i] = '.';
sysCfg.pulsetime[0] = sysCfg.ex_pulsetime;
for (byte i = 1; i < MAX_PULSETIMERS; i++) sysCfg.pulsetime[i] = 0;
}

void CFG_Default()
Expand Down Expand Up @@ -657,7 +684,7 @@ void CFG_Delta()
{
if (sysCfg.version != VERSION) { // Fix version dependent changes
if (sysCfg.version < 0x03000600) { // 3.0.6 - Add parameter
sysCfg.pulsetime = APP_PULSETIME;
sysCfg.ex_pulsetime = APP_PULSETIME;
}
if (sysCfg.version < 0x03010100) { // 3.1.1 - Add parameter
sysCfg.poweronstate = APP_POWERON_STATE;
Expand All @@ -673,17 +700,7 @@ void CFG_Delta()
getClient(sysCfg.friendlyname[0], sysCfg.mqtt_client, sizeof(sysCfg.friendlyname[0]));
}
if (sysCfg.version < 0x03020400) { // 3.2.4 - Add parameter
sysCfg.ws_pixels = WS2812_LEDS;
sysCfg.ws_red = 255;
sysCfg.ws_green = 0;
sysCfg.ws_blue = 0;
sysCfg.ws_ledtable = 0;
sysCfg.ws_dimmer = 8;
sysCfg.ws_fade = 0;
sysCfg.ws_speed = 1;
sysCfg.ws_scheme = 0;
sysCfg.ws_width = 1;
sysCfg.ws_wakeup = 0;
CFG_DefaultSet_3_2_4();
}
if (sysCfg.version < 0x03020500) { // 3.2.5 - Add parameter
getClient(sysCfg.friendlyname[0], sysCfg.mqtt_client, sizeof(sysCfg.friendlyname[0]));
Expand All @@ -699,27 +716,13 @@ void CFG_Delta()
if (sysCfg.version < 0x03020C00) { // 3.2.12 - Add parameter
sysCfg.sleep = APP_SLEEP;
}
if (sysCfg.version < 0x03090204) { // 3.9.2d - Add parameter
for (byte i = 0; i < 4; i++) sysCfg.domoticz_switch_idx[i] = 0;
for (byte i = 0; i < 12; i++) sysCfg.domoticz_sensor_idx[i] = 0;

sysCfg.module = MODULE;
for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;

sysCfg.led_pixels = 0;
for (byte i = 0; i < 5; i++) sysCfg.led_color[i] = 255;
sysCfg.led_table = 0;
for (byte i = 0; i < 3; i++) sysCfg.led_dimmer[i] = 10;
sysCfg.led_fade = 0;
sysCfg.led_speed = 0;
sysCfg.led_scheme = 0;
sysCfg.led_width = 0;
sysCfg.led_wakeup = 0;
if (sysCfg.version < 0x03090300) { // 3.9.2d - Add parameter
CFG_DefaultSet_3_9_3();
}
if (sysCfg.version < 0x03090700) { // 3.9.7 - Add parameter
sysCfg.emulation = EMULATION;
}
if (sysCfg.version < 0x03091301) {
if (sysCfg.version < 0x03091400) {
strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password));
}
if (sysCfg.version < 0x03091500) {
Expand All @@ -728,7 +731,9 @@ void CFG_Delta()
if (sysCfg.version < 0x04000200) {
sysCfg.button_restrict = 0;
}

if (sysCfg.version < 0x04000400) {
CFG_DefaultSet_4_0_4();
}
sysCfg.version = VERSION;
}
}
Expand Down
45 changes: 29 additions & 16 deletions sonoff/sonoff.ino
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

//#define ALLOW_MIGRATE_TO_V3
#ifdef ALLOW_MIGRATE_TO_V3
#define VERSION 0x03091A00 // 3.9.26
#define VERSION 0x03091B00 // 3.9.27
#else
#define VERSION 0x04000300 // 4.0.3
#define VERSION 0x04000400 // 4.0.4
#endif // ALLOW_MIGRATE_TO_V3

enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
Expand Down Expand Up @@ -112,6 +112,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#define MQTT_RETRY_SECS 10 // Seconds to retry MQTT connection
#define APP_POWER 0 // Default saved power state Off
#define MAX_DEVICE 1 // Max number of devices
#define MAX_PULSETIMERS 4 // Max number of supported pulse timers
#define WS2812_MAX_LEDS 256 // Max number of LEDs

#define MAX_POWER_HOLD 10 // Time in SECONDS to allow max agreed power (Pow)
Expand Down Expand Up @@ -241,7 +242,7 @@ byte logidx = 0; // Index in Web log buffer
byte logajaxflg = 0; // Reset web console log
byte Maxdevice = MAX_DEVICE; // Max number of devices supported
int status_update_timer = 0; // Refresh initial status
uint16_t pulse_timer = 0; // Power off timer
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
Expand Down Expand Up @@ -820,12 +821,12 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"PowerOnState\":%d}"), sysCfg.poweronstate);
}
else if (!strcmp(type,"PULSETIME")) {
else if (!strcmp(type,"PULSETIME") && (index > 0) && (index <= MAX_PULSETIMERS)) {
if (data_len > 0) {
sysCfg.pulsetime = payload16; // 0 - 65535
pulse_timer = 0;
sysCfg.pulsetime[index -1] = payload16; // 0 - 65535
pulse_timer[index -1] = 0;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"PulseTime\":%d}"), sysCfg.pulsetime);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"PulseTime%d\":%d}"), index, sysCfg.pulsetime[index -1]);
}
else if (!strcmp(type,"BLINKTIME")) {
if ((data_len > 0) && (payload > 2) && (payload <= 3600)) {
Expand Down Expand Up @@ -1011,6 +1012,14 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"LogPort\":%d}"), sysCfg.syslog_port);
}
else if (!strcmp(type,"NTPSERVER") && (index > 0) && (index <= 3)) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.ntp_server[0]))) {
strlcpy(sysCfg.ntp_server[index -1], (payload == 1) ? (index==1)?NTP_SERVER1:(index==2)?NTP_SERVER2:NTP_SERVER3 : dataBuf, sizeof(sysCfg.ntp_server[0]));
for (i = 0; i < strlen(sysCfg.ntp_server[index -1]); i++) if (sysCfg.ntp_server[index -1][i] == ',') sysCfg.ntp_server[index -1][i] = '.';
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"NTPServer%d\":\"%s\"}"), index, sysCfg.ntp_server[index -1]);
}
else if (!strcmp(type,"AP")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
switch (payload) {
Expand Down Expand Up @@ -1232,7 +1241,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
mqtt_publish_topic_P(0, PSTR("COMMANDS2"), svalue);

snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands3\":\"%s%s, PulseTime, BlinkTime, BlinkCount, ButtonRestrict"), (Maxdevice == 1) ? "Power, Light" : "Power1, Power2, Light1 Light2", (sysCfg.module != MOTOR) ? ", PowerOnState" : "");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands3\":\"%s%s, PulseTime, BlinkTime, BlinkCount, ButtonRestrict, NtpServer"), (Maxdevice == 1) ? "Power, Light" : "Power1, Power2, Light1 Light2", (sysCfg.module != MOTOR) ? ", PowerOnState" : "");
#ifdef USE_WEBSERVER
snprintf_P(svalue, sizeof(svalue), PSTR("%s, Weblog, Webserver, WebPassword, Emulation"), svalue);
#endif
Expand Down Expand Up @@ -1307,7 +1316,7 @@ void do_cmnd_power(byte device, byte state)

if ((device < 1) || (device > Maxdevice)) device = 1;
byte mask = 0x01 << (device -1);
pulse_timer = 0;
pulse_timer[(device -1)&3] = 0;
if (state <= 2) {
if ((blink_mask & mask)) {
blink_mask &= (0xFF ^ mask); // Clear device mask
Expand All @@ -1327,7 +1336,7 @@ void do_cmnd_power(byte device, byte state)
#ifdef USE_DOMOTICZ
domoticz_updatePowerState(device);
#endif // USE_DOMOTICZ
if (device == 1) pulse_timer = (power & mask) ? sysCfg.pulsetime : 0;
pulse_timer[(device -1)&3] = (power & mask) ? sysCfg.pulsetime[(device -1)&3] : 0;
}
else if (state == 3) { // Blink
if (!(blink_mask & mask)) {
Expand Down Expand Up @@ -1510,7 +1519,7 @@ void every_second()
{
char svalue[MESSZ];

if (pulse_timer > 111) pulse_timer--;
for (byte i = 0; i < MAX_PULSETIMERS; i++) if (pulse_timer[i] > 111) pulse_timer[i]--;

if (seriallog_timer) {
seriallog_timer--;
Expand Down Expand Up @@ -1625,10 +1634,11 @@ void stateloop()
if (!latching_relay_pulse) setLatchingRelay(0, 0);
}

if ((pulse_timer > 0) && (pulse_timer < 112)) {
pulse_timer--;
if (!pulse_timer) do_cmnd_power(1, 0);
}
for (byte i = 0; i < MAX_PULSETIMERS; i++)
if ((pulse_timer[i] > 0) && (pulse_timer[i] < 112)) {
pulse_timer[i]--;
if (!pulse_timer[i]) do_cmnd_power(i +1, 0);
}

if (blink_mask) {
blink_timer--;
Expand Down Expand Up @@ -1815,7 +1825,10 @@ void stateloop()
savedatacounter--;
if (savedatacounter <= 0) {
if (sysCfg.savestate) {
if (!((sysCfg.pulsetime > 0) && (sysCfg.pulsetime < 30) && ((sysCfg.power &0xFE) == (power &0xFE)))) sysCfg.power = power;
byte mask = 0xFF;
for (byte i = 0; i < MAX_PULSETIMERS; i++)
if ((sysCfg.pulsetime[i] > 0) && (sysCfg.pulsetime[i] < 30)) mask &= ~(1 << i);
if (!((sysCfg.power &mask) == (power &mask))) sysCfg.power = power;
}
CFG_Save();
savedatacounter = sysCfg.savedata;
Expand Down
18 changes: 2 additions & 16 deletions sonoff/sonoff_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ enum module_t {
EXS_RELAY,
WION,
WEMOS,
USER_TEST,
MAXMODULE };

/********************************************************************************************/
Expand Down Expand Up @@ -299,12 +298,12 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
GPIO_KEY1, // GPIO02 Button 1
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_USER, // GPIO04 Optional sensor
0,
GPIO_USER, // GPIO05 Optional sensor
0, 0, 0, 0, 0, 0, // Flash connection
GPIO_REL2, // GPIO12 Red Led and Relay 2 (0 = Off, 1 = On)
GPIO_REL1, // GPIO13 Red Led and Relay 1 (0 = Off, 1 = On)
GPIO_USER, // GPIO14 Optional sensor
0,
GPIO_USER, // GPIO15 Optional sensor
GPIO_LED1 // GPIO16 Green/Blue Led (1 = On, 0 = Off)
},
{ "EXS Relay", // Latching relay https://ex-store.de/ESP8266-WiFi-Relay-V31 (ESP8266)
Expand Down Expand Up @@ -347,19 +346,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
GPIO_USER, // GPIO14 D5
GPIO_USER, // GPIO15 D8
GPIO_USER // GPIO16 D0 Wemos Wake
},
{ "User Test", // Sonoff Basic User Test (ESP8266)
GPIO_KEY1, // GPIO00 Button
GPIO_USER, // GPIO01 Serial RXD and Optional sensor
GPIO_USER, // GPIO02 Optional sensor
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_USER, // GPIO04 Optional sensor
GPIO_USER, // GPIO05 Optional sensor
0, 0, 0, 0, 0, 0, // Flash connection
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off)
GPIO_USER, // GPIO14 Optional sensor
0, 0
}
};

Loading

0 comments on commit d094e71

Please sign in to comment.