From 8a80559ea700261ad6ca0a8c72a9c79ba3f470d6 Mon Sep 17 00:00:00 2001 From: Rune Harlyk Date: Thu, 27 Nov 2025 16:54:30 +0100 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=90=9B=20Call=20begin=20on=20camera?= =?UTF-8?q?=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- esp32/src/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index 1042126..e998ebe 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -144,6 +144,10 @@ void IRAM_ATTR serviceLoopEntry(void *) { MDNS.setInstanceName(APP_NAME); apService.begin(); +#if FT_ENABLED(USE_CAMERA) + cameraService.begin(); +#endif + setupServer(); socket.begin(); From 7d2f384898d558df59317c5543d6826d05ae1a5c Mon Sep 17 00:00:00 2001 From: Rune Harlyk Date: Thu, 27 Nov 2025 17:30:00 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=90=9B=20Fix=20system=20metric=20emit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- esp32/include/communication/comm_base.hpp | 2 +- esp32/include/system_service.h | 4 ++-- esp32/src/main.cpp | 2 +- esp32/src/system_service.cpp | 15 ++++++++------- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/esp32/include/communication/comm_base.hpp b/esp32/include/communication/comm_base.hpp index 1a55429..cafd346 100644 --- a/esp32/include/communication/comm_base.hpp +++ b/esp32/include/communication/comm_base.hpp @@ -47,7 +47,7 @@ class CommAdapterBase { #else String out; serializeJson(doc, out); - send(out.c_str(), cid); + send(out.c_str(), -1); #endif } diff --git a/esp32/include/system_service.h b/esp32/include/system_service.h index 1edd4f9..04b8efd 100644 --- a/esp32/include/system_service.h +++ b/esp32/include/system_service.h @@ -3,7 +3,7 @@ #include #include #include -// #include +#include #include #include #include "esp_timer.h" @@ -25,7 +25,7 @@ void sleep(); void status(JsonObject &root); void metrics(JsonObject &root); -void emitMetrics(); +void emitMetrics(Websocket &socket); const char *resetReason(esp_reset_reason_t reason); } // namespace system_service \ No newline at end of file diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index e998ebe..13afab8 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -157,7 +157,7 @@ void IRAM_ATTR serviceLoopEntry(void *) { for (;;) { wifiService.loop(); apService.loop(); - EXECUTE_EVERY_N_MS(2000, system_service::emitMetrics()); + EXECUTE_EVERY_N_MS(2000, system_service::emitMetrics(socket)); vTaskDelay(100 / portTICK_PERIOD_MS); } diff --git a/esp32/src/system_service.cpp b/esp32/src/system_service.cpp index 136b267..7fdbb34 100644 --- a/esp32/src/system_service.cpp +++ b/esp32/src/system_service.cpp @@ -121,13 +121,14 @@ void metrics(JsonObject &root) { root["core_temp"] = temperatureRead(); } -void emitMetrics() { - // if (!socket.hasSubscribers(EVENT_ANALYTICS)) return; - // analyticsDoc.clear(); - // JsonObject root = analyticsDoc.to(); - // system_service::metrics(root); - // JsonVariant data = analyticsDoc.as(); - // socket.emit(EVENT_ANALYTICS, data); +void emitMetrics(Websocket &socket) { + if (!socket.hasSubscribers(EVENT_ANALYTICS)) return; + + JsonDocument doc; + JsonObject root = doc.to(); + system_service::metrics(root); + JsonVariant data = doc.as(); + socket.emit(EVENT_ANALYTICS, data); } const char *resetReason(esp_reset_reason_t reason) { From 6c61227623e0171087ef63b781b50d511f47ed7c Mon Sep 17 00:00:00 2001 From: Rune Harlyk Date: Thu, 27 Nov 2025 17:38:37 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=E2=9C=A8=20Emit=20imu,=20mag=20and=20bmp?= =?UTF-8?q?=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/lib/stores/imu.ts | 23 ++++++++++++++++++----- app/src/lib/types/models.ts | 6 ++++++ app/src/routes/peripherals/imu/imu.svelte | 4 ++-- esp32/src/main.cpp | 6 ++++++ esp32/src/peripherals/peripherals.cpp | 9 ++++++--- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/app/src/lib/stores/imu.ts b/app/src/lib/stores/imu.ts index 12ee5e1..3bf1491 100644 --- a/app/src/lib/stores/imu.ts +++ b/app/src/lib/stores/imu.ts @@ -1,5 +1,5 @@ import { writable } from 'svelte/store' -import type { IMU } from '$lib/types/models' +import type { IMUMsg } from '$lib/types/models' const maxIMUData = 100 @@ -14,11 +14,24 @@ export const imu = (() => { bmp_temp: [] as number[] }) - const addData = (content: IMU) => { + const addData = (content: IMUMsg) => { update(data => { - ;(Object.keys(content) as (keyof IMU)[]).forEach(key => { - data[key] = [...data[key], content[key]].slice(-maxIMUData) - }) + if (content.imu && content.imu[3]) { + data.x = [...data.x, content.imu[0]].slice(-maxIMUData) + data.y = [...data.y, content.imu[1]].slice(-maxIMUData) + data.z = [...data.z, content.imu[2]].slice(-maxIMUData) + } + + if (content.mag && content.mag[4]) { + data.heading = [...data.heading, content.mag[3]].slice(-maxIMUData) + } + + if (content.bmp && content.bmp[3]) { + data.pressure = [...data.pressure, content.bmp[0]].slice(-maxIMUData) + data.altitude = [...data.altitude, content.bmp[1]].slice(-maxIMUData) + data.bmp_temp = [...data.bmp_temp, content.bmp[2]].slice(-maxIMUData) + } + return data }) } diff --git a/app/src/lib/types/models.ts b/app/src/lib/types/models.ts index 616b222..85ab164 100644 --- a/app/src/lib/types/models.ts +++ b/app/src/lib/types/models.ts @@ -154,6 +154,12 @@ export type IMU = { pressure: number } +export type IMUMsg = { + imu: [number, number, number, boolean] + mag: [number, number, number, number, boolean] + bmp: [number, number, number, boolean] +} + export interface I2CDevice { address: number part_number: string diff --git a/app/src/routes/peripherals/imu/imu.svelte b/app/src/routes/peripherals/imu/imu.svelte index f038a8e..38b75d0 100644 --- a/app/src/routes/peripherals/imu/imu.svelte +++ b/app/src/routes/peripherals/imu/imu.svelte @@ -6,7 +6,7 @@ import { slide } from 'svelte/transition' import { onDestroy, onMount } from 'svelte' import { socket } from '$lib/stores' - import { MessageTopic, type IMU } from '$lib/types/models' + import { MessageTopic, type IMUMsg } from '$lib/types/models' import { useFeatureFlags } from '$lib/stores/featureFlags' import { Rotate3d } from '$lib/components/icons' @@ -201,7 +201,7 @@ } onMount(() => { - socket.on(MessageTopic.imu, (data: IMU) => { + socket.on(MessageTopic.imu, (data: IMUMsg) => { console.log(data) imu.addData(data) }) diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index 13afab8..7dad36a 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -132,6 +132,12 @@ void IRAM_ATTR SpotControlLoopEntry(void *) { #if FT_ENABLED(USE_WS2812) ledService.loop(); #endif + EXECUTE_EVERY_N_MS(250, [&]() { + JsonDocument doc; + JsonVariant results = doc.to(); + peripherals.getIMUResult(results); + socket.emit(EVENT_IMU, results); + }); vTaskDelayUntil(&xLastWakeTime, xFrequency); } } diff --git a/esp32/src/peripherals/peripherals.cpp b/esp32/src/peripherals/peripherals.cpp index 3048d8d..fc8fbbd 100644 --- a/esp32/src/peripherals/peripherals.cpp +++ b/esp32/src/peripherals/peripherals.cpp @@ -166,13 +166,16 @@ float Peripherals::rightDistance() { return _right_distance; } void Peripherals::getIMUResult(JsonVariant &root) { #if FT_ENABLED(USE_MPU6050 || USE_BNO055) - _imu.getResults(root); + JsonVariant imu = root["imu"].to(); + _imu.getResults(imu); #endif #if FT_ENABLED(USE_HMC5883) - _mag.getResults(root); + JsonVariant mag = root["mag"].to(); + _mag.getResults(mag); #endif #if FT_ENABLED(USE_BMP180) - _bmp.getResults(root); + JsonVariant bmp = root["bmp"].to(); + _bmp.getResults(bmp); #endif } From 70c798a2cc0173c170999d4aadef97eabdfa2fe6 Mon Sep 17 00:00:00 2001 From: Rune Harlyk Date: Thu, 27 Nov 2025 17:38:51 +0100 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=90=9B=20Fix=20socket=20deadlock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- esp32/include/communication/comm_base.hpp | 6 +++--- esp32/include/communication/websocket_adapter.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/esp32/include/communication/comm_base.hpp b/esp32/include/communication/comm_base.hpp index cafd346..b1ed5b0 100644 --- a/esp32/include/communication/comm_base.hpp +++ b/esp32/include/communication/comm_base.hpp @@ -38,15 +38,15 @@ class CommAdapterBase { array.add(event); array.add(payload); - // TODO: Only send to subscribed - #if USE_MSGPACK std::string bin; serializeMsgPack(doc, bin); - send(reinterpret_cast(bin.data()), bin.size(), -1); // TODO: Make CID dynamic + xSemaphoreGive(mutex_); + send(reinterpret_cast(bin.data()), bin.size(), -1); #else String out; serializeJson(doc, out); + xSemaphoreGive(mutex_); send(out.c_str(), -1); #endif } diff --git a/esp32/include/communication/websocket_adapter.h b/esp32/include/communication/websocket_adapter.h index af151e6..da2cb1b 100644 --- a/esp32/include/communication/websocket_adapter.h +++ b/esp32/include/communication/websocket_adapter.h @@ -10,7 +10,7 @@ #include -class Websocket : CommAdapterBase { +class Websocket : public CommAdapterBase { public: Websocket(PsychicHttpServer &server, const char *route = "/api/ws");