Skip to content

Commit

Permalink
(2.4.3) Fixed Alexa apps and groups issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Aircoookie committed Jun 3, 2019
1 parent cae0de6 commit 9d57e2c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 38 deletions.
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=Espalexa
version=2.4.2
version=2.4.3
author=Christian Schwinne
maintainer=Christian Schwinne
sentence=Library to control an ESP module with the Alexa voice assistant
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Here is an overview of the devices (light types) Espalexa can emulate:
| EspalexaDeviceType::whitespectrum | Color temperature adjustment not working on Dot |
| EspalexaDeviceType::color | Works as intended (dimming + color) |
| EspalexaDeviceType::extendedcolor | Color temperature adjustment not working on Dot |
| EspalexaDeviceType::onoff (experimental) | No control from app possible, only voice |
| EspalexaDeviceType::onoff (experimental) | Works, but is treated as dimmable by Alexa |
See the example `EspalexaFullyFeatured` to learn how to define each device type and use the new EspalexaDevice pointer callback function type!
Expand Down
89 changes: 53 additions & 36 deletions src/Espalexa.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/
/*
* @title Espalexa library
* @version 2.4.2
* @version 2.4.3
* @author Christian Schwinne
* @license MIT
* @contributors d-999
Expand Down Expand Up @@ -49,7 +49,7 @@
#include <WiFiUdp.h>

#ifdef ESPALEXA_DEBUG
#pragma message "Espalexa 2.4.2 debug mode"
#pragma message "Espalexa 2.4.3 debug mode"
#define EA_DEBUG(x) Serial.print (x)
#define EA_DEBUGLN(x) Serial.println (x)
#else
Expand Down Expand Up @@ -121,11 +121,25 @@ class Espalexa {
return "Plug";
}

//Workaround functions courtesy of Sonoff-Tasmota
uint32_t encodeLightId(uint8_t idx)
{
uint8_t mac[6];
WiFi.macAddress(mac);
uint32_t id = (mac[3] << 20) | (mac[4] << 12) | (mac[5] << 4) | (idx & 0xF);
return id;
}

uint32_t decodeLightId(uint32_t id) {
return id & 0xF;
}

//device JSON string: color+temperature device emulates LCT015, dimmable device LWB010, (TODO: on/off Plug 01, color temperature device LWT010, color device LST001)
String deviceJsonString(uint8_t deviceId)
{
if (deviceId < 1 || deviceId > currentDeviceCount) return "{}"; //error
EspalexaDevice* dev = devices[deviceId-1];
deviceId--;
if (deviceId >= currentDeviceCount) return "{}"; //error
EspalexaDevice* dev = devices[deviceId];

String json = "{\"state\":{\"on\":";
json += boolString(dev->getValue());
Expand All @@ -149,8 +163,8 @@ class Espalexa {
json += "\",\"name\":\"" + dev->getName();
json += "\",\"modelid\":\"" + modelidString(dev->getType());
json += "\",\"manufacturername\":\"Philips\",\"productname\":\"E" + String(static_cast<uint8_t>(dev->getType()));
json += "\",\"uniqueid\":\""+ WiFi.macAddress() +"-"+ (deviceId+1);
json += "\",\"swversion\":\"espalexa-2.4.2\"}";
json += "\",\"uniqueid\":\"" + String(encodeLightId(deviceId+1));
json += "\",\"swversion\":\"espalexa-2.4.3\"}";

return json;
}
Expand All @@ -174,7 +188,7 @@ class Espalexa {
}
res += "\r\nFree Heap: " + (String)ESP.getFreeHeap();
res += "\r\nUptime: " + (String)millis();
res += "\r\n\r\nEspalexa library v2.4.2 by Christian Schwinne 2019";
res += "\r\n\r\nEspalexa library v2.4.3 by Christian Schwinne 2019";
server->send(200, "text/plain", res);
}
#endif
Expand Down Expand Up @@ -219,15 +233,6 @@ class Espalexa {
"<serialNumber>"+ escapedMac +"</serialNumber>"
"<UDN>uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"</UDN>"
"<presentationURL>index.html</presentationURL>"
"<iconList>"
" <icon>"
" <mimetype>image/png</mimetype>"
" <height>48</height>"
" <width>48</width>"
" <depth>24</depth>"
" <url>hue_logo_0.png</url>"
" </icon>"
"</iconList>"
"</device>"
"</root>";

Expand Down Expand Up @@ -450,58 +455,63 @@ class Espalexa {
{
server->send(200, "application/json", "[{\"success\":true}]"); //short valid response

int devId = req.substring(req.indexOf("lights")+7).toInt();
uint32_t devId = req.substring(req.indexOf("lights")+7).toInt();
EA_DEBUG("ls"); EA_DEBUGLN(devId);
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::none);
devId = decodeLightId(devId);
EA_DEBUGLN(devId);
devId--; //zero-based for devices array
if (devId >= currentDeviceCount) return true; //return if invalid ID

devices[devId]->setPropertyChanged(EspalexaDeviceProperty::none);

if (body.indexOf("false")>0) //OFF command
{
devices[devId-1]->setValue(0);
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::off);
devices[devId-1]->doCallback();
devices[devId]->setValue(0);
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::off);
devices[devId]->doCallback();
return true;
}

if (body.indexOf("true") >0) //ON command
{
devices[devId-1]->setValue(devices[devId-1]->getLastValue());
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::on);
devices[devId]->setValue(devices[devId]->getLastValue());
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::on);
}

if (body.indexOf("bri") >0) //BRIGHTNESS command
{
uint8_t briL = body.substring(body.indexOf("bri") +5).toInt();
if (briL == 255)
{
devices[devId-1]->setValue(255);
devices[devId]->setValue(255);
} else {
devices[devId-1]->setValue(briL+1);
devices[devId]->setValue(briL+1);
}
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::bri);
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::bri);
}

if (body.indexOf("xy") >0) //COLOR command (XY mode)
{
devices[devId-1]->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::xy);
devices[devId]->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::xy);
}

if (body.indexOf("hue") >0) //COLOR command (HS mode)
{
devices[devId-1]->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt());
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::hs);
devices[devId]->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt());
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::hs);
}

if (body.indexOf("ct") >0) //COLOR TEMP command (white spectrum)
{
devices[devId-1]->setColor(body.substring(body.indexOf("ct") +4).toInt());
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::ct);
devices[devId]->setColor(body.substring(body.indexOf("ct") +4).toInt());
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::ct);
}

devices[devId-1]->doCallback();
devices[devId]->doCallback();

#ifdef ESPALEXA_DEBUG
if (devices[devId-1]->getLastChangedProperty() == EspalexaDeviceProperty::none)
if (devices[devId]->getLastChangedProperty() == EspalexaDeviceProperty::none)
EA_DEBUGLN("STATE REQ WITHOUT BODY (likely Content-Type issue #6)");
#endif
return true;
Expand All @@ -519,15 +529,22 @@ class Espalexa {
String jsonTemp = "{";
for (int i = 0; i<currentDeviceCount; i++)
{
jsonTemp += "\"" + String(i+1) + "\":";
jsonTemp += "\"" + String(encodeLightId(i+1)) + "\":";
jsonTemp += deviceJsonString(i+1);
if (i < currentDeviceCount-1) jsonTemp += ",";
}
jsonTemp += "}";
server->send(200, "application/json", jsonTemp);
} else //client wants one light (devId)
{
server->send(200, "application/json", deviceJsonString(devId));
devId = decodeLightId(devId);
EA_DEBUGLN(devId);
if (devId > currentDeviceCount)
{
server->send(200, "application/json", "{}");
} else {
server->send(200, "application/json", deviceJsonString(devId));
}
}

return true;
Expand Down

0 comments on commit 9d57e2c

Please sign in to comment.