diff options
Diffstat (limited to 'linz/oekofen_thermo')
| -rw-r--r-- | linz/oekofen_thermo/platformio.ini | 1 | ||||
| -rw-r--r-- | linz/oekofen_thermo/src/main.cpp | 158 |
2 files changed, 144 insertions, 15 deletions
diff --git a/linz/oekofen_thermo/platformio.ini b/linz/oekofen_thermo/platformio.ini index 2c7b00e..625bc4f 100644 --- a/linz/oekofen_thermo/platformio.ini +++ b/linz/oekofen_thermo/platformio.ini | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | [env:d1_mini] | 11 | [env:d1_mini] |
| 12 | platform = espressif8266 | 12 | platform = espressif8266 |
| 13 | board = d1_mini | 13 | board = d1_mini |
| 14 | lib_deps = WiFiManager, PubSubClient | ||
| 14 | framework = arduino | 15 | framework = arduino |
| 15 | monitor_speed = 115200 | 16 | monitor_speed = 115200 |
| 16 | upload_speed = 115200 | 17 | upload_speed = 115200 |
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 @@ | |||
| 2 | #include <WiFiManager.h> | 2 | #include <WiFiManager.h> |
| 3 | #include <ESP8266WebServer.h> | 3 | #include <ESP8266WebServer.h> |
| 4 | 4 | ||
| 5 | #include "MCP42010.h" | 5 | #include <PubSubClient.h> |
| 6 | #include <ESP8266httpUpdate.h> | ||
| 7 | |||
| 8 | #include "secrets.h" | ||
| 9 | |||
| 10 | #define MQTT_BROKER "192.168.0.6" | ||
| 11 | #define MQTT_BROKER_PORT 1883 | ||
| 12 | //#define MQTT_USERNAME "" | ||
| 13 | //#define MQTT_PASSWORD "" | ||
| 14 | #define MQTT_BASE "home/oekofen" | ||
| 15 | |||
| 16 | // fw update | ||
| 17 | // - increment number + build | ||
| 18 | // - scp .pio/build/$ENV/firmware.bin manuel@mausz.at:public_html/coding/.firmware/oekofen.bin | ||
| 19 | // - reboot device or send "fwupdate" to mqtt_topic_cmd | ||
| 20 | // - fw update state is published in mqtt_topic_state | ||
| 21 | #define FIRMWARE_VERSION 1 | ||
| 22 | //#define FIRMWARE_URL "" | ||
| 23 | |||
| 24 | #define _STR(s) #s | ||
| 25 | #define STR(s) _STR(s) | ||
| 26 | |||
| 27 | const String mqtt_clientId = "OekoFen-" + String(ESP.getChipId()) | ||
| 28 | + "/v" + STR(FIRMWARE_VERSION); | ||
| 29 | const char* mqtt_topic_ping = MQTT_BASE "/ping"; | ||
| 30 | const char* mqtt_topic_cmd = MQTT_BASE "/command"; | ||
| 31 | const String mqtt_topic_state = String(MQTT_BASE) + "/" + String(ESP.getChipId()); | ||
| 32 | |||
| 33 | bool mqttLoop(); | ||
| 34 | void mqttCallback(char *topic, byte *payload, unsigned int length); | ||
| 35 | void checkFirmwareUpdate(); | ||
| 36 | |||
| 37 | WiFiClient wifi_client; | ||
| 38 | PubSubClient mqtt(wifi_client); | ||
| 6 | 39 | ||
| 7 | ESP8266WebServer http_service(80); | 40 | ESP8266WebServer http_service(80); |
| 8 | MCP42010 msp42010(D8); | ||
| 9 | 41 | ||
| 10 | void setup() { | 42 | void setup() { |
| 11 | Serial.begin(115200); | 43 | Serial.begin(115200); |
| 12 | msp42010.setup(); | 44 | analogWriteFreq(8000); |
| 45 | pinMode(D3, OUTPUT); | ||
| 46 | pinMode(LED_BUILTIN, OUTPUT); | ||
| 13 | 47 | ||
| 14 | WiFiManager wifiManager; | 48 | WiFiManager wifiManager; |
| 15 | wifiManager.setConfigPortalTimeout(600); | 49 | wifiManager.setConfigPortalTimeout(600); |
| @@ -22,25 +56,119 @@ void setup() { | |||
| 22 | ESP.restart(); | 56 | ESP.restart(); |
| 23 | } | 57 | } |
| 24 | 58 | ||
| 59 | yield(); | ||
| 60 | checkFirmwareUpdate(); | ||
| 61 | yield(); | ||
| 62 | |||
| 63 | mqtt.setServer(MQTT_BROKER, MQTT_BROKER_PORT); | ||
| 64 | mqtt.setCallback(mqttCallback); | ||
| 65 | |||
| 25 | http_service.on("/", HTTP_GET, []() { | 66 | http_service.on("/", HTTP_GET, []() { |
| 26 | uint8_t val = random(0, 255); | 67 | http_service.send_P(200, PSTR("text/plain"), PSTR("I'm an oekofen fake thermostat")); |
| 27 | //msp42010.setPot(MCP42010::P0, val); | 68 | }); |
| 28 | msp42010.setPot(MCP42010::P1, val); | 69 | http_service.on("/set", HTTP_POST, []() { |
| 29 | http_service.send(200, PSTR("text/plain"), String(val)); | 70 | if (!http_service.hasArg("value")) { |
| 71 | http_service.send_P(400, PSTR("text/plain"), PSTR("Bad Request")); | ||
| 72 | return; | ||
| 73 | } | ||
| 74 | |||
| 75 | int val = http_service.arg("value").toInt(); | ||
| 76 | int pwm_val = constrain(val, 0, 1023); | ||
| 77 | analogWrite(D3, pwm_val); | ||
| 78 | http_service.send(200, "text/plain", String(pwm_val)); | ||
| 30 | }); | 79 | }); |
| 31 | http_service.begin(); | 80 | http_service.begin(); |
| 32 | 81 | ||
| 33 | Serial.println("Setup done"); | 82 | Serial.println("Setup done"); |
| 34 | } | 83 | } |
| 35 | 84 | ||
| 36 | void loop() { | 85 | bool mqttLoop() |
| 37 | //http_service.handleClient(); | 86 | { |
| 38 | if (Serial.available() > 0) | 87 | if (!mqtt.connected()) |
| 39 | { | 88 | { |
| 40 | while (Serial.read() >= 0) {} | 89 | Serial.printf_P(PSTR("Connecting to MQTT\n")); |
| 41 | uint8_t val = random(0, 255); | 90 | if (!mqtt.connect(mqtt_clientId.c_str(), MQTT_USERNAME, MQTT_PASSWORD)) |
| 42 | //msp42010.setPot(MCP42010::P0, val); | 91 | return false; |
| 43 | msp42010.setPot(MCP42010::P1, val); | 92 | |
| 44 | Serial.println(val, DEC); | 93 | Serial.printf_P(PSTR("MQTT connected\n")); |
| 94 | mqtt.publish(mqtt_topic_ping, mqtt_clientId.c_str()); | ||
| 95 | mqtt.subscribe(mqtt_topic_ping); | ||
| 96 | mqtt.subscribe(mqtt_topic_cmd); | ||
| 45 | } | 97 | } |
| 98 | |||
| 99 | yield(); | ||
| 100 | mqtt.loop(); | ||
| 101 | return true; | ||
| 102 | } | ||
| 103 | |||
| 104 | void mqttCallback(char *topic, byte *payload, unsigned int length) | ||
| 105 | { | ||
| 106 | char c_payload[length + 1]; | ||
| 107 | memcpy(c_payload, payload, length); | ||
| 108 | c_payload[length] = '\0'; | ||
| 109 | |||
| 110 | if (!strcmp(topic, mqtt_topic_ping)) | ||
| 111 | { | ||
| 112 | if (!strcmp(c_payload, "ping")) | ||
| 113 | mqtt.publish(mqtt_topic_ping, mqtt_clientId.c_str()); | ||
| 114 | return; | ||
| 115 | } | ||
| 116 | else if (!strcmp(topic, mqtt_topic_cmd)) | ||
| 117 | { | ||
| 118 | if (!strcmp(c_payload, "TODO")) | ||
| 119 | { | ||
| 120 | return; | ||
| 121 | } | ||
| 122 | else if (!strcmp(c_payload, "fwupdate")) | ||
| 123 | { | ||
| 124 | checkFirmwareUpdate(); | ||
| 125 | return; | ||
| 126 | } | ||
| 127 | else if (!strcmp(c_payload, "reset")) | ||
| 128 | { | ||
| 129 | Serial.printf_P(PSTR("Resetting\n")); | ||
| 130 | ESP.reset(); | ||
| 131 | return; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | Serial.printf_P(PSTR("Unhandled MQTT message: [%s] %s\n"), topic, c_payload); | ||
| 136 | } | ||
| 137 | |||
| 138 | void checkFirmwareUpdate() | ||
| 139 | { | ||
| 140 | BearSSL::WiFiClientSecure update_client; | ||
| 141 | update_client.setInsecure(); | ||
| 142 | |||
| 143 | mqtt.publish(mqtt_topic_state.c_str(), "fwupdate running"); | ||
| 144 | ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH); | ||
| 145 | ESPhttpUpdate.rebootOnUpdate(true); | ||
| 146 | t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION)); | ||
| 147 | switch(ret) | ||
| 148 | { | ||
| 149 | case HTTP_UPDATE_FAILED: | ||
| 150 | { | ||
| 151 | Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"), | ||
| 152 | ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); | ||
| 153 | String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString(); | ||
| 154 | mqtt.publish(mqtt_topic_state.c_str(), tmp.c_str()); | ||
| 155 | } | ||
| 156 | break; | ||
| 157 | |||
| 158 | case HTTP_UPDATE_NO_UPDATES: | ||
| 159 | Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n")); | ||
| 160 | mqtt.publish(mqtt_topic_state.c_str(), "fwupdate noupdates"); | ||
| 161 | break; | ||
| 162 | |||
| 163 | case HTTP_UPDATE_OK: | ||
| 164 | Serial.printf_P(PSTR("HTTP_UPDATE_OK\n")); | ||
| 165 | mqtt.publish(mqtt_topic_state.c_str(), "fwupdate ok"); | ||
| 166 | break; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | void loop() { | ||
| 171 | http_service.handleClient(); | ||
| 172 | if (!mqttLoop()) | ||
| 173 | delay(5000); | ||
| 46 | } | 174 | } |
