diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 3a3e18910..bcca8cde8 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -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 support for LG HVac and IrRemote (#4377) * Add command SetOption56 0/1 to enable wifi network scan and select highest RSSI (#3173) diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 9f9350c64..e53a7c83d 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -138,6 +138,9 @@ typedef unsigned long power_t; // Power (Relay) type #define SERIAL_POLLING 100 // Serial receive polling in ms #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) /* @@ -189,9 +192,6 @@ typedef unsigned long power_t; // Power (Relay) type #define KNX_MAX_device_param 30 #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 \*********************************************************************************************/ diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 78acd0305..21ed0ce8f 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x0603000A +#define VERSION 0x0603000B #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support_wifi.ino b/sonoff/support_wifi.ino index 4c5546687..b427a3f9b 100644 --- a/sonoff/support_wifi.ino +++ b/sonoff/support_wifi.ino @@ -21,6 +21,13 @@ * 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_CHECK_SEC 20 // seconds #define WIFI_RETRY_OFFSET_SEC 20 // seconds @@ -207,7 +214,7 @@ void WifiBegin(uint8_t flag, uint8_t channel) WiFiSetSleepMode(); // if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); } if (!WiFi.getAutoConnect()) { WiFi.setAutoConnect(true); } - WiFi.setAutoReconnect(true); +// WiFi.setAutoReconnect(true); switch (flag) { case 0: // AP1 case 1: // AP2 @@ -231,8 +238,6 @@ void WifiBegin(uint8_t flag, uint8_t channel) AddLog(LOG_LEVEL_INFO); } -#define WIFI_RSSI_THRESHOLD 10 - void WifiBeginAfterScan() { static int8_t best_network_db; @@ -395,17 +400,17 @@ void WifiCheckIp(void) } } 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) { WifiBegin(3, 0); // Select default SSID } if ((Settings.sta_config != WIFI_WAIT) && ((wifi_retry_init / 2) == wifi_retry)) { WifiBegin(2, 0); // Select alternate SSID } - } else { - if (wifi_retry_init == wifi_retry) { - wifi_scan_state = 1; - } } wifi_counter = 1; wifi_retry--; @@ -473,7 +478,7 @@ void WifiCheck(uint8_t param) WifiSetState(1); if (Settings.flag3.use_wifi_rescan) { - if (!(uptime % (60 * 44))) { + if (!(uptime % (60 * WIFI_RESCAN_MINUTES))) { wifi_scan_state = 2; } } diff --git a/sonoff/xdrv_05_irremote.ino b/sonoff/xdrv_05_irremote.ino index 4f71fd6d9..8836c4ddf 100644 --- a/sonoff/xdrv_05_irremote.ino +++ b/sonoff/xdrv_05_irremote.ino @@ -1,18 +1,18 @@ /* xdrv_05_irremote.ino - infra red support for Sonoff-Tasmota - + Copyright (C) 2018 Heiko Krupp, Lazar Obradovic and Theo Arends - + 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 the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -137,60 +137,11 @@ void IrReceiveCheck(void) #endif // USE_IR_RECEIVE #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 \*********************************************************************************************/ -/******************* +/******************* TOSHIBA ********************/ @@ -284,7 +235,7 @@ boolean IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean H } -/******************* +/******************* MITSUBISHI ********************/ @@ -333,7 +284,7 @@ boolean IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, boolea } -/******************* +/******************* LG ********************/ @@ -353,21 +304,21 @@ boolean IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_P if (!HVAC_Power) { data[2] = (byte)0x0C; // Turn OFF HVAC, code 0x88C0051 - data[3] = (byte)0x00; - data[4] = (byte)0x00; - data[5] = (byte)0x05; - data[6] = (byte)0x01; + data[3] = (byte)0x00; + data[4] = (byte)0x00; + data[5] = (byte)0x05; + data[6] = (byte)0x01; hvacOn = false; } else { - + // Set code for HVAC Mode - data[3] if (HVAC_Mode == NULL) { p = (char *)kHvacModeOptions; // default HVAC_HOT } else { - p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0])); + p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0])); } if (!p) { return true; @@ -385,16 +336,16 @@ boolean IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_P break; case 3: // HOT data[3] = 12; - break; + break; } if (!hvacOn) { data[3] = data[3] & 7; // reset bit3 hvacOn = true; } - + snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: HvacMode %s, ModeVal %d, Code %d"), p, mode, data[3]); AddLog(LOG_LEVEL_DEBUG); - + // Set code for HVAC temperature - data[4] if (HVAC_Temp > 30) { Temp = 30; @@ -424,14 +375,14 @@ boolean IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_P else { 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]); AddLog(LOG_LEVEL_DEBUG); // Set CRC code - data[6] data[6] = (data[3] + data[4] + data[5]) & 0x0f; // CRC - } + } // Build LG IR code LG_Code = data[0] << 4; 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); AddLog(LOG_LEVEL_DEBUG); - // Send LG IR Code + // Send LG IR Code noInterrupts(); irsend->sendLG(LG_Code, 28); interrupts(); - + 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 /*********************************************************************************************\ @@ -562,6 +568,7 @@ boolean IrSendCommand(void) } else if (!strcasecmp_P(HVAC_Vendor, PSTR("LG"))) { error = IrHvacLG(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); + } else if (!strcasecmp_P(HVAC_Vendor, PSTR("FUJITSU"))) { error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); } diff --git a/sonoff/xdrv_interface.ino b/sonoff/xdrv_interface.ino index 12b9e2711..c9557ec56 100644 --- a/sonoff/xdrv_interface.ino +++ b/sonoff/xdrv_interface.ino @@ -238,7 +238,7 @@ boolean XdrvCall(byte Function) boolean result = false; for (byte x = 0; x < xdrv_present; x++) { -// AppDelay(); + AppDelay(); result = xdrv_func_ptr[x](Function); if (result) break; } diff --git a/sonoff/xsns_interface.ino b/sonoff/xsns_interface.ino index a7ab6d7a7..cb1649d11 100644 --- a/sonoff/xsns_interface.ino +++ b/sonoff/xsns_interface.ino @@ -280,7 +280,7 @@ boolean XsnsNextCall(byte Function) if (xsns_index == xsns_present) { xsns_index = 0; } } #endif -// AppDelay(); + AppDelay(); return xsns_func_ptr[xsns_index](Function); } @@ -300,7 +300,7 @@ boolean XsnsCall(byte Function) #ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND uint32_t profile_start_millis = millis(); #endif // PROFILE_XSNS_SENSOR_EVERY_SECOND -// AppDelay(); + AppDelay(); result = xsns_func_ptr[x](Function); #ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND