mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-02 10:51:57 +00:00
fix(bot): !temp and {temp} fall back to the chip's temperature
Same gap as the screens had: the bot reply, a typed message's {temp} and
the placeholder lists read only the sensors, so a board without one (the
L1) answered !temp with n/a while its telemetry carried a temperature.
The fallback moves to LocalSensors.h, shared by the screens, expandMsg()
and sensorPlaceholders(); the latter now takes the chip's temperature.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
// This device's own readings, as the screens, the bot and message placeholders
|
||||||
|
// read them.
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <helpers/SensorManager.h>
|
||||||
|
#include <helpers/sensors/LPPDataHelpers.h>
|
||||||
|
|
||||||
|
// The sensors' readings, plus the chip's own temperature (NaN where a board has
|
||||||
|
// none) when no sensor reads one: the telemetry reply sends it too, so a board
|
||||||
|
// without a temperature sensor shows on screen and in {temp} what the app shows.
|
||||||
|
inline void queryLocalSensors(SensorManager& sm, float mcu_temp, CayenneLPP& lpp) {
|
||||||
|
sm.querySensors(0xFF, lpp);
|
||||||
|
if (isnan(mcu_temp)) return;
|
||||||
|
LPPReader r(lpp.getBuffer(), lpp.getSize());
|
||||||
|
uint8_t ch, type;
|
||||||
|
while (r.readHeader(ch, type)) {
|
||||||
|
if (type == LPP_TEMPERATURE) return;
|
||||||
|
r.skipData(type);
|
||||||
|
}
|
||||||
|
lpp.addTemperature(TELEM_CHANNEL_SELF, mcu_temp);
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <helpers/SensorManager.h>
|
#include <helpers/SensorManager.h>
|
||||||
#include "NodePrefs.h" // localTm()
|
#include "NodePrefs.h" // localTm()
|
||||||
#include <helpers/sensors/LPPDataHelpers.h>
|
#include <helpers/sensors/LPPDataHelpers.h>
|
||||||
|
#include "LocalSensors.h"
|
||||||
|
|
||||||
// Expands placeholders in tmpl into out (out_len bytes).
|
// Expands placeholders in tmpl into out (out_len bytes).
|
||||||
// {loc} — GPS coordinates (lat/lon) or "no GPS"
|
// {loc} — GPS coordinates (lat/lon) or "no GPS"
|
||||||
@@ -26,14 +27,15 @@ inline void expandMsg(const char* tmpl, char* out, int out_len,
|
|||||||
SensorManager* sm = nullptr,
|
SensorManager* sm = nullptr,
|
||||||
float batt_volts = -1.0f,
|
float batt_volts = -1.0f,
|
||||||
const char* sender_name = nullptr,
|
const char* sender_name = nullptr,
|
||||||
int hops = -1) {
|
int hops = -1,
|
||||||
|
float mcu_temp = NAN) { // the chip's, for {temp} without a sensor
|
||||||
// sv indices: 0=temp 1=hum 2=pres 3=batt 4=alt 5=lux 6=dist 7=co2
|
// sv indices: 0=temp 1=hum 2=pres 3=batt 4=alt 5=lux 6=dist 7=co2
|
||||||
float sv[8] = {};
|
float sv[8] = {};
|
||||||
bool sv_ok[8] = {};
|
bool sv_ok[8] = {};
|
||||||
|
|
||||||
if (sm) {
|
if (sm) {
|
||||||
CayenneLPP lpp(100);
|
CayenneLPP lpp(100);
|
||||||
sm->querySensors(0xFF, lpp);
|
queryLocalSensors(*sm, mcu_temp, lpp);
|
||||||
LPPReader r(lpp.getBuffer(), lpp.getSize());
|
LPPReader r(lpp.getBuffer(), lpp.getSize());
|
||||||
uint8_t ch, type;
|
uint8_t ch, type;
|
||||||
while (r.readHeader(ch, type)) {
|
while (r.readHeader(ch, type)) {
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ void MyMesh::tryBotReplyDM(const ContactInfo& from, const char* text, uint8_t ho
|
|||||||
sensors.node_lat != 0.0 || sensors.node_lon != 0.0,
|
sensors.node_lat != 0.0 || sensors.node_lon != 0.0,
|
||||||
ts, _prefs.tz_offset_hours,
|
ts, _prefs.tz_offset_hours,
|
||||||
&sensors, (float)board.getBattMilliVolts() / 1000.0f,
|
&sensors, (float)board.getBattMilliVolts() / 1000.0f,
|
||||||
from.name, hops);
|
from.name, hops, board.getMCUTemperature());
|
||||||
uint32_t expected_ack, est_timeout;
|
uint32_t expected_ack, est_timeout;
|
||||||
if (sendMessage(from, ts, 0, expanded, expected_ack, est_timeout) != MSG_SEND_FAILED) {
|
if (sendMessage(from, ts, 0, expanded, expected_ack, est_timeout) != MSG_SEND_FAILED) {
|
||||||
botDmRecord(from.id.pub_key);
|
botDmRecord(from.id.pub_key);
|
||||||
@@ -184,7 +184,7 @@ void MyMesh::tryBotReplyChannel(uint8_t channel_idx, const char* text, uint8_t h
|
|||||||
sensors.node_lat != 0.0 || sensors.node_lon != 0.0,
|
sensors.node_lat != 0.0 || sensors.node_lon != 0.0,
|
||||||
ts, _prefs.tz_offset_hours,
|
ts, _prefs.tz_offset_hours,
|
||||||
&sensors, (float)board.getBattMilliVolts() / 1000.0f,
|
&sensors, (float)board.getBattMilliVolts() / 1000.0f,
|
||||||
sender_name, hops);
|
sender_name, hops, board.getMCUTemperature());
|
||||||
// Anti-loop: don't echo a message identical to our own reply (e.g. another bot
|
// Anti-loop: don't echo a message identical to our own reply (e.g. another bot
|
||||||
// on the channel sending the same text), which would ping-pong forever. The
|
// on the channel sending the same text), which would ping-pong forever. The
|
||||||
// per-channel cooldown caps any residual back-and-forth between mismatched bots.
|
// per-channel cooldown caps any residual back-and-forth between mismatched bots.
|
||||||
@@ -228,7 +228,7 @@ void MyMesh::tryBotReplyRoom(const ContactInfo& from, const uint8_t* sender_pref
|
|||||||
sensors.node_lat != 0.0 || sensors.node_lon != 0.0,
|
sensors.node_lat != 0.0 || sensors.node_lon != 0.0,
|
||||||
ts, _prefs.tz_offset_hours,
|
ts, _prefs.tz_offset_hours,
|
||||||
&sensors, (float)board.getBattMilliVolts() / 1000.0f,
|
&sensors, (float)board.getBattMilliVolts() / 1000.0f,
|
||||||
sender_name, hops);
|
sender_name, hops, board.getMCUTemperature());
|
||||||
// Anti-loop, mirrors the channel path: don't echo a message identical to
|
// Anti-loop, mirrors the channel path: don't echo a message identical to
|
||||||
// our own reply (e.g. re-synced back from the room server).
|
// our own reply (e.g. re-synced back from the room server).
|
||||||
if (strcmp(text, expanded) == 0) return;
|
if (strcmp(text, expanded) == 0) return;
|
||||||
@@ -367,7 +367,7 @@ bool MyMesh::botCommandReply(const char* cmd, const char* arg, const char* arg2,
|
|||||||
sensors.node_lat != 0.0 || sensors.node_lon != 0.0,
|
sensors.node_lat != 0.0 || sensors.node_lon != 0.0,
|
||||||
ts, _prefs.tz_offset_hours,
|
ts, _prefs.tz_offset_hours,
|
||||||
&sensors, (float)board.getBattMilliVolts() / 1000.0f,
|
&sensors, (float)board.getBattMilliVolts() / 1000.0f,
|
||||||
sender_name, hops);
|
sender_name, hops, board.getMCUTemperature());
|
||||||
if (strchr(out, '{')) strcpy(out, "n/a"); // requested sensor not present
|
if (strchr(out, '{')) strcpy(out, "n/a"); // requested sensor not present
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ static void seedQuick(NodePrefs* p) {
|
|||||||
// ── Placeholders ──────────────────────────────────────────────────────────────
|
// ── Placeholders ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
// The sensor readings this device has right now, as placeholders ({temp},
|
// The sensor readings this device has right now, as placeholders ({temp},
|
||||||
// {hum}, ...; {batt} only from a voltage sensor).
|
// {hum}, ...; {batt} only from a voltage sensor; {temp} also from the chip, mcu_temp).
|
||||||
static void sensorPlaceholders(SensorManager* sm, void (*add)(const char* ph, void* ctx), void* ctx) {
|
static void sensorPlaceholders(SensorManager* sm, float mcu_temp, void (*add)(const char* ph, void* ctx), void* ctx) {
|
||||||
if (!sm) return;
|
if (!sm) return;
|
||||||
CayenneLPP lpp(100);
|
CayenneLPP lpp(100);
|
||||||
sm->querySensors(0xFF, lpp);
|
queryLocalSensors(*sm, mcu_temp, lpp);
|
||||||
uint8_t present[16];
|
uint8_t present[16];
|
||||||
int pc = 0;
|
int pc = 0;
|
||||||
LPPReader r(lpp.getBuffer(), lpp.getSize());
|
LPPReader r(lpp.getBuffer(), lpp.getSize());
|
||||||
@@ -62,12 +62,12 @@ static void sensorPlaceholders(SensorManager* sm, void (*add)(const char* ph, vo
|
|||||||
|
|
||||||
// Everything a message can carry here: {loc}, {time}, {batt} (the board's
|
// Everything a message can carry here: {loc}, {time}, {batt} (the board's
|
||||||
// voltage), then the sensors'.
|
// voltage), then the sensors'.
|
||||||
static void placeholders(SensorManager* sm, void (*add)(const char* ph, void* ctx), void* ctx) {
|
static void placeholders(SensorManager* sm, float mcu_temp, void (*add)(const char* ph, void* ctx), void* ctx) {
|
||||||
add("{loc}", ctx);
|
add("{loc}", ctx);
|
||||||
add("{time}", ctx);
|
add("{time}", ctx);
|
||||||
add("{batt}", ctx);
|
add("{batt}", ctx);
|
||||||
struct Skip { void (*add)(const char*, void*); void* ctx; } skip = { add, ctx };
|
struct Skip { void (*add)(const char*, void*); void* ctx; } skip = { add, ctx };
|
||||||
sensorPlaceholders(sm, [](const char* ph, void* c) {
|
sensorPlaceholders(sm, mcu_temp, [](const char* ph, void* c) {
|
||||||
Skip* s = (Skip*)c;
|
Skip* s = (Skip*)c;
|
||||||
if (strcmp(ph, "{batt}") != 0) s->add(ph, s->ctx); // already there
|
if (strcmp(ph, "{batt}") != 0) s->add(ph, s->ctx); // already there
|
||||||
}, &skip);
|
}, &skip);
|
||||||
@@ -89,7 +89,7 @@ static void expand(const char* tmpl, char* out, int n, const NodePrefs* p) {
|
|||||||
#endif
|
#endif
|
||||||
float batt = (float)board.getBattMilliVolts() / 1000.0f;
|
float batt = (float)board.getBattMilliVolts() / 1000.0f;
|
||||||
::expandMsg(tmpl, out, n, lat, lon, gps_valid, rtc_clock.getCurrentTime(),
|
::expandMsg(tmpl, out, n, lat, lon, gps_valid, rtc_clock.getCurrentTime(),
|
||||||
p ? p->tz_offset_hours : 0, &sensors, batt);
|
p ? p->tz_offset_hours : 0, &sensors, batt, nullptr, -1, board.getMCUTemperature());
|
||||||
}
|
}
|
||||||
|
|
||||||
// A typed message: a reply's leading "@[nick] " stays as it is (a nick may
|
// A typed message: a reply's leading "@[nick] " stays as it is (a nick may
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
|
||||||
#include <helpers/SensorManager.h>
|
|
||||||
#include <helpers/sensors/LPPDataHelpers.h>
|
#include <helpers/sensors/LPPDataHelpers.h>
|
||||||
#include <helpers/sensors/LocationProvider.h>
|
#include <helpers/sensors/LocationProvider.h>
|
||||||
#include "Battery.h"
|
#include "Battery.h"
|
||||||
@@ -66,21 +64,6 @@ static uint8_t lppType(uint8_t f) {
|
|||||||
// Read from the sensors, not the radio or GPS.
|
// Read from the sensors, not the radio or GPS.
|
||||||
static bool isSensor(uint8_t f) { return lppType(f) != 0; }
|
static bool isSensor(uint8_t f) { return lppType(f) != 0; }
|
||||||
|
|
||||||
// The sensors' readings, plus the chip's own temperature (NaN where a board has
|
|
||||||
// none) when no sensor reads one: the telemetry reply sends it too, so a board
|
|
||||||
// without a temperature sensor shows on screen what the app shows.
|
|
||||||
static void querySensors(SensorManager& sm, float mcu_temp, CayenneLPP& lpp) {
|
|
||||||
sm.querySensors(0xFF, lpp);
|
|
||||||
if (isnan(mcu_temp)) return;
|
|
||||||
LPPReader r(lpp.getBuffer(), lpp.getSize());
|
|
||||||
uint8_t ch, type;
|
|
||||||
while (r.readHeader(ch, type)) {
|
|
||||||
if (type == LPP_TEMPERATURE) return;
|
|
||||||
r.skipData(type);
|
|
||||||
}
|
|
||||||
lpp.addTemperature(TELEM_CHANNEL_SELF, mcu_temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Altitude always in the small unit (never km / mi).
|
// Altitude always in the small unit (never km / mi).
|
||||||
static void altText(float m, bool imperial, const Style& st, char* v, int n) {
|
static void altText(float m, bool imperial, const Style& st, char* v, int n) {
|
||||||
snprintf(v, n, "%.0f%s%s", imperial ? m * 3.28084f : m, st.spaced ? " " : "", imperial ? "ft" : "m");
|
snprintf(v, n, "%.0f%s%s", imperial ? m * 3.28084f : m, st.spaced ? " " : "", imperial ? "ft" : "m");
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ void UITask::botRow(int row) {
|
|||||||
lv_obj_set_scrollbar_mode(chips, LV_SCROLLBAR_MODE_OFF);
|
lv_obj_set_scrollbar_mode(chips, LV_SCROLLBAR_MODE_OFF);
|
||||||
s_chip_ta = _nav_ta;
|
s_chip_ta = _nav_ta;
|
||||||
for (int i = 0; i < botcfg::REPLY_PLACEHOLDER_COUNT; i++) botChip(botcfg::REPLY_PLACEHOLDERS[i], chips);
|
for (int i = 0; i < botcfg::REPLY_PLACEHOLDER_COUNT; i++) botChip(botcfg::REPLY_PLACEHOLDERS[i], chips);
|
||||||
msgtext::sensorPlaceholders(&sensors, [](const char* ph, void* c) {
|
msgtext::sensorPlaceholders(&sensors, board.getMCUTemperature(), [](const char* ph, void* c) {
|
||||||
if (strcmp(ph, "{batt}") != 0) botChip(ph, c); // already there
|
if (strcmp(ph, "{batt}") != 0) botChip(ph, c); // already there
|
||||||
}, chips);
|
}, chips);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -621,7 +621,7 @@ void UITask::homeFieldText(uint8_t f, char* v, int n) {
|
|||||||
if (_sensors && (s_lpp_ms == 0 || millis() - s_lpp_ms > 5000)) {
|
if (_sensors && (s_lpp_ms == 0 || millis() - s_lpp_ms > 5000)) {
|
||||||
s_lpp_ms = millis() | 1;
|
s_lpp_ms = millis() | 1;
|
||||||
s_lpp.reset();
|
s_lpp.reset();
|
||||||
telemetry::querySensors(*_sensors, board.getMCUTemperature(), s_lpp);
|
queryLocalSensors(*_sensors, board.getMCUTemperature(), s_lpp);
|
||||||
}
|
}
|
||||||
in.lpp = s_lpp.getBuffer();
|
in.lpp = s_lpp.getBuffer();
|
||||||
in.lpp_len = s_lpp.getSize();
|
in.lpp_len = s_lpp.getSize();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ static int s_edit = -1; // quick message being edited
|
|||||||
|
|
||||||
static void collect() {
|
static void collect() {
|
||||||
s_ph_n = 0;
|
s_ph_n = 0;
|
||||||
msgtext::placeholders(&sensors, [](const char* ph, void*) { if (s_ph_n < PH_MAX) s_ph[s_ph_n++] = ph; }, nullptr);
|
msgtext::placeholders(&sensors, board.getMCUTemperature(), [](const char* ph, void*) { if (s_ph_n < PH_MAX) s_ph[s_ph_n++] = ph; }, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The placeholders as small buttons; `cb` gets the index as user data.
|
// The placeholders as small buttons; `cb` gets the index as user data.
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ static void formatDashVal(uint8_t field, char* val, int val_len, uint16_t batt_m
|
|||||||
if (telemetry::isSensor(field)) {
|
if (telemetry::isSensor(field)) {
|
||||||
if (!lpp) {
|
if (!lpp) {
|
||||||
static CayenneLPP s_lpp(200); s_lpp.reset();
|
static CayenneLPP s_lpp(200); s_lpp.reset();
|
||||||
{ CardKBBusLock bus_lock; telemetry::querySensors(sensors, board.getMCUTemperature(), s_lpp); }
|
{ CardKBBusLock bus_lock; queryLocalSensors(sensors, board.getMCUTemperature(), s_lpp); }
|
||||||
lpp = &s_lpp;
|
lpp = &s_lpp;
|
||||||
}
|
}
|
||||||
in.lpp = lpp->getBuffer();
|
in.lpp = lpp->getBuffer();
|
||||||
@@ -652,7 +652,7 @@ class HomeScreen : public UIScreen {
|
|||||||
sensors_lpp.reset();
|
sensors_lpp.reset();
|
||||||
sensors_nb = 0;
|
sensors_nb = 0;
|
||||||
sensors_lpp.addVoltage(TELEM_CHANNEL_SELF, (float)board.getBattMilliVolts() / 1000.0f);
|
sensors_lpp.addVoltage(TELEM_CHANNEL_SELF, (float)board.getBattMilliVolts() / 1000.0f);
|
||||||
{ CardKBBusLock bus_lock; telemetry::querySensors(sensors, board.getMCUTemperature(), sensors_lpp); }
|
{ CardKBBusLock bus_lock; queryLocalSensors(sensors, board.getMCUTemperature(), sensors_lpp); }
|
||||||
LPPReader reader (sensors_lpp.getBuffer(), sensors_lpp.getSize());
|
LPPReader reader (sensors_lpp.getBuffer(), sensors_lpp.getSize());
|
||||||
uint8_t channel, type;
|
uint8_t channel, type;
|
||||||
while(reader.readHeader(channel, type)) {
|
while(reader.readHeader(channel, type)) {
|
||||||
|
|||||||
@@ -8,5 +8,5 @@
|
|||||||
#include <helpers/sensors/LPPDataHelpers.h>
|
#include <helpers/sensors/LPPDataHelpers.h>
|
||||||
|
|
||||||
inline void kbAddSensorPlaceholders(KeyboardWidget& kb, SensorManager* sm) { // list: ui-core/MessageText.h
|
inline void kbAddSensorPlaceholders(KeyboardWidget& kb, SensorManager* sm) { // list: ui-core/MessageText.h
|
||||||
msgtext::sensorPlaceholders(sm, [](const char* ph, void* k) { ((KeyboardWidget*)k)->addPlaceholder(ph); }, &kb);
|
msgtext::sensorPlaceholders(sm, board.getMCUTemperature(), [](const char* ph, void* k) { ((KeyboardWidget*)k)->addPlaceholder(ph); }, &kb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ private:
|
|||||||
// Sensors: every reading but the battery (above) and the position (GPS).
|
// Sensors: every reading but the battery (above) and the position (GPS).
|
||||||
if (!_lpp_at || millis() - _lpp_at > 5000) { // both passes (measure, draw) read one query
|
if (!_lpp_at || millis() - _lpp_at > 5000) { // both passes (measure, draw) read one query
|
||||||
_lpp.reset();
|
_lpp.reset();
|
||||||
{ CardKBBusLock bus_lock; telemetry::querySensors(sensors, board.getMCUTemperature(), _lpp); } // shares the CardKB's bus
|
{ CardKBBusLock bus_lock; queryLocalSensors(sensors, board.getMCUTemperature(), _lpp); } // shares the CardKB's bus
|
||||||
_lpp_at = millis() | 1;
|
_lpp_at = millis() | 1;
|
||||||
}
|
}
|
||||||
static const struct { uint8_t type; const char* name; } NAMES[] = {
|
static const struct { uint8_t type; const char* name; } NAMES[] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user