From a517cd8db485faaf0e63122798ddd266371cb36e Mon Sep 17 00:00:00 2001 From: manuel Date: Fri, 25 Dec 2020 23:37:33 +0100 Subject: Improve and harmonize code --- linz/oekofen_thermo/src/main.cpp | 158 +++++++++++++++++++++++++++++++++++---- 1 file changed, 143 insertions(+), 15 deletions(-) (limited to 'linz/oekofen_thermo/src/main.cpp') diff --git a/linz/oekofen_thermo/src/main.cpp b/linz/oekofen_thermo/src/main.cpp index 5713a0b..084a305 100644 --- a/linz/oekofen_thermo/src/main.cpp +++ b/linz/oekofen_thermo/src/main.cpp @@ -2,14 +2,48 @@ #include #include -#include "MCP42010.h" +#include +#include + +#include "secrets.h" + +#define MQTT_BROKER "192.168.0.6" +#define MQTT_BROKER_PORT 1883 +//#define MQTT_USERNAME "" +//#define MQTT_PASSWORD "" +#define MQTT_BASE "home/oekofen" + +// fw update +// - increment number + build +// - scp .pio/build/$ENV/firmware.bin manuel@mausz.at:public_html/coding/.firmware/oekofen.bin +// - reboot device or send "fwupdate" to mqtt_topic_cmd +// - fw update state is published in mqtt_topic_state +#define FIRMWARE_VERSION 1 +//#define FIRMWARE_URL "" + +#define _STR(s) #s +#define STR(s) _STR(s) + +const String mqtt_clientId = "OekoFen-" + String(ESP.getChipId()) + + "/v" + STR(FIRMWARE_VERSION); +const char* mqtt_topic_ping = MQTT_BASE "/ping"; +const char* mqtt_topic_cmd = MQTT_BASE "/command"; +const String mqtt_topic_state = String(MQTT_BASE) + "/" + String(ESP.getChipId()); + +bool mqttLoop(); +void mqttCallback(char *topic, byte *payload, unsigned int length); +void checkFirmwareUpdate(); + +WiFiClient wifi_client; +PubSubClient mqtt(wifi_client); ESP8266WebServer http_service(80); -MCP42010 msp42010(D8); void setup() { Serial.begin(115200); - msp42010.setup(); + analogWriteFreq(8000); + pinMode(D3, OUTPUT); + pinMode(LED_BUILTIN, OUTPUT); WiFiManager wifiManager; wifiManager.setConfigPortalTimeout(600); @@ -22,25 +56,119 @@ void setup() { ESP.restart(); } + yield(); + checkFirmwareUpdate(); + yield(); + + mqtt.setServer(MQTT_BROKER, MQTT_BROKER_PORT); + mqtt.setCallback(mqttCallback); + http_service.on("/", HTTP_GET, []() { - uint8_t val = random(0, 255); - //msp42010.setPot(MCP42010::P0, val); - msp42010.setPot(MCP42010::P1, val); - http_service.send(200, PSTR("text/plain"), String(val)); + http_service.send_P(200, PSTR("text/plain"), PSTR("I'm an oekofen fake thermostat")); + }); + http_service.on("/set", HTTP_POST, []() { + if (!http_service.hasArg("value")) { + http_service.send_P(400, PSTR("text/plain"), PSTR("Bad Request")); + return; + } + + int val = http_service.arg("value").toInt(); + int pwm_val = constrain(val, 0, 1023); + analogWrite(D3, pwm_val); + http_service.send(200, "text/plain", String(pwm_val)); }); http_service.begin(); Serial.println("Setup done"); } -void loop() { - //http_service.handleClient(); - if (Serial.available() > 0) +bool mqttLoop() +{ + if (!mqtt.connected()) { - while (Serial.read() >= 0) {} - uint8_t val = random(0, 255); - //msp42010.setPot(MCP42010::P0, val); - msp42010.setPot(MCP42010::P1, val); - Serial.println(val, DEC); + Serial.printf_P(PSTR("Connecting to MQTT\n")); + if (!mqtt.connect(mqtt_clientId.c_str(), MQTT_USERNAME, MQTT_PASSWORD)) + return false; + + Serial.printf_P(PSTR("MQTT connected\n")); + mqtt.publish(mqtt_topic_ping, mqtt_clientId.c_str()); + mqtt.subscribe(mqtt_topic_ping); + mqtt.subscribe(mqtt_topic_cmd); } + + yield(); + mqtt.loop(); + return true; +} + +void mqttCallback(char *topic, byte *payload, unsigned int length) +{ + char c_payload[length + 1]; + memcpy(c_payload, payload, length); + c_payload[length] = '\0'; + + if (!strcmp(topic, mqtt_topic_ping)) + { + if (!strcmp(c_payload, "ping")) + mqtt.publish(mqtt_topic_ping, mqtt_clientId.c_str()); + return; + } + else if (!strcmp(topic, mqtt_topic_cmd)) + { + if (!strcmp(c_payload, "TODO")) + { + return; + } + else if (!strcmp(c_payload, "fwupdate")) + { + checkFirmwareUpdate(); + return; + } + else if (!strcmp(c_payload, "reset")) + { + Serial.printf_P(PSTR("Resetting\n")); + ESP.reset(); + return; + } + } + + Serial.printf_P(PSTR("Unhandled MQTT message: [%s] %s\n"), topic, c_payload); +} + +void checkFirmwareUpdate() +{ + BearSSL::WiFiClientSecure update_client; + update_client.setInsecure(); + + mqtt.publish(mqtt_topic_state.c_str(), "fwupdate running"); + ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH); + ESPhttpUpdate.rebootOnUpdate(true); + t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION)); + switch(ret) + { + case HTTP_UPDATE_FAILED: + { + Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"), + ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); + String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString(); + mqtt.publish(mqtt_topic_state.c_str(), tmp.c_str()); + } + break; + + case HTTP_UPDATE_NO_UPDATES: + Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n")); + mqtt.publish(mqtt_topic_state.c_str(), "fwupdate noupdates"); + break; + + case HTTP_UPDATE_OK: + Serial.printf_P(PSTR("HTTP_UPDATE_OK\n")); + mqtt.publish(mqtt_topic_state.c_str(), "fwupdate ok"); + break; + } +} + +void loop() { + http_service.handleClient(); + if (!mqttLoop()) + delay(5000); } -- cgit v1.2.3