Implement OTA update functionality with configuration and response handling; add necessary protobuf definitions and update main loop integration
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "hardware",
|
||||||
|
"dependencies": {
|
||||||
|
"nanopb": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "ota",
|
||||||
|
"dependencies": {
|
||||||
|
"hardware": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#include "ota_update.hpp"
|
||||||
|
|
||||||
|
OtaUpdate::OtaUpdate()
|
||||||
|
: _server(80), _httpUpdater(), _configured(false), _startTime(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OtaUpdate::configure(const hardware_SensorOTAEnable& config) {
|
||||||
|
_config = config;
|
||||||
|
_configured = true;
|
||||||
|
_startTime = millis();
|
||||||
|
|
||||||
|
// Disconnect if already connected
|
||||||
|
WiFi.disconnect();
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
if (_config.as_station_mode) {
|
||||||
|
// STA mode
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin(_config.ssid, _config.password);
|
||||||
|
|
||||||
|
Serial.print("Connecting to WiFi STA: ");
|
||||||
|
Serial.println(_config.ssid);
|
||||||
|
|
||||||
|
unsigned long startAttempt = millis();
|
||||||
|
while (WiFi.status() != WL_CONNECTED && millis() - startAttempt < 10000) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
|
Serial.println("Failed to connect to WiFi");
|
||||||
|
_configured = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_config.use_static_ip) {
|
||||||
|
IPAddress ip, gateway, subnet;
|
||||||
|
ip.fromString(_config.static_ip);
|
||||||
|
gateway.fromString(_config.gateway);
|
||||||
|
subnet.fromString(_config.netmask);
|
||||||
|
WiFi.config(ip, gateway, subnet);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print("Connected to ");
|
||||||
|
Serial.println(_config.ssid);
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
} else {
|
||||||
|
// AP mode
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP(_config.ssid, _config.password);
|
||||||
|
|
||||||
|
Serial.print("Started AP: ");
|
||||||
|
Serial.println(_config.ssid);
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.softAPIP());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup HTTP Update Server
|
||||||
|
_httpUpdater.setup(&_server);
|
||||||
|
_server.begin();
|
||||||
|
Serial.println("HTTP Update Server started");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OtaUpdate::update() {
|
||||||
|
if (!_configured) return;
|
||||||
|
|
||||||
|
_server.handleClient();
|
||||||
|
|
||||||
|
// Check timeout
|
||||||
|
if (_config.timeout_seconds > 0 && millis() - _startTime > _config.timeout_seconds * 1000) {
|
||||||
|
Serial.println("OTA timeout, disabling WiFi");
|
||||||
|
disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OtaUpdate::disable() {
|
||||||
|
_server.stop();
|
||||||
|
WiFi.disconnect();
|
||||||
|
_configured = false;
|
||||||
|
Serial.println("OTA disabled");
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hardware.pb.h"
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266WebServer.h>
|
||||||
|
#include <ESP8266HTTPUpdateServer.h>
|
||||||
|
|
||||||
|
class OtaUpdate {
|
||||||
|
public:
|
||||||
|
OtaUpdate();
|
||||||
|
bool configure(const hardware_SensorOTAEnable& config);
|
||||||
|
void update();
|
||||||
|
void disable();
|
||||||
|
|
||||||
|
private:
|
||||||
|
hardware_SensorOTAEnable _config;
|
||||||
|
ESP8266WebServer _server;
|
||||||
|
ESP8266HTTPUpdateServer _httpUpdater;
|
||||||
|
bool _configured;
|
||||||
|
unsigned long _startTime;
|
||||||
|
};
|
||||||
@@ -20,6 +20,7 @@ lib_deps =
|
|||||||
;adafruit/Adafruit NeoPixel@^1.15.1
|
;adafruit/Adafruit NeoPixel@^1.15.1
|
||||||
fastled/FastLED@^3.10.3
|
fastled/FastLED@^3.10.3
|
||||||
nanopb/Nanopb@^0.4.91
|
nanopb/Nanopb@^0.4.91
|
||||||
|
; jandrassy/ArduinoOTA @ ^1.1.0
|
||||||
custom_nanopb_protos =
|
custom_nanopb_protos =
|
||||||
+<proto/hardware.proto>
|
+<proto/hardware.proto>
|
||||||
custom_nanopb_options =
|
custom_nanopb_options =
|
||||||
@@ -27,3 +28,8 @@ custom_nanopb_protos =
|
|||||||
[env:esp8285]
|
[env:esp8285]
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
board = esp12e
|
board = esp12e
|
||||||
|
[env:esp8285-ota]
|
||||||
|
platform = espressif8266
|
||||||
|
board = esp12e
|
||||||
|
upload_protocol = espota
|
||||||
|
upload_port = 192.168.20.41
|
||||||
@@ -2,3 +2,11 @@
|
|||||||
|
|
||||||
# LED configuration
|
# LED configuration
|
||||||
hardware.FadeParams.colors max_count:5
|
hardware.FadeParams.colors max_count:5
|
||||||
|
|
||||||
|
hardware.SensorOTAEnable.ssid max_length:32
|
||||||
|
hardware.SensorOTAEnable.password max_length:64
|
||||||
|
hardware.SensorOTAEnable.static_ip max_length:16
|
||||||
|
hardware.SensorOTAEnable.netmask max_length:16
|
||||||
|
hardware.SensorOTAEnable.gateway max_length:16
|
||||||
|
hardware.SensorOTAEnableResponse.ip_address max_length:16
|
||||||
|
hardware.SensorOTAEnableResponse.error_message max_length:64
|
||||||
+25
-5
@@ -23,6 +23,8 @@ message HardwareConfig {
|
|||||||
bool enable_serial_sensor = 9;
|
bool enable_serial_sensor = 9;
|
||||||
// repeated char sensor_api_key = 10;
|
// repeated char sensor_api_key = 10;
|
||||||
// bool enable_ws_sensor = 11;
|
// bool enable_ws_sensor = 11;
|
||||||
|
LedConfig on_override_open_led = 12;
|
||||||
|
LedConfig on_interception_led = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LED configuration
|
// LED configuration
|
||||||
@@ -61,19 +63,37 @@ message RfidReading {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SensorToControlMessage {
|
message SensorToControlMessage {
|
||||||
uint32 sensor_id = 1;
|
uint32 sensor_id = 1;
|
||||||
oneof payload {
|
oneof payload {
|
||||||
RfidReading rfid_reading = 2;
|
RfidReading rfid_reading = 2;
|
||||||
// Add other sensor message types as needed
|
SensorOTAEnableResponse ota_response = 3;
|
||||||
}
|
// Add other sensor message types as needed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message SensorOTAEnable {
|
||||||
|
string ssid = 1;
|
||||||
|
string password = 2;
|
||||||
|
uint32 timeout_seconds = 3;
|
||||||
|
bool as_station_mode = 4;
|
||||||
|
bool use_static_ip = 5;
|
||||||
|
string static_ip = 6;
|
||||||
|
string netmask = 7;
|
||||||
|
string gateway = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SensorOTAEnableResponse {
|
||||||
|
bool success = 1;
|
||||||
|
string ip_address = 2;
|
||||||
|
string error_message = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
message ControlToSensorMessage {
|
message ControlToSensorMessage {
|
||||||
uint32 control_id = 1;
|
uint32 control_id = 1;
|
||||||
oneof payload {
|
oneof payload {
|
||||||
LedConfig led_config = 2;
|
LedConfig led_config = 2;
|
||||||
|
SensorOTAEnable ota_enable = 3;
|
||||||
// Add other control message types as needed
|
// Add other control message types as needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+31
-39
@@ -2,8 +2,11 @@
|
|||||||
#include <hardware_led.hpp>
|
#include <hardware_led.hpp>
|
||||||
#include <hardware_rfid.hpp>
|
#include <hardware_rfid.hpp>
|
||||||
#include <hardware_serial.hpp>
|
#include <hardware_serial.hpp>
|
||||||
|
#include <ota_update.hpp>
|
||||||
#include "hardware.pb.h"
|
#include "hardware.pb.h"
|
||||||
|
|
||||||
|
OtaUpdate ota;
|
||||||
|
|
||||||
// Demo for HardwareLed
|
// Demo for HardwareLed
|
||||||
HardwareLed<2> led; // Assuming NeoPixel on pin 2 (D2 on ESP8266)
|
HardwareLed<2> led; // Assuming NeoPixel on pin 2 (D2 on ESP8266)
|
||||||
|
|
||||||
@@ -27,62 +30,51 @@ void onRfidTag(const hardware_SensorToControlMessage& msg) {
|
|||||||
void onSerialMessage(const IncomingMessage& msg) {
|
void onSerialMessage(const IncomingMessage& msg) {
|
||||||
if (msg.which_payload == hardware_ControlToSensorMessage_led_config_tag) {
|
if (msg.which_payload == hardware_ControlToSensorMessage_led_config_tag) {
|
||||||
led.set(msg.payload.led_config);
|
led.set(msg.payload.led_config);
|
||||||
|
} else if (msg.which_payload == hardware_ControlToSensorMessage_ota_enable_tag) {
|
||||||
|
hardware_SensorOTAEnableResponse response = {0};
|
||||||
|
response.success = ota.configure(msg.payload.ota_enable);
|
||||||
|
if (response.success) {
|
||||||
|
IPAddress ip = WiFi.localIP();
|
||||||
|
if (!msg.payload.ota_enable.as_station_mode) {
|
||||||
|
ip = WiFi.softAPIP();
|
||||||
|
}
|
||||||
|
strcpy(response.ip_address, ip.toString().c_str());
|
||||||
|
} else {
|
||||||
|
strcpy(response.error_message, "Failed to configure OTA");
|
||||||
|
}
|
||||||
|
|
||||||
|
hardware_SensorToControlMessage responseMsg = {0};
|
||||||
|
responseMsg.sensor_id = msg.control_id; // or some id
|
||||||
|
responseMsg.which_payload = hardware_SensorToControlMessage_ota_response_tag;
|
||||||
|
responseMsg.payload.ota_response = response;
|
||||||
|
|
||||||
|
serial.sendMessage(responseMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
led.begin();
|
led.begin();
|
||||||
rfid.begin();
|
rfid.begin();
|
||||||
rfid.setCallback(onRfidTag);
|
rfid.setCallback(onRfidTag);
|
||||||
serial.begin(Serial);
|
serial.begin(Serial);
|
||||||
serial.setCallback(onSerialMessage);
|
serial.setCallback(onSerialMessage);
|
||||||
|
|
||||||
// // Static config
|
// Static config
|
||||||
// configs[0] = {0};
|
configs[0] = {0};
|
||||||
// configs[0].brightness = 128;
|
configs[0].brightness = 128;
|
||||||
// configs[0].duration_ms = 0;
|
configs[0].duration_ms = 0;
|
||||||
// configs[0].which_animation_params = 3;
|
configs[0].which_animation_params = 3;
|
||||||
// configs[0].animation_params.static_params.color = 0x00FF00; // Green
|
configs[0].animation_params.static_params.color = 0x00FF00; // Green
|
||||||
|
|
||||||
// // Pulse config
|
|
||||||
// configs[1] = {0};
|
|
||||||
// configs[1].brightness = 128;
|
|
||||||
// configs[1].duration_ms = 0;
|
|
||||||
// configs[1].which_animation_params = 4;
|
|
||||||
// configs[1].animation_params.pulse_params.color = 0xFF0000; // Red
|
|
||||||
// configs[1].animation_params.pulse_params.speed_ms = 500;
|
|
||||||
|
|
||||||
// // Fade config
|
led.set(configs[0]);
|
||||||
// configs[2] = {0};
|
|
||||||
// configs[2].brightness = 128;
|
|
||||||
// configs[2].duration_ms = 0;
|
|
||||||
// configs[2].which_animation_params = 5;
|
|
||||||
// configs[2].animation_params.fade_params.colors_count = 3;
|
|
||||||
// configs[2].animation_params.fade_params.colors[0] = 0xFF0000; // Red
|
|
||||||
// configs[2].animation_params.fade_params.colors[1] = 0x00FF00; // Green
|
|
||||||
// configs[2].animation_params.fade_params.colors[2] = 0x0000FF; // Blue
|
|
||||||
// configs[2].animation_params.fade_params.speed_ms = 1000;
|
|
||||||
|
|
||||||
// // Flicker config
|
|
||||||
// configs[3] = {0};
|
|
||||||
// configs[3].brightness = 128;
|
|
||||||
// configs[3].duration_ms = 0;
|
|
||||||
// configs[3].which_animation_params = 6;
|
|
||||||
// configs[3].animation_params.flicker_params.color = 0xFFFFFF; // White
|
|
||||||
// configs[3].animation_params.flicker_params.intensity = 50;
|
|
||||||
|
|
||||||
// led.set(configs[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
led.update();
|
led.update();
|
||||||
rfid.update();
|
rfid.update();
|
||||||
serial.update();
|
serial.update();
|
||||||
|
ota.update();
|
||||||
// if (millis() - lastChange >= 10000) {
|
|
||||||
// lastChange = millis();
|
|
||||||
// currentConfig = (currentConfig + 1) % 4;
|
|
||||||
// led.set(configs[currentConfig]);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user