Fix Alexa bug in discovery

This commit is contained in:
Stephan Hadinger 2022-01-17 18:36:13 +01:00
parent 342af3d466
commit 21dd58e59f
5 changed files with 59 additions and 41 deletions

View File

@ -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);

View File

@ -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<Z_Data_Light>(0);
if (&light != nullptr) {
if (&light != &z_data_unk) {
return light.getConfig();
} else {
return -1;

View File

@ -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<Z_Data_Light>(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<Z_Data_OnOff>(ep);
return (&onoff != nullptr);
return (&onoff != &z_data_unk);
}
bool Z_Device::getPower(uint8_t ep) const {
const Z_Data_OnOff & onoff = data.find<Z_Data_OnOff>(ep);
if (&onoff != nullptr) return onoff.getPower();
if (&onoff != &z_data_unk) return onoff.getPower();
return false;
}

View File

@ -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<Z_Data_Light>();
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

View File

@ -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<Z_Data_Light>(_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
}