mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
v3.9.15
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
This commit is contained in:
parent
bb5251c2c8
commit
533855c210
@ -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```.
|
||||
|
Binary file not shown.
@ -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
|
||||
|
@ -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};
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -751,8 +786,26 @@ 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);
|
||||
@ -760,14 +813,18 @@ void setRelay(uint8_t 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);
|
||||
@ -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)) {
|
||||
@ -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);
|
||||
@ -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++) {
|
||||
@ -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));
|
||||
|
@ -84,6 +84,7 @@ enum module_t {
|
||||
CH4,
|
||||
MOTOR,
|
||||
ELECTRODRAGON,
|
||||
EXS_RELAY,
|
||||
USER_TEST,
|
||||
MAXMODULE };
|
||||
|
||||
@ -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,
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
@ -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"),
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user