float tmpHum, tmpTemp; int DHTreadRetries = 2; //int DHTreadDelay = 20; void readDHTsensorTemp() { //delay(DHTreadDelay); tmpTemp = dht.readTemperature(); // Read temperature as Celsius (the default) } void readDHTsensorHum() { //delay(DHTreadDelay); tmpHum = dht.readHumidity(); } void measureTempHum() { for(int i=0; i < DHTreadRetries; i++) { readDHTsensorTemp(); if(!isnan(tmpTemp)) { sendStatus("DHT reading Temp OK"); i=DHTreadRetries; } //else { // sendStatus("DHT reading Temp failed - retrying.."); //} } for(int i=0; i < DHTreadRetries; i++) { readDHTsensorHum(); if(!isnan(tmpHum)) { sendStatus("DHT reading Hum OK"); i=DHTreadRetries; } //else { // sendStatus("DHT reading Hum failed - retrying.."); //} } // Check if any reads failed if (isnan(tmpHum) || isnan(tmpTemp)) { //Serial.println("Failed to read from DHT sensor!"); sendStatus("Error: Failed to read from DHT sensor!"); } else { tmpTemp = tmpTemp + tempCorrVal; tmpHum = round(tmpHum) + humCorrVal; int tmpHumInt = tmpHum; if (tmpTemp < 50.0 && tmpTemp > -20.0) { // measurement is in range currTemp_raw = tmpTemp; currHum_raw = tmpHumInt; if ( lastTempUpdate > 0 && tmpTemp <= ( currTemp + 2.0 ) && tmpTemp >= ( currTemp - 2.0 ) ) { // temp has already been measured - only accept new measurement if it does not differ much from the last value //Temp = (Temp * (FilterFaktor -1) + AktuellerMesswert) / FilterFaktor; //temperature = tmpTemp; currTemp = (currTemp * 9 + tmpTemp) / 10; // filter currHum = (currHum * 9 + tmpHumInt) / 10; // filter lastTempUpdate = millis(); } else if ( lastTempUpdate == 0 || (millis() - lastTempUpdate) > maxMeasurementAge ) { // this is the first measurement or the last one is older than 5m - then accept this measurement currTemp = tmpTemp + tempCorrVal; currHum = tmpHumInt + humCorrVal; lastTempUpdate = millis(); } // skip in all other cases //#ifdef DEBUG_VERBOSE // Serial.print("lastTempUpdate: "); // long lastTempUpdateDelta = millis() - lastTempUpdate; // Serial.print(lastTempUpdateDelta / 1000); // Serial.println("s ago"); //#endif } } } void updateCurrSetTemp() { // set target temp for heating mode if (heatingMode > 0) { // heating on if (preset == 0) { // normal/day preset currSetTemp = setTemp; } else if (preset == 1) { // night/reduction preset currSetTemp = setTempLow; } else if (preset == 2) { // night/reduction 2 preset currSetTemp = setTempLow2; } } else { // if heatingMode == 0 currSetTemp = DEFAULT_SETTEMP_HEATOFF; } } void thermostat() { updateCurrSetTemp(); char tmp_topic_out[50]; if (heatingMode > 0 && turnHeatingOn) { heatingOnTime = (millis() - heatingLastOnMillis) / 1000; char buf[101]; sprintf(buf, "heating on since %d s", heatingOnTime); sendStatus(buf); } else if (heatingMode > 0 && !turnHeatingOn) { heatingOffTime = (millis() - heatingLastOffMillis) / 1000; char buf[101]; sprintf(buf, "heating off since %d s", heatingOffTime); sendStatus(buf); } //char tmp_topic_out[50]; //sprintf(tmp_topic_out, "%s/%s", mqtt_topic_out, "heating"); if ( lastTempUpdate != 0 && (millis() - lastTempUpdate) <= maxMeasurementAge ) { // thermostat - only active if measured temperature is < 2 min old #ifdef DEBUG_VERBOSE Serial.print("thermostat, lastTempUpdate="); Serial.print(lastTempUpdate); Serial.print(", lastTempUpdate_delta="); long lastTempUpdateDelta = millis() - lastTempUpdate; Serial.println(lastTempUpdateDelta); #endif // thermostat with hysteresis if ( turnHeatingOn && currTemp >= (currSetTemp - setTempDecreaseVal) ) { turnHeatingOn = false; heatingLastOffMillis = millis(); digitalWrite(PIN_RELAIS, !RELAISONSTATE); updateDisplay(); char buf[101]; sprintf(buf, "switch heating OFF, on since %d s", heatingOnTime); sendStatus(buf); //Serial.println("heating off"); //mqttclient.publish(tmp_topic_out, "off"); publishCurrentThermostatValues(); sendToDomoticz_Heating(); } else if ( !turnHeatingOn && heatingMode > 0 && ( currTemp < (currSetTemp - setTempDecreaseVal - hysteresis) ) && ( heatingOffTime > heatingMinOffTime ) ) { turnHeatingOn = true; heatingLastOnMillis = millis(); digitalWrite(PIN_RELAIS, RELAISONSTATE); updateDisplay(); char buf[101]; sprintf(buf, "switch heating ON, off since %d s", heatingOffTime); sendStatus(buf); //Serial.println("heating on"); //mqttclient.publish(tmp_topic_out, "on"); publishCurrentThermostatValues(); sendToDomoticz_Heating(); } } else { if (turnHeatingOn) { digitalWrite(PIN_RELAIS, !RELAISONSTATE); turnHeatingOn = false; heatingLastOffMillis = millis(); } if ( lastTempUpdate != 0 ) sendStatus("switch heating OFF, temp reading not yet available"); else if ( (millis() - lastTempUpdate) > maxMeasurementAge ) sendStatus("switch heating OFF, last temp reading too old"); //mqttclient.publish(tmp_topic_out, "off"); publishCurrentThermostatValues(); sendToDomoticz_Heating(); } } void toggleOnOff() { if (heatingMode > 0) { heatingMode = 0; lastValueChange = millis(); heatingModeAlreadySaved = false; } else { heatingMode = 1; lastValueChange = millis(); heatingModeAlreadySaved = false; } updateCurrentHeatingModeName(); updateDisplay(); } void togglePreset() { Serial.print("switch preset to "); if (pendingPreset < 0 || pendingPreset > 2) pendingPreset = preset; // if (pendingPresetToggle && preset == 0 && pendingPreset == 0) pendingPreset = 1; // else if (pendingPresetToggle && preset == 1 && pendingPreset == 1) pendingPreset = 0; // else if (pendingPreset == 1 && pendingPresetToggle) pendingPreset = 2; // else if (pendingPreset == 2 && !pendingPresetToggle) pendingPreset = 0; // else if (pendingPreset == 2 && pendingPresetToggle) pendingPreset = 1; if (pendingPreset == 0) pendingPreset = 1; else if (pendingPreset == 1) pendingPreset = 2; else if (pendingPreset == 2) pendingPreset = 0; // if (preset == 0 && pendingPreset == 0) pendingPreset = 1; // else if (preset == 0 && pendingPreset == 1) pendingPreset = 2; // else if (preset == 1 && pendingPreset == 0) pendingPreset = 2; // else if (preset == 1 && pendingPreset == 1) pendingPreset = 0; // else if (preset == 1 && pendingPreset == 2) pendingPreset = 1; // else if (preset == 1 && pendingPreset == 0) pendingPreset = 1; // else if (preset == 2 && pendingPreset == 0) pendingPreset = 1; // else if (preset == 2 && pendingPreset == 1) pendingPreset = 0; // else if (preset == 2 && pendingPreset == 2) pendingPreset = 0; lastValueChange = millis(); presetAlreadySaved = false; updatePendingPresetName(); //updateDisplay(); //pendingPresetToggle = true; displayShowLine2OverlayMessage(pendingPresetName); Serial.print(pendingPreset); Serial.print(" - \""); Serial.print(currentPresetName); Serial.println("\""); } void updateCurrentHeatingModeName() { if (heatingMode == 0) strlcpy(currentModeName, modename0, 14); else if (heatingMode == 1) strlcpy(currentModeName, modename1, 14); } void updateCurrentPresetName() { if (preset == 0) strlcpy(currentPresetName, psetname0, 14); else if (preset == 1) strlcpy(currentPresetName, psetname1, 14); else if (preset == 2) strlcpy(currentPresetName, psetname2, 14); } void updatePendingPresetName() { if (pendingPreset == 0) strlcpy(pendingPresetName, psetname0, 14); else if (pendingPreset == 1) strlcpy(pendingPresetName, psetname1, 14); else if (pendingPreset == 2) strlcpy(pendingPresetName, psetname2, 14); } void setTempStepUp() { if (heatingMode == 1) { Serial.println("setTemp +0.5"); if ( setTemp <= (setTempMax - 0.5)) { setTemp += 0.5; lastValueChange = millis(); setTempAlreadySaved = false; } updateDisplay(); } } void setTempStepDown() { if (heatingMode == 1) { Serial.println("setTemp -0.5"); if ( setTemp >= (setTempMin + 0.5)) { setTemp -= 0.5; lastValueChange = millis(); setTempAlreadySaved = false; } updateDisplay(); } } void setTempTo(float setTo) { boolean changes = false; if (setTo >= setTempMin && setTo <= setTempMax) { setTemp = setTo; changes = true; } else if (setTo > setTempMax) { setTemp = setTempMax; changes = true; } else if (setTo < setTempMin) { setTemp = setTempMin; changes = true; } if (changes) { lastValueChange = millis(); setTempAlreadySaved = false; updateDisplay(); publishCurrentThermostatValues(); } } void setTempLowTo(float setTo) { boolean changes = false; if (setTo >= setTempLowMin && setTo <= setTempLowMax) { setTempLow = setTo; changes = true; } else if (setTo > setTempLowMax) { setTempLow = setTempLowMax; changes = true; } else if (setTo < setTempLowMin) { setTempLow = setTempLowMin; changes = true; } if (changes) { updateDisplay(); publishCurrentThermostatValues(); } } void setTempLow2To(float setTo) { boolean changes = false; if (setTo >= setTempLowMin && setTo <= setTempLowMax) { setTempLow2 = setTo; changes = true; } else if (setTo > setTempLowMax) { setTempLow2 = setTempLowMax; changes = true; } else if (setTo < setTempLowMin) { setTempLow2 = setTempLowMin; changes = true; } if (changes) { updateDisplay(); publishCurrentThermostatValues(); } } void setHeatingmodeTo(byte setTo) { boolean changes = false; switch (setTo) { case 0: heatingMode = 0; changes = true; break; case 1: heatingMode = 1; changes = true; break; } if (changes) { updateCurrSetTemp(); lastValueChange = millis(); heatingModeAlreadySaved = false; updateCurrentHeatingModeName(); updateDisplay(); publishCurrentThermostatValues(); } } void setPresetTo(byte setTo) { boolean changes = false; switch (setTo) { case 0: preset = 0; pendingPreset = 0; changes = true; break; case 1: preset = 1; pendingPreset = 1; changes = true; break; case 2: preset = 2; pendingPreset = 2; changes = true; break; } if (changes) { updateCurrSetTemp(); lastValueChange = millis(); presetAlreadySaved = false; updateCurrentPresetName(); updateDisplay(); publishCurrentThermostatValues(); } } void checkValuesChanged() { // called every second by everySecond() / misc.ino if ( !setTempAlreadySaved || !heatingModeAlreadySaved || !presetAlreadySaved) { if ( (millis() - lastValueChange) > saveValuesTimeout ) { // value was changed 5s ago. now save if auto-save enabled if (!setTempAlreadySaved) { lastUpdate_setTemp = millis(); sendToDomoticz_thermostat(); if (autoSaveSetTemp && setTemp != setTempSaved) { saveSetTemp(); sendStatus("setTemp autosave done"); } setTempAlreadySaved = true; } if (!heatingModeAlreadySaved) { lastUpdate_heatingMode = millis(); sendToDomoticz_heatingMode(); if (autoSaveHeatingMode && heatingMode != heatingModeSaved) { saveHeatingMode(); sendStatus("heatingMode autosave done"); } heatingModeAlreadySaved = true; } if (!presetAlreadySaved) { lastUpdate_preset = millis(); //sendToDomoticz_heatingMode(); preset = pendingPreset; if (autoSaveHeatingMode && preset != presetSaved) { savePreset(); sendStatus("preset autosave done"); } presetAlreadySaved = true; } publishCurrentThermostatValues(); } } }