Skip to content

Commit

Permalink
v3.9.15
Browse files Browse the repository at this point in the history
3.9.15 20170213
* Change JSON float values from string to number according to
http://json.org (#56)
* Add support for exs latched relay module
https://ex-store.de/ESP8266-WiFi-Relay-V31 (#58)
* Add support for inverted relays
* Changed MAX_LOG_LINES from 70 to 60 to preserve memory
  • Loading branch information
arendst committed Feb 13, 2017
1 parent bb5251c commit 533855c
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 42 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 **3.9.14** - See ```sonoff/_releasenotes.ino``` for change information.
Current version is **3.9.15** - See ```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.
10 changes: 8 additions & 2 deletions sonoff/_releasenotes.ino
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
/* 3.9.14 20170211
/* 3.9.15 20170213
* Change JSON float values from string to number according to http://json.org (#56)
* Add support for exs latched relay module https://ex-store.de/ESP8266-WiFi-Relay-V31 (#58)
* Add support for inverted relays
* Changed MAX_LOG_LINES from 70 to 60 to preserve memory
*
* 3.9.14 20170211
* Add False and True as alternatives for 0/Off and 1/On (#49)
* Fix Status10 JSON format (#52)
* Fix DS18x20 using OneWire library (#53)
*
* 3.9.13 20170210
* Add FlashChipSize to Status 4
* Add FlashChipMode to Status 4
* Removed redundant DHT2 option and code
* Add Sonoff SV GPIO pin 05 configuration (#40)
* Add configuration file backup and restore via web page
Expand Down
118 changes: 92 additions & 26 deletions sonoff/sonoff.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
* ====================================================
*/

#define VERSION 0x03090E00 // 3.9.14
#define VERSION 0x03090F00 // 3.9.15

//#define BE_MINIMAL // Compile a minimal version if upgrade memory gets tight (still 404k)
// To be used as step 1. Next step is compile and use desired version

enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
enum week_t {Last, First, Second, Third, Fourth};
Expand Down Expand Up @@ -38,6 +41,41 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};

#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
#endif

#ifdef BE_MINIMAL
//#ifdef USE_MQTT_TLS
//#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set
//#endif
#ifdef USE_DISCOVERY
#undef USE_DISCOVERY // Disable Discovery services for both MQTT and web server
#endif
#ifdef USE_DOMOTICZ
#undef USE_DOMOTICZ // Disable Domoticz
#endif
#ifdef USE_EMULATION
#undef USE_EMULATION // Disable Wemo or Hue emulation
#endif
#ifdef USE_DS18x20
#undef USE_DS18x20 // Disable DS18x20 sensor
#endif
#ifdef USE_I2C
#undef USE_I2C // Disable all I2C sensors
#endif
#ifdef USE_WS2812
#undef USE_WS2812 // Disable WS2812 Led string
#endif
#ifdef USE_DS18B20
#undef USE_DS18B20 // Disable internal DS18B20 sensor
#endif
#ifdef USE_DHT
#undef USE_DHT // Disable internal DHT sensor
#endif
#endif // BE_MINIMAL

#ifndef SWITCH_MODE
#define SWITCH_MODE TOGGLE // TOGGLE, FOLLOW or FOLLOW_INV (the wall switch state)
#endif
Expand All @@ -46,16 +84,11 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#define MQTT_FINGERPRINT "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07"
#endif

#ifndef USE_DS18x20
#define USE_DS18B20 // Default DS18B20 sensor needs no external library
#endif

#ifndef WS2812_LEDS
#define WS2812_LEDS 30 // [Pixels] Number of LEDs
#endif

#define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address>
#define USE_DHT // Default DHT11 sensor needs no external library
#define CONFIG_FILE_SIGN 0xA5 // Configuration file signature
#define CONFIG_FILE_XOR 0x5A // Configuration file xor (0 = No Xor)

Expand Down Expand Up @@ -88,7 +121,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#ifdef USE_MQTT_TLS
#define MAX_LOG_LINES 10 // Max number of lines in weblog
#else
#define MAX_LOG_LINES 70 // Max number of lines in weblog
#define MAX_LOG_LINES 60 // Max number of lines in weblog
#endif

#define APP_BAUDRATE 115200 // Default serial baudrate
Expand Down Expand Up @@ -371,6 +404,8 @@ 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
uint16_t mqtt_cmnd_publish = 0; // ignore flag for publish command
uint8_t latching_power = 0; // Power state at latching start
uint8_t latching_relay_pulse = 0; // Latching relay pulse timer

#ifdef USE_MQTT_TLS
WiFiClientSecure espClient; // Wifi Secure Client
Expand Down Expand Up @@ -751,23 +786,45 @@ void getClient(char* output, const char* input, byte size)
if (!digits) strlcpy(output, input, size);
}

void setLatchingRelay(uint8_t power, uint8_t state)
{
power &= 1;
if (state == 2) { // Init relay
state = 0;
}
else if (state == 1) { // Set port power to On
latching_power = power;
latching_relay_pulse = 2; // max 200mS (initiated by stateloop())
}
else { // Set saved port to Off
power = latching_power;
}
if (pin[GPIO_REL1 +power] < 99) digitalWrite(pin[GPIO_REL1 +power], rel_inverted[power] ? !state : state);
}

void setRelay(uint8_t power)
{
uint8_t state;

if ((sysCfg.module == SONOFF_DUAL) || (sysCfg.module == CH4)) {
Serial.write(0xA0);
Serial.write(0x04);
Serial.write(power);
Serial.write(0xA1);
Serial.write('\n');
Serial.flush();
} else {
if (sysCfg.module == SONOFF_LED) {
sl_setColor(power &1);
} else {
for (byte i = 0; i < Maxdevice; i++) {
if (pin[GPIO_REL1 +i] < 99) digitalWrite(pin[GPIO_REL1 +i], power & 0x1);
power >>= 1;
}
}
else if (sysCfg.module == SONOFF_LED) {
sl_setColor(power &1);
}
else if (sysCfg.module == EXS_RELAY) {
setLatchingRelay(power, 1);
}
else {
for (byte i = 0; i < Maxdevice; i++) {
state = power &1;
if (pin[GPIO_REL1 +i] < 99) digitalWrite(pin[GPIO_REL1 +i], rel_inverted[i] ? !state : state);
power >>= 1;
}
}
hlw_setPowerSteadyCounter(2);
Expand Down Expand Up @@ -1513,7 +1570,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
if ((data_len > 0) && (((payload >= -12) && (payload <= 12)) || (payload == 99))) {
sysCfg.timezone = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Timezone\":\"%d%s\"}"), sysCfg.timezone, (sysCfg.value_units) ? " Hr" : "");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Timezone\":%d}"), sysCfg.timezone);
}
else if (!strcmp(type,"LEDPOWER")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
Expand Down Expand Up @@ -2090,6 +2147,11 @@ void stateloop()

if (mqtt_cmnd_publish) mqtt_cmnd_publish--; // Clean up

if (latching_relay_pulse) {
latching_relay_pulse--;
if (!latching_relay_pulse) setLatchingRelay(0, 0);
}

if ((pulse_timer > 0) && (pulse_timer < 112)) {
pulse_timer--;
if (!pulse_timer) do_cmnd_power(1, 0);
Expand Down Expand Up @@ -2431,16 +2493,16 @@ void GPIO_init()

if ((sysCfg.module == SONOFF_DUAL) || (sysCfg.module == CH4)) {
Baudrate = 19200;
} else {
if (sysCfg.module == SONOFF_LED) {
for (byte i = 0; i < 5; i++) {
if (pin[GPIO_PWM0 +i] < 99) pinMode(pin[GPIO_PWM0 +i], OUTPUT);
}
} else {
for (byte i = 0; i < 4; i++) {
if (pin[GPIO_KEY1 +i] < 99) pinMode(pin[GPIO_KEY1 +i], INPUT_PULLUP);
if (pin[GPIO_REL1 +i] < 99) pinMode(pin[GPIO_REL1 +i], OUTPUT);
}
}
else if (sysCfg.module == SONOFF_LED) {
for (byte i = 0; i < 5; i++) {
if (pin[GPIO_PWM0 +i] < 99) pinMode(pin[GPIO_PWM0 +i], OUTPUT);
}
}
else {
for (byte i = 0; i < 4; i++) {
if (pin[GPIO_KEY1 +i] < 99) pinMode(pin[GPIO_KEY1 +i], INPUT_PULLUP);
if (pin[GPIO_REL1 +i] < 99) pinMode(pin[GPIO_REL1 +i], OUTPUT);
}
}
for (byte i = 0; i < 4; i++) {
Expand All @@ -2453,6 +2515,10 @@ void GPIO_init()
lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // set global now so doesn't change the saved power state on first switch check
}
}
if (sysCfg.module == EXS_RELAY) {
setLatchingRelay(0,2);
setLatchingRelay(1,2);
}
setLed(sysCfg.ledstate &8);

hlw_flg = ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99));
Expand Down
16 changes: 16 additions & 0 deletions sonoff/sonoff_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ enum module_t {
CH4,
MOTOR,
ELECTRODRAGON,
EXS_RELAY,
USER_TEST,
MAXMODULE };

Expand Down Expand Up @@ -253,6 +254,21 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
0,
GPIO_LED1 // GPIO16 Green/Blue Led (1 = On, 0 = Off)
},
{ "EXS Relay", // Latching relay https://ex-store.de/ESP8266-WiFi-Relay-V31
// Module Pin 1 VCC 3V3, Module Pin 6 GND
GPIO_KEY1, // GPIO00 Module Pin 8 - Button (firmware flash)
GPIO_USER, // GPIO01 Module Pin 2 = UART0_TXD
GPIO_USER, // GPIO02 Module Pin 7
GPIO_USER, // GPIO03 Module Pin 3 = UART0_RXD
GPIO_USER, // GPIO04 Module Pin 10
GPIO_USER, // GPIO05 Module Pin 9
0, 0, 0, 0, 0, 0,
GPIO_REL1, // GPIO12 Relay1 ( 1 = Off)
GPIO_REL2, // GPIO13 Relay1 ( 1 = On)
GPIO_USER, // GPIO14 Module Pin 5
0,
GPIO_USER // GPIO16 Module Pin 4
},
{ "User Test", // Sonoff Basic User Test
GPIO_KEY1, // GPIO00 Button
0,
Expand Down
6 changes: 1 addition & 5 deletions sonoff/user_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
#define APP_POWERON_STATE 3 // [PowerOnState] Power On Relay state (0 = Off, 1 = On, 2 = Toggle Saved state, 3 = Saved state)
#define APP_BLINKTIME 10 // [BlinkTime] Time in 0.1 Sec to blink/toggle power for relay 1
#define APP_BLINKCOUNT 10 // [BlinkCount] Number of blinks (0 = 32000)
#define APP_SLEEP 0 // [Sleep] Sleep time to lower energy consumption (0 = Off, 1 - 250 mSec)
#define APP_SLEEP 0 // [Sleep] Sleep time to lower energy consumption (0 = Off, 1 - 250 mSec)

#define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON or PUSHBUTTON_INV (the wall switch state)
#define WS2812_LEDS 30 // [Pixels] Number of WS2812 LEDs to start with
Expand All @@ -133,10 +133,6 @@
* No user configurable items below
\*********************************************************************************************/

#if defined(USE_WEMO_EMULATION) && defined(USE_HUE_EMULATION)
#error "Select either USE_WEMO_EMULATION or USE_HUE_EMULATION"
#endif

#if (ARDUINO < 10610)
#error "This software is supported with Arduino IDE starting from 1.6.10 and ESP8266 Release 2.3.0"
#endif
Expand Down
4 changes: 2 additions & 2 deletions sonoff/xsns_bmp.ino
Original file line number Diff line number Diff line change
Expand Up @@ -437,10 +437,10 @@ void bmp_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
dtostrf(p, 1, PRESSURE_RESOLUTION &3, stemp2);
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp3);
if (!strcmp(bmpstype,"BME280")) {
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":\"%s\", \"Humidity\":\"%s\", \"Pressure\":\"%s\"}"),
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s, \"Pressure\":%s}"),
svalue, bmpstype, stemp1, stemp3, stemp2);
} else {
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":\"%s\", \"Pressure\":\"%s\"}"),
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Pressure\":%s}"),
svalue, bmpstype, stemp1, stemp2);
}
*djson = 1;
Expand Down
2 changes: 1 addition & 1 deletion sonoff/xsns_dht.ino
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
snprintf_P(svalue, ssvalue, PSTR("%s, \"DHT\":{\"Temperature\":\"%s\", \"Humidity\":\"%s\"}"), svalue, stemp1, stemp2);
snprintf_P(svalue, ssvalue, PSTR("%s, \"DHT\":{\"Temperature\":%s, \"Humidity\":%s}"), svalue, stemp1, stemp2);
*djson = 1;
#ifdef USE_DOMOTICZ
domoticz_sensor2(stemp1, stemp2);
Expand Down
2 changes: 1 addition & 1 deletion sonoff/xsns_ds18b20.ino
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ void dsb_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)

if (dsb_readTemp(TEMP_CONVERSION, t)) { // Check if read failed
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18B20\":{\"Temperature\":\"%s\"}"), svalue, stemp1);
snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18B20\":{\"Temperature\":%s}"), svalue, stemp1);
*djson = 1;
#ifdef USE_DOMOTICZ
domoticz_sensor1(stemp1);
Expand Down
2 changes: 1 addition & 1 deletion sonoff/xsns_ds18x20.ino
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
stemp1[0] = '\0';
}
dsxflg++;
snprintf_P(svalue, ssvalue, PSTR("%s%s\"DS%d\":{\"Type\":\"%s\", \"Address\":\"%s\", \"Temperature\":\"%s\"}"),
snprintf_P(svalue, ssvalue, PSTR("%s%s\"DS%d\":{\"Type\":\"%s\", \"Address\":\"%s\", \"Temperature\":%s}"),
svalue, stemp1, i +1, ds18x20_type(i).c_str(), ds18x20_address(i).c_str(), stemp2);
strcpy(stemp1, ", ");
#ifdef USE_DOMOTICZ
Expand Down
3 changes: 1 addition & 2 deletions sonoff/xsns_hlw8012.ino
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue)
dtostrf(pc, 1, 2, stemp2);
dtostrf(pi, 1, 3, stemp3);
snprintf_P(speriod, sizeof(speriod), PSTR(", \"Period\":%d"), pe);
snprintf_P(svalue, ssvalue, PSTR("%s\"Yesterday\":\"%s\", \"Today\":\"%s\"%s, \"Power\":%d, \"Factor\":\"%s\", \"Voltage\":%d, \"Current\":\"%s\"}"),
snprintf_P(svalue, ssvalue, PSTR("%s\"Yesterday\":%s, \"Today\":%s%s, \"Power\":%d, \"Factor\":%s, \"Voltage\":%d, \"Current\":%s}"),
svalue, stemp0, stemp1, (option) ? speriod : "", pw, stemp2, pu, stemp3);
#ifdef USE_DOMOTICZ
dtostrf(ped * 1000, 1, 1, stemp1);
Expand All @@ -540,7 +540,6 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue)

void hlw_mqttPresent()
{
// char stopic[TOPSZ], svalue[MESSZ], stime[21];
char svalue[MESSZ], stime[21];

snprintf_P(stime, sizeof(stime), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
Expand Down
2 changes: 1 addition & 1 deletion sonoff/xsns_htu21.ino
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ void htu_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
h = htu21_compensatedHumidity(h, t);
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":\"%s\", \"Humidity\":\"%s\"}"), svalue, htustype, stemp1, stemp2);
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"), svalue, htustype, stemp1, stemp2);
*djson = 1;
#ifdef USE_DOMOTICZ
domoticz_sensor2(stemp1, stemp2);
Expand Down

0 comments on commit 533855c

Please sign in to comment.