From 3a962660753fe236deb88d303e7a8e5754b2a8bd Mon Sep 17 00:00:00 2001 From: Wolfram Keil Date: Thu, 27 Aug 2026 21:38:46 +0200 Subject: [PATCH] Add board hooks for periodic work and variant telemetry Two no-op virtuals on MainBoard, so a variant can do these things without core changes: - tick(): called from the simple_repeater and simple_sensor main loops. Lets a board feed its watchdog and run periodic housekeeping. - queryBoardTelemetry(CayenneLPP&): simple_repeater asks the board for extra telemetry channels, gated by TELEM_PERM_ENVIRONMENT. Variant-specific CLI is already covered by MainBoard::handleCommand(), so this adds nothing for that. Both defaults are no-ops, so existing variants build and behave unchanged. Used by the Inhero MR2 variant (separate PR). --- examples/simple_repeater/MyMesh.cpp | 5 +++++ examples/simple_repeater/main.cpp | 2 ++ examples/simple_sensor/main.cpp | 2 ++ src/MeshCore.h | 9 +++++++++ 4 files changed, 18 insertions(+) diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index ca6a3e607e..9e57894008 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -249,6 +249,11 @@ int MyMesh::handleRequest(ClientInfo *sender, uint32_t sender_timestamp, uint8_t } sensors.querySensors(perm_mask, telemetry); + // board specific telemetry -- target specific + if (perm_mask & TELEM_PERM_ENVIRONMENT) { + board.queryBoardTelemetry(telemetry); + } + // This default temperature will be overridden by external sensors (if any) float temperature = board.getMCUTemperature(); if(!isnan(temperature)) { // Supported boards with built-in temperature sensor. ESP32-C3 may return NAN diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index a714db68ec..628d1d11b8 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -157,6 +157,8 @@ void loop() { command[0] = 0; // reset command buffer } + board.tick(); // let the board feed its watchdog, run periodic housekeeping + #ifdef ETHERNET_ENABLED ethernet_loop_maintain(); if (ethernet_read_line(ethernet_command, sizeof(ethernet_command))) { diff --git a/examples/simple_sensor/main.cpp b/examples/simple_sensor/main.cpp index 69182f3a7a..b8e3ec4b6d 100644 --- a/examples/simple_sensor/main.cpp +++ b/examples/simple_sensor/main.cpp @@ -145,6 +145,8 @@ void loop() { command[0] = 0; // reset command buffer } + board.tick(); // let the board feed its watchdog, run periodic housekeeping + the_mesh.loop(); sensors.loop(); #ifdef DISPLAY_CLASS diff --git a/src/MeshCore.h b/src/MeshCore.h index 4349523225..61e5227a3b 100644 --- a/src/MeshCore.h +++ b/src/MeshCore.h @@ -37,6 +37,8 @@ #define BRIDGE_DEBUG_PRINTLN(...) {} #endif +class CayenneLPP; + namespace mesh { #define BD_STARTUP_NORMAL 0 // getStartupReason() codes @@ -74,6 +76,13 @@ class MainBoard { virtual const char* getShutdownReasonString(uint8_t reason) { return "Not available"; } virtual bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply) { return false; } + + // Called from the example main loops. Lets a board feed its watchdog and + // run periodic housekeeping. Default no-op. + virtual void tick() { /* no op */ } + + // Lets a board contribute its own telemetry channels. Default no-op. + virtual bool queryBoardTelemetry(CayenneLPP& telemetry) { return false; } }; /**