thermostat.ino 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. void measureTempHum() {
  2. delay(1);
  3. float tmpHum = round(dht.readHumidity()) + humCorrVal;
  4. delay(1);
  5. float tmpTemp = dht.readTemperature() + tempCorrVal; // Read temperature as Celsius (the default)
  6. delay(1);
  7. int tmpHumInt = tmpHum;
  8. // Check if any reads failed
  9. if (isnan(tmpHum) || isnan(tmpTemp)) {
  10. //Serial.println("Failed to read from DHT sensor!");
  11. sendStatus("Error: Failed to read from DHT sensor!");
  12. }
  13. else {
  14. if (tmpTemp < 50.0 && tmpTemp > -20.0) {
  15. // measurement is in range
  16. currTemp_raw = tmpTemp;
  17. currHum_raw = tmpHumInt;
  18. if ( lastTempUpdate > 0 && tmpTemp <= ( currTemp + 2.0 ) && tmpTemp >= ( currTemp - 2.0 ) ) {
  19. // temp has already been measured - only accept new measurement if it does not differ much from the last value
  20. //Temp = (Temp * (FilterFaktor -1) + AktuellerMesswert) / FilterFaktor;
  21. //temperature = tmpTemp;
  22. currTemp = (currTemp * 9 + tmpTemp) / 10; // filter
  23. currHum = (currHum * 9 + tmpHumInt) / 10; // filter
  24. lastTempUpdate = millis();
  25. }
  26. else if ( lastTempUpdate == 0 || (millis() - lastTempUpdate) > 300000 ) {
  27. // this is the first measurement or the last one is older than 5m - then accept this measurement
  28. currTemp = tmpTemp + tempCorrVal;
  29. currHum = tmpHumInt + humCorrVal;
  30. lastTempUpdate = millis();
  31. }
  32. // skip in all other cases
  33. //#ifdef DEBUG_VERBOSE
  34. // Serial.print("lastTempUpdate: ");
  35. // long lastTempUpdateDelta = millis() - lastTempUpdate;
  36. // Serial.print(lastTempUpdateDelta / 1000);
  37. // Serial.println("s ago");
  38. //#endif
  39. }
  40. }
  41. }
  42. void updateCurrSetTemp() {
  43. // set target temp for heating mode
  44. if (heatingMode > 0) { // heating on
  45. if (preset == 0) { // normal/day preset
  46. currSetTemp = setTemp;
  47. }
  48. else if (preset == 1) { // night/reduction preset
  49. currSetTemp = setTempLow;
  50. }
  51. else if (preset == 2) { // night/reduction 2 preset
  52. currSetTemp = setTempLow2;
  53. }
  54. }
  55. else { // if heatingMode == 0
  56. currSetTemp = DEFAULT_SETTEMP_HEATOFF;
  57. }
  58. }
  59. void thermostat() {
  60. updateCurrSetTemp();
  61. char tmp_topic_out[50];
  62. if (heatingMode > 0 && turnHeatingOn) {
  63. heatingOnTime = (millis() - heatingLastOnMillis) / 1000;
  64. char buf[101];
  65. sprintf(buf, "heating on since %d s", heatingOnTime);
  66. sendStatus(buf);
  67. }
  68. else if (heatingMode > 0 && !turnHeatingOn) {
  69. heatingOffTime = (millis() - heatingLastOffMillis) / 1000;
  70. char buf[101];
  71. sprintf(buf, "heating off since %d s", heatingOffTime);
  72. sendStatus(buf);
  73. }
  74. //char tmp_topic_out[50];
  75. //sprintf(tmp_topic_out, "%s/%s", mqtt_topic_out, "heating");
  76. if ( lastTempUpdate != 0 && (millis() - lastTempUpdate) <= 120000 ) {
  77. // thermostat - only active if measured temperature is < 2 min old
  78. #ifdef DEBUG_VERBOSE
  79. Serial.print("thermostat, lastTempUpdate=");
  80. Serial.print(lastTempUpdate);
  81. Serial.print(", lastTempUpdate_delta=");
  82. long lastTempUpdateDelta = millis() - lastTempUpdate;
  83. Serial.println(lastTempUpdateDelta);
  84. #endif
  85. // thermostat with hysteresis
  86. if ( turnHeatingOn && currTemp >= (currSetTemp - setTempDecreaseVal) ) {
  87. turnHeatingOn = false;
  88. heatingLastOffMillis = millis();
  89. digitalWrite(PIN_RELAIS, !RELAISONSTATE);
  90. updateDisplay();
  91. char buf[101];
  92. sprintf(buf, "switch heating OFF, on since %d s", heatingOnTime);
  93. sendStatus(buf);
  94. //Serial.println("heating off");
  95. //mqttclient.publish(tmp_topic_out, "off");
  96. publishCurrentThermostatValues();
  97. sendToDomoticz_Heating();
  98. }
  99. else if ( !turnHeatingOn && heatingMode > 0 && ( currTemp < (currSetTemp - setTempDecreaseVal - hysteresis) ) && ( heatingOffTime > heatingMinOffTime ) ) {
  100. turnHeatingOn = true;
  101. heatingLastOnMillis = millis();
  102. digitalWrite(PIN_RELAIS, RELAISONSTATE);
  103. updateDisplay();
  104. char buf[101];
  105. sprintf(buf, "switch heating ON, off since %d s", heatingOffTime);
  106. sendStatus(buf);
  107. //Serial.println("heating on");
  108. //mqttclient.publish(tmp_topic_out, "on");
  109. publishCurrentThermostatValues();
  110. sendToDomoticz_Heating();
  111. }
  112. }
  113. else {
  114. if (turnHeatingOn) {
  115. digitalWrite(PIN_RELAIS, !RELAISONSTATE);
  116. turnHeatingOn = false;
  117. heatingLastOffMillis = millis();
  118. }
  119. if ( lastTempUpdate != 0 ) sendStatus("switch heating OFF, temp reading not yet available");
  120. else if ( (millis() - lastTempUpdate) > 120000 ) sendStatus("switch heating OFF, last temp reading too old");
  121. //mqttclient.publish(tmp_topic_out, "off");
  122. publishCurrentThermostatValues();
  123. sendToDomoticz_Heating();
  124. }
  125. }
  126. void toggleOnOff() {
  127. if (heatingMode > 0) {
  128. heatingMode = 0;
  129. lastValueChange = millis();
  130. heatingModeAlreadySaved = false;
  131. }
  132. else {
  133. heatingMode = 1;
  134. lastValueChange = millis();
  135. heatingModeAlreadySaved = false;
  136. }
  137. updateCurrentHeatingModeName();
  138. updateDisplay();
  139. }
  140. void togglePreset() {
  141. Serial.print("switch preset to ");
  142. if (pendingPreset < 0 || pendingPreset > 2) pendingPreset = preset;
  143. // if (pendingPresetToggle && preset == 0 && pendingPreset == 0) pendingPreset = 1;
  144. // else if (pendingPresetToggle && preset == 1 && pendingPreset == 1) pendingPreset = 0;
  145. // else if (pendingPreset == 1 && pendingPresetToggle) pendingPreset = 2;
  146. // else if (pendingPreset == 2 && !pendingPresetToggle) pendingPreset = 0;
  147. // else if (pendingPreset == 2 && pendingPresetToggle) pendingPreset = 1;
  148. if (pendingPreset == 0) pendingPreset = 1;
  149. else if (pendingPreset == 1) pendingPreset = 2;
  150. else if (pendingPreset == 2) pendingPreset = 0;
  151. // if (preset == 0 && pendingPreset == 0) pendingPreset = 1;
  152. // else if (preset == 0 && pendingPreset == 1) pendingPreset = 2;
  153. // else if (preset == 1 && pendingPreset == 0) pendingPreset = 2;
  154. // else if (preset == 1 && pendingPreset == 1) pendingPreset = 0;
  155. // else if (preset == 1 && pendingPreset == 2) pendingPreset = 1;
  156. // else if (preset == 1 && pendingPreset == 0) pendingPreset = 1;
  157. // else if (preset == 2 && pendingPreset == 0) pendingPreset = 1;
  158. // else if (preset == 2 && pendingPreset == 1) pendingPreset = 0;
  159. // else if (preset == 2 && pendingPreset == 2) pendingPreset = 0;
  160. lastValueChange = millis();
  161. presetAlreadySaved = false;
  162. updatePendingPresetName();
  163. //updateDisplay();
  164. //pendingPresetToggle = true;
  165. displayShowLine2OverlayMessage(pendingPresetName);
  166. Serial.print(pendingPreset);
  167. Serial.print(" - \"");
  168. Serial.print(currentPresetName);
  169. Serial.println("\"");
  170. }
  171. void updateCurrentHeatingModeName() {
  172. if (heatingMode == 0) strlcpy(currentModeName, modename0, 14);
  173. else if (heatingMode == 1) strlcpy(currentModeName, modename1, 14);
  174. }
  175. void updateCurrentPresetName() {
  176. if (preset == 0) strlcpy(currentPresetName, psetname0, 14);
  177. else if (preset == 1) strlcpy(currentPresetName, psetname1, 14);
  178. else if (preset == 2) strlcpy(currentPresetName, psetname2, 14);
  179. }
  180. void updatePendingPresetName() {
  181. if (pendingPreset == 0) strlcpy(pendingPresetName, psetname0, 14);
  182. else if (pendingPreset == 1) strlcpy(pendingPresetName, psetname1, 14);
  183. else if (pendingPreset == 2) strlcpy(pendingPresetName, psetname2, 14);
  184. }
  185. void setTempStepUp() {
  186. if (heatingMode == 1) {
  187. Serial.println("setTemp +0.5");
  188. if ( setTemp <= (setTempMax - 0.5)) {
  189. setTemp += 0.5;
  190. lastValueChange = millis();
  191. setTempAlreadySaved = false;
  192. }
  193. updateDisplay();
  194. }
  195. }
  196. void setTempStepDown() {
  197. if (heatingMode == 1) {
  198. Serial.println("setTemp -0.5");
  199. if ( setTemp >= (setTempMin + 0.5)) {
  200. setTemp -= 0.5;
  201. lastValueChange = millis();
  202. setTempAlreadySaved = false;
  203. }
  204. updateDisplay();
  205. }
  206. }
  207. void setTempTo(float setTo) {
  208. boolean changes = false;
  209. if (setTo >= setTempMin && setTo <= setTempMax) {
  210. setTemp = setTo;
  211. changes = true;
  212. }
  213. else if (setTo > setTempMax) {
  214. setTemp = setTempMax;
  215. changes = true;
  216. }
  217. else if (setTo < setTempMin) {
  218. setTemp = setTempMin;
  219. changes = true;
  220. }
  221. if (changes) {
  222. lastValueChange = millis();
  223. setTempAlreadySaved = false;
  224. updateDisplay();
  225. publishCurrentThermostatValues();
  226. }
  227. }
  228. void setTempLowTo(float setTo) {
  229. boolean changes = false;
  230. if (setTo >= setTempLowMin && setTo <= setTempLowMax) {
  231. setTempLow = setTo;
  232. changes = true;
  233. }
  234. else if (setTo > setTempLowMax) {
  235. setTempLow = setTempLowMax;
  236. changes = true;
  237. }
  238. else if (setTo < setTempLowMin) {
  239. setTempLow = setTempLowMin;
  240. changes = true;
  241. }
  242. if (changes) {
  243. updateDisplay();
  244. publishCurrentThermostatValues();
  245. }
  246. }
  247. void setTempLow2To(float setTo) {
  248. boolean changes = false;
  249. if (setTo >= setTempLowMin && setTo <= setTempLowMax) {
  250. setTempLow2 = setTo;
  251. changes = true;
  252. }
  253. else if (setTo > setTempLowMax) {
  254. setTempLow2 = setTempLowMax;
  255. changes = true;
  256. }
  257. else if (setTo < setTempLowMin) {
  258. setTempLow2 = setTempLowMin;
  259. changes = true;
  260. }
  261. if (changes) {
  262. updateDisplay();
  263. publishCurrentThermostatValues();
  264. }
  265. }
  266. void setHeatingmodeTo(byte setTo) {
  267. boolean changes = false;
  268. switch (setTo) {
  269. case 0:
  270. heatingMode = 0;
  271. changes = true;
  272. break;
  273. case 1:
  274. heatingMode = 1;
  275. changes = true;
  276. break;
  277. }
  278. if (changes) {
  279. updateCurrSetTemp();
  280. lastValueChange = millis();
  281. heatingModeAlreadySaved = false;
  282. updateCurrentHeatingModeName();
  283. updateDisplay();
  284. publishCurrentThermostatValues();
  285. }
  286. }
  287. void setPresetTo(byte setTo) {
  288. boolean changes = false;
  289. switch (setTo) {
  290. case 0:
  291. preset = 0;
  292. pendingPreset = 0;
  293. changes = true;
  294. break;
  295. case 1:
  296. preset = 1;
  297. pendingPreset = 1;
  298. changes = true;
  299. break;
  300. case 2:
  301. preset = 2;
  302. pendingPreset = 2;
  303. changes = true;
  304. break;
  305. }
  306. if (changes) {
  307. updateCurrSetTemp();
  308. lastValueChange = millis();
  309. presetAlreadySaved = false;
  310. updateCurrentPresetName();
  311. updateDisplay();
  312. publishCurrentThermostatValues();
  313. }
  314. }
  315. void checkValuesChanged() { // called every second by everySecond() / misc.ino
  316. if ( !setTempAlreadySaved || !heatingModeAlreadySaved || !presetAlreadySaved) {
  317. if ( (millis() - lastValueChange) > saveValuesTimeout ) { // value was changed 5s ago. now save if auto-save enabled
  318. if (!setTempAlreadySaved) {
  319. lastUpdate_setTemp = millis();
  320. sendToDomoticz_thermostat();
  321. if (autoSaveSetTemp && setTemp != setTempSaved) {
  322. saveSetTemp();
  323. sendStatus("setTemp autosave done");
  324. }
  325. setTempAlreadySaved = true;
  326. }
  327. if (!heatingModeAlreadySaved) {
  328. lastUpdate_heatingMode = millis();
  329. sendToDomoticz_heatingMode();
  330. if (autoSaveHeatingMode && heatingMode != heatingModeSaved) {
  331. saveHeatingMode();
  332. sendStatus("heatingMode autosave done");
  333. }
  334. heatingModeAlreadySaved = true;
  335. }
  336. if (!presetAlreadySaved) {
  337. lastUpdate_preset = millis();
  338. //sendToDomoticz_heatingMode();
  339. preset = pendingPreset;
  340. if (autoSaveHeatingMode && preset != presetSaved) {
  341. savePreset();
  342. sendStatus("preset autosave done");
  343. }
  344. presetAlreadySaved = true;
  345. }
  346. publishCurrentThermostatValues();
  347. }
  348. }
  349. }