diff options
Diffstat (limited to 'oliver/dr_desk/src/main.cpp')
| -rw-r--r-- | oliver/dr_desk/src/main.cpp | 172 |
1 files changed, 91 insertions, 81 deletions
diff --git a/oliver/dr_desk/src/main.cpp b/oliver/dr_desk/src/main.cpp index 6f31b76..8791c80 100644 --- a/oliver/dr_desk/src/main.cpp +++ b/oliver/dr_desk/src/main.cpp | |||
| @@ -1,22 +1,17 @@ | |||
| 1 | #include <Arduino.h> | 1 | #include <Arduino.h> |
| 2 | #include <ESP8266mDNS.h> | 2 | #include <ESP8266mDNS.h> |
| 3 | #include <PubSubClient.h> | ||
| 4 | #include <WiFiManager.h> | 3 | #include <WiFiManager.h> |
| 5 | #include <FastLED.h> | 4 | #include <FastLED.h> |
| 5 | #include <PubSubClient.h> | ||
| 6 | #include <ESP8266httpUpdate.h> | 6 | #include <ESP8266httpUpdate.h> |
| 7 | #include "secrets.h" | ||
| 8 | 7 | ||
| 9 | #define _STR(s) #s | 8 | #include "secrets.h" |
| 10 | #define STR(s) _STR(s) | ||
| 11 | |||
| 12 | const char* mqtt_server = "192.168.1.2"; //MQTT Server IP, your home MQTT server eg Mosquitto on RPi, or some public MQTT | ||
| 13 | const int mqtt_port = 1883; //MQTT Server PORT, default is 1883 but can be anything. | ||
| 14 | |||
| 15 | const char* mqtt_pingall_sub = "home/pingall"; | ||
| 16 | const char* mqtt_pingall_pub = "home/pingall/response"; | ||
| 17 | 9 | ||
| 18 | #define MQTT_BASE "home/diningroom/desk" | 10 | #define MQTT_BROKER "192.168.1.5" |
| 19 | const char* mqtt_device_boot = MQTT_BASE "/device"; | 11 | #define MQTT_BROKER_PORT 1883 |
| 12 | //#define MQTT_USERNAME "" | ||
| 13 | //#define MQTT_PASSWORD "" | ||
| 14 | #define MQTT_BASE "home/diningroom/desk" | ||
| 20 | 15 | ||
| 21 | const char* mqtt_mode_sub = MQTT_BASE; | 16 | const char* mqtt_mode_sub = MQTT_BASE; |
| 22 | const char* mqtt_mode_pub = MQTT_BASE "/status"; | 17 | const char* mqtt_mode_pub = MQTT_BASE "/status"; |
| @@ -33,16 +28,25 @@ const char* mqtt_brightness_pub = MQTT_BASE "/brightness/status"; | |||
| 33 | #define RGB_COLOR_ORDER GRB | 28 | #define RGB_COLOR_ORDER GRB |
| 34 | #define NUM(a) (sizeof(a) / sizeof(*a)) | 29 | #define NUM(a) (sizeof(a) / sizeof(*a)) |
| 35 | 30 | ||
| 36 | #define FIRMWARE_VERSION 1 | 31 | // fw update |
| 37 | //#define FIRMWARE_URL "" | 32 | // - increment number + build |
| 33 | // - scp .pio/build/$ENV/firmware.bin manuel@mausz.at:public_html/coding/.firmware/olidrdesk.bin | ||
| 34 | // - reboot device or send "fwupdate" to mqtt_topic_cmd | ||
| 35 | // - fw update state is published in mqtt_topic_state | ||
| 36 | #define FIRMWARE_VERSION 1 | ||
| 37 | //#define FIRMWARE_URL "" | ||
| 38 | 38 | ||
| 39 | WiFiClient espClient; | 39 | #define _STR(s) #s |
| 40 | PubSubClient client(espClient); | 40 | #define STR(s) _STR(s) |
| 41 | char convBuffer[10]; | ||
| 42 | CRGB leds[RGB_NUM_LEDS]; | ||
| 43 | 41 | ||
| 44 | void callback(char *topic, uint8_t *payload, unsigned int length); | 42 | const String mqtt_clientId = "DrDesk-" + String(ESP.getChipId()) |
| 45 | void blink(); | 43 | + "/v" + STR(FIRMWARE_VERSION); |
| 44 | const char* mqtt_topic_ping = MQTT_BASE "/ping"; | ||
| 45 | const char* mqtt_topic_cmd = MQTT_BASE "/command"; | ||
| 46 | const String mqtt_topic_state = String(MQTT_BASE) + "/" + String(ESP.getChipId()); | ||
| 47 | |||
| 48 | bool mqttLoop(); | ||
| 49 | void mqttCallback(char *topic, byte *payload, unsigned int length); | ||
| 46 | void checkFirmwareUpdate(); | 50 | void checkFirmwareUpdate(); |
| 47 | 51 | ||
| 48 | void switchMode(struct mode *mode); | 52 | void switchMode(struct mode *mode); |
| @@ -52,6 +56,11 @@ void modeRainbow(); | |||
| 52 | void modeRainbowFast(); | 56 | void modeRainbowFast(); |
| 53 | void modeStrobo(); | 57 | void modeStrobo(); |
| 54 | 58 | ||
| 59 | WiFiClient wifi_client; | ||
| 60 | PubSubClient mqtt(wifi_client); | ||
| 61 | char convBuffer[10]; | ||
| 62 | CRGB leds[RGB_NUM_LEDS]; | ||
| 63 | |||
| 55 | struct mode { | 64 | struct mode { |
| 56 | const char *name; | 65 | const char *name; |
| 57 | void (*func)(); | 66 | void (*func)(); |
| @@ -92,7 +101,9 @@ void setup() | |||
| 92 | WiFiManager wifiManager; | 101 | WiFiManager wifiManager; |
| 93 | wifiManager.setConfigPortalTimeout(600); | 102 | wifiManager.setConfigPortalTimeout(600); |
| 94 | Serial.printf_P(PSTR("Setting up WiFi\n")); | 103 | Serial.printf_P(PSTR("Setting up WiFi\n")); |
| 95 | if (!wifiManager.autoConnect("ESP8266_DR_DESK")) { | 104 | WiFi.hostname("drdesk"); |
| 105 | if (!wifiManager.autoConnect("ESP8266_DR_DESK")) | ||
| 106 | { | ||
| 96 | Serial.printf_P(PSTR("Failed to connect and hit timeout\n")); | 107 | Serial.printf_P(PSTR("Failed to connect and hit timeout\n")); |
| 97 | delay(5000); | 108 | delay(5000); |
| 98 | ESP.restart(); | 109 | ESP.restart(); |
| @@ -102,63 +113,71 @@ void setup() | |||
| 102 | checkFirmwareUpdate(); | 113 | checkFirmwareUpdate(); |
| 103 | yield(); | 114 | yield(); |
| 104 | 115 | ||
| 105 | client.setServer(mqtt_server, mqtt_port); | 116 | mqtt.setServer(MQTT_BROKER, MQTT_BROKER_PORT); |
| 106 | client.setCallback(callback); | 117 | mqtt.setCallback(mqttCallback); |
| 107 | 118 | ||
| 108 | digitalWrite(LED_BUILTIN, HIGH); //Turn off led as default | 119 | digitalWrite(LED_BUILTIN, HIGH); //Turn off led as default |
| 109 | } | 120 | } |
| 110 | 121 | ||
| 111 | void reconnect() | 122 | bool mqttLoop() |
| 112 | { | 123 | { |
| 113 | // Loop until we're reconnected | 124 | if (!mqtt.connected()) |
| 114 | while (!client.connected()) | ||
| 115 | { | 125 | { |
| 116 | // Create a random client ID | 126 | Serial.printf_P(PSTR("Connecting to MQTT\n")); |
| 117 | String clientId = "ESP8266Client-"; | 127 | if (!mqtt.connect(mqtt_clientId.c_str(), MQTT_USERNAME, MQTT_PASSWORD)) |
| 118 | clientId += String(random(0xffff), HEX); | 128 | return false; |
| 129 | |||
| 130 | Serial.printf_P(PSTR("MQTT connected\n")); | ||
| 131 | mqtt.publish(mqtt_topic_ping, mqtt_clientId.c_str()); | ||
| 132 | mqtt.subscribe(mqtt_topic_ping); | ||
| 133 | mqtt.subscribe(mqtt_topic_cmd); | ||
| 134 | |||
| 135 | // publish states | ||
| 136 | Serial.println(mqtt_mode_sub); | ||
| 137 | mqtt.subscribe(mqtt_mode_sub); | ||
| 138 | mqtt.publish(mqtt_mode_pub, set.mode->name, true); | ||
| 139 | |||
| 140 | Serial.println(mqtt_color_sub); | ||
| 141 | mqtt.subscribe(mqtt_color_sub); | ||
| 142 | itoa(set.color, convBuffer, 10); | ||
| 143 | mqtt.publish(mqtt_color_pub, convBuffer, true); | ||
| 119 | 144 | ||
| 120 | // Attempt to connect | 145 | Serial.println(mqtt_brightness_sub); |
| 121 | if (client.connect(clientId.c_str())) | 146 | mqtt.subscribe(mqtt_brightness_sub); |
| 122 | { | 147 | itoa(map(set.brightness, 0, 255, 0, 100), convBuffer, 10); |
| 123 | // Once connected, publish an announcement... | 148 | mqtt.publish(mqtt_brightness_pub, convBuffer, true); |
| 124 | client.publish(mqtt_device_boot, "connected"); | ||
| 125 | // ... and resubscribe | ||
| 126 | client.subscribe(mqtt_pingall_sub); | ||
| 127 | |||
| 128 | // publish states | ||
| 129 | Serial.println(mqtt_mode_sub); | ||
| 130 | client.subscribe(mqtt_mode_sub); | ||
| 131 | client.publish(mqtt_mode_pub, set.mode->name, true); | ||
| 132 | |||
| 133 | Serial.println(mqtt_color_sub); | ||
| 134 | client.subscribe(mqtt_color_sub); | ||
| 135 | itoa(set.color, convBuffer, 10); | ||
| 136 | client.publish(mqtt_color_pub, convBuffer, true); | ||
| 137 | |||
| 138 | Serial.println(mqtt_brightness_sub); | ||
| 139 | client.subscribe(mqtt_brightness_sub); | ||
| 140 | itoa(map(set.brightness, 0, 255, 0, 100), convBuffer, 10); | ||
| 141 | client.publish(mqtt_brightness_pub, convBuffer, true); | ||
| 142 | } | ||
| 143 | else | ||
| 144 | { | ||
| 145 | // Wait 5 seconds before retrying | ||
| 146 | delay(5000); | ||
| 147 | } | ||
| 148 | } | 149 | } |
| 150 | |||
| 151 | yield(); | ||
| 152 | mqtt.loop(); | ||
| 153 | return true; | ||
| 149 | } | 154 | } |
| 150 | 155 | ||
| 151 | void callback(char *topic, uint8_t *payload, unsigned int length) | 156 | void mqttCallback(char *topic, byte *payload, unsigned int length) |
| 152 | { | 157 | { |
| 153 | uint8_t c_payload[length]; | 158 | char c_payload[length + 1]; |
| 154 | memcpy(c_payload, payload, length); | 159 | memcpy(c_payload, payload, length); |
| 155 | c_payload[length] = '\0'; | 160 | c_payload[length] = '\0'; |
| 156 | 161 | ||
| 157 | if (strcmp(topic, mqtt_pingall_sub) == 0) | 162 | if (!strcmp(topic, mqtt_topic_ping)) |
| 163 | { | ||
| 164 | if (!strcmp(c_payload, "ping")) | ||
| 165 | mqtt.publish(mqtt_topic_ping, mqtt_clientId.c_str()); | ||
| 166 | return; | ||
| 167 | } | ||
| 168 | else if (!strcmp(topic, mqtt_topic_cmd)) | ||
| 158 | { | 169 | { |
| 159 | blink(); | 170 | if (!strcmp(c_payload, "fwupdate")) |
| 160 | client.publish(mqtt_pingall_pub, | 171 | { |
| 161 | "{\"diningroom_desk\":\"connected\"}"); | 172 | checkFirmwareUpdate(); |
| 173 | return; | ||
| 174 | } | ||
| 175 | else if (!strcmp(c_payload, "reset")) | ||
| 176 | { | ||
| 177 | Serial.printf_P(PSTR("Resetting\n")); | ||
| 178 | ESP.reset(); | ||
| 179 | return; | ||
| 180 | } | ||
| 162 | } | 181 | } |
| 163 | else if (strcmp(topic, mqtt_mode_sub) == 0) | 182 | else if (strcmp(topic, mqtt_mode_sub) == 0) |
| 164 | { | 183 | { |
| @@ -179,25 +198,17 @@ void callback(char *topic, uint8_t *payload, unsigned int length) | |||
| 179 | set.color = atoi((char *)c_payload); | 198 | set.color = atoi((char *)c_payload); |
| 180 | current.idle = false; | 199 | current.idle = false; |
| 181 | itoa(set.color, convBuffer, 10); | 200 | itoa(set.color, convBuffer, 10); |
| 182 | client.publish(mqtt_color_pub, convBuffer, true); | 201 | mqtt.publish(mqtt_color_pub, convBuffer, true); |
| 183 | } | 202 | } |
| 184 | else if (strcmp(topic, mqtt_brightness_sub) == 0) | 203 | else if (strcmp(topic, mqtt_brightness_sub) == 0) |
| 185 | { | 204 | { |
| 186 | set.brightness = map(atoi((char *)c_payload), 0, 100, 0, 255); | 205 | set.brightness = map(atoi((char *)c_payload), 0, 100, 0, 255); |
| 187 | current.idle = false; | 206 | current.idle = false; |
| 188 | itoa(map(set.brightness, 0, 255, 0, 100), convBuffer, 10); | 207 | itoa(map(set.brightness, 0, 255, 0, 100), convBuffer, 10); |
| 189 | client.publish(mqtt_brightness_pub, convBuffer, true); | 208 | mqtt.publish(mqtt_brightness_pub, convBuffer, true); |
| 190 | } | 209 | } |
| 191 | } | 210 | } |
| 192 | 211 | ||
| 193 | void blink() | ||
| 194 | { | ||
| 195 | //Blink on received MQTT message | ||
| 196 | digitalWrite(LED_BUILTIN, LOW); | ||
| 197 | delay(25); | ||
| 198 | digitalWrite(LED_BUILTIN, HIGH); | ||
| 199 | } | ||
| 200 | |||
| 201 | void calcBrightness() | 212 | void calcBrightness() |
| 202 | { | 213 | { |
| 203 | #define FADE_STEP 10 | 214 | #define FADE_STEP 10 |
| @@ -217,7 +228,7 @@ void switchMode(struct mode *mode) | |||
| 217 | Serial.println(mode->name); | 228 | Serial.println(mode->name); |
| 218 | set.mode = mode; | 229 | set.mode = mode; |
| 219 | current.idle = false; | 230 | current.idle = false; |
| 220 | client.publish(mqtt_mode_pub, set.mode->name, true); | 231 | mqtt.publish(mqtt_mode_pub, set.mode->name, true); |
| 221 | } | 232 | } |
| 222 | 233 | ||
| 223 | void modeOff() | 234 | void modeOff() |
| @@ -270,7 +281,7 @@ void checkFirmwareUpdate() | |||
| 270 | BearSSL::WiFiClientSecure update_client; | 281 | BearSSL::WiFiClientSecure update_client; |
| 271 | update_client.setInsecure(); | 282 | update_client.setInsecure(); |
| 272 | 283 | ||
| 273 | client.publish(mqtt_device_boot, "fwupdate running"); | 284 | mqtt.publish(mqtt_topic_state.c_str(), "fwupdate running"); |
| 274 | ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH); | 285 | ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH); |
| 275 | ESPhttpUpdate.rebootOnUpdate(true); | 286 | ESPhttpUpdate.rebootOnUpdate(true); |
| 276 | t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION)); | 287 | t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION)); |
| @@ -281,27 +292,26 @@ void checkFirmwareUpdate() | |||
| 281 | Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"), | 292 | Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"), |
| 282 | ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); | 293 | ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); |
| 283 | String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString(); | 294 | String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString(); |
| 284 | client.publish(mqtt_device_boot, tmp.c_str()); | 295 | mqtt.publish(mqtt_topic_state.c_str(), tmp.c_str()); |
| 285 | } | 296 | } |
| 286 | break; | 297 | break; |
| 287 | 298 | ||
| 288 | case HTTP_UPDATE_NO_UPDATES: | 299 | case HTTP_UPDATE_NO_UPDATES: |
| 289 | Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n")); | 300 | Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n")); |
| 290 | client.publish(mqtt_device_boot, "fwupdate noupdates"); | 301 | mqtt.publish(mqtt_topic_state.c_str(), "fwupdate noupdates"); |
| 291 | break; | 302 | break; |
| 292 | 303 | ||
| 293 | case HTTP_UPDATE_OK: | 304 | case HTTP_UPDATE_OK: |
| 294 | Serial.printf_P(PSTR("HTTP_UPDATE_OK\n")); | 305 | Serial.printf_P(PSTR("HTTP_UPDATE_OK\n")); |
| 295 | client.publish(mqtt_device_boot, "fwupdate ok"); | 306 | mqtt.publish(mqtt_topic_state.c_str(), "fwupdate ok"); |
| 296 | break; | 307 | break; |
| 297 | } | 308 | } |
| 298 | } | 309 | } |
| 299 | 310 | ||
| 300 | void loop() | 311 | void loop() |
| 301 | { | 312 | { |
| 302 | if (!client.connected()) | 313 | if (!mqttLoop()) |
| 303 | reconnect(); | 314 | delay(5000); |
| 304 | client.loop(); | ||
| 305 | 315 | ||
| 306 | EVERY_N_MILLISECONDS(100) | 316 | EVERY_N_MILLISECONDS(100) |
| 307 | { | 317 | { |
