A remote timer, equipped with a scheduling Web interface, controls a "DigitalOut".

Dependencies:   Timezone NTPClient

WebTimer

The WebTimer is an Mbed device enabling to remotely control a DigitalOut. It has a "calendar-like" user interface to edit the schedule - a table you can click on (or tap on a touch-screen device).
The program was ported to Mbed from the Tuxgraphics site. Thank you Guido for sharing!

  • When starting, it will print it's IP address over the USB serial link to the terminal screen. However, you can set a different static IP address if you modify the code in the main.cpp.
  • To connect to the WebTimer, type the IP address into the web browser edit box and hit ENTER.
  • When a cell is green then the timer keeps it's output ON during that period of time. If a cell is not green it means the output is OFF.
  • To select or deselect multiple cells you can click (keep down the button) and move the mouse over more cells.
  • The smallest time interval on this 24h timer is 15minutes.
  • To save the changes type in the password and hit ENTER or click on the Save button.
  • The default password is "secret". But you can change it by editing the source code in main.cpp.
OnDesktopOnPhone
Committer:
hudakz
Date:
Thu Nov 12 18:36:25 2020 +0000
Revision:
3:2862fe67dce0
Parent:
2:6d02d3d314a2
Child:
4:fe9189193dcd
A remote timer, equipped with a scheduling Web interface, controls a "DigitalOut".

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:f78e57015038 1 /*********************************************
hudakz 0:f78e57015038 2 * Author: Guido Socher
hudakz 0:f78e57015038 3 * Copyright: GPL V2
hudakz 0:f78e57015038 4 * See http://www.gnu.org/licenses/gpl.html
hudakz 0:f78e57015038 5 *
hudakz 0:f78e57015038 6 * 24h timer with web interface.
hudakz 0:f78e57015038 7 *
hudakz 0:f78e57015038 8 * See http://tuxgraphics.org/electronics/
hudakz 0:f78e57015038 9 *
hudakz 0:f78e57015038 10 * Ported to mbed by Zoltan Hudak
hudakz 0:f78e57015038 11 *********************************************/
hudakz 0:f78e57015038 12
hudakz 0:f78e57015038 13 #include "mbed.h"
hudakz 0:f78e57015038 14 #include "EthernetInterface.h"
hudakz 0:f78e57015038 15 #include "TCPSocket.h"
hudakz 0:f78e57015038 16 #include <stdio.h>
hudakz 0:f78e57015038 17 #include <string>
hudakz 0:f78e57015038 18 #include "websrv_help_functions.h"
hudakz 0:f78e57015038 19 #include "mbed_mktime.h"
hudakz 0:f78e57015038 20 #include "NTPClient.h"
hudakz 0:f78e57015038 21 #include "Timezone.h"
hudakz 0:f78e57015038 22
hudakz 0:f78e57015038 23 #define IP "192.168.1.181"
hudakz 0:f78e57015038 24 #define GATEWAY "192.168.1.1"
hudakz 0:f78e57015038 25 #define NETMASK "255.255.255.0"
hudakz 0:f78e57015038 26 #define PORT 80
hudakz 0:f78e57015038 27 #define STR_BUFFER_SIZE 40
hudakz 0:f78e57015038 28 #define NTP_SERVER "europe.pool.ntp.org"
hudakz 0:f78e57015038 29
hudakz 0:f78e57015038 30 /**/
hudakz 0:f78e57015038 31 EthernetInterface* net;
hudakz 0:f78e57015038 32 TCPSocket server;
hudakz 0:f78e57015038 33 TCPSocket* client;
hudakz 0:f78e57015038 34 char httpBuf[1500];
hudakz 0:f78e57015038 35 char httpHeader[256];
hudakz 0:f78e57015038 36 const int OFF = 0;
hudakz 0:f78e57015038 37 const int ON = 1;
hudakz 0:f78e57015038 38 const char PASSWORD[] = "secret"; // Change as you like
hudakz 0:f78e57015038 39 DigitalOut output(LED1);
hudakz 0:f78e57015038 40 char strBuf[STR_BUFFER_SIZE + 1];
hudakz 0:f78e57015038 41 uint16_t tablebitmap[6] = { 0 }; // each of the 96 bits represents one field in the time table
hudakz 0:f78e57015038 42 Thread thread;
hudakz 0:f78e57015038 43 EventQueue eventQueue;
hudakz 0:f78e57015038 44 tm tmNow;
hudakz 0:f78e57015038 45 DigitalOut relay(LED1, 0);
hudakz 0:f78e57015038 46 NTPClient* ntp;
hudakz 0:f78e57015038 47 TimeChangeRule cest = { "CEST", Last, Sun, Mar, 2, 1 * 60 }; // Central European Summer Time = NTP + 1 hour
hudakz 0:f78e57015038 48 TimeChangeRule cet = { "CET", Last, Sun, Oct, 2, 0 }; // Central European Time = NTP
hudakz 0:f78e57015038 49 Timezone cetZone(cest, cet); // Central European Time Zone
hudakz 0:f78e57015038 50
hudakz 0:f78e57015038 51 /**
hudakz 0:f78e57015038 52 * @brief
hudakz 0:f78e57015038 53 * @note
hudakz 0:f78e57015038 54 * @param
hudakz 0:f78e57015038 55 * @retval
hudakz 0:f78e57015038 56 */
hudakz 0:f78e57015038 57 uint8_t verifyPassword(char* str)
hudakz 0:f78e57015038 58 {
hudakz 0:f78e57015038 59 if (strncmp(PASSWORD, str, strlen(PASSWORD)) == 0)
hudakz 0:f78e57015038 60 return(1);
hudakz 0:f78e57015038 61 else
hudakz 0:f78e57015038 62 return(0);
hudakz 0:f78e57015038 63 }
hudakz 0:f78e57015038 64
hudakz 0:f78e57015038 65 /**
hudakz 0:f78e57015038 66 * @brief
hudakz 0:f78e57015038 67 * @note
hudakz 0:f78e57015038 68 * @param
hudakz 0:f78e57015038 69 * @retval
hudakz 0:f78e57015038 70 */
hudakz 0:f78e57015038 71 void setHeaderToHttp200ok(void)
hudakz 0:f78e57015038 72 {
hudakz 0:f78e57015038 73 strcpy(httpHeader, "HTTP/1.0 200 OK");
hudakz 0:f78e57015038 74 }
hudakz 0:f78e57015038 75
hudakz 0:f78e57015038 76 /**
hudakz 0:f78e57015038 77 * @brief
hudakz 0:f78e57015038 78 * @note
hudakz 0:f78e57015038 79 * @param
hudakz 0:f78e57015038 80 * @retval
hudakz 0:f78e57015038 81 */
hudakz 0:f78e57015038 82 void addHttpDataUint8(uint8_t i)
hudakz 0:f78e57015038 83 {
hudakz 0:f78e57015038 84 sprintf(strBuf, "%i", i); // convert integer to string
hudakz 0:f78e57015038 85 if (i < 10)
hudakz 0:f78e57015038 86 strcat(httpBuf, "0");
hudakz 0:f78e57015038 87 strcat(httpBuf, strBuf);
hudakz 0:f78e57015038 88 }
hudakz 0:f78e57015038 89
hudakz 0:f78e57015038 90 /**
hudakz 0:f78e57015038 91 * @brief
hudakz 0:f78e57015038 92 * @note
hudakz 0:f78e57015038 93 * @param
hudakz 0:f78e57015038 94 * @retval
hudakz 0:f78e57015038 95 */
hudakz 0:f78e57015038 96 void addHttpDataUint16(uint16_t ui)
hudakz 0:f78e57015038 97 {
hudakz 0:f78e57015038 98 uint8_t i = 6;
hudakz 0:f78e57015038 99 if (ui == 0) {
hudakz 0:f78e57015038 100 strcat(httpBuf, "0");
hudakz 0:f78e57015038 101 return;
hudakz 0:f78e57015038 102 }
hudakz 0:f78e57015038 103
hudakz 0:f78e57015038 104 // convert a 16bit unsigned integer into a printable string
hudakz 0:f78e57015038 105 strBuf[i] = '\0';
hudakz 0:f78e57015038 106 while (ui && i) {
hudakz 0:f78e57015038 107 i--;
hudakz 0:f78e57015038 108 strBuf[i] = (char)((ui % 10 & 0xf)) + 0x30;
hudakz 0:f78e57015038 109 ui = ui / 10;
hudakz 0:f78e57015038 110 }
hudakz 0:f78e57015038 111
hudakz 1:2d2517f82319 112 strcat(httpBuf, &strBuf[i]);
hudakz 0:f78e57015038 113 }
hudakz 0:f78e57015038 114
hudakz 2:6d02d3d314a2 115 /**
hudakz 2:6d02d3d314a2 116 * @brief Check the tablebitmap
hudakz 2:6d02d3d314a2 117 * @note
hudakz 2:6d02d3d314a2 118 * @param
hudakz 2:6d02d3d314a2 119 * @retval 0 there is no change compared to previous minute and current state is off
hudakz 2:6d02d3d314a2 120 * 1 the on/off state changed from on to off
hudakz 2:6d02d3d314a2 121 * 2 the on/off state changed from off to on
hudakz 2:6d02d3d314a2 122 * 3 there is no change compared to previous minute and current state is on
hudakz 0:f78e57015038 123 */
hudakz 2:6d02d3d314a2 124
hudakz 0:f78e57015038 125 uint8_t checkTableBitmap(uint8_t h, uint8_t m)
hudakz 0:f78e57015038 126 {
hudakz 0:f78e57015038 127 uint8_t tablepage, bitpos;
hudakz 0:f78e57015038 128 uint8_t curr = 0;
hudakz 0:f78e57015038 129 uint8_t prev = 0;
hudakz 0:f78e57015038 130 tablepage = h / 4; // which table page is the current
hudakz 0:f78e57015038 131 if (tablepage > 5)
hudakz 0:f78e57015038 132 tablepage = 5; // bounds check in case of garbage time
hudakz 0:f78e57015038 133 bitpos = ((h % 4) * 60 + m) / 15;
hudakz 0:f78e57015038 134 if (bitpos > 15)
hudakz 0:f78e57015038 135 bitpos = 15; // bounds check in case of garbage time
hudakz 0:f78e57015038 136 if (tablebitmap[tablepage] & (1 << bitpos)) {
hudakz 0:f78e57015038 137 curr = 1;
hudakz 0:f78e57015038 138 }
hudakz 0:f78e57015038 139
hudakz 0:f78e57015038 140 // now check what the previous value was
hudakz 0:f78e57015038 141 if (m > 0) {
hudakz 0:f78e57015038 142 m--;
hudakz 0:f78e57015038 143 }
hudakz 0:f78e57015038 144 else {
hudakz 0:f78e57015038 145 m = 59;
hudakz 0:f78e57015038 146 if (h > 0) {
hudakz 0:f78e57015038 147 h--;
hudakz 0:f78e57015038 148 }
hudakz 0:f78e57015038 149 else {
hudakz 0:f78e57015038 150 h = 23;
hudakz 0:f78e57015038 151 }
hudakz 0:f78e57015038 152 }
hudakz 0:f78e57015038 153
hudakz 0:f78e57015038 154 tablepage = h / 4; // which table page is the current
hudakz 0:f78e57015038 155 if (tablepage > 5)
hudakz 0:f78e57015038 156 tablepage = 5; // bounds check in case of garbage time
hudakz 0:f78e57015038 157 bitpos = ((h % 4) * 60 + m) / 15;
hudakz 0:f78e57015038 158 if (bitpos > 15)
hudakz 0:f78e57015038 159 bitpos = 15; // bounds check in case of garbage time
hudakz 0:f78e57015038 160 if (tablebitmap[tablepage] & (1 << bitpos)) {
hudakz 0:f78e57015038 161 prev = 1;
hudakz 0:f78e57015038 162 }
hudakz 0:f78e57015038 163
hudakz 0:f78e57015038 164 if (prev == curr && curr == 0)
hudakz 0:f78e57015038 165 return(0);
hudakz 0:f78e57015038 166 if (prev == curr && curr == 1)
hudakz 0:f78e57015038 167 return(3);
hudakz 0:f78e57015038 168 if (curr == 1 && prev == 0)
hudakz 0:f78e57015038 169 return(2);
hudakz 0:f78e57015038 170 return(1);
hudakz 0:f78e57015038 171 }
hudakz 0:f78e57015038 172
hudakz 0:f78e57015038 173 /**
hudakz 0:f78e57015038 174 * @brief
hudakz 0:f78e57015038 175 * @note
hudakz 0:f78e57015038 176 * @param
hudakz 0:f78e57015038 177 * @retval
hudakz 0:f78e57015038 178 */
hudakz 0:f78e57015038 179 void checkRelayStatus(void)
hudakz 0:f78e57015038 180 {
hudakz 0:f78e57015038 181 uint8_t i;
hudakz 0:f78e57015038 182 i = checkTableBitmap(tmNow.tm_hour, tmNow.tm_min);
hudakz 0:f78e57015038 183 if (i == 2 || i == 3) {
hudakz 0:f78e57015038 184 relay = ON;
hudakz 0:f78e57015038 185 }
hudakz 0:f78e57015038 186 else {
hudakz 0:f78e57015038 187 relay = OFF;
hudakz 0:f78e57015038 188 }
hudakz 0:f78e57015038 189 }
hudakz 0:f78e57015038 190
hudakz 0:f78e57015038 191 /**
hudakz 0:f78e57015038 192 * @brief
hudakz 0:f78e57015038 193 * @note
hudakz 0:f78e57015038 194 * @param
hudakz 0:f78e57015038 195 * @retval
hudakz 0:f78e57015038 196 */
hudakz 0:f78e57015038 197 void printPageSetClock(void)
hudakz 0:f78e57015038 198 {
hudakz 0:f78e57015038 199 strcpy(httpHeader, "HTTP/1.0 200 OK");
hudakz 0:f78e57015038 200 memset(httpBuf, 0, sizeof(httpBuf));
hudakz 0:f78e57015038 201 strcpy(httpBuf, "<meta name=viewport content=\"width=device-width\">\n");
hudakz 0:f78e57015038 202 strcat
hudakz 0:f78e57015038 203 (
hudakz 0:f78e57015038 204 httpBuf,
hudakz 0:f78e57015038 205 "<a href=/>[&#8592;Back]</a>\n"
hudakz 0:f78e57015038 206 "<h2>Set clock</h2>\n<pre>"
hudakz 0:f78e57015038 207 "<form action=cc method=get>\n"
hudakz 0:f78e57015038 208 "<blockquote>"
hudakz 0:f78e57015038 209 "<input type=radio name=mt value=0 checked>Automatically by NTP server<br>"
hudakz 0:f78e57015038 210 "<input type=radio name=mt value=1>Manually to"
hudakz 0:f78e57015038 211 "</blockquote>"
hudakz 0:f78e57015038 212 "time :<input type=text name=tv id=tf size=10>\n\n"
hudakz 0:f78e57015038 213 "passw:<input type=password name=pw size=10><input type=submit value=\"set time\">\n"
hudakz 0:f78e57015038 214 "</form>\n"
hudakz 0:f78e57015038 215 "<script>\n"
hudakz 0:f78e57015038 216 "d=new Date();\n"
hudakz 0:f78e57015038 217 "e=document.getElementById(\"tf\");\n"
hudakz 0:f78e57015038 218 "mo=d.getMonth()+1;\n"
hudakz 0:f78e57015038 219 "e.value=d.getFullYear()+\"-\"+mo+\"-\"+d.getDate()+\"-\"+d.getHours()+\":\"+d.getMinutes();\n"
hudakz 0:f78e57015038 220 "</script>\n"
hudakz 0:f78e57015038 221 "</pre><hr>\n"
hudakz 0:f78e57015038 222 );
hudakz 0:f78e57015038 223 }
hudakz 0:f78e57015038 224
hudakz 0:f78e57015038 225 /**
hudakz 0:f78e57015038 226 * @brief
hudakz 0:f78e57015038 227 * @note
hudakz 0:f78e57015038 228 * @param
hudakz 0:f78e57015038 229 * @retval
hudakz 0:f78e57015038 230 */
hudakz 0:f78e57015038 231 void printPageRelay(void)
hudakz 0:f78e57015038 232 {
hudakz 0:f78e57015038 233 setHeaderToHttp200ok();
hudakz 0:f78e57015038 234 memset(httpBuf, 0, sizeof(httpBuf));
hudakz 0:f78e57015038 235 strcpy(httpBuf, "<meta name=viewport content=\"width=device-width\">\n");
hudakz 0:f78e57015038 236 strcat(httpBuf, "<a href=/>[&#8592;Back]</a> <a href=/sw>[&#8635;Refresh]</a>\n""<h2>Switch</h2>\n""<pre>state: ");
hudakz 0:f78e57015038 237 if (relay == ON) {
hudakz 0:f78e57015038 238 strcat(httpBuf, "<font color=#00AA00>ON</font>");
hudakz 0:f78e57015038 239 }
hudakz 0:f78e57015038 240 else {
hudakz 0:f78e57015038 241 strcat(httpBuf, "OFF");
hudakz 0:f78e57015038 242 }
hudakz 0:f78e57015038 243
hudakz 0:f78e57015038 244 strcat(httpBuf, "\n<form action=/cr method=get>");
hudakz 0:f78e57015038 245 strcat(httpBuf, "<input type=hidden name=sw value=");
hudakz 0:f78e57015038 246 if (relay == ON) {
hudakz 0:f78e57015038 247 strcat(httpBuf, "0>\npassw: <input type=password size=10 name=pw>");
hudakz 0:f78e57015038 248 strcat(httpBuf, "<input type=submit value=\"switch off\"></form>\n");
hudakz 0:f78e57015038 249 }
hudakz 0:f78e57015038 250 else {
hudakz 0:f78e57015038 251 strcat(httpBuf, "1>\npassw: <input type=password size=10 name=pw>");
hudakz 0:f78e57015038 252 strcat(httpBuf, "<input type=submit value=\"switch on\"></form>\n");
hudakz 0:f78e57015038 253 }
hudakz 0:f78e57015038 254
hudakz 0:f78e57015038 255 strcat(httpBuf, "</pre><hr>\n");
hudakz 0:f78e57015038 256 }
hudakz 0:f78e57015038 257
hudakz 0:f78e57015038 258 /**
hudakz 0:f78e57015038 259 * @brief
hudakz 2:6d02d3d314a2 260 * @note In the function fill we encode all the 96 fiels into 6 numbers
hudakz 2:6d02d3d314a2 261 * with 16 bit. Every bit represents a table box. If the box was
hudakz 2:6d02d3d314a2 262 * green then the bit is 1 otherwise zero.
hudakz 0:f78e57015038 263 * @param
hudakz 0:f78e57015038 264 * @retval
hudakz 0:f78e57015038 265 */
hudakz 0:f78e57015038 266 void printJavaScriptFunctions(void)
hudakz 0:f78e57015038 267 {
hudakz 0:f78e57015038 268 setHeaderToHttp200ok();
hudakz 0:f78e57015038 269 memset(httpBuf, 0, sizeof(httpBuf));
hudakz 0:f78e57015038 270 strcpy
hudakz 0:f78e57015038 271 (
hudakz 0:f78e57015038 272 httpBuf,
hudakz 0:f78e57015038 273 "var col=\"\";\n"
hudakz 0:f78e57015038 274 "var cc=0;\n"
hudakz 0:f78e57015038 275 "var e,i,j;\n"
hudakz 0:f78e57015038 276 "function dw(s){document.writeln(s)}\n"
hudakz 0:f78e57015038 277 "function mc(e){if (cc) e.style.backgroundColor=col}\n"
hudakz 0:f78e57015038 278 "function wr(t,i){dw(\"<tr><td>\"+t+\"</td><td id=t\"+i+\" onmousedown=cbg(this) onmouseover=mc(this)>&nbsp;</td></tr>\")}\n"
hudakz 0:f78e57015038 279 "function dwh(s){dw(\"<table border=1><tr><td>Time</td><td>green=on<br>white=off</td></tr>\")}\n"
hudakz 0:f78e57015038 280 "function cbg(e)\n"
hudakz 0:f78e57015038 281 "{\n"
hudakz 0:f78e57015038 282 "cc=1;\n"
hudakz 0:f78e57015038 283 "col=e.style.backgroundColor ? \"\" : \"#7AFA7A\";\n"
hudakz 0:f78e57015038 284 "e.style.backgroundColor=col;\n"
hudakz 0:f78e57015038 285 "}\n"
hudakz 0:f78e57015038 286 "function sc(){cc=0}\n"
hudakz 0:f78e57015038 287 "function fill(ff){\n"
hudakz 0:f78e57015038 288 "var b=new Array();\n"
hudakz 0:f78e57015038 289 "for(i=0;i<6;i++){\n"
hudakz 0:f78e57015038 290 "b[i]=0;\n"
hudakz 0:f78e57015038 291 "for(j=0;j<16;j++){\n"
hudakz 0:f78e57015038 292 "e=document.getElementById(\"t\"+(i*16+j));\n"
hudakz 0:f78e57015038 293 "if (e.style.backgroundColor)\n"
hudakz 0:f78e57015038 294 "b[i]|=1<<j;\n"
hudakz 0:f78e57015038 295 "}\n"
hudakz 0:f78e57015038 296 "}\n"
hudakz 0:f78e57015038 297 "ff.elements[0].value=b[0] +\"-\"+b[1]+\"-\"+b[2]+\"-\"+b[3]+\"-\"+b[4]+\"-\"+b[5]+\"-\";\n"
hudakz 0:f78e57015038 298 "}\n"
hudakz 0:f78e57015038 299 "function it(a)\n"
hudakz 0:f78e57015038 300 "{\n"
hudakz 0:f78e57015038 301 "for(i=0;i<6;i++){\n"
hudakz 0:f78e57015038 302 "for(j=0;j<16;j++){\n"
hudakz 0:f78e57015038 303 "e=document.getElementById(\"t\"+(i*16+j));\n"
hudakz 0:f78e57015038 304 "if (a[i]&(1<<j))\n"
hudakz 0:f78e57015038 305 "e.style.backgroundColor=\"#7AFA7A\";\n"
hudakz 0:f78e57015038 306 "}\n"
hudakz 0:f78e57015038 307 "}\n"
hudakz 0:f78e57015038 308 "}"
hudakz 0:f78e57015038 309 );
hudakz 0:f78e57015038 310 }
hudakz 0:f78e57015038 311
hudakz 0:f78e57015038 312 /**
hudakz 2:6d02d3d314a2 313 * @brief This is the top level main web page
hudakz 0:f78e57015038 314 * @note
hudakz 0:f78e57015038 315 * @param
hudakz 0:f78e57015038 316 * @retval
hudakz 0:f78e57015038 317 */
hudakz 0:f78e57015038 318 void printPageMain(void)
hudakz 0:f78e57015038 319 {
hudakz 0:f78e57015038 320 setHeaderToHttp200ok();
hudakz 0:f78e57015038 321 memset(httpBuf, 0, sizeof(httpBuf));
hudakz 0:f78e57015038 322 strcpy
hudakz 0:f78e57015038 323 (
hudakz 0:f78e57015038 324 httpBuf,
hudakz 0:f78e57015038 325 "<meta name=viewport content=\"width=device-width\">\n"
hudakz 0:f78e57015038 326 "<a href=/sw>[Switch]</a> <a href=/sc>[Set clock]</a> <a href=/>[&#8635;Refresh]</a>\n"
hudakz 0:f78e57015038 327 );
hudakz 0:f78e57015038 328 strcat(httpBuf, "<h2><pre>Watering Timer<br>");
hudakz 0:f78e57015038 329
hudakz 0:f78e57015038 330 strcat(httpBuf, "Output: ");
hudakz 0:f78e57015038 331 if (relay == ON) {
hudakz 0:f78e57015038 332 strcat(httpBuf, "<font color=#00AA00>ON</font>");
hudakz 0:f78e57015038 333 }
hudakz 0:f78e57015038 334 else {
hudakz 0:f78e57015038 335 strcat(httpBuf, "OFF");
hudakz 0:f78e57015038 336 }
hudakz 0:f78e57015038 337
hudakz 0:f78e57015038 338 //strcat(httpBuf, "\n");
hudakz 0:f78e57015038 339 strcat(httpBuf, " Time: ");
hudakz 0:f78e57015038 340 addHttpDataUint8(tmNow.tm_hour);
hudakz 0:f78e57015038 341 strcat(httpBuf, ":");
hudakz 0:f78e57015038 342 addHttpDataUint8(tmNow.tm_min);
hudakz 0:f78e57015038 343 strcat(httpBuf, "</pre></h2>\n");
hudakz 0:f78e57015038 344 strcat
hudakz 0:f78e57015038 345 (
hudakz 0:f78e57015038 346 httpBuf,
hudakz 0:f78e57015038 347 //"<br>Click table fields to change.\n"
hudakz 0:f78e57015038 348 "<script src=p1.js></script>\n"
hudakz 0:f78e57015038 349 "<script>\n"
hudakz 0:f78e57015038 350 "dw(\"<table onmouseup=sc()>\");\n"
hudakz 0:f78e57015038 351 "dw(\"<tr><td>\");\n"
hudakz 0:f78e57015038 352 "dwh();\n"
hudakz 0:f78e57015038 353 "var i,t;\n"
hudakz 0:f78e57015038 354 "for(i=0;i<48;i++){\n"
hudakz 0:f78e57015038 355 "t=\"\";\n"
hudakz 0:f78e57015038 356 "if (i%4==0) t=i/4+\":00\";\n"
hudakz 0:f78e57015038 357 "wr(t,i);\n"
hudakz 0:f78e57015038 358 "}\n"
hudakz 0:f78e57015038 359 "dw(\"</table></td><td>\");\n"
hudakz 0:f78e57015038 360 "dwh();\n"
hudakz 0:f78e57015038 361 "for(i=48;i<96;i++){\n"
hudakz 0:f78e57015038 362 "t=\"\";\n"
hudakz 0:f78e57015038 363 "if (i%4==0) t=i/4+\":00\";\n"
hudakz 0:f78e57015038 364 "wr(t,i);\n"
hudakz 0:f78e57015038 365 "}\n"
hudakz 0:f78e57015038 366 "dw(\"</table></td></tr></table>\");\n"
hudakz 2:6d02d3d314a2 367 "dw(\"1 cell=15min\");\n"
hudakz 0:f78e57015038 368 );
hudakz 3:2862fe67dce0 369
hudakz 0:f78e57015038 370 // initialize the table with the current settings
hudakz 0:f78e57015038 371 strcat(httpBuf, "it(new Array(");
hudakz 0:f78e57015038 372 addHttpDataUint16(tablebitmap[0]);
hudakz 0:f78e57015038 373
hudakz 0:f78e57015038 374 int i = 1;
hudakz 0:f78e57015038 375 while (i < 6) {
hudakz 0:f78e57015038 376 strcat(httpBuf, ",");
hudakz 0:f78e57015038 377 addHttpDataUint16(tablebitmap[i]);
hudakz 0:f78e57015038 378 i++;
hudakz 0:f78e57015038 379 }
hudakz 0:f78e57015038 380
hudakz 0:f78e57015038 381 strcat(httpBuf, "));\n");
hudakz 0:f78e57015038 382 strcat(
hudakz 0:f78e57015038 383 httpBuf,
hudakz 0:f78e57015038 384 "</script>\n"
hudakz 0:f78e57015038 385 "<br><br>\n"
hudakz 0:f78e57015038 386 "<form onsubmit=fill(this) action=st method=get>\n"
hudakz 0:f78e57015038 387 "<input type=hidden name=tt>\n"
hudakz 0:f78e57015038 388 "passw: <input type=password size=10 name=pw>\n"
hudakz 0:f78e57015038 389 "<input type=submit value=save>\n"
hudakz 0:f78e57015038 390 "</form>\n"
hudakz 0:f78e57015038 391 );
hudakz 0:f78e57015038 392 }
hudakz 0:f78e57015038 393
hudakz 3:2862fe67dce0 394 /**
hudakz 3:2862fe67dce0 395 * @brief Takes a string of the form command/Number and analyses it.
hudakz 3:2862fe67dce0 396 * @note Thre string is like "cc?tv=8%3A15&pw=secret HTTP/1.1"
hudakz 3:2862fe67dce0 397 * The first char of the url ('/') is already removed.
hudakz 3:2862fe67dce0 398 * @param str The string to be analysed.
hudakz 3:2862fe67dce0 399 * @retval -1 Unauthorized
hudakz 3:2862fe67dce0 400 * 0 Page not found
hudakz 3:2862fe67dce0 401 * 1 Send page
hudakz 3:2862fe67dce0 402 * 2 Send Java Script function
hudakz 3:2862fe67dce0 403 *
hudakz 3:2862fe67dce0 404 */
hudakz 0:f78e57015038 405 int8_t analyseUrl(char* str)
hudakz 0:f78e57015038 406 {
hudakz 0:f78e57015038 407 int8_t i;
hudakz 0:f78e57015038 408 int8_t j;
hudakz 0:f78e57015038 409 uint8_t n;
hudakz 0:f78e57015038 410
hudakz 0:f78e57015038 411 if (str[0] == ' ') {
hudakz 0:f78e57015038 412 printPageMain();
hudakz 0:f78e57015038 413 return(1);
hudakz 0:f78e57015038 414 }
hudakz 0:f78e57015038 415
hudakz 0:f78e57015038 416 if (strncmp("sc", str, 2) == 0) {
hudakz 0:f78e57015038 417 printPageSetClock();
hudakz 0:f78e57015038 418 return(1);
hudakz 0:f78e57015038 419 }
hudakz 0:f78e57015038 420
hudakz 0:f78e57015038 421 if (strncmp("sw", str, 2) == 0) {
hudakz 0:f78e57015038 422 printPageRelay();
hudakz 0:f78e57015038 423 return(1);
hudakz 0:f78e57015038 424 }
hudakz 0:f78e57015038 425
hudakz 0:f78e57015038 426 if (strncmp("p1.js", str, 5) == 0) {
hudakz 0:f78e57015038 427 printJavaScriptFunctions();
hudakz 0:f78e57015038 428 return(2);
hudakz 0:f78e57015038 429 }
hudakz 0:f78e57015038 430
hudakz 0:f78e57015038 431 // save the tablebitmap
hudakz 0:f78e57015038 432 if (strncmp("st", str, 2) == 0) {
hudakz 0:f78e57015038 433
hudakz 0:f78e57015038 434 // save the tablebitmap
hudakz 0:f78e57015038 435 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"pw")) {
hudakz 0:f78e57015038 436 urldecode(strBuf);
hudakz 0:f78e57015038 437 if (verifyPassword(strBuf)) {
hudakz 0:f78e57015038 438 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"tt")) {
hudakz 0:f78e57015038 439 urldecode(strBuf);
hudakz 0:f78e57015038 440 strBuf[37] = '\0'; // max length
hudakz 0:f78e57015038 441
hudakz 0:f78e57015038 442 // gStrbuf is a string like this: 11-58-0-0-0-0-
hudakz 0:f78e57015038 443 // no space allowed
hudakz 0:f78e57015038 444 if (!isdigit(strBuf[0])) {
hudakz 0:f78e57015038 445 return(0);
hudakz 0:f78e57015038 446 }
hudakz 0:f78e57015038 447
hudakz 0:f78e57015038 448 n = 0;
hudakz 0:f78e57015038 449 i = 0;
hudakz 0:f78e57015038 450 j = 0;
hudakz 0:f78e57015038 451 while (strBuf[i] && n < 6) {
hudakz 0:f78e57015038 452 if (strBuf[i] == '-') {
hudakz 0:f78e57015038 453 strBuf[i] = '\0';
hudakz 0:f78e57015038 454 tablebitmap[n] = atol(&strBuf[j]);
hudakz 0:f78e57015038 455 n++;
hudakz 0:f78e57015038 456 j = i + 1;
hudakz 0:f78e57015038 457 }
hudakz 0:f78e57015038 458
hudakz 0:f78e57015038 459 i++;
hudakz 0:f78e57015038 460 }
hudakz 0:f78e57015038 461
hudakz 0:f78e57015038 462 checkRelayStatus();
hudakz 0:f78e57015038 463 printPageMain();
hudakz 0:f78e57015038 464 return(1); // main page
hudakz 0:f78e57015038 465 }
hudakz 0:f78e57015038 466 }
hudakz 0:f78e57015038 467 }
hudakz 0:f78e57015038 468
hudakz 0:f78e57015038 469 return(-1);
hudakz 0:f78e57015038 470 }
hudakz 0:f78e57015038 471
hudakz 0:f78e57015038 472 // change clock
hudakz 0:f78e57015038 473 if (strncmp("cc", str, 2) == 0) {
hudakz 0:f78e57015038 474 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"pw")) {
hudakz 0:f78e57015038 475 urldecode(strBuf);
hudakz 0:f78e57015038 476 if (verifyPassword(strBuf)) {
hudakz 0:f78e57015038 477 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"mt")) {
hudakz 0:f78e57015038 478 urldecode(strBuf);
hudakz 0:f78e57015038 479 if (strBuf[0] == '0') {
hudakz 0:f78e57015038 480 ntp->setTime(NTP_SERVER, 123, 3000); // set clock
hudakz 0:f78e57015038 481 set_time(cetZone.toLocal(rtc_read())); // daylight saving time
hudakz 0:f78e57015038 482 }
hudakz 0:f78e57015038 483 else
hudakz 0:f78e57015038 484 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"tv")) {
hudakz 0:f78e57015038 485 urldecode(strBuf);
hudakz 0:f78e57015038 486 strBuf[16] = '\0';
hudakz 0:f78e57015038 487
hudakz 0:f78e57015038 488 // strBuf is a string like: 2020-10-21-11:58
hudakz 0:f78e57015038 489 // no space allowed
hudakz 0:f78e57015038 490 if (!isdigit(strBuf[0])) {
hudakz 0:f78e57015038 491 return(0);
hudakz 0:f78e57015038 492 }
hudakz 0:f78e57015038 493
hudakz 0:f78e57015038 494 char* token = strBuf;
hudakz 0:f78e57015038 495 char* delim;
hudakz 0:f78e57015038 496
hudakz 0:f78e57015038 497 delim = strchr(token, '-');
hudakz 0:f78e57015038 498 *delim = '\0';
hudakz 0:f78e57015038 499 tmNow.tm_year = atoi(token) - 1900;
hudakz 0:f78e57015038 500
hudakz 0:f78e57015038 501 token = delim + 1;
hudakz 0:f78e57015038 502 delim = strchr(token, '-');
hudakz 0:f78e57015038 503 *delim = '\0';
hudakz 0:f78e57015038 504 tmNow.tm_mon = atoi(token) - 1;
hudakz 0:f78e57015038 505
hudakz 0:f78e57015038 506 token = delim + 1;
hudakz 0:f78e57015038 507 delim = strchr(token, '-');
hudakz 0:f78e57015038 508 *delim = '\0';
hudakz 0:f78e57015038 509 tmNow.tm_mday = atoi(token);
hudakz 0:f78e57015038 510
hudakz 0:f78e57015038 511 token = delim + 1;
hudakz 0:f78e57015038 512 delim = strchr(token, ':');
hudakz 0:f78e57015038 513 *delim = '\0';
hudakz 0:f78e57015038 514 tmNow.tm_hour = atoi(token);
hudakz 0:f78e57015038 515
hudakz 0:f78e57015038 516 token = delim + 1;
hudakz 0:f78e57015038 517 tmNow.tm_min = atoi(token);
hudakz 0:f78e57015038 518
hudakz 0:f78e57015038 519 tmNow.tm_isdst = 1; // apply daylight saving
hudakz 0:f78e57015038 520 time_t seconds;
hudakz 0:f78e57015038 521
hudakz 0:f78e57015038 522 _rtc_maketime(&tmNow, &seconds, RTC_FULL_LEAP_YEAR_SUPPORT);
hudakz 0:f78e57015038 523 set_time(seconds);
hudakz 0:f78e57015038 524 }
hudakz 0:f78e57015038 525
hudakz 0:f78e57015038 526 time_t seconds = rtc_read();
hudakz 0:f78e57015038 527 _rtc_localtime(seconds, &tmNow, RTC_FULL_LEAP_YEAR_SUPPORT);
hudakz 0:f78e57015038 528 checkRelayStatus();
hudakz 0:f78e57015038 529 printPageMain();
hudakz 0:f78e57015038 530 return(1); // main page
hudakz 0:f78e57015038 531 }
hudakz 0:f78e57015038 532
hudakz 0:f78e57015038 533 return(0);
hudakz 0:f78e57015038 534 }
hudakz 0:f78e57015038 535 }
hudakz 0:f78e57015038 536
hudakz 0:f78e57015038 537 return(-1);
hudakz 0:f78e57015038 538 }
hudakz 0:f78e57015038 539
hudakz 0:f78e57015038 540 i = 0; // switch on or off
hudakz 0:f78e57015038 541
hudakz 0:f78e57015038 542 // change relay state FORM
hudakz 0:f78e57015038 543 if (strncmp("cr", str, 2) == 0) {
hudakz 0:f78e57015038 544 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"sw")) {
hudakz 0:f78e57015038 545 if (strBuf[0] == '1') {
hudakz 0:f78e57015038 546 i = 1;
hudakz 0:f78e57015038 547 }
hudakz 0:f78e57015038 548
hudakz 0:f78e57015038 549 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"pw")) {
hudakz 0:f78e57015038 550 urldecode(strBuf);
hudakz 0:f78e57015038 551 if (verifyPassword(strBuf)) {
hudakz 0:f78e57015038 552 if (i)
hudakz 0:f78e57015038 553 relay = ON;
hudakz 0:f78e57015038 554 else
hudakz 0:f78e57015038 555 relay = OFF;
hudakz 0:f78e57015038 556
hudakz 0:f78e57015038 557 printPageMain();
hudakz 0:f78e57015038 558 return(1); // main page
hudakz 0:f78e57015038 559 }
hudakz 0:f78e57015038 560 }
hudakz 0:f78e57015038 561
hudakz 0:f78e57015038 562 return(-1);
hudakz 0:f78e57015038 563 }
hudakz 0:f78e57015038 564
hudakz 0:f78e57015038 565 return(0);
hudakz 0:f78e57015038 566 }
hudakz 0:f78e57015038 567
hudakz 0:f78e57015038 568 return(0);
hudakz 0:f78e57015038 569 }
hudakz 0:f78e57015038 570
hudakz 0:f78e57015038 571 /**
hudakz 0:f78e57015038 572 * @brief
hudakz 0:f78e57015038 573 * @note
hudakz 0:f78e57015038 574 * @param
hudakz 0:f78e57015038 575 * @retval
hudakz 0:f78e57015038 576 */
hudakz 0:f78e57015038 577 void sendHttp(TCPSocket* client, char* header, char* content, bool js = false)
hudakz 0:f78e57015038 578 {
hudakz 0:f78e57015038 579 char content_length[10] = { };
hudakz 0:f78e57015038 580
hudakz 0:f78e57015038 581 sprintf(content_length, "%u\r\n", strlen(content));
hudakz 0:f78e57015038 582
hudakz 0:f78e57015038 583 if (js) {
hudakz 0:f78e57015038 584 strcat(header, "Content-Type: application/x-javascript\r\n\r\n");
hudakz 0:f78e57015038 585 }
hudakz 0:f78e57015038 586 else {
hudakz 0:f78e57015038 587 strcat(header, "\r\nContent-Type: text/html\r\n");
hudakz 0:f78e57015038 588 strcat(header, "Content-Length: ");
hudakz 0:f78e57015038 589 strcat(header, content_length);
hudakz 0:f78e57015038 590 strcat(header, "Pragma: no-cache\r\n");
hudakz 0:f78e57015038 591 strcat(header, "Connection: About to close\r\n\r\n");
hudakz 0:f78e57015038 592 }
hudakz 0:f78e57015038 593
hudakz 0:f78e57015038 594 char c = content[0];
hudakz 0:f78e57015038 595 memmove(httpBuf + strlen(header), httpBuf, strlen(content)); // make room for the header
hudakz 0:f78e57015038 596 strcpy(httpBuf, header); // copy the header on front of the content
hudakz 0:f78e57015038 597 httpBuf[strlen(header)] = c;
hudakz 0:f78e57015038 598 client->send((uint8_t*)httpBuf, strlen(httpBuf));
hudakz 0:f78e57015038 599 }
hudakz 0:f78e57015038 600
hudakz 0:f78e57015038 601 /**
hudakz 0:f78e57015038 602 * @brief
hudakz 0:f78e57015038 603 * @note
hudakz 0:f78e57015038 604 * @param
hudakz 0:f78e57015038 605 * @retval
hudakz 0:f78e57015038 606 */
hudakz 0:f78e57015038 607 void onTick()
hudakz 0:f78e57015038 608 {
hudakz 0:f78e57015038 609 time_t seconds = rtc_read();
hudakz 0:f78e57015038 610 #ifdef DEBUG
hudakz 0:f78e57015038 611 printf("Seconds since January 1, 1970 = %llu s\r\n", seconds);
hudakz 0:f78e57015038 612 #endif
hudakz 0:f78e57015038 613 _rtc_localtime(seconds, &tmNow, RTC_FULL_LEAP_YEAR_SUPPORT);
hudakz 0:f78e57015038 614 checkRelayStatus();
hudakz 0:f78e57015038 615 }
hudakz 0:f78e57015038 616
hudakz 0:f78e57015038 617 /**
hudakz 0:f78e57015038 618 * @brief
hudakz 0:f78e57015038 619 * @note
hudakz 0:f78e57015038 620 * @param
hudakz 0:f78e57015038 621 * @retval
hudakz 0:f78e57015038 622 */
hudakz 0:f78e57015038 623 int main(void)
hudakz 0:f78e57015038 624 {
hudakz 0:f78e57015038 625 printf("\r\nStarting..\r\n");
hudakz 0:f78e57015038 626
hudakz 0:f78e57015038 627 eventQueue.call_every(1s, onTick);
hudakz 0:f78e57015038 628 thread.start(callback(&eventQueue, &EventQueue::dispatch_forever));
hudakz 0:f78e57015038 629
hudakz 0:f78e57015038 630 //net = NetworkInterface::get_default_instance();
hudakz 0:f78e57015038 631 net = new EthernetInterface();
hudakz 0:f78e57015038 632
hudakz 0:f78e57015038 633 //net->set_network("192.168.1.181","255.255.255.0","192.168.1.1"); // use static IP address, netmask, gateway
hudakz 0:f78e57015038 634 if (!net) {
hudakz 0:f78e57015038 635 printf("Error! No network inteface found.\n");
hudakz 0:f78e57015038 636 return 0;
hudakz 0:f78e57015038 637 }
hudakz 0:f78e57015038 638
hudakz 0:f78e57015038 639 //net->set_network (IP, NETMASK, GATEWAY); // include this to use static IP address
hudakz 0:f78e57015038 640 nsapi_size_or_error_t r = net->connect();
hudakz 0:f78e57015038 641 if (r != NSAPI_ERROR_OK) {
hudakz 0:f78e57015038 642 printf("Error! net->connect() returned: %d\n", r);
hudakz 0:f78e57015038 643 return r;
hudakz 0:f78e57015038 644 }
hudakz 0:f78e57015038 645
hudakz 0:f78e57015038 646 // Show the network address
hudakz 0:f78e57015038 647 SocketAddress addr;
hudakz 0:f78e57015038 648 net->get_ip_address(&addr);
hudakz 0:f78e57015038 649 printf("IP address: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
hudakz 0:f78e57015038 650 net->get_netmask(&addr);
hudakz 0:f78e57015038 651 printf("Netmask: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
hudakz 0:f78e57015038 652 net->get_gateway(&addr);
hudakz 0:f78e57015038 653 printf("Gateway: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
hudakz 0:f78e57015038 654
hudakz 0:f78e57015038 655 // Create NTP connection
hudakz 0:f78e57015038 656 ntp = new NTPClient(*net);
hudakz 0:f78e57015038 657 ntp->setTime(NTP_SERVER, 123, 3000); // set clock
hudakz 0:f78e57015038 658 set_time(cetZone.toLocal(rtc_read())); // daylight saving time
hudakz 0:f78e57015038 659
hudakz 0:f78e57015038 660 /* Open the server on ethernet stack */
hudakz 0:f78e57015038 661 server.open(net);
hudakz 0:f78e57015038 662
hudakz 0:f78e57015038 663 /* Bind the HTTP port (TCP 80) to the server */
hudakz 0:f78e57015038 664 server.bind(PORT);
hudakz 0:f78e57015038 665
hudakz 0:f78e57015038 666 /* Listen for clients */
hudakz 0:f78e57015038 667 server.listen();
hudakz 0:f78e57015038 668
hudakz 0:f78e57015038 669 //listening for http GET request
hudakz 0:f78e57015038 670 while (true) {
hudakz 0:f78e57015038 671 client = server.accept();
hudakz 0:f78e57015038 672 if (client)
hudakz 0:f78e57015038 673 {
hudakz 0:f78e57015038 674 #ifdef DEBUG
hudakz 0:f78e57015038 675 client->getpeername(&addr);
hudakz 0:f78e57015038 676 printf("Connection succeeded!\n\rIP: %s\n\r", addr.get_ip_address());
hudakz 0:f78e57015038 677 #endif
hudakz 0:f78e57015038 678 client->recv(httpBuf, 1500);
hudakz 0:f78e57015038 679 if (strncmp(httpBuf, "GET", 3) != 0) {
hudakz 0:f78e57015038 680 setHeaderToHttp200ok();
hudakz 0:f78e57015038 681 strcpy(httpBuf, "<h1>200 OK</h1>");
hudakz 0:f78e57015038 682 sendHttp(client, httpHeader, httpBuf);
hudakz 0:f78e57015038 683 }
hudakz 0:f78e57015038 684 else {
hudakz 0:f78e57015038 685 int cmd = analyseUrl((char*) &httpBuf[5]); // "GET [this is the tex to be analysed]"
hudakz 0:f78e57015038 686
hudakz 0:f78e57015038 687 switch (cmd) {
hudakz 0:f78e57015038 688 case -1:
hudakz 0:f78e57015038 689 strcpy(httpHeader, "HTTP/1.0 401 Unauthorized");
hudakz 0:f78e57015038 690 strcpy(httpBuf, "<h1>401 Unauthorized</h1>");
hudakz 0:f78e57015038 691 sendHttp(client, httpHeader, httpBuf);
hudakz 0:f78e57015038 692 break;
hudakz 0:f78e57015038 693
hudakz 0:f78e57015038 694 case 0:
hudakz 0:f78e57015038 695 strcpy(httpHeader, "HTTP/1.0 404 Page Not Found");
hudakz 0:f78e57015038 696 strcpy(httpBuf, "<h1>404 Page Not Found</h1>");
hudakz 0:f78e57015038 697 sendHttp(client, httpHeader, httpBuf);
hudakz 0:f78e57015038 698 break;
hudakz 0:f78e57015038 699
hudakz 0:f78e57015038 700 case 1:
hudakz 0:f78e57015038 701 sendHttp(client, httpHeader, httpBuf);
hudakz 0:f78e57015038 702 break;
hudakz 0:f78e57015038 703
hudakz 0:f78e57015038 704 case 2:
hudakz 0:f78e57015038 705 sendHttp(client, httpHeader, httpBuf, true);
hudakz 0:f78e57015038 706 break;
hudakz 0:f78e57015038 707 }
hudakz 0:f78e57015038 708 }
hudakz 0:f78e57015038 709
hudakz 0:f78e57015038 710 client->close();
hudakz 0:f78e57015038 711 }
hudakz 0:f78e57015038 712 }
hudakz 0:f78e57015038 713 }