Browse Source

Initial files import

Import UKI sketch files as of 14/03/2016
Etienne Landon 9 years ago
parent
commit
5a34632d84
14 changed files with 1625 additions and 0 deletions
  1. 83 0
      ESP_UKI.ino
  2. 166 0
      LICENSE.md
  3. 206 0
      PAGE_NetworkConfiguration.h
  4. 34 0
      Page_Admin.h
  5. 120 0
      Page_General.h
  6. 74 0
      Page_Information.h
  7. 112 0
      Page_NTPSettings.h
  8. 32 0
      Page_Root.h
  9. 31 0
      Page_Script.js.h
  10. 68 0
      Page_Style.css.h
  11. 197 0
      functions.h
  12. 246 0
      global.h
  13. 210 0
      helpers.h
  14. 46 0
      includes.h

+ 83 - 0
ESP_UKI.ino

@@ -0,0 +1,83 @@
+/*
+    ESP_UKI
+
+  TODO :  clean webserver
+          add uki configuration/information page (player number, ADC value, IP of main computer)
+          send ADC to default IP via udp, allow configuration
+          ajout numéro de firmware sur webserver
+*/
+	
+
+#include "includes.h"  //headers and variables declaration
+
+/* UKI udp configuration */
+
+int UKI_UDP_In_Port = 9000;  //udp port input for ESP
+IPAddress UKI_UDP_Master_IP(192, 168, 0, 41);  //default udp address to send to. Will automatically change to the ip sending something to udp in
+ 
+
+void setup ( void ) {
+  startESP();
+  setupWifi();
+  setupWebserver();
+  setupOTA();
+  
+  delay(200);
+  Serial.println("Ready");
+  Serial.print("IP address: ");
+  Serial.println(WiFi.localIP());
+
+  //UKI sensor setup
+  UKI_UDP.begin(UKI_UDP_In_Port); 
+  delay(1000);
+  digitalWrite(Red_Led, HIGH); //red led off
+  digitalWrite(Blue_Led, HIGH);
+  delay(1000);
+  ledBlink(Red_Led, 3, 100); //3 quick blink on red led as we start 
+  delay (1000);
+}
+
+
+void loop ( void ) {
+  
+  loopWebserver();
+  
+  loopHandles();
+
+  /*  UKI part	*/
+  GSR_sensor = analogRead(A0);
+  //UKI_UDP.beginPacketMulticast((224, 1, 2, 3), 8000, WiFi.localIP());//
+  UKI_UDP.beginPacket(UKI_UDP_Master_IP, 8000);
+  UKI_UDP.print(config.DeviceName);
+  UKI_UDP.print(" ");
+  UKI_UDP.print(GSR_sensor);
+  UKI_UDP.endPacket();
+  //yield();
+//Red_Led_State = !Red_Led_State;
+  
+  //analogWrite(Red_Led, GSR_sensor);
+
+  
+  delay(20);
+  
+
+  //Check udp in
+  int packetSize = UKI_UDP.parsePacket();
+  
+  if(packetSize) {
+    UKI_UDP_Master_IP = UKI_UDP.remoteIP();
+    UKI_UDP.beginPacket(UKI_UDP_Master_IP, 8000);
+    UKI_UDP.print("new master ip");
+    UKI_UDP.endPacket();
+  }
+
+
+
+
+
+
+
+
+
+}
+

+ 166 - 0
LICENSE.md

@@ -0,0 +1,166 @@
+
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.

+ 206 - 0
PAGE_NetworkConfiguration.h

@@ -0,0 +1,206 @@
+
+
+//
+//  HTML PAGE
+//
+const char PAGE_NetworkConfiguration[] PROGMEM = R"=====(
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<a href="admin.html"  class="btn btn--s"><</a>&nbsp;&nbsp;<strong>Network Configuration</strong>
+<hr>
+Connect to Router with these settings:<br>
+<form action="" method="get">
+<table border="0"  cellspacing="0" cellpadding="3" style="width:310px" >
+<tr><td align="right">SSID:</td><td><input type="text" id="ssid" name="ssid" value=""></td></tr>
+<tr><td align="right">Password:</td><td><input type="text" id="password" name="password" value=""></td></tr>
+<tr><td align="right">DHCP:</td><td><input type="checkbox" id="dhcp" name="dhcp"></td></tr>
+<tr><td align="right">IP:     </td><td><input type="text" id="ip_0" name="ip_0" size="3">.<input type="text" id="ip_1" name="ip_1" size="3">.<input type="text" id="ip_2" name="ip_2" size="3">.<input type="text" id="ip_3" name="ip_3" value="" size="3"></td></tr>
+<tr><td align="right">Netmask:</td><td><input type="text" id="nm_0" name="nm_0" size="3">.<input type="text" id="nm_1" name="nm_1" size="3">.<input type="text" id="nm_2" name="nm_2" size="3">.<input type="text" id="nm_3" name="nm_3" size="3"></td></tr>
+<tr><td align="right">Gateway:</td><td><input type="text" id="gw_0" name="gw_0" size="3">.<input type="text" id="gw_1" name="gw_1" size="3">.<input type="text" id="gw_2" name="gw_2" size="3">.<input type="text" id="gw_3" name="gw_3" size="3"></td></tr>
+<tr><td colspan="2" align="center"><input type="submit" style="width:150px" class="btn btn--m btn--blue" value="Save"></td></tr>
+</table>
+</form>
+<hr>
+<strong>Connection State:</strong><div id="connectionstate">N/A</div>
+<hr>
+<strong>Networks:</strong><br>
+<table border="0"  cellspacing="3" style="width:310px" >
+<tr><td><div id="networks">Scanning...</div></td></tr>
+<tr><td align="center"><a href="javascript:GetState()" style="width:150px" class="btn btn--m btn--blue">Refresh</a></td></tr>
+</table>
+
+
+<script>
+
+function GetState()
+{
+	setValues("/admin/connectionstate");
+}
+function selssid(value)
+{
+	document.getElementById("ssid").value = value; 
+}
+
+
+window.onload = function ()
+{
+	load("style.css","css", function() 
+	{
+		load("microajax.js","js", function() 
+		{
+					setValues("/admin/values");
+					setTimeout(GetState,3000);
+		});
+	});
+}
+function load(e,t,n){if("js"==t){var a=document.createElement("script");a.src=e,a.type="text/javascript",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}else if("css"==t){var a=document.createElement("link");a.href=e,a.rel="stylesheet",a.type="text/css",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}}
+
+
+
+
+</script>
+
+
+)=====";
+
+const char PAGE_WaitAndReload[] PROGMEM = R"=====(
+<meta http-equiv="refresh" content="5; URL=config.html">
+Please Wait....Configuring and Restarting.
+)=====";
+
+
+//
+//  SEND HTML PAGE OR IF A FORM SUMBITTED VALUES, PROCESS THESE VALUES
+// 
+
+void send_network_configuration_html()
+{
+	digitalWrite(Blue_Led, LOW);
+	if (server.args() > 0 )  // Save Settings
+	{
+		String temp = "";
+		config.dhcp = false;
+		for ( uint8_t i = 0; i < server.args(); i++ ) {
+			if (server.argName(i) == "ssid") config.ssid =   urldecode(server.arg(i));
+			if (server.argName(i) == "password") config.password =    urldecode(server.arg(i)); 
+			if (server.argName(i) == "ip_0") if (checkRange(server.arg(i))) 	config.IP[0] =  server.arg(i).toInt();
+			if (server.argName(i) == "ip_1") if (checkRange(server.arg(i))) 	config.IP[1] =  server.arg(i).toInt();
+			if (server.argName(i) == "ip_2") if (checkRange(server.arg(i))) 	config.IP[2] =  server.arg(i).toInt();
+			if (server.argName(i) == "ip_3") if (checkRange(server.arg(i))) 	config.IP[3] =  server.arg(i).toInt();
+			if (server.argName(i) == "nm_0") if (checkRange(server.arg(i))) 	config.Netmask[0] =  server.arg(i).toInt();
+			if (server.argName(i) == "nm_1") if (checkRange(server.arg(i))) 	config.Netmask[1] =  server.arg(i).toInt();
+			if (server.argName(i) == "nm_2") if (checkRange(server.arg(i))) 	config.Netmask[2] =  server.arg(i).toInt();
+			if (server.argName(i) == "nm_3") if (checkRange(server.arg(i))) 	config.Netmask[3] =  server.arg(i).toInt();
+			if (server.argName(i) == "gw_0") if (checkRange(server.arg(i))) 	config.Gateway[0] =  server.arg(i).toInt();
+			if (server.argName(i) == "gw_1") if (checkRange(server.arg(i))) 	config.Gateway[1] =  server.arg(i).toInt();
+			if (server.argName(i) == "gw_2") if (checkRange(server.arg(i))) 	config.Gateway[2] =  server.arg(i).toInt();
+			if (server.argName(i) == "gw_3") if (checkRange(server.arg(i))) 	config.Gateway[3] =  server.arg(i).toInt();
+			if (server.argName(i) == "dhcp") config.dhcp = true;
+		}
+		 server.send ( 200, "text/html", PAGE_WaitAndReload );
+		WriteConfig();
+		ConfigureWifi();
+		AdminTimeOutCounter=0;
+		
+	}
+	else
+	{
+		server.send ( 200, "text/html", PAGE_NetworkConfiguration ); 
+	}
+	Serial.println(__FUNCTION__); 
+  digitalWrite(Blue_Led, HIGH);
+}
+
+
+
+//
+//   FILL THE PAGE WITH VALUES
+//
+
+void send_network_configuration_values_html()
+{
+  digitalWrite(Blue_Led, LOW);
+	String values ="";
+
+	values += "ssid|" + (String) config.ssid + "|input\n";
+	values += "password|" +  (String) config.password + "|input\n";
+	values += "ip_0|" +  (String) config.IP[0] + "|input\n";
+	values += "ip_1|" +  (String) config.IP[1] + "|input\n";
+	values += "ip_2|" +  (String) config.IP[2] + "|input\n";
+	values += "ip_3|" +  (String) config.IP[3] + "|input\n";
+	values += "nm_0|" +  (String) config.Netmask[0] + "|input\n";
+	values += "nm_1|" +  (String) config.Netmask[1] + "|input\n";
+	values += "nm_2|" +  (String) config.Netmask[2] + "|input\n";
+	values += "nm_3|" +  (String) config.Netmask[3] + "|input\n";
+	values += "gw_0|" +  (String) config.Gateway[0] + "|input\n";
+	values += "gw_1|" +  (String) config.Gateway[1] + "|input\n";
+	values += "gw_2|" +  (String) config.Gateway[2] + "|input\n";
+	values += "gw_3|" +  (String) config.Gateway[3] + "|input\n";
+	values += "dhcp|" +  (String) (config.dhcp ? "checked" : "") + "|chk\n";
+	server.send ( 200, "text/plain", values);
+	Serial.println(__FUNCTION__); 
+	digitalWrite(Blue_Led, HIGH);
+}
+
+
+//
+//   FILL THE PAGE WITH NETWORKSTATE & NETWORKS
+//
+
+void send_connection_state_values_html()
+{
+  digitalWrite(Blue_Led, LOW);
+	String state = "N/A";
+	String Networks = "";
+	if (WiFi.status() == 0) state = "Idle";
+	else if (WiFi.status() == 1) state = "NO SSID AVAILBLE";
+	else if (WiFi.status() == 2) state = "SCAN COMPLETED";
+	else if (WiFi.status() == 3) state = "CONNECTED";
+	else if (WiFi.status() == 4) state = "CONNECT FAILED";
+	else if (WiFi.status() == 5) state = "CONNECTION LOST";
+	else if (WiFi.status() == 6) state = "DISCONNECTED";
+
+
+
+	 int n = WiFi.scanNetworks();
+ 
+	 if (n == 0)
+	 {
+		 Networks = "<font color='#FF0000'>No networks found!</font>";
+	 }
+	else
+    {
+	 
+		
+		Networks = "Found " +String(n) + " Networks<br>";
+		Networks += "<table border='0' cellspacing='0' cellpadding='3'>";
+		Networks += "<tr bgcolor='#DDDDDD' ><td><strong>Name</strong></td><td><strong>Quality</strong></td><td><strong>Enc</strong></td><tr>";
+		for (int i = 0; i < n; ++i)
+		{
+			int quality=0;
+			if(WiFi.RSSI(i) <= -100)
+			{
+					quality = 0;
+			}
+			else if(WiFi.RSSI(i) >= -50)
+			{
+					quality = 100;
+			}
+			else
+			{
+				quality = 2 * (WiFi.RSSI(i) + 100);
+			}
+
+
+			Networks += "<tr><td><a href='javascript:selssid(\""  +  String(WiFi.SSID(i))  + "\")'>"  +  String(WiFi.SSID(i))  + "</a></td><td>" +  String(quality) + "%</td><td>" +  String((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*")  + "</td></tr>";
+		}
+		Networks += "</table>";
+	}
+   
+	String values ="";
+	values += "connectionstate|" +  state + "|div\n";
+	values += "networks|" +  Networks + "|div\n";
+	server.send ( 200, "text/plain", values);
+	Serial.println(__FUNCTION__); 
+	digitalWrite(Blue_Led, HIGH);
+}

+ 34 - 0
Page_Admin.h

@@ -0,0 +1,34 @@
+
+
+//
+//  HTML PAGE
+//
+
+const char PAGE_AdminMainPage[] PROGMEM = R"=====(
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<strong>Administration</strong>
+<hr>
+<a href="general.html" style="width:250px" class="btn btn--m btn--blue" >General Configuration</a><br>
+<a href="config.html" style="width:250px" class="btn btn--m btn--blue" >Network Configuration</a><br>
+<a href="info.html"   style="width:250px"  class="btn btn--m btn--blue" >Network Information</a><br>
+<a href="ntp.html"   style="width:250px"  class="btn btn--m btn--blue" >NTP Settings</a><br>
+
+
+<script>
+window.onload = function ()
+{
+	load("style.css","css", function() 
+	{
+		load("microajax.js","js", function() 
+		{
+				// Do something after load...
+		});
+	});
+}
+function load(e,t,n){if("js"==t){var a=document.createElement("script");a.src=e,a.type="text/javascript",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}else if("css"==t){var a=document.createElement("link");a.href=e,a.rel="stylesheet",a.type="text/css",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}}
+
+</script>
+
+)=====";
+
+

+ 120 - 0
Page_General.h

@@ -0,0 +1,120 @@
+//
+//  HTML PAGE
+//
+
+const char PAGE_AdminGeneralSettings[] PROGMEM =  R"=====(
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<a href="admin.html"  class="btn btn--s"><</a>&nbsp;&nbsp;<strong>General Settings</strong>
+<hr>
+<form action="" method="post">
+<table border="0"  cellspacing="0" cellpadding="3" >
+<tr>
+	<td align="right">Name of Device</td>
+	<td><input type="text" id="devicename" name="devicename" value=""></td>
+</tr>
+
+<tr>
+	<td align="left" colspan="2"><hr></td>
+</tr>
+
+<tr>
+	<td align="left" colspan="2">Turn on at</td>
+</tr>
+<tr>
+	<td align="right"> Enabled:</td>
+	<td><input type="checkbox" id="tonenabled" name="tonenabled"></td>
+</tr>
+
+<tr>
+	<td align="right"> Time:</td>
+	<td><input type="text" id="tonhour" name="tonhour" size="2" value="00">:<input type="text" id="tonminute" name="tonminute" size="2" value="00"></td>
+</tr>
+
+<tr>
+	<td align="left" colspan="2">Turn off at:</td>
+<tr>
+	<td align="right"> Enabled:</td>
+	<td><input type="checkbox" id="toffenabled" name="toffenabled"></td>
+</tr>
+<tr>
+	<td align="right"> Time:</td>
+	<td><input type="text" id="toffhour" name="toffhour" size="2" value="00">:<input type="text" id="toffminute" name="toffminute" size="2" value="00"></td>
+</tr>
+<tr><td colspan="2" align="center"><input type="submit" style="width:150px" class="btn btn--m btn--blue" value="Save"></td></tr>
+</table>
+</form>
+<script>
+
+ 
+
+window.onload = function ()
+{
+	load("style.css","css", function() 
+	{
+		load("microajax.js","js", function() 
+		{
+				setValues("/admin/generalvalues");
+		});
+	});
+}
+function load(e,t,n){if("js"==t){var a=document.createElement("script");a.src=e,a.type="text/javascript",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}else if("css"==t){var a=document.createElement("link");a.href=e,a.rel="stylesheet",a.type="text/css",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}}
+
+
+
+</script>
+)=====";
+
+
+// Functions for this Page
+void send_devicename_value_html()
+{
+	digitalWrite(Blue_Led, LOW);
+	String values ="";
+	values += "devicename|" + (String) config.DeviceName + "|div\n";
+	server.send ( 200, "text/plain", values);
+	Serial.println(__FUNCTION__); 
+	digitalWrite(Blue_Led, HIGH);
+}
+
+void send_general_html()
+{
+	digitalWrite(Blue_Led, LOW);
+	if (server.args() > 0 )  // Save Settings
+	{
+		config.AutoTurnOn = false;
+		config.AutoTurnOff = false;
+		String temp = "";
+		for ( uint8_t i = 0; i < server.args(); i++ ) {
+			if (server.argName(i) == "devicename") config.DeviceName = urldecode(server.arg(i)); 
+			if (server.argName(i) == "tonenabled") config.AutoTurnOn = true; 
+			if (server.argName(i) == "toffenabled") config.AutoTurnOff = true; 
+			if (server.argName(i) == "tonhour") config.TurnOnHour =  server.arg(i).toInt(); 
+			if (server.argName(i) == "tonminute") config.TurnOnMinute =  server.arg(i).toInt(); 
+			if (server.argName(i) == "toffhour") config.TurnOffHour =  server.arg(i).toInt(); 
+			if (server.argName(i) == "toffminute") config.TurnOffMinute =  server.arg(i).toInt(); 
+		}
+		WriteConfig();
+		firstStart = true;
+	}
+	server.send ( 200, "text/html", PAGE_AdminGeneralSettings ); 
+	Serial.println(__FUNCTION__); 
+	
+	digitalWrite(Blue_Led, HIGH);
+}
+
+void send_general_configuration_values_html()
+{
+  digitalWrite(Blue_Led, LOW);
+	String values ="";
+	values += "devicename|" +  (String)  config.DeviceName +  "|input\n";
+	values += "tonhour|" +  (String)  config.TurnOnHour +  "|input\n";
+	values += "tonminute|" +   (String) config.TurnOnMinute +  "|input\n";
+	values += "toffhour|" +  (String)  config.TurnOffHour +  "|input\n";
+	values += "toffminute|" +   (String)  config.TurnOffMinute +  "|input\n";
+	values += "toffenabled|" +  (String) (config.AutoTurnOff ? "checked" : "") + "|chk\n";
+	values += "tonenabled|" +  (String) (config.AutoTurnOn ? "checked" : "") + "|chk\n";
+	server.send ( 200, "text/plain", values);
+	Serial.println(__FUNCTION__); 
+  digitalWrite(Blue_Led, HIGH);
+}

+ 74 - 0
Page_Information.h

@@ -0,0 +1,74 @@
+#ifndef PAGE_INFOMATION_H
+#define PAGE_INFOMATION_H
+
+
+//
+//   The HTML PAGE
+//
+const char PAGE_Information[] PROGMEM = R"=====(
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="stylesheet" href="style.css" type="text/css" />
+<script src="microajax.js"></script> 
+<a href="admin.html"  class="btn btn--s"><</a>&nbsp;&nbsp;<strong>Network Information</strong>
+<hr>
+<table border="0"  cellspacing="0" cellpadding="3" style="width:310px" >
+<tr><td align="right">SSID :</td><td><span id="x_ssid"></span></td></tr>
+<tr><td align="right">IP :</td><td><span id="x_ip"></span></td></tr>
+<tr><td align="right">Netmask :</td><td><span id="x_netmask"></span></td></tr>
+<tr><td align="right">Gateway :</td><td><span id="x_gateway"></span></td></tr>
+<tr><td align="right">Mac :</td><td><span id="x_mac"></span></td></tr>
+
+<tr><td colspan="2"><hr></span></td></tr>
+<tr><td align="right">NTP Time:</td><td><span id="x_ntp"></span></td></tr>
+
+
+<tr><td colspan="2" align="center"><a href="javascript:GetState()" class="btn btn--m btn--blue">Refresh</a></td></tr>
+</table>
+<script>
+
+function GetState()
+{
+	setValues("/admin/infovalues");
+}
+
+window.onload = function ()
+{
+	load("style.css","css", function() 
+	{
+		load("microajax.js","js", function() 
+		{
+				GetState();
+		});
+	});
+}
+function load(e,t,n){if("js"==t){var a=document.createElement("script");a.src=e,a.type="text/javascript",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}else if("css"==t){var a=document.createElement("link");a.href=e,a.rel="stylesheet",a.type="text/css",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}}
+
+
+
+</script>
+)=====" ;
+
+
+//
+// FILL WITH INFOMATION
+// 
+
+void send_information_values_html ()
+{
+  digitalWrite(Blue_Led, LOW);
+	String values ="";
+
+	values += "x_ssid|" + (String)WiFi.SSID() +  "|div\n";
+	values += "x_ip|" +  (String) WiFi.localIP()[0] + "." +  (String) WiFi.localIP()[1] + "." +  (String) WiFi.localIP()[2] + "." + (String) WiFi.localIP()[3] +  "|div\n";
+	values += "x_gateway|" +  (String) WiFi.gatewayIP()[0] + "." +  (String) WiFi.gatewayIP()[1] + "." +  (String) WiFi.gatewayIP()[2] + "." + (String) WiFi.gatewayIP()[3] +  "|div\n";
+	values += "x_netmask|" +  (String) WiFi.subnetMask()[0] + "." +  (String) WiFi.subnetMask()[1] + "." +  (String) WiFi.subnetMask()[2] + "." + (String) WiFi.subnetMask()[3] +  "|div\n";
+	values += "x_mac|" + GetMacAddress() +  "|div\n";
+	values += "x_ntp|" +  (String) DateTime.hour + ":" + (String) + DateTime.minute +  ":"  + (String)  DateTime.second + " " + (String)   DateTime.year + "-" + (String)  DateTime.month + "-" + (String)  DateTime.day +  "|div\n";
+	server.send ( 200, "text/plain", values);
+	Serial.println(__FUNCTION__); 
+  digitalWrite(Blue_Led, HIGH);
+}
+
+
+#endif

+ 112 - 0
Page_NTPSettings.h

@@ -0,0 +1,112 @@
+
+const char PAGE_NTPConfiguration[] PROGMEM = R"=====(
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<a href="admin.html"  class="btn btn--s"><</a>&nbsp;&nbsp;<strong>NTP Settings</strong>
+<hr>
+<form action="" method="get">
+<table border="0"  cellspacing="0" cellpadding="3" >
+<tr><td align="right">NTP Server:</td><td><input type="text" id="ntpserver" name="ntpserver" maxlength="172" value=""></td></tr>
+<tr><td align="right">Update:</td><td><input type="text" id="update" name="update" size="3"maxlength="6" value=""> minutes (0=disable)</td></tr>
+<tr><td>Timezone</td><td>
+<select  id="tz" name="tz">
+	<option value="-120">(GMT-12:00)</option>
+	<option value="-110">(GMT-11:00)</option>
+	<option value="-100">(GMT-10:00)</option>
+	<option value="-90">(GMT-09:00)</option>
+	<option value="-80">(GMT-08:00)</option>
+	<option value="-70">(GMT-07:00)</option>
+	<option value="-60">(GMT-06:00)</option>
+	<option value="-50">(GMT-05:00)</option>
+	<option value="-40">(GMT-04:00)</option>
+	<option value="-35">(GMT-03:30)</option>
+	<option value="-30">(GMT-03:00)</option>
+	<option value="-20">(GMT-02:00)</option>
+	<option value="-10">(GMT-01:00)</option>
+	<option value="0">(GMT+00:00)</option>
+	<option value="10">(GMT+01:00)</option>
+	<option value="20">(GMT+02:00)</option>
+	<option value="30">(GMT+03:00)</option>
+	<option value="35">(GMT+03:30)</option>
+	<option value="40">(GMT+04:00)</option>
+	<option value="45">(GMT+04:30)</option>
+	<option value="50">(GMT+05:00)</option>
+	<option value="55">(GMT+05:30)</option>
+	<option value="57">(GMT+05:45)</option>
+	<option value="60">(GMT+06:00)</option>
+	<option value="65">(GMT+06:30)</option>
+	<option value="70">(GMT+07:00)</option>
+	<option value="80">(GMT+08:00)</option>
+	<option value="90">(GMT+09:00)</option>
+	<option value="95">(GMT+09:30)</option>
+	<option value="100">(GMT+10:00)</option>
+	<option value="110">(GMT+11:00)</option>
+	<option value="120">(GMT+12:00)</option>
+	<option value="120">(GMT+12:00)</option>
+	<option value="130">(GMT+13:00)</option>
+</select>
+</td></tr>
+<tr><td align="right">Daylight saving:</td><td><input type="checkbox" id="dst" name="dst"></td></tr>
+<tr><td colspan="2" align="center"><input type="submit" style="width:150px" class="btn btn--m btn--blue" value="Save"></td></tr>
+</table>
+</form>
+<script>
+	
+
+window.onload = function ()
+{
+	load("style.css","css", function() 
+	{
+		load("microajax.js","js", function() 
+		{
+				setValues("/admin/ntpvalues");
+		});
+	});
+}
+function load(e,t,n){if("js"==t){var a=document.createElement("script");a.src=e,a.type="text/javascript",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}else if("css"==t){var a=document.createElement("link");a.href=e,a.rel="stylesheet",a.type="text/css",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)}}
+
+
+
+</script>
+)=====";
+
+
+void send_NTP_configuration_html()
+{
+	
+	digitalWrite(Blue_Led, LOW);
+	if (server.args() > 0 )  // Save Settings
+	{
+		config.daylight = false;
+		String temp = "";
+		for ( uint8_t i = 0; i < server.args(); i++ ) {
+			if (server.argName(i) == "ntpserver") config.ntpServerName = urldecode( server.arg(i)); 
+			if (server.argName(i) == "update") config.Update_Time_Via_NTP_Every =  server.arg(i).toInt(); 
+			if (server.argName(i) == "tz") config.timezone =  server.arg(i).toInt(); 
+			if (server.argName(i) == "dst") config.daylight = true; 
+		}
+		WriteConfig();
+		firstStart = true;
+	}
+	server.send ( 200, "text/html", PAGE_NTPConfiguration ); 
+	Serial.println(__FUNCTION__); 
+	digitalWrite(Blue_Led, HIGH);
+}
+
+
+
+
+
+
+void send_NTP_configuration_values_html()
+{
+		
+	String values ="";
+	values += "ntpserver|" + (String) config.ntpServerName + "|input\n";
+	values += "update|" +  (String) config.Update_Time_Via_NTP_Every + "|input\n";
+	values += "tz|" +  (String) config.timezone + "|input\n";
+	values += "dst|" +  (String) (config.daylight ? "checked" : "") + "|chk\n";
+	server.send ( 200, "text/plain", values);
+	Serial.println(__FUNCTION__); 
+	
+}

+ 32 - 0
Page_Root.h

@@ -0,0 +1,32 @@
+
+
+const char PAGE_Root[] PROGMEM = R"=====(
+<!doctype html>
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<script src="microajax.js"></script> 
+<html>
+	<head>
+	<title></title>
+	<meta charset="utf-8" />
+	</head>
+	<body>
+	<link rel="stylesheet" href="style.css" type="text/css" />
+	It work's!
+	</body>
+</html>
+
+)=====";
+
+void sendRootPage()
+{        
+    digitalWrite(Blue_Led, LOW);
+    if (server.args() > 0 )  // Are there any POST/GET Fields ? 
+    {
+       for ( uint8_t i = 0; i < server.args(); i++ ) {  // Iterate through the fields
+            
+        }
+    }
+    server.send ( 200, "text/html", PAGE_Root ); 
+    digitalWrite(Blue_Led, HIGH);
+}
+ 

File diff suppressed because it is too large
+ 31 - 0
Page_Script.js.h


+ 68 - 0
Page_Style.css.h

@@ -0,0 +1,68 @@
+
+const char PAGE_Style_css[] PROGMEM = R"=====(
+body { color: #000000; font-family: avenir, helvetica, arial, sans-serif;  letter-spacing: 0.15em;} 
+hr {    background-color: #eee;    border: 0 none;   color: #eee;    height: 1px; } 
+.btn, .btn:link, .btn:visited {  
+	border-radius: 0.3em;  
+	border-style: solid;  
+	border-width: 1px;  
+color: #111;  
+display: inline-block;  
+	font-family: avenir, helvetica, arial, sans-serif;  
+	letter-spacing: 0.15em;  
+	margin-bottom: 0.5em;  
+padding: 1em 0.75em;  
+	text-decoration: none;  
+	text-transform: uppercase;  
+	-webkit-transition: color 0.4s, background-color 0.4s, border 0.4s;  
+transition: color 0.4s, background-color 0.4s, border 0.4s; 
+} 
+.btn:hover, .btn:focus {
+color: #7FDBFF;  
+border: 1px solid #7FDBFF;  
+	-webkit-transition: background-color 0.3s, color 0.3s, border 0.3s;  
+transition: background-color 0.3s, color 0.3s, border 0.3s; 
+}
+	.btn:active {  
+color: #0074D9;  
+border: 1px solid #0074D9;  
+		-webkit-transition: background-color 0.3s, color 0.3s, border 0.3s;  
+transition: background-color 0.3s, color 0.3s, border 0.3s; 
+	} 
+	.btn--s 
+	{  
+		font-size: 12px; 
+	}
+	.btn--m { 
+		font-size: 14px; 
+	}
+	.btn--l {  
+		font-size: 20px;  border-radius: 0.25em !important; 
+	} 
+	.btn--full, .btn--full:link {
+		border-radius: 0.25em; 
+display: block;  
+			margin-left: auto; 
+			margin-right: auto; 
+			text-align: center; 
+width: 100%; 
+	} 
+	.btn--blue:link, .btn--blue:visited {
+color: #fff;  
+		background-color: #0074D9; 
+	}
+	.btn--blue:hover, .btn--blue:focus {
+color: #fff !important;  
+		background-color: #0063aa;  
+		border-color: #0063aa; 
+	}
+	.btn--blue:active {
+color: #fff; 
+		background-color: #001F3F;  border-color: #001F3F; 
+	}
+	@media screen and (min-width: 32em) {
+		.btn--full {  
+			max-width: 16em !important; } 
+	}
+)=====";
+ 

+ 197 - 0
functions.h

@@ -0,0 +1,197 @@
+
+
+void ledBlink (int Led, int blink_qty, int blink_time) {
+  for (int i = 0 ; i < blink_qty ; i++) {
+    digitalWrite(Led, LOW) ;
+    delay(blink_time);
+    digitalWrite(Led, HIGH);
+    delay(blink_time);
+  }
+  
+  void startESP() {
+  EEPROM.begin(512);
+  Serial.begin(115200);
+  pinMode(Blue_Led, OUTPUT);
+  digitalWrite(Blue_Led, HIGH);
+  pinMode(Red_Led, OUTPUT);
+  digitalWrite(Red_Led, LOW);//red led on
+  delay(500);
+  Serial.println("Starting ES8266");
+}
+
+
+   
+}
+
+void setupWifi(){
+  if (!ReadConfig())  {
+    // DEFAULT CONFIG
+    config.ssid = "Freebox-6F7B3C";
+    config.password = "accessorem6-gignendi7-insultare!";
+    config.dhcp = true;
+    config.IP[0] = 192; config.IP[1] = 168; config.IP[2] = 0; config.IP[3] = 100;
+    config.Netmask[0] = 255; config.Netmask[1] = 255; config.Netmask[2] = 255; config.Netmask[3] = 0;
+    config.Gateway[0] = 192; config.Gateway[1] = 168; config.Gateway[2] = 0; config.Gateway[3] = 254;
+    config.ntpServerName = "0.de.pool.ntp.org";
+    config.Update_Time_Via_NTP_Every =  0;
+    config.timezone = -10;
+    config.daylight = true;
+    config.DeviceName = "UKI_ESP_default";
+    config.AutoTurnOff = false;
+    config.AutoTurnOn = false;
+    config.TurnOffHour = 0;
+    config.TurnOffMinute = 0;
+    config.TurnOnHour = 0;
+    config.TurnOnMinute = 0;
+    WriteConfig();
+    Serial.println("General config applied");
+  }
+
+
+  if (AdminEnabled)  {
+    WiFi.mode(WIFI_AP_STA);
+    //WiFi.softAP( ACCESS_POINT_NAME , ACCESS_POINT_PASSWORD);
+    WiFi.softAP( config.DeviceName.c_str() , ACCESS_POINT_PASSWORD);
+  }
+  else  { WiFi.mode(WIFI_STA); }
+  ConfigureWifi();
+  while (WiFi.status() != 3) {
+    Serial.println(WiFi.status());
+  }
+//    Serial.print(".");
+//    digitalWrite(Blue_Led, Blue_Led_State);
+//    Blue_Led_State = !Blue_Led_State;
+//    yield();
+//  }
+  Serial.println(WiFi.status());
+
+  /* A MODIFIER : pour le moment si AdminEnabled, lance pendant AdminTimeOut un AP en parallèle de la connection configurée
+   *  devrait être remplacé par  - tente de se connecter au wifi configuré, si ok on continue normalement
+   *                             - si n'arrive pas à se connecter au wifi configuré, passe en mode AP avec webserver pour reconfigurer le wifi / ou demarrer en mode AP si bouton utilisateur appuyé pendant démarragae
+   *                             - normalement redémarre après reconfiguration, donc ok
+   *                             - eventuellement ajouter dans loop un redemarrage en cas de perte de connection
+   */
+
+}
+
+void setupWebserver(){
+  server.on ( "/", []() {digitalWrite(Blue_Led, LOW); Serial.println("admin.html"); server.send ( 200, "text/html", PAGE_AdminMainPage ); digitalWrite(Blue_Led, HIGH);  }  );
+  server.on ( "/admin.html", []() {digitalWrite(Blue_Led, LOW); Serial.println("admin.html"); server.send ( 200, "text/html", PAGE_AdminMainPage ); digitalWrite(Blue_Led, HIGH);  }  );
+  server.on ( "/config.html", send_network_configuration_html );
+  server.on ( "/info.html", []() { digitalWrite(Blue_Led, LOW) ; Serial.println("info.html"); server.send ( 200, "text/html", PAGE_Information ); digitalWrite(Blue_Led, HIGH) ; }  );
+  server.on ( "/ntp.html", send_NTP_configuration_html  );
+  server.on ( "/general.html",  send_general_html );
+  server.on ( "/style.css", []() { digitalWrite(Blue_Led, LOW) ; Serial.println("style.css"); server.send ( 200, "text/plain", PAGE_Style_css ); digitalWrite(Blue_Led, HIGH) ; } );
+  server.on ( "/microajax.js", []() { digitalWrite(Blue_Led, LOW) ; Serial.println("microajax.js"); server.send ( 200, "text/plain", PAGE_microajax_js ); digitalWrite(Blue_Led, HIGH); } );
+  server.on ( "/admin/values", send_network_configuration_values_html );
+  server.on ( "/admin/connectionstate", send_connection_state_values_html );
+  server.on ( "/admin/infovalues", send_information_values_html );
+  server.on ( "/admin/ntpvalues", send_NTP_configuration_values_html );
+  server.on ( "/admin/generalvalues", send_general_configuration_values_html);
+  server.on ( "/admin/devicename",     send_devicename_value_html);
+
+  server.onNotFound ( []() {
+    Serial.println("Page Not Found");
+    server.send ( 400, "text/html", "Page not Found" );
+    ledBlink(Blue_Led, 10, 100);
+  }  );
+  server.begin();
+  Serial.println( "HTTP server started" );
+  tkSecond.attach(1, Second_Tick);
+  UDPNTPClient.begin(2390);  // Port for NTP receive
+}
+
+void loopWebserver(){
+  if (AdminEnabled)  {
+    if (AdminTimeOutCounter > AdminTimeOut)   {
+      AdminEnabled = false;
+      Serial.println("Admin Mode disabled!");
+      WiFi.mode(WIFI_STA);
+    }
+  }
+  if (config.Update_Time_Via_NTP_Every  > 0 )  {
+    if (cNTP_Update > 5 && firstStart)    {
+      NTPRefresh();
+      cNTP_Update = 0;
+      firstStart = false;
+    }
+    else if ( cNTP_Update > (config.Update_Time_Via_NTP_Every * 60) )    {
+      NTPRefresh();
+      cNTP_Update = 0;
+    }
+  }
+
+  if (DateTime.minute != Minute_Old)  {
+    Minute_Old = DateTime.minute;
+    if (config.AutoTurnOn)
+      if (DateTime.hour == config.TurnOnHour && DateTime.minute == config.TurnOnMinute)      {
+        Serial.println("SwitchON");
+      }
+    }
+
+    Minute_Old = DateTime.minute;
+    if (config.AutoTurnOff)    {
+      if (DateTime.hour == config.TurnOffHour && DateTime.minute == config.TurnOffMinute)      {
+        Serial.println("SwitchOff");
+      }
+    }
+  }
+
+
+void setupOTA(){
+  ArduinoOTA.onStart([]() {
+    Serial.println("Start");
+    digitalWrite(Red_Led, HIGH);
+    digitalWrite(Blue_Led, LOW);
+    delay(1000);
+    digitalWrite(Blue_Led, HIGH);
+    delay(500);
+  });
+  ArduinoOTA.onEnd([]() {
+    Serial.println("End");
+    digitalWrite(Blue_Led, HIGH);
+    delay(1000);
+    ledBlink(Blue_Led, 3, 100);
+
+  });
+  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
+    Serial.printf("Progress: %u%%\n", (progress / (total / 100)));
+    digitalWrite(Blue_Led, Blue_Led_State);
+    Blue_Led_State = !Blue_Led_State;
+
+  });
+  ArduinoOTA.onError([](ota_error_t error) {
+    Serial.printf("Error[%u]: ", error);
+    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
+    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
+    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
+    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
+    else if (error == OTA_END_ERROR) Serial.println("End Failed");
+    digitalWrite(Blue_Led, HIGH);
+  });
+  ArduinoOTA.begin();
+}
+
+void loopHandles(){
+  if (loop_counter == 10)  {
+    loop_counter = 0;
+    server.handleClient();
+    Red_Led_State = !Red_Led_State;
+    digitalWrite(Red_Led, Red_Led_State);
+    delay(10);
+    }
+  if (loop_counter == 5)  {
+    ArduinoOTA.handle();
+    delay(10);
+    }
+  loop_counter += 1;
+  if (Refresh)  {
+    Refresh = false;
+    ///Serial.println("Refreshing...");
+    //Serial.printf("FreeMem:%d %d:%d:%d %d.%d.%d \n",ESP.getFreeHeap() , DateTime.hour,DateTime.minute, DateTime.second, DateTime.year, DateTime.month, DateTime.day);
+  }
+
+}
+
+
+

+ 246 - 0
global.h

@@ -0,0 +1,246 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+ESP8266WebServer server(80);									// The Webserver
+boolean firstStart = true;										// On firststart = true, NTP will try to get a valid time
+int AdminTimeOutCounter = 0;									// Counter for Disabling the AdminMode
+strDateTime DateTime;											// Global DateTime structure, will be refreshed every Second
+WiFiUDP UDPNTPClient;											// NTP Client
+unsigned long UnixTimestamp = 0;								// GLOBALTIME  ( Will be set by NTP)
+boolean Refresh = false; // For Main Loop, to refresh things like GPIO / WS2812
+int cNTP_Update = 0;											// Counter for Updating the time via NTP
+Ticker tkSecond;												// Second - Timer for Updating Datetime Structure
+boolean AdminEnabled = false;		// Enable Admin Mode for a given Time
+byte Minute_Old = 100;				// Helpvariable for checking, when a new Minute comes up (for Auto Turn On / Off)
+
+
+#define ACCESS_POINT_NAME  "ESP"
+#define ACCESS_POINT_PASSWORD  "12345678"
+#define AdminTimeOut 60  // Defines the Time in Seconds, when the Admin-Mode will be diabled
+
+struct strConfig {
+	String ssid;
+	String password;
+	byte  IP[4];
+	byte  Netmask[4];
+	byte  Gateway[4];
+	boolean dhcp;
+	String ntpServerName;
+	long Update_Time_Via_NTP_Every;
+	long timezone;
+	boolean daylight;
+	String DeviceName;
+	boolean AutoTurnOff;
+	boolean AutoTurnOn;
+	byte TurnOffHour;
+	byte TurnOffMinute;
+	byte TurnOnHour;
+	byte TurnOnMinute;
+	byte LED_R;
+	byte LED_G;
+	byte LED_B;
+}   config;
+
+
+/*
+**
+** CONFIGURATION HANDLING
+**
+*/
+void ConfigureWifi()
+{
+	Serial.println("Configuring Wifi");
+	WiFi.begin (config.ssid.c_str(), config.password.c_str());
+	if (!config.dhcp)
+	{
+		WiFi.config(IPAddress(config.IP[0],config.IP[1],config.IP[2],config.IP[3] ),  IPAddress(config.Gateway[0],config.Gateway[1],config.Gateway[2],config.Gateway[3] ) , IPAddress(config.Netmask[0],config.Netmask[1],config.Netmask[2],config.Netmask[3] ));
+	}
+}
+
+void WriteConfig()
+{
+
+	Serial.println("Writing Config");
+	EEPROM.write(0,'C');
+	EEPROM.write(1,'F');
+	EEPROM.write(2,'G');
+
+	EEPROM.write(16,config.dhcp);
+	EEPROM.write(17,config.daylight);
+	
+	EEPROMWritelong(18,config.Update_Time_Via_NTP_Every); // 4 Byte
+
+	EEPROMWritelong(22,config.timezone);  // 4 Byte
+
+
+	EEPROM.write(26,config.LED_R);
+	EEPROM.write(27,config.LED_G);
+	EEPROM.write(28,config.LED_B);
+
+	EEPROM.write(32,config.IP[0]);
+	EEPROM.write(33,config.IP[1]);
+	EEPROM.write(34,config.IP[2]);
+	EEPROM.write(35,config.IP[3]);
+
+	EEPROM.write(36,config.Netmask[0]);
+	EEPROM.write(37,config.Netmask[1]);
+	EEPROM.write(38,config.Netmask[2]);
+	EEPROM.write(39,config.Netmask[3]);
+
+	EEPROM.write(40,config.Gateway[0]);
+	EEPROM.write(41,config.Gateway[1]);
+	EEPROM.write(42,config.Gateway[2]);
+	EEPROM.write(43,config.Gateway[3]);
+
+
+	WriteStringToEEPROM(64,config.ssid);
+	WriteStringToEEPROM(96,config.password);
+	WriteStringToEEPROM(128,config.ntpServerName);
+
+	EEPROM.write(300,config.AutoTurnOn);
+	EEPROM.write(301,config.AutoTurnOff);
+	EEPROM.write(302,config.TurnOnHour);
+	EEPROM.write(303,config.TurnOnMinute);
+	EEPROM.write(304,config.TurnOffHour);
+	EEPROM.write(305,config.TurnOffMinute);
+	WriteStringToEEPROM(306,config.DeviceName);
+	
+
+
+	EEPROM.commit();
+}
+boolean ReadConfig()
+{
+
+	Serial.println("Reading Configuration");
+	if (EEPROM.read(0) == 'C' && EEPROM.read(1) == 'F'  && EEPROM.read(2) == 'G' )
+	{
+		Serial.println("Configurarion Found!");
+		config.dhcp = 	EEPROM.read(16);
+
+		config.daylight = EEPROM.read(17);
+
+		config.Update_Time_Via_NTP_Every = EEPROMReadlong(18); // 4 Byte
+
+		config.timezone = EEPROMReadlong(22); // 4 Byte
+
+		config.LED_R = EEPROM.read(26);
+		config.LED_G = EEPROM.read(27);
+		config.LED_B = EEPROM.read(28);
+
+		config.IP[0] = EEPROM.read(32);
+		config.IP[1] = EEPROM.read(33);
+		config.IP[2] = EEPROM.read(34);
+		config.IP[3] = EEPROM.read(35);
+		config.Netmask[0] = EEPROM.read(36);
+		config.Netmask[1] = EEPROM.read(37);
+		config.Netmask[2] = EEPROM.read(38);
+		config.Netmask[3] = EEPROM.read(39);
+		config.Gateway[0] = EEPROM.read(40);
+		config.Gateway[1] = EEPROM.read(41);
+		config.Gateway[2] = EEPROM.read(42);
+		config.Gateway[3] = EEPROM.read(43);
+		config.ssid = ReadStringFromEEPROM(64);
+		config.password = ReadStringFromEEPROM(96);
+		config.ntpServerName = ReadStringFromEEPROM(128);
+		
+		
+		config.AutoTurnOn = EEPROM.read(300);
+		config.AutoTurnOff = EEPROM.read(301);
+		config.TurnOnHour = EEPROM.read(302);
+		config.TurnOnMinute = EEPROM.read(303);
+		config.TurnOffHour = EEPROM.read(304);
+		config.TurnOffMinute = EEPROM.read(305);
+		config.DeviceName= ReadStringFromEEPROM(306);
+		return true;
+		
+	}
+	else
+	{
+		Serial.println("Configurarion NOT FOUND!!!!");
+		return false;
+	}
+}
+
+/*
+**
+**  NTP 
+**
+*/
+
+const int NTP_PACKET_SIZE = 48; 
+byte packetBuffer[ NTP_PACKET_SIZE]; 
+void NTPRefresh()
+{
+
+	
+
+
+	if (WiFi.status() == WL_CONNECTED)
+	{
+		IPAddress timeServerIP; 
+		WiFi.hostByName(config.ntpServerName.c_str(), timeServerIP); 
+		//sendNTPpacket(timeServerIP); // send an NTP packet to a time server
+
+
+		Serial.println("sending NTP packet...");
+		memset(packetBuffer, 0, NTP_PACKET_SIZE);
+		packetBuffer[0] = 0b11100011;   // LI, Version, Mode
+		packetBuffer[1] = 0;     // Stratum, or type of clock
+		packetBuffer[2] = 6;     // Polling Interval
+		packetBuffer[3] = 0xEC;  // Peer Clock Precision
+		packetBuffer[12]  = 49;
+		packetBuffer[13]  = 0x4E;
+		packetBuffer[14]  = 49;
+		packetBuffer[15]  = 52;
+		UDPNTPClient.beginPacket(timeServerIP, 123); 
+		UDPNTPClient.write(packetBuffer, NTP_PACKET_SIZE);
+		UDPNTPClient.endPacket();
+
+
+		delay(1000);
+  
+		int cb = UDPNTPClient.parsePacket();
+		if (!cb) {
+			Serial.println("NTP no packet yet");
+		}
+		else 
+		{
+			Serial.print("NTP packet received, length=");
+			Serial.println(cb);
+			UDPNTPClient.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
+			unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
+			unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
+			unsigned long secsSince1900 = highWord << 16 | lowWord;
+			const unsigned long seventyYears = 2208988800UL;
+			unsigned long epoch = secsSince1900 - seventyYears;
+			UnixTimestamp = epoch;
+		}
+	}
+}
+
+void Second_Tick()
+{
+	strDateTime tempDateTime;
+	AdminTimeOutCounter++;
+	cNTP_Update++;
+	UnixTimestamp++;
+	ConvertUnixTimeStamp(UnixTimestamp +  (config.timezone *  360) , &tempDateTime);
+	if (config.daylight) // Sommerzeit beachten
+		if (summertime(tempDateTime.year,tempDateTime.month,tempDateTime.day,tempDateTime.hour,0))
+		{
+			ConvertUnixTimeStamp(UnixTimestamp +  (config.timezone *  360) + 3600, &DateTime);
+		}
+		else
+		{
+			DateTime = tempDateTime;
+		}
+	else
+	{
+			DateTime = tempDateTime;
+	}
+	Refresh = true;
+}
+ 
+
+#endif

+ 210 - 0
helpers.h

@@ -0,0 +1,210 @@
+#ifndef HELPERS_H
+#define HELPERS_H
+
+
+
+static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; 
+#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
+
+
+struct  strDateTime
+{
+	byte hour;
+	byte minute;
+	byte second;
+	int year;
+	byte month;
+	byte day;
+	byte wday;
+
+} ;
+
+
+
+//
+// Summertime calculates the daylight saving for a given date.
+//
+boolean summertime(int year, byte month, byte day, byte hour, byte tzHours)
+// input parameters: "normal time" for year, month, day, hour and tzHours (0=UTC, 1=MEZ)
+{
+ if (month<3 || month>10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
+ if (month>3 && month<10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
+ if (month==3 && (hour + 24 * day)>=(1 + tzHours + 24*(31 - (5 * year /4 + 4) % 7)) || month==10 && (hour + 24 * day)<(1 + tzHours + 24*(31 - (5 * year /4 + 1) % 7)))
+   return true;
+ else
+   return false;
+}
+
+//
+// Check the Values is between 0-255
+//
+boolean checkRange(String Value)
+{
+	 if (Value.toInt() < 0 || Value.toInt() > 255)
+	 {
+		 return false;
+	 }
+	 else
+	 {
+		 return true;
+	 }
+}
+
+
+void WriteStringToEEPROM(int beginaddress, String string)
+{
+	char  charBuf[string.length()+1];
+	string.toCharArray(charBuf, string.length()+1);
+	for (int t=  0; t<sizeof(charBuf);t++)
+	{
+			EEPROM.write(beginaddress + t,charBuf[t]);
+	}
+}
+String  ReadStringFromEEPROM(int beginaddress)
+{
+	byte counter=0;
+	char rChar;
+	String retString = "";
+	while (1)
+	{
+		rChar = EEPROM.read(beginaddress + counter);
+		if (rChar == 0) break;
+		if (counter > 31) break;
+		counter++;
+		retString.concat(rChar);
+
+	}
+	return retString;
+}
+void EEPROMWritelong(int address, long value)
+      {
+      byte four = (value & 0xFF);
+      byte three = ((value >> 8) & 0xFF);
+      byte two = ((value >> 16) & 0xFF);
+      byte one = ((value >> 24) & 0xFF);
+
+      //Write the 4 bytes into the eeprom memory.
+      EEPROM.write(address, four);
+      EEPROM.write(address + 1, three);
+      EEPROM.write(address + 2, two);
+      EEPROM.write(address + 3, one);
+      }
+long EEPROMReadlong(long address)
+      {
+      //Read the 4 bytes from the eeprom memory.
+      long four = EEPROM.read(address);
+      long three = EEPROM.read(address + 1);
+      long two = EEPROM.read(address + 2);
+      long one = EEPROM.read(address + 3);
+
+      //Return the recomposed long by using bitshift.
+      return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
+}
+
+void ConvertUnixTimeStamp( unsigned long TimeStamp, struct strDateTime* DateTime)
+{
+		uint8_t year;
+	uint8_t month, monthLength;
+	uint32_t time;
+	unsigned long days;
+	  time = (uint32_t)TimeStamp;
+	  DateTime->second = time % 60;
+	  time /= 60; // now it is minutes
+	  DateTime->minute = time % 60;
+	  time /= 60; // now it is hours
+	  DateTime->hour = time % 24;
+	  time /= 24; // now it is days
+	  DateTime->wday = ((time + 4) % 7) + 1;  // Sunday is day 1 
+  
+	  year = 0;  
+	days = 0;
+	while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
+		year++;
+	}
+	DateTime->year = year; // year is offset from 1970 
+  
+	  days -= LEAP_YEAR(year) ? 366 : 365;
+	  time  -= days; // now it is days in this year, starting at 0
+  
+	  days=0;
+	  month=0;
+	  monthLength=0;
+	  for (month=0; month<12; month++) {
+		if (month==1) { // february
+		  if (LEAP_YEAR(year)) {
+			monthLength=29;
+		  } else {
+			monthLength=28;
+		  }
+		} else {
+		  monthLength = monthDays[month];
+		}
+    
+		if (time >= monthLength) {
+		  time -= monthLength;
+		} else {
+			break;
+		}
+	  }
+	  DateTime->month = month + 1;  // jan is month 1  
+	  DateTime->day = time + 1;     // day of month
+	  DateTime->year += 1970;
+
+	 
+}
+
+
+	
+String GetMacAddress()
+{
+	uint8_t mac[6];
+    char macStr[18] = {0};
+	WiFi.macAddress(mac);
+    sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0],  mac[1], mac[2], mac[3], mac[4], mac[5]);
+    return  String(macStr);
+}
+
+// convert a single hex digit character to its integer value (from https://code.google.com/p/avr-netino/)
+unsigned char h2int(char c)
+{
+    if (c >= '0' && c <='9'){
+        return((unsigned char)c - '0');
+    }
+    if (c >= 'a' && c <='f'){
+        return((unsigned char)c - 'a' + 10);
+    }
+    if (c >= 'A' && c <='F'){
+        return((unsigned char)c - 'A' + 10);
+    }
+    return(0);
+}
+
+String urldecode(String input) // (based on https://code.google.com/p/avr-netino/)
+{
+	 char c;
+	 String ret = "";
+	 
+	 for(byte t=0;t<input.length();t++)
+	 {
+		 c = input[t];
+		 if (c == '+') c = ' ';
+         if (c == '%') {
+
+
+         t++;
+         c = input[t];
+         t++;
+         c = (h2int(c) << 4) | h2int(input[t]);
+		 }
+		
+		 ret.concat(c);
+	 }
+	 return ret;
+  
+}
+
+
+
+
+ 
+#endif

+ 46 - 0
includes.h

@@ -0,0 +1,46 @@
+
+int GSR_sensor;
+
+
+const int Blue_Led = 2;
+bool Blue_Led_State ;
+
+const int Red_Led = 0;
+bool Red_Led_State ;
+
+int loop_counter;
+
+#include <ESP8266WiFi.h>
+#include <WiFiClient.h>
+#include <ESP8266WebServer.h>
+#include <Ticker.h>
+#include <EEPROM.h>
+#include <WiFiUdp.h>
+#include "helpers.h"
+#include "global.h"
+
+//OTA includes
+#include <ESP8266mDNS.h>
+#include <WiFiUdp.h>
+#include <ArduinoOTA.h>
+
+WiFiUDP UKI_UDP;
+/*
+  Include the HTML, STYLE and Script "Pages"
+*/
+#include "Page_Root.h"
+#include "Page_Admin.h"
+#include "Page_Script.js.h"
+#include "Page_Style.css.h"
+#include "Page_NTPSettings.h"
+#include "Page_Information.h"
+#include "Page_General.h"
+#include "PAGE_NetworkConfiguration.h"
+
+
+
+
+
+#include "functions.h"
+
+