X10 Server - IOT device to leverage a collection of old X10 devices for home automation and lighting control.
Dependencies: IniManager mbed HTTPClient SWUpdate mbed-rtos Watchdog X10 SW_HTTPServer SW_String EthernetInterface TimeInterface SSDP
X10 Server
See the X10 Server Nodebook page
Diff: WebPages.cpp
- Revision:
- 7:16129d213e6a
- Parent:
- 4:5da66fab599c
- Child:
- 8:a45fe77efcc5
--- a/WebPages.cpp Sat Sep 01 01:46:33 2018 +0000 +++ b/WebPages.cpp Wed Feb 27 18:24:32 2019 +0000 @@ -2,7 +2,13 @@ #include "mbed.h" #include "EthernetInterface.h" +#include "SW_String.h" +#include "X10.h" #include "WebPages.h" +#include "IniManager.h" // v20 + +extern INI ini; +extern X10Interface cm17a; extern EthernetInterface eth; extern const char * BUILD_DATE; @@ -11,6 +17,7 @@ extern const char * My_SerialNum; extern int Server_Port; +extern bool swUpdateCheck; // ########################################## // This test version controls the LEDs @@ -23,55 +30,6 @@ "Cache-Control: no-cache\r\n"; -// sprintf(buf, ROOTPAGE, "NodeName", "NodeName", "BuildDate", -static const char ROOTPAGE[] = - "<!DOCTYPE html>\r\n" - "<html><head><title>%s</title>\r\n" - "</head>\r\n" - "<body>\r\n" - "<h1>%s</h1>" - "This project demonstrates the Smartware web server and the Smartware SSDP discovery server.\n" - "You should be able to scan the network (e.g. in Windows Explorer) and find this device.\n" - "Then you can click on it to open this web page to interact with it.\n" - "<br/><br/>Build %s<br/><br/>\n" - "<font size='+5'>\n" - "<table><tr>\n" - "<td>" - "<button onclick=\"window.location.href='/?LED=1&CMD=1'\">LED 1 On</button><br/>\n" - "<button onclick=\"window.location.href='/?LED=1&CMD=0'\">LED 1 Off</button><br/>\n" - "</td><td>" - "<button onclick=\"window.location.href='/?LED=2&CMD=1'\">LED 2 On</button><br/>\n" - "<button onclick=\"window.location.href='/?LED=2&CMD=0'\">LED 2 Off</button><br/>\n" - "</td><td>" - "<button onclick=\"window.location.href='/?LED=3&CMD=1'\">LED 3 On</button><br/>\n" - "<button onclick=\"window.location.href='/?LED=3&CMD=0'\">LED 3 Off</button><br/>\n" - "</td><td>" - "<button onclick=\"window.location.href='/?LED=4&CMD=1'\">LED 4 On</button><br/>\n" - "<button onclick=\"window.location.href='/?LED=4&CMD=0'\">LED 4 Off</button><br/>\n" - "</td>" - "</tr></table>\n" - "</font>\n" - "<form method='get'>\n" - "<table>\n" - "<tr><td>Set LED</td>\n" - "<td><select name='LED'>\n" - " <option value='1'>1</option>\n" - " <option value='2'>2</option>\n" - " <option value='3'>3</option>\n" - " <option value='4'>4</option>\n" - " </select>\n" - " \n" - " <select name='CMD'>\n" - " <option value='0'>Off</option>\n" - " <option value='1'>On</option>\n" - " </select>\n" - "</td></tr>\n" - "<tr><td> </td><td><input type='submit' value='Apply'></td></tr>\n" - "</table>\n" - "</form>\n" - "</body>\n" - "</html>\n" - ""; // The /setup.xml file @@ -92,7 +50,7 @@ " <modelDescription>Special thing</modelDescription>\n" ///< " <modelName>Smart Node</modelName>\n" ///< " <modelNumber>1.0.0</modelNumber>\n" -#if 0 +#if 1 " <modelURL>http://www.smart-family.net</modelURL>\n" ///< This causes it to fail to send completely #endif " <UDN>uuid:Socket-1_0-%s</UDN>\n" @@ -215,43 +173,91 @@ HTTPServer::CallBackResults RootPage(HTTPServer *svr, HTTPServer::CallBackType type, char * path, const HTTPServer::namevalue *queryParams, int queryParamCount) { - #define bufSize (sizeof(ROOTPAGE) + 100) - char * BigBuffer = (char *)malloc(bufSize); + char buf[100]; + int count; HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR; - if (!BigBuffer) { - printf("cannot allocate %d bytes\n", bufSize); - return ret; - } - - int led, cmd; - int mask = 0; - for (int i=0; i<queryParamCount; i++) { - if (strcmp(queryParams[i].name, "LED") == 0) { - led = atoi(queryParams[i].value); - mask |= 1; - } else if (strcmp(queryParams[i].name, "CMD") == 0) { - cmd = atoi(queryParams[i].value); - mask |= 2; - } - } - if (mask == 3) { - switch (led) { - case 1: - case 2: - case 3: - case 4: - leds[led - 1] = cmd; - break; - default: - break; - } - } switch (type) { case HTTPServer::SEND_PAGE: - svr->header(HTTPServer::OK, "OK", hdrTypeHTML_NoCache); - snprintf(BigBuffer, bufSize, ROOTPAGE, PROG_NAME, PROG_NAME, BUILD_DATE); - svr->send(BigBuffer); + if (0 == strcmp(svr->GetParameter("SWUpdate"),"CheckNow")) { + swUpdateCheck = true; + svr->header(HTTPServer::Found, "Found", "Location: /\r\n"); + svr->send("\r\n"); + break; + } + count = svr->GetParameterCount(); + printf("Data Transfer: %d parameters\r\n", count); + if (count) { + for (int i=0; i<count; i++) { + const HTTPServer::namevalue * nv = svr->GetParameter(i); + printf(" %d: %s => %s\r\n", i, nv->name, nv->value); + } + const char * p = svr->GetParameter("House"); + if (p && strlen(p) == 1) { + char cmdBuf[7]; // "HUU +6" + strcpy_s(cmdBuf, sizeof(cmdBuf), p); + p = svr->GetParameter("Unit"); + if (p && strlen(p) >= 1 && strlen(p) <= 2) { + strcat_s(cmdBuf, sizeof(cmdBuf), p); + p = svr->GetParameter("Cmd"); + if (p && strlen(p) >= 1 && strlen(p) <= 2) { + strcat_s(cmdBuf, sizeof(cmdBuf), " "); + strcat_s(cmdBuf, sizeof(cmdBuf), p); + printf("Web Command: '%s'\r\n", cmdBuf); + cm17a.ParseCommand(cmdBuf); + svr->header(HTTPServer::Found, "Found", "Location: /\r\n"); + svr->send("\r\n"); + break; + } + } + } + } + + svr->header(HTTPServer::OK, "OK", "Content-Type: text/html\r\n"); + svr->send("<!DOCTYPE html>\r\n<html><head><title>X10 Server Info</title></head>\r\n"); + svr->send("<body>\r\n"); + svr->send("<h1>X10 Server Info</h1>\r\n"); + svr->send("<blockquote>\r\n"); + svr->send("<table border='1'>\r\n"); + svr->send("<tr><th><h2>Command</h2></th></tr>\r\n"); + svr->send("<tr><td>\r\n"); + svr->send("<form method='get'>\r\n"); + svr->send("<table border='1'><tr><th>House</th><th>Unit</th><th>Cmd</th><th> </th></tr>\r\n"); + svr->send("<tr><td align='center'><select name='House'>\r\n"); + for (int i = 'A'; i <= 'P'; i++) { + snprintf(buf, 100, "<option value='%c'>%c</option>\r\n", i, i); + svr->send(buf); + } + svr->send("</select></td>\r\n"); + svr->send("<td><select name='Unit'>\r\n"); + for (int i = 1; i <= 16; i++) { + snprintf(buf, 100, "<option value='%d'>%d</option>\r\n", i, i); + svr->send(buf); + } + svr->send("</select></td>\r\n"); + + svr->send("<td><select name='Cmd'>\r\n"); + for (int i = -6; i <= 7; i++) { + if (i < 0) + snprintf(buf, 100, "<option value='%+d'>%+d</option>\r\n", i, i); + else if (i == 0) + snprintf(buf, 100, "<option value='%d' selected>%d</option>\r\n", i, i); + else if (i == 1) + snprintf(buf, 100, "<option value='%d'>%d</option>\r\n", i, i); + else // if (i > 1) + snprintf(buf, 100, "<option value='%+d'>%+d</option>\r\n", i-1, i-1); + svr->send(buf); + } + svr->send("</select></td>\r\n"); + + svr->send("<td><input type='Submit' value='Send'></td>\r\n"); + svr->send("</tr></table>\r\n"); + svr->send("</form>\r\n"); + svr->send("</td></tr></table>\r\n"); + svr->send("<br/><br/><a href='/info'>info Page</a> | <a href='/setup.xml'>setup.xml</a>\r\n"); + svr->send("</blockquote>\r\n"); + svr->send("X10 Server, Copyright © 2019 by Smartware Computing, all rights reserved."); + svr->send("</body></html>"); ret = HTTPServer::ACCEPT_COMPLETE; break; case HTTPServer::CONTENT_LENGTH_REQUEST: @@ -264,7 +270,102 @@ ret = HTTPServer::ACCEPT_ERROR; break; } - if (BigBuffer) - free(BigBuffer); return ret; } + + +HTTPServer::CallBackResults InfoPage(HTTPServer *svr, HTTPServer::CallBackType type, char * path, + const HTTPServer::namevalue *queryParams, int queryParamCount) +{ + char lineBuf[60]; + char buf[4000] = ""; + HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR; + FILE * fh; + + switch (type) { + case HTTPServer::SEND_PAGE: + svr->header(HTTPServer::OK, "OK", "Content-Type: text/html\r\n"); + strcpy_s(buf, sizeof(buf), "<!DOCTYPE html>\r\n<html><head><title>X10 Server Info</title></head>\r\n"); + strcat_s(buf, sizeof(buf), "<body>\r\n"); + strcat_s(buf, sizeof(buf), "<h1>X10 Server Info</h1>\r\n"); + strcat_s(buf, sizeof(buf), "<table border='1' width='100%'>\r\n"); + strcat_s(buf, sizeof(buf), "<tr><th>Configuration</th><th>Software</th></tr>\r\n"); + strcat_s(buf, sizeof(buf), "<tr><td valign='top' width='50%'><pre>\r\n"); + fh = fopen("/local/X10svr.ini", "rt"); + if (fh) { + char fileBuf[60]; + while(fgets(fileBuf, sizeof(fileBuf), fh)) { + strcat_s(buf, sizeof(buf), fileBuf); + } + fclose(fh); + } + strcat_s(buf, sizeof(buf), "</pre>\r\n"); + strcat_s(buf, sizeof(buf), "</td>\r\n"); + strcat_s(buf, sizeof(buf), "<td valign='top' width='50%'><pre>\r\n"); + if (INI::INI_SUCCESS == ini.ReadString("SWUpdate", "name", lineBuf, sizeof(lineBuf))) { + strcat_s(buf, sizeof(buf), "name="); + strcat_s(buf, sizeof(buf), lineBuf); + strcat_s(buf, sizeof(buf), "\r\nversion="); + lineBuf[6] = '\0'; + char fname[45]; + snprintf(fname, sizeof(fname), "/local/%s.ver", lineBuf); + fh = fopen(fname, "rt"); + if (fh) { + while(fgets(lineBuf, sizeof(lineBuf), fh)) { + strcat_s(buf, sizeof(buf), lineBuf); + } + fclose(fh); + } + } + strcat_s(buf, sizeof(buf), "</pre>\r\n"); + strcat_s(buf, sizeof(buf), "<img src='/icon.png'>"); + strcat_s(buf, sizeof(buf), "</td></tr>\r\n"); + strcat_s(buf, sizeof(buf), "<tr>\r\n"); + strcat_s(buf, sizeof(buf), "<td><a href='/software'>Software Update Check</a></td>\r\n"); + strcat_s(buf, sizeof(buf), "<td><a href='/'>Home Page</a> | "); + strcat_s(buf, sizeof(buf), "<a href='/setup.xml' target='_xml'>view setup.xml</a>\r\n"); + strcat_s(buf, sizeof(buf), "</td></tr></table>\r\n"); + strcat_s(buf, sizeof(buf), "</body></html>"); + printf("big buf size is %d bytes\r\n", strlen(buf)); + svr->send(buf); + ret = HTTPServer::ACCEPT_COMPLETE; + break; + case HTTPServer::CONTENT_LENGTH_REQUEST: + ret = HTTPServer::ACCEPT_COMPLETE; + break; + case HTTPServer::DATA_TRANSFER: + ret = HTTPServer::ACCEPT_COMPLETE; + break; + default: + ret = HTTPServer::ACCEPT_ERROR; + break; + } + return ret; +} + + +HTTPServer::CallBackResults SoftwarePage(HTTPServer *svr, HTTPServer::CallBackType type, char * path, + const HTTPServer::namevalue *queryParams, int queryParamCount) +{ + HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR; + + switch (type) { + case HTTPServer::SEND_PAGE: + swUpdateCheck = true; + printf("SW Update Check scheduled.\r\n"); + svr->header(HTTPServer::Found, "Found", "Location: /\r\n"); + svr->send("\r\n"); + ret = HTTPServer::ACCEPT_COMPLETE; + break; + case HTTPServer::CONTENT_LENGTH_REQUEST: + ret = HTTPServer::ACCEPT_COMPLETE; + break; + case HTTPServer::DATA_TRANSFER: + ret = HTTPServer::ACCEPT_COMPLETE; + break; + default: + ret = HTTPServer::ACCEPT_ERROR; + break; + } + return ret; +}