mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
Sensors page: show placeholders for all connected sensors; support all LPP types
- SensorManager::getAvailableLPPTypes() reports which LPP types will be present based on initialized sensor flags (temp, humidity, pressure, etc.) - Sensors page renders one row per available type; shows "--" for any sensor that hasn't produced a reading yet instead of hiding the row entirely - LPPReader: add readLuminosity, readPercentage, readConcentration, readDistance - All known LPP types now have proper names and units in the sensor display Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1976,72 +1976,73 @@ public:
|
||||
} else if (_page == HomePage::SENSORS) {
|
||||
int y = 18;
|
||||
refresh_sensors();
|
||||
char buf[30];
|
||||
char name[30];
|
||||
LPPReader r(sensors_lpp.getBuffer(), sensors_lpp.getSize());
|
||||
|
||||
for (int i = 0; i < sensors_scroll_offset; i++) {
|
||||
uint8_t channel, type;
|
||||
r.readHeader(channel, type);
|
||||
r.skipData(type);
|
||||
}
|
||||
uint8_t avail_types[16];
|
||||
int avail_count = _sensors ? _sensors->getAvailableLPPTypes(avail_types, 16) : 0;
|
||||
bool need_scroll = avail_count > UI_RECENT_LIST_SIZE;
|
||||
int offset = need_scroll ? (sensors_scroll_offset % avail_count) : 0;
|
||||
int show_n = need_scroll ? UI_RECENT_LIST_SIZE : avail_count;
|
||||
|
||||
for (int i = 0; i < (sensors_scroll?UI_RECENT_LIST_SIZE:sensors_nb); i++) {
|
||||
uint8_t channel, type;
|
||||
if (!r.readHeader(channel, type)) { // reached end, reset
|
||||
r.reset();
|
||||
r.readHeader(channel, type);
|
||||
for (int i = 0; i < show_n; i++) {
|
||||
uint8_t target = avail_types[(offset + i) % avail_count];
|
||||
|
||||
// scan LPP buffer for this type
|
||||
LPPReader r(sensors_lpp.getBuffer(), sensors_lpp.getSize());
|
||||
uint8_t ch, type;
|
||||
bool found = false;
|
||||
char buf[22] = "--";
|
||||
while (r.readHeader(ch, type)) {
|
||||
if (type == target) {
|
||||
float v, v2, v3;
|
||||
switch (type) {
|
||||
case LPP_GPS:
|
||||
r.readGPS(v, v2, v3);
|
||||
if (v != 0 || v2 != 0) snprintf(buf, sizeof(buf), "%.4f %.4f", v, v2);
|
||||
break;
|
||||
case LPP_VOLTAGE: r.readVoltage(v); snprintf(buf, sizeof(buf), "%.2fV", v); break;
|
||||
case LPP_CURRENT: r.readCurrent(v); snprintf(buf, sizeof(buf), "%.3fA", v); break;
|
||||
case LPP_POWER: r.readPower(v); snprintf(buf, sizeof(buf), "%.1fW", v); break;
|
||||
case LPP_TEMPERATURE:r.readTemperature(v); snprintf(buf, sizeof(buf), "%.1f\xf8""C", v); break;
|
||||
case LPP_RELATIVE_HUMIDITY: r.readRelativeHumidity(v); snprintf(buf, sizeof(buf), "%.0f%%", v); break;
|
||||
case LPP_BAROMETRIC_PRESSURE: r.readPressure(v); snprintf(buf, sizeof(buf), "%.1fhPa", v); break;
|
||||
case LPP_ALTITUDE: r.readAltitude(v); snprintf(buf, sizeof(buf), "%.0fm", v); break;
|
||||
case LPP_LUMINOSITY: r.readLuminosity(v); snprintf(buf, sizeof(buf), "%.0flux", v); break;
|
||||
case LPP_PERCENTAGE: r.readPercentage(v); snprintf(buf, sizeof(buf), "%.0f%%", v); break;
|
||||
case LPP_DISTANCE: r.readDistance(v); snprintf(buf, sizeof(buf), "%.2fm", v); break;
|
||||
case LPP_CONCENTRATION: r.readConcentration(v); snprintf(buf, sizeof(buf), "%.0fppm", v); break;
|
||||
default: r.skipData(type); continue;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
r.skipData(type);
|
||||
}
|
||||
(void)found;
|
||||
|
||||
static const struct { uint8_t type; const char* name; } TYPE_NAMES[] = {
|
||||
{ LPP_VOLTAGE, "voltage" },
|
||||
{ LPP_GPS, "gps" },
|
||||
{ LPP_TEMPERATURE, "temp" },
|
||||
{ LPP_RELATIVE_HUMIDITY, "humidity" },
|
||||
{ LPP_BAROMETRIC_PRESSURE,"pressure" },
|
||||
{ LPP_ALTITUDE, "altitude" },
|
||||
{ LPP_CURRENT, "current" },
|
||||
{ LPP_POWER, "power" },
|
||||
{ LPP_LUMINOSITY, "light" },
|
||||
{ LPP_PERCENTAGE, "moisture" },
|
||||
{ LPP_DISTANCE, "distance" },
|
||||
{ LPP_CONCENTRATION, "CO2" },
|
||||
};
|
||||
const char* name = "sensor";
|
||||
for (auto& tn : TYPE_NAMES) { if (tn.type == target) { name = tn.name; break; } }
|
||||
|
||||
display.setCursor(0, y);
|
||||
float v;
|
||||
switch (type) {
|
||||
case LPP_GPS: // GPS
|
||||
float lat, lon, alt;
|
||||
r.readGPS(lat, lon, alt);
|
||||
strcpy(name, "gps"); sprintf(buf, "%.4f %.4f", lat, lon);
|
||||
break;
|
||||
case LPP_VOLTAGE:
|
||||
r.readVoltage(v);
|
||||
strcpy(name, "voltage"); sprintf(buf, "%6.2f", v);
|
||||
break;
|
||||
case LPP_CURRENT:
|
||||
r.readCurrent(v);
|
||||
strcpy(name, "current"); sprintf(buf, "%.3f", v);
|
||||
break;
|
||||
case LPP_TEMPERATURE:
|
||||
r.readTemperature(v);
|
||||
strcpy(name, "temperature"); sprintf(buf, "%.2f", v);
|
||||
break;
|
||||
case LPP_RELATIVE_HUMIDITY:
|
||||
r.readRelativeHumidity(v);
|
||||
strcpy(name, "humidity"); sprintf(buf, "%.2f", v);
|
||||
break;
|
||||
case LPP_BAROMETRIC_PRESSURE:
|
||||
r.readPressure(v);
|
||||
strcpy(name, "pressure"); sprintf(buf, "%.2f", v);
|
||||
break;
|
||||
case LPP_ALTITUDE:
|
||||
r.readAltitude(v);
|
||||
strcpy(name, "altitude"); sprintf(buf, "%.0f", v);
|
||||
break;
|
||||
case LPP_POWER:
|
||||
r.readPower(v);
|
||||
strcpy(name, "power"); sprintf(buf, "%6.2f", v);
|
||||
break;
|
||||
default:
|
||||
r.skipData(type);
|
||||
strcpy(name, "unk"); sprintf(buf, "");
|
||||
}
|
||||
display.setCursor(0, y);
|
||||
display.print(name);
|
||||
display.setCursor(
|
||||
display.width()-display.getTextWidth(buf)-1, y
|
||||
);
|
||||
display.setCursor(display.width() - display.getTextWidth(buf) - 1, y);
|
||||
display.print(buf);
|
||||
y = y + 12;
|
||||
y += 12;
|
||||
}
|
||||
if (sensors_scroll) sensors_scroll_offset = (sensors_scroll_offset+1)%sensors_nb;
|
||||
if (need_scroll) sensors_scroll_offset = (sensors_scroll_offset + 1) % avail_count;
|
||||
else sensors_scroll_offset = 0;
|
||||
#endif
|
||||
} else if (_page == HomePage::SETTINGS) {
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
virtual const char* getSettingValue(int i) const { return NULL; }
|
||||
virtual bool setSettingValue(const char* name, const char* value) { return false; }
|
||||
virtual LocationProvider* getLocationProvider() { return NULL; }
|
||||
virtual int getAvailableLPPTypes(uint8_t* types, int max_count) const { return 0; }
|
||||
|
||||
// Helper functions to manage setting by keys (useful in many places ...)
|
||||
const char* getSettingByKey(const char* key) {
|
||||
|
||||
@@ -540,6 +540,46 @@ bool EnvironmentSensorManager::querySensors(uint8_t requester_permissions, Cayen
|
||||
}
|
||||
|
||||
|
||||
int EnvironmentSensorManager::getAvailableLPPTypes(uint8_t* types, int max_count) const {
|
||||
int n = 0;
|
||||
auto add = [&](uint8_t t) { if (n < max_count) types[n++] = t; };
|
||||
|
||||
add(LPP_VOLTAGE); // battery voltage — always present
|
||||
|
||||
#if ENV_INCLUDE_GPS
|
||||
add(LPP_GPS);
|
||||
#endif
|
||||
|
||||
bool has_temp = AHTX0_initialized || BME680_initialized || BME280_initialized ||
|
||||
BMP280_initialized || SHTC3_initialized || SHT4X_initialized ||
|
||||
LPS22HB_initialized || MLX90614_initialized || BMP085_initialized ||
|
||||
RAK12035_initialized;
|
||||
if (has_temp) add(LPP_TEMPERATURE);
|
||||
|
||||
bool has_hum = AHTX0_initialized || BME680_initialized || BME280_initialized ||
|
||||
SHTC3_initialized || SHT4X_initialized || RAK12035_initialized;
|
||||
if (has_hum) add(LPP_RELATIVE_HUMIDITY);
|
||||
|
||||
bool has_press = BME680_initialized || LPS22HB_initialized;
|
||||
if (has_press) add(LPP_BAROMETRIC_PRESSURE);
|
||||
|
||||
bool has_alt = BME680_initialized || BME280_initialized || BMP280_initialized || BMP085_initialized;
|
||||
if (has_alt) add(LPP_ALTITUDE);
|
||||
|
||||
bool has_power = INA3221_initialized || INA219_initialized || INA260_initialized || INA226_initialized;
|
||||
if (has_power) { add(LPP_CURRENT); add(LPP_POWER); }
|
||||
|
||||
#if ENV_INCLUDE_VL53L0X
|
||||
if (VL53L0X_initialized) add(LPP_DISTANCE);
|
||||
#endif
|
||||
|
||||
#if ENV_INCLUDE_RAK12035
|
||||
if (RAK12035_initialized) add(LPP_PERCENTAGE);
|
||||
#endif
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int EnvironmentSensorManager::getNumSettings() const {
|
||||
int settings = 0;
|
||||
#if ENV_INCLUDE_GPS
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
#endif
|
||||
bool begin() override;
|
||||
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
|
||||
int getAvailableLPPTypes(uint8_t* types, int max_count) const override;
|
||||
#if ENV_INCLUDE_GPS
|
||||
void loop() override;
|
||||
#endif
|
||||
|
||||
@@ -136,6 +136,22 @@ public:
|
||||
m = getFloat(&_buf[_pos], 2, 1, true); _pos += 2;
|
||||
return _pos <= _len;
|
||||
}
|
||||
bool readLuminosity(float& lux) {
|
||||
lux = getFloat(&_buf[_pos], 2, 1, false); _pos += 2;
|
||||
return _pos <= _len;
|
||||
}
|
||||
bool readPercentage(float& pct) {
|
||||
pct = getFloat(&_buf[_pos], 1, 1, false); _pos += 1;
|
||||
return _pos <= _len;
|
||||
}
|
||||
bool readConcentration(float& ppm) {
|
||||
ppm = getFloat(&_buf[_pos], 2, 1, false); _pos += 2;
|
||||
return _pos <= _len;
|
||||
}
|
||||
bool readDistance(float& m) {
|
||||
m = getFloat(&_buf[_pos], 4, 1000, false); _pos += 4;
|
||||
return _pos <= _len;
|
||||
}
|
||||
|
||||
void skipData(uint8_t type) {
|
||||
switch (type) {
|
||||
|
||||
Reference in New Issue
Block a user