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

Files at this revision

API Documentation at this revision

Comitter:
WiredHome
Date:
Sat Mar 02 23:13:58 2019 +0000
Parent:
7:16129d213e6a
Child:
9:2c96e69b6035
Commit message:
Blink the link data LED on network transactions.

Changed in this revision

WebPages.cpp Show annotated file Show diff for this revision Revisions of this file
WebPages.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/WebPages.cpp	Wed Feb 27 18:24:32 2019 +0000
+++ b/WebPages.cpp	Sat Mar 02 23:13:58 2019 +0000
@@ -19,6 +19,10 @@
 
 extern bool swUpdateCheck;
 
+extern DigitalOut linkdata;
+
+extern "C" void mbed_reset();
+
 // ##########################################
 // This test version controls the LEDs
 //
@@ -146,6 +150,7 @@
 {
     char BigBuffer[sizeof(SETUP_TEMPLATE) + 150];
     HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
+    linkdata = true;
     switch (type) {
         case HTTPServer::SEND_PAGE:
             svr->header(HTTPServer::OK, "OK", hdrTypeHTML_NoCache);
@@ -165,6 +170,7 @@
             ret = HTTPServer::ACCEPT_ERROR;
             break;
     }
+    linkdata = false;
     return ret;
 }
 
@@ -173,10 +179,12 @@
 HTTPServer::CallBackResults RootPage(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
                        const HTTPServer::namevalue *queryParams, int queryParamCount)
 {
-    char buf[100];
+    char smallBuf[100];
+    char bigBuf[3000] = "";      // sized by test and adjust, and then round up generously.
     int count;
     HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
     
+    linkdata = true;
     switch (type) {
         case HTTPServer::SEND_PAGE:
             if (0 == strcmp(svr->GetParameter("SWUpdate"),"CheckNow")) {
@@ -188,10 +196,10 @@
             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);
-                }
+                //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"
@@ -214,50 +222,60 @@
             }
 
             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>&nbsp;</th></tr>\r\n");
-            svr->send("<tr><td align='center'><select name='House'>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<title>X10 Server Info</title>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<style>\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "body {\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "   transform: scale(1.6);\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "   transform-origin: 0 0;\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "}\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</style>\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</head>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<body>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<h1>X10 Server Info</h1>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<blockquote>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<table border='1'>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<tr><th><h2>Command</h2></th></tr>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<tr><td>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<form method='get'>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<table border='0'><tr><th>House</th><th>Unit</th><th>Cmd</th><th>&nbsp;</th></tr>\r\n");
+            // House code
+            strcat_s(bigBuf, sizeof(bigBuf), "<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);
+                snprintf(smallBuf, 100, "<option value='%c'>%c</option>\r\n", i, i);
+                strcat_s(bigBuf, sizeof(bigBuf), smallBuf);
             }
-            svr->send("</select></td>\r\n");
-            svr->send("<td><select name='Unit'>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</select></td>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<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);
+                snprintf(smallBuf, 100, "<option value='%d'>%d</option>\r\n", i, i);
+                strcat_s(bigBuf, sizeof(bigBuf), smallBuf);
             }
-            svr->send("</select></td>\r\n");
-
-            svr->send("<td><select name='Cmd'>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</select></td>\r\n");
+            // Unit code
+            strcat_s(bigBuf, sizeof(bigBuf), "<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);
+                    snprintf(smallBuf, 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);
+                    snprintf(smallBuf, 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);
+                    snprintf(smallBuf, 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);
+                    snprintf(smallBuf, 100, "<option value='%+d'>%+d</option>\r\n", i-1, i-1);
+                strcat_s(bigBuf, sizeof(bigBuf), smallBuf);
             }
-            svr->send("</select></td>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</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 &copy; 2019 by Smartware Computing, all rights reserved.");
-            svr->send("</body></html>");
+            strcat_s(bigBuf, sizeof(bigBuf), "<td><input type='Submit' value='Send'></td>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</tr></table>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</form>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</td></tr></table>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<br/><br/><a href='/info'>info Page</a> | <a href='/setup.xml'>setup.xml</a>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</blockquote>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "X10 Server, Copyright &copy; 2019 by Smartware Computing, all rights reserved.");
+            strcat_s(bigBuf, sizeof(bigBuf), "</body></html>");
+            printf("bigBuf size is %d bytes\r\n", strlen(bigBuf));
+            svr->send(bigBuf);
             ret = HTTPServer::ACCEPT_COMPLETE;
             break;
         case HTTPServer::CONTENT_LENGTH_REQUEST:
@@ -270,6 +288,7 @@
             ret = HTTPServer::ACCEPT_ERROR;
             break;
     }
+    linkdata = false;
     return ret;
 }
 
@@ -278,56 +297,57 @@
                        const HTTPServer::namevalue *queryParams, int queryParamCount)
 {
     char lineBuf[60];
-    char buf[4000] = "";
+    char bigBuf[1000] = "";      // sized by test and adjust, and then round up generously.
     HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
     FILE * fh;
     
+    linkdata = true;
     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");
+            strcat_s(bigBuf, sizeof(bigBuf), "<!DOCTYPE html>\r\n<html><head><title>X10 Server Info</title></head>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<body>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<h1>X10 Server Info</h1>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<table border='1' width='100%'>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<tr><th>Configuration</th><th>Software</th></tr>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<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);
+                    strcat_s(bigBuf, sizeof(bigBuf), 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");
+            strcat_s(bigBuf, sizeof(bigBuf), "</pre>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</td>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<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=");
+                strcat_s(bigBuf, sizeof(bigBuf), "name=");
+                strcat_s(bigBuf, sizeof(bigBuf), lineBuf);
+                strcat_s(bigBuf, sizeof(bigBuf), "\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);
+                        strcat_s(bigBuf, sizeof(bigBuf), 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);
+            strcat_s(bigBuf, sizeof(bigBuf), "</pre>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<img src='/icon.png'>");
+            strcat_s(bigBuf, sizeof(bigBuf), "</td></tr>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<tr>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<td><a href='/'>Home Page</a> | <a href='/reboot'>Reboot</a></td>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "<td><a href='/software'>Software Update Check</a> | ");
+            strcat_s(bigBuf, sizeof(bigBuf), "<a href='/setup.xml' target='_xml'>view setup.xml</a>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</td></tr></table>\r\n");
+            strcat_s(bigBuf, sizeof(bigBuf), "</body></html>");
+            printf("bigBuf size is %d bytes\r\n", strlen(bigBuf));
+            svr->send(bigBuf);
             ret = HTTPServer::ACCEPT_COMPLETE;
             break;
         case HTTPServer::CONTENT_LENGTH_REQUEST:
@@ -340,6 +360,7 @@
             ret = HTTPServer::ACCEPT_ERROR;
             break;
     }
+    linkdata = false;
     return ret;
 }
 
@@ -349,6 +370,7 @@
 {
     HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
     
+    linkdata = true;
     switch (type) {
         case HTTPServer::SEND_PAGE:
             swUpdateCheck = true;
@@ -367,5 +389,37 @@
             ret = HTTPServer::ACCEPT_ERROR;
             break;
     }
+    linkdata = false;
     return ret;
 }
+
+
+HTTPServer::CallBackResults RebootPage(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
+                       const HTTPServer::namevalue *queryParams, int queryParamCount)
+{
+    HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
+    
+    linkdata = true;
+    switch (type) {
+        case HTTPServer::SEND_PAGE:
+            swUpdateCheck = true;
+            printf("Reboot scheduled.\r\n");
+            svr->header(HTTPServer::Found, "Found", "Location: /\r\n");
+            svr->send("\r\n");
+            Thread::wait(500);
+            mbed_reset();
+            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;
+    }
+    linkdata = false;
+    return ret;
+}
--- a/WebPages.h	Wed Feb 27 18:24:32 2019 +0000
+++ b/WebPages.h	Sat Mar 02 23:13:58 2019 +0000
@@ -17,4 +17,6 @@
 HTTPServer::CallBackResults SoftwarePage(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
                        const HTTPServer::namevalue *queryParams, int queryParamCount);
 
+HTTPServer::CallBackResults RebootPage(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
+                       const HTTPServer::namevalue *queryParams, int queryParamCount);
 #endif // WEBPAGES_H
--- a/main.cpp	Wed Feb 27 18:24:32 2019 +0000
+++ b/main.cpp	Sat Mar 02 23:13:58 2019 +0000
@@ -87,7 +87,8 @@
                 pc.printf("  no update available.\r\n");
                 swUpdateCheck = false;
             } else {
-                pc.printf("  update failed %04X\r\n", su);
+                pc.printf("  update failed %04X - %s\r\n", su, 
+                    SoftwareUpdateGetHTTPErrorMsg(SoftwareUpdateGetHTTPErrorCode()));
                 Thread::wait(1000);
             }
             linkdata = false;
@@ -132,6 +133,7 @@
                 ntp.set_dst(dstStart,dstStop);
             }
             ntp.set_tzo_min(tzo_min);
+            linkdata = true;
             int res = ntp.setTime(url);
             //printf("  NTP (release ethernet)\r\n");
             if (res == 0) {
@@ -141,10 +143,12 @@
                 tlast = ctTime;
                 printf("   Time set to (UTC): %s\r\n", ntp.ctime(&ctTime));
                 printf("            ntpSyncd: %s\r\n", ntp.ctime(&ntpSyncd));
+                ntpUpdateCheck = false;
             } else {
                 ntpSyncd = 0;
                 printf("Error return from setTime(%s) %d\r\n", url, res);
             }
+            linkdata = false;
         } else {
             ntpSyncd = 0;
             printf("no time server was set\r\n");
@@ -343,6 +347,7 @@
                 svr.RegisterHandler("/", RootPage);
                 svr.RegisterHandler("/info", InfoPage);
                 svr.RegisterHandler("/software", SoftwarePage);
+                svr.RegisterHandler("/reboot", RebootPage);
                 svr.RegisterHandler("/setup.xml", Setup_xml);
                 SSDP ssdp(My_Name, eth.getMACAddress(), eth.getIPAddress(), Server_Port);