Fixed Alexa discovery
This commit is contained in:
parent
c9cd7b087a
commit
c277ebb43e
@ -2,6 +2,10 @@
|
||||
|
||||
### Development versions after 0.11.0 release
|
||||
|
||||
#### Build 2012160
|
||||
|
||||
- Bump Espalexa to 2.5.0, fixing discovery (PR Espalexa/#152, originally PR #1497)
|
||||
|
||||
#### Build 2012150
|
||||
|
||||
- Added Blends FX (PR #1491)
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
/*
|
||||
* @title Espalexa library
|
||||
* @version 2.4.6
|
||||
* @version 2.5.0
|
||||
* @author Christian Schwinne
|
||||
* @license MIT
|
||||
* @contributors d-999
|
||||
@ -50,7 +50,7 @@
|
||||
#include "../network/Network.h"
|
||||
|
||||
#ifdef ESPALEXA_DEBUG
|
||||
#pragma message "Espalexa 2.4.6 debug mode"
|
||||
#pragma message "Espalexa 2.5.0 debug mode"
|
||||
#define EA_DEBUG(x) Serial.print (x)
|
||||
#define EA_DEBUGLN(x) Serial.println (x)
|
||||
#else
|
||||
@ -60,6 +60,7 @@
|
||||
|
||||
#include "EspalexaDevice.h"
|
||||
|
||||
#define DEVICE_UNIQUE_ID_LENGTH 12
|
||||
|
||||
class Espalexa {
|
||||
private:
|
||||
@ -116,17 +117,24 @@ private:
|
||||
return "";
|
||||
}
|
||||
|
||||
//Workaround functions courtesy of Sonoff-Tasmota
|
||||
uint32_t encodeLightId(uint8_t idx)
|
||||
void encodeLightId(uint8_t idx, char* out)
|
||||
{
|
||||
//Unique id must be 12 character len
|
||||
//use the last 10 characters of the MAC followed by the device id in hex value
|
||||
//uniqueId: aabbccddeeii
|
||||
|
||||
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;
|
||||
//shift the mac address to the left (discard first byte)
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
mac[i] = mac[i+1];
|
||||
}
|
||||
mac[5] = idx;
|
||||
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
sprintf(out + i*2, "%.2x", mac[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//device JSON string: color+temperature device emulates LCT015, dimmable device LWB010, (TODO: on/off Plug 01, color temperature device LWT010, color device LST001)
|
||||
@ -136,10 +144,8 @@ private:
|
||||
if (deviceId >= currentDeviceCount) {strcpy(buf,"{}"); return;} //error
|
||||
EspalexaDevice* dev = devices[deviceId];
|
||||
|
||||
//char buf_bri[12] = "";
|
||||
//brightness support, add "bri" to JSON
|
||||
//if (dev->getType() != EspalexaDeviceType::onoff)
|
||||
// sprintf(buf_bri,",\"bri\":%u", dev->getLastValue()-1);
|
||||
char buf_lightid[13];
|
||||
encodeLightId(deviceId + 1, buf_lightid);
|
||||
|
||||
char buf_col[80] = "";
|
||||
//color support
|
||||
@ -161,10 +167,10 @@ private:
|
||||
|
||||
sprintf_P(buf, PSTR("{\"state\":{\"on\":%s,\"bri\":%u%s%s,\"alert\":\"none%s\",\"mode\":\"homeautomation\",\"reachable\":true},"
|
||||
"\"type\":\"%s\",\"name\":\"%s\",\"modelid\":\"%s\",\"manufacturername\":\"Philips\",\"productname\":\"E%u"
|
||||
"\",\"uniqueid\":\"%u\",\"swversion\":\"espalexa-2.4.6\"}")
|
||||
"\",\"uniqueid\":\"%s\",\"swversion\":\"espalexa-2.5.0\"}")
|
||||
|
||||
, (dev->getValue())?"true":"false", dev->getLastValue()-1, buf_col, buf_ct, buf_cm, typeString(dev->getType()),
|
||||
dev->getName().c_str(), modelidString(dev->getType()), static_cast<uint8_t>(dev->getType()), encodeLightId(deviceId+1));
|
||||
dev->getName().c_str(), modelidString(dev->getType()), static_cast<uint8_t>(dev->getType()), buf_lightid);
|
||||
}
|
||||
|
||||
//Espalexa status page /espalexa
|
||||
@ -186,7 +192,7 @@ private:
|
||||
}
|
||||
res += "\r\nFree Heap: " + (String)ESP.getFreeHeap();
|
||||
res += "\r\nUptime: " + (String)millis();
|
||||
res += "\r\n\r\nEspalexa library v2.4.6 by Christian Schwinne 2020";
|
||||
res += "\r\n\r\nEspalexa library v2.5.0 by Christian Schwinne 2020";
|
||||
server->send(200, "text/plain", res);
|
||||
}
|
||||
#endif
|
||||
@ -222,7 +228,7 @@ private:
|
||||
"<URLBase>http://%s:80/</URLBase>"
|
||||
"<device>"
|
||||
"<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>"
|
||||
"<friendlyName>Espalexa (%s)</friendlyName>"
|
||||
"<friendlyName>Espalexa (%s:80)</friendlyName>"
|
||||
"<manufacturer>Royal Philips Electronics</manufacturer>"
|
||||
"<manufacturerURL>http://www.philips.com</manufacturerURL>"
|
||||
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>"
|
||||
@ -237,8 +243,8 @@ private:
|
||||
|
||||
server->send(200, "text/xml", buf);
|
||||
|
||||
EA_DEBUG("Send setup.xml");
|
||||
//EA_DEBUGLN(setup_xml);
|
||||
EA_DEBUGLN("Send setup.xml");
|
||||
EA_DEBUGLN(buf);
|
||||
}
|
||||
|
||||
//init the server
|
||||
@ -298,7 +304,7 @@ private:
|
||||
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.17.0\r\n" // _modelName, _modelNumber
|
||||
"hue-bridgeid: %s\r\n"
|
||||
"ST: urn:schemas-upnp-org:device:basic:1\r\n" // _deviceType
|
||||
"USN: uuid:2f402f80-da50-11e1-9b23-%s::ssdp:all\r\n" // _uuid::_deviceType
|
||||
"USN: uuid:2f402f80-da50-11e1-9b23-%s::upnp:rootdevice\r\n" // _uuid::_deviceType
|
||||
"\r\n"),s,escapedMac.c_str(),escapedMac.c_str());
|
||||
|
||||
espalexaUdp.beginPacket(espalexaUdp.remoteIP(), espalexaUdp.remotePort());
|
||||
@ -359,24 +365,28 @@ public:
|
||||
|
||||
if (!udpConnected) return;
|
||||
int packetSize = espalexaUdp.parsePacket();
|
||||
if (!packetSize) return; //no new udp packet
|
||||
if (packetSize < 1) return; //no new udp packet
|
||||
|
||||
EA_DEBUGLN("Got UDP!");
|
||||
char packetBuffer[255]; //buffer to hold incoming udp packet
|
||||
uint16_t len = espalexaUdp.read(packetBuffer, 254);
|
||||
if (len > 0) {
|
||||
packetBuffer[len] = 0;
|
||||
}
|
||||
|
||||
unsigned char packetBuffer[packetSize+1]; //buffer to hold incoming udp packet
|
||||
espalexaUdp.read(packetBuffer, packetSize);
|
||||
packetBuffer[packetSize] = 0;
|
||||
|
||||
espalexaUdp.flush();
|
||||
if (!discoverable) return; //do not reply to M-SEARCH if not discoverable
|
||||
|
||||
String request = packetBuffer;
|
||||
if(request.indexOf("M-SEARCH") >= 0) {
|
||||
EA_DEBUGLN(request);
|
||||
if(request.indexOf("upnp:rootdevice") > 0 || request.indexOf("asic:1") > 0 || request.indexOf("ssdp:all") > 0) {
|
||||
EA_DEBUGLN("Responding search req...");
|
||||
respondToSearch();
|
||||
}
|
||||
const char* request = (const char *) packetBuffer;
|
||||
if (strstr(request, "M-SEARCH") == nullptr) return;
|
||||
|
||||
EA_DEBUGLN(request);
|
||||
if (strstr(request, "ssdp:disc") != nullptr && //short for "ssdp:discover"
|
||||
(strstr(request, "upnp:rootd") != nullptr || //short for "upnp:rootdevice"
|
||||
strstr(request, "ssdp:all") != nullptr ||
|
||||
strstr(request, "asic:1") != nullptr )) //short for "device:basic:1"
|
||||
{
|
||||
EA_DEBUGLN("Responding search req...");
|
||||
respondToSearch();
|
||||
}
|
||||
}
|
||||
|
||||
@ -452,13 +462,12 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (req.indexOf("state") > 0) //client wants to control light
|
||||
if ((req.indexOf("state") > 0) && (body.length() > 0)) //client wants to control light
|
||||
{
|
||||
server->send(200, "application/json", F("[{\"success\":{\"/lights/1/state/\": true}}]"));
|
||||
|
||||
uint32_t devId = req.substring(req.indexOf("lights")+7).toInt();
|
||||
EA_DEBUG("ls"); EA_DEBUGLN(devId);
|
||||
devId = decodeLightId(devId);
|
||||
EA_DEBUGLN(devId);
|
||||
devId--; //zero-based for devices array
|
||||
if (devId >= currentDeviceCount) return true; //return if invalid ID
|
||||
@ -530,7 +539,7 @@ public:
|
||||
String jsonTemp = "{";
|
||||
for (int i = 0; i<currentDeviceCount; i++)
|
||||
{
|
||||
jsonTemp += "\"" + String(encodeLightId(i+1)) + "\":";
|
||||
jsonTemp += "\"" + String(i+1) + "\":";
|
||||
char buf[512];
|
||||
deviceJsonString(i+1, buf);
|
||||
jsonTemp += buf;
|
||||
@ -540,7 +549,6 @@ public:
|
||||
server->send(200, "application/json", jsonTemp);
|
||||
} else //client wants one light (devId)
|
||||
{
|
||||
devId = decodeLightId(devId);
|
||||
EA_DEBUGLN(devId);
|
||||
if (devId > currentDeviceCount)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2012150
|
||||
#define VERSION 2012160
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
|
Loading…
Reference in New Issue
Block a user