Merge branch 'arendst/development' into development

This commit is contained in:
reloxx13 2018-07-01 13:13:05 +02:00
commit 20934afc12
11 changed files with 106 additions and 36 deletions

View File

@ -13,7 +13,7 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute!
### Development
[![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota)
Current version is **6.0.0a** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
Current version is **6.0.0b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
### Disclaimer
:warning: **DANGER OF ELECTROCUTION** :warning:
@ -52,8 +52,9 @@ The following devices are supported:
- [iTead Sonoff Pow R2 with Energy Monitoring](https://www.itead.cc/sonoff-pow-r2.html)
- [iTead Sonoff 4CH (R2)](https://www.itead.cc/smart-home/sonoff-4ch.html)
- [iTead Sonoff 4CH Pro (R2)](https://www.itead.cc/smart-home/sonoff-4ch-pro.html)
- [iTead S20 Smart Socket](https://www.itead.cc/smart-socket.html)
- [iTead Sonoff S20 Smart Socket](https://www.itead.cc/smart-socket.html)
- [Sonoff S22 Smart Socket](https://github.com/arendst/Sonoff-Tasmota/issues/627)
- [iTead Sonoff S26 Smart Socket](https://www.itead.cc/sonoff-s26-wifi-smart-plug.html)
- [iTead Sonoff S31 Smart Socket with Energy Monitoring](https://www.itead.cc/sonoff-s31.html)
- [iTead Slampher](https://www.itead.cc/slampher.html)
- [iTead Sonoff Touch](https://www.itead.cc/sonoff-touch.html)
@ -62,6 +63,7 @@ The following devices are supported:
- [iTead Sonoff Led](https://www.itead.cc/sonoff-led.html)<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoff4chpror2.jpg" height="250" align="right" />
- [iTead Sonoff BN-SZ01 Ceiling Led](https://www.itead.cc/bn-sz01.html)
- [iTead Sonoff B1](https://www.itead.cc/sonoff-b1.html)
- [iTead Sonoff iFan02](https://www.itead.cc/sonoff-ifan02-wifi-smart-ceiling-fan-with-light.html)
- [iTead Sonoff RF Bridge 433](https://www.itead.cc/sonoff-rf-bridge-433.html)
- [iTead Sonoff Dev](https://www.itead.cc/sonoff-dev.html)
- [iTead 1 Channel Switch 5V / 12V](https://www.itead.cc/smart-home/inching-self-locking-wifi-wireless-switch.html)

View File

@ -1,4 +1,8 @@
/* 6.0.0b
* Add initial support for Sonoff iFan02 - Module 44 - Command FanSpeed 0..3 - Webpage will only allow Toggle1 (#2839)
* Add support for Sonoff S26 Smart Socket (#2808)
* Add command SetOption30 to enforce Hass discovery as light group (#1784)
* Add decimal values support for commands ADD, SUB, MULT and SCALE (#3083, #3089)
* Add experimental (untested) TM1638 switch support (#2226)
* Change number of switches from 4 to 8 (#2885, #3086)
*

View File

@ -166,6 +166,7 @@
#define D_STATUS11_STATUS "STS"
#define D_CMND_STATE "State"
#define D_CMND_POWER "Power"
#define D_CMND_FANSPEED "FanSpeed"
#define D_CMND_POWERONSTATE "PowerOnState"
#define D_CMND_PULSETIME "PulseTime"
#define D_CMND_BLINKTIME "BlinkTime"

View File

@ -55,7 +55,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t knx_enable_enhancement : 1; // bit 27 (v5.14.0a) KNX
uint32_t rf_receive_decimal : 1; // bit 28 (v6.0.0a)
uint32_t ir_receive_decimal : 1; // bit 29 (v6.0.0a)
uint32_t spare30 : 1;
uint32_t hass_light : 1; // bit 30 (v6.0.0b)
uint32_t spare31 : 1;
};
} SysBitfield;

View File

@ -76,7 +76,7 @@
#include "settings.h"
enum TasmotaCommands {
CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_STATUS, CMND_STATE, CMND_POWERONSTATE, CMND_PULSETIME,
CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_FANSPEED, CMND_STATUS, CMND_STATE, CMND_POWERONSTATE, CMND_PULSETIME,
CMND_BLINKTIME, CMND_BLINKCOUNT, CMND_SENSOR, CMND_SAVEDATA, CMND_SETOPTION, CMND_TEMPERATURE_RESOLUTION, CMND_HUMIDITY_RESOLUTION,
CMND_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_CURRENT_RESOLUTION, CMND_ENERGY_RESOLUTION, CMND_MODULE, CMND_MODULES,
CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE,
@ -86,7 +86,7 @@ enum TasmotaCommands {
CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_TIMESTD, CMND_TIMEDST, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE,
CMND_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_SERIALDELIMITER };
const char kTasmotaCommands[] PROGMEM =
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|"
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_FANSPEED "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|"
D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SENSOR "|" D_CMND_SAVEDATA "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|"
D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" D_CMND_MODULE "|" D_CMND_MODULES "|"
D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|"
@ -96,6 +96,10 @@ const char kTasmotaCommands[] PROGMEM =
D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|"
D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER;
//const uint8_t kIFan02Speed[4][3] = {{0,0,0}, {1,0,0}, {1,1,0}, {1,0,1}};
const uint8_t kIFan02Speed[4][3] = {{6,6,6}, {7,6,6}, {7,7,6}, {7,6,7}};
//const uint8_t kIFan02Speed[4][3] = {{16,16,16}, {17,16,16}, {17,17,16}, {17,16,17}};
// Global variables
unsigned long feature_drv1; // Compiled driver feature map
unsigned long feature_drv2; // Compiled driver feature map
@ -502,6 +506,19 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
fallback_topic_flag = 0;
return;
}
else if ((CMND_FANSPEED == command_code) && (SONOFF_IFAN02 == Settings.module)) {
uint8_t fanspeed = (uint8_t)(power &0xF) >> 1;
if (fanspeed) { fanspeed = (fanspeed >> 1) +1; }
if ((payload >= 0) && (payload <= 3) && (payload != fanspeed)) {
fanspeed = payload;
for (byte i = 0; i < 3; i++) {
uint8_t state = kIFan02Speed[fanspeed][i];
// uint8_t state = pgm_read_byte(kIFan02Speed +(fanspeed *3) +i);
ExecuteCommandPower(i +2, state, SRC_IGNORE);
}
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, fanspeed);
}
else if (CMND_STATUS == command_code) {
if ((payload < 0) || (payload > MAX_STATUS)) payload = 99;
PublishStatus(payload);
@ -573,7 +590,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
XsnsCall(FUNC_COMMAND);
// if (!XsnsCall(FUNC_COMMAND)) type = NULL;
}
else if ((CMND_SETOPTION == command_code) && ((index <= 29) || ((index > 31) && (index <= P_MAX_PARAM8 + 31)))) {
else if ((CMND_SETOPTION == command_code) && (index <= P_MAX_PARAM8 + 31)) {
if (index <= 31) {
ptype = 0; // SetOption0 .. 31
} else {
@ -611,6 +628,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
// case 27: // knx_enable_enhancement
case 28: // rf_receive_decimal
case 29: // ir_receive_decimal
case 30: // hass_light
bitWrite(Settings.flag.data, index, payload);
}
if (12 == index) { // stop_flash_rotate
@ -618,7 +636,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
SettingsSave(2);
}
#ifdef USE_HOME_ASSISTANT
if (19 == index) { // hass_discovery
if ((19 == index) || (30 == index)) { // hass_discovery or hass_light
HAssDiscovery(1);
}
#endif // USE_HOME_ASSISTANT
@ -985,7 +1003,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_SVALUE, command, Settings.sta_config, stemp1);
}
}
else if ((CMND_FRIENDLYNAME == command_code) && (index > 0) && (index <= 4)) {
else if ((CMND_FRIENDLYNAME == command_code) && (index > 0) && (index <= MAX_FRIENDLYNAMES)) {
if ((data_len > 0) && (data_len < sizeof(Settings.friendlyname[0]))) {
if (1 == index) {
snprintf_P(stemp1, sizeof(stemp1), PSTR(FRIENDLY_NAME));
@ -1189,6 +1207,20 @@ void ExecuteCommandPower(byte device, byte state, int source)
// ShowSource(source);
/*
if (SONOFF_IFAN02 == Settings.module) {
if (state > 15) { // Only allow Fanspeed control over relay 2..4
state -= 10;
blink_mask &= 1;
Settings.flag.interlock = 0;
Settings.pulse_timer[1] = 0;
Settings.pulse_timer[2] = 0;
Settings.pulse_timer[3] = 0;
} else {
device = 1; // Only allow user control over light
}
}
*/
uint8_t publish_power = 1;
if ((POWER_OFF_NO_STATE == state) || (POWER_ON_NO_STATE == state)) {
state &= 1;
@ -1292,7 +1324,7 @@ void ExecuteCommand(char *cmnd, int source)
void PublishStatus(uint8_t payload)
{
uint8_t option = STAT;
char stemp[MAX_FRIENDLYNAMES * (sizeof(Settings.friendlyname[0]) +4)];
char stemp[MAX_FRIENDLYNAMES * (sizeof(Settings.friendlyname[0]) +MAX_FRIENDLYNAMES)];
// Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX
if (!strcmp(Settings.mqtt_prefix[0],Settings.mqtt_prefix[1]) && (!payload)) option++; // TELE

View File

@ -163,7 +163,7 @@ enum SupportedModules {
SONOFF_DUAL,
SONOFF_POW,
SONOFF_4CH,
S20,
SONOFF_S2X,
SLAMPHER,
SONOFF_TOUCH,
SONOFF_LED,
@ -199,6 +199,7 @@ enum SupportedModules {
SONOFF_S31,
ZENGGE_ZF_WF017,
SONOFF_POW_R2,
SONOFF_IFAN02,
MAXMODULE };
/********************************************************************************************/
@ -229,7 +230,7 @@ const uint8_t kNiceList[MAXMODULE] PROGMEM = {
SONOFF_4CHPRO,
SONOFF_SV,
SONOFF_DEV,
S20,
SONOFF_S2X,
SLAMPHER,
SONOFF_TOUCH,
SONOFF_T11,
@ -239,6 +240,7 @@ const uint8_t kNiceList[MAXMODULE] PROGMEM = {
SONOFF_B1,
SONOFF_LED,
SONOFF_BN,
SONOFF_IFAN02,
SONOFF_BRIDGE,
CH1,
CH4,
@ -365,15 +367,15 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
GPIO_REL4, // GPIO15 Red Led and Relay 4 (0 = Off, 1 = On)
0, 0
},
{ "S20 Socket", // S20 Smart Socket (ESP8266)
{ "Sonoff S2X", // Sonoff S20, S22 and S26 Smart Socket (ESP8266)
GPIO_KEY1, // GPIO00 Button
GPIO_USER, // GPIO01 Serial RXD and Optional sensor
0,
GPIO_USER, // GPIO02 Optional sensor
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
0, 0,
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_LED1_INV, // GPIO13 Green/Blue Led (0 = On, 1 = Off)
0, 0, 0, 0
},
{ "Slampher", // Slampher (ESP8266)
@ -834,6 +836,23 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off)
0, 0, 0, 0
},
{ "Sonoff iFan02", // Sonoff iFan02 (ESP8285)
GPIO_KEY1, // GPIO00 Virtual button 1
GPIO_USER, // GPIO01 Serial RXD and Optional sensor
0, // GPIO02 Optional sensor
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_REL3, // GPIO04 Relay 3 (0 = Off, 1 = On)
GPIO_REL2, // GPIO05 Relay 2 (0 = Off, 1 = On)
0, 0, 0, // Flash connection
GPIO_KEY2, // GPIO09 Virtual button 2
GPIO_KEY3, // GPIO10 Virtual button 3
0, // Flash connection
GPIO_REL1, // GPIO12 Relay 1 (0 = Off, 1 = On)
GPIO_LED1_INV, // GPIO13 Blue Led on PCA (0 = On, 1 = Off)
GPIO_KEY4, // GPIO14 Virtual button 4
GPIO_REL4, // GPIO15 Relay 4 (0 = Off, 1 = On)
0, 0
}
};

View File

@ -869,6 +869,12 @@ void GetFeatures()
#ifdef USE_LM75AD
feature_sns1 |= 0x20000000; // xsns_26_lm75ad.ino
#endif
#ifdef USE_APDS9960
feature_sns1 |= 0x40000000; // xsns_27_apds9960.ino
#endif
#ifdef USE_TM1638
feature_sns1 |= 0x80000000; // xsns_28_tm1638.ino
#endif
/*********************************************************************************************/

View File

@ -592,7 +592,11 @@ void HandleAjaxStatusRefresh()
WebGetArg("o", tmp, sizeof(tmp));
if (strlen(tmp)) {
ShowWebSource(SRC_WEBGUI);
ExecuteCommandPower(atoi(tmp), POWER_TOGGLE, SRC_IGNORE);
if (SONOFF_IFAN02 == Settings.module) { // QandD
ExecuteCommandPower(1, POWER_TOGGLE, SRC_IGNORE);
} else {
ExecuteCommandPower(atoi(tmp), POWER_TOGGLE, SRC_IGNORE);
}
}
WebGetArg("d", tmp, sizeof(tmp));
if (strlen(tmp)) {
@ -1076,16 +1080,14 @@ void HandleSaveSettings()
WebGetArg("b2", tmp, sizeof(tmp));
Settings.flag2.emulation = (!strlen(tmp)) ? 0 : atoi(tmp);
#endif // USE_EMULATION
WebGetArg("a1", tmp, sizeof(tmp));
strlcpy(Settings.friendlyname[0], (!strlen(tmp)) ? FRIENDLY_NAME : tmp, sizeof(Settings.friendlyname[0]));
WebGetArg("a2", tmp, sizeof(tmp));
strlcpy(Settings.friendlyname[1], (!strlen(tmp)) ? FRIENDLY_NAME"2" : tmp, sizeof(Settings.friendlyname[1]));
WebGetArg("a3", tmp, sizeof(tmp));
strlcpy(Settings.friendlyname[2], (!strlen(tmp)) ? FRIENDLY_NAME"3" : tmp, sizeof(Settings.friendlyname[2]));
WebGetArg("a4", tmp, sizeof(tmp));
strlcpy(Settings.friendlyname[3], (!strlen(tmp)) ? FRIENDLY_NAME"4" : tmp, sizeof(Settings.friendlyname[3]));
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME " %s, %s, %s, %s"),
GetStateText(Settings.flag.mqtt_enabled), Settings.flag2.emulation, Settings.friendlyname[0], Settings.friendlyname[1], Settings.friendlyname[2], Settings.friendlyname[3]);
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME), GetStateText(Settings.flag.mqtt_enabled), Settings.flag2.emulation);
for (byte i = 0; i < MAX_FRIENDLYNAMES; i++) {
snprintf_P(stemp, sizeof(stemp), PSTR("a%d"), i +1);
WebGetArg(stemp, tmp, sizeof(tmp));
snprintf_P(stemp2, sizeof(stemp2), PSTR(FRIENDLY_NAME"%d"), i +1);
strlcpy(Settings.friendlyname[i], (!strlen(tmp)) ? (i) ? stemp2 : FRIENDLY_NAME : tmp, sizeof(Settings.friendlyname[i]));
snprintf_P(log_data, sizeof(log_data), PSTR("%s%s %s"), log_data, (i) ? "," : "", Settings.friendlyname[i]);
}
AddLog(LOG_LEVEL_INFO);
break;
case 6:

View File

@ -71,18 +71,20 @@ void HAssDiscoverRelay()
char sidx[8];
char stopic[TOPSZ];
bool is_light = false;
bool is_topic_light = false;
for (int i = 1; i <= MAX_RELAYS; i++) {
is_light = ((i == devices_present) && (light_type));
is_topic_light = Settings.flag.hass_light;
mqtt_data[0] = '\0'; // Clear retained message
snprintf_P(sidx, sizeof(sidx), PSTR("_%d"), i);
// Clear "other" topic first in case the device has been reconfigured
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), (is_light) ? "switch" : "light", mqtt_topic, sidx);
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), (is_topic_light) ? "switch" : "light", mqtt_topic, sidx);
MqttPublish(stopic, true);
// Clear or Set topic
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), (is_light) ? "light" : "switch", mqtt_topic, sidx);
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), (is_topic_light) ? "light" : "switch", mqtt_topic, sidx);
if (Settings.flag.hass_discovery && (i <= devices_present)) {
char name[33];

View File

@ -28,6 +28,8 @@
#define TM1638_COLOR_RED 1
#define TM1638_COLOR_GREEN 2
#define TM1638_CLOCK_DELAY 1 // uSec
uint8_t tm1638_type = 1;
uint8_t tm1638_clock_pin = 0;
uint8_t tm1638_data_pin = 0;
@ -46,6 +48,7 @@ void Tm16XXSend(byte data)
digitalWrite(tm1638_clock_pin, LOW);
digitalWrite(tm1638_data_pin, data & 1 ? HIGH : LOW);
data >>= 1;
delayMicroseconds(TM1638_CLOCK_DELAY);
digitalWrite(tm1638_clock_pin, HIGH);
}
}
@ -77,9 +80,8 @@ byte Tm16XXReceive()
for (int i = 0; i < 8; i++) {
temp >>= 1;
digitalWrite(tm1638_clock_pin, LOW);
if (digitalRead(tm1638_data_pin)) {
temp |= 0x80;
}
delayMicroseconds(TM1638_CLOCK_DELAY);
if (digitalRead(tm1638_data_pin)) { temp |= 0x80; }
digitalWrite(tm1638_clock_pin, HIGH);
}
@ -169,9 +171,9 @@ void TmInit()
void TmLoop()
{
byte buttons = Tm1638GetButtons();
for (byte i = 0; i < 8; i++) {
for (byte i = 0; i < MAX_SWITCHES; i++) {
virtualswitch[i] = buttons &1;
byte color = virtualswitch[i] ? TM1638_COLOR_RED : TM1638_COLOR_NONE;
byte color = (virtualswitch[i]) ? TM1638_COLOR_RED : TM1638_COLOR_NONE;
Tm1638SetLED(color, i);
buttons >>= 1;
}

View File

@ -72,14 +72,14 @@ a_setoption = [
"Do not control Power with Dimmer",
"Energy monitoring while powered off",
"MQTT serial",
"Rules",
"Rules once mode",
"Rules until 5.14.0b",
"Rules once mode until 5.14.0b",
"KNX",
"Use Power device index on single relay devices",
"KNX enhancement",
"RF receive decimal",
"IR receive decimal",
"",""]
"Enforce HASS light group",""]
a_features = [[
"","","USE_I2C","USE_SPI",
@ -107,7 +107,7 @@ a_features = [[
"USE_INA219","USE_SHT3X","USE_MHZ19","USE_TSL2561",
"USE_SENSEAIR","USE_PMS5003","USE_MGS","USE_NOVA_SDS",
"USE_SGP30","USE_SR04","USE_SDM120","USE_SI1145",
"USE_SDM630","USE_LM75AD","",""
"USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638"
],[
"","","","",
"","","","",