From 21dd58e59fa8a632140d90c508aba81ef4cd48f3 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 17 Jan 2022 18:36:13 +0100 Subject: [PATCH] Fix Alexa bug in discovery --- tasmota/xdrv_20_hue.ino | 44 +++++++++++++-------- tasmota/xdrv_23_zigbee_2_devices.ino | 2 +- tasmota/xdrv_23_zigbee_2a_devices_impl.ino | 6 +-- tasmota/xdrv_23_zigbee_3_hue.ino | 46 +++++++++++++--------- tasmota/xdrv_23_zigbee_5_converters.ino | 2 +- 5 files changed, 59 insertions(+), 41 deletions(-) diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index 55d994439..34af5420a 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -676,7 +676,7 @@ void HueGlobalConfig(String *path) { CheckHue(&response, appending); #endif // USE_LIGHT #ifdef USE_ZIGBEE - ZigbeeCheckHue(&response, appending); + ZigbeeCheckHue(response, &appending); #endif // USE_ZIGBEE response += F("},\"groups\":{},\"schedules\":{},\"config\":"); HueConfigResponse(&response); @@ -914,42 +914,44 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { } #endif // USE_LIGHT -void HueLights(String *path) +void HueLights(String *path_req) { /* * http://tasmota/api/username/lights/1/state?1={"on":true,"hue":56100,"sat":254,"bri":254,"alert":"none","transitiontime":40} */ String response; - int code = 200; + int32_t code = 200; uint8_t device = 1; uint32_t device_id; // the raw device_id used by Hue emulation uint8_t maxhue = (TasmotaGlobal.devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : TasmotaGlobal.devices_present; + path_req->remove(0,path_req->indexOf(F("/lights"))); // Remove until /lights + String path(*path_req); - path->remove(0,path->indexOf(F("/lights"))); // Remove until /lights - if (path->endsWith(F("/lights"))) { // Got /lights + if (path.endsWith(F("/lights"))) { // Got /lights response = F("{"); bool appending = false; #ifdef USE_LIGHT CheckHue(&response, appending); #endif // USE_LIGHT #ifdef USE_ZIGBEE - ZigbeeCheckHue(&response, appending); + ZigbeeCheckHue(response, &appending); #endif // USE_ZIGBEE #ifdef USE_SCRIPT_HUE Script_Check_Hue(&response); #endif response += F("}"); } - else if (path->endsWith(F("/state"))) { // Got ID/state - path->remove(0,8); // Remove /lights/ - path->remove(path->indexOf(F("/state"))); // Remove /state - device_id = atoi(path->c_str()); + else if (path.endsWith(F("/state"))) { // Got ID/state + path.remove(0,8); // Remove /lights/ + path.remove(path.indexOf(F("/state"))); // Remove /state + device_id = atoi(path.c_str()); device = DecodeLightId(device_id); #ifdef USE_ZIGBEE uint16_t shortaddr; device = DecodeLightId(device_id, &shortaddr); if (shortaddr) { - return ZigbeeHandleHue(shortaddr, device_id, response); + code = ZigbeeHandleHue(shortaddr, device_id, response); + goto exit; } #endif // USE_ZIGBEE @@ -965,16 +967,16 @@ void HueLights(String *path) #endif // USE_LIGHT } - else if(path->indexOf(F("/lights/")) >= 0) { // Got /lights/ID - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("/lights path=%s"), path->c_str()); - path->remove(0,8); // Remove /lights/ - device_id = atoi(path->c_str()); + else if(path.indexOf(F("/lights/")) >= 0) { // Got /lights/ID + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("/lights path=%s"), path.c_str()); + path.remove(0,8); // Remove /lights/ + device_id = atoi(path.c_str()); device = DecodeLightId(device_id); #ifdef USE_ZIGBEE uint16_t shortaddr; device = DecodeLightId(device_id, &shortaddr); if (shortaddr) { - ZigbeeHueStatus(&response, shortaddr); + code = ZigbeeHueStatus(&response, shortaddr); goto exit; } #endif // USE_ZIGBEE @@ -1000,6 +1002,14 @@ void HueLights(String *path) code = 406; } exit: + if (code < 0) { + response = F("{\"error\":{\"type\":"); + response += -code; + response += F(",\"address\":\""); + response += *path_req; + response += F("\",\"description\":\"\"}}"); + code = 200; + } AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str()); WSSend(code, CT_APP_JSON, response); } @@ -1011,7 +1021,7 @@ void HueGroups(String *path) */ String response(F("{}")); uint8_t maxhue = (TasmotaGlobal.devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : TasmotaGlobal.devices_present; - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " HueGroups (%s)"), path->c_str()); + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " HueGroups (%s)"), path.c_str()); if (path->endsWith(F("/0"))) { UnishoxStrings msg(HUE_LIGHTS); diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 23004f9db..9ae8114f7 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -823,7 +823,7 @@ public: // If light, returns the number of channels, or 0xFF if unknown int8_t getLightChannels(void) const { const Z_Data_Light & light = data.find(0); - if (&light != nullptr) { + if (&light != &z_data_unk) { return light.getConfig(); } else { return -1; diff --git a/tasmota/xdrv_23_zigbee_2a_devices_impl.ino b/tasmota/xdrv_23_zigbee_2a_devices_impl.ino index 543916efa..77027fc91 100644 --- a/tasmota/xdrv_23_zigbee_2a_devices_impl.ino +++ b/tasmota/xdrv_23_zigbee_2a_devices_impl.ino @@ -744,7 +744,7 @@ void Z_Device::jsonLightState(Z_attribute_list & attr_list) const { if (validPower()) { attr_list.addAttributePMEM(PSTR("Power")).setUInt(getPower()); } int32_t light_mode = -1; const Z_Data_Light & light = data.find(0); - if (&light != nullptr) { + if (&light != &z_data_unk) { if (light.validConfig()) { light_mode = light.getConfig(); } @@ -912,12 +912,12 @@ void Z_Device::setPower(bool power_on, uint8_t ep) { bool Z_Device::validPower(uint8_t ep) const { const Z_Data_OnOff & onoff = data.find(ep); - return (&onoff != nullptr); + return (&onoff != &z_data_unk); } bool Z_Device::getPower(uint8_t ep) const { const Z_Data_OnOff & onoff = data.find(ep); - if (&onoff != nullptr) return onoff.getPower(); + if (&onoff != &z_data_unk) return onoff.getPower(); return false; } diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino index 01b7a5fda..ff3b637c1 100644 --- a/tasmota/xdrv_23_zigbee_3_hue.ino +++ b/tasmota/xdrv_23_zigbee_3_hue.ino @@ -42,7 +42,7 @@ void HueLightStatus1Zigbee(uint16_t shortaddr, uint8_t local_light_subtype, Stri const Z_Device & device = zigbee_devices.findShortAddr(shortaddr); const Z_Data_Light & light = device.data.find(); - if (&light != nullptr) { + if (&light != &z_data_unk) { bri = light.getDimmer(); colormode = light.getColorMode(); sat = light.getSat(); @@ -112,13 +112,19 @@ void HueLightStatus2Zigbee(uint16_t shortaddr, String *response) free(buf); } -void ZigbeeHueStatus(String * response, uint16_t shortaddr) { - *response += F("{\"state\":"); - HueLightStatus1Zigbee(shortaddr, zigbee_devices.getHueBulbtype(shortaddr), response); - HueLightStatus2Zigbee(shortaddr, response); +int32_t ZigbeeHueStatus(String * response, uint16_t shortaddr) { + int8_t bulbtype = zigbee_devices.getHueBulbtype(shortaddr); + if (bulbtype >= 0) { // respond only if eligible + *response += F("{\"state\":"); + HueLightStatus1Zigbee(shortaddr, zigbee_devices.getHueBulbtype(shortaddr), response); + HueLightStatus2Zigbee(shortaddr, response); + return 200; + } else { + return -3; + } } -void ZigbeeCheckHue(String * response, bool &appending) { +void ZigbeeCheckHue(String & response, bool * appending) { uint32_t zigbee_num = zigbee_devices.devicesSize(); for (uint32_t i = 0; i < zigbee_num; i++) { uint16_t shortaddr = zigbee_devices.devicesAt(i).shortaddr; @@ -126,13 +132,13 @@ void ZigbeeCheckHue(String * response, bool &appending) { if (bulbtype >= 0) { // this bulb is advertized - if (appending) { *response += ","; } - *response += "\""; - *response += EncodeLightId(0, shortaddr); - *response += F("\":{\"state\":"); - HueLightStatus1Zigbee(shortaddr, bulbtype, response); // TODO - HueLightStatus2Zigbee(shortaddr, response); - appending = true; + if (*appending) { response += ","; } + response += "\""; + response += EncodeLightId(0, shortaddr); + response += F("\":{\"state\":"); + HueLightStatus1Zigbee(shortaddr, bulbtype, &response); // TODO + HueLightStatus2Zigbee(shortaddr, &response); + *appending = true; } } } @@ -223,16 +229,20 @@ void ZigbeeHueHS(uint16_t shortaddr, uint16_t hue, uint8_t sat) { light.setHue(hue); } -void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) { +int32_t ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) { uint8_t bri, sat; uint16_t ct, hue; int code = 200; + int8_t bulbtype = zigbee_devices.getHueBulbtype(shortaddr); + if (bulbtype < 0) { // respond only if eligible + response = F("{}"); + return 200; + } + bool resp = false; // is the response non null (add comma between parameters) bool on = false; - uint8_t bulbtype = zigbee_devices.getHueBulbtype(shortaddr); - const size_t buf_size = 100; char * buf = (char*) malloc(buf_size); UnishoxStrings msg(HUE_LIGHTS); @@ -368,10 +378,8 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) { else { response = msg[HUE_ERROR_JSON]; } - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str()); - WSSend(code, CT_APP_JSON, response); - free(buf); + return 200; } #endif // USE_WEBSERVER && USE_EMULATION && USE_EMULATION_HUE diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index f2d3334eb..805297380 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1353,7 +1353,7 @@ void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) { uint8_t brightness = 255; if (device.valid()) { const Z_Data_Light & light = device.data.find(_srcendpoint); - if ((&light != nullptr) && (light.validDimmer())) { + if ((&light != &z_data_unk) && (light.validDimmer())) { // Dimmer has a valid value brightness = changeUIntScale(light.getDimmer(), 0, 254, 0, 255); // range is 0..255 }