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:
Wed Nov 11 17:09:39 2020 +0000
Revision:
1:2d2517f82319
Parent:
0:f78e57015038
Child:
2:6d02d3d314a2
A timer to control a DigitalOut equipped with Web interface for scheduling.

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