|
@@ -1,35 +1,54 @@
|
|
|
|
|
|
// pre compiletime config
|
|
// pre compiletime config
|
|
|
|
+
|
|
|
|
+//#define DEBUG_VERBOSE
|
|
|
|
+
|
|
|
|
+#define SPIFFS_DBG
|
|
|
|
+#define SPIFFS_USE_MAGIC
|
|
|
|
+
|
|
|
|
+#define FIRMWARE_NAME "WiFiThermostat"
|
|
#define VERSION "0.1.2"
|
|
#define VERSION "0.1.2"
|
|
|
|
+#define COPYRIGHT " by Flo Kra"
|
|
|
|
+
|
|
|
|
+// default values, can later be overridden via configuration
|
|
|
|
+#define DEVICE_NAME "WiFi-Thermostat-1"
|
|
|
|
+#define MQTT_SERVER "10.1.1.11"
|
|
|
|
+#define MQTT_PORT 1883
|
|
|
|
+#define MQTT_TOPIC_IN "Test/Thermostat/cmd"
|
|
|
|
+#define MQTT_TOPIC_OUT "Test/Thermostat/status"
|
|
|
|
+#define BUTTON_DEBOUNCE_TIME 120
|
|
|
|
+#define BUTTON_HOLD_TIME 750
|
|
|
|
+#define DOMOTICZ_IN_TOPIC "domoticz/in"
|
|
|
|
+#define DOMOTICZ_OUT_TOPIC "domoticz/out"
|
|
|
|
+#define OUTTEMP_TOPIC_IN "wetter/atemp"
|
|
|
|
+#define OUTHUM_TOPIC_IN "wetter/ahum"
|
|
|
|
+
|
|
|
|
+#define CLEARCONF_TOKEN "TUES"
|
|
|
|
|
|
-#define DEVICE_NAME "WIFI-THERMOSTAT"
|
|
|
|
|
|
|
|
|
|
+// pin assignments and I2C addresses
|
|
#define PIN_DHTSENSOR 13
|
|
#define PIN_DHTSENSOR 13
|
|
#define PIN_RELAIS 16
|
|
#define PIN_RELAIS 16
|
|
-#define PIN_BUTTON_PLUS 0
|
|
|
|
-#define PIN_BUTTON_MINUS 2
|
|
|
|
|
|
+#define PIN_BUTTON_PLUS 2
|
|
|
|
+#define PIN_BUTTON_MINUS 0
|
|
#define PIN_BUTTON_MODE 14
|
|
#define PIN_BUTTON_MODE 14
|
|
#define PIN_PIRSENSOR 12
|
|
#define PIN_PIRSENSOR 12
|
|
|
|
|
|
-#define RELAISONSTATE LOW
|
|
|
|
-#define BUTTONONSTATE LOW
|
|
|
|
-
|
|
|
|
#define DHTTYPE DHT22 // DHT sensor type
|
|
#define DHTTYPE DHT22 // DHT sensor type
|
|
|
|
+
|
|
#define LCDADDR 0x27 // I2C address LCD
|
|
#define LCDADDR 0x27 // I2C address LCD
|
|
|
|
+#define LCDCOLS 16
|
|
|
|
+#define LCDLINES 2
|
|
|
|
|
|
|
|
|
|
-#define DEBUG_SERIAL //uncomment for Serial debugging statements
|
|
|
|
|
|
+// default logic levels
|
|
|
|
+#define RELAISONSTATE LOW
|
|
|
|
+#define BUTTONONSTATE LOW
|
|
|
|
|
|
-#ifdef DEBUG_SERIAL
|
|
|
|
-#define DEBUG_BEGIN Serial.begin(115200)
|
|
|
|
-#define DEBUG_PRINT(x) Serial.println(x)
|
|
|
|
-#else
|
|
|
|
-#define DEBUG_PRINT(x)
|
|
|
|
-#define DEBUG_BEGIN
|
|
|
|
-#endif
|
|
|
|
|
|
|
|
-#include "PersWiFiManager.h"
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
+#include "PersWiFiManager.h"
|
|
#include <ArduinoJson.h>
|
|
#include <ArduinoJson.h>
|
|
#include <ESP8266WiFi.h>
|
|
#include <ESP8266WiFi.h>
|
|
#include <WiFiClient.h>
|
|
#include <WiFiClient.h>
|
|
@@ -37,96 +56,129 @@
|
|
#include <ESP8266mDNS.h>
|
|
#include <ESP8266mDNS.h>
|
|
#include <ESP8266HTTPUpdateServer.h>
|
|
#include <ESP8266HTTPUpdateServer.h>
|
|
#include "PubSubClient.h"
|
|
#include "PubSubClient.h"
|
|
-
|
|
|
|
|
|
+#include <DNSServer.h>
|
|
|
|
+#include <FS.h>
|
|
#include <Wire.h>
|
|
#include <Wire.h>
|
|
#include "LiquidCrystal_I2C.h"
|
|
#include "LiquidCrystal_I2C.h"
|
|
|
|
+#include "DHT.h"
|
|
|
|
|
|
-#include <DNSServer.h>
|
|
|
|
-#include <FS.h>
|
|
|
|
|
|
|
|
-//#include <AS_BH1750.h> // BH1750 lux sensor
|
|
|
|
-#include "DHT.h"
|
|
|
|
|
|
+#ifndef MESSZ
|
|
|
|
+#define MESSZ 405 // Max number of characters in JSON message string (4 x DS18x20 sensors)
|
|
|
|
+#endif
|
|
|
|
+// Max message size calculated by PubSubClient is (MQTT_MAX_PACKET_SIZE < 5 + 2 + strlen(topic) + plength)
|
|
|
|
+#if (MQTT_MAX_PACKET_SIZE -TOPSZ -7) < MESSZ // If the max message size is too small, throw an error at compile time
|
|
|
|
+// See pubsubclient.c line 359
|
|
|
|
+#error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 512"
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// config variables - do not change here!
|
|
|
|
+//conf
|
|
|
|
+char deviceName[31]; // device name - just for web interface
|
|
|
|
+char http_user[31];
|
|
|
|
+char http_pass[31];
|
|
|
|
+char mqtt_server[41];
|
|
|
|
+int mqtt_port = MQTT_PORT;
|
|
|
|
+char mqtt_user[31];
|
|
|
|
+char mqtt_pass[31];
|
|
|
|
+char mqtt_topic_in[51]; // MQTT in topic for commands
|
|
|
|
+char mqtt_topic_out[51]; // MQTT out base topic, will be extended by various value names
|
|
|
|
+boolean mqtt_outRetain = false; // send MQTT out with retain flag
|
|
|
|
+char mqtt_willTopic[51]; // MQTT Last Will topic
|
|
|
|
+int mqtt_willQos = 2; // MQTT Last Will topic QOS
|
|
|
|
+boolean mqtt_willRetain = false; // MQTT Last Will retain
|
|
|
|
+char mqtt_willMsg[31]; // MQTT Last Will payload
|
|
|
|
+char domoticz_out_topic[55]; // domoticz out topic to subscribe to (only applicable if domoticzIdx_Thermostat and/or domoticzIdx_ThermostatMode is set to >0)
|
|
|
|
+
|
|
|
|
+//conf2
|
|
|
|
+int domoticzIdx_Thermostat = 0;
|
|
|
|
+int domoticzIdx_ThermostatMode = 0;
|
|
|
|
+int domoticzIdx_TempHumSensor = 0;
|
|
|
|
+int domoticzIdx_PIR = 0;
|
|
|
|
+char outTemp_topic_in[51];
|
|
|
|
+char outHum_topic_in[51];
|
|
|
|
+bool autoSaveSetTemp = true;
|
|
|
|
+bool autoSaveHeatingMode = true;
|
|
|
|
+int heatingMinOffTime = 10; // minimal time the heating keeps turned off in s
|
|
|
|
+float setTempMin = 14.0; // minimal temperature that can be set
|
|
|
|
+float setTempMax = 29.0; // maximal temperature that can be set
|
|
|
|
+float setTempLow = 18.0; // set temperature in night/low mode
|
|
|
|
+float hysteresis = 0.5;
|
|
|
|
+float tempCorrVal = 0.0; // correction value for temperature sensor reading
|
|
|
|
+int humCorrVal = 0; // correction value for humidity sensor reading
|
|
|
|
+int measureInterval = 15; // interval for temp/hum measurement
|
|
|
|
+int displayInterval = 5; //
|
|
|
|
+int displayTimeout = 120;
|
|
|
|
+
|
|
|
|
|
|
|
|
+//set values
|
|
|
|
+float setTemp = 21.5;
|
|
|
|
+byte heatingMode = 1; // 0 = off, 1 = normal/day, 2 = night/reduction
|
|
|
|
|
|
|
|
+float setTempSaved;
|
|
|
|
+byte heatingModeSaved; // 0 = off, 1 = normal/day, 2 = night/reduction
|
|
|
|
+
|
|
|
|
+// not changeable via configuration
|
|
|
|
+float setTempLowMin = 14.0;
|
|
|
|
+float setTempLowMax = 19.0;
|
|
|
|
+boolean debug = true;
|
|
|
|
+int debounceTime = BUTTON_DEBOUNCE_TIME;
|
|
|
|
+int buttonHoldTime = BUTTON_HOLD_TIME;
|
|
|
|
|
|
// global variables
|
|
// global variables
|
|
-float humidity, temperature;
|
|
|
|
-bool turnHeatingOn = false;
|
|
|
|
-bool heatingEnabled = true;
|
|
|
|
-byte heatingMode = 1; // 0 = off, 1 = default/day, 2 = night/reduction
|
|
|
|
-
|
|
|
|
-float setTemp;
|
|
|
|
-long heatingLastOnMillis;
|
|
|
|
-long heatingLastOffMillis;
|
|
|
|
-
|
|
|
|
-float aTemp, aHum;
|
|
|
|
-long aTempHumLastUpdate;
|
|
|
|
-byte whichTempToDisplay; // 1=temp inside (from DHT sensor), 2= temp outside (via MQTT)
|
|
|
|
-
|
|
|
|
-long lastMeasure = 0;
|
|
|
|
-long lastDisplayUpdate = 0;
|
|
|
|
-long lastDisplayToggle = 0;
|
|
|
|
-long lastTempUpdate = 0;
|
|
|
|
|
|
+float temperature; // last reading from DHT sensor
|
|
|
|
+int humidity; // last reading from DHT sensor
|
|
|
|
+bool turnHeatingOn = false; // true if heating is active (relais switched on)
|
|
|
|
+unsigned long heatingLastOnMillis; // last time heating was switched on
|
|
|
|
+unsigned long heatingLastOffMillis; // last time heating was switched off
|
|
|
|
+float outTemp; // outside temp (via MQTT if enabled and in-topic configured)
|
|
|
|
+int outHum; // outside temp (via MQTT if enabled and in-topic configured)
|
|
|
|
+long outTempHumLastUpdate; // last reading from out temp/hum source
|
|
|
|
+byte whichTempToDisplay; // 1=temp inside (from DHT sensor), 2= temp outside (via MQTT) - if out temp/hum available this value and the displayed value pair toggles with every displayInterval
|
|
|
|
+unsigned long lastMeasure = 0; // millis of last temp/hum measurement
|
|
|
|
+unsigned long lastDisplayUpdate = 0; // millis of last display update
|
|
|
|
+unsigned long lastDisplayToggle = 0; // millis of last display toggle
|
|
|
|
+unsigned long lastTempUpdate = 0; // last update time of DHT reading
|
|
char msg[50]; // buffer MQTT in payload
|
|
char msg[50]; // buffer MQTT in payload
|
|
char topic[50]; // buffer MQTT in topic
|
|
char topic[50]; // buffer MQTT in topic
|
|
|
|
+bool displayActive = false; // gets true when button is pressed. display light gets switched on until timeout. button actions are only performed while display is active
|
|
|
|
|
|
-// global variables from other modules
|
|
|
|
-//extern bool displayActive;
|
|
|
|
-bool displayActive = false;
|
|
|
|
-
|
|
|
|
-// functions from other modules/files
|
|
|
|
-//extern void httpServerHandleNotFound();
|
|
|
|
-//extern void httpServerHandleRoot();
|
|
|
|
-//extern void enableDisplay();
|
|
|
|
-//extern void disableDisplay();
|
|
|
|
-//extern void extendDisplayTimeout();
|
|
|
|
-//extern void handleDisplayTimeout();
|
|
|
|
-//extern void updateDisplay();
|
|
|
|
-//extern void initDisplay();
|
|
|
|
-//extern void plusButtonAction();
|
|
|
|
-//extern void minusButtonAction();
|
|
|
|
-//extern void modeButtonAction();
|
|
|
|
-//extern void modeButtonHoldAction();
|
|
|
|
-//extern void checkButtonStates();
|
|
|
|
-
|
|
|
|
-// config variables
|
|
|
|
-
|
|
|
|
-const char* mqtt_server = "10.1.1.11";
|
|
|
|
-const int mqtt_port = 1883;
|
|
|
|
-long minOffTime = 10; // s
|
|
|
|
-
|
|
|
|
-float setTempDay = 21.5;
|
|
|
|
-float setTempNight = 18.0;
|
|
|
|
-float setTempMin = 14.0;
|
|
|
|
-float setTempMax = 29.0;
|
|
|
|
-float setTempMinLow = 10.0;
|
|
|
|
-float setTempMaxLow = 19.0;
|
|
|
|
-float hysteresis = 0.5;
|
|
|
|
-int measureinterval = 60000; // ms
|
|
|
|
-int displayinterval = 5000;
|
|
|
|
-int displayTimeout = 60000;
|
|
|
|
-
|
|
|
|
|
|
+unsigned long heatingOnTime, heatingOffTime;
|
|
|
|
|
|
-//const char* mqtt_topic_prefix = "Test/Thermostat/";
|
|
|
|
-const char* mqtt_topic_temp = "Test/Thermostat/Temp";
|
|
|
|
-const char* mqtt_topic_settemp = "Test/Thermostat/SetTemp";
|
|
|
|
-//const char* mqtt_topic_setmode = "Test/Thermostat/SetMode";
|
|
|
|
-const char* mqtt_topic_hum = "Test/Thermostat/Hum";
|
|
|
|
-const char* mqtt_topic_lux = "Test/Thermostat/Lux";
|
|
|
|
-const char* mqtt_topic_heating = "Test/Thermostat/Heating";
|
|
|
|
-const char* mqtt_topic_heating_lastofftime = "Test/Thermostat/HeatingLastOffTime";
|
|
|
|
-const char* mqtt_topic_heating_lastontime = "Test/Thermostat/HeatingLastOnTime";
|
|
|
|
-
|
|
|
|
-const char* mqtt_topic_in = "Test/Thermostat/in"; // subscribe topic
|
|
|
|
|
|
+boolean useDomoticz = false; // will be set to true in setup() if idx-values other than 0 are configured
|
|
|
|
+boolean domoticzOutParseData = false; // indicates that domoticz/out json data is buffered, will then be parsed in next loop() run
|
|
|
|
+boolean domoticzOutParserBusy = false; // indicates that domoticz/out json data is currently processed - no futher data will be accepted until finished
|
|
|
|
+char domoticzOutPayload[450]; // buffer for domoticz/out data
|
|
|
|
+int dismissUpdateFromDomoticzTimeout = 2500; // after a value was changed by data from domoticz/out, domoticz/out parsing for this device will be turned off for this time to prevent infinite loops
|
|
|
|
+unsigned long lastUpdate_setTemp = 0; // set to millis() every time setTemp value is changed. next update from domoticz/out will be rejected for dismissUpdateFromDomoticzTimeout in this case
|
|
|
|
+unsigned long lastUpdate_heatingMode = 0; // set to millis() every time heatingMode value is changed. next update from domoticz/out will be rejected for dismissUpdateFromDomoticzTimeout in this case
|
|
|
|
+bool lastUpdateFromDomoticz_setTemp = false;
|
|
|
|
+bool lastUpdateFromDomoticz_heatingMode = false;
|
|
|
|
+int domoticzUpdateInterval = 30; // interval in min to force update of domoticz devices
|
|
|
|
|
|
|
|
+char cmdPayload[101]; // buffer for commands
|
|
|
|
+boolean cmdInQueue = false; // command is queued and will be processed next loop() run
|
|
|
|
+bool saveConfigToFlash = false; // conf is saved in next loop() run
|
|
|
|
+bool saveConfig2ToFlash = false; // conf2 is saved in next loop() run
|
|
|
|
|
|
|
|
+unsigned int saveValuesTimeout = 5000;
|
|
|
|
+unsigned long lastValueChange; // is set to millis() whenever setTemp value and/or heatingMode value is changed. used for autoSave function with hardcoded 5s timeout
|
|
|
|
+bool setTempAlreadySaved = true; // only save if not yet done
|
|
|
|
+bool heatingModeAlreadySaved = true; // only save if not yet done
|
|
|
|
|
|
|
|
+byte mqttMode = 0;
|
|
|
|
+unsigned long mqttLastReconnectAttempt = 0;
|
|
|
|
+int mqttReconnects = 0;
|
|
|
|
|
|
|
|
|
|
DHT dht(PIN_DHTSENSOR, DHTTYPE);
|
|
DHT dht(PIN_DHTSENSOR, DHTTYPE);
|
|
-LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
|
|
|
|
|
+LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDLINES); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
|
|
|
|
|
WiFiClient espClient;
|
|
WiFiClient espClient;
|
|
|
|
+
|
|
|
|
+void mqttCallback(char* topic, byte* payload, unsigned int length);
|
|
PubSubClient mqttclient(espClient);
|
|
PubSubClient mqttclient(espClient);
|
|
|
|
|
|
ESP8266WebServer httpServer(80);
|
|
ESP8266WebServer httpServer(80);
|
|
@@ -136,194 +188,108 @@ PersWiFiManager persWM(httpServer, dnsServer);
|
|
ESP8266HTTPUpdateServer httpUpdater;
|
|
ESP8266HTTPUpdateServer httpUpdater;
|
|
|
|
|
|
|
|
|
|
-// MQTT callback
|
|
|
|
-void mqttCallback(char* topic, byte* payload, unsigned int length) {
|
|
|
|
- Serial.print("Message arrived [");
|
|
|
|
- Serial.print(topic);
|
|
|
|
- Serial.print("] ");
|
|
|
|
- for (int i = 0; i < length; i++) {
|
|
|
|
- Serial.print((char)payload[i]);
|
|
|
|
- }
|
|
|
|
|
|
+void setup() {
|
|
|
|
+ Serial.begin(115200);
|
|
|
|
+ delay(500);
|
|
Serial.println();
|
|
Serial.println();
|
|
|
|
+ Serial.print(FIRMWARE_NAME);
|
|
|
|
+ Serial.print(" v");
|
|
|
|
+ Serial.print(VERSION);
|
|
|
|
+ Serial.println(COPYRIGHT);
|
|
|
|
+ Serial.println("starting...");
|
|
|
|
|
|
- if (strcmp(topic, mqtt_topic_in) == 0) { //if topic = mqtt_topic_in
|
|
|
|
- Serial.println("TOPIC!!");
|
|
|
|
|
|
|
|
- char tmpPayload[length + 1];
|
|
|
|
- for (int i = 0; i < length; i++) {
|
|
|
|
- tmpPayload[i] = (char)payload[i];
|
|
|
|
- }
|
|
|
|
- tmpPayload[sizeof(tmpPayload) - 1] = '\0';
|
|
|
|
-
|
|
|
|
- Serial.print("tmpPayload:");
|
|
|
|
- Serial.println(tmpPayload);
|
|
|
|
-
|
|
|
|
- if (strncmp(tmpPayload, "set temp ", 9) == 0) {
|
|
|
|
- char inValue[length - 9 + 1];
|
|
|
|
- for (int i = 0; i < length; i++) {
|
|
|
|
- inValue[i] = (char)payload[i + 9];
|
|
|
|
- }
|
|
|
|
- inValue[sizeof(inValue) - 1] = '\0';
|
|
|
|
- Serial.print(inValue);
|
|
|
|
- Serial.println();
|
|
|
|
- float invalueFloat = round(atof(inValue) * 2.0) / 2.0;
|
|
|
|
-
|
|
|
|
- Serial.print(invalueFloat);
|
|
|
|
- if (invalueFloat >= setTempMin && invalueFloat <= setTempMax) {
|
|
|
|
- setTempDay = invalueFloat;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- else if (invalueFloat > setTempMax) {
|
|
|
|
- setTempDay = setTempMax;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- else if (invalueFloat < setTempMin) {
|
|
|
|
- setTempDay = setTempMin;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- }// if payload=="set temp "
|
|
|
|
-
|
|
|
|
- else if (strncmp(tmpPayload, "set tlow ", 9) == 0) {
|
|
|
|
- char inValue[length - 9 + 1];
|
|
|
|
- for (int i = 0; i < length; i++) {
|
|
|
|
- inValue[i] = (char)payload[i + 9];
|
|
|
|
- }
|
|
|
|
- inValue[sizeof(inValue) - 1] = '\0';
|
|
|
|
- Serial.print(inValue);
|
|
|
|
- Serial.println();
|
|
|
|
- float invalueFloat = round(atof(inValue) * 2.0) / 2.0;
|
|
|
|
-
|
|
|
|
- Serial.print(invalueFloat);
|
|
|
|
- if (invalueFloat >= setTempMinLow && invalueFloat <= setTempMaxLow) {
|
|
|
|
- setTempNight = invalueFloat;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- else if (invalueFloat > setTempMaxLow) {
|
|
|
|
- setTempNight = setTempMaxLow;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- else if (invalueFloat < setTempMinLow) {
|
|
|
|
- setTempNight = setTempMinLow;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ pinMode(PIN_RELAIS, OUTPUT);
|
|
|
|
+ digitalWrite(PIN_RELAIS, HIGH);
|
|
|
|
+ pinMode(PIN_BUTTON_PLUS, INPUT_PULLUP);
|
|
|
|
+ pinMode(PIN_BUTTON_MINUS, INPUT_PULLUP);
|
|
|
|
+ pinMode(PIN_BUTTON_MODE, INPUT_PULLUP);
|
|
|
|
|
|
- else if (strncmp(tmpPayload, "set mode ", 9) == 0) {
|
|
|
|
- if ((char)payload[9] == '1') {
|
|
|
|
- // switch to mode default/day
|
|
|
|
- heatingMode = 1;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- else if ((char)payload[9] == '2') {
|
|
|
|
- // switch to mode night/reduction
|
|
|
|
- heatingMode = 2;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
- else if (strncmp(tmpPayload, "set enab ", 9) == 0) {
|
|
|
|
- if ((char)payload[9] == '0') {
|
|
|
|
- // switch heating off
|
|
|
|
- heatingEnabled = false;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- else if ((char)payload[9] == '1') {
|
|
|
|
- // switch heating on
|
|
|
|
- heatingEnabled = true;
|
|
|
|
- updateDisplay();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }//if topic = mqtt_topic_in
|
|
|
|
|
|
+ strlcpy(deviceName, DEVICE_NAME, 31);
|
|
|
|
+ strlcpy(mqtt_server, MQTT_SERVER, 41);
|
|
|
|
+ strlcpy(mqtt_topic_in, MQTT_TOPIC_IN, 51);
|
|
|
|
+ strlcpy(mqtt_topic_out, MQTT_TOPIC_OUT, 51);
|
|
|
|
+ strlcpy(domoticz_out_topic, DOMOTICZ_OUT_TOPIC, 51); // changeable subscription topic, as domoticz supports different flat/hierarchical out-topics
|
|
|
|
+ strlcpy(outTemp_topic_in, OUTTEMP_TOPIC_IN, 51);
|
|
|
|
+ strlcpy(outHum_topic_in, OUTHUM_TOPIC_IN, 51);
|
|
|
|
|
|
- if (strcmp(topic, "wetter/atemp") == 0) { //if topic = "wetter/atemp"
|
|
|
|
- char inValue[length + 1];
|
|
|
|
- for (int i = 0; i < length; i++) {
|
|
|
|
- inValue[i] = (char)payload[i];
|
|
|
|
- }
|
|
|
|
- inValue[sizeof(inValue) - 1] = '\0';
|
|
|
|
- //Serial.print(inValue);
|
|
|
|
- //Serial.println();
|
|
|
|
- float invalueFloat = atof(inValue);
|
|
|
|
- aTemp = invalueFloat;
|
|
|
|
- aTempHumLastUpdate = millis();
|
|
|
|
- //Serial.print("atemp=");
|
|
|
|
- //Serial.println(invalueFloat);
|
|
|
|
- }//if topic = "wetter/atemp"
|
|
|
|
-
|
|
|
|
- if (strcmp(topic, "wetter/ahum") == 0) { //if topic = "wetter/atemp"
|
|
|
|
- char inValue[length + 1];
|
|
|
|
- for (int i = 0; i < length; i++) {
|
|
|
|
- inValue[i] = (char)payload[i];
|
|
|
|
|
|
+ Serial.println("default config values loaded..");
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ Serial.println("Mounting FS...");
|
|
|
|
+ if (!SPIFFS.begin()) {
|
|
|
|
+ Serial.println("Failed to mount file system");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //SPIFFS.format();
|
|
|
|
+ //Serial.print("Format SPIFFS complete.");
|
|
|
|
+
|
|
|
|
+ if (!SPIFFS.exists("/formatComplete.txt")) {
|
|
|
|
+ Serial.println("Please wait 30 secs for SPIFFS to be formatted");
|
|
|
|
+ SPIFFS.format();
|
|
|
|
+ Serial.println("Spiffs formatted");
|
|
|
|
+
|
|
|
|
+ File f = SPIFFS.open("/formatComplete.txt", "w");
|
|
|
|
+ if (!f) {
|
|
|
|
+ Serial.println("file open failed");
|
|
|
|
+ } else {
|
|
|
|
+ f.println("Format Complete");
|
|
}
|
|
}
|
|
- inValue[sizeof(inValue) - 1] = '\0';
|
|
|
|
- //Serial.print(inValue);
|
|
|
|
- //Serial.println();
|
|
|
|
- float invalueFloat = atof(inValue);
|
|
|
|
- aHum = invalueFloat;
|
|
|
|
- aTempHumLastUpdate = millis();
|
|
|
|
- //Serial.println("ahum=");
|
|
|
|
- //Serial.println(invalueFloat);
|
|
|
|
- }//if topic = "wetter/ahum"
|
|
|
|
-
|
|
|
|
-}//mqttCallback
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-long mqttLastReconnectAttempt = 0;
|
|
|
|
-
|
|
|
|
-boolean mqttReconnect() {
|
|
|
|
- // Create a random MQTT client ID
|
|
|
|
- String mqttClientId = "ESP8266Client-";
|
|
|
|
- mqttClientId += String(random(0xffff), HEX);
|
|
|
|
- if (mqttclient.connect(mqttClientId.c_str())) {
|
|
|
|
- Serial.println("connected");
|
|
|
|
- // Once connected, publish an announcement...
|
|
|
|
- //mqttclient.publish("TestoutTopic", "hello world");
|
|
|
|
- // ... and resubscribe
|
|
|
|
- mqttclient.subscribe(mqtt_topic_in);
|
|
|
|
- mqttclient.subscribe("wetter/atemp");
|
|
|
|
- mqttclient.subscribe("wetter/ahum");
|
|
|
|
|
|
+ f.close();
|
|
|
|
+ } else {
|
|
|
|
+ Serial.println("SPIFFS is formatted. Moving along...");
|
|
}
|
|
}
|
|
- return mqttclient.connected();
|
|
|
|
-} //mqttReconnect
|
|
|
|
|
|
|
|
|
|
|
|
-void setup() {
|
|
|
|
- DEBUG_BEGIN; //for terminal debugging
|
|
|
|
- DEBUG_PRINT();
|
|
|
|
|
|
+ // // load config from SPIFFS if files exist
|
|
|
|
+ if (!loadConfig()) {
|
|
|
|
+ Serial.println("Failed to load conf.json");
|
|
|
|
+ } else {
|
|
|
|
+ Serial.println("conf.json loaded");
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ if (!loadConfig2()) {
|
|
|
|
+ Serial.println("Failed to load conf2.json");
|
|
|
|
+ } else {
|
|
|
|
+ Serial.println("conf2.json loaded");
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ if (!loadSetTemp()) {
|
|
|
|
+ Serial.println("Failed to load file 'setTemp'");
|
|
|
|
+ } else {
|
|
|
|
+ Serial.println("file 'setTemp' loaded");
|
|
|
|
+ }
|
|
|
|
|
|
- Serial.print("WiFi Thermostat v");
|
|
|
|
- Serial.print(VERSION);
|
|
|
|
- Serial.println(" by Flo Kra");
|
|
|
|
- Serial.println("starting...");
|
|
|
|
|
|
+ if (!loadHeatingMode()) {
|
|
|
|
+ Serial.println("Failed to load file 'heatingMode'");
|
|
|
|
+ } else {
|
|
|
|
+ Serial.println("file 'heatingMode' loaded");
|
|
|
|
+ }
|
|
|
|
|
|
- pinMode(PIN_RELAIS, OUTPUT);
|
|
|
|
- digitalWrite(PIN_RELAIS, HIGH);
|
|
|
|
- pinMode(PIN_BUTTON_PLUS, INPUT_PULLUP);
|
|
|
|
- pinMode(PIN_BUTTON_MINUS, INPUT_PULLUP);
|
|
|
|
- pinMode(PIN_BUTTON_MODE, INPUT_PULLUP);
|
|
|
|
|
|
+ setTempSaved = setTemp;
|
|
|
|
+ heatingModeSaved = heatingMode;
|
|
|
|
|
|
// initialize DHT11/22 temp/hum sensor
|
|
// initialize DHT11/22 temp/hum sensor
|
|
dht.begin();
|
|
dht.begin();
|
|
|
|
|
|
|
|
+ checkUseDomoticz();
|
|
|
|
+ delay(500);
|
|
|
|
+
|
|
|
|
|
|
//optional code handlers to run everytime wifi is connected...
|
|
//optional code handlers to run everytime wifi is connected...
|
|
persWM.onConnect([]() {
|
|
persWM.onConnect([]() {
|
|
- DEBUG_PRINT("wifi connected");
|
|
|
|
- DEBUG_PRINT(WiFi.SSID());
|
|
|
|
- DEBUG_PRINT(WiFi.localIP());
|
|
|
|
|
|
+ Serial.println("wifi connected");
|
|
|
|
+ Serial.println(WiFi.SSID());
|
|
|
|
+ Serial.println(WiFi.localIP());
|
|
});
|
|
});
|
|
//...or AP mode is started
|
|
//...or AP mode is started
|
|
persWM.onAp([]() {
|
|
persWM.onAp([]() {
|
|
- DEBUG_PRINT("AP MODE");
|
|
|
|
- DEBUG_PRINT(persWM.getApSsid());
|
|
|
|
|
|
+ Serial.println("AP MODE");
|
|
|
|
+ Serial.println(persWM.getApSsid());
|
|
});
|
|
});
|
|
|
|
|
|
- //allows serving of files from SPIFFS
|
|
|
|
- //SPIFFS.begin();
|
|
|
|
- //SPIFFS.format();
|
|
|
|
//sets network name for AP mode
|
|
//sets network name for AP mode
|
|
persWM.setApCredentials(DEVICE_NAME);
|
|
persWM.setApCredentials(DEVICE_NAME);
|
|
//persWM.setApCredentials(DEVICE_NAME, "password"); optional password
|
|
//persWM.setApCredentials(DEVICE_NAME, "password"); optional password
|
|
@@ -333,402 +299,44 @@ void setup() {
|
|
|
|
|
|
//in non-blocking mode, program will continue past this point without waiting
|
|
//in non-blocking mode, program will continue past this point without waiting
|
|
persWM.begin();
|
|
persWM.begin();
|
|
|
|
+ delay(500);
|
|
|
|
|
|
- //handles commands from webpage, sends live data in JSON format
|
|
|
|
- httpServer.on("/api", []() {
|
|
|
|
- DEBUG_PRINT("httpServer.on /api");
|
|
|
|
- if (httpServer.hasArg("plusBtn")) {
|
|
|
|
- plusButtonAction();
|
|
|
|
- DEBUG_PRINT(P("web plusBtn"));
|
|
|
|
- } //if
|
|
|
|
- if (httpServer.hasArg("minusBtn")) {
|
|
|
|
- minusButtonAction();
|
|
|
|
- DEBUG_PRINT(P("web minusBtn"));
|
|
|
|
- } //if
|
|
|
|
- if (httpServer.hasArg("modeBtn")) {
|
|
|
|
- modeButtonAction();
|
|
|
|
- DEBUG_PRINT(P("web modeBtn"));
|
|
|
|
- } //if
|
|
|
|
- if (httpServer.hasArg("onoffBtn")) {
|
|
|
|
- modeButtonHoldAction();
|
|
|
|
- DEBUG_PRINT(P("web onoffBtn"));
|
|
|
|
- } //if
|
|
|
|
-
|
|
|
|
- //build json object of program data
|
|
|
|
- StaticJsonBuffer<200> jsonBuffer;
|
|
|
|
- JsonObject &json = jsonBuffer.createObject();
|
|
|
|
- json["ssid"] = WiFi.SSID();
|
|
|
|
- json["setTemp"] = setTempDay;
|
|
|
|
- json["temp"] = temperature;
|
|
|
|
- json["hum"] = int(humidity);
|
|
|
|
- json["mode"] = heatingMode;
|
|
|
|
- json["heatingEnabled"] = heatingEnabled;
|
|
|
|
- json["heating"] = turnHeatingOn;
|
|
|
|
-
|
|
|
|
- char jsonchar[200];
|
|
|
|
- json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
|
|
|
|
- httpServer.send(200, "application/json", jsonchar);
|
|
|
|
-
|
|
|
|
- }); //httpServer.on /api
|
|
|
|
-
|
|
|
|
- //get heap status, analog input value and all GPIO statuses in one json call
|
|
|
|
- httpServer.on("/info", HTTP_GET, []() {
|
|
|
|
- String json = "{";
|
|
|
|
- json += "\"wifissid\":\"" + WiFi.SSID() + "\"";
|
|
|
|
- json += "\"heap\":" + String(ESP.getFreeHeap());
|
|
|
|
- //json += ", \"analog\":" + String(analogRead(A0));
|
|
|
|
- //json += ", \"gpio\":" + String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
|
|
|
|
- json += "}";
|
|
|
|
- httpServer.send(200, "text/json", json);
|
|
|
|
- json = String();
|
|
|
|
- }); //httpServer.on /info
|
|
|
|
-
|
|
|
|
- httpServer.on("/", []() {
|
|
|
|
- httpServerHandleRoot();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- httpServer.on("/config", []() {
|
|
|
|
- httpServerHandleConfPage();
|
|
|
|
- });
|
|
|
|
|
|
+ httpServerInit();
|
|
|
|
|
|
- httpServer.onNotFound([]() {
|
|
|
|
- httpServerHandleNotFound();
|
|
|
|
- }); //httpServer.onNotFound
|
|
|
|
-
|
|
|
|
- // HTTP Updater at /update
|
|
|
|
- httpUpdater.setup(&httpServer);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- httpServer.begin();
|
|
|
|
-
|
|
|
|
- DEBUG_PRINT("setup complete.");
|
|
|
|
-
|
|
|
|
- mqttclient.setServer(mqtt_server, mqtt_port);
|
|
|
|
- mqttclient.setCallback(mqttCallback);
|
|
|
|
- mqttLastReconnectAttempt = 0;
|
|
|
|
|
|
+ mqttPrepareConnection();
|
|
|
|
+ mqttClientInit();
|
|
|
|
|
|
initDisplay();
|
|
initDisplay();
|
|
|
|
|
|
|
|
+ Serial.println("setup complete.");
|
|
|
|
+ delay(1000);
|
|
} //void setup
|
|
} //void setup
|
|
|
|
|
|
void loop() {
|
|
void loop() {
|
|
- persWM.handleWiFi(); //in non-blocking mode, handleWiFi must be called in the main loop
|
|
|
|
|
|
+ checkMillis();
|
|
|
|
|
|
|
|
+ persWM.handleWiFi(); //in non-blocking mode, handleWiFi must be called in the main loop
|
|
|
|
+ yield();
|
|
dnsServer.processNextRequest();
|
|
dnsServer.processNextRequest();
|
|
httpServer.handleClient();
|
|
httpServer.handleClient();
|
|
|
|
|
|
- // MQTT reconnect if not connected (nonblocking)
|
|
|
|
- if (!mqttclient.connected()) {
|
|
|
|
- long now = millis();
|
|
|
|
-
|
|
|
|
- if (now - mqttLastReconnectAttempt > 5000) {
|
|
|
|
- mqttLastReconnectAttempt = now;
|
|
|
|
- // Attempt to reconnect
|
|
|
|
- if (mqttReconnect()) {
|
|
|
|
- mqttLastReconnectAttempt = 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- // Client connected
|
|
|
|
- mqttclient.loop();
|
|
|
|
- }//else
|
|
|
|
|
|
+ mqttHandleConnection();
|
|
|
|
|
|
checkButtonStates();
|
|
checkButtonStates();
|
|
- handleDisplayTimeout();
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- // set target temp for heating mode
|
|
|
|
- if (heatingMode == 1) { // heating on - default/day mode
|
|
|
|
- setTemp = setTempDay;
|
|
|
|
- }
|
|
|
|
- else if (heatingMode == 2) { // heating of - night/reduction mode
|
|
|
|
- setTemp = setTempNight;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- if ( (millis() - lastMeasure) > measureinterval) {
|
|
|
|
- lastMeasure = millis();
|
|
|
|
-
|
|
|
|
- float tmpHum = round(dht.readHumidity());
|
|
|
|
- float tmpTemp = dht.readTemperature(); // Read temperature as Celsius (the default)
|
|
|
|
-
|
|
|
|
- // Check if any reads failed
|
|
|
|
- if (isnan(tmpHum) || isnan(tmpTemp)) {
|
|
|
|
- Serial.println("Failed to read from DHT sensor!");
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- if (tmpTemp < 50.0 && tmpTemp > -20.0) {
|
|
|
|
- temperature = tmpTemp;
|
|
|
|
- humidity = tmpHum;
|
|
|
|
- lastTempUpdate = millis();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- unsigned long heatingOnTime, heatingOffTime;
|
|
|
|
- if (heatingEnabled && turnHeatingOn) {
|
|
|
|
- heatingOnTime = (millis() - heatingLastOffMillis) / 1000;
|
|
|
|
- Serial.print("heatingOnTime: ");
|
|
|
|
- Serial.print(heatingOnTime);
|
|
|
|
- Serial.println();
|
|
|
|
- }
|
|
|
|
- else if (heatingEnabled && !turnHeatingOn) {
|
|
|
|
- heatingOffTime = (millis() - heatingLastOnMillis) / 1000;
|
|
|
|
- Serial.print("heatingOffTime: ");
|
|
|
|
- Serial.print(heatingOffTime);
|
|
|
|
- Serial.println();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- Serial.print("lastTempUpdate: ");
|
|
|
|
- Serial.println(lastTempUpdate);
|
|
|
|
-
|
|
|
|
- long test1 = millis() - lastTempUpdate;
|
|
|
|
- Serial.print("lastTempUpdate test1: ");
|
|
|
|
- Serial.println(test1);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- if ( (millis() - lastTempUpdate) < 120000 ) {
|
|
|
|
- // thermostat - only active if measured temperature is < 2 min old
|
|
|
|
-
|
|
|
|
- // thermostat with hysteresis
|
|
|
|
- if ( temperature >= setTemp ) {
|
|
|
|
- turnHeatingOn = false;
|
|
|
|
- heatingLastOnMillis = millis();
|
|
|
|
- digitalWrite(PIN_RELAIS, !RELAISONSTATE);
|
|
|
|
- updateDisplay();
|
|
|
|
- Serial.println("heating off");
|
|
|
|
-
|
|
|
|
- Serial.print("last onTime: ");
|
|
|
|
- Serial.print(heatingOnTime);
|
|
|
|
- Serial.println();
|
|
|
|
-
|
|
|
|
- mqttclient.publish(mqtt_topic_heating, "off");
|
|
|
|
-
|
|
|
|
- //mqttclient.publish(mqtt_topic_heating_lastontime, heatingOnTime);
|
|
|
|
- }
|
|
|
|
- else if ( heatingEnabled && ( temperature < (setTemp - hysteresis) ) && ( heatingOffTime > minOffTime ) ) {
|
|
|
|
- turnHeatingOn = true;
|
|
|
|
- digitalWrite(PIN_RELAIS, RELAISONSTATE);
|
|
|
|
- updateDisplay();
|
|
|
|
- Serial.println("heating on");
|
|
|
|
-
|
|
|
|
- Serial.print("last offTime: ");
|
|
|
|
- Serial.print(heatingOffTime);
|
|
|
|
- Serial.println();
|
|
|
|
-
|
|
|
|
- mqttclient.publish(mqtt_topic_heating, "on");
|
|
|
|
-
|
|
|
|
- //mqttclient.publish(mqtt_topic_heating_lastofftime, heatingOffTime);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- turnHeatingOn = false;
|
|
|
|
- digitalWrite(PIN_RELAIS, !RELAISONSTATE);
|
|
|
|
- Serial.println("heating off");
|
|
|
|
- mqttclient.publish(mqtt_topic_heating, "off");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
+ yield();
|
|
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- // if (lightMeter_present) {
|
|
|
|
- // delay(50);
|
|
|
|
- // lux = lightMeter.readLightLevel();
|
|
|
|
- //
|
|
|
|
- // String lux_str = String(lux, 1); //converting humidity (the float variable above) to a string with 0 decimals
|
|
|
|
- // char lux_chararr[lux_str.length() + 1];
|
|
|
|
- // lux_str.toCharArray(lux_chararr, lux_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
- //
|
|
|
|
- // Serial.print("Lux: ");
|
|
|
|
- // Serial.println(lux_str);
|
|
|
|
- // mqttclient.publish(mqtt_topic_lux, lux_chararr);
|
|
|
|
- // }
|
|
|
|
|
|
+ evalCmd();
|
|
|
|
|
|
-
|
|
|
|
- long now = millis();
|
|
|
|
- if ( ((now - aTempHumLastUpdate) < 300000) && whichTempToDisplay == 1 && ((now - lastDisplayToggle) > displayinterval) ) {
|
|
|
|
- // A-temp has been updated < 5 min ago, last displayed temp was I and display interval is overdue
|
|
|
|
- whichTempToDisplay = 2; // 1= I, 2= A
|
|
|
|
- lastDisplayToggle = now;
|
|
|
|
- }
|
|
|
|
- else if ( whichTempToDisplay != 1 && ((now - lastDisplayToggle) > displayinterval) ) {
|
|
|
|
- whichTempToDisplay = 1; // 1= I, 2= A
|
|
|
|
- lastDisplayToggle = now;
|
|
|
|
|
|
+ if ( domoticzOutParseData ) {
|
|
|
|
+ parseDomoticzOut();
|
|
|
|
+ yield();
|
|
}
|
|
}
|
|
|
|
|
|
- // update display?
|
|
|
|
- if ( (now - lastDisplayUpdate) > displayinterval) {
|
|
|
|
- lastDisplayUpdate = now;
|
|
|
|
-
|
|
|
|
- // char temp_chararr[6];
|
|
|
|
- // char hum_chararr[3];
|
|
|
|
- // if ( (millis() - lastTempUpdate) < 120000) {
|
|
|
|
- // String temp_str = String(temperature, 1); //converting Temperature (the float variable above) to a string with 1 decimal
|
|
|
|
- // //char temp_chararr[temp_str.length() + 1];
|
|
|
|
- // temp_str.toCharArray(temp_chararr, temp_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
- //
|
|
|
|
- // String hum_str = String(humidity, 0); //converting humidity (the float variable above) to a string with 0 decimals
|
|
|
|
- // //char hum_chararr[hum_str.length() + 1];
|
|
|
|
- // hum_str.toCharArray(hum_chararr, hum_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
- //
|
|
|
|
- // mqttclient.publish(mqtt_topic_temp, temp_chararr);
|
|
|
|
- // mqttclient.publish(mqtt_topic_hum, hum_chararr);
|
|
|
|
- // }
|
|
|
|
- // else {
|
|
|
|
- // char temp_chararr[] = {'-', '-', ',', '-', '\0'};
|
|
|
|
- // char hum_chararr[] = {'-', '-', '\0'};
|
|
|
|
- // }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- String temp_str = String(temperature, 1); //converting Temperature (the float variable above) to a string with 1 decimal
|
|
|
|
- char temp_chararr[temp_str.length() + 1];
|
|
|
|
- temp_str.toCharArray(temp_chararr, temp_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
-
|
|
|
|
- String hum_str = String(humidity, 0); //converting humidity (the float variable above) to a string with 0 decimals
|
|
|
|
- char hum_chararr[hum_str.length() + 1];
|
|
|
|
- hum_str.toCharArray(hum_chararr, hum_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
-
|
|
|
|
- if ( (now - lastTempUpdate) < 120000 ) {
|
|
|
|
- mqttclient.publish(mqtt_topic_temp, temp_chararr);
|
|
|
|
- mqttclient.publish(mqtt_topic_hum, hum_chararr);
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- temp_str = "--.-";
|
|
|
|
- hum_str = "--";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- String atemp_str = String(aTemp, 1); //converting Temperature (the float variable above) to a string with 1 decimal
|
|
|
|
- char atemp_chararr[atemp_str.length() + 1];
|
|
|
|
- atemp_str.toCharArray(atemp_chararr, atemp_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
-
|
|
|
|
- String ahum_str = String(aHum, 0); //converting humidity (the float variable above) to a string with 0 decimals
|
|
|
|
- char ahum_chararr[ahum_str.length() + 1];
|
|
|
|
- ahum_str.toCharArray(ahum_chararr, ahum_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- char setTemp_chararr[5]; //result string 4 positions + \0 at the end
|
|
|
|
- // convert float to fprintf type string format 2 positions with 1 decimal place
|
|
|
|
- dtostrf(setTemp, 2, 1, setTemp_chararr );
|
|
|
|
-
|
|
|
|
- Serial.print("set temp: ");
|
|
|
|
- Serial.println(setTemp_chararr);
|
|
|
|
- Serial.print("current temp: ");
|
|
|
|
- Serial.println(temp_chararr);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- mqttclient.publish(mqtt_topic_settemp, setTemp_chararr);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- if (whichTempToDisplay == 2) {
|
|
|
|
- // print inside temperature incl = and ° symbol + humidity to lcd, line 1, first 11 chars
|
|
|
|
- lcd.setCursor(0, 0);
|
|
|
|
- //lcd.write(0x3D); // = Zeichen
|
|
|
|
- lcd.print("A");
|
|
|
|
-
|
|
|
|
- if (aTemp <= -10);
|
|
|
|
- else if (aTemp < 0) lcd.print(" ");
|
|
|
|
- else if (aTemp < 10) lcd.print(" ");
|
|
|
|
- else lcd.print(" ");
|
|
|
|
-
|
|
|
|
- lcd.print(atemp_str); // inside temperature should hopefully always be 2.1 chars, so no special formatting necessary
|
|
|
|
- lcd.write(0xDF); // degree symbol
|
|
|
|
- lcd.print(" ");
|
|
|
|
-
|
|
|
|
- //lcd.print(humstr2);
|
|
|
|
- lcd.print(ahum_str); // always 2 chars
|
|
|
|
- lcd.print("%");
|
|
|
|
- lcd.print(" ");
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- // print outside temperature incl = and ° symbol + humidity to lcd, line 1, first 11 chars
|
|
|
|
- lcd.setCursor(0, 0);
|
|
|
|
- //lcd.write(0x3D); // = Zeichen
|
|
|
|
- lcd.print("I");
|
|
|
|
-
|
|
|
|
- //lcd.print(" "); // inside temperature should hopefully always be 2.1 chars, so no special formatting/spaces handling necessary
|
|
|
|
-
|
|
|
|
- if (temperature <= -10);
|
|
|
|
- else if (temperature < 0) lcd.print(" ");
|
|
|
|
- else if (temperature < 10) lcd.print(" ");
|
|
|
|
- else lcd.print(" ");
|
|
|
|
-
|
|
|
|
- //if (temperature < -9) lcd.print(" ");
|
|
|
|
- //else if (temperature < 0) lcd.print("");
|
|
|
|
- //else if (temperature < 10) lcd.print(" ");
|
|
|
|
- //else lcd.print(" ");
|
|
|
|
- //lcd.print(tempstr2);
|
|
|
|
- //lcd.print(temp_str);
|
|
|
|
- lcd.print(temp_chararr);
|
|
|
|
- lcd.write(0xDF); // degree symbol
|
|
|
|
- lcd.print(" ");
|
|
|
|
-
|
|
|
|
- //lcd.print(humstr2);
|
|
|
|
- //lcd.print(hum_str); // always 2 chars
|
|
|
|
- lcd.print(hum_chararr); // always 2 chars
|
|
|
|
- lcd.print("%");
|
|
|
|
- lcd.print(" ");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- // display current mode on LCD
|
|
|
|
- lcd.setCursor(13, 0); // to char 15, line 1
|
|
|
|
- if (heatingEnabled) {
|
|
|
|
- if ( heatingMode == 1 ) { // day/normal mode
|
|
|
|
- lcd.print(" ");
|
|
|
|
- lcd.write((uint8_t)1); // sun symbol if mode is day/normal
|
|
|
|
- lcd.print(" ");
|
|
|
|
- }
|
|
|
|
- else if ( heatingMode == 2 ) { // night/reduction mode
|
|
|
|
- lcd.print(" ");
|
|
|
|
- lcd.write((uint8_t)0); // moon symbol if mode is night/reduction
|
|
|
|
- lcd.print(" ");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else lcd.print(" "); // mode is heating off
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- // display target temperature to line 2, 8 chars length incl space at the end
|
|
|
|
- lcd.setCursor(0, 1);
|
|
|
|
-
|
|
|
|
- // when the heating mode is OFF, do not display target temp - instead show "Heating off" info in line 2
|
|
|
|
- if ( !heatingEnabled ) {
|
|
|
|
- // 1234567890123456
|
|
|
|
- lcd.print(" Heizung aus ");
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- lcd.write((uint8_t)2); // Pfeil rechts
|
|
|
|
- lcd.print(" ");
|
|
|
|
- lcd.print(setTemp_chararr);
|
|
|
|
- lcd.write(0xDF); // degree symbol
|
|
|
|
- lcd.print(" ");
|
|
|
|
-
|
|
|
|
- // display status info to line 2 from char 9 -> 8 chars length
|
|
|
|
- lcd.setCursor(8, 1);
|
|
|
|
- if (turnHeatingOn) {
|
|
|
|
- // 12345678
|
|
|
|
- lcd.print("heizen..");
|
|
|
|
- }
|
|
|
|
- else if ( heatingMode == 1 ) { // day/normal mode
|
|
|
|
- // 12345678
|
|
|
|
- lcd.print(" ");
|
|
|
|
- }
|
|
|
|
- else if ( heatingMode == 2 ) { // night/reduction mode
|
|
|
|
- // 12345678
|
|
|
|
- lcd.print("N-Absenk");
|
|
|
|
- }
|
|
|
|
- else lcd.print(" ");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+ if (Serial.available()) {
|
|
|
|
+ serialEvent();
|
|
|
|
+ yield();
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
} //void loop
|
|
} //void loop
|
|
|
|
|