|
|
@ -22,18 +22,17 @@ DallasTemperature sensor(&oneWire);
|
|
|
|
|
|
|
|
|
|
|
|
//========== Init variables ==========
|
|
|
|
//========== Init variables ==========
|
|
|
|
|
|
|
|
|
|
|
|
float avgTemperature;
|
|
|
|
float temperature;
|
|
|
|
String metrics;
|
|
|
|
String metrics;
|
|
|
|
bool heating;
|
|
|
|
bool heating;
|
|
|
|
float reqTemp = 21.5;
|
|
|
|
float reqTemp = 21.5;
|
|
|
|
float offset = 0.25;
|
|
|
|
float offset = 0.25;
|
|
|
|
float correction[3] = {CORRECTION1, CORRECTION2, CORRECTION3};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=================================
|
|
|
|
//=================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
void setup() {
|
|
|
|
//========== Wi-Fi setup ==========
|
|
|
|
//========== Wi-Fi setup ==========
|
|
|
|
|
|
|
|
|
|
|
|
WiFi.mode(WIFI_STA);
|
|
|
|
WiFi.mode(WIFI_STA);
|
|
|
|
WiFi.begin(STASSID, STAPSK);
|
|
|
|
WiFi.begin(STASSID, STAPSK);
|
|
|
@ -42,8 +41,8 @@ void setup() {
|
|
|
|
delay(5000);
|
|
|
|
delay(5000);
|
|
|
|
ESP.restart();
|
|
|
|
ESP.restart();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//========== OTA setup ==========
|
|
|
|
//========== OTA setup ==========
|
|
|
|
|
|
|
|
|
|
|
|
// Port defaults to 8266
|
|
|
|
// Port defaults to 8266
|
|
|
|
// ArduinoOTA.setPort(8266);
|
|
|
|
// ArduinoOTA.setPort(8266);
|
|
|
@ -59,171 +58,151 @@ void setup() {
|
|
|
|
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
|
|
|
|
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
|
|
|
|
ArduinoOTA.begin();
|
|
|
|
ArduinoOTA.begin();
|
|
|
|
SPIFFS.begin();
|
|
|
|
SPIFFS.begin();
|
|
|
|
//========== Pin setup ==========
|
|
|
|
//========== Pin setup ==========
|
|
|
|
|
|
|
|
|
|
|
|
pinMode(RELAY_PIN, OUTPUT);
|
|
|
|
pinMode(RELAY_PIN, OUTPUT);
|
|
|
|
pinMode(LED_PIN, OUTPUT);
|
|
|
|
pinMode(LED_PIN, OUTPUT);
|
|
|
|
digitalWrite(LED_PIN, HIGH);
|
|
|
|
digitalWrite(LED_PIN, HIGH);
|
|
|
|
|
|
|
|
|
|
|
|
//========== Sensor setup ==========
|
|
|
|
//========== Sensor setup ==========
|
|
|
|
|
|
|
|
|
|
|
|
sensor.begin();
|
|
|
|
sensor.begin();
|
|
|
|
// do not block during temperature conversion
|
|
|
|
// do not block during temperature conversion
|
|
|
|
sensor.setWaitForConversion(false);
|
|
|
|
sensor.setWaitForConversion(false);
|
|
|
|
|
|
|
|
|
|
|
|
//========== Tasks init ==========
|
|
|
|
//========== Tasks init ==========
|
|
|
|
|
|
|
|
|
|
|
|
startConversion(); // First temp read
|
|
|
|
startConversion(); // First temp read
|
|
|
|
tasker.setInterval(startConversion, 15000); // read temperature every 15 seconds
|
|
|
|
tasker.setInterval(startConversion, 15000); // read temperature every 15 seconds
|
|
|
|
tasker.setInterval(otaHandle, 1000);
|
|
|
|
tasker.setInterval(otaHandle, 1000);
|
|
|
|
|
|
|
|
|
|
|
|
if (THERMOSTAT) {
|
|
|
|
if(THERMOSTAT){
|
|
|
|
tasker.setInterval(thermostatCheck, 1000);
|
|
|
|
tasker.setInterval(thermostatCheck, 1000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//========== Web server setup ==========
|
|
|
|
//========== Web server setup ==========
|
|
|
|
|
|
|
|
|
|
|
|
if (METRICS_EXPORT || API) {
|
|
|
|
if(METRICS_EXPORT || API){
|
|
|
|
if (METRICS_EXPORT) {
|
|
|
|
if(METRICS_EXPORT){
|
|
|
|
server.on("/metrics", HTTP_GET, [](AsyncWebServerRequest * request) {
|
|
|
|
server.on("/metrics", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
|
|
tasker.setTimeout(ledBlink, 10);
|
|
|
|
tasker.setTimeout(ledBlink, 10);
|
|
|
|
request->send(200, "text/plain; charset=utf-8", metrics);
|
|
|
|
request->send(200, "text/plain; charset=utf-8", metrics);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (API) {
|
|
|
|
if(API){
|
|
|
|
server.on("/set", HTTP_GET, [](AsyncWebServerRequest * request) {
|
|
|
|
server.on("/set", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
|
|
//nutno nastavit maxima a minima
|
|
|
|
//nutno nastavit maxima a minima
|
|
|
|
|
|
|
|
|
|
|
|
String repply;
|
|
|
|
String repply;
|
|
|
|
|
|
|
|
|
|
|
|
if (THERMOSTAT) {
|
|
|
|
if(THERMOSTAT){
|
|
|
|
if (request->hasParam("increasereqtemp")) {
|
|
|
|
if (request->hasParam("increasereqtemp")) {
|
|
|
|
reqTemp += request->getParam("increasereqtemp")->value().toFloat();
|
|
|
|
reqTemp += request->getParam("increasereqtemp")->value().toFloat();
|
|
|
|
repply = String(reqTemp);
|
|
|
|
repply = String(reqTemp);
|
|
|
|
} else if (request->hasParam("decreasereqtemp")) {
|
|
|
|
}else if (request->hasParam("decreasereqtemp")) {
|
|
|
|
reqTemp -= request->getParam("decreasereqtemp")->value().toFloat();
|
|
|
|
reqTemp -= request->getParam("decreasereqtemp")->value().toFloat();
|
|
|
|
repply = String(reqTemp);
|
|
|
|
repply = String(reqTemp);
|
|
|
|
} else if (request->hasParam("increaseoffset")) {
|
|
|
|
}else if (request->hasParam("increaseoffset")) {
|
|
|
|
offset += request->getParam("increaseoffset")->value().toFloat();
|
|
|
|
offset += request->getParam("increaseoffset")->value().toFloat();
|
|
|
|
repply = String(offset);
|
|
|
|
repply = String(offset);
|
|
|
|
} else if (request->hasParam("decreaseoffset")) {
|
|
|
|
}else if (request->hasParam("decreaseoffset")) {
|
|
|
|
offset -= request->getParam("decreaseoffset")->value().toFloat();
|
|
|
|
offset -= request->getParam("decreaseoffset")->value().toFloat();
|
|
|
|
repply = String(offset);
|
|
|
|
repply = String(offset);
|
|
|
|
} else {
|
|
|
|
}else{
|
|
|
|
repply = "unknown parameter";
|
|
|
|
repply = "unknown parameter";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
}else{
|
|
|
|
if (request->hasParam("relay")) {
|
|
|
|
if (request->hasParam("relay")) {
|
|
|
|
boolean state = request->getParam("relay")->value() == "0";
|
|
|
|
boolean state = request->getParam("relay")->value() == "0";
|
|
|
|
digitalWrite(RELAY_PIN, state);
|
|
|
|
digitalWrite(RELAY_PIN, state);
|
|
|
|
repply = "success";
|
|
|
|
repply = "success";
|
|
|
|
} else {
|
|
|
|
}else{
|
|
|
|
repply = "unknown parameter";
|
|
|
|
repply = "unknown parameter";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
request->send(200, "text/plain; charset=utf-8", repply);
|
|
|
|
request->send(200, "text/plain; charset=utf-8", repply);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
server.on("/get", HTTP_GET, [](AsyncWebServerRequest * request) {
|
|
|
|
server.on("/get", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
|
|
//nutno vyřešit dotazy na více parametrů najednou
|
|
|
|
//nutno vyřešit dotazy na více parametrů najednou
|
|
|
|
String repply;
|
|
|
|
String repply;
|
|
|
|
|
|
|
|
|
|
|
|
if (request->hasParam("temp")) {
|
|
|
|
if(request->hasParam("temp")) {
|
|
|
|
repply = String(avgTemperature);
|
|
|
|
repply = String(temperature);
|
|
|
|
} else if (request->hasParam("relay")) {
|
|
|
|
}else if(request->hasParam("relay")){
|
|
|
|
repply = String(heating);
|
|
|
|
repply = String(heating);
|
|
|
|
} else if (THERMOSTAT && request->hasParam("reqtemp")) {
|
|
|
|
}else if(THERMOSTAT && request->hasParam("reqtemp")){
|
|
|
|
repply = String(reqTemp);
|
|
|
|
repply = String(reqTemp);
|
|
|
|
} else if (THERMOSTAT && request->hasParam("offset")) {
|
|
|
|
}else if(THERMOSTAT && request->hasParam("offset")) {
|
|
|
|
repply = String(offset);
|
|
|
|
repply = String(offset);
|
|
|
|
} else {
|
|
|
|
}else{
|
|
|
|
repply = "unknown parameter";
|
|
|
|
repply = "unknown parameter";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
request->send(200, "text/plain; charset=utf-8", repply);
|
|
|
|
request->send(200, "text/plain; charset=utf-8", repply);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (API && WEBAPP) {
|
|
|
|
if(API && WEBAPP){
|
|
|
|
server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");
|
|
|
|
server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
server.onNotFound(notFound);
|
|
|
|
server.onNotFound(notFound);
|
|
|
|
server.begin();
|
|
|
|
server.begin();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//=================================
|
|
|
|
//=================================
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
void loop() {
|
|
|
|
tasker.loop();
|
|
|
|
tasker.loop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void otaHandle() {
|
|
|
|
void otaHandle(){
|
|
|
|
ArduinoOTA.handle();
|
|
|
|
ArduinoOTA.handle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void notFound(AsyncWebServerRequest *request) {
|
|
|
|
void notFound(AsyncWebServerRequest *request) {
|
|
|
|
request->send(404, "text/plain", "Not found");
|
|
|
|
request->send(404, "text/plain", "Not found");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void thermostatCheck() {
|
|
|
|
void thermostatCheck(){
|
|
|
|
if (avgTemperature <= (reqTemp - offset)) {
|
|
|
|
if(temperature < (reqTemp - offset)){
|
|
|
|
heating = 1;
|
|
|
|
heating = 1;
|
|
|
|
digitalWrite(RELAY_PIN, !heating);
|
|
|
|
digitalWrite(RELAY_PIN, !heating);
|
|
|
|
} else if (avgTemperature >= (reqTemp + offset)) {
|
|
|
|
}else if(temperature > (reqTemp + offset)){
|
|
|
|
heating = 0;
|
|
|
|
heating = 0;
|
|
|
|
digitalWrite(RELAY_PIN, !heating);
|
|
|
|
digitalWrite(RELAY_PIN, !heating);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void readSensor() {
|
|
|
|
void readSensor() {
|
|
|
|
uint8_t ds18Count = sensor.getDS18Count();
|
|
|
|
float tempC = sensor.getTempCByIndex(0);
|
|
|
|
float tempC[ds18Count];
|
|
|
|
|
|
|
|
float temperature[ds18Count];
|
|
|
|
if(tempC != DEVICE_DISCONNECTED_C){
|
|
|
|
float avgTemperature;
|
|
|
|
// read the actual temperature after it's been converted
|
|
|
|
int savedTemperatures = 0;
|
|
|
|
temperature = tempC + CORRECTION;
|
|
|
|
|
|
|
|
// do what you need with the temperature here
|
|
|
|
for (int i = 0; i < ds18Count; i++) {
|
|
|
|
|
|
|
|
tempC[i] = sensor.getTempCByIndex(i);
|
|
|
|
|
|
|
|
if (tempC[i] != DEVICE_DISCONNECTED_C) {
|
|
|
|
|
|
|
|
temperature[i] = tempC[i] + correction[i];
|
|
|
|
|
|
|
|
avgTemperature += temperature[i];
|
|
|
|
|
|
|
|
savedTemperatures++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
avgTemperature = avgTemperature / savedTemperatures;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ds18Count; i++) {
|
|
|
|
|
|
|
|
metrics += "\ntemp{device=\"";
|
|
|
|
|
|
|
|
metrics += i;
|
|
|
|
|
|
|
|
metrics += "\"} ";
|
|
|
|
|
|
|
|
metrics += temperature[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < ds18Count; i++) {
|
|
|
|
metrics = "temp ";
|
|
|
|
metrics += "\nraw_temp{device=\"";
|
|
|
|
metrics += temperature;
|
|
|
|
metrics += i;
|
|
|
|
metrics += "\nraw_temp ";
|
|
|
|
metrics += "\"} ";
|
|
|
|
metrics += tempC;
|
|
|
|
metrics += tempC[i];
|
|
|
|
metrics += "\nheating ";
|
|
|
|
}
|
|
|
|
metrics += heating;
|
|
|
|
if (THERMOSTAT) {
|
|
|
|
metrics += "\nreqTemp ";
|
|
|
|
metrics += "\nheating ";
|
|
|
|
metrics += reqTemp;
|
|
|
|
metrics += heating;
|
|
|
|
metrics += "\noffset ";
|
|
|
|
metrics += "\nreqTemp ";
|
|
|
|
metrics += offset;
|
|
|
|
metrics += reqTemp;
|
|
|
|
|
|
|
|
metrics += "\noffset ";
|
|
|
|
|
|
|
|
metrics += offset;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void startConversion() {
|
|
|
|
void startConversion() {
|
|
|
|
// start temperature conversion (does not block)
|
|
|
|
// start temperature conversion (does not block)
|
|
|
|
sensor.requestTemperatures();
|
|
|
|
sensor.requestTemperatures();
|
|
|
|
// schedule reading the actual temperature in 750 milliseconds
|
|
|
|
// schedule reading the actual temperature in 750 milliseconds
|
|
|
|
tasker.setTimeout(readSensor, 750);
|
|
|
|
tasker.setTimeout(readSensor, 750);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void ledBlink() {
|
|
|
|
void ledBlink() {
|
|
|
|
digitalWrite(LED_PIN, LOW);
|
|
|
|
digitalWrite(LED_PIN, LOW);
|
|
|
|
delay(200);
|
|
|
|
delay(200);
|
|
|
|
digitalWrite(LED_PIN, HIGH);
|
|
|
|
digitalWrite(LED_PIN, HIGH);
|
|
|
|
}
|
|
|
|
}
|
|
|
|