#include #include #include #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); void setup() { Serial.begin(115200); analogWriteFreq(8000); pinMode(D3, OUTPUT); analogWrite(D3, 757); //default value pinMode(LED_BUILTIN, OUTPUT); WiFiManager wifiManager; wifiManager.setConfigPortalTimeout(600); Serial.printf_P(PSTR("Setting up WiFi\n")); WiFi.hostname("oekofen"); if (!wifiManager.autoConnect("oekofen-thermo")) { Serial.printf_P(PSTR("Failed to connect and hit timeout\n")); delay(5000); ESP.restart(); } yield(); checkFirmwareUpdate(); yield(); mqtt.setServer(MQTT_BROKER, MQTT_BROKER_PORT); mqtt.setCallback(mqttCallback); http_service.on("/", HTTP_GET, []() { 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"); } bool mqttLoop() { if (!mqtt.connected()) { 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); }