6.3.0.11 Add delays

6.3.0.11 20181120
 * Add delays removed in 6.3.0.9 (#4233)
 * Allow user definition of defines WIFI_RSSI_THRESHOLD (default 10) and WIFI_RESCAN_MINUTES (default 44)
 * Add support for Fujitsu HVac and IrRemote (#4387)
This commit is contained in:
Theo Arends 2018-11-20 14:10:32 +01:00
parent 7218d86722
commit 76829d4ced
7 changed files with 103 additions and 86 deletions

View File

@ -1,4 +1,9 @@
/* 6.3.0.10 20181118 /* 6.3.0.11 20181120
* Add delays removed in 6.3.0.9 (#4233)
* Allow user definition of defines WIFI_RSSI_THRESHOLD (default 10) and WIFI_RESCAN_MINUTES (default 44)
* Add support for Fujitsu HVac and IrRemote (#4387)
*
* 6.3.0.10 20181118
* Add command SetOption36 0..255 milliseconds (50 default) to tune main loop dynamic delay * Add command SetOption36 0..255 milliseconds (50 default) to tune main loop dynamic delay
* Add support for LG HVac and IrRemote (#4377) * Add support for LG HVac and IrRemote (#4377)
* Add command SetOption56 0/1 to enable wifi network scan and select highest RSSI (#3173) * Add command SetOption56 0/1 to enable wifi network scan and select highest RSSI (#3173)

View File

@ -138,6 +138,9 @@ typedef unsigned long power_t; // Power (Relay) type
#define SERIAL_POLLING 100 // Serial receive polling in ms #define SERIAL_POLLING 100 // Serial receive polling in ms
#define MAX_STATUS 11 // Max number of status lines #define MAX_STATUS 11 // Max number of status lines
#define DRIVER_BOOT_DELAY 1 // Number of milliseconds to retard driver cycles during boot-up time to reduce overall CPU load whilst Wifi is connecting
#define LOOP_SLEEP_DELAY 50 // Lowest number of milliseconds to go through the main loop using delay when needed
#define NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions) #define NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions)
/* /*
@ -189,9 +192,6 @@ typedef unsigned long power_t; // Power (Relay) type
#define KNX_MAX_device_param 30 #define KNX_MAX_device_param 30
#define MAX_KNXTX_CMNDS 5 #define MAX_KNXTX_CMNDS 5
#define DRIVER_BOOT_DELAY 1 // Number of milliseconds to retard driver cycles during boot-up time to reduce overall CPU load whilst Wifi is connecting
#define LOOP_SLEEP_DELAY 50 // Lowest number of milliseconds to go through the main loop using delay when needed
/*********************************************************************************************\ /*********************************************************************************************\
* Enumeration * Enumeration
\*********************************************************************************************/ \*********************************************************************************************/

View File

@ -20,7 +20,7 @@
#ifndef _SONOFF_VERSION_H_ #ifndef _SONOFF_VERSION_H_
#define _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_
#define VERSION 0x0603000A #define VERSION 0x0603000B
#define D_PROGRAMNAME "Sonoff-Tasmota" #define D_PROGRAMNAME "Sonoff-Tasmota"
#define D_AUTHOR "Theo Arends" #define D_AUTHOR "Theo Arends"

View File

@ -21,6 +21,13 @@
* Wifi * Wifi
\*********************************************************************************************/ \*********************************************************************************************/
#ifndef WIFI_RSSI_THRESHOLD
#define WIFI_RSSI_THRESHOLD 10 // Difference in dB between current network and scanned network
#endif
#ifndef WIFI_RESCAN_MINUTES
#define WIFI_RESCAN_MINUTES 44 // Number of minutes between wifi network rescan
#endif
#define WIFI_CONFIG_SEC 180 // seconds before restart #define WIFI_CONFIG_SEC 180 // seconds before restart
#define WIFI_CHECK_SEC 20 // seconds #define WIFI_CHECK_SEC 20 // seconds
#define WIFI_RETRY_OFFSET_SEC 20 // seconds #define WIFI_RETRY_OFFSET_SEC 20 // seconds
@ -207,7 +214,7 @@ void WifiBegin(uint8_t flag, uint8_t channel)
WiFiSetSleepMode(); WiFiSetSleepMode();
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); } // if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); }
if (!WiFi.getAutoConnect()) { WiFi.setAutoConnect(true); } if (!WiFi.getAutoConnect()) { WiFi.setAutoConnect(true); }
WiFi.setAutoReconnect(true); // WiFi.setAutoReconnect(true);
switch (flag) { switch (flag) {
case 0: // AP1 case 0: // AP1
case 1: // AP2 case 1: // AP2
@ -231,8 +238,6 @@ void WifiBegin(uint8_t flag, uint8_t channel)
AddLog(LOG_LEVEL_INFO); AddLog(LOG_LEVEL_INFO);
} }
#define WIFI_RSSI_THRESHOLD 10
void WifiBeginAfterScan() void WifiBeginAfterScan()
{ {
static int8_t best_network_db; static int8_t best_network_db;
@ -395,17 +400,17 @@ void WifiCheckIp(void)
} }
} }
if (wifi_retry) { if (wifi_retry) {
if (!Settings.flag3.use_wifi_scan) { if (Settings.flag3.use_wifi_scan) {
if (wifi_retry_init == wifi_retry) {
wifi_scan_state = 1; // Select scanned SSID
}
} else {
if (wifi_retry_init == wifi_retry) { if (wifi_retry_init == wifi_retry) {
WifiBegin(3, 0); // Select default SSID WifiBegin(3, 0); // Select default SSID
} }
if ((Settings.sta_config != WIFI_WAIT) && ((wifi_retry_init / 2) == wifi_retry)) { if ((Settings.sta_config != WIFI_WAIT) && ((wifi_retry_init / 2) == wifi_retry)) {
WifiBegin(2, 0); // Select alternate SSID WifiBegin(2, 0); // Select alternate SSID
} }
} else {
if (wifi_retry_init == wifi_retry) {
wifi_scan_state = 1;
}
} }
wifi_counter = 1; wifi_counter = 1;
wifi_retry--; wifi_retry--;
@ -473,7 +478,7 @@ void WifiCheck(uint8_t param)
WifiSetState(1); WifiSetState(1);
if (Settings.flag3.use_wifi_rescan) { if (Settings.flag3.use_wifi_rescan) {
if (!(uptime % (60 * 44))) { if (!(uptime % (60 * WIFI_RESCAN_MINUTES))) {
wifi_scan_state = 2; wifi_scan_state = 2;
} }
} }

View File

@ -1,18 +1,18 @@
/* /*
xdrv_05_irremote.ino - infra red support for Sonoff-Tasmota xdrv_05_irremote.ino - infra red support for Sonoff-Tasmota
Copyright (C) 2018 Heiko Krupp, Lazar Obradovic and Theo Arends Copyright (C) 2018 Heiko Krupp, Lazar Obradovic and Theo Arends
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -137,60 +137,11 @@ void IrReceiveCheck(void)
#endif // USE_IR_RECEIVE #endif // USE_IR_RECEIVE
#ifdef USE_IR_HVAC #ifdef USE_IR_HVAC
boolean IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_Power, int HVAC_Temp)
{
const char kFujitsuHvacModeOptions[] = "HDCAF";
char stemp[64];
snprintf_P(stemp, sizeof(stemp), PSTR("FUJITSU: mode:%s, fan:%s, power:%u, temp:%u"), HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
IRFujitsuAC ac(pin[GPIO_IRSEND]);
if (HVAC_Power == 0) {
ac.off();
ac.send();
return false;
}
byte modes[5] = {FUJITSU_AC_MODE_HEAT, FUJITSU_AC_MODE_DRY, FUJITSU_AC_MODE_COOL, FUJITSU_AC_MODE_AUTO, FUJITSU_AC_MODE_FAN};
byte fanModes[7] = {FUJITSU_AC_FAN_AUTO, FUJITSU_AC_FAN_LOW, FUJITSU_AC_FAN_MED, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_QUIET};
ac.setCmd(FUJITSU_AC_CMD_TURN_ON);
ac.setSwing(FUJITSU_AC_SWING_VERT);
char *p;
if (HVAC_Mode == NULL) {
p = (char *)kFujitsuHvacModeOptions;
}
else {
p = strchr(kFujitsuHvacModeOptions, toupper(HVAC_Mode[0]));
}
if (!p) {
return true;
}
ac.setMode(modes[p - kFujitsuHvacModeOptions]);
if (HVAC_FanMode == NULL) {
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
}
else {
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
}
if (!p) {
return true;
}
ac.setFanSpeed(fanModes[p - kFanSpeedOptions]);
ac.setTemp(HVAC_Temp);
ac.send();
return false;
}
/********************************************************************************************* \ /********************************************************************************************* \
* IR Heating, Ventilation and Air Conditioning using IRMitsubishiAC library * IR Heating, Ventilation and Air Conditioning using IRMitsubishiAC library
\*********************************************************************************************/ \*********************************************************************************************/
/******************* /*******************
TOSHIBA TOSHIBA
********************/ ********************/
@ -284,7 +235,7 @@ boolean IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean H
} }
/******************* /*******************
MITSUBISHI MITSUBISHI
********************/ ********************/
@ -333,7 +284,7 @@ boolean IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, boolea
} }
/******************* /*******************
LG LG
********************/ ********************/
@ -353,21 +304,21 @@ boolean IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_P
if (!HVAC_Power) { if (!HVAC_Power) {
data[2] = (byte)0x0C; // Turn OFF HVAC, code 0x88C0051 data[2] = (byte)0x0C; // Turn OFF HVAC, code 0x88C0051
data[3] = (byte)0x00; data[3] = (byte)0x00;
data[4] = (byte)0x00; data[4] = (byte)0x00;
data[5] = (byte)0x05; data[5] = (byte)0x05;
data[6] = (byte)0x01; data[6] = (byte)0x01;
hvacOn = false; hvacOn = false;
} }
else { else {
// Set code for HVAC Mode - data[3] // Set code for HVAC Mode - data[3]
if (HVAC_Mode == NULL) { if (HVAC_Mode == NULL) {
p = (char *)kHvacModeOptions; // default HVAC_HOT p = (char *)kHvacModeOptions; // default HVAC_HOT
} }
else { else {
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0])); p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
} }
if (!p) { if (!p) {
return true; return true;
@ -385,16 +336,16 @@ boolean IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_P
break; break;
case 3: // HOT case 3: // HOT
data[3] = 12; data[3] = 12;
break; break;
} }
if (!hvacOn) { if (!hvacOn) {
data[3] = data[3] & 7; // reset bit3 data[3] = data[3] & 7; // reset bit3
hvacOn = true; hvacOn = true;
} }
snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: HvacMode %s, ModeVal %d, Code %d"), p, mode, data[3]); snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: HvacMode %s, ModeVal %d, Code %d"), p, mode, data[3]);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
// Set code for HVAC temperature - data[4] // Set code for HVAC temperature - data[4]
if (HVAC_Temp > 30) { if (HVAC_Temp > 30) {
Temp = 30; Temp = 30;
@ -424,14 +375,14 @@ boolean IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_P
else { else {
data[5] = (mode * 2) - 2; // Low = 0x00, Mid = 0x02, High = 0x04 data[5] = (mode * 2) - 2; // Low = 0x00, Mid = 0x02, High = 0x04
} }
snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: FanMode %s, ModeVal %d, Code %d"), p, mode, data[5]); snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: FanMode %s, ModeVal %d, Code %d"), p, mode, data[5]);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
// Set CRC code - data[6] // Set CRC code - data[6]
data[6] = (data[3] + data[4] + data[5]) & 0x0f; // CRC data[6] = (data[3] + data[4] + data[5]) & 0x0f; // CRC
} }
// Build LG IR code // Build LG IR code
LG_Code = data[0] << 4; LG_Code = data[0] << 4;
for (int i = 1; i < 6; i++) { for (int i = 1; i < 6; i++) {
@ -442,13 +393,68 @@ boolean IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_P
snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: LG_Code %d"), LG_Code); snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: LG_Code %d"), LG_Code);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
// Send LG IR Code // Send LG IR Code
noInterrupts(); noInterrupts();
irsend->sendLG(LG_Code, 28); irsend->sendLG(LG_Code, 28);
interrupts(); interrupts();
return false; return false;
} }
/*******************
Fujitsu
********************/
boolean IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_Power, int HVAC_Temp)
{
const char kFujitsuHvacModeOptions[] = "HDCAF";
char stemp[64];
snprintf_P(stemp, sizeof(stemp), PSTR("FUJITSU: mode:%s, fan:%s, power:%u, temp:%u"), HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
IRFujitsuAC ac(pin[GPIO_IRSEND]);
if (0 == HVAC_Power) {
ac.off();
ac.send();
return false;
}
byte modes[5] = {FUJITSU_AC_MODE_HEAT, FUJITSU_AC_MODE_DRY, FUJITSU_AC_MODE_COOL, FUJITSU_AC_MODE_AUTO, FUJITSU_AC_MODE_FAN};
byte fanModes[7] = {FUJITSU_AC_FAN_AUTO, FUJITSU_AC_FAN_LOW, FUJITSU_AC_FAN_MED, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_QUIET};
ac.setCmd(FUJITSU_AC_CMD_TURN_ON);
ac.setSwing(FUJITSU_AC_SWING_VERT);
char *p;
if (NULL == HVAC_Mode) {
p = (char *)kFujitsuHvacModeOptions;
}
else {
p = strchr(kFujitsuHvacModeOptions, toupper(HVAC_Mode[0]));
}
if (!p) {
return true;
}
ac.setMode(modes[p - kFujitsuHvacModeOptions]);
if (HVAC_FanMode == NULL) {
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
}
else {
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
}
if (!p) {
return true;
}
ac.setFanSpeed(fanModes[p - kFanSpeedOptions]);
ac.setTemp(HVAC_Temp);
ac.send();
return false;
}
#endif // USE_IR_HVAC #endif // USE_IR_HVAC
/*********************************************************************************************\ /*********************************************************************************************\
@ -562,6 +568,7 @@ boolean IrSendCommand(void)
} }
else if (!strcasecmp_P(HVAC_Vendor, PSTR("LG"))) { else if (!strcasecmp_P(HVAC_Vendor, PSTR("LG"))) {
error = IrHvacLG(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); error = IrHvacLG(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
}
else if (!strcasecmp_P(HVAC_Vendor, PSTR("FUJITSU"))) { else if (!strcasecmp_P(HVAC_Vendor, PSTR("FUJITSU"))) {
error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
} }

View File

@ -238,7 +238,7 @@ boolean XdrvCall(byte Function)
boolean result = false; boolean result = false;
for (byte x = 0; x < xdrv_present; x++) { for (byte x = 0; x < xdrv_present; x++) {
// AppDelay(); AppDelay();
result = xdrv_func_ptr[x](Function); result = xdrv_func_ptr[x](Function);
if (result) break; if (result) break;
} }

View File

@ -280,7 +280,7 @@ boolean XsnsNextCall(byte Function)
if (xsns_index == xsns_present) { xsns_index = 0; } if (xsns_index == xsns_present) { xsns_index = 0; }
} }
#endif #endif
// AppDelay(); AppDelay();
return xsns_func_ptr[xsns_index](Function); return xsns_func_ptr[xsns_index](Function);
} }
@ -300,7 +300,7 @@ boolean XsnsCall(byte Function)
#ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND #ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND
uint32_t profile_start_millis = millis(); uint32_t profile_start_millis = millis();
#endif // PROFILE_XSNS_SENSOR_EVERY_SECOND #endif // PROFILE_XSNS_SENSOR_EVERY_SECOND
// AppDelay(); AppDelay();
result = xsns_func_ptr[x](Function); result = xsns_func_ptr[x](Function);
#ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND #ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND