denisfou
Published © GPL3+

WiFi Temperature and Humidity Sensor

A NodeMCU-based temperature and humidity controller. Sends alerts and periodic summary reports by mail.

AdvancedFull instructions provided10 hours1,436
WiFi Temperature and Humidity Sensor

Things used in this project

Hardware components

DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
resistor 6.8k ohm
used to pull up D0 entry of the nodemcu, useless if you use only one button connected on other pin than D0
×1
membrane keyboard 5 keys
This version of my code doesn't use all keys, you can replace it by a single push button
×1
plastic box
hermetic box is necessary if you plan to put the sensor in an "hostile" environment.
×1
nodemcu v3
I suggest to choose the LoLin NodeMcu V3 model
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
10 cm size is better (20 is too long) Can be found at Aliexpress for very less price. https://fr.aliexpress.com/store/product/10pcs-RCmall-10cm-Female-to-Female-Female-to-Male-Male-to-Male-Dupond-Cable-Wire-Line/2334225_32880760562.html
×1
5*7CM Universal Board Breadboard Dual Side Tin Experimental Board Green Oil Fiberglass Board Double-Sided PCB
"Mother board" of the device.
×1

Hand tools and fabrication machines

Hot glue gun (generic)
Hot glue gun (generic)
used to fix components in the hermetic box and to fill the holes hermeticaly.
electric drill
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

nodemcu temperature sensor DTH22

Schematics

nodemcu temperature sensor DTH22

Code

WifiTemperatureOK.ino

Arduino
Here is the very last version of the code.
I am still developping it the improve this device. (full keyboard usage, mobile device display etc.)
/* serveur de temperature et humidite
		dfournier AT 1234mail DOT fr
		
	
		v 4.91  : add calendar for send mails STABLE
		v 4.92  : add some check to avoid blocking situation after global poweroff (no internet at startup)
		v 4.93  : add more tests to try to reduce (Nan temperatures) + fixed Daily array (0,0) values + Quick Setup if not credential (no more SSID in hard coded) + IP and ExtraMEssage in the mail subject 
		*************************
		v 4.94  : STABLE 
		************************
		v 4.95  : Only one button version (menu disabled)
		v 4.96  : Full factory reset.
		v 4.97  : TimeZone (essentially for DST)
		v 4.98  : fix empty message bug for warning alert
		v 4.99  : Some typos
		
		v 5.00 TODO : Add full menu keypad

* ********************************************************************************************
*/

/*
 * Compilations options : Plateform : NodeCMU 1.0 (ESP12 Module)
 * 80 Mhz
 * Flash Size 4M (3M SPIFFS)
 * Vtables Flash
 * Erease Flash : Only Scketch
 * 
 * 
 * 
 * 
 * 
 */



#define VERSION "4.99"
// #define DEBUGMAIL
#define DEBUG(X) X
#define DEBUGV1(X)
#define DEBUGV2(X)


#include "DHT.h"

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

#include <rBase64.h>
#include <EasyNTPClient.h>
#include <WiFiUdp.h>
#include <Time.h>
#include <TimeLib.h>
#include <FS.h> 

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET D5

/* Object named display, of the class Adafruit_SSD1306 */
Adafruit_SSD1306 display(OLED_RESET);


// Nodemcu table
// Nodemcu Arduino PIN

#define ND0		16
#define ND2 	4
#define ND3 	0
#define ND4     2
#define ND5    	14
#define ND6		12
#define ND7		13
#define ND8		15

#define ND9		3 //RX
#define	ND10	1 //TX

// Current Hardware
// Warning ! Only 3.3v on "BUTTON_DISPLAY" 
// DISPLAY or OK, same BUTTON

#define BUTTON_DISPLAY	D0
//#define BUTTON_UP  		D4
//#define BUTTON_DWN 		D5
//#define BUTTON_LFT 		D3
//#define BUTTON_RGH 		D6
#define RELAY			D8
// 
#define DHTPIN ND7
#define DHTTYPE DHT22

// Initialize DHT sensor.
DHT dht(DHTPIN, DHTTYPE);

#define NBCHAR 90
const char asciiTable[]="_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&#'()[]{}-|`_^@)=+,?;.:/!%*";

// Default init config
char *SetupPassword = "12345678";
char *SetupSsid = "setup";
//char *InitialPassword = "XXXXXXX";
//char *InitialSsid = "yourSSID";
char ErrorMessage[64];


// Current config
char ssid[32];
char password[32];
char offset[6];
char MinPanic[5];
char MinWarn[5];
char MaxPanic[5];
char MaxWarn[5];

char smtpHost[64];
char smtpPort[5];
char smtpUser[32];
char smtpPassword[32];
char smtpFrom[32];
char smtpTo[32];
char deviceName[16];
char DelayH[3];
int  iDelayH;
char TimeZone[7];
long iTimeZone;


char TempPass[32];
// end of config 

// Global Variables 
float TJour[24];
float HJour[24];
unsigned long HTDate[24];

float LastT,LastH ;


char TempStr[10240]; // Html Page 
char BuffStr[5120]; // Messages and big strings*
char StrIP[32];
char chBuffer[128]; // Screen Buffer




typedef struct _Mesure 
{
	float T;
	float H;
	unsigned When ;
} Mesure ;


typedef enum 
{ 
	DevError, 
	Recap, 
	Normal,
	Display,
	NoMail, 
	SaveSPIFFS,
	Resume
} STATE ;


typedef enum {
		KNONE,
		KUP,
		KDOWN,
		KLEFT,
		KRIGHT,
		KOK } KPRESSED ;


char EMAILBASE64_LOGIN[64];
char EMAILBASE64_PASSWORD[64];
		
bool InError=false ;
bool InSetup=false ;
bool InRecap=false ;
bool DeviceOk=false ;
bool Crashed=false ;
bool Boot=false ;
bool deja=false ;
bool DisplayON=true;


boolean connect = false; // connect needed ?

// Network 
ESP8266WebServer server(80);
WiFiUDP udp;
EasyNTPClient ntpClient(udp, "pool.ntp.org");

// WiFiClientSecure MailClient;
WiFiClient MailClient;

// Time management global variables
unsigned long LastTime=0L;
unsigned long InitTime=0L;
unsigned long NowTime=0L;
unsigned long LastDisplay=0L;


char LastDateTime[32] ;

// HTTPClient client ;
// const int httpPort=80;



/* Soft AP network parameters */
IPAddress apIP(192, 168, 4, 1);
IPAddress netMsk(255, 255, 255, 0);
IPAddress IP;

void setup()
{
	int nbtries = 0;

	//ESP.eraseConfig();
	//ESP.reset();
	Serial.begin(115200);

	pinMode(BUTTON_DISPLAY, INPUT_PULLUP);
//	pinMode(BUTTON_UP, 		INPUT_PULLUP);
//	pinMode(BUTTON_DWN, 	INPUT_PULLUP);
//	pinMode(BUTTON_LFT, 	INPUT_PULLUP);
//	pinMode(BUTTON_RGH, 	INPUT_PULLUP);	
	pinMode(RELAY,			OUTPUT);

	digitalWrite(RELAY,LOW);

	display.begin(SSD1306_SWITCHCAPVCC, 0x3C); /* Initialize display with address 0x3C */
	display.clearDisplay();  /* Clear display */
	display.setTextSize(1);	/* Select font size of text. Increases with size of argument. */
	display.setTextColor(WHITE);	/* Color of text*/
    
    DisplayStr("init Ok",0,8,true,true) ;

	if (SPIFFS.begin())
	{
		if (!SPIFFS.exists("/OK"))
		{
			  if (SPIFFS.format())
			  {
			      if (SPIFFS.open("/OK", "w"))
			      {
			          DEBUG(Serial.println("SPIFF Cr !");)
			      }
			  }
		}
		else
		{
			DEBUG(Serial.println("SPIFF exists !");)
		}
// Reboot after crash
		if (SPIFFS.exists("/REBOOTED"))
		{
			Crashed=true ;
			SPIFFS.remove("/REBOOTED");
		}
		else
		{
			Boot=true ;
		}
	}


	DisplayStr("reading conf",0,16,false,true) ;
	DEBUG(Serial.println("goto ReadConfig");)
	memset(TempStr,0,sizeof(TempStr)); 
	
	 if (ReadConfig("/config.txt"))
	 {
	 	DisplayStr("credentials loaded",0,0,true,true);
		DisplayStr("Connecting...",0,24,false,true) ;
		DEBUG(Serial.printf("connecting to %s/%s\n", ssid, password);)
		WiFi.mode(WIFI_STA);
		WiFi.begin(ssid, password);
		DEBUG(Serial.print("Connecting");)	 	
		InSetup=false ;
	 }
	else
	{
		DisplayStr("credentials NOT loaded",0,0,true,true);
		CoolDelay(1000);
		InSetup=true;
	}

	while ((!InSetup)&& (WiFi.status() != WL_CONNECTED) && (nbtries < 40))
	{
		CoolDelay(500);
		DEBUG(Serial.print(".");)
		nbtries++;
	}
	if ((nbtries >= 40)||(InSetup))
	{
		DEBUG(Serial.println("\nOk lets open AP");)
		
		WiFi.mode(WIFI_AP);
		WiFi.softAPConfig(apIP, apIP, netMsk);
		WiFi.softAP(SetupSsid, SetupPassword);
		
		CoolDelay(500); // Without CoolDelay I've seen the IP address blank
		DEBUG(Serial.print("AP IP address: ");)
		DEBUG(Serial.println(WiFi.softAPIP());)
		IP=WiFi.softAPIP();
		InSetup=true ;
		CoolDelay(500);
		sprintf(StrIP,"%d.%d.%d.%d",IP[0],IP[1],IP[2],IP[3]);
		DisplayStr("Setup Mode",0,8,true,true);
		DisplayStr(StrIP,0,32,false,true);
	}
	else
	{
		DEBUG(Serial.println();)
		DEBUG(Serial.print("Connected, IP address: ");)
		DEBUG(Serial.println(WiFi.localIP());)
		IP=WiFi.localIP(); 
		sprintf(StrIP,"%d.%d.%d.%d",IP[0],IP[1],IP[2],IP[3]);
		DisplayStr(StrIP,0,0,true,true);
		
		InitTime=ntpClient.getUnixTime()-(millis()/1000)+iTimeZone; // We might have internet, let's get the time.
		InSetup=false ;
		handleMeteo();
	}
 
	// server.on("/other", []() { server.send(200, "text / plain", "Other URL"); });

	server.on("/", handleRootPath);    //Associate the handler function to the path
	server.on("/testmail", handleMeteo); // Page de meteo
	server.on("/setconfig", handleSetConfig); // set wifi credential
	server.on("/configsave", handleConfigSave); // save the form
	server.on("/infos", handleInfos); // get infos on the device
	server.on("/sendrecap", handleRecap); // get infos on the device
	server.on("/readspiffs",ReadMesure); // ReadSPIFFS
	server.on("/savespiffs",SaveMesure_);
	server.on("/resetMesure",EraseMesure);
	server.on("/fullreset",FullReset);
	server.on("/reboot",Reboot);
	server.on("/onrelay",onRelay);
	server.on("/offrelay",offRelay);

	
	server.begin();                    //Start the server

	DEBUG(Serial.println("Server listening");)

}

int GetDeviceInfo(float *t, float *h)
{
	float calibrate;
	int i=3;

	calibrate=atof(offset);
	
	// Reading temperature or humidity takes about 250 milliseconds!
    *h = dht.readHumidity();
	CoolDelay(250);    
	*t = dht.readTemperature();  // Read temperature as Celsius (the default)

	if (isnan(*h) || isnan(*t))
	{
		CoolDelay(3000);
		if (isnan(*h))  
			*h = dht.readHumidity();
		if (isnan(*t)) 
		{
			CoolDelay(250);    
			*t = dht.readTemperature();  // Read temperature as Celsius (the default)
		}
	}
	else
	{
		*t=*t+calibrate;
		LastT=*t;
		LastH=*h;
		DeviceOk=true;
		return 0;
	}
	
	if (isnan(*h) || isnan(*t))
	{
		CoolDelay(3000);
		if (isnan(*h))  
			*h = dht.readHumidity();
		
		if (isnan(*t)) 
		{
			CoolDelay(250);    
			*t = dht.readTemperature();  // Read temperature as Celsius (the default)
		}
	}
	else
	{
		*t=*t+calibrate;
		LastT=*t;
		LastH=*h;
		DeviceOk=true;
		return 0;
	}
		
	if (isnan(*h) || isnan(*t))
	{
		CoolDelay(10000);
		
		if (isnan(*h))  
			*h = dht.readHumidity();
		if (isnan(*t)) 
		{
			CoolDelay(250);    
			*t = dht.readTemperature();  // Read temperature as Celsius (the default)
		}
	}
	else
	{
		*t=*t+calibrate;
		LastT=*t;
		LastH=*h;
		DeviceOk=true;
		return 0;
	}	
	
	if (isnan(*h) || isnan(*t))
	{
		CoolDelay(10000);
		
		if (isnan(*h))  
			*h = dht.readHumidity();
		if (isnan(*t)) 
		{
			CoolDelay(250);    
			*t = dht.readTemperature();  // Read temperature as Celsius (the default)
		}
	}
	else
	{
		*t=*t+calibrate;
		LastT=*t;
		LastH=*h;
		DeviceOk=true;
		return 0;
	}
	
	if (isnan(*h) || isnan(*t))
	{
			LastT=0;
			LastH=0;
			DeviceOk=false;
			return -1;
	}
	else
	{
		*t=*t+calibrate;
		LastT=*t;
		LastH=*h;
		DeviceOk=true;
		return 0;
	}
}


void handleRootPath()  //handler for the rooth path
{
	sprintf(TempStr,"<html><body>");
	strcat(TempStr,"<h2> Device ");
	strcat(TempStr,deviceName);
	strcat(TempStr,"</h2><br><br>");
	strcat(TempStr,"<a href='./setconfig'> Config </a><br><a href='./infos'>Device Informations</a><br><a href='/sendrecap'>test recap</a>");
	strcat(TempStr,"</body></html>");  
	server.send(200, "text/html", TempStr);
}

void handleRecap()  //handler for the rooth path
{
	sprintf(TempStr,"OK");
	InRecap=true ;
	InError=false ;
	
	if (TraiteFlow(0, 0, Recap))
		strcat(TempStr,ErrorMessage);
	else
		strcat(TempStr,"Message sent");
		
	server.send(200, "text/html", TempStr);
}

void handleMeteo()
{
	String result ;
	String tmpresult;
	String temperature ;
	String humidity ;
	float h,t;
	int iserror;
	unsigned int GoodTime;
	DEBUG(Serial.println("handlemeteo 0");)
	iserror=GetDeviceInfo(&t, &h);
	DEBUG(Serial.println("handlemeteo 1");)
	if (iserror)
	{
		DEBUG(Serial.println("handlemeteo 2");)
		result = "<h2>No data...</h2>" ;
		strcpy(ErrorMessage,"No DATA... Check the device !");
		InError=true;
		if (!InSetup)
		{
			if (Crashed)
			{
				TraiteFlow(t,h,Resume);
				Crashed=false;
			}
			if (TraiteFlow(0.0, 0.0, DevError))
			{
			  tmpresult=ErrorMessage;
			  result+=tmpresult; 
			}
			else
			  result+="Message sent";
		}
		else
		{
			result+="InSetup, NO Mail" ;
			// are we in setup for more than one hour ?
			if (millis()/1000 > 3600 )
			{
				SPIFFS.open("/REBOOTED", "w");
				CoolDelay(2000);
				Reboot();
			}
		}
	}
	else
	{
		DEBUG(Serial.println("handlemeteo 3");)
		InError=false;
	// here we add offset to calibrate
		
		temperature = String(t);
		humidity = String(h);
		DEBUG(Serial.println("handlemeteo 4");)
		result = "Temperature : " + temperature + "<br>humidite :" + humidity + "<br>";
		if (!InSetup)
		{
			DEBUG(Serial.println("handlemeteo 5");)
			LastTime=ntpClient.getUnixTime()+iTimeZone;
			GoodTime=LastTime ;
			sprintf(LastDateTime,"%02d/%02d/%04d - %02d:%02d:%02d", day(GoodTime),month(GoodTime),year(GoodTime),hour(GoodTime),minute(GoodTime),second(GoodTime));
			DEBUG(Serial.println("handlemeteo 7");)
			if (Crashed)
			{
				Boot=false;
				TraiteFlow(t,h,Resume);
				Crashed=false;
			}

			if (SPIFFS.exists("/DAILY")) // Daily reboot detected !
			{
				SPIFFS.remove("/DAILY");
				if (!hour(GoodTime))
				{
				  TJour[0]=t;
				  HJour[0]=h;
				}
			}

			if (TraiteFlow(t, h, Normal))
			{
			  DEBUG(Serial.println("handlemeteo 8");)
			  tmpresult=ErrorMessage; 
			  result+=tmpresult; 
			}
			else
			{
			  DEBUG(Serial.println("handlemeteo 8 bis MEssage sent");)
			  result+="Message sent";
			}
		}
		else
		{
			if (millis()/1000 > 3600 )
			{
				SPIFFS.open("/REBOOTED", "w");
				CoolDelay(2000);
				Reboot();
			}
		}
	}
	DEBUG(Serial.println("handlemeteo 9");)
	// server.send(200, "text/html", (String)"<html><body>"+result+"</html></body>");
}
void handleInfos()
{

	char Numbers[7];
	unsigned int Time;
	char TempChar[64];
	float t,h;
	int HH,MM,SS;
	unsigned long Sec, NowTime;

	Sec=millis()/1000.0;
	HH=(Sec/3600);
	MM=(Sec-(HH*3600))/60;
	SS=Sec%60;

	NowTime=InitTime + millis()/1000 ;

	Time=ntpClient.getUnixTime()+iTimeZone;
	
	sprintf(TempStr,"<html><body><br>Version : %s<br>Time/Date : %02d/%02d/%04d - %02d:%02d:%02d Powered since : %d h %d mn %d sec<br> Estimated Time : %02d:%02d:%02d",\
	VERSION, day(Time),month(Time),year(Time),hour(Time),minute(Time),second(Time),HH,MM,SS,hour(NowTime),minute(NowTime),second(NowTime));
	sprintf(TempChar,"IP %s<br>",StrIP);
	strcat(TempStr,TempChar);
	
	if (!GetDeviceInfo(&t,&h))
	{
			sprintf(TempChar,"Temp : %2.1f Hum : %2.02f%%<br>",t,h);
			strcat(TempStr,TempChar);
	}
	else
	{
		strcat(TempStr,"<h2>Device Not Ready</h2><br>");
	}

	strcat(TempStr,"<fieldset><legend>General Config</legend>\n");
	strcat(TempStr,"<table>" "<tr><td> ssid </td> <td>");
	strcat(TempStr,ssid);
	strcat(TempStr,"</td></tr>\n"
	"<tr><td>password</td><td>");
	strcat(TempStr,"*********");
	//strcat(TempStr,password);
	strcat(TempStr,"</td></tr>\n"
	"<tr><td>Device Name</td><td>");
	strcat(TempStr,deviceName);
	strcat(TempStr,"</td></tr>\n");
	strcat(TempStr,"<tr><td>Time Offset (TZ)</td><td>");
	strcat(TempStr,TimeZone);
	strcat(TempStr," seconds</td><tr></table>" 
		"</fieldset>"
		"<fieldset><legend>Temperature control</legend><table>"
		"<tr><td>offset calibration</td><td>");
	strcat(TempStr,offset);
	strcat(TempStr,"&deg; C</td></tr>\n");

	strcat(TempStr,"<tr><td>Min Warning</td><td>");
	strcat(TempStr,MinWarn);
	strcat(TempStr,"&deg; C</td></tr>\n");
		
	strcat(TempStr,"<tr><td>Min Panic</td><td>");
	strcat(TempStr,MinPanic);
	strcat(TempStr,"&deg; C</td></tr>\n");
		
	strcat(TempStr,"<tr><td>Max Warning</td><td>");
	strcat(TempStr,MaxWarn);
	strcat(TempStr,"&deg; C</td></tr>\n");
		
	strcat(TempStr,"<tr><td>Max Panic</td><td>");
	strcat(TempStr,MaxPanic);
	strcat(TempStr,"&deg; C</td></tr>\n</table>\n"
	"</fieldset>");
	strcat(TempStr,"<fieldset><legend>Mail Control</legend><table>");
	strcat(TempStr,"<tr><td>smtp Host </td><td>");
	strcat(TempStr,smtpHost);
	strcat(TempStr,"</td></tr>\n");

	strcat(TempStr,"<tr><td>smtp Port </td><td>");
	strcat(TempStr,smtpPort);
	strcat(TempStr,"</td></tr>\n");

	strcat(TempStr,"<tr><td>smtp User</td><td>");
	strcat(TempStr,smtpUser);
	strcat(TempStr,"</td></tr>\n");

	strcat(TempStr,"<tr><td>smtp Password</td><td>");
	strcat(TempStr,"************");
	// strcat(TempStr,smtpPassword);
	strcat(TempStr,"</td></tr>\n");

	strcat(TempStr,"<tr><td>smtp From </td><td>");
	strcat(TempStr,smtpFrom);
	strcat(TempStr,"</td></tr>\n");

	strcat(TempStr,"<tr><td>smtp To </td><td>");
	strcat(TempStr,smtpTo);
	strcat(TempStr,"</td></tr>\n");
	strcat(TempStr,"<tr><td>Mail every</td><td>");
	strcat(TempStr,DelayH);
	strcat(TempStr," Hours");
	strcat(TempStr,"</td></tr>\n</table>\n");
	strcat(TempStr,"</fieldset>");
	strcat(TempStr,"<fieldset><legend>Current History</legend><table>\n");
	strcat(TempStr,"<tr><th>Heure</th><th>Temp</th><th>Humidite</th></tr>\n");
	for (int i=0; i<24;i++)
	{
			strcat(TempStr,"<tr><td>");
			sprintf(Numbers,"%02dH",i);
			strcat(TempStr,Numbers);
			strcat(TempStr,"</td><td>");
			sprintf(Numbers,"%2.1f",TJour[i]);
			strcat(TempStr,Numbers);
			strcat(TempStr,"</td><td>");
			sprintf(Numbers,"%2.2f",HJour[i]);
			strcat(TempStr,Numbers);
			strcat(TempStr,"</td></tr>\n");
	}
	
	strcat(TempStr,"</table>\n");
	strcat(TempStr,"</fieldset>\n");
	strcat(TempStr,"<p><a href='/'>Home page</a>.</p>\n");
	strcat(TempStr,"<p><a href='/testmail'>TESTMAIL</a>.</p>\n");			
	strcat(TempStr,"<p><a href='/savespiffs'>SAVESPIFFS</a>.</p>\n");
	strcat(TempStr,"<p><a href='/readspiffs'>READSPIFFS</a>.</p>\n");
	strcat(TempStr,"<p><a href='/resetMesure'>RESET Mesures</a>.</p>\n");
	strcat(TempStr,"<p><a href='/reboot'>REBOOT Device</a>.</p>\n");
	strcat(TempStr,"<p><a href='/fullreset'>FACTORY RESET</a>.</p>\n");

//	strcat(TempStr,"<p><a href='/onrelay'>ONRELAY</a>.</p>\n");
//	strcat(TempStr,"<p><a href='/offrelay'>OFFRELAY</a>.</p>\n");		

	strcat(TempStr,"</body></html>");  
	server.send(200, "text/html", TempStr);

	DEBUG(ReadMesure();)

}

void handleSetConfig()
{
	int n = WiFi.scanNetworks();

	server.sendContent("<body><html><br>Version :");
	server.sendContent(VERSION);
	server.sendContent("<br><form id='MyForm' method='POST' action='configsave'><br>");
	server.sendContent("<fieldset><legend>General Config</legend>\n");
	server.sendContent("<table>\n" "<tr><td> ssid </td> <td><input type='text' placeholder='network' name='issid' value='");
	server.sendContent(ssid);
	server.sendContent("' /></td></tr>\n"
	"<tr><td>password</td><td> <input type='password' placeholder='password' name='pass' value='12345678");
	// server.sendContent(password);
	server.sendContent("' /></td></tr>\n"
	"<tr><td>Device Name</td><td> <input type='text' placeholder='device name' name='deviceName' value='");
	server.sendContent(deviceName);
	server.sendContent("' /></td></tr>\n"),
	server.sendContent("<tr><td>Time Offset (TZ)</td><td><input type='text' placeholder='Offsest' name='TimeZone' value='");
	server.sendContent(TimeZone);
	server.sendContent("' /> seconds</td><tr></table>\n"); 
	server.sendContent("</fieldset>"
		"<fieldset><legend>Temperature control</legend>\n<table>"
		"<tr><td>offset calibration</td><td><input type='text' placeholder='offset' name='offs' value='");
	server.sendContent(offset);
	server.sendContent("'/> &deg; C</td></tr>\n");

	server.sendContent("<tr><td>Min Warning</td><td><input type='text' placeholder='MinWarn' name='MinWarn' value='");
	server.sendContent(MinWarn);
	server.sendContent("'/> &deg; C</td></tr>\n");
		
	server.sendContent("<tr><td>Min Panic</td><td><input type='text' placeholder='MinPanic' name='MinPanic' value='");
	server.sendContent(MinPanic);
	server.sendContent("'/> &deg; C</td></tr>\n");
		
	server.sendContent("<tr><td>Max Warning</td><td><input type='text' placeholder='MaxWarn' name='MaxWarn' value='");
	server.sendContent(MaxWarn);
	server.sendContent("'/> &deg; C</td></tr>\n");
		
	server.sendContent("<tr><td>Max Panic</td><td><input type='text' placeholder='MaxPanic' name='MaxPanic' value='");
	server.sendContent(MaxPanic);
	server.sendContent("'/> &deg; C</td></tr>\n</table>\n"
	"</fieldset>");
	server.sendContent("<fieldset><legend>Mail Control</legend><table>");
	server.sendContent("<tr><td>smtp Host </td><td><input type='text' placeholder='hostname or IP' name='smtpHost' value='");
	server.sendContent(smtpHost);
	server.sendContent("'/></td></tr>\n");

	server.sendContent("<tr><td>smtp Port </td><td><input type='text' placeholder='Smtp Port' name='smtpPort' value='");
	server.sendContent(smtpPort);
	server.sendContent("'/></td></tr>\n");

	server.sendContent("<tr><td>smtp User</td><td><input type='text' placeholder='Smtp User' name='smtpUser' value='");
	server.sendContent(smtpUser);
	server.sendContent("'/></td></tr>\n");

	server.sendContent("<tr><td>smtp Password</td><td><input type='password' placeholder='Smtp Password' name='smtpPassword' value='12345678");
	// server.sendContent(smtpPassword);
	server.sendContent("'/></td></tr>\n");

	server.sendContent("<tr><td>smtp From </td><td><input type='text' placeholder='Email Sender' name='smtpFrom' value='");
	server.sendContent(smtpFrom);
	server.sendContent("'/></td></tr>\n");

	server.sendContent("<tr><td>smtp To </td><td><input type='text' placeholder='Email destination' name='smtpTo' value='");
	server.sendContent(smtpTo);
	server.sendContent("'/></td></tr>\n");
	server.sendContent("<tr><td rowspan=7>Frequency </td>\n");
	server.sendContent("    <td><input type='radio' name='dH' value='1'");
	if (iDelayH==1)
		server.sendContent("checked");
	server.sendContent("> 1 hour</td></tr>\n");
	
	server.sendContent("<tr><td><input type='radio' name='dH' value='2'");
	if (iDelayH==2)
		server.sendContent("checked");	
	server.sendContent("> 2 hours</td></tr>\n");
	
	server.sendContent("<tr><td><input type='radio' name='dH' value='3'");
	if (iDelayH==3)
		server.sendContent("checked");	
	server.sendContent("> 3 hours</td></tr>\n");
	
	server.sendContent("<tr><td><input type='radio' name='dH' value='4'");
	if (iDelayH==4)
		server.sendContent("checked");	
	server.sendContent("> 4 hours</td></tr>\n");
	
	server.sendContent("<tr><td><input type='radio' name='dH' value='6'");
	if (iDelayH==6)
		server.sendContent("checked");	
	server.sendContent("> 6 hours</td></tr>\n");
	
	server.sendContent("<tr><td><input type='radio' name='dH' value='8'");
	if (iDelayH==8)
		server.sendContent("checked");	
	server.sendContent("> 8 hours</td></tr>\n");
	
	server.sendContent("<tr><td><input type='radio' name='dH' value='12'");
	if (iDelayH==12)
		server.sendContent(" checked");	
	server.sendContent(">12 hours</td></tr>\n");
	
	server.sendContent("</table>\n");
	server.sendContent("</fieldset>\n");
	
	server.sendContent("<table><tr><td><input type='submit'/><input type='reset'/></td></tr></table>");
	server.sendContent("</form>\n");
	server.sendContent("<br><br><a href='/'>home</a>.</p>\n");
	server.sendContent("<table><tr><td><H2>WIFI networks avaiable </h2></td></tr>\n");

	if (n > 0) 
	{
		for (int i = 0; i < n; i++) 
		{
			server.sendContent(String() + "\r\n<tr><td> <a href=\"javascript:void(0);\" onclick=\"document.forms['MyForm'].elements['issid'].value='"+WiFi.SSID(i)+"';\">"+ WiFi.SSID(i)  + String((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : " *") + " (" + WiFi.RSSI(i) + ")</a></td></tr>");
		}
	}

// <a href="javascript:void(0);" onclick="textFill('txt1','This data goes to field 1');">Populate field 1</a>	
	else 
	{
		server.sendContent(String() + "<tr><td>No WLAN found</td><td></td></tr>\n");
	}
	server.sendContent("</table>");
	server.sendContent("</body></html>");
	
	server.client().stop(); // Stop is needed because we sent no content length

}

void handleConfigSave()
{
 
	DEBUG(Serial.println("Config save");)
	server.arg("issid").toCharArray(ssid, sizeof(ssid) - 1);
	server.arg("pass").toCharArray(TempPass, sizeof(TempPass) - 1);
	if (strcmp(TempPass,"12345678"))
	{
			strcpy(password,TempPass);
	}
	

	server.arg("offs").toCharArray(offset, sizeof(offset) - 1);
	server.arg("deviceName").toCharArray(deviceName,sizeof(deviceName)-1);
	server.arg("TimeZone").toCharArray(TimeZone,sizeof(TimeZone)-1);
	iTimeZone=atoi(TimeZone);

	server.arg("MinPanic").toCharArray(MinPanic, sizeof(MinPanic) - 1);
	server.arg("MinWarn").toCharArray(MinWarn, sizeof(MinWarn) - 1);
	server.arg("MaxPanic").toCharArray(MaxPanic, sizeof(MaxPanic) - 1);
	server.arg("MaxWarn").toCharArray(MaxWarn, sizeof(MaxWarn) - 1);
	
	server.arg("smtpHost").toCharArray(smtpHost, sizeof(smtpHost) - 1);
	server.arg("smtpPort").toCharArray(smtpPort, sizeof(smtpPort) - 1);
	server.arg("smtpUser").toCharArray(smtpUser, sizeof(smtpUser) - 1);
	server.arg("smtpPassword").toCharArray(TempPass, sizeof(TempPass) - 1);
	server.arg("dH").toCharArray(DelayH,sizeof(DelayH)-1);
	
	iDelayH=atoi(DelayH);
	
	if (strcmp(TempPass,"12345678"))
	{
			strcpy(smtpPassword,TempPass);
	}

	
	server.arg("smtpFrom").toCharArray(smtpFrom, sizeof(smtpFrom) - 1);
	server.arg("smtpTo").toCharArray(smtpTo, sizeof(smtpTo) - 1);
	
 
	server.sendHeader("Location", "/", true);
	server.sendHeader("Pragma", "no-cache");	server.sendHeader("Expires", "-1");
	server.send ( 302, "text/plain", "");  // Empty content inhibits Content-length header so we have to close the socket ourselves.
	server.client().stop(); // Stop is needed because we sent no content length

	WriteConfig("/config.txt");

	connect = strlen(ssid) > 0; // Request WLAN connect with new credentials if there is a SSID
	
}



int TraiteFlow(float f, float h, STATE Status)
{

		char subject[64];
		char tmpMess[64];
		char ExtraMsg[16];
		int encodeLen ;
		bool ToMail=false, ToHistory=false;
		Mesure M;

		BuffStr[0]=0;
		ExtraMsg[0]=0;

		// NowTime=ntpClient.getUnixTime();
		NowTime=InitTime+(millis()/1000);

		
		sprintf(LastDateTime,"%02d/%02d/%04d - %02d:%02d:%02d", day(NowTime),month(NowTime),year(NowTime),hour(NowTime),minute(NowTime),second(NowTime));
		
		DEBUG(Serial.println("Entree TraiteFlow");)

		

		if (Status != DevError)
		{
			M.When=InitTime+(millis()/1000);
			M.T=f;
			M.H=h;
			SaveMesure(&M);
		}
		else
		{
			if ((f<atof(MinWarn))&&(Status != Display))
			{
					TraiteFlow(f, h, Display);
			}
		}


		if (Boot)
		{
			sprintf(ExtraMsg,"Reboot");
			Boot=false;
		}

		switch(Status)
		{
			case DevError:
			{
			  sprintf(subject,"ERREUR CRITIQUE !!! %s (%s)",deviceName,StrIP);    
			  strcpy(BuffStr,ErrorMessage);
			  ToMail=true;
			  break;
			}
			case Recap:
			{
			    sprintf(subject,"Recap - 24h %s (%s)",deviceName,StrIP);
			    for (int i=0; i<24;i++)
			    {
			      sprintf(tmpMess,"%0dH => %0.2lf C %2.2f%%<br>\n",i,TJour[i],HJour[i]);
			      strcat(BuffStr,tmpMess);
			      DEBUG(Serial.println(BuffStr);)
			    }
			    ToMail=true;
			    break;
			  
			} 
			case Resume:
			{
				sprintf(subject,"RESUME OPERATIONS %s (%s)",deviceName,StrIP);
				sprintf(BuffStr,"Reboot effectu");
				break;
			}

			case Normal:
			{
			  if (f<atof(MinWarn) || (f>atof(MaxWarn)))
			  {
			    if (f<atof(MinPanic) || (f>atof(MaxPanic)))
			    {
			       sprintf(subject,"ALERTE !!! %s %s (%s)",deviceName,ExtraMsg,StrIP);
			    }
			    else
...

This file has been truncated, please download it to see its full contents.

Credits

denisfou

denisfou

2 projects • 2 followers
French geek older than 50 years old, i’ve been a Unix system ingeneer for more than 20 years. I've always written code as a hobby.

Comments