diff --git a/README.md b/README.md index dc57ce296..a5e309f9e 100644 --- a/README.md +++ b/README.md @@ -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.6** - See ```sonoff/_releasenotes.ino``` for change information. +Current version is **3.9.7** - 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```. diff --git a/api/arduino/sonoff.ino.bin b/api/arduino/sonoff.ino.bin index fa2783e8b..b4306d1dc 100644 Binary files a/api/arduino/sonoff.ino.bin and b/api/arduino/sonoff.ino.bin differ diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 8dd3a0552..d0ee99334 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,8 @@ -/* 3.9.6 20170129 +/* 3.9.7 20170129 + * Fix possible WS2812 exceptions when using emulation + * Add command Emulation to dynamic configure Belkin WeMo and Hue Bridge for Alexa + * + * 3.9.6 20170129 * Add dynamic sleep for WS2812 animation (#1) * * 3.9.5 20170128 diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 53890c57a..4dfa6853a 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -10,7 +10,7 @@ * ==================================================== */ -#define VERSION 0x03090600 // 3.9.6 +#define VERSION 0x03090700 // 3.9.7 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}; @@ -19,6 +19,7 @@ enum month_t {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; enum wifi_t {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, MAX_WIFI_OPTION}; enum swtch_t {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, MAX_SWITCH_OPTION}; enum led_t {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION}; +enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; #include "sonoff_template.h" @@ -311,6 +312,8 @@ struct SYSCFG { uint8_t led_width; uint16_t led_wakeup; + uint8_t emulation; + } sysCfg; struct TIME_T { @@ -422,7 +425,7 @@ void CFG_DefaultSet() sysCfg.model = 0; sysCfg.timezone = APP_TIMEZONE; strlcpy(sysCfg.otaUrl, OTA_URL, sizeof(sysCfg.otaUrl)); - strlcpy(sysCfg.ex_friendlyname, FRIENDLY_NAME1, sizeof(sysCfg.ex_friendlyname)); + strlcpy(sysCfg.ex_friendlyname, FRIENDLY_NAME, sizeof(sysCfg.ex_friendlyname)); sysCfg.seriallog_level = SERIAL_LOG_LEVEL; sysCfg.sta_active = 0; @@ -506,10 +509,10 @@ void CFG_DefaultSet() sysCfg.ws_width = 1; sysCfg.ws_wakeup = 0; - strlcpy(sysCfg.friendlyname[0], FRIENDLY_NAME1, sizeof(sysCfg.friendlyname[0])); - strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME2, sizeof(sysCfg.friendlyname[1])); - strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME3, sizeof(sysCfg.friendlyname[2])); - strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME4, sizeof(sysCfg.friendlyname[3])); + strlcpy(sysCfg.friendlyname[0], FRIENDLY_NAME, sizeof(sysCfg.friendlyname[0])); + strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME"2", sizeof(sysCfg.friendlyname[1])); + strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME"3", sizeof(sysCfg.friendlyname[2])); + strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3])); for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0; @@ -526,6 +529,8 @@ void CFG_DefaultSet() strlcpy(sysCfg.switch_topic, "0", sizeof(sysCfg.switch_topic)); sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN; sysCfg.mqtt_enabled = MQTT_USE; + + sysCfg.emulation = EMULATION; } @@ -678,9 +683,9 @@ void CFG_Delta() } if (sysCfg.version < 0x03020500) { // 3.2.5 - Add parameter strlcpy(sysCfg.friendlyname[0], sysCfg.ex_friendlyname, sizeof(sysCfg.friendlyname[0])); - strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME2, sizeof(sysCfg.friendlyname[1])); - strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME3, sizeof(sysCfg.friendlyname[2])); - strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME4, sizeof(sysCfg.friendlyname[3])); + strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME"2", sizeof(sysCfg.friendlyname[1])); + strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME"3", sizeof(sysCfg.friendlyname[2])); + strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3])); } if (sysCfg.version < 0x03020800) { // 3.2.8 - Add parameter strlcpy(sysCfg.switch_topic, sysCfg.button_topic, sizeof(sysCfg.switch_topic)); @@ -707,6 +712,9 @@ void CFG_Delta() sysCfg.led_width = 0; sysCfg.led_wakeup = 0; } + if (sysCfg.version < 0x03090700) { // 3.9.7 - Add parameter + sysCfg.emulation = EMULATION; + } sysCfg.version = VERSION; } @@ -1003,9 +1011,9 @@ void mqtt_reconnect() mqtt_connected(); return; } -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) +#ifdef USE_EMULATION UDP_Disconnect(); -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#endif // USE_EMULATION if (mqttflag > 1) { #ifdef USE_MQTT_TLS addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Verify TLS fingerprint...")); @@ -1389,14 +1397,12 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } else if (!strcmp(type,"FRIENDLYNAME") && (index > 0) && (index <= 4)) { if ((data_len > 0) && (data_len < sizeof(sysCfg.friendlyname[0]))) { - if (index == 1) - strlcpy(sysCfg.friendlyname[0], (payload == 1) ? FRIENDLY_NAME1 : dataBuf, sizeof(sysCfg.friendlyname[0])); - else if (index == 2) - strlcpy(sysCfg.friendlyname[1], (payload == 1) ? FRIENDLY_NAME2 : dataBuf, sizeof(sysCfg.friendlyname[1])); - else if (index == 3) - strlcpy(sysCfg.friendlyname[2], (payload == 1) ? FRIENDLY_NAME3 : dataBuf, sizeof(sysCfg.friendlyname[2])); - else if (index == 4) - strlcpy(sysCfg.friendlyname[3], (payload == 1) ? FRIENDLY_NAME4 : dataBuf, sizeof(sysCfg.friendlyname[3])); + if (index == 1) { + snprintf_P(stemp1, sizeof(stemp1), PSTR(FRIENDLY_NAME)); + } else { + snprintf_P(stemp1, sizeof(stemp1), PSTR(FRIENDLY_NAME "%d"), index); + } + strlcpy(sysCfg.friendlyname[index -1], (payload == 1) ? stemp1 : dataBuf, sizeof(sysCfg.friendlyname[index -1])); } snprintf_P(svalue, sizeof(svalue), PSTR("{\"FriendlyName%d\":\"%s\"}"), index, sysCfg.friendlyname[index -1]); } @@ -1424,6 +1430,15 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } snprintf_P(svalue, sizeof(svalue), PSTR("{\"WebLog\":%d}"), sysCfg.weblog_level); } +#ifdef USE_EMULATION + else if (!strcmp(type,"EMULATION")) { + if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { + sysCfg.emulation = payload; + restartflag = 2; + } + snprintf_P(svalue, sizeof(svalue), PSTR("{\"Emulation\":%d}"), sysCfg.emulation); + } +#endif // USE_EMULATION #endif // USE_WEBSERVER else if (!strcmp(type,"UNITS")) { if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { @@ -1669,7 +1684,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands\":\"%s%s, PulseTime, BlinkTime, BlinkCount"), (Maxdevice == 1) ? "Power, Light" : "Power1, Power2, Light1 Light2", (sysCfg.module != MOTOR) ? ", PowerOnState" : ""); #ifdef USE_WEBSERVER - snprintf_P(svalue, sizeof(svalue), PSTR("%s, Weblog, Webserver"), svalue); + snprintf_P(svalue, sizeof(svalue), PSTR("%s, Weblog, Webserver, Emulation"), svalue); #endif if (swt_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, SwitchMode"), svalue); #ifdef USE_I2C @@ -2521,9 +2536,9 @@ void loop() pollDnsWeb(); #endif // USE_WEBSERVER -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) - pollUDP(); -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#ifdef USE_EMULATION + if (sysCfg.emulation) pollUDP(); +#endif // USE_EMULATION if (millis() >= timerxs) stateloop(); if (sysCfg.mqtt_enabled) mqttClient.loop(); diff --git a/sonoff/support.ino b/sonoff/support.ino index e3b35f33a..3442cd31c 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -375,9 +375,9 @@ void WIFI_config(uint8_t type) { if (!_wificonfigflag) { if (type == WIFI_RETRY) return; -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) +#ifdef USE_EMULATION UDP_Disconnect(); -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#endif // USE_EMULATION WiFi.disconnect(); // Solve possible Wifi hangs _wificonfigflag = type; _wifiConfigCounter = WIFI_CONFIG_SEC; // Allow up to WIFI_CONFIG_SECS seconds for phone to provide ssid/pswd @@ -412,9 +412,9 @@ void WIFI_begin(uint8_t flag) const char PhyMode[] = " BGN"; char log[LOGSZ]; -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) +#ifdef USE_EMULATION UDP_Disconnect(); -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#endif // USE_EMULATION if (!strncmp(ESP.getSdkVersion(),"1.5.3",5)) { addLog_P(LOG_LEVEL_DEBUG, "Wifi: Patch issue 2186"); WiFi.mode(WIFI_OFF); // See https://github.com/esp8266/Arduino/issues/2186 @@ -541,14 +541,14 @@ void WIFI_Check(uint8_t param) } else { stopWebserver(); } -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) - UDP_Connect(); -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#ifdef USE_EMULATION + if (sysCfg.emulation) UDP_Connect(); +#endif // USE_EMULATION #endif // USE_WEBSERVER } else { -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) +#ifdef USE_EMULATION UDP_Disconnect(); -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#endif // USE_EMULATION mDNSbegun = false; } } diff --git a/sonoff/user_config.h b/sonoff/user_config.h index a0cae5c9a..2edb63c08 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -79,13 +79,10 @@ // -- HTTP ---------------------------------------- #define USE_WEBSERVER // Enable web server and wifi manager (+43k code, +2k mem) - Disable by // - #define FRIENDLY_NAME1 "Sonoff" // [FriendlyName1] Friendlyname up to 32 characters used by webpages and Alexa - #define FRIENDLY_NAME2 "Sonoff2" // [FriendlyName2] Friendlyname up to 32 characters used by Alexa - #define FRIENDLY_NAME3 "Sonoff3" // [FriendlyName3] Friendlyname up to 32 characters used by Alexa - #define FRIENDLY_NAME4 "Sonoff4" // [FriendlyName4] Friendlyname up to 32 characters used by Alexa + #define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa #define WEB_SERVER 2 // [WebServer] Web server (0 = Off, 1 = Start as User, 2 = Start as Admin) -// #define USE_WEMO_EMULATION // Enable Belkin WeMo PowerSwitch emulation for Alexa (+4k code, +2k mem) -// #define USE_HUE_EMULATION // Enable Hue Bridge emulation for Alexa (+5k code, +2k mem) + #define USE_EMULATION // Enable Belkin WeMo and Hue Bridge emulation for Alexa (+11k code, +2k mem) + #define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo or Hue Bridge emulation (EMUL_NONE, EMUL_WEMO or EMUL_HUE) // -- mDNS ---------------------------------------- #define USE_DISCOVERY // Enable mDNS for the following services (+8k code, +0.3k mem) diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index aa677d8ba..7689ada06 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -158,7 +158,16 @@ const char HTTP_FORM_LOG3[] PROGMEM = const char HTTP_FORM_OTHER[] PROGMEM = "
 Other parameters 
" "" - "
MQTT enable
"; + "
MQTT enable
"; +const char HTTP_FORM_OTHER2[] PROGMEM = + "
Friendly Name {1 ({2)

"; +#ifdef USE_EMULATION +const char HTTP_FORM_OTHER3[] PROGMEM = + "
 Emulation " + "
None
" + "
Belkin WeMo
" + "
Hue Bridge
"; +#endif // USE_EMULATION const char HTTP_FORM_END[] PROGMEM = "
"; const char HTTP_FORM_UPG[] PROGMEM = @@ -188,7 +197,7 @@ const char HTTP_END[] PROGMEM = "" "" ""; -#ifdef USE_WEMO_EMULATION +#ifdef USE_EMULATION const char WEMO_EVENTSERVICE_XML[] PROGMEM = "" "" @@ -241,8 +250,6 @@ const char WEMO_SETUP_XML[] PROGMEM = "" "\r\n" "\r\n"; -#endif // USE_WEMO_EMULATION -#ifdef USE_HUE_EMULATION const char HUE_DESCRIPTION_XML[] PROGMEM = "" "" @@ -261,7 +268,6 @@ const char HUE_DESCRIPTION_XML[] PROGMEM = "" "\r\n" "\r\n"; - const char HUE_LIGHT_STATUS_JSON[] PROGMEM = "{\"state\":" "{\"on\":{state}," @@ -280,10 +286,9 @@ const char HUE_LIGHT_STATUS_JSON[] PROGMEM = "\"uniqueid\":\"{j2}\"," "\"swversion\":\"66012040\"" "}"; - const char HUE_LIGHT_RESPONSE_JSON[] PROGMEM = "{\"success\":{\"{api}/{id}/{cmd}\":{res}}}"; -#endif // USE_HUE_EMULATION +#endif // USE_EMULATION #define DNS_PORT 53 enum http_t {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER}; @@ -325,14 +330,14 @@ void startWebserver(int type, IPAddress ipweb) webServer->on("/in", handleInfo); webServer->on("/rb", handleRestart); webServer->on("/fwlink", handleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler. -#ifdef USE_WEMO_EMULATION - webServer->on("/upnp/control/basicevent1", HTTP_POST, handleUPnPevent); - webServer->on("/eventservice.xml", handleUPnPservice); - webServer->on("/setup.xml", handleUPnPsetup); -#endif // USE_WEMO_EMULATION -#ifdef USE_HUE_EMULATION - webServer->on("/description.xml", handleUPnPsetup); -#endif // USE_HUE_EMULATION +#ifdef USE_EMULATION + if (sysCfg.emulation == EMUL_WEMO) { + webServer->on("/upnp/control/basicevent1", HTTP_POST, handleUPnPevent); + webServer->on("/eventservice.xml", handleUPnPservice); + webServer->on("/setup.xml", handleUPnPsetupWemo); + } + if (sysCfg.emulation == EMUL_HUE) webServer->on("/description.xml", handleUPnPsetupHue); +#endif // USE_EMULATION webServer->onNotFound(handleNotFound); } webServer->begin(); // Web server start @@ -572,9 +577,9 @@ void handleWifi(boolean scan) page.replace("{v}", "Configure Wifi"); if (scan) { -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) +#ifdef USE_EMULATION UDP_Disconnect(); -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#endif // USE_EMULATION int n = WiFi.scanNetworks(); addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifi: Scan done")); @@ -748,20 +753,30 @@ void handleOther() return; } addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle other config")); + char stemp[40]; String page = FPSTR(HTTP_HEAD); page.replace("{v}", "Configure Other"); page += FPSTR(HTTP_FORM_OTHER); page.replace("{r1}", (sysCfg.mqtt_enabled) ? " checked" : ""); - for (int i = 0; i < Maxdevice; i++) { - page += F("
Friendly Name {1 ({2)

"); + page += FPSTR(HTTP_FORM_OTHER2); + page.replace("{1", "1"); + page.replace("{2", FRIENDLY_NAME); + page.replace("{3", String(sysCfg.friendlyname[0])); +#ifdef USE_EMULATION + page += FPSTR(HTTP_FORM_OTHER3); + page.replace("{r2}", (sysCfg.emulation == EMUL_NONE) ? " checked" : ""); + page.replace("{r3}", (sysCfg.emulation == EMUL_WEMO) ? " checked" : ""); + page.replace("{r4}", (sysCfg.emulation == EMUL_HUE) ? " checked" : ""); + for (int i = 1; i < Maxdevice; i++) { + page += FPSTR(HTTP_FORM_OTHER2); page.replace("{1", String(i +1)); - if (i == 0) page.replace("{2", FRIENDLY_NAME1); - else if (i == 1) page.replace("{2", FRIENDLY_NAME2); - else if (i == 2) page.replace("{2", FRIENDLY_NAME3); - else if (i == 3) page.replace("{2", FRIENDLY_NAME4); + snprintf_P(stemp, sizeof(stemp), PSTR(FRIENDLY_NAME"%d"), i +1); + page.replace("{2", stemp); page.replace("{3", String(sysCfg.friendlyname[i])); } + page += F("
"); +#endif // USE_EMULATION page += FPSTR(HTTP_FORM_END); page += FPSTR(HTTP_BTN_CONF); showPage(page); @@ -823,13 +838,16 @@ void handleSave() break; #endif // USE_DOMOTICZ case 5: - sysCfg.mqtt_enabled = webServer->hasArg("r1"); - strlcpy(sysCfg.friendlyname[0], (!strlen(webServer->arg("a1").c_str())) ? FRIENDLY_NAME1 : webServer->arg("a1").c_str(), sizeof(sysCfg.friendlyname[0])); - strlcpy(sysCfg.friendlyname[1], (!strlen(webServer->arg("a2").c_str())) ? FRIENDLY_NAME2 : webServer->arg("a2").c_str(), sizeof(sysCfg.friendlyname[1])); - strlcpy(sysCfg.friendlyname[2], (!strlen(webServer->arg("a3").c_str())) ? FRIENDLY_NAME3 : webServer->arg("a3").c_str(), sizeof(sysCfg.friendlyname[2])); - strlcpy(sysCfg.friendlyname[3], (!strlen(webServer->arg("a4").c_str())) ? FRIENDLY_NAME4 : webServer->arg("a4").c_str(), sizeof(sysCfg.friendlyname[3])); - snprintf_P(log, sizeof(log), PSTR("HTTP: Other MQTT Enable %s, Friendly Names %s, %s, %s and %s"), - (sysCfg.mqtt_enabled) ? MQTT_STATUS_ON : MQTT_STATUS_OFF, sysCfg.friendlyname[0], sysCfg.friendlyname[1], sysCfg.friendlyname[2], sysCfg.friendlyname[3]); + sysCfg.mqtt_enabled = webServer->hasArg("b1"); +#ifdef USE_EMULATION + sysCfg.emulation = (!strlen(webServer->arg("b2").c_str())) ? 0 : atoi(webServer->arg("b2").c_str()); +#endif // USE_EMULATION + strlcpy(sysCfg.friendlyname[0], (!strlen(webServer->arg("a1").c_str())) ? FRIENDLY_NAME : webServer->arg("a1").c_str(), sizeof(sysCfg.friendlyname[0])); + strlcpy(sysCfg.friendlyname[1], (!strlen(webServer->arg("a2").c_str())) ? FRIENDLY_NAME"2" : webServer->arg("a2").c_str(), sizeof(sysCfg.friendlyname[1])); + strlcpy(sysCfg.friendlyname[2], (!strlen(webServer->arg("a3").c_str())) ? FRIENDLY_NAME"3" : webServer->arg("a3").c_str(), sizeof(sysCfg.friendlyname[2])); + strlcpy(sysCfg.friendlyname[3], (!strlen(webServer->arg("a4").c_str())) ? FRIENDLY_NAME"4" : webServer->arg("a4").c_str(), sizeof(sysCfg.friendlyname[3])); + snprintf_P(log, sizeof(log), PSTR("HTTP: Other MQTT Enable %s, Emulation %d, Friendly Names %s, %s, %s and %s"), + (sysCfg.mqtt_enabled) ? MQTT_STATUS_ON : MQTT_STATUS_OFF, sysCfg.emulation, sysCfg.friendlyname[0], sysCfg.friendlyname[1], sysCfg.friendlyname[2], sysCfg.friendlyname[3]); addLog(LOG_LEVEL_INFO, log); break; case 6: @@ -1007,9 +1025,9 @@ void handleUploadLoop() _uploaderror = 1; return; } -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) +#ifdef USE_EMULATION UDP_Disconnect(); -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#endif // USE_EMULATION if (sysCfg.mqtt_enabled) mqttClient.disconnect(); snprintf_P(log, sizeof(log), PSTR("Upload: File %s ..."), upload.filename.c_str()); @@ -1262,7 +1280,7 @@ void handleRestart() /********************************************************************************************/ -#ifdef USE_WEMO_EMULATION +#ifdef USE_EMULATION void handleUPnPevent() { addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle WeMo basic event")); @@ -1281,7 +1299,7 @@ void handleUPnPservice() webServer->send(200, "text/plain", eventservice_xml); } -void handleUPnPsetup() +void handleUPnPsetupWemo() { addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle WeMo setup")); @@ -1292,11 +1310,9 @@ void handleUPnPsetup() setup_xml.replace("{x3}", wemo_serial()); webServer->send(200, "text/xml", setup_xml); } -#endif // USE_WEMO_EMULATION /********************************************************************************************/ -#ifdef USE_HUE_EMULATION String hue_deviceId(uint8_t id) { char deviceid[16]; @@ -1305,7 +1321,7 @@ String hue_deviceId(uint8_t id) return String(deviceid); } -void handleUPnPsetup() +void handleUPnPsetupHue() { addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Hue Bridge setup")); @@ -1344,13 +1360,16 @@ void hue_lights(String *path) response.replace("{state}", (power & (0x01 << (i-1))) ? "true" : "false"); response.replace("{j1}", sysCfg.friendlyname[i-1]); response.replace("{j2}", hue_deviceId(i)); + if (pin[GPIO_WS2812] < 99) { #ifdef USE_WS2812 - ws2812_replaceHSB(&response); -#else - response.replace("{h}", "0"); - response.replace("{s}", "0"); - response.replace("{b}", "0"); + ws2812_replaceHSB(&response); #endif // USE_WS2812 + } else + { + response.replace("{h}", "0"); + response.replace("{s}", "0"); + response.replace("{b}", "0"); + } } response += "}"; webServer->send(200, "application/json", response); @@ -1388,8 +1407,7 @@ void hue_lights(String *path) } } #ifdef USE_WS2812 - if ((pos=json.indexOf("\"bri\":")) >= 0) - { + if ((pin[GPIO_WS2812] < 99) && ((pos=json.indexOf("\"bri\":")) >= 0)) { bri=atoi(json.substring(pos+6).c_str()); ws2812_changeBrightness(bri); response += ","; @@ -1405,8 +1423,7 @@ void hue_lights(String *path) } else webServer->send(406, "application/json", "{}"); } - else if(path->indexOf("/lights/") >= 0) // Got /lights/ID - { + else if(path->indexOf("/lights/") >= 0) { // Got /lights/ID path->remove(0,8); // Remove /lights/ device = atoi(path->c_str()); if ((device < 1) || (device > Maxdevice)) device = 1; @@ -1414,13 +1431,16 @@ void hue_lights(String *path) response.replace("{state}", (power & (0x01 << (device -1))) ? "true" : "false"); response.replace("{j1}", sysCfg.friendlyname[device -1]); response.replace("{j2}", hue_deviceId(device)); + if (pin[GPIO_WS2812] < 99) { #ifdef USE_WS2812 - ws2812_replaceHSB(&response); -#else - response.replace("{h}", "0"); - response.replace("{s}", "0"); - response.replace("{b}", "0"); + ws2812_replaceHSB(&response); #endif // USE_WS2812 + } else + { + response.replace("{h}", "0"); + response.replace("{s}", "0"); + response.replace("{b}", "0"); + } webServer->send(200, "application/json", response); } else webServer->send(406, "application/json", "{}"); @@ -1453,7 +1473,7 @@ void handle_hue_api(String *path) webServer->send(406, "application/json", "{}"); } } -#endif // USE_HUE_EMULATION +#endif // USE_EMULATION /********************************************************************************************/ @@ -1463,33 +1483,30 @@ void handleNotFound() return; } -#ifdef USE_HUE_EMULATION +#ifdef USE_EMULATION String path = webServer->uri(); - if (path.startsWith("/api")) + if ((sysCfg.emulation == EMUL_HUE) && (path.startsWith("/api"))) { handle_hue_api(&path); - else { -#endif // USE_HUE_EMULATION - - String message = "File Not Found\n\n"; - message += "URI: "; - message += webServer->uri(); - message += "\nMethod: "; - message += ( webServer->method() == HTTP_GET ) ? "GET" : "POST"; - message += "\nArguments: "; - message += webServer->args(); - message += "\n"; - for ( uint8_t i = 0; i < webServer->args(); i++ ) { - message += " " + webServer->argName ( i ) + ": " + webServer->arg ( i ) + "\n"; - } + } else +#endif // USE_EMULATION + { + String message = "File Not Found\n\n"; + message += "URI: "; + message += webServer->uri(); + message += "\nMethod: "; + message += ( webServer->method() == HTTP_GET ) ? "GET" : "POST"; + message += "\nArguments: "; + message += webServer->args(); + message += "\n"; + for ( uint8_t i = 0; i < webServer->args(); i++ ) { + message += " " + webServer->argName ( i ) + ": " + webServer->arg ( i ) + "\n"; + } - webServer->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - webServer->sendHeader("Pragma", "no-cache"); - webServer->sendHeader("Expires", "-1"); - webServer->send(404, "text/plain", message); -#ifdef USE_HUE_EMULATION - addLog_P(LOG_LEVEL_DEBUG_MORE, message.c_str()); + webServer->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + webServer->sendHeader("Pragma", "no-cache"); + webServer->sendHeader("Expires", "-1"); + webServer->send(404, "text/plain", message); } -#endif // USE_HUE_EMULATION } /* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */ @@ -1517,5 +1534,4 @@ boolean isIp(String str) } return true; } - #endif // USE_WEBSERVER diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino index 7f2e47752..38d379c48 100644 --- a/sonoff/xdrv_wemohue.ino +++ b/sonoff/xdrv_wemohue.ino @@ -23,7 +23,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) +#ifdef USE_EMULATION #define UDP_BUFFER_SIZE 200 // Max UDP buffer size needed for M-SEARCH message @@ -33,7 +33,6 @@ char packetBuffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP packet IPAddress ipMulticast(239, 255, 255, 250); // Simple Service Discovery Protocol (SSDP) uint32_t portMulticast = 1900; // Multicast address and port -#ifdef USE_WEMO_EMULATION /*********************************************************************************************\ * WeMo UPNP support routines \*********************************************************************************************/ @@ -83,9 +82,7 @@ void wemo_respondToMSearch() message, portUDP.remoteIP().toString().c_str(), portUDP.remotePort()); addLog(LOG_LEVEL_DEBUG, log); } -#endif // USE_WEMO_EMULATION -#ifdef USE_HUE_EMULATION /*********************************************************************************************\ * Hue Bridge UPNP support routines * Need to send 3 response packets with varying ST and USN @@ -174,11 +171,9 @@ void hue_respondToMSearch() message, portUDP.remoteIP().toString().c_str(), portUDP.remotePort()); addLog(LOG_LEVEL_DEBUG, log); } -#endif // USE_HUE_EMULATION /********************************************************************************************/ -#if defined(USE_WEMO_EMULATION) || defined(USE_HUE_EMULATION) boolean UDP_Disconnect() { if (udpConnected) { @@ -212,22 +207,15 @@ void pollUDP() String request = packetBuffer; // addLog_P(LOG_LEVEL_DEBUG_MORE, packetBuffer); if (request.indexOf("M-SEARCH") >= 0) { -#ifdef USE_WEMO_EMULATION - if (request.indexOf("urn:Belkin:device:**") > 0) { + if ((sysCfg.emulation == EMUL_WEMO) &&(request.indexOf("urn:Belkin:device:**") > 0)) { wemo_respondToMSearch(); } -#endif // USE_WEMO_EMULATION -#ifdef USE_HUE_EMULATION - if (request.indexOf("ST: urn:schemas-upnp-org:device:basic:1") > 0 || - request.indexOf("ST: upnp:rootdevice") > 0 || - request.indexOf("ST: ssdp:all") > 0) { + else if ((sysCfg.emulation == EMUL_HUE) && ((request.indexOf("ST: urn:schemas-upnp-org:device:basic:1") > 0) || (request.indexOf("ST: upnp:rootdevice") > 0) || (request.indexOf("ST: ssdp:all") > 0))) { hue_respondToMSearch(); } -#endif // USE_HUE_EMULATION } } } } -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION -#endif // USE_WEMO_EMULATION || USE_HUE_EMULATION +#endif // USE_EMULATION