Hardware components | ||||||
  | × | 1 | ||||
  | × | 2 | ||||
![]()  | 
  | × | 2 | |||
The air near the ceiling is hotter than the air onthe ground.
I have a fan from a dead server's power suplly, so in buy a 15cm tube (for kitchen exhaust) ant attached the fan on top.
The tempatatures are measured with DS18B20 dgital sensor, and the relays are driven accordingly to the temp. set points i.e.:-below TempfanSLOW: OFF-between TempFanSLOW and TempFanFAST: SLOW-above TempFanFAST: FAST
Manual control is done in a loop : AUTO, SLOW, FAST, OFF
If sensor is defective, set TempFanSlow to 0 force MAN mode.
The speed is limited by a capacitor in series with the fan.
The 'fast' relay bypass the capacitor, thus full speed
In addition to the info, all parameters can be modified from a 'site' generated by the NodeMCU.
Re programming by 'Over The Air'
Manual control from a hardware button.
If you want info, send me a message.
Matériel :
Vertical Circulator
Arduino/*
//
//  version nodemcu 2020 01 12
//  https://randomnerdtutorials.com/esp8266-ds18b20-temperature-sensor-web-server-with-arduino-ide/
//
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! my nodeMCU use  ESP8266
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* 
// https://www.vultr.com/docs/using-screen-on-ubuntu-14-04
ctrl-A \  
screen /dev/ttyUSB0 115200
 ADDED  <pgmspace.h>
 * /home/luc/arduino-1.8.9/hardware/tools/avr/avr/include/avr/pgmspace.h
 * /home/luc/Dropbox/arduino_ino/libraries/OneWire/OneWire.h
 *
 * warning: 'bool HTTPClient::begin(String)' is deprecated 
(declared at 
/home/luc/.arduino15/packages/esp8266/hardware/esp8266/2.6.3/libraries/
ESP8266HTTPClient/src/ESP8266HTTPClient.h:155) [-Wdeprecated-declarations]
* 
* https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#enable-wi-fi-diagnostic
https://makeradvisor.com/esp32-vs-esp8266/
* Rcuprer automatiquement des redmarrages en boucle du ESP8266
* https://www.sigmdel.ca/michel/program/esp8266/arduino/watchdogs2_fr.html
* 
*/
//______________________________________________________________________
const char FileName[]="=== V 001.78 DifferentialTemp_nodeMCU03-SRV-OTA.ino";
const char HostName[]="VertCirc";
//______________________________________________________________________
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//#include <ESP8266WiFi.h> 
// <ESP8266WiFi.h>  // official arduino  //https://randomnerdtutorials.com/esp32-esp8266-input-data-html-form/#more-88796
// <ESP8266wifi.h>  // is  Jonas Ekstrand.
#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
  #include <SPIFFS.h>
#else  //my nodemcu with ESP8266
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
  #include <Hash.h>
  #include <FS.h>
#endif
#include <ESPAsyncWebServer.h>    // my nodemcu with ESP8266
//https://techtutorialsx.com/2017/12/01/esp32-arduino-asynchronous-http-webserver/
#include <ESP8266HTTPClient.h>
//  OTA   
// https://projetsdiy.fr/arduinoota-ota-mise-jour-sans-fil-ide-arduino-programmes-esp8266/
//debug by ota:
// https://www.fais-le-toi-meme.fr/fr/electronique/tutoriel/esp8266-arduinoota-mise-a-jour-logiciel-esp8266-wifi
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
//
///////////////////////////////////////////////////////////
//set relay output wire
#define RELAY_ON   D5 // 14  // D5 GPIO14  relayboard in1
#define RELAY_FAST D6 // 12  // D6 GPIO12  relayboard in2
#define ENABLE LOW      //relay is reverse logic: active on low 
#define DISABLED HIGH 
///////////////////////////////////////////////////////////
// led
#define LED_ON     0
#define LED_OFF    1
//status led : ON if auto mode
#define pinled LED_BUILTIN  // D0 ;  //  GPIO16 ;
///////////////////////////////////////////////////////////
// button
// https://www.baldengineer.com/detect-short-long-button-press.html
#define PRESSED     LOW
#define NOT_PRESSED HIGH
const unsigned long shortPress = 50;
const unsigned long longPress = 500;
typedef struct Buttons {
    const byte pin = D1 ;  // D1 =GPIO5
    const int debounce = 20;
    unsigned long counter=0;
    bool prevState = NOT_PRESSED;
    bool currentState;
} Button;
Button button;
//  
// https://randomnerdtutorials.com/esp32-esp8266-input-data-html-form/#more-88796
//
#if defined(ESP8266)   // my NodeMCU  use this
	//ESP8266WebServer server(80);
	AsyncWebServer server(80);
#endif
#if defined(ESP32)
	WebServer server(80);
#endif
///////////////////////////////////////////////////////////
// temperature sensors
#define TEMPERATURE_PRECISION 12 //9..12
#define ONE_WIRE_BUS 4  // D2 = GPIO4  Data wire ONE_WIRE_BUS 
// arrays to hold device addresses
#define iMaxCntDev 2   //max devs expected. limit mem used  real count will be in 
byte iCntDev  ;                    //physical dev count
DeviceAddress probes[iMaxCntDev];  // table holding dev adress
float probeTemp[iMaxCntDev];       // table holding measures
OneWire myOneWireDev(ONE_WIRE_BUS);// Setup a myOneWireDev instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature mySensors(&myOneWireDev);// Pass our myOneWireDev reference to Dallas Temperature.
///////////////////////////////////////////////////////////
// wifi
char ssid[] = "BRG-FLOOR0-2G";  // your network SSID (name) "BRG-FLOOR0-2G" "BRG-FLOOR0-TPLINK"
char password[] = "0499185306";       // your network password
const char* PARAM_idelayMeasures = "idelayMeasures";
const char* PARAM_idelayRelays = "idelayRelays";
const char* PARAM_idelaySendData = "idelaySendData";
const char* PARAM_idelayRstDelta	 = "idelayRstDelta";
const char* PARAM_TempFanSLOW = "TempFanSLOW";
const char* PARAM_TempFanFAST = "TempFanFAST";
const char* PARAM_mode = "mode";
const char* PARAM_state = "state";
String  GETdata ;  //will contains line send to server
/*
 * 
 *     function submitMessage() {
      alert("Saved value to ESP SPIFFS");
      setTimeout(function(){ document.location.reload(false); }, 500);   
 * */
// https://www.w3schools.com/html/tryit.asp
//  definition of the html page site
//  https://www.w3schools.com/code/tryit.asp?filename=GDSIWKZTNCZ2
// <input type="submit" method="POST" VALUE=">> Rechercher <<">
// <input type="submit" value="" onclick="submitMessage()">
//  https://www.w3schools.com/get?  TempFanSLOW= &Def_TempFanSLOW=_TempFanSLOW
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>Vertical Circulator Parameters</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<META HTTP-EQUIV="Refresh" CONTENT="60">
<script>function submitMessage(){setTimeout(function(){ document.location.reload(false); }, 500);}</script>
<style>table, th, td {border: 1px solid black;border-collapse: collapse;} </style>
</head><body>
%FileName%
<table>
  <tr>
    <th>Temp up</th>
    <th>Temp down</th>
    <th>Delta</th>
  </tr> 
 <br>
  <tr>
    <td>%temp01%</td>
    <td>%temp02%</td>
    <td>%delta%</td>
    </tr>
</table>
<br>
<form action="/get" target="hidden-form">
<b>State  %state%</b>
<b>Mode %mode%  ( loop: AUTO -> FanSLOW -> FanFAST -> FanOFF )</b>
<br><input type="number " name="mode">
<input type="submit" value="Step to next" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
<b>TempFanSLOW (Now %TempFanSLOW% deg) (0 to force MAN): <input type="number " name="TempFanSLOW"></b>
<br>
<input type="radio" name="Def_TempFanSLOW" VALUE="setdef_TempFanSLOW" >Set default
<input type="radio" name="Def_TempFanSLOW" VALUE="setval_TempFanSLOW" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
<b>TempFanFAST (Now %TempFanFAST% deg): <input type="number " name="TempFanFAST"></b>
<br>
<input type="radio" name="Def_TempFanFAST" VALUE="setdef_TempFanFAST" >Set default
<input type="radio" name="Def_TempFanFAST" VALUE="setval_TempFanFAST" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
idelayMeasures (Current %idelayMeasures% sec): <input type="number " name="idelayMeasures">
<br>
<input type="radio" name="Def_idelayMeasures" VALUE="setdef_idelayMeasures" >Set default
<input type="radio" name="Def_idelayMeasures" VALUE="setval_idelayMeasures" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
idelayRelays (Current %idelayRelays% sec ): <input type="number " name="idelayRelays">
<br>
<input type="radio" name="Def_idelayRelays" VALUE="setdef_idelayRelays" >Set default
<input type="radio" name="Def_idelayRelays" VALUE="setval_idelayRelays" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
idelaySendData (Current  %idelaySendData% sec ): <input type="number " name="idelaySendData">
<br>
<input type="radio" name="Def_idelaySendData" VALUE="setdef_idelaySendData" >Set default
<input type="radio" name="Def_idelaySendData" VALUE="setval_idelaySendData" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
idelayRstDelta (Current %idelayRstDelta% sec ): <input type="number " name="idelayRstDelta">
<br>
<input type="radio" name="Def_idelayRstDelta" VALUE="setdef_idelayRstDelta" >Set default
<input type="radio" name="Def_idelayRstDelta" VALUE="setval_idelayRstDelta" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form>
<iframe style="display:none" name="hidden-form"></iframe>
</body></html>)rawliteral";
//______________________________________________________________________
bool  bFastON;  //set true if FastOn, lock to avoid useless switch
bool Op_StateAUTO= true;   // auto: true , man: false // 0 (nu), 1 FanSLOW, 2 FanFast, 3 FanOFF 
byte Op_Mode = 1 ; // 0 (nu), 1 FanSLOW, 2 FanFast, 3 FanOFF 
unsigned long  previousCPdelayMeasures=0  ; // to avoid millis rollover
unsigned long  previousCPdelayRelays=0  ; // to avoid millis rollover
unsigned long  previousCPdelaySendData=0  ; // to avoid millis rollover
unsigned long  previousCPdelayResetMaxDelta=0  ; // to avoid millis rollover
float TempDelta ;
float maxDelta = 0;
//______________________________________________________________________
//parameters  ..
//______________________________________________________________________
/*
             0 ...........|.................|................ delta temp
                          |                 |
Limits              TempFanSLOW       TempFanFAST
Fan:            OFF       |     SLOW        |      FAST
                          |                 |
*/
float TempFanSLOW_def = 7.11  ;                      //limit start delta fan normal (capacitor limited) speed
float TempFanFAST_def  =                 8.22;   //limit start fan fast
long int idelayMeasures_def      = 31000 ;   // def val 
long int idelayRelays_def        = 72000 ;   // relays cntrl  
long int idelaySendData_def      = 73000 ;   // send data  10 sec
long int idelayRstDelta_def      =300000 ;   // 5 mins   1800000 ; // 30 mins // reset max delta 
bool Op_StateAUTO_def= true;   // auto: true , man: false // 0 (nu), 1 FanSLOW, 2 FanFast, 3 FanOFF 
byte Op_Mode_def = 0 ;    // 0 (nu), 1 FanSLOW, 2 FanFast, 3 FanOFF 
float TempFanSLOW ;
float TempFanFAST ;
long int idelayMeasures ; 
long int idelayRelays   ;
long int idelaySendData  ;
long int idelayRstDelta;
//==========================
void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}
//==========================
//______________________________________________________________________
void LedBlink(int c=2, int ms=500){
	int i=0 , st;
	st= digitalRead(pinled);
	for (i; i<=c; i++)  {
		digitalWrite(pinled,LED_ON );   // turn the LED on
		delay(ms);
		digitalWrite(pinled, LED_OFF);    // turn the LED off
		delay(ms);        
		}
	digitalWrite(pinled, st);  
}
//______________________________________________________________________
void setup(void) {
	byte i ;
	Serial.begin(115200); // start serial port
	pinMode(pinled, OUTPUT);
	pinMode(button.pin, INPUT_PULLUP);
	delay(1000);
	Serial.println("");
	Serial.println(FileName);	
	
	#ifdef ESP32  // Initialize SPIFFS	
    if(!SPIFFS.begin(true)){
		Serial.println("An Error has occurred while mounting SPIFFS");
		return;
		}
	#else   //  ESP8266
	if(!SPIFFS.begin()){
		Serial.println("An Error has occurred while mounting SPIFFS");
		return;
		}
	#endif
	Serial.println(">>>InitWifiCx");	InitWifiCx();
	Serial.println(">>>InitParams");	InitParams();
	Serial.println(">>>MonParams"); 	MonParams();
	
	pinMode(RELAY_ON, OUTPUT); // set relays out pins
	pinMode(RELAY_FAST, OUTPUT);
	
	digitalWrite(RELAY_ON, DISABLED); // relay to off
	digitalWrite(RELAY_FAST, DISABLED);
	mySensors.begin();   // Start up the sensor library
	iCntDev=mySensors.getDeviceCount();
	// locate devices on the bus
	Serial.print(F("Locating devices...")); Serial.print(F("Found ")); Serial.print(iCntDev, DEC);	 Serial.println(" devices.");
	Serial.print(F("Set to maximum "));Serial.print(iMaxCntDev, DEC);  Serial.println(" devices ! (See iMaxCntDev)");
	Serial.print(F("ONE_WIRE_BUS bus on pin "));Serial.print(ONE_WIRE_BUS, DEC);  Serial.println("");
	Serial.print(F("Parasite power is: "));// report parasite power requirements
	if (mySensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF");
	for( i = 0 ; i < iCntDev; i++){  // print infos for each device
		if (!mySensors.getAddress(probes[i], i)) Serial.println("Unable to find address for Device "); 
		Serial.print(F("Device ")); Serial.print(i);
		Serial.print(F(", address: ")); printAddress(probes[i]); 
		// set the resolution to 12 bit per device
		mySensors.setResolution(probes[i], TEMPERATURE_PRECISION);
		Serial.print(F(", resolution: ")); int res = mySensors.getResolution(probes[i]); Serial.print(res, DEC); 
    Serial.println();
	}
	GetTemps();
	PrtDataToMon();
	DriveRelays();
	
	//  OTA _____________________________________________________________________
	// https://www.fais-le-toi-meme.fr/fr/electronique/tutoriel/esp8266-arduinoota-mise-a-jour-logiciel-esp8266-wifi
	// Port defaults to 8266
	// ArduinoOTA.setPort(8266);
	// Hostname defaults to esp8266-[ChipID]
	ArduinoOTA.setHostname(HostName);
	
	// No authentication by default
	// ArduinoOTA.setPassword("admin");
	// Password can be set with it's md5 value as well
	// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
	// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }
    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
	LedBlink(20,100);
    Serial.println(F("\nEnd"));
    
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  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");
    }
  });
  
  ArduinoOTA.begin();
  
//  OTA _____________________________________________________________________
	
	LedBlink(5);
	Serial.println(" ============ End setup()");
    } //end  setup(void)
//______________________________________________________________________
void loop(void){
	unsigned long CPdelayMeasures = millis();
	unsigned long CPdelayRelays = millis();
	unsigned long CPdelaySendData = millis();
	unsigned long CPdelayResetMaxDelta = millis();	
	ArduinoOTA.handle();
	//keysacn();
	if ((unsigned long)(CPdelayMeasures - previousCPdelayMeasures) >= idelayMeasures) {
	Serial.print(F("1.idelayMeasures ")); Serial.println(idelayMeasures/1000);
	GetTemps(); //get t and fill maxDelta, TempDelta
	PrtDataToMon();
	previousCPdelayMeasures=CPdelayMeasures;
	} 
	if ((unsigned long)(CPdelayRelays - previousCPdelayRelays) >= idelayRelays) {
	Serial.print(F("2.idelayRelays ")); Serial.println(idelayRelays/1000);
	DriveRelays(); 
	//SendData();
	previousCPdelayRelays=CPdelayRelays;
	} 
	if ((unsigned long)(CPdelaySendData - previousCPdelaySendData) >= idelaySendData) {
	Serial.print(F("3.idelaySendData ")); Serial.println(idelaySendData/1000);
	//SendData();
	//PrtDataToMon();
	previousCPdelaySendData=CPdelaySendData;
	} 
	if ((unsigned long)(CPdelayResetMaxDelta - previousCPdelayResetMaxDelta) >= idelayRstDelta) {
	Serial.print(F("4.idelayRstDelta ")); Serial.println(idelayRstDelta/1000);
	maxDelta = 0;
	previousCPdelayResetMaxDelta=CPdelayResetMaxDelta;
	}
	}
//______________________________________________________________________
void GetTemps(){ //get t and fill maxDelta, TempDelta
	//Serial.println(F("GetTemps"));
	mySensors.requestTemperatures();
	for(byte i = 0 ; i < iCntDev; i++){  //The loop that goes through the sensors
		float fMes ;
		//Serial.print(F("Device ")); Serial.print(i);
		//Serial.print(F(", ")); printAddress(probes[i]); 
		//Serial.print(F(": "));
		probeTemp[i] = printTemperature(probes[i]) ;
		//Serial.print(fMes);
		//Serial.println(" C ");
		} //for loop
	
	if (probeTemp[0]>probeTemp[1]) {TempDelta=(probeTemp[0]-probeTemp[1]);}else{TempDelta=(probeTemp[1]-probeTemp[0]); }
	if (TempDelta>maxDelta ){ maxDelta=TempDelta;}
}
//______________________________________________________________________
void DriveRelays(){ //drive relays
// replace call proc by mode and state ?
if (TempFanSLOW ==0) {  //force manual, probably no sensors
	Op_StateAUTO=false;
	}
		if (Op_StateAUTO) { 
			//  AUTO
			//if (Op_StateAUTO) { Serial.print(F(" MAN"));   else  {  Serial.print(F(" AUTO"));  }
			digitalWrite(pinled,LED_OFF);  
			if (TempDelta > TempFanFAST){FanFAST();	Op_Mode=2;	}
			else if (TempDelta > TempFanSLOW){ FanSLOW();Op_Mode=1;		}       
			else if (TempDelta <= TempFanSLOW){FanOFF(); Op_Mode=3;		}
		}
		else {  // MAN
			digitalWrite(pinled,LED_ON);  
			LedBlink(15,100);
			switch(Op_Mode) {// Op_StateAUTO  0 ignore  1 FanSLOW, 2 FanFast 3 FanOFF
				case 0 : FanSLOW();break;  //for man loop
				case 1 : FanSLOW();break;
				case 2 : FanFAST();break;
				case 3 : FanOFF(); break;
				}
			
			}	
}  // DriveRelays
//______________________________________________________________________
void SendData(){ //send data via index.php
float fMes0,fMes1;
String Link, getData  ;
WiFiClient client;
HTTPClient http;    //Declare object of class HTTPClient
// build a HTTP request
if (WiFi.status() == WL_CONNECTED) {  
	fMes0=probeTemp[0] ;
	fMes1=probeTemp[1] ;
	// String GETdata="GET /esp8266/index.php/?t0=" + String(fMes0)
	GETdata="?t0=" + String(fMes0)  
	+ "&t1="+ fMes1  
	+ "&TD="+  String(TempDelta) 
	+ "&mTD="+ String(maxDelta) 
	+ "&Md="+  String(Op_Mode )
	//+ "&St="+  sState
	+ "&St="+  	String(Op_StateAUTO)
	+ "&ti="+  millis();
	+ " HTTP/1.1";
	//echo to sermon
	Link = "http://192.168.0.11/esp8266/index.php" + GETdata;
	Serial.print(F("===> GETdata: "));	Serial.println(Link);
	http.begin(client,Link);     //Specify request destination
	int httpCode = http.GET();            //Send the request
	Serial.println("=response");	
	String payload = http.getString();    //Get the response payload
	Serial.println(httpCode);   //Print HTTP return code
	Serial.println(payload);    //Print request response payload
	Serial.println("=end response");
	http.end();  //Close connection
	}
else {
	Serial.println("WiFiStatus != WL_CONNECTED");
	}
}
//______________________________________________________________________
void PrtDataToMon(){
	//  (Limits: ON >5.10, FAST >6.30) Delta: 7.12 (max: 7.19), State AUTO, Mode 2 FAST	
	//  Device 0, 2888DA7997040306: 24.44 C 
	//  Device 1, 286E6D4692020290: 17.31 C 
	
	Serial.print(F("PrtDataToMon > (Limits: ON >"));Serial.print(TempFanSLOW);Serial.print(F(", FAST >"));	Serial.print(TempFanFAST);Serial.print(")");
	Serial.print(F(" Delta: "));Serial.print(TempDelta);Serial.print(F(" (max: "));Serial.print(maxDelta);Serial.print(F(")"));
	Serial.print(F(", ")); if (Op_StateAUTO) {Serial.print(F("AUTO"));}  else  {Serial.print(F("MAN"));}
	
	Serial.print(F(", Mode ")) ; Serial.print(Op_Mode);
	switch (Op_Mode) {  //Op_Mode: 0 Auto, 1 FanSLOW, 2 FanFast, 3 FanOFF 
		case 0: Serial.println(F(" -nu-")); break;
		case 1: Serial.println(F(" SLOW")); break;
		case 2: Serial.println(F(" FAST")); break;
		case 3: Serial.println(F(" OFF")); break;
		}
	for(byte i = 0 ; i < iCntDev; i++){ 
			Serial.print(F("Device ")); Serial.print(i);
			Serial.print(F(", ")); printAddress(probes[i]); 
			Serial.print(F(": "));
			Serial.print(probeTemp[i])  ;
			Serial.println(" C ");
			}
	Serial.println("PrtDataToMon <");
	}
//______________________________________________________________________
void printAddress(DeviceAddress deviceAddress) {
// function to print a device address
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print(F("0"));
    Serial.print(deviceAddress[i], HEX);
  }
    }
//______________________________________________________________________
float printTemperature(DeviceAddress deviceAddress) {
// function to print the temperature for a device
  float tempC = mySensors.getTempC(deviceAddress);
  //Serial.print(tempC);
  //Serial.println(" C ");
return tempC;
  //Serial.print(" Temp F: ");
  //Serial.print(DallasTemperature::toFahrenheit(tempC));
    }
//______________________________________________________________________
void printResolution(DeviceAddress deviceAddress) {
// function to print a device's resolution
  Serial.print("Resolution: ");
  Serial.print(mySensors.getResolution(deviceAddress));
  Serial.println();
    }
//______________________________________________________________________
void printData(DeviceAddress deviceAddress) {
// main function to print information about a device
  //Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(F(" "));
  printTemperature(deviceAddress);
  Serial.println();
    }
//______________________________________________________________________
void keysacn(){
	//https://www.baldengineer.com/detect-short-long-button-press.html
    // check the button
    button.currentState = digitalRead(button.pin);
    // has it changed?
    if (button.currentState != button.prevState) {
        delay(button.debounce);
        //Serial.println(F("   After debounce"));
        // update status in case of bounce
        button.currentState = digitalRead(button.pin);
        if (button.currentState == PRESSED) {
            // a new press event occured
            // record when button went down
            //Serial.println(F("   pressed"));
            button.counter = millis();
        }
        if (button.currentState == NOT_PRESSED) {
			//Serial.println(F("   no longer pressed"));
            // but no longer pressed, how long was it down?
            unsigned long currentMillis = millis();
            if ((currentMillis - button.counter >= shortPress) && !(currentMillis - button.counter >= longPress)) {
                // short press detected. 
                handleShortPress();
            }
            if ((currentMillis - button.counter >= longPress)) {
                // the long press was detected
                handleLongPress();
            }
        }
        // used to detect when state changes
        button.prevState = button.currentState;
    }
    }
//______________________________________________________________________
void handleShortPress() {
	 // auto: false , man: true // 0 (nu), 1 FanSLOW, 2 FanFAST, 3 FanOFF
	Serial.print(F(" >>> ShortPress entry "));
	Serial.print(Op_StateAUTO);Serial.print(F(" "));
	Serial.println(Op_Mode);   
	Op_Mode=Op_Mode+1;
	if (Op_Mode<=3) {
		if (Op_StateAUTO) {
			Op_StateAUTO = false ;
			Op_Mode=1;
			}
		else {
			Op_StateAUTO = false ;
			}
		}
	
	if (Op_Mode==4) {      // set AUTO
		Op_StateAUTO = true ; 
		Op_Mode = 0;       
		//MonParams();
        }
	//PrtDataToMon();
	DriveRelays();
	}
//______________________________________________________________________
void handleLongPress() {   //set to auto, slow
	handleShortPress();
	/*
	Serial.println(F("   >>> Long Press"));
	Op_StateAUTO=true ; 
	Op_Mode = 1;
	PrtDataToMon();
	SendData();
	DriveRelays();
	* */
    }
//______________________________________________________________________
void FanSLOW()  {// relay is activated when DO is DISABLED  LOW !
// fan low speed
	//Serial.println("FanSLOW");
	bFastON=false;
	//Op_Mode =1 ;  // when in auto: 0 ignore  1 FanSLOW, 2 FanFast   3 FanOFF
	digitalWrite(RELAY_ON, ENABLE);
	digitalWrite(RELAY_FAST, DISABLED);
    }
//______________________________________________________________________
void FanFAST(){// relay is activated when DO is DISABLED !
// fan high speed
	//Serial.println("FanFAST");
	if (!bFastON) {
		bFastON=true;
		//Op_Mode =2 ;  // when in auto: 0 ignore  1 FanSLOW, 2 FanFast   3 FanOFF
		digitalWrite(RELAY_ON, DISABLED);//cut power
		delay(2000);//wait for discharge of limiting condo
		digitalWrite(RELAY_FAST, ENABLE);//bypass limiting condo
		digitalWrite(RELAY_ON, ENABLE);//power
		}
    }
//______________________________________________________________________
void FanOFF() {// relay is activated when DO is DISABLED !
//fan off
	//Serial.println("FanOFF");
	bFastON=false;
	//Op_Mode =3  ;  // when in auto: 0 ignore  1 FanSLOW, 2 FanFast   3 FanOFF
	digitalWrite(RELAY_ON, DISABLED);
	delay(2000); //wait for discharge of limiting condo // TODO  use millis  !
	digitalWrite(RELAY_FAST, DISABLED);	
    }
//______________________________________________________________________
void printWifiStatus(){
	// print the SSID of the network you're attached to
	Serial.print(F("Connected to WiFi SSID: "));
	Serial.print(WiFi.SSID());
	Serial.print(F(", ip: "));  
	Serial.print(WiFi.localIP());   
	Serial.print(F(" MAC: "));  
	Serial.println(WiFi.macAddress());
	long rssi = WiFi.RSSI();
	Serial.print(F(", signal (RSSI): "));
	Serial.print(rssi); Serial.print(F(" dBm"));
	}
//______________________________________________________________________
void InitWifiCx(){
	WiFi.mode(WIFI_OFF);        //Prevents reconnection issue (taking too long to connect)
	delay(1000);
	WiFi.mode(WIFI_STA);        //This line hides the viewing of ESP as wifi hotspot
	
	WiFi.begin(ssid, password);
	Serial.println("");
	// if (WiFi.waitForConnectResult() != WL_CONNECTED) {
	int i=0;
	while(WiFi.status() != WL_CONNECTED) {
		delay(500);
		Serial.print(i++);
		}
	// you're connected now, so print out the data
	Serial.println("");
	printWifiStatus();
	Serial.println();
	//  set server to response
	//code based on 
	// https://techtutorialsx.com/2017/12/01/esp32-arduino-asynchronous-http-webserver/	
	// https://github.com/me-no-dev/ESPAsyncWebServer/blob/master/src/StringArray.h
	//
	// Send web page with input fields to client  start server 
	server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
		GetTemps();
		request->send_P(200, "text/html", index_html, processor);
		});
	
	// Send a GET request to <ESP_IP>/get?inputString=<inputMessage>
	//  https://www.w3schools.com/get?TempFanSLOW=&Def_TempFanSLOW=_TempFanSLOW
	server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
	    String inputMessage;
	    // GET inputInt value on <ESP_IP>/get?inputInt=<inputMessage>
	    // GET TempFanSLOW value on <ESP_IP>/get?TempFanSLOW=<inputMessage>
	    // http://192.168.0.22/get?idelayMeasures=70000
	    if (request->hasParam(PARAM_idelayMeasures)) {
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_idelayMeasures" ) { // search for &Def_idelayMeasures=
					if (p->value()=="setdef_idelayMeasures") {  // if set, use def value, ignore other option: handled by else part
						FileWrite(SPIFFS, "/idelayMeasures.txt", (String(idelayMeasures_def)).c_str()  ) ;
						idelayMeasures=idelayMeasures_def;		
						}
					else {
						inputMessage=atoi((request->getParam(0)->value()).c_str()) * 1000;
						//Serial.print("inputMessage =");Serial.print(inputMessage);Serial.println("<");
						if (inputMessage.toInt() > 0) {
							FileWrite(SPIFFS, "/idelayMeasures.txt", inputMessage.c_str());
							idelayMeasures=atol(inputMessage.c_str() );
							}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)			
		    }
		else if (request->hasParam(PARAM_idelayRelays)) {
			/*
			inputMessage = request->getParam(PARAM_idelayRelays)->value();
			inputMessage=(inputMessage.toInt())*1000;
			FileWrite(SPIFFS, "/idelayRelays.txt", inputMessage.c_str());
			idelayRelays = atol(inputMessage.c_str());
			*/
			
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_idelayRelays" ) {
					if (p->value()=="setdef_idelayRelays") {
						FileWrite(SPIFFS, "/idelayRelays.txt", (String(idelayRelays_def)).c_str()  ) ;
						idelayRelays=idelayRelays_def;		
						}
					else {
						//inputMessage=(request->getParam(0)->value()) *1000 ;
						inputMessage=request->getParam(0)->value()   ;
						inputMessage=(atoi(inputMessage.c_str())) * 1000;	
		
						if (inputMessage.toInt() > 0) {
							FileWrite(SPIFFS, "/idelayRelays.txt", inputMessage.c_str());
							idelayRelays=(float)atof( inputMessage.c_str()  );
							}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)		
			
			
			}
		else if (request->hasParam(PARAM_idelaySendData)) {
			/*
			inputMessage = request->getParam(PARAM_idelaySendData)->value();
			inputMessage=(inputMessage.toInt())*1000;
			FileWrite(SPIFFS, "/idelaySendData.txt", inputMessage.c_str());
			idelaySendData = atol(inputMessage.c_str());
			*/
			
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_idelaySendData" ) {
					if (p->value()=="setdef_idelaySendData") {
						FileWrite(SPIFFS, "/idelaySendData.txt", (String(idelaySendData_def)).c_str()  ) ;
						idelaySendData=idelaySendData_def;		
						}
					else {
						//inputMessage=(request->getParam(0)->value()) *1000 ;
						inputMessage=request->getParam(0)->value()   ;
						inputMessage=(atoi(inputMessage.c_str())) * 1000;						
						if (inputMessage.toInt() > 0) {
						FileWrite(SPIFFS, "/idelaySendData.txt", inputMessage.c_str());
						idelaySendData=(float)atof( inputMessage.c_str()  );
						}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)					
		
			
			}
		else if (request->hasParam(PARAM_idelayRstDelta)) {
			/*
			inputMessage = request->getParam(PARAM_idelayRstDelta)->value();
			inputMessage=(inputMessage.toInt())*1000;
			FileWrite(SPIFFS, "/idelayRstDelta.txt", inputMessage.c_str());
			idelayRstDelta= atol(inputMessage.c_str());
			*/
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_idelayRstDelta" ) {
					if (p->value()=="setdef_idelayRstDelta") {
						FileWrite(SPIFFS, "/idelayRstDelta.txt", (String(idelayRstDelta_def)).c_str()  ) ;
						idelayRstDelta=idelayRstDelta_def;		
						}
					else {
						//inputMessage=(request->getParam(0)->value()) *1000 ;
						inputMessage=request->getParam(0)->value()   ;
						inputMessage=(atoi(inputMessage.c_str())) * 1000;						
						if (inputMessage.toInt() > 0) {
						FileWrite(SPIFFS, "/idelayRstDelta.txt", inputMessage.c_str());
						idelayRstDelta=(float)atof( inputMessage.c_str()  );
						}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)					
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			}
	    else if (request->hasParam(PARAM_TempFanSLOW)) {  // has received TempFanSLOW=12.34 &Def_TempFanSLOW=setval_TempFanSLOW
			/*
			https://www.w3schools.com/get?TempFanSLOW=00&Def_TempFanSLOW=setdef_TempFanSLOW	
			<input type="radio" 
			name="Def_TempFanSLOW" VALUE="setdef_TempFanSLOW">Set def
			<input type="radio"  
			name="Def_TempFanSLOW" VALUE="setval_TempFanSLOW" checked>Set val
			
			//  https://forum.arduino.cc/index.php?topic=590802.0
			int paramsNr = request->params();
			Serial.println(paramsNr);
			int paramsNr = request->params();
			for(int i=0;i<paramsNr;i++){
			
			AsyncWebParameter* p = request->getParam(i);
			Serial.print("Param name: ");
			Serial.println(p->name());
			Serial.print("Param value: ");
			Serial.println(p->value());
			Serial.println("------");
			}
			*/
			/*
			TempFanSLOW=12.34 &Def_TempFanSLOW=setval_TempFanSLOW
			TempFanSLOW=78.91 &Def_TempFanSLOW=setdef_TempFanSLOW
			*/
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        /*
		        Serial.print("Param name: ");  Serial.println(p->name());
		        Serial.print("Param value: ");  Serial.println(p->value());
		        Serial.println("------");
		        */
		        if (p->name()=="Def_TempFanSLOW" ) {
					if (p->value()=="setdef_TempFanSLOW") {
						FileWrite(SPIFFS, "/TempFanSLOW.txt", (String(TempFanSLOW_def)).c_str()  ) ;
						TempFanSLOW=TempFanSLOW_def;		
						}
					else {
						inputMessage=request->getParam(0)->value();
						if (inputMessage!=0) {
						//inputMessage = request->getParam(PARAM_TempFanSLOW)->value();
						FileWrite(SPIFFS, "/TempFanSLOW.txt", inputMessage.c_str());
						TempFanSLOW=(float)atof( inputMessage.c_str()  );
						}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)
			}
		else if (request->hasParam(PARAM_TempFanFAST)) {
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_TempFanFAST" ) {
					if (p->value()=="setdef_TempFanFAST") {
						FileWrite(SPIFFS, "/TempFanFAST.txt", (String(TempFanFAST_def)).c_str()  ) ;
						TempFanFAST=TempFanFAST_def;		
						}
					else {
						inputMessage=request->getParam(0)->value();
						if (inputMessage!=0) {
						FileWrite(SPIFFS, "/TempFanFAST.txt", inputMessage.c_str());
						TempFanFAST=(float)atof( inputMessage.c_str()  );
						}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)
			}
		else if (request->hasParam(PARAM_mode)) {
			handleShortPress();
			//inputMessage = request->getParam(PARAM_mode)->value();
			//inputMessage = String(Op_Mode);
			//FileWrite(SPIFFS, "/mode.txt", inputMessage.c_str());
			//Op_Mode=atol( inputMessage.c_str()  );
			}
				
			
			
		else    { inputMessage = "No message sent";
			}
	    Serial.println(inputMessage);
	    request->send(200, "text/text", inputMessage);
		}
	);  // server.on(
	server.onNotFound(notFound);
	server.begin();	
 }
//______________________________________________________________________
String FileRead(fs::FS &fs, const char * path){
  //Serial.printf("FileRead(): Reading file: %s\r\n", path);
  //Serial.printf("FileRead(): Reading file: %s ", path);
  File file = fs.open(path, "r");
  if(!file || file.isDirectory()){
    //Serial.println("- empty file or failed to open file");
    return String();
  }
  //Serial.print("- read from file:");
  String fileContent;
  while(file.available()){
    fileContent+=String((char)file.read());
  }
  //Serial.println(fileContent);
  return fileContent;
}
//______________________________________________________________________
void FileWrite(fs::FS &fs, const char * path, const char * message){
  Serial.printf("Writing file: %s", path);
  File file = fs.open(path, "w");
  if(!file){
    Serial.print(F("- failed to open file for writing"));
    return;
  }
  if(file.print(message)){
    Serial.print(F("- file written"));
  } else {
    Serial.print(F("- write failed"));
  }
  Serial.println(F(""));
}
//______________________________________________________________________
String processor(const String& var){   // Replaces placeholder with stored values
  //pass param 'id' return value or null (?)
  //Serial.println("==processor");
  //Serial.println(var);
//GetTemps();   //  THIS CRASH WITH WDT   !  too much calls   :)
// / TIMINGS
  if(var == "idelayMeasures"){
    //return FileRead(SPIFFS, "/idelayMeasures.txt");
    return String(idelayMeasures/1000);  }
  else  if(var == "idelayRelays"){
    //return FileRead(SPIFFS, "/idelayRelays.txt");
    return String(idelayRelays/1000);  }
  else  if(var == "idelaySendData"){
    //return FileRead(SPIFFS, "/idelaySendData.txt");
    return String(idelaySendData/1000);  }  
...
This file has been truncated, please download it to see its full contents.
/*
//
//  version nodemcu 2020 01 12
//  https://randomnerdtutorials.com/esp8266-ds18b20-temperature-sensor-web-server-with-arduino-ide/
//
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! my nodeMCU use  ESP8266
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* 
// https://www.vultr.com/docs/using-screen-on-ubuntu-14-04
ctrl-A \  
screen /dev/ttyUSB0 115200
 ADDED  <pgmspace.h>
 * /home/luc/arduino-1.8.9/hardware/tools/avr/avr/include/avr/pgmspace.h
 * /home/luc/Dropbox/arduino_ino/libraries/OneWire/OneWire.h
 *
 * warning: 'bool HTTPClient::begin(String)' is deprecated 
(declared at 
/home/luc/.arduino15/packages/esp8266/hardware/esp8266/2.6.3/libraries/
ESP8266HTTPClient/src/ESP8266HTTPClient.h:155) [-Wdeprecated-declarations]
* 
* https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#enable-wi-fi-diagnostic
https://makeradvisor.com/esp32-vs-esp8266/
* Rcuprer automatiquement des redmarrages en boucle du ESP8266
* https://www.sigmdel.ca/michel/program/esp8266/arduino/watchdogs2_fr.html
* 
*/
//______________________________________________________________________
const char FileName[]="=== V 001.78 DifferentialTemp_nodeMCU03-SRV-OTA.ino";
const char HostName[]="VertCirc";
//______________________________________________________________________
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//#include <ESP8266WiFi.h> 
// <ESP8266WiFi.h>  // official arduino  //https://randomnerdtutorials.com/esp32-esp8266-input-data-html-form/#more-88796
// <ESP8266wifi.h>  // is  Jonas Ekstrand.
#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
  #include <SPIFFS.h>
#else  //my nodemcu with ESP8266
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
  #include <Hash.h>
  #include <FS.h>
#endif
#include <ESPAsyncWebServer.h>    // my nodemcu with ESP8266
//https://techtutorialsx.com/2017/12/01/esp32-arduino-asynchronous-http-webserver/
#include <ESP8266HTTPClient.h>
//  OTA   
// https://projetsdiy.fr/arduinoota-ota-mise-jour-sans-fil-ide-arduino-programmes-esp8266/
//debug by ota:
// https://www.fais-le-toi-meme.fr/fr/electronique/tutoriel/esp8266-arduinoota-mise-a-jour-logiciel-esp8266-wifi
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
//
///////////////////////////////////////////////////////////
//set relay output wire
#define RELAY_ON   D5 // 14  // D5 GPIO14  relayboard in1
#define RELAY_FAST D6 // 12  // D6 GPIO12  relayboard in2
#define ENABLE LOW      //relay is reverse logic: active on low 
#define DISABLED HIGH 
///////////////////////////////////////////////////////////
// led
#define LED_ON     0
#define LED_OFF    1
//status led : ON if auto mode
#define pinled LED_BUILTIN  // D0 ;  //  GPIO16 ;
///////////////////////////////////////////////////////////
// button
// https://www.baldengineer.com/detect-short-long-button-press.html
#define PRESSED     LOW
#define NOT_PRESSED HIGH
const unsigned long shortPress = 50;
const unsigned long longPress = 500;
typedef struct Buttons {
    const byte pin = D1 ;  // D1 =GPIO5
    const int debounce = 20;
    unsigned long counter=0;
    bool prevState = NOT_PRESSED;
    bool currentState;
} Button;
Button button;
//  
// https://randomnerdtutorials.com/esp32-esp8266-input-data-html-form/#more-88796
//
#if defined(ESP8266)   // my NodeMCU  use this
	//ESP8266WebServer server(80);
	AsyncWebServer server(80);
#endif
#if defined(ESP32)
	WebServer server(80);
#endif
///////////////////////////////////////////////////////////
// temperature sensors
#define TEMPERATURE_PRECISION 12 //9..12
#define ONE_WIRE_BUS 4  // D2 = GPIO4  Data wire ONE_WIRE_BUS 
// arrays to hold device addresses
#define iMaxCntDev 2   //max devs expected. limit mem used  real count will be in 
byte iCntDev  ;                    //physical dev count
DeviceAddress probes[iMaxCntDev];  // table holding dev adress
float probeTemp[iMaxCntDev];       // table holding measures
OneWire myOneWireDev(ONE_WIRE_BUS);// Setup a myOneWireDev instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature mySensors(&myOneWireDev);// Pass our myOneWireDev reference to Dallas Temperature.
///////////////////////////////////////////////////////////
// wifi
char ssid[] = "BRG-FLOOR0-2G";  // your network SSID (name) "BRG-FLOOR0-2G" "BRG-FLOOR0-TPLINK"
char password[] = "0499185306";       // your network password
const char* PARAM_idelayMeasures = "idelayMeasures";
const char* PARAM_idelayRelays = "idelayRelays";
const char* PARAM_idelaySendData = "idelaySendData";
const char* PARAM_idelayRstDelta	 = "idelayRstDelta";
const char* PARAM_TempFanSLOW = "TempFanSLOW";
const char* PARAM_TempFanFAST = "TempFanFAST";
const char* PARAM_mode = "mode";
const char* PARAM_state = "state";
String  GETdata ;  //will contains line send to server
/*
 * 
 *     function submitMessage() {
      alert("Saved value to ESP SPIFFS");
      setTimeout(function(){ document.location.reload(false); }, 500);   
 * */
// https://www.w3schools.com/html/tryit.asp
//  definition of the html page site
//  https://www.w3schools.com/code/tryit.asp?filename=GDSIWKZTNCZ2
// <input type="submit" method="POST" VALUE=">> Rechercher <<">
// <input type="submit" value="" onclick="submitMessage()">
//  https://www.w3schools.com/get?  TempFanSLOW= &Def_TempFanSLOW=_TempFanSLOW
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>Vertical Circulator Parameters</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<META HTTP-EQUIV="Refresh" CONTENT="60">
<script>function submitMessage(){setTimeout(function(){ document.location.reload(false); }, 500);}</script>
<style>table, th, td {border: 1px solid black;border-collapse: collapse;} </style>
</head><body>
%FileName%
<table>
  <tr>
    <th>Temp up</th>
    <th>Temp down</th>
    <th>Delta</th>
  </tr> 
 <br>
  <tr>
    <td>%temp01%</td>
    <td>%temp02%</td>
    <td>%delta%</td>
    </tr>
</table>
<br>
<form action="/get" target="hidden-form">
<b>State  %state%</b>
<b>Mode %mode%  ( loop: AUTO -> FanSLOW -> FanFAST -> FanOFF )</b>
<br><input type="number " name="mode">
<input type="submit" value="Step to next" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
<b>TempFanSLOW (Now %TempFanSLOW% deg) (0 to force MAN): <input type="number " name="TempFanSLOW"></b>
<br>
<input type="radio" name="Def_TempFanSLOW" VALUE="setdef_TempFanSLOW" >Set default
<input type="radio" name="Def_TempFanSLOW" VALUE="setval_TempFanSLOW" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
<b>TempFanFAST (Now %TempFanFAST% deg): <input type="number " name="TempFanFAST"></b>
<br>
<input type="radio" name="Def_TempFanFAST" VALUE="setdef_TempFanFAST" >Set default
<input type="radio" name="Def_TempFanFAST" VALUE="setval_TempFanFAST" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
idelayMeasures (Current %idelayMeasures% sec): <input type="number " name="idelayMeasures">
<br>
<input type="radio" name="Def_idelayMeasures" VALUE="setdef_idelayMeasures" >Set default
<input type="radio" name="Def_idelayMeasures" VALUE="setval_idelayMeasures" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
idelayRelays (Current %idelayRelays% sec ): <input type="number " name="idelayRelays">
<br>
<input type="radio" name="Def_idelayRelays" VALUE="setdef_idelayRelays" >Set default
<input type="radio" name="Def_idelayRelays" VALUE="setval_idelayRelays" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
idelaySendData (Current  %idelaySendData% sec ): <input type="number " name="idelaySendData">
<br>
<input type="radio" name="Def_idelaySendData" VALUE="setdef_idelaySendData" >Set default
<input type="radio" name="Def_idelaySendData" VALUE="setval_idelaySendData" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
idelayRstDelta (Current %idelayRstDelta% sec ): <input type="number " name="idelayRstDelta">
<br>
<input type="radio" name="Def_idelayRstDelta" VALUE="setdef_idelayRstDelta" >Set default
<input type="radio" name="Def_idelayRstDelta" VALUE="setval_idelayRstDelta" checked >Set value
<input type="submit" value="Submit" onclick="submitMessage()">
</form>
<iframe style="display:none" name="hidden-form"></iframe>
</body></html>)rawliteral";
//______________________________________________________________________
bool  bFastON;  //set true if FastOn, lock to avoid useless switch
bool Op_StateAUTO= true;   // auto: true , man: false // 0 (nu), 1 FanSLOW, 2 FanFast, 3 FanOFF 
byte Op_Mode = 1 ; // 0 (nu), 1 FanSLOW, 2 FanFast, 3 FanOFF 
unsigned long  previousCPdelayMeasures=0  ; // to avoid millis rollover
unsigned long  previousCPdelayRelays=0  ; // to avoid millis rollover
unsigned long  previousCPdelaySendData=0  ; // to avoid millis rollover
unsigned long  previousCPdelayResetMaxDelta=0  ; // to avoid millis rollover
float TempDelta ;
float maxDelta = 0;
//______________________________________________________________________
//parameters  ..
//______________________________________________________________________
/*
             0 ...........|.................|................ delta temp
                          |                 |
Limits              TempFanSLOW       TempFanFAST
Fan:            OFF       |     SLOW        |      FAST
                          |                 |
*/
float TempFanSLOW_def = 7.11  ;                      //limit start delta fan normal (capacitor limited) speed
float TempFanFAST_def  =                 8.22;   //limit start fan fast
long int idelayMeasures_def      = 31000 ;   // def val 
long int idelayRelays_def        = 72000 ;   // relays cntrl  
long int idelaySendData_def      = 73000 ;   // send data  10 sec
long int idelayRstDelta_def      =300000 ;   // 5 mins   1800000 ; // 30 mins // reset max delta 
bool Op_StateAUTO_def= true;   // auto: true , man: false // 0 (nu), 1 FanSLOW, 2 FanFast, 3 FanOFF 
byte Op_Mode_def = 0 ;    // 0 (nu), 1 FanSLOW, 2 FanFast, 3 FanOFF 
float TempFanSLOW ;
float TempFanFAST ;
long int idelayMeasures ; 
long int idelayRelays   ;
long int idelaySendData  ;
long int idelayRstDelta;
//==========================
void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}
//==========================
//______________________________________________________________________
void LedBlink(int c=2, int ms=500){
	int i=0 , st;
	st= digitalRead(pinled);
	for (i; i<=c; i++)  {
		digitalWrite(pinled,LED_ON );   // turn the LED on
		delay(ms);
		digitalWrite(pinled, LED_OFF);    // turn the LED off
		delay(ms);        
		}
	digitalWrite(pinled, st);  
}
//______________________________________________________________________
void setup(void) {
	byte i ;
	Serial.begin(115200); // start serial port
	pinMode(pinled, OUTPUT);
	pinMode(button.pin, INPUT_PULLUP);
	delay(1000);
	Serial.println("");
	Serial.println(FileName);	
	
	#ifdef ESP32  // Initialize SPIFFS	
    if(!SPIFFS.begin(true)){
		Serial.println("An Error has occurred while mounting SPIFFS");
		return;
		}
	#else   //  ESP8266
	if(!SPIFFS.begin()){
		Serial.println("An Error has occurred while mounting SPIFFS");
		return;
		}
	#endif
	Serial.println(">>>InitWifiCx");	InitWifiCx();
	Serial.println(">>>InitParams");	InitParams();
	Serial.println(">>>MonParams"); 	MonParams();
	
	pinMode(RELAY_ON, OUTPUT); // set relays out pins
	pinMode(RELAY_FAST, OUTPUT);
	
	digitalWrite(RELAY_ON, DISABLED); // relay to off
	digitalWrite(RELAY_FAST, DISABLED);
	mySensors.begin();   // Start up the sensor library
	iCntDev=mySensors.getDeviceCount();
	// locate devices on the bus
	Serial.print(F("Locating devices...")); Serial.print(F("Found ")); Serial.print(iCntDev, DEC);	 Serial.println(" devices.");
	Serial.print(F("Set to maximum "));Serial.print(iMaxCntDev, DEC);  Serial.println(" devices ! (See iMaxCntDev)");
	Serial.print(F("ONE_WIRE_BUS bus on pin "));Serial.print(ONE_WIRE_BUS, DEC);  Serial.println("");
	Serial.print(F("Parasite power is: "));// report parasite power requirements
	if (mySensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF");
	for( i = 0 ; i < iCntDev; i++){  // print infos for each device
		if (!mySensors.getAddress(probes[i], i)) Serial.println("Unable to find address for Device "); 
		Serial.print(F("Device ")); Serial.print(i);
		Serial.print(F(", address: ")); printAddress(probes[i]); 
		// set the resolution to 12 bit per device
		mySensors.setResolution(probes[i], TEMPERATURE_PRECISION);
		Serial.print(F(", resolution: ")); int res = mySensors.getResolution(probes[i]); Serial.print(res, DEC); 
    Serial.println();
	}
	GetTemps();
	PrtDataToMon();
	DriveRelays();
	
	//  OTA _____________________________________________________________________
	// https://www.fais-le-toi-meme.fr/fr/electronique/tutoriel/esp8266-arduinoota-mise-a-jour-logiciel-esp8266-wifi
	// Port defaults to 8266
	// ArduinoOTA.setPort(8266);
	// Hostname defaults to esp8266-[ChipID]
	ArduinoOTA.setHostname(HostName);
	
	// No authentication by default
	// ArduinoOTA.setPassword("admin");
	// Password can be set with it's md5 value as well
	// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
	// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }
    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
	LedBlink(20,100);
    Serial.println(F("\nEnd"));
    
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  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");
    }
  });
  
  ArduinoOTA.begin();
  
//  OTA _____________________________________________________________________
	
	LedBlink(5);
	Serial.println(" ============ End setup()");
    } //end  setup(void)
//______________________________________________________________________
void loop(void){
	unsigned long CPdelayMeasures = millis();
	unsigned long CPdelayRelays = millis();
	unsigned long CPdelaySendData = millis();
	unsigned long CPdelayResetMaxDelta = millis();	
	ArduinoOTA.handle();
	//keysacn();
	if ((unsigned long)(CPdelayMeasures - previousCPdelayMeasures) >= idelayMeasures) {
	Serial.print(F("1.idelayMeasures ")); Serial.println(idelayMeasures/1000);
	GetTemps(); //get t and fill maxDelta, TempDelta
	PrtDataToMon();
	previousCPdelayMeasures=CPdelayMeasures;
	} 
	if ((unsigned long)(CPdelayRelays - previousCPdelayRelays) >= idelayRelays) {
	Serial.print(F("2.idelayRelays ")); Serial.println(idelayRelays/1000);
	DriveRelays(); 
	//SendData();
	previousCPdelayRelays=CPdelayRelays;
	} 
	if ((unsigned long)(CPdelaySendData - previousCPdelaySendData) >= idelaySendData) {
	Serial.print(F("3.idelaySendData ")); Serial.println(idelaySendData/1000);
	//SendData();
	//PrtDataToMon();
	previousCPdelaySendData=CPdelaySendData;
	} 
	if ((unsigned long)(CPdelayResetMaxDelta - previousCPdelayResetMaxDelta) >= idelayRstDelta) {
	Serial.print(F("4.idelayRstDelta ")); Serial.println(idelayRstDelta/1000);
	maxDelta = 0;
	previousCPdelayResetMaxDelta=CPdelayResetMaxDelta;
	}
	}
//______________________________________________________________________
void GetTemps(){ //get t and fill maxDelta, TempDelta
	//Serial.println(F("GetTemps"));
	mySensors.requestTemperatures();
	for(byte i = 0 ; i < iCntDev; i++){  //The loop that goes through the sensors
		float fMes ;
		//Serial.print(F("Device ")); Serial.print(i);
		//Serial.print(F(", ")); printAddress(probes[i]); 
		//Serial.print(F(": "));
		probeTemp[i] = printTemperature(probes[i]) ;
		//Serial.print(fMes);
		//Serial.println(" C ");
		} //for loop
	
	if (probeTemp[0]>probeTemp[1]) {TempDelta=(probeTemp[0]-probeTemp[1]);}else{TempDelta=(probeTemp[1]-probeTemp[0]); }
	if (TempDelta>maxDelta ){ maxDelta=TempDelta;}
}
//______________________________________________________________________
void DriveRelays(){ //drive relays
// replace call proc by mode and state ?
if (TempFanSLOW ==0) {  //force manual, probably no sensors
	Op_StateAUTO=false;
	}
		if (Op_StateAUTO) { 
			//  AUTO
			//if (Op_StateAUTO) { Serial.print(F(" MAN"));   else  {  Serial.print(F(" AUTO"));  }
			digitalWrite(pinled,LED_OFF);  
			if (TempDelta > TempFanFAST){FanFAST();	Op_Mode=2;	}
			else if (TempDelta > TempFanSLOW){ FanSLOW();Op_Mode=1;		}       
			else if (TempDelta <= TempFanSLOW){FanOFF(); Op_Mode=3;		}
		}
		else {  // MAN
			digitalWrite(pinled,LED_ON);  
			LedBlink(15,100);
			switch(Op_Mode) {// Op_StateAUTO  0 ignore  1 FanSLOW, 2 FanFast 3 FanOFF
				case 0 : FanSLOW();break;  //for man loop
				case 1 : FanSLOW();break;
				case 2 : FanFAST();break;
				case 3 : FanOFF(); break;
				}
			
			}	
}  // DriveRelays
//______________________________________________________________________
void SendData(){ //send data via index.php
float fMes0,fMes1;
String Link, getData  ;
WiFiClient client;
HTTPClient http;    //Declare object of class HTTPClient
// build a HTTP request
if (WiFi.status() == WL_CONNECTED) {  
	fMes0=probeTemp[0] ;
	fMes1=probeTemp[1] ;
	// String GETdata="GET /esp8266/index.php/?t0=" + String(fMes0)
	GETdata="?t0=" + String(fMes0)  
	+ "&t1="+ fMes1  
	+ "&TD="+  String(TempDelta) 
	+ "&mTD="+ String(maxDelta) 
	+ "&Md="+  String(Op_Mode )
	//+ "&St="+  sState
	+ "&St="+  	String(Op_StateAUTO)
	+ "&ti="+  millis();
	+ " HTTP/1.1";
	//echo to sermon
	Link = "http://192.168.0.11/esp8266/index.php" + GETdata;
	Serial.print(F("===> GETdata: "));	Serial.println(Link);
	http.begin(client,Link);     //Specify request destination
	int httpCode = http.GET();            //Send the request
	Serial.println("=response");	
	String payload = http.getString();    //Get the response payload
	Serial.println(httpCode);   //Print HTTP return code
	Serial.println(payload);    //Print request response payload
	Serial.println("=end response");
	http.end();  //Close connection
	}
else {
	Serial.println("WiFiStatus != WL_CONNECTED");
	}
}
//______________________________________________________________________
void PrtDataToMon(){
	//  (Limits: ON >5.10, FAST >6.30) Delta: 7.12 (max: 7.19), State AUTO, Mode 2 FAST	
	//  Device 0, 2888DA7997040306: 24.44 C 
	//  Device 1, 286E6D4692020290: 17.31 C 
	
	Serial.print(F("PrtDataToMon > (Limits: ON >"));Serial.print(TempFanSLOW);Serial.print(F(", FAST >"));	Serial.print(TempFanFAST);Serial.print(")");
	Serial.print(F(" Delta: "));Serial.print(TempDelta);Serial.print(F(" (max: "));Serial.print(maxDelta);Serial.print(F(")"));
	Serial.print(F(", ")); if (Op_StateAUTO) {Serial.print(F("AUTO"));}  else  {Serial.print(F("MAN"));}
	
	Serial.print(F(", Mode ")) ; Serial.print(Op_Mode);
	switch (Op_Mode) {  //Op_Mode: 0 Auto, 1 FanSLOW, 2 FanFast, 3 FanOFF 
		case 0: Serial.println(F(" -nu-")); break;
		case 1: Serial.println(F(" SLOW")); break;
		case 2: Serial.println(F(" FAST")); break;
		case 3: Serial.println(F(" OFF")); break;
		}
	for(byte i = 0 ; i < iCntDev; i++){ 
			Serial.print(F("Device ")); Serial.print(i);
			Serial.print(F(", ")); printAddress(probes[i]); 
			Serial.print(F(": "));
			Serial.print(probeTemp[i])  ;
			Serial.println(" C ");
			}
	Serial.println("PrtDataToMon <");
	}
//______________________________________________________________________
void printAddress(DeviceAddress deviceAddress) {
// function to print a device address
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print(F("0"));
    Serial.print(deviceAddress[i], HEX);
  }
    }
//______________________________________________________________________
float printTemperature(DeviceAddress deviceAddress) {
// function to print the temperature for a device
  float tempC = mySensors.getTempC(deviceAddress);
  //Serial.print(tempC);
  //Serial.println(" C ");
return tempC;
  //Serial.print(" Temp F: ");
  //Serial.print(DallasTemperature::toFahrenheit(tempC));
    }
//______________________________________________________________________
void printResolution(DeviceAddress deviceAddress) {
// function to print a device's resolution
  Serial.print("Resolution: ");
  Serial.print(mySensors.getResolution(deviceAddress));
  Serial.println();
    }
//______________________________________________________________________
void printData(DeviceAddress deviceAddress) {
// main function to print information about a device
  //Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(F(" "));
  printTemperature(deviceAddress);
  Serial.println();
    }
//______________________________________________________________________
void keysacn(){
	//https://www.baldengineer.com/detect-short-long-button-press.html
    // check the button
    button.currentState = digitalRead(button.pin);
    // has it changed?
    if (button.currentState != button.prevState) {
        delay(button.debounce);
        //Serial.println(F("   After debounce"));
        // update status in case of bounce
        button.currentState = digitalRead(button.pin);
        if (button.currentState == PRESSED) {
            // a new press event occured
            // record when button went down
            //Serial.println(F("   pressed"));
            button.counter = millis();
        }
        if (button.currentState == NOT_PRESSED) {
			//Serial.println(F("   no longer pressed"));
            // but no longer pressed, how long was it down?
            unsigned long currentMillis = millis();
            if ((currentMillis - button.counter >= shortPress) && !(currentMillis - button.counter >= longPress)) {
                // short press detected. 
                handleShortPress();
            }
            if ((currentMillis - button.counter >= longPress)) {
                // the long press was detected
                handleLongPress();
            }
        }
        // used to detect when state changes
        button.prevState = button.currentState;
    }
    }
//______________________________________________________________________
void handleShortPress() {
	 // auto: false , man: true // 0 (nu), 1 FanSLOW, 2 FanFAST, 3 FanOFF
	Serial.print(F(" >>> ShortPress entry "));
	Serial.print(Op_StateAUTO);Serial.print(F(" "));
	Serial.println(Op_Mode);   
	Op_Mode=Op_Mode+1;
	if (Op_Mode<=3) {
		if (Op_StateAUTO) {
			Op_StateAUTO = false ;
			Op_Mode=1;
			}
		else {
			Op_StateAUTO = false ;
			}
		}
	
	if (Op_Mode==4) {      // set AUTO
		Op_StateAUTO = true ; 
		Op_Mode = 0;       
		//MonParams();
        }
	//PrtDataToMon();
	DriveRelays();
	}
//______________________________________________________________________
void handleLongPress() {   //set to auto, slow
	handleShortPress();
	/*
	Serial.println(F("   >>> Long Press"));
	Op_StateAUTO=true ; 
	Op_Mode = 1;
	PrtDataToMon();
	SendData();
	DriveRelays();
	* */
    }
//______________________________________________________________________
void FanSLOW()  {// relay is activated when DO is DISABLED  LOW !
// fan low speed
	//Serial.println("FanSLOW");
	bFastON=false;
	//Op_Mode =1 ;  // when in auto: 0 ignore  1 FanSLOW, 2 FanFast   3 FanOFF
	digitalWrite(RELAY_ON, ENABLE);
	digitalWrite(RELAY_FAST, DISABLED);
    }
//______________________________________________________________________
void FanFAST(){// relay is activated when DO is DISABLED !
// fan high speed
	//Serial.println("FanFAST");
	if (!bFastON) {
		bFastON=true;
		//Op_Mode =2 ;  // when in auto: 0 ignore  1 FanSLOW, 2 FanFast   3 FanOFF
		digitalWrite(RELAY_ON, DISABLED);//cut power
		delay(2000);//wait for discharge of limiting condo
		digitalWrite(RELAY_FAST, ENABLE);//bypass limiting condo
		digitalWrite(RELAY_ON, ENABLE);//power
		}
    }
//______________________________________________________________________
void FanOFF() {// relay is activated when DO is DISABLED !
//fan off
	//Serial.println("FanOFF");
	bFastON=false;
	//Op_Mode =3  ;  // when in auto: 0 ignore  1 FanSLOW, 2 FanFast   3 FanOFF
	digitalWrite(RELAY_ON, DISABLED);
	delay(2000); //wait for discharge of limiting condo // TODO  use millis  !
	digitalWrite(RELAY_FAST, DISABLED);	
    }
//______________________________________________________________________
void printWifiStatus(){
	// print the SSID of the network you're attached to
	Serial.print(F("Connected to WiFi SSID: "));
	Serial.print(WiFi.SSID());
	Serial.print(F(", ip: "));  
	Serial.print(WiFi.localIP());   
	Serial.print(F(" MAC: "));  
	Serial.println(WiFi.macAddress());
	long rssi = WiFi.RSSI();
	Serial.print(F(", signal (RSSI): "));
	Serial.print(rssi); Serial.print(F(" dBm"));
	}
//______________________________________________________________________
void InitWifiCx(){
	WiFi.mode(WIFI_OFF);        //Prevents reconnection issue (taking too long to connect)
	delay(1000);
	WiFi.mode(WIFI_STA);        //This line hides the viewing of ESP as wifi hotspot
	
	WiFi.begin(ssid, password);
	Serial.println("");
	// if (WiFi.waitForConnectResult() != WL_CONNECTED) {
	int i=0;
	while(WiFi.status() != WL_CONNECTED) {
		delay(500);
		Serial.print(i++);
		}
	// you're connected now, so print out the data
	Serial.println("");
	printWifiStatus();
	Serial.println();
	//  set server to response
	//code based on 
	// https://techtutorialsx.com/2017/12/01/esp32-arduino-asynchronous-http-webserver/	
	// https://github.com/me-no-dev/ESPAsyncWebServer/blob/master/src/StringArray.h
	//
	// Send web page with input fields to client  start server 
	server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
		GetTemps();
		request->send_P(200, "text/html", index_html, processor);
		});
	
	// Send a GET request to <ESP_IP>/get?inputString=<inputMessage>
	//  https://www.w3schools.com/get?TempFanSLOW=&Def_TempFanSLOW=_TempFanSLOW
	server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
	    String inputMessage;
	    // GET inputInt value on <ESP_IP>/get?inputInt=<inputMessage>
	    // GET TempFanSLOW value on <ESP_IP>/get?TempFanSLOW=<inputMessage>
	    // http://192.168.0.22/get?idelayMeasures=70000
	    if (request->hasParam(PARAM_idelayMeasures)) {
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_idelayMeasures" ) { // search for &Def_idelayMeasures=
					if (p->value()=="setdef_idelayMeasures") {  // if set, use def value, ignore other option: handled by else part
						FileWrite(SPIFFS, "/idelayMeasures.txt", (String(idelayMeasures_def)).c_str()  ) ;
						idelayMeasures=idelayMeasures_def;		
						}
					else {
						inputMessage=atoi((request->getParam(0)->value()).c_str()) * 1000;
						//Serial.print("inputMessage =");Serial.print(inputMessage);Serial.println("<");
						if (inputMessage.toInt() > 0) {
							FileWrite(SPIFFS, "/idelayMeasures.txt", inputMessage.c_str());
							idelayMeasures=atol(inputMessage.c_str() );
							}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)			
		    }
		else if (request->hasParam(PARAM_idelayRelays)) {
			/*
			inputMessage = request->getParam(PARAM_idelayRelays)->value();
			inputMessage=(inputMessage.toInt())*1000;
			FileWrite(SPIFFS, "/idelayRelays.txt", inputMessage.c_str());
			idelayRelays = atol(inputMessage.c_str());
			*/
			
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_idelayRelays" ) {
					if (p->value()=="setdef_idelayRelays") {
						FileWrite(SPIFFS, "/idelayRelays.txt", (String(idelayRelays_def)).c_str()  ) ;
						idelayRelays=idelayRelays_def;		
						}
					else {
						//inputMessage=(request->getParam(0)->value()) *1000 ;
						inputMessage=request->getParam(0)->value()   ;
						inputMessage=(atoi(inputMessage.c_str())) * 1000;	
		
						if (inputMessage.toInt() > 0) {
							FileWrite(SPIFFS, "/idelayRelays.txt", inputMessage.c_str());
							idelayRelays=(float)atof( inputMessage.c_str()  );
							}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)		
			
			
			}
		else if (request->hasParam(PARAM_idelaySendData)) {
			/*
			inputMessage = request->getParam(PARAM_idelaySendData)->value();
			inputMessage=(inputMessage.toInt())*1000;
			FileWrite(SPIFFS, "/idelaySendData.txt", inputMessage.c_str());
			idelaySendData = atol(inputMessage.c_str());
			*/
			
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_idelaySendData" ) {
					if (p->value()=="setdef_idelaySendData") {
						FileWrite(SPIFFS, "/idelaySendData.txt", (String(idelaySendData_def)).c_str()  ) ;
						idelaySendData=idelaySendData_def;		
						}
					else {
						//inputMessage=(request->getParam(0)->value()) *1000 ;
						inputMessage=request->getParam(0)->value()   ;
						inputMessage=(atoi(inputMessage.c_str())) * 1000;						
						if (inputMessage.toInt() > 0) {
						FileWrite(SPIFFS, "/idelaySendData.txt", inputMessage.c_str());
						idelaySendData=(float)atof( inputMessage.c_str()  );
						}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)					
		
			
			}
		else if (request->hasParam(PARAM_idelayRstDelta)) {
			/*
			inputMessage = request->getParam(PARAM_idelayRstDelta)->value();
			inputMessage=(inputMessage.toInt())*1000;
			FileWrite(SPIFFS, "/idelayRstDelta.txt", inputMessage.c_str());
			idelayRstDelta= atol(inputMessage.c_str());
			*/
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_idelayRstDelta" ) {
					if (p->value()=="setdef_idelayRstDelta") {
						FileWrite(SPIFFS, "/idelayRstDelta.txt", (String(idelayRstDelta_def)).c_str()  ) ;
						idelayRstDelta=idelayRstDelta_def;		
						}
					else {
						//inputMessage=(request->getParam(0)->value()) *1000 ;
						inputMessage=request->getParam(0)->value()   ;
						inputMessage=(atoi(inputMessage.c_str())) * 1000;						
						if (inputMessage.toInt() > 0) {
						FileWrite(SPIFFS, "/idelayRstDelta.txt", inputMessage.c_str());
						idelayRstDelta=(float)atof( inputMessage.c_str()  );
						}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)					
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			}
	    else if (request->hasParam(PARAM_TempFanSLOW)) {  // has received TempFanSLOW=12.34 &Def_TempFanSLOW=setval_TempFanSLOW
			/*
			https://www.w3schools.com/get?TempFanSLOW=00&Def_TempFanSLOW=setdef_TempFanSLOW	
			<input type="radio" 
			name="Def_TempFanSLOW" VALUE="setdef_TempFanSLOW">Set def
			<input type="radio"  
			name="Def_TempFanSLOW" VALUE="setval_TempFanSLOW" checked>Set val
			
			//  https://forum.arduino.cc/index.php?topic=590802.0
			int paramsNr = request->params();
			Serial.println(paramsNr);
			int paramsNr = request->params();
			for(int i=0;i<paramsNr;i++){
			
			AsyncWebParameter* p = request->getParam(i);
			Serial.print("Param name: ");
			Serial.println(p->name());
			Serial.print("Param value: ");
			Serial.println(p->value());
			Serial.println("------");
			}
			*/
			/*
			TempFanSLOW=12.34 &Def_TempFanSLOW=setval_TempFanSLOW
			TempFanSLOW=78.91 &Def_TempFanSLOW=setdef_TempFanSLOW
			*/
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        /*
		        Serial.print("Param name: ");  Serial.println(p->name());
		        Serial.print("Param value: ");  Serial.println(p->value());
		        Serial.println("------");
		        */
		        if (p->name()=="Def_TempFanSLOW" ) {
					if (p->value()=="setdef_TempFanSLOW") {
						FileWrite(SPIFFS, "/TempFanSLOW.txt", (String(TempFanSLOW_def)).c_str()  ) ;
						TempFanSLOW=TempFanSLOW_def;		
						}
					else {
						inputMessage=request->getParam(0)->value();
						if (inputMessage!=0) {
						//inputMessage = request->getParam(PARAM_TempFanSLOW)->value();
						FileWrite(SPIFFS, "/TempFanSLOW.txt", inputMessage.c_str());
						TempFanSLOW=(float)atof( inputMessage.c_str()  );
						}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)
			}
		else if (request->hasParam(PARAM_TempFanFAST)) {
			int paramsNr = request->params();
		    for(int i=0;i<paramsNr;i++){
		        AsyncWebParameter* p = request->getParam(i);
		        if (p->name()=="Def_TempFanFAST" ) {
					if (p->value()=="setdef_TempFanFAST") {
						FileWrite(SPIFFS, "/TempFanFAST.txt", (String(TempFanFAST_def)).c_str()  ) ;
						TempFanFAST=TempFanFAST_def;		
						}
					else {
						inputMessage=request->getParam(0)->value();
						if (inputMessage!=0) {
						FileWrite(SPIFFS, "/TempFanFAST.txt", inputMessage.c_str());
						TempFanFAST=(float)atof( inputMessage.c_str()  );
						}
						}
					}
		    }	//  end for(int i=0;i<paramsNr;i++)
			}
		else if (request->hasParam(PARAM_mode)) {
			handleShortPress();
			//inputMessage = request->getParam(PARAM_mode)->value();
			//inputMessage = String(Op_Mode);
			//FileWrite(SPIFFS, "/mode.txt", inputMessage.c_str());
			//Op_Mode=atol( inputMessage.c_str()  );
			}
				
			
			
		else    { inputMessage = "No message sent";
			}
	    Serial.println(inputMessage);
	    request->send(200, "text/text", inputMessage);
		}
	);  // server.on(
	server.onNotFound(notFound);
	server.begin();	
 }
//______________________________________________________________________
String FileRead(fs::FS &fs, const char * path){
  //Serial.printf("FileRead(): Reading file: %s\r\n", path);
  //Serial.printf("FileRead(): Reading file: %s ", path);
  File file = fs.open(path, "r");
  if(!file || file.isDirectory()){
    //Serial.println("- empty file or failed to open file");
    return String();
  }
  //Serial.print("- read from file:");
  String fileContent;
  while(file.available()){
    fileContent+=String((char)file.read());
  }
  //Serial.println(fileContent);
  return fileContent;
}
//______________________________________________________________________
void FileWrite(fs::FS &fs, const char * path, const char * message){
  Serial.printf("Writing file: %s", path);
  File file = fs.open(path, "w");
  if(!file){
    Serial.print(F("- failed to open file for writing"));
    return;
  }
  if(file.print(message)){
    Serial.print(F("- file written"));
  } else {
    Serial.print(F("- write failed"));
  }
  Serial.println(F(""));
}
//______________________________________________________________________
String processor(const String& var){   // Replaces placeholder with stored values
  //pass param 'id' return value or null (?)
  //Serial.println("==processor");
  //Serial.println(var);
//GetTemps();   //  THIS CRASH WITH WDT   !  too much calls   :)
// / TIMINGS
  if(var == "idelayMeasures"){
    //return FileRead(SPIFFS, "/idelayMeasures.txt");
    return String(idelayMeasures/1000);  }
  else  if(var == "idelayRelays"){
    //return FileRead(SPIFFS, "/idelayRelays.txt");
    return String(idelayRelays/1000);  }
  else  if(var == "idelaySendData"){
    //return FileRead(SPIFFS, "/idelaySendData.txt");
    return String(idelaySendData/1000);  }  
...
This file has been truncated, please download it to see its full contents.







_1x_bGT19vVAby.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)

Comments