temporary state of new ssdp implementation
This commit is contained in:
parent
4f8f5e7e3a
commit
78b344f437
@ -1,8 +0,0 @@
|
||||
#ifndef CALLBACKFUNCTION_H
|
||||
#define CALLBACKFUNCTION_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
typedef void (*CallbackFunction) ();
|
||||
|
||||
#endif
|
@ -1,23 +0,0 @@
|
||||
https://github.com/kakopappa/arduino-esp8266-alexa-multiple-wemo-switch
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,211 +0,0 @@
|
||||
#include "Switch.h"
|
||||
#include "CallbackFunction.h"
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_PRINT(x) Serial.print (x)
|
||||
#define DEBUG_PRINTLN(x) Serial.println (x)
|
||||
#define DEBUG_PRINTF(x) Serial.printf (x)
|
||||
#else
|
||||
#define DEBUG_PRINT(x)
|
||||
#define DEBUG_PRINTLN(x)
|
||||
#define DEBUG_PRINTF(x)
|
||||
#endif
|
||||
|
||||
//<<constructor>>
|
||||
Switch::Switch(){
|
||||
DEBUG_PRINTLN("default constructor called");
|
||||
}
|
||||
//Switch::Switch(String alexaInvokeName,unsigned int port){
|
||||
Switch::Switch(String alexaInvokeName, unsigned int port, CallbackFunction oncb, CallbackFunction offcb){
|
||||
uint32_t chipId = ESP.getChipId();
|
||||
char uuid[64];
|
||||
sprintf_P(uuid, PSTR("38323636-4558-4dda-9188-cda0e6%02x%02x%02x"),
|
||||
(uint16_t) ((chipId >> 16) & 0xff),
|
||||
(uint16_t) ((chipId >> 8) & 0xff),
|
||||
(uint16_t) chipId & 0xff);
|
||||
|
||||
serial = String(uuid);
|
||||
persistent_uuid = "Socket-1_0-" + serial+"-"+ String(port);
|
||||
|
||||
device_name = alexaInvokeName;
|
||||
localPort = port;
|
||||
onCallback = oncb;
|
||||
offCallback = offcb;
|
||||
|
||||
startWebServer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//<<destructor>>
|
||||
Switch::~Switch(){/*nothing to destruct*/}
|
||||
|
||||
void Switch::serverLoop(){
|
||||
if (server != NULL) {
|
||||
server->handleClient();
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
void Switch::startWebServer(){
|
||||
server = new ESP8266WebServer(localPort);
|
||||
|
||||
server->on("/", [&]() {
|
||||
handleRoot();
|
||||
});
|
||||
|
||||
|
||||
server->on("/setup.xml", [&]() {
|
||||
handleSetupXml();
|
||||
});
|
||||
|
||||
server->on("/upnp/control/basicevent1", [&]() {
|
||||
handleUpnpControl();
|
||||
});
|
||||
|
||||
server->on("/eventservice.xml", [&]() {
|
||||
handleEventservice();
|
||||
});
|
||||
|
||||
//server->onNotFound(handleNotFound);
|
||||
server->begin();
|
||||
|
||||
DEBUG_PRINTLN("WebServer started on port: ");
|
||||
DEBUG_PRINTLN(localPort);
|
||||
}
|
||||
|
||||
void Switch::handleEventservice(){
|
||||
DEBUG_PRINTLN(" ########## Responding to eventservice.xml ... ########\n");
|
||||
|
||||
String eventservice_xml = "<?scpd xmlns=\"urn:Belkin:service-1-0\"?>"
|
||||
"<actionList>"
|
||||
"<action>"
|
||||
"<name>SetBinaryState</name>"
|
||||
"<argumentList>"
|
||||
"<argument>"
|
||||
"<retval/>"
|
||||
"<name>BinaryState</name>"
|
||||
"<relatedStateVariable>BinaryState</relatedStateVariable>"
|
||||
"<direction>in</direction>"
|
||||
"</argument>"
|
||||
"</argumentList>"
|
||||
"<serviceStateTable>"
|
||||
"<stateVariable sendEvents=\"yes\">"
|
||||
"<name>BinaryState</name>"
|
||||
"<dataType>Boolean</dataType>"
|
||||
"<defaultValue>0</defaultValue>"
|
||||
"</stateVariable>"
|
||||
"<stateVariable sendEvents=\"yes\">"
|
||||
"<name>level</name>"
|
||||
"<dataType>string</dataType>"
|
||||
"<defaultValue>0</defaultValue>"
|
||||
"</stateVariable>"
|
||||
"</serviceStateTable>"
|
||||
"</action>"
|
||||
"</scpd>\r\n"
|
||||
"\r\n";
|
||||
|
||||
server->send(200, "text/plain", eventservice_xml.c_str());
|
||||
}
|
||||
|
||||
void Switch::handleUpnpControl(){
|
||||
DEBUG_PRINTLN("########## Responding to /upnp/control/basicevent1 ... ##########");
|
||||
|
||||
//for (int x=0; x <= HTTP.args(); x++) {
|
||||
// DEBUG_PRINTLN(HTTP.arg(x));
|
||||
//}
|
||||
|
||||
String request = server->arg(0);
|
||||
DEBUG_PRINT("request:");
|
||||
DEBUG_PRINTLN(request);
|
||||
|
||||
if(request.indexOf("<BinaryState>1</BinaryState>") > 0) {
|
||||
DEBUG_PRINTLN("Got Turn on request");
|
||||
onCallback();
|
||||
}
|
||||
|
||||
if(request.indexOf("<BinaryState>0</BinaryState>") > 0) {
|
||||
DEBUG_PRINTLN("Got Turn off request");
|
||||
offCallback();
|
||||
}
|
||||
|
||||
server->send(200, "text/plain", "");
|
||||
}
|
||||
|
||||
void Switch::handleRoot(){
|
||||
server->send(200, "text/plain", "You should tell Alexa to discover devices");
|
||||
}
|
||||
|
||||
void Switch::handleSetupXml(){
|
||||
DEBUG_PRINTLN(" ########## Responding to setup.xml ... ########\n");
|
||||
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
char s[16];
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
String setup_xml = "<?xml version=\"1.0\"?>"
|
||||
"<root>"
|
||||
"<device>"
|
||||
"<deviceType>urn:Belkin:device:controllee:1</deviceType>"
|
||||
"<friendlyName>"+ device_name +"</friendlyName>"
|
||||
"<manufacturer>Belkin International Inc.</manufacturer>"
|
||||
"<modelName>Emulated Socket</modelName>"
|
||||
"<modelNumber>3.1415</modelNumber>"
|
||||
"<UDN>uuid:"+ persistent_uuid +"</UDN>"
|
||||
"<serialNumber>221517K0101769</serialNumber>"
|
||||
"<binaryState>0</binaryState>"
|
||||
"<serviceList>"
|
||||
"<service>"
|
||||
"<serviceType>urn:Belkin:service:basicevent:1</serviceType>"
|
||||
"<serviceId>urn:Belkin:serviceId:basicevent1</serviceId>"
|
||||
"<controlURL>/upnp/control/basicevent1</controlURL>"
|
||||
"<eventSubURL>/upnp/event/basicevent1</eventSubURL>"
|
||||
"<SCPDURL>/eventservice.xml</SCPDURL>"
|
||||
"</service>"
|
||||
"</serviceList>"
|
||||
"</device>"
|
||||
"</root>\r\n"
|
||||
"\r\n";
|
||||
|
||||
server->send(200, "text/xml", setup_xml.c_str());
|
||||
|
||||
DEBUG_PRINT("Sending :");
|
||||
DEBUG_PRINTLN(setup_xml);
|
||||
}
|
||||
|
||||
String Switch::getAlexaInvokeName() {
|
||||
return device_name;
|
||||
}
|
||||
|
||||
void Switch::respondToSearch(IPAddress& senderIP, unsigned int senderPort) {
|
||||
DEBUG_PRINTLN("");
|
||||
DEBUG_PRINT("Sending response to ");
|
||||
DEBUG_PRINTLN(senderIP);
|
||||
DEBUG_PRINT("Port : ");
|
||||
DEBUG_PRINTLN(senderPort);
|
||||
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
char s[16];
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
String response =
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"CACHE-CONTROL: max-age=86400\r\n"
|
||||
"DATE: Sat, 26 Nov 2016 04:56:29 GMT\r\n"
|
||||
"EXT:\r\n"
|
||||
"LOCATION: http://" + String(s) + ":" + String(localPort) + "/setup.xml\r\n"
|
||||
"OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
|
||||
"01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n"
|
||||
"SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
|
||||
"ST: urn:Belkin:device:**\r\n"
|
||||
"USN: uuid:" + persistent_uuid + "::urn:Belkin:device:**\r\n"
|
||||
"X-User-Agent: redsonic\r\n\r\n";
|
||||
|
||||
UDP.beginPacket(senderIP, senderPort);
|
||||
UDP.write(response.c_str());
|
||||
UDP.endPacket();
|
||||
|
||||
DEBUG_PRINTLN("Response sent !");
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
#ifndef SWITCH_H
|
||||
#define SWITCH_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <WiFiUDP.h>
|
||||
#include "CallbackFunction.h"
|
||||
|
||||
|
||||
class Switch {
|
||||
private:
|
||||
ESP8266WebServer *server = NULL;
|
||||
WiFiUDP UDP;
|
||||
String serial;
|
||||
String persistent_uuid;
|
||||
String device_name;
|
||||
unsigned int localPort;
|
||||
CallbackFunction onCallback;
|
||||
CallbackFunction offCallback;
|
||||
|
||||
void startWebServer();
|
||||
void handleEventservice();
|
||||
void handleUpnpControl();
|
||||
void handleRoot();
|
||||
void handleSetupXml();
|
||||
public:
|
||||
Switch();
|
||||
Switch(String alexaInvokeName, unsigned int port, CallbackFunction onCallback, CallbackFunction offCallback);
|
||||
~Switch();
|
||||
String getAlexaInvokeName();
|
||||
void serverLoop();
|
||||
void respondToSearch(IPAddress& senderIP, unsigned int senderPort);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,98 +0,0 @@
|
||||
#include "UpnpBroadcastResponder.h"
|
||||
#include "Switch.h"
|
||||
#include <functional>
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_PRINT(x) Serial.print (x)
|
||||
#define DEBUG_PRINTLN(x) Serial.println (x)
|
||||
#define DEBUG_PRINTF(x) Serial.printf (x)
|
||||
#else
|
||||
#define DEBUG_PRINT(x)
|
||||
#define DEBUG_PRINTLN(x)
|
||||
#define DEBUG_PRINTF(x)
|
||||
#endif
|
||||
|
||||
// Multicast declarations
|
||||
IPAddress ipMulti(239, 255, 255, 250);
|
||||
const unsigned int portMulti = 1900;
|
||||
char packetBuffer[512];
|
||||
|
||||
#define MAX_SWITCHES 14
|
||||
Switch switches[MAX_SWITCHES] = {};
|
||||
int numOfSwitchs = 0;
|
||||
|
||||
//#define numOfSwitchs (sizeof(switches)/sizeof(Switch)) //array size
|
||||
|
||||
//<<constructor>>
|
||||
UpnpBroadcastResponder::UpnpBroadcastResponder(){
|
||||
|
||||
}
|
||||
|
||||
//<<destructor>>
|
||||
UpnpBroadcastResponder::~UpnpBroadcastResponder(){/*nothing to destruct*/}
|
||||
|
||||
bool UpnpBroadcastResponder::beginUdpMulticast(){
|
||||
boolean state = false;
|
||||
|
||||
DEBUG_PRINTLN("Begin multicast ..");
|
||||
|
||||
if(UDP.beginMulticast(WiFi.localIP(), ipMulti, portMulti)) {
|
||||
DEBUG_PRINT("Udp multicast server started at ");
|
||||
DEBUG_PRINT(ipMulti);
|
||||
DEBUG_PRINT(":");
|
||||
DEBUG_PRINTLN(portMulti);
|
||||
|
||||
state = true;
|
||||
}
|
||||
else{
|
||||
DEBUG_PRINTLN("Connection failed");
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
//Switch *ptrArray;
|
||||
|
||||
void UpnpBroadcastResponder::addDevice(Switch& device) {
|
||||
DEBUG_PRINT("Adding switch : ");
|
||||
DEBUG_PRINT(device.getAlexaInvokeName());
|
||||
DEBUG_PRINT(" index : ");
|
||||
DEBUG_PRINTLN(numOfSwitchs);
|
||||
|
||||
switches[numOfSwitchs] = device;
|
||||
numOfSwitchs++;
|
||||
}
|
||||
|
||||
void UpnpBroadcastResponder::serverLoop(){
|
||||
int packetSize = UDP.parsePacket();
|
||||
if (packetSize <= 0)
|
||||
return;
|
||||
|
||||
IPAddress senderIP = UDP.remoteIP();
|
||||
unsigned int senderPort = UDP.remotePort();
|
||||
|
||||
// read the packet into the buffer
|
||||
UDP.read(packetBuffer, packetSize);
|
||||
|
||||
// check if this is a M-SEARCH for WeMo device
|
||||
String request = String((char *)packetBuffer);
|
||||
|
||||
if(request.indexOf('M-SEARCH') > 0) {
|
||||
if(request.indexOf("urn:Belkin:device:**") > 0) {
|
||||
DEBUG_PRINTLN("Got UDP Belkin Request..");
|
||||
|
||||
// int arrSize = sizeof(switchs) / sizeof(Switch);
|
||||
|
||||
for(int n = 0; n < numOfSwitchs; n++) {
|
||||
Switch &sw = switches[n];
|
||||
|
||||
if (&sw != NULL) {
|
||||
sw.respondToSearch(senderIP, senderPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
#ifndef UPNPBROADCASTRESPONDER_H
|
||||
#define UPNPBROADCASTRESPONDER_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiUDP.h>
|
||||
#include "Switch.h"
|
||||
|
||||
class UpnpBroadcastResponder {
|
||||
private:
|
||||
WiFiUDP UDP;
|
||||
public:
|
||||
UpnpBroadcastResponder();
|
||||
~UpnpBroadcastResponder();
|
||||
bool beginUdpMulticast();
|
||||
void serverLoop();
|
||||
void addDevice(Switch& device);
|
||||
};
|
||||
|
||||
#endif
|
@ -17,15 +17,12 @@
|
||||
#include "src/dependencies/time/Time.h"
|
||||
#include "src/dependencies/time/TimeLib.h"
|
||||
#include "src/dependencies/timezone/Timezone.h"
|
||||
#include "src/dependencies/alexa-multiple/switch.h"
|
||||
#include "src/dependencies/alexa-multiple/UpnpBroadcastResponder.h"
|
||||
#include "src/dependencies/alexa-multiple/CallbackFunction.h"
|
||||
#include "htmls00.h"
|
||||
#include "htmls01.h"
|
||||
#include "WS2812FX.h"
|
||||
|
||||
//version in format yymmddb (b = daily build)
|
||||
#define VERSION 1712300
|
||||
#define VERSION 1712310
|
||||
|
||||
//AP and OTA default passwords (change them!)
|
||||
String appass = "wled1234";
|
||||
@ -34,10 +31,10 @@ String otapass = "wledota";
|
||||
//If you have an RGBW strip, uncomment first line in WS2812FX.h!
|
||||
|
||||
//overlays, needed for clocks etc.
|
||||
//#define USEOVERLAYS
|
||||
#define USEOVERLAYS
|
||||
|
||||
//support for the CRONIXIE clock by Diamex (disable overlays!)
|
||||
#define CRONIXIE
|
||||
//#define CRONIXIE
|
||||
|
||||
//spiffs FS only useful for debug
|
||||
//#define USEFS
|
||||
@ -217,8 +214,12 @@ boolean useGammaCorrectionRGB = true;
|
||||
int arlsOffset = -22; //10: -22 assuming arls52
|
||||
|
||||
//alexa
|
||||
Switch *alexa = NULL;
|
||||
UpnpBroadcastResponder upnpBroadcastResponder;
|
||||
WiFiUDP UDP;
|
||||
IPAddress ipMulti(239, 255, 255, 250);
|
||||
unsigned int portMulti = 1900;
|
||||
unsigned int localPort = 1900;
|
||||
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
|
||||
String escapedMac;
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
|
@ -160,6 +160,7 @@ void wledInit()
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
alexaInit();
|
||||
|
||||
server.begin();
|
||||
DEBUG_PRINTLN("HTTP server started");
|
||||
|
@ -46,7 +46,7 @@ void handleNotifications()
|
||||
if(packetSize && notifierUdp.remoteIP() != WiFi.localIP())
|
||||
{
|
||||
notifierUdp.read(udpIn, packetSize);
|
||||
if (udpIn[0] == 0) //wled notifier
|
||||
if (udpIn[0] == 0 && !arlsTimeout) //wled notifier, block if realtime packets active
|
||||
{
|
||||
col[0] = udpIn[3];
|
||||
col[1] = udpIn[4];
|
||||
|
@ -6,9 +6,11 @@ void alexaInit()
|
||||
{
|
||||
if (alexaEnabled && WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
upnpBroadcastResponder.beginUdpMulticast();
|
||||
alexa = new Switch(alexaInvocationName, 81, alexaOn, alexaOff);
|
||||
upnpBroadcastResponder.addDevice(*alexa);
|
||||
prepareIds();
|
||||
|
||||
udpConnected = connectUDP();
|
||||
|
||||
if (udpConnected) alexaInitPages();
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,8 +18,25 @@ void handleAlexa()
|
||||
{
|
||||
if (alexaEnabled && WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
upnpBroadcastResponder.serverLoop();
|
||||
alexa->serverLoop();
|
||||
if(udpConnected){
|
||||
// if there’s data available, read a packet
|
||||
int packetSize = UDP.parsePacket();
|
||||
if(packetSize) {
|
||||
IPAddress remote = UDP.remoteIP();
|
||||
int len = UDP.read(packetBuffer, 255);
|
||||
if (len > 0) {
|
||||
packetBuffer[len] = 0;
|
||||
}
|
||||
String request = packetBuffer;
|
||||
|
||||
if(request.indexOf("M-SEARCH") >= 0) {
|
||||
if((request.indexOf("urn:Belkin:device:**") > 0) || (request.indexOf("ssdp:all") > 0) || (request.indexOf("upnp:rootdevice") > 0)) {
|
||||
Serial.println("Responding to search request ...");
|
||||
respondToSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +49,18 @@ void alexaOn()
|
||||
{
|
||||
applyMacro(alexaOnMacro);
|
||||
}
|
||||
|
||||
String body =
|
||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>\r\n"
|
||||
"<u:SetBinaryStateResponse xmlns:u=\"urn:Belkin:service:basicevent:1\">\r\n"
|
||||
"<BinaryState>1</BinaryState>\r\n"
|
||||
"</u:SetBinaryStateResponse>\r\n"
|
||||
"</s:Body> </s:Envelope>";
|
||||
|
||||
server.send(200, "text/xml", body.c_str());
|
||||
|
||||
Serial.print("Sending :");
|
||||
Serial.println(body);
|
||||
}
|
||||
|
||||
void alexaOff()
|
||||
@ -41,6 +72,18 @@ void alexaOff()
|
||||
{
|
||||
applyMacro(alexaOffMacro);
|
||||
}
|
||||
|
||||
String body =
|
||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>\r\n"
|
||||
"<u:SetBinaryStateResponse xmlns:u=\"urn:Belkin:service:basicevent:1\">\r\n"
|
||||
"<BinaryState>0</BinaryState>\r\n"
|
||||
"</u:SetBinaryStateResponse>\r\n"
|
||||
"</s:Body> </s:Envelope>";
|
||||
|
||||
server.send(200, "text/xml", body.c_str());
|
||||
|
||||
Serial.print("Sending :");
|
||||
Serial.println(body);
|
||||
}
|
||||
|
||||
void alexaDim(uint8_t bri)
|
||||
@ -50,3 +93,219 @@ void alexaDim(uint8_t bri)
|
||||
handleSet(ct);
|
||||
}
|
||||
|
||||
void prepareIds() {
|
||||
escapedMac = WiFi.macAddress();
|
||||
escapedMac.replace(":", "");
|
||||
escapedMac.toLowerCase();
|
||||
}
|
||||
|
||||
void respondToSearch() {
|
||||
Serial.println("");
|
||||
Serial.print("Sending response to ");
|
||||
Serial.println(UDP.remoteIP());
|
||||
Serial.print("Port : ");
|
||||
Serial.println(UDP.remotePort());
|
||||
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
char s[16];
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
String response =
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"EXT:\r\n"
|
||||
"CACHE-CONTROL: max-age=%u\r\n" // SSDP_INTERVAL
|
||||
"LOCATION: http://"+ String(s) +":80/description.xml\r\n"
|
||||
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.17.0\r\n" // _modelName, _modelNumber
|
||||
"hue-bridgeid: "+ escapedMac +"\r\n"
|
||||
"ST: urn:schemas-upnp-org:device:basic:1\r\n" // _deviceType
|
||||
"USN: uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"::upnp:rootdevice\r\n" // _uuid::_deviceType
|
||||
"\r\n";
|
||||
|
||||
UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());
|
||||
UDP.write(response.c_str());
|
||||
UDP.endPacket();
|
||||
|
||||
Serial.println("Response sent !");
|
||||
}
|
||||
|
||||
void alexaInitPages() {
|
||||
server.on("/upnp/control/basicevent1", HTTP_POST, []() {
|
||||
Serial.println("########## Responding to /upnp/control/basicevent1 ... ##########");
|
||||
|
||||
String request = server.arg(0);
|
||||
Serial.print("request:");
|
||||
Serial.println(request);
|
||||
|
||||
if(request.indexOf("SetBinaryState") >= 0) {
|
||||
if(request.indexOf("<BinaryState>1</BinaryState>") >= 0) {
|
||||
Serial.println("Got Turn on request");
|
||||
alexaOn();
|
||||
}
|
||||
|
||||
if(request.indexOf("<BinaryState>0</BinaryState>") >= 0) {
|
||||
Serial.println("Got Turn off request");
|
||||
alexaOff();
|
||||
}
|
||||
}
|
||||
|
||||
if(request.indexOf("GetBinaryState") >= 0) {
|
||||
Serial.println("Got binary state request");
|
||||
sendState();
|
||||
}
|
||||
|
||||
server.send(200, "text/plain", "");
|
||||
});
|
||||
|
||||
server.on("/eventservice.xml", HTTP_GET, [](){
|
||||
Serial.println(" ########## Responding to eventservice.xml ... ########\n");
|
||||
|
||||
String eventservice_xml = "<scpd xmlns=\"urn:Belkin:service-1-0\">"
|
||||
"<actionList>"
|
||||
"<action>"
|
||||
"<name>SetBinaryState</name>"
|
||||
"<argumentList>"
|
||||
"<argument>"
|
||||
"<retval/>"
|
||||
"<name>BinaryState</name>"
|
||||
"<relatedStateVariable>BinaryState</relatedStateVariable>"
|
||||
"<direction>in</direction>"
|
||||
"</argument>"
|
||||
"</argumentList>"
|
||||
"</action>"
|
||||
"<action>"
|
||||
"<name>GetBinaryState</name>"
|
||||
"<argumentList>"
|
||||
"<argument>"
|
||||
"<retval/>"
|
||||
"<name>BinaryState</name>"
|
||||
"<relatedStateVariable>BinaryState</relatedStateVariable>"
|
||||
"<direction>out</direction>"
|
||||
"</argument>"
|
||||
"</argumentList>"
|
||||
"</action>"
|
||||
"</actionList>"
|
||||
"<serviceStateTable>"
|
||||
"<stateVariable sendEvents=\"yes\">"
|
||||
"<name>BinaryState</name>"
|
||||
"<dataType>Boolean</dataType>"
|
||||
"<defaultValue>0</defaultValue>"
|
||||
"</stateVariable>"
|
||||
"<stateVariable sendEvents=\"yes\">"
|
||||
"<name>level</name>"
|
||||
"<dataType>string</dataType>"
|
||||
"<defaultValue>0</defaultValue>"
|
||||
"</stateVariable>"
|
||||
"</serviceStateTable>"
|
||||
"</scpd>\r\n"
|
||||
"\r\n";
|
||||
|
||||
server.send(200, "text/plain", eventservice_xml.c_str());
|
||||
});
|
||||
|
||||
server.on("/description.xml", HTTP_GET, [](){
|
||||
Serial.println(" ########## Responding to setup.xml ... ########\n");
|
||||
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
char s[16];
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
String setup_xml = "<?xml version=\"1.0\" ?>"
|
||||
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\">"
|
||||
"<specVersion><major>1</major><minor>0</minor></specVersion>"
|
||||
"<URLBase>http://"+ String(s) +":80/</URLBase>"
|
||||
"<device>"
|
||||
"<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>"
|
||||
"<friendlyName>Philips hue ("+ String(s) +")</friendlyName>"
|
||||
"<manufacturer>Royal Philips Electronics</manufacturer>"
|
||||
"<manufacturerURL>http://www.philips.com</manufacturerURL>"
|
||||
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>"
|
||||
"<modelName>Philips hue bridge 2012</modelName>"
|
||||
"<modelNumber>929000226503</modelNumber>"
|
||||
"<modelURL>http://www.meethue.com</modelURL>"
|
||||
"<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>"
|
||||
" <icon>"
|
||||
" <mimetype>image/png</mimetype>"
|
||||
" <height>120</height>"
|
||||
" <width>120</width>"
|
||||
" <depth>24</depth>"
|
||||
" <url>hue_logo_3.png</url>"
|
||||
" </icon>"
|
||||
"</iconList>"
|
||||
"</device>"
|
||||
"</root>";
|
||||
|
||||
server.send(200, "text/xml", setup_xml.c_str());
|
||||
|
||||
Serial.print("Sending :");
|
||||
Serial.println(setup_xml);
|
||||
});
|
||||
|
||||
// openHAB support
|
||||
server.on("/on.html", HTTP_GET, [](){
|
||||
Serial.println("on req");
|
||||
server.send(200, "text/plain", "turned on");
|
||||
alexaOn();
|
||||
});
|
||||
|
||||
server.on("/off.html", HTTP_GET, [](){
|
||||
Serial.println("off req");
|
||||
server.send(200, "text/plain", "turned off");
|
||||
alexaOff();
|
||||
});
|
||||
|
||||
server.on("/status.html", HTTP_GET, [](){
|
||||
Serial.println("Got status request");
|
||||
|
||||
String statrespone = "0";
|
||||
if (bri > 0) {
|
||||
statrespone = "1";
|
||||
}
|
||||
server.send(200, "text/plain", statrespone);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
boolean connectUDP(){
|
||||
boolean state = false;
|
||||
|
||||
Serial.println("");
|
||||
Serial.println("Con UDP");
|
||||
|
||||
if(UDP.beginMulticast(WiFi.localIP(), ipMulti, portMulti)) {
|
||||
Serial.println("Con success");
|
||||
state = true;
|
||||
}
|
||||
else{
|
||||
Serial.println("Con failed");
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void sendState() {
|
||||
|
||||
String body =
|
||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>\r\n"
|
||||
"<u:GetBinaryStateResponse xmlns:u=\"urn:Belkin:service:basicevent:1\">\r\n"
|
||||
"<BinaryState>";
|
||||
|
||||
body += ((bri>0) ? "1" : "0");
|
||||
|
||||
body += "</BinaryState>\r\n"
|
||||
"</u:GetBinaryStateResponse>\r\n"
|
||||
"</s:Body> </s:Envelope>\r\n";
|
||||
|
||||
server.send(200, "text/xml", body.c_str());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user