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:23:29 2020 +0000
Revision:
2:6d02d3d314a2
Parent:
1:2d2517f82319
Child:
3:2862fe67dce0
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 /*$off*/
hudakz 0:f78e57015038 203 strcat
hudakz 0:f78e57015038 204 (
hudakz 0:f78e57015038 205 httpBuf,
hudakz 0:f78e57015038 206 "<a href=/>[&#8592;Back]</a>\n"
hudakz 0:f78e57015038 207 "<h2>Set clock</h2>\n<pre>"
hudakz 0:f78e57015038 208 "<form action=cc method=get>\n"
hudakz 0:f78e57015038 209 "<blockquote>"
hudakz 0:f78e57015038 210 "<input type=radio name=mt value=0 checked>Automatically by NTP server<br>"
hudakz 0:f78e57015038 211 "<input type=radio name=mt value=1>Manually to"
hudakz 0:f78e57015038 212 "</blockquote>"
hudakz 0:f78e57015038 213 "time :<input type=text name=tv id=tf size=10>\n\n"
hudakz 0:f78e57015038 214 "passw:<input type=password name=pw size=10><input type=submit value=\"set time\">\n"
hudakz 0:f78e57015038 215 "</form>\n"
hudakz 0:f78e57015038 216 "<script>\n"
hudakz 0:f78e57015038 217 "d=new Date();\n"
hudakz 0:f78e57015038 218 "e=document.getElementById(\"tf\");\n"
hudakz 0:f78e57015038 219 "mo=d.getMonth()+1;\n"
hudakz 0:f78e57015038 220 "e.value=d.getFullYear()+\"-\"+mo+\"-\"+d.getDate()+\"-\"+d.getHours()+\":\"+d.getMinutes();\n"
hudakz 0:f78e57015038 221 "</script>\n"
hudakz 0:f78e57015038 222 "</pre><hr>\n"
hudakz 0:f78e57015038 223 );
hudakz 0:f78e57015038 224 /*$on*/
hudakz 0:f78e57015038 225 }
hudakz 0:f78e57015038 226
hudakz 0:f78e57015038 227 /**
hudakz 0:f78e57015038 228 * @brief
hudakz 0:f78e57015038 229 * @note
hudakz 0:f78e57015038 230 * @param
hudakz 0:f78e57015038 231 * @retval
hudakz 0:f78e57015038 232 */
hudakz 0:f78e57015038 233 void printPageRelay(void)
hudakz 0:f78e57015038 234 {
hudakz 0:f78e57015038 235 setHeaderToHttp200ok();
hudakz 0:f78e57015038 236 memset(httpBuf, 0, sizeof(httpBuf));
hudakz 0:f78e57015038 237 strcpy(httpBuf, "<meta name=viewport content=\"width=device-width\">\n");
hudakz 0:f78e57015038 238 strcat(httpBuf, "<a href=/>[&#8592;Back]</a> <a href=/sw>[&#8635;Refresh]</a>\n""<h2>Switch</h2>\n""<pre>state: ");
hudakz 0:f78e57015038 239 if (relay == ON) {
hudakz 0:f78e57015038 240 strcat(httpBuf, "<font color=#00AA00>ON</font>");
hudakz 0:f78e57015038 241 }
hudakz 0:f78e57015038 242 else {
hudakz 0:f78e57015038 243 strcat(httpBuf, "OFF");
hudakz 0:f78e57015038 244 }
hudakz 0:f78e57015038 245
hudakz 0:f78e57015038 246 strcat(httpBuf, "\n<form action=/cr method=get>");
hudakz 0:f78e57015038 247 strcat(httpBuf, "<input type=hidden name=sw value=");
hudakz 0:f78e57015038 248 if (relay == ON) {
hudakz 0:f78e57015038 249 strcat(httpBuf, "0>\npassw: <input type=password size=10 name=pw>");
hudakz 0:f78e57015038 250 strcat(httpBuf, "<input type=submit value=\"switch off\"></form>\n");
hudakz 0:f78e57015038 251 }
hudakz 0:f78e57015038 252 else {
hudakz 0:f78e57015038 253 strcat(httpBuf, "1>\npassw: <input type=password size=10 name=pw>");
hudakz 0:f78e57015038 254 strcat(httpBuf, "<input type=submit value=\"switch on\"></form>\n");
hudakz 0:f78e57015038 255 }
hudakz 0:f78e57015038 256
hudakz 0:f78e57015038 257 strcat(httpBuf, "</pre><hr>\n");
hudakz 0:f78e57015038 258 }
hudakz 0:f78e57015038 259
hudakz 0:f78e57015038 260 /**
hudakz 0:f78e57015038 261 * @brief
hudakz 2:6d02d3d314a2 262 * @note In the function fill we encode all the 96 fiels into 6 numbers
hudakz 2:6d02d3d314a2 263 * with 16 bit. Every bit represents a table box. If the box was
hudakz 2:6d02d3d314a2 264 * green then the bit is 1 otherwise zero.
hudakz 0:f78e57015038 265 * @param
hudakz 0:f78e57015038 266 * @retval
hudakz 0:f78e57015038 267 */
hudakz 0:f78e57015038 268 void printJavaScriptFunctions(void)
hudakz 0:f78e57015038 269 {
hudakz 0:f78e57015038 270 setHeaderToHttp200ok();
hudakz 0:f78e57015038 271
hudakz 0:f78e57015038 272 //
hudakz 0:f78e57015038 273 /*$off*/
hudakz 0:f78e57015038 274 memset(httpBuf, 0, sizeof(httpBuf));
hudakz 0:f78e57015038 275 strcpy
hudakz 0:f78e57015038 276 (
hudakz 0:f78e57015038 277 httpBuf,
hudakz 0:f78e57015038 278 "var col=\"\";\n"
hudakz 0:f78e57015038 279 "var cc=0;\n"
hudakz 0:f78e57015038 280 "var e,i,j;\n"
hudakz 0:f78e57015038 281 "function dw(s){document.writeln(s)}\n"
hudakz 0:f78e57015038 282 "function mc(e){if (cc) e.style.backgroundColor=col}\n"
hudakz 0:f78e57015038 283 "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 284 "function dwh(s){dw(\"<table border=1><tr><td>Time</td><td>green=on<br>white=off</td></tr>\")}\n"
hudakz 0:f78e57015038 285 "function cbg(e)\n"
hudakz 0:f78e57015038 286 "{\n"
hudakz 0:f78e57015038 287 "cc=1;\n"
hudakz 0:f78e57015038 288 "col=e.style.backgroundColor ? \"\" : \"#7AFA7A\";\n"
hudakz 0:f78e57015038 289 "e.style.backgroundColor=col;\n"
hudakz 0:f78e57015038 290 "}\n"
hudakz 0:f78e57015038 291 "function sc(){cc=0}\n"
hudakz 0:f78e57015038 292 "function fill(ff){\n"
hudakz 0:f78e57015038 293 "var b=new Array();\n"
hudakz 0:f78e57015038 294 "for(i=0;i<6;i++){\n"
hudakz 0:f78e57015038 295 "b[i]=0;\n"
hudakz 0:f78e57015038 296 "for(j=0;j<16;j++){\n"
hudakz 0:f78e57015038 297 "e=document.getElementById(\"t\"+(i*16+j));\n"
hudakz 0:f78e57015038 298 "if (e.style.backgroundColor)\n"
hudakz 0:f78e57015038 299 "b[i]|=1<<j;\n"
hudakz 0:f78e57015038 300 "}\n"
hudakz 0:f78e57015038 301 "}\n"
hudakz 0:f78e57015038 302 "ff.elements[0].value=b[0] +\"-\"+b[1]+\"-\"+b[2]+\"-\"+b[3]+\"-\"+b[4]+\"-\"+b[5]+\"-\";\n"
hudakz 0:f78e57015038 303 "}\n"
hudakz 0:f78e57015038 304 "function it(a)\n"
hudakz 0:f78e57015038 305 "{\n"
hudakz 0:f78e57015038 306 "for(i=0;i<6;i++){\n"
hudakz 0:f78e57015038 307 "for(j=0;j<16;j++){\n"
hudakz 0:f78e57015038 308 "e=document.getElementById(\"t\"+(i*16+j));\n"
hudakz 0:f78e57015038 309 "if (a[i]&(1<<j))\n"
hudakz 0:f78e57015038 310 "e.style.backgroundColor=\"#7AFA7A\";\n"
hudakz 0:f78e57015038 311 "}\n"
hudakz 0:f78e57015038 312 "}\n"
hudakz 0:f78e57015038 313 "}"
hudakz 0:f78e57015038 314 );
hudakz 0:f78e57015038 315 /*$on*/
hudakz 0:f78e57015038 316 }
hudakz 0:f78e57015038 317
hudakz 0:f78e57015038 318 /**
hudakz 2:6d02d3d314a2 319 * @brief This is the top level main web page
hudakz 0:f78e57015038 320 * @note
hudakz 0:f78e57015038 321 * @param
hudakz 0:f78e57015038 322 * @retval
hudakz 0:f78e57015038 323 */
hudakz 0:f78e57015038 324 void printPageMain(void)
hudakz 0:f78e57015038 325 {
hudakz 0:f78e57015038 326 setHeaderToHttp200ok();
hudakz 0:f78e57015038 327 memset(httpBuf, 0, sizeof(httpBuf));
hudakz 0:f78e57015038 328 strcpy
hudakz 0:f78e57015038 329 (
hudakz 0:f78e57015038 330 httpBuf,
hudakz 0:f78e57015038 331 "<meta name=viewport content=\"width=device-width\">\n"
hudakz 0:f78e57015038 332 "<a href=/sw>[Switch]</a> <a href=/sc>[Set clock]</a> <a href=/>[&#8635;Refresh]</a>\n"
hudakz 0:f78e57015038 333 );
hudakz 0:f78e57015038 334 /*$on*/
hudakz 0:f78e57015038 335 strcat(httpBuf, "<h2><pre>Watering Timer<br>");
hudakz 0:f78e57015038 336
hudakz 0:f78e57015038 337 strcat(httpBuf, "Output: ");
hudakz 0:f78e57015038 338 if (relay == ON) {
hudakz 0:f78e57015038 339 strcat(httpBuf, "<font color=#00AA00>ON</font>");
hudakz 0:f78e57015038 340 }
hudakz 0:f78e57015038 341 else {
hudakz 0:f78e57015038 342 strcat(httpBuf, "OFF");
hudakz 0:f78e57015038 343 }
hudakz 0:f78e57015038 344
hudakz 0:f78e57015038 345 //strcat(httpBuf, "\n");
hudakz 0:f78e57015038 346 strcat(httpBuf, " Time: ");
hudakz 0:f78e57015038 347 addHttpDataUint8(tmNow.tm_hour);
hudakz 0:f78e57015038 348 strcat(httpBuf, ":");
hudakz 0:f78e57015038 349 addHttpDataUint8(tmNow.tm_min);
hudakz 0:f78e57015038 350 strcat(httpBuf, "</pre></h2>\n");
hudakz 0:f78e57015038 351 /*$off*/
hudakz 0:f78e57015038 352 strcat
hudakz 0:f78e57015038 353 (
hudakz 0:f78e57015038 354 httpBuf,
hudakz 0:f78e57015038 355 //"<br>Click table fields to change.\n"
hudakz 0:f78e57015038 356 "<script src=p1.js></script>\n"
hudakz 0:f78e57015038 357 "<script>\n"
hudakz 0:f78e57015038 358 "dw(\"<table onmouseup=sc()>\");\n"
hudakz 0:f78e57015038 359 "dw(\"<tr><td>\");\n"
hudakz 0:f78e57015038 360 "dwh();\n"
hudakz 0:f78e57015038 361 "var i,t;\n"
hudakz 0:f78e57015038 362 "for(i=0;i<48;i++){\n"
hudakz 0:f78e57015038 363 "t=\"\";\n"
hudakz 0:f78e57015038 364 "if (i%4==0) t=i/4+\":00\";\n"
hudakz 0:f78e57015038 365 "wr(t,i);\n"
hudakz 0:f78e57015038 366 "}\n"
hudakz 0:f78e57015038 367 "dw(\"</table></td><td>\");\n"
hudakz 0:f78e57015038 368 "dwh();\n"
hudakz 0:f78e57015038 369 "for(i=48;i<96;i++){\n"
hudakz 0:f78e57015038 370 "t=\"\";\n"
hudakz 0:f78e57015038 371 "if (i%4==0) t=i/4+\":00\";\n"
hudakz 0:f78e57015038 372 "wr(t,i);\n"
hudakz 0:f78e57015038 373 "}\n"
hudakz 0:f78e57015038 374 "dw(\"</table></td></tr></table>\");\n"
hudakz 2:6d02d3d314a2 375 "dw(\"1 cell=15min\");\n"
hudakz 0:f78e57015038 376 );
hudakz 0:f78e57015038 377 /*$on*/
hudakz 0:f78e57015038 378 // initialize the table with the current settings
hudakz 0:f78e57015038 379 strcat(httpBuf, "it(new Array(");
hudakz 0:f78e57015038 380 addHttpDataUint16(tablebitmap[0]);
hudakz 0:f78e57015038 381
hudakz 0:f78e57015038 382 int i = 1;
hudakz 0:f78e57015038 383 while (i < 6) {
hudakz 0:f78e57015038 384 strcat(httpBuf, ",");
hudakz 0:f78e57015038 385 addHttpDataUint16(tablebitmap[i]);
hudakz 0:f78e57015038 386 i++;
hudakz 0:f78e57015038 387 }
hudakz 0:f78e57015038 388
hudakz 0:f78e57015038 389 strcat(httpBuf, "));\n");
hudakz 0:f78e57015038 390 /*$off*/
hudakz 0:f78e57015038 391 strcat(
hudakz 0:f78e57015038 392 httpBuf,
hudakz 0:f78e57015038 393 "</script>\n"
hudakz 0:f78e57015038 394 "<br><br>\n"
hudakz 0:f78e57015038 395 "<form onsubmit=fill(this) action=st method=get>\n"
hudakz 0:f78e57015038 396 "<input type=hidden name=tt>\n"
hudakz 0:f78e57015038 397 "passw: <input type=password size=10 name=pw>\n"
hudakz 0:f78e57015038 398 "<input type=submit value=save>\n"
hudakz 0:f78e57015038 399 "</form>\n"
hudakz 0:f78e57015038 400 );
hudakz 0:f78e57015038 401 /*$on*/
hudakz 0:f78e57015038 402 }
hudakz 0:f78e57015038 403
hudakz 0:f78e57015038 404 // takes a string of the form command/Number and analyse it (e.g "cc?tv=8%3A15&pw=secret HTTP/1.1")
hudakz 0:f78e57015038 405
hudakz 0:f78e57015038 406 // The first char of the url ('/') is already removed.
hudakz 0:f78e57015038 407 int8_t analyseUrl(char* str)
hudakz 0:f78e57015038 408 {
hudakz 0:f78e57015038 409 int8_t i;
hudakz 0:f78e57015038 410 int8_t j;
hudakz 0:f78e57015038 411 uint8_t n;
hudakz 0:f78e57015038 412
hudakz 0:f78e57015038 413 if (str[0] == ' ') {
hudakz 0:f78e57015038 414 printPageMain();
hudakz 0:f78e57015038 415 return(1);
hudakz 0:f78e57015038 416 }
hudakz 0:f78e57015038 417
hudakz 0:f78e57015038 418 if (strncmp("sc", str, 2) == 0) {
hudakz 0:f78e57015038 419 printPageSetClock();
hudakz 0:f78e57015038 420 return(1);
hudakz 0:f78e57015038 421 }
hudakz 0:f78e57015038 422
hudakz 0:f78e57015038 423 if (strncmp("sw", str, 2) == 0) {
hudakz 0:f78e57015038 424 printPageRelay();
hudakz 0:f78e57015038 425 return(1);
hudakz 0:f78e57015038 426 }
hudakz 0:f78e57015038 427
hudakz 0:f78e57015038 428 if (strncmp("p1.js", str, 5) == 0) {
hudakz 0:f78e57015038 429 printJavaScriptFunctions();
hudakz 0:f78e57015038 430 return(2);
hudakz 0:f78e57015038 431 }
hudakz 0:f78e57015038 432
hudakz 0:f78e57015038 433 // save the tablebitmap
hudakz 0:f78e57015038 434 if (strncmp("st", str, 2) == 0) {
hudakz 0:f78e57015038 435
hudakz 0:f78e57015038 436 // save the tablebitmap
hudakz 0:f78e57015038 437 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"pw")) {
hudakz 0:f78e57015038 438 urldecode(strBuf);
hudakz 0:f78e57015038 439 if (verifyPassword(strBuf)) {
hudakz 0:f78e57015038 440 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"tt")) {
hudakz 0:f78e57015038 441 urldecode(strBuf);
hudakz 0:f78e57015038 442 strBuf[37] = '\0'; // max length
hudakz 0:f78e57015038 443
hudakz 0:f78e57015038 444 // gStrbuf is a string like this: 11-58-0-0-0-0-
hudakz 0:f78e57015038 445 // no space allowed
hudakz 0:f78e57015038 446 if (!isdigit(strBuf[0])) {
hudakz 0:f78e57015038 447 return(0);
hudakz 0:f78e57015038 448 }
hudakz 0:f78e57015038 449
hudakz 0:f78e57015038 450 n = 0;
hudakz 0:f78e57015038 451 i = 0;
hudakz 0:f78e57015038 452 j = 0;
hudakz 0:f78e57015038 453 while (strBuf[i] && n < 6) {
hudakz 0:f78e57015038 454 if (strBuf[i] == '-') {
hudakz 0:f78e57015038 455 strBuf[i] = '\0';
hudakz 0:f78e57015038 456 tablebitmap[n] = atol(&strBuf[j]);
hudakz 0:f78e57015038 457 n++;
hudakz 0:f78e57015038 458 j = i + 1;
hudakz 0:f78e57015038 459 }
hudakz 0:f78e57015038 460
hudakz 0:f78e57015038 461 i++;
hudakz 0:f78e57015038 462 }
hudakz 0:f78e57015038 463
hudakz 0:f78e57015038 464 checkRelayStatus();
hudakz 0:f78e57015038 465 printPageMain();
hudakz 0:f78e57015038 466 return(1); // main page
hudakz 0:f78e57015038 467 }
hudakz 0:f78e57015038 468 }
hudakz 0:f78e57015038 469 }
hudakz 0:f78e57015038 470
hudakz 0:f78e57015038 471 return(-1);
hudakz 0:f78e57015038 472 }
hudakz 0:f78e57015038 473
hudakz 0:f78e57015038 474 // change clock
hudakz 0:f78e57015038 475 if (strncmp("cc", str, 2) == 0) {
hudakz 0:f78e57015038 476 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"pw")) {
hudakz 0:f78e57015038 477 urldecode(strBuf);
hudakz 0:f78e57015038 478 if (verifyPassword(strBuf)) {
hudakz 0:f78e57015038 479 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"mt")) {
hudakz 0:f78e57015038 480 urldecode(strBuf);
hudakz 0:f78e57015038 481 if (strBuf[0] == '0') {
hudakz 0:f78e57015038 482 ntp->setTime(NTP_SERVER, 123, 3000); // set clock
hudakz 0:f78e57015038 483 set_time(cetZone.toLocal(rtc_read())); // daylight saving time
hudakz 0:f78e57015038 484 }
hudakz 0:f78e57015038 485 else
hudakz 0:f78e57015038 486 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"tv")) {
hudakz 0:f78e57015038 487 urldecode(strBuf);
hudakz 0:f78e57015038 488 strBuf[16] = '\0';
hudakz 0:f78e57015038 489
hudakz 0:f78e57015038 490 // strBuf is a string like: 2020-10-21-11:58
hudakz 0:f78e57015038 491 // no space allowed
hudakz 0:f78e57015038 492 if (!isdigit(strBuf[0])) {
hudakz 0:f78e57015038 493 return(0);
hudakz 0:f78e57015038 494 }
hudakz 0:f78e57015038 495
hudakz 0:f78e57015038 496 char* token = strBuf;
hudakz 0:f78e57015038 497 char* delim;
hudakz 0:f78e57015038 498
hudakz 0:f78e57015038 499 delim = strchr(token, '-');
hudakz 0:f78e57015038 500 *delim = '\0';
hudakz 0:f78e57015038 501 tmNow.tm_year = atoi(token) - 1900;
hudakz 0:f78e57015038 502
hudakz 0:f78e57015038 503 token = delim + 1;
hudakz 0:f78e57015038 504 delim = strchr(token, '-');
hudakz 0:f78e57015038 505 *delim = '\0';
hudakz 0:f78e57015038 506 tmNow.tm_mon = atoi(token) - 1;
hudakz 0:f78e57015038 507
hudakz 0:f78e57015038 508 token = delim + 1;
hudakz 0:f78e57015038 509 delim = strchr(token, '-');
hudakz 0:f78e57015038 510 *delim = '\0';
hudakz 0:f78e57015038 511 tmNow.tm_mday = atoi(token);
hudakz 0:f78e57015038 512
hudakz 0:f78e57015038 513 token = delim + 1;
hudakz 0:f78e57015038 514 delim = strchr(token, ':');
hudakz 0:f78e57015038 515 *delim = '\0';
hudakz 0:f78e57015038 516 tmNow.tm_hour = atoi(token);
hudakz 0:f78e57015038 517
hudakz 0:f78e57015038 518 token = delim + 1;
hudakz 0:f78e57015038 519 tmNow.tm_min = atoi(token);
hudakz 0:f78e57015038 520
hudakz 0:f78e57015038 521 tmNow.tm_isdst = 1; // apply daylight saving
hudakz 0:f78e57015038 522 time_t seconds;
hudakz 0:f78e57015038 523
hudakz 0:f78e57015038 524 _rtc_maketime(&tmNow, &seconds, RTC_FULL_LEAP_YEAR_SUPPORT);
hudakz 0:f78e57015038 525 set_time(seconds);
hudakz 0:f78e57015038 526 }
hudakz 0:f78e57015038 527
hudakz 0:f78e57015038 528 time_t seconds = rtc_read();
hudakz 0:f78e57015038 529 _rtc_localtime(seconds, &tmNow, RTC_FULL_LEAP_YEAR_SUPPORT);
hudakz 0:f78e57015038 530 checkRelayStatus();
hudakz 0:f78e57015038 531 printPageMain();
hudakz 0:f78e57015038 532 return(1); // main page
hudakz 0:f78e57015038 533 }
hudakz 0:f78e57015038 534
hudakz 0:f78e57015038 535 return(0);
hudakz 0:f78e57015038 536 }
hudakz 0:f78e57015038 537 }
hudakz 0:f78e57015038 538
hudakz 0:f78e57015038 539 return(-1);
hudakz 0:f78e57015038 540 }
hudakz 0:f78e57015038 541
hudakz 0:f78e57015038 542 i = 0; // switch on or off
hudakz 0:f78e57015038 543
hudakz 0:f78e57015038 544 // change relay state FORM
hudakz 0:f78e57015038 545 if (strncmp("cr", str, 2) == 0) {
hudakz 0:f78e57015038 546 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"sw")) {
hudakz 0:f78e57015038 547 if (strBuf[0] == '1') {
hudakz 0:f78e57015038 548 i = 1;
hudakz 0:f78e57015038 549 }
hudakz 0:f78e57015038 550
hudakz 0:f78e57015038 551 if (find_key_val(str, strBuf, STR_BUFFER_SIZE, (char*)"pw")) {
hudakz 0:f78e57015038 552 urldecode(strBuf);
hudakz 0:f78e57015038 553 if (verifyPassword(strBuf)) {
hudakz 0:f78e57015038 554 if (i)
hudakz 0:f78e57015038 555 relay = ON;
hudakz 0:f78e57015038 556 else
hudakz 0:f78e57015038 557 relay = OFF;
hudakz 0:f78e57015038 558
hudakz 0:f78e57015038 559 printPageMain();
hudakz 0:f78e57015038 560 return(1); // main page
hudakz 0:f78e57015038 561 }
hudakz 0:f78e57015038 562 }
hudakz 0:f78e57015038 563
hudakz 0:f78e57015038 564 return(-1);
hudakz 0:f78e57015038 565 }
hudakz 0:f78e57015038 566
hudakz 0:f78e57015038 567 return(0);
hudakz 0:f78e57015038 568 }
hudakz 0:f78e57015038 569
hudakz 0:f78e57015038 570 return(0);
hudakz 0:f78e57015038 571 }
hudakz 0:f78e57015038 572
hudakz 0:f78e57015038 573 /**
hudakz 0:f78e57015038 574 * @brief
hudakz 0:f78e57015038 575 * @note
hudakz 0:f78e57015038 576 * @param
hudakz 0:f78e57015038 577 * @retval
hudakz 0:f78e57015038 578 */
hudakz 0:f78e57015038 579 void sendHttp(TCPSocket* client, char* header, char* content, bool js = false)
hudakz 0:f78e57015038 580 {
hudakz 0:f78e57015038 581 char content_length[10] = { };
hudakz 0:f78e57015038 582
hudakz 0:f78e57015038 583 sprintf(content_length, "%u\r\n", strlen(content));
hudakz 0:f78e57015038 584
hudakz 0:f78e57015038 585 if (js) {
hudakz 0:f78e57015038 586 strcat(header, "Content-Type: application/x-javascript\r\n\r\n");
hudakz 0:f78e57015038 587 }
hudakz 0:f78e57015038 588 else {
hudakz 0:f78e57015038 589 strcat(header, "\r\nContent-Type: text/html\r\n");
hudakz 0:f78e57015038 590 strcat(header, "Content-Length: ");
hudakz 0:f78e57015038 591 strcat(header, content_length);
hudakz 0:f78e57015038 592 strcat(header, "Pragma: no-cache\r\n");
hudakz 0:f78e57015038 593 strcat(header, "Connection: About to close\r\n\r\n");
hudakz 0:f78e57015038 594 }
hudakz 0:f78e57015038 595
hudakz 0:f78e57015038 596 char c = content[0];
hudakz 0:f78e57015038 597 memmove(httpBuf + strlen(header), httpBuf, strlen(content)); // make room for the header
hudakz 0:f78e57015038 598 strcpy(httpBuf, header); // copy the header on front of the content
hudakz 0:f78e57015038 599 httpBuf[strlen(header)] = c;
hudakz 0:f78e57015038 600 client->send((uint8_t*)httpBuf, strlen(httpBuf));
hudakz 0:f78e57015038 601 }
hudakz 0:f78e57015038 602
hudakz 0:f78e57015038 603 /**
hudakz 0:f78e57015038 604 * @brief
hudakz 0:f78e57015038 605 * @note
hudakz 0:f78e57015038 606 * @param
hudakz 0:f78e57015038 607 * @retval
hudakz 0:f78e57015038 608 */
hudakz 0:f78e57015038 609 void onTick()
hudakz 0:f78e57015038 610 {
hudakz 0:f78e57015038 611 time_t seconds = rtc_read();
hudakz 0:f78e57015038 612 #ifdef DEBUG
hudakz 0:f78e57015038 613 printf("Seconds since January 1, 1970 = %llu s\r\n", seconds);
hudakz 0:f78e57015038 614 #endif
hudakz 0:f78e57015038 615 _rtc_localtime(seconds, &tmNow, RTC_FULL_LEAP_YEAR_SUPPORT);
hudakz 0:f78e57015038 616 checkRelayStatus();
hudakz 0:f78e57015038 617 }
hudakz 0:f78e57015038 618
hudakz 0:f78e57015038 619 /**
hudakz 0:f78e57015038 620 * @brief
hudakz 0:f78e57015038 621 * @note
hudakz 0:f78e57015038 622 * @param
hudakz 0:f78e57015038 623 * @retval
hudakz 0:f78e57015038 624 */
hudakz 0:f78e57015038 625 int main(void)
hudakz 0:f78e57015038 626 {
hudakz 0:f78e57015038 627 printf("\r\nStarting..\r\n");
hudakz 0:f78e57015038 628
hudakz 0:f78e57015038 629 eventQueue.call_every(1s, onTick);
hudakz 0:f78e57015038 630 thread.start(callback(&eventQueue, &EventQueue::dispatch_forever));
hudakz 0:f78e57015038 631
hudakz 0:f78e57015038 632 //net = NetworkInterface::get_default_instance();
hudakz 0:f78e57015038 633 net = new EthernetInterface();
hudakz 0:f78e57015038 634
hudakz 0:f78e57015038 635 //net->set_network("192.168.1.181","255.255.255.0","192.168.1.1"); // use static IP address, netmask, gateway
hudakz 0:f78e57015038 636 if (!net) {
hudakz 0:f78e57015038 637 printf("Error! No network inteface found.\n");
hudakz 0:f78e57015038 638 return 0;
hudakz 0:f78e57015038 639 }
hudakz 0:f78e57015038 640
hudakz 0:f78e57015038 641 //net->set_network (IP, NETMASK, GATEWAY); // include this to use static IP address
hudakz 0:f78e57015038 642 nsapi_size_or_error_t r = net->connect();
hudakz 0:f78e57015038 643 if (r != NSAPI_ERROR_OK) {
hudakz 0:f78e57015038 644 printf("Error! net->connect() returned: %d\n", r);
hudakz 0:f78e57015038 645 return r;
hudakz 0:f78e57015038 646 }
hudakz 0:f78e57015038 647
hudakz 0:f78e57015038 648 // Show the network address
hudakz 0:f78e57015038 649 SocketAddress addr;
hudakz 0:f78e57015038 650 net->get_ip_address(&addr);
hudakz 0:f78e57015038 651 printf("IP address: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
hudakz 0:f78e57015038 652 net->get_netmask(&addr);
hudakz 0:f78e57015038 653 printf("Netmask: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
hudakz 0:f78e57015038 654 net->get_gateway(&addr);
hudakz 0:f78e57015038 655 printf("Gateway: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
hudakz 0:f78e57015038 656
hudakz 0:f78e57015038 657 // Create NTP connection
hudakz 0:f78e57015038 658 ntp = new NTPClient(*net);
hudakz 0:f78e57015038 659 ntp->setTime(NTP_SERVER, 123, 3000); // set clock
hudakz 0:f78e57015038 660 set_time(cetZone.toLocal(rtc_read())); // daylight saving time
hudakz 0:f78e57015038 661
hudakz 0:f78e57015038 662 /* Open the server on ethernet stack */
hudakz 0:f78e57015038 663 server.open(net);
hudakz 0:f78e57015038 664
hudakz 0:f78e57015038 665 /* Bind the HTTP port (TCP 80) to the server */
hudakz 0:f78e57015038 666 server.bind(PORT);
hudakz 0:f78e57015038 667
hudakz 0:f78e57015038 668 /* Listen for clients */
hudakz 0:f78e57015038 669 server.listen();
hudakz 0:f78e57015038 670
hudakz 0:f78e57015038 671 //listening for http GET request
hudakz 0:f78e57015038 672 while (true) {
hudakz 0:f78e57015038 673 client = server.accept();
hudakz 0:f78e57015038 674 if (client)
hudakz 0:f78e57015038 675 {
hudakz 0:f78e57015038 676 #ifdef DEBUG
hudakz 0:f78e57015038 677 client->getpeername(&addr);
hudakz 0:f78e57015038 678 printf("Connection succeeded!\n\rIP: %s\n\r", addr.get_ip_address());
hudakz 0:f78e57015038 679 #endif
hudakz 0:f78e57015038 680 client->recv(httpBuf, 1500);
hudakz 0:f78e57015038 681 if (strncmp(httpBuf, "GET", 3) != 0) {
hudakz 0:f78e57015038 682 setHeaderToHttp200ok();
hudakz 0:f78e57015038 683 strcpy(httpBuf, "<h1>200 OK</h1>");
hudakz 0:f78e57015038 684 sendHttp(client, httpHeader, httpBuf);
hudakz 0:f78e57015038 685 }
hudakz 0:f78e57015038 686 else {
hudakz 0:f78e57015038 687 int cmd = analyseUrl((char*) &httpBuf[5]); // "GET [this is the tex to be analysed]"
hudakz 0:f78e57015038 688
hudakz 0:f78e57015038 689 switch (cmd) {
hudakz 0:f78e57015038 690 case -1:
hudakz 0:f78e57015038 691 strcpy(httpHeader, "HTTP/1.0 401 Unauthorized");
hudakz 0:f78e57015038 692 strcpy(httpBuf, "<h1>401 Unauthorized</h1>");
hudakz 0:f78e57015038 693 sendHttp(client, httpHeader, httpBuf);
hudakz 0:f78e57015038 694 break;
hudakz 0:f78e57015038 695
hudakz 0:f78e57015038 696 case 0:
hudakz 0:f78e57015038 697 strcpy(httpHeader, "HTTP/1.0 404 Page Not Found");
hudakz 0:f78e57015038 698 strcpy(httpBuf, "<h1>404 Page Not Found</h1>");
hudakz 0:f78e57015038 699 sendHttp(client, httpHeader, httpBuf);
hudakz 0:f78e57015038 700 break;
hudakz 0:f78e57015038 701
hudakz 0:f78e57015038 702 case 1:
hudakz 0:f78e57015038 703 sendHttp(client, httpHeader, httpBuf);
hudakz 0:f78e57015038 704 break;
hudakz 0:f78e57015038 705
hudakz 0:f78e57015038 706 case 2:
hudakz 0:f78e57015038 707 sendHttp(client, httpHeader, httpBuf, true);
hudakz 0:f78e57015038 708 break;
hudakz 0:f78e57015038 709 }
hudakz 0:f78e57015038 710 }
hudakz 0:f78e57015038 711
hudakz 0:f78e57015038 712 client->close();
hudakz 0:f78e57015038 713 }
hudakz 0:f78e57015038 714 }
hudakz 0:f78e57015038 715 }