From c386b24fde0874f7a258391b36ef23901912c667 Mon Sep 17 00:00:00 2001 From: jptrsn Date: Mon, 10 Dec 2018 16:29:24 -0500 Subject: [PATCH] OTA support for PlatformIO cli --- ESP32-mqtt-room.ino | 60 +++++++++++++++++++++++++++++++++++----- README.md | 5 +++- partitions_singleapp.csv | 7 +++++ 3 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 partitions_singleapp.csv diff --git a/ESP32-mqtt-room.ino b/ESP32-mqtt-room.ino index fa75598..2897cab 100644 --- a/ESP32-mqtt-room.ino +++ b/ESP32-mqtt-room.ino @@ -24,6 +24,7 @@ extern "C" { #include #include #include +#include #include "BLEBeacon.h" #include "BLEEddystoneTLM.h" #include "BLEEddystoneURL.h" @@ -32,9 +33,11 @@ extern "C" { BLEScan* pBLEScan; int scanTime = 5; //In seconds int waitTime = scanInterval; //In seconds +bool updateInProgress = false; uint16_t beconUUID = 0xFEAA; #define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8)) +#define LED_BUILTIN 2 WiFiClient espClient; AsyncMqttClient mqttClient; @@ -99,12 +102,14 @@ void WiFiEvent(WiFiEvent_t event) { Serial.println(event); switch(event) { case SYSTEM_EVENT_STA_GOT_IP: + digitalWrite(LED_BUILTIN, 0); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); connectToMqtt(); break; case SYSTEM_EVENT_STA_DISCONNECTED: + digitalWrite(LED_BUILTIN, 1); Serial.println("WiFi lost connection"); xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi xTimerStart(wifiReconnectTimer, 0); @@ -278,7 +283,10 @@ class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { - Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str()); + digitalWrite(LED_BUILTIN, 1); + // Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str()); + vTaskDelay(100 / portTICK_PERIOD_MS); + digitalWrite(LED_BUILTIN, 0); } @@ -290,15 +298,12 @@ TaskHandle_t BLEScan; void scanForDevices(void * parameter) { while(1) { - if (WiFi.isConnected() && mqttClient.connected() && (millis() - last > (waitTime * 1000) || last == 0)) { + if (!updateInProgress && WiFi.isConnected() && mqttClient.connected() && (millis() - last > (waitTime * 1000) || last == 0)) { Serial.print("Scanning...\t"); - BLEScanResults foundDevices = pBLEScan->start(scanTime); + BLEScanResults foundDevices = pBLEScan->start(scanTime); Serial.printf("Scan done! Devices found: %d\t",foundDevices.getCount()); for (uint32_t i = 0; i < foundDevices.getCount(); i++) { - // Serial.printf("Getting device %d",i); - reportDevice(foundDevices.getDevice(i)); - } last = millis(); Serial.println("Reports sent"); @@ -306,10 +311,48 @@ void scanForDevices(void * parameter) { } } +void configureOTA() { + ArduinoOTA + .onStart([]() { + updateInProgress = true; + String type; + if (ArduinoOTA.getCommand() == U_FLASH) + type = "sketch"; + else // U_SPIFFS + type = "filesystem"; + + // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() + Serial.println("Start updating " + type); + }) + .onEnd([]() { + updateInProgress = false; + digitalWrite(LED_BUILTIN, 0); + Serial.println("\nEnd"); + }) + .onProgress([](unsigned int progress, unsigned int total) { + byte percent = (progress / (total / 100)); + Serial.printf("Progress: %u%%\n", percent); + digitalWrite(LED_BUILTIN, percent % 2); + }) + .onError([](ota_error_t error) { + Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); + else if (error == OTA_END_ERROR) Serial.println("End Failed"); + ESP.restart(); + }); + + ArduinoOTA.begin(); +} + void setup() { Serial.begin(115200); + pinMode(LED_BUILTIN, OUTPUT); + mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast(connectToMqtt)); wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast(connectToWifi)); @@ -323,9 +366,11 @@ void setup() { connectToWifi(); + configureOTA(); + BLEDevice::init(""); pBLEScan = BLEDevice::getScan(); //create new scan - // pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); + pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster // pBLEScan->setInterval(100); // pBLEScan->setWindow(200); @@ -345,4 +390,5 @@ void loop() { TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG0.wdt_feed=1; TIMERG0.wdt_wprotect=0; + ArduinoOTA.handle(); } diff --git a/README.md b/README.md index 6266042..833a38c 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ Create a copy of the `Settings.h` file, and rename it to `Settings_local.h`. Thi Open the folder in Atom, using the `open project` option in the PlatformIO Home screen. Modify the settings in the `Settings_local.h` file to match your environment. Set the correct port in the `platformio.ini` file (or remove the line to use auto-detection), and upload to the board. Open the serial monitor after successful upload to check for success. +### OTA Support +It is possible to update the device using "Over the Air" (OTA) updates from the command line interface of PlatformIO. You will need to know the IP address of the device itself (check your router). From the command line, enter the command `platformio run -t upload --upload-port {{Device IP Address}}` + ## Home Assistant Configuration Once the device is running, it is important to configure Home Assistant to use the information from the MQTT topic to determine what devices to track. You can read the full documentation [on the Home Assistant website](https://www.home-assistant.io/components/sensor.mqtt_room/). It is critical that you configure your device IDs to include the Major version, but ignore Minor version (i.e. set it to 0). This is to match the configuration used on the ESP32. @@ -48,5 +51,5 @@ Unfortunately, Apple does not allow devices to advertise iBeacon data in the bac - [x] Scan interval Settings - [ ] Configuration via Web UI - [ ] Wifi Manager for managing access point credentials -- [ ] Implement Over-The-Air (OTA) updates +- [x] Implement Over-The-Air (OTA) updates - [x] Build and upload via [PlatformIO](platformio.org) diff --git a/partitions_singleapp.csv b/partitions_singleapp.csv new file mode 100644 index 0000000..ae4aa75 --- /dev/null +++ b/partitions_singleapp.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1E0000, +app1, app, ota_1, 0x1F0000,0x1E0000, +eeprom, data, 0x99, 0x3F0000,0x1000, +spiffs, data, spiffs, 0x3F1000,0xF000,