Merge branch 'master' into tft-gui-work

This commit is contained in:
Manuel 2024-09-18 21:49:44 +02:00 committed by GitHub
commit 002ae3178e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 124 additions and 21 deletions

@ -1 +1 @@
Subproject commit 1e212f113583dfd8d21a0daa47a32b080d3f842f Subproject commit 5709c0a05eaefccbc9cb8ed3917adbf5fd134197

View File

@ -411,7 +411,7 @@ void setup()
#endif #endif
#ifdef AQ_SET_PIN #ifdef AQ_SET_PIN
// RAK-12039 set pin for Air quality sensor // RAK-12039 set pin for Air quality sensor. Detectable on I2C after ~3 seconds, so we need to rescan later
pinMode(AQ_SET_PIN, OUTPUT); pinMode(AQ_SET_PIN, OUTPUT);
digitalWrite(AQ_SET_PIN, HIGH); digitalWrite(AQ_SET_PIN, HIGH);
#endif #endif
@ -1205,6 +1205,9 @@ extern meshtastic_DeviceMetadata getDeviceMetadata()
deviceMetadata.position_flags = config.position.position_flags; deviceMetadata.position_flags = config.position.position_flags;
deviceMetadata.hw_model = HW_VENDOR; deviceMetadata.hw_model = HW_VENDOR;
deviceMetadata.hasRemoteHardware = moduleConfig.remote_hardware.enabled; deviceMetadata.hasRemoteHardware = moduleConfig.remote_hardware.enabled;
#if !(MESHTASTIC_EXCLUDE_PKI)
deviceMetadata.hasPKC = true;
#endif
return deviceMetadata; return deviceMetadata;
} }

View File

@ -3,6 +3,8 @@
#include <cstdint> #include <cstdint>
#define ONE_DAY 24 * 60 * 60 #define ONE_DAY 24 * 60 * 60
#define ONE_MINUTE_MS 60 * 1000 #define ONE_MINUTE_MS 60 * 1000
#define THIRTY_SECONDS_MS 30 * 1000
#define FIVE_SECONDS_MS 5 * 1000
#define default_gps_update_interval IF_ROUTER(ONE_DAY, 2 * 60) #define default_gps_update_interval IF_ROUTER(ONE_DAY, 2 * 60)
#define default_telemetry_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 30 * 60) #define default_telemetry_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 30 * 60)

View File

@ -25,6 +25,7 @@
#if !MESHTASTIC_EXCLUDE_MQTT #if !MESHTASTIC_EXCLUDE_MQTT
#include "mqtt/MQTT.h" #include "mqtt/MQTT.h"
#endif #endif
#include <RTC.h>
PhoneAPI::PhoneAPI() PhoneAPI::PhoneAPI()
{ {
@ -541,14 +542,37 @@ bool PhoneAPI::available()
return false; return false;
} }
void PhoneAPI::sendNotification(meshtastic_LogRecord_Level level, uint32_t replyId, const char *message)
{
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->has_reply_id = true;
cn->reply_id = replyId;
cn->level = meshtastic_LogRecord_Level_WARNING;
cn->time = getValidTime(RTCQualityFromNet);
strncpy(cn->message, message, sizeof(cn->message));
service->sendClientNotification(cn);
delete cn;
}
/** /**
* Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool * Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool
*/ */
bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p) bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
{ {
printPacket("PACKET FROM PHONE", &p); printPacket("PACKET FROM PHONE", &p);
if (p.decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP && lastPortNumToRadio[p.decoded.portnum] &&
(millis() - lastPortNumToRadio[p.decoded.portnum]) < (THIRTY_SECONDS_MS)) {
LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum);
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "TraceRoute can only be sent once every 30 seconds");
return false;
} else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] &&
(millis() - lastPortNumToRadio[p.decoded.portnum]) < (FIVE_SECONDS_MS)) {
LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum);
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Position can only be sent once every 5 seconds");
return false;
}
lastPortNumToRadio[p.decoded.portnum] = millis();
service->handleToRadio(p); service->handleToRadio(p);
return true; return true;
} }

View File

@ -2,8 +2,10 @@
#include "Observer.h" #include "Observer.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include "meshtastic/portnums.pb.h"
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
// Make sure that we never let our packets grow too large for one BLE packet // Make sure that we never let our packets grow too large for one BLE packet
@ -48,6 +50,9 @@ class PhoneAPI
uint8_t config_state = 0; uint8_t config_state = 0;
// Hashmap of timestamps for last time we received a packet on the API per portnum
std::unordered_map<meshtastic_PortNum, uint32_t> lastPortNumToRadio;
/** /**
* Each packet sent to the phone has an incrementing count * Each packet sent to the phone has an incrementing count
*/ */
@ -99,6 +104,11 @@ class PhoneAPI
*/ */
virtual bool handleToRadio(const uint8_t *buf, size_t len); virtual bool handleToRadio(const uint8_t *buf, size_t len);
/**
* Send a (client)notification to the phone
*/
virtual void sendNotification(meshtastic_LogRecord_Level level, uint32_t replyId, const char *message);
/** /**
* Get the next packet we want to send to the phone * Get the next packet we want to send to the phone
* *

View File

@ -5,6 +5,7 @@
#define PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED
#include <pb.h> #include <pb.h>
#include "meshtastic/localonly.pb.h" #include "meshtastic/localonly.pb.h"
#include "meshtastic/mesh.pb.h"
#if PB_PROTO_HEADER_VERSION != 40 #if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator. #error Regenerate this file with the current version of nanopb generator.
@ -28,6 +29,15 @@ typedef struct _meshtastic_DeviceProfile {
/* The ModuleConfig of the node */ /* The ModuleConfig of the node */
bool has_module_config; bool has_module_config;
meshtastic_LocalModuleConfig module_config; meshtastic_LocalModuleConfig module_config;
/* Fixed position data */
bool has_fixed_position;
meshtastic_Position fixed_position;
/* Ringtone for ExternalNotification */
bool has_ringtone;
char ringtone[231];
/* Predefined messages for CannedMessage */
bool has_canned_messages;
char canned_messages[201];
} meshtastic_DeviceProfile; } meshtastic_DeviceProfile;
@ -36,8 +46,8 @@ extern "C" {
#endif #endif
/* Initializer values for message structs */ /* Initializer values for message structs */
#define meshtastic_DeviceProfile_init_default {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default} #define meshtastic_DeviceProfile_init_default {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default, false, meshtastic_Position_init_default, false, "", false, ""}
#define meshtastic_DeviceProfile_init_zero {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero} #define meshtastic_DeviceProfile_init_zero {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero, false, meshtastic_Position_init_zero, false, "", false, ""}
/* Field tags (for use in manual encoding/decoding) */ /* Field tags (for use in manual encoding/decoding) */
#define meshtastic_DeviceProfile_long_name_tag 1 #define meshtastic_DeviceProfile_long_name_tag 1
@ -45,6 +55,9 @@ extern "C" {
#define meshtastic_DeviceProfile_channel_url_tag 3 #define meshtastic_DeviceProfile_channel_url_tag 3
#define meshtastic_DeviceProfile_config_tag 4 #define meshtastic_DeviceProfile_config_tag 4
#define meshtastic_DeviceProfile_module_config_tag 5 #define meshtastic_DeviceProfile_module_config_tag 5
#define meshtastic_DeviceProfile_fixed_position_tag 6
#define meshtastic_DeviceProfile_ringtone_tag 7
#define meshtastic_DeviceProfile_canned_messages_tag 8
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define meshtastic_DeviceProfile_FIELDLIST(X, a) \ #define meshtastic_DeviceProfile_FIELDLIST(X, a) \
@ -52,11 +65,15 @@ X(a, STATIC, OPTIONAL, STRING, long_name, 1) \
X(a, STATIC, OPTIONAL, STRING, short_name, 2) \ X(a, STATIC, OPTIONAL, STRING, short_name, 2) \
X(a, CALLBACK, OPTIONAL, STRING, channel_url, 3) \ X(a, CALLBACK, OPTIONAL, STRING, channel_url, 3) \
X(a, STATIC, OPTIONAL, MESSAGE, config, 4) \ X(a, STATIC, OPTIONAL, MESSAGE, config, 4) \
X(a, STATIC, OPTIONAL, MESSAGE, module_config, 5) X(a, STATIC, OPTIONAL, MESSAGE, module_config, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, fixed_position, 6) \
X(a, STATIC, OPTIONAL, STRING, ringtone, 7) \
X(a, STATIC, OPTIONAL, STRING, canned_messages, 8)
#define meshtastic_DeviceProfile_CALLBACK pb_default_field_callback #define meshtastic_DeviceProfile_CALLBACK pb_default_field_callback
#define meshtastic_DeviceProfile_DEFAULT NULL #define meshtastic_DeviceProfile_DEFAULT NULL
#define meshtastic_DeviceProfile_config_MSGTYPE meshtastic_LocalConfig #define meshtastic_DeviceProfile_config_MSGTYPE meshtastic_LocalConfig
#define meshtastic_DeviceProfile_module_config_MSGTYPE meshtastic_LocalModuleConfig #define meshtastic_DeviceProfile_module_config_MSGTYPE meshtastic_LocalModuleConfig
#define meshtastic_DeviceProfile_fixed_position_MSGTYPE meshtastic_Position
extern const pb_msgdesc_t meshtastic_DeviceProfile_msg; extern const pb_msgdesc_t meshtastic_DeviceProfile_msg;

View File

@ -876,6 +876,8 @@ typedef struct _meshtastic_DeviceMetadata {
meshtastic_HardwareModel hw_model; meshtastic_HardwareModel hw_model;
/* Has Remote Hardware enabled */ /* Has Remote Hardware enabled */
bool hasRemoteHardware; bool hasRemoteHardware;
/* Has PKC capabilities */
bool hasPKC;
} meshtastic_DeviceMetadata; } meshtastic_DeviceMetadata;
/* Packets from the radio to the phone will appear on the fromRadio characteristic. /* Packets from the radio to the phone will appear on the fromRadio characteristic.
@ -1105,7 +1107,7 @@ extern "C" {
#define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}} #define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}}
#define meshtastic_NeighborInfo_init_default {0, 0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}} #define meshtastic_NeighborInfo_init_default {0, 0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}}
#define meshtastic_Neighbor_init_default {0, 0, 0, 0} #define meshtastic_Neighbor_init_default {0, 0, 0, 0}
#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0} #define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0}
#define meshtastic_Heartbeat_init_default {0} #define meshtastic_Heartbeat_init_default {0}
#define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default} #define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default}
#define meshtastic_ChunkedPayload_init_default {0, 0, 0, {0, {0}}} #define meshtastic_ChunkedPayload_init_default {0, 0, 0, {0, {0}}}
@ -1130,7 +1132,7 @@ extern "C" {
#define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}} #define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}}
#define meshtastic_NeighborInfo_init_zero {0, 0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}} #define meshtastic_NeighborInfo_init_zero {0, 0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}}
#define meshtastic_Neighbor_init_zero {0, 0, 0, 0} #define meshtastic_Neighbor_init_zero {0, 0, 0, 0}
#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0} #define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0}
#define meshtastic_Heartbeat_init_zero {0} #define meshtastic_Heartbeat_init_zero {0}
#define meshtastic_NodeRemoteHardwarePin_init_zero {0, false, meshtastic_RemoteHardwarePin_init_zero} #define meshtastic_NodeRemoteHardwarePin_init_zero {0, false, meshtastic_RemoteHardwarePin_init_zero}
#define meshtastic_ChunkedPayload_init_zero {0, 0, 0, {0, {0}}} #define meshtastic_ChunkedPayload_init_zero {0, 0, 0, {0, {0}}}
@ -1261,6 +1263,7 @@ extern "C" {
#define meshtastic_DeviceMetadata_position_flags_tag 8 #define meshtastic_DeviceMetadata_position_flags_tag 8
#define meshtastic_DeviceMetadata_hw_model_tag 9 #define meshtastic_DeviceMetadata_hw_model_tag 9
#define meshtastic_DeviceMetadata_hasRemoteHardware_tag 10 #define meshtastic_DeviceMetadata_hasRemoteHardware_tag 10
#define meshtastic_DeviceMetadata_hasPKC_tag 11
#define meshtastic_FromRadio_id_tag 1 #define meshtastic_FromRadio_id_tag 1
#define meshtastic_FromRadio_packet_tag 2 #define meshtastic_FromRadio_packet_tag 2
#define meshtastic_FromRadio_my_info_tag 3 #define meshtastic_FromRadio_my_info_tag 3
@ -1541,7 +1544,8 @@ X(a, STATIC, SINGULAR, BOOL, hasEthernet, 6) \
X(a, STATIC, SINGULAR, UENUM, role, 7) \ X(a, STATIC, SINGULAR, UENUM, role, 7) \
X(a, STATIC, SINGULAR, UINT32, position_flags, 8) \ X(a, STATIC, SINGULAR, UINT32, position_flags, 8) \
X(a, STATIC, SINGULAR, UENUM, hw_model, 9) \ X(a, STATIC, SINGULAR, UENUM, hw_model, 9) \
X(a, STATIC, SINGULAR, BOOL, hasRemoteHardware, 10) X(a, STATIC, SINGULAR, BOOL, hasRemoteHardware, 10) \
X(a, STATIC, SINGULAR, BOOL, hasPKC, 11)
#define meshtastic_DeviceMetadata_CALLBACK NULL #define meshtastic_DeviceMetadata_CALLBACK NULL
#define meshtastic_DeviceMetadata_DEFAULT NULL #define meshtastic_DeviceMetadata_DEFAULT NULL
@ -1640,7 +1644,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
#define meshtastic_ClientNotification_size 415 #define meshtastic_ClientNotification_size 415
#define meshtastic_Compressed_size 243 #define meshtastic_Compressed_size 243
#define meshtastic_Data_size 273 #define meshtastic_Data_size 273
#define meshtastic_DeviceMetadata_size 46 #define meshtastic_DeviceMetadata_size 48
#define meshtastic_FileInfo_size 236 #define meshtastic_FileInfo_size 236
#define meshtastic_FromRadio_size 510 #define meshtastic_FromRadio_size 510
#define meshtastic_Heartbeat_size 0 #define meshtastic_Heartbeat_size 0

View File

@ -73,12 +73,38 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
meshtastic_Channel *ch = &channels.getByIndex(mp.channel); meshtastic_Channel *ch = &channels.getByIndex(mp.channel);
// Could tighten this up further by tracking the last public_key we went an AdminMessage request to // Could tighten this up further by tracking the last public_key we went an AdminMessage request to
// and only allowing responses from that remote. // and only allowing responses from that remote.
if (!((mp.from == 0 && !config.security.is_managed) || messageIsResponse(r) || if (messageIsResponse(r)) {
(strcasecmp(ch->settings.name, Channels::adminChannel) == 0 && config.security.admin_channel_enabled) || LOG_DEBUG("Allowing admin response message\n");
(mp.pki_encrypted && memcmp(mp.public_key.bytes, config.security.admin_key[0].bytes, 32) == 0))) { } else if (mp.from == 0) {
LOG_INFO("Ignoring admin payload %i\n", r->which_payload_variant); if (config.security.is_managed) {
LOG_INFO("Ignoring local admin payload because is_managed.\n");
return handled;
}
} else if (strcasecmp(ch->settings.name, Channels::adminChannel) == 0) {
if (!config.security.admin_channel_enabled) {
LOG_INFO("Ignoring admin channel, as legacy admin is disabled.\n");
myReply = allocErrorResponse(meshtastic_Routing_Error_NOT_AUTHORIZED, &mp);
return handled;
}
} else if (mp.pki_encrypted) {
if ((config.security.admin_key[0].size == 32 &&
memcmp(mp.public_key.bytes, config.security.admin_key[0].bytes, 32) == 0) ||
(config.security.admin_key[1].size == 32 &&
memcmp(mp.public_key.bytes, config.security.admin_key[1].bytes, 32) == 0) ||
(config.security.admin_key[2].size == 32 &&
memcmp(mp.public_key.bytes, config.security.admin_key[2].bytes, 32) == 0)) {
LOG_INFO("PKC admin payload with authorized sender key.\n");
} else {
myReply = allocErrorResponse(meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED, &mp);
LOG_INFO("Received PKC admin payload, but the sender public key does not match the admin authorized key!\n");
return handled;
}
} else {
LOG_INFO("Ignoring unauthorized admin payload %i\n", r->which_payload_variant);
myReply = allocErrorResponse(meshtastic_Routing_Error_NOT_AUTHORIZED, &mp);
return handled; return handled;
} }
LOG_INFO("Handling admin payload %i\n", r->which_payload_variant); LOG_INFO("Handling admin payload %i\n", r->which_payload_variant);
// all of the get and set messages, including those for other modules, flow through here first. // all of the get and set messages, including those for other modules, flow through here first.
@ -86,6 +112,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
if (mp.from != 0 && !messageIsRequest(r) && !messageIsResponse(r)) { if (mp.from != 0 && !messageIsRequest(r) && !messageIsResponse(r)) {
if (!checkPassKey(r)) { if (!checkPassKey(r)) {
LOG_WARN("Admin message without session_key!\n"); LOG_WARN("Admin message without session_key!\n");
myReply = allocErrorResponse(meshtastic_Routing_Error_ADMIN_BAD_SESSION_KEY, &mp);
return handled; return handled;
} }
} }

View File

@ -10,11 +10,11 @@
#include "PowerFSM.h" #include "PowerFSM.h"
#include "RTC.h" #include "RTC.h"
#include "Router.h" #include "Router.h"
#include "detect/ScanI2CTwoWire.h"
#include "main.h" #include "main.h"
int32_t AirQualityTelemetryModule::runOnce() int32_t AirQualityTelemetryModule::runOnce()
{ {
int32_t result = INT32_MAX;
/* /*
Uncomment the preferences below if you want to use the module Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI. without having to configure it from the PythonAPI or WebUI.
@ -29,21 +29,36 @@ int32_t AirQualityTelemetryModule::runOnce()
if (firstTime) { if (firstTime) {
// This is the first time the OSThread library has called this function, so do some setup // This is the first time the OSThread library has called this function, so do some setup
firstTime = 0; firstTime = false;
if (moduleConfig.telemetry.air_quality_enabled) { if (moduleConfig.telemetry.air_quality_enabled) {
LOG_INFO("Air quality Telemetry: Initializing\n"); LOG_INFO("Air quality Telemetry: Initializing\n");
if (!aqi.begin_I2C()) { if (!aqi.begin_I2C()) {
LOG_WARN("Could not establish i2c connection to AQI sensor\n"); LOG_WARN("Could not establish i2c connection to AQI sensor. Rescanning...\n");
// rescan for late arriving sensors. AQI Module starts about 10 seconds into the boot so this is plenty.
uint8_t i2caddr_scan[] = {PMSA0031_ADDR};
uint8_t i2caddr_asize = 1;
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
#if defined(I2C_SDA1)
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize);
#endif
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize);
auto found = i2cScanner->find(ScanI2C::DeviceType::PMSA0031);
if (found.type != ScanI2C::DeviceType::NONE) {
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first = found.address.address;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].second =
i2cScanner->fetchI2CBus(found.address);
return 1000;
}
return disable(); return disable();
} }
return 1000; return 1000;
} }
return result; return disable();
} else { } else {
// if we somehow got to a second run of this module with measurement disabled, then just wait forever // if we somehow got to a second run of this module with measurement disabled, then just wait forever
if (!moduleConfig.telemetry.air_quality_enabled) if (!moduleConfig.telemetry.air_quality_enabled)
return result; return disable();
uint32_t now = millis(); uint32_t now = millis();
if (((lastSentToMesh == 0) || if (((lastSentToMesh == 0) ||

View File

@ -44,7 +44,7 @@ class AirQualityTelemetryModule : private concurrency::OSThread, public Protobuf
private: private:
Adafruit_PM25AQI aqi; Adafruit_PM25AQI aqi;
PM25_AQI_Data data = {0}; PM25_AQI_Data data = {0};
bool firstTime = 1; bool firstTime = true;
meshtastic_MeshPacket *lastMeasurementPacket; meshtastic_MeshPacket *lastMeasurementPacket;
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
uint32_t lastSentToMesh = 0; uint32_t lastSentToMesh = 0;

View File

@ -66,6 +66,7 @@
#define SCREEN_ROTATE #define SCREEN_ROTATE
#define SCREEN_TRANSITION_FRAMERATE 5 // fps #define SCREEN_TRANSITION_FRAMERATE 5 // fps
#define DISPLAY_FORCE_SMALL_FONTS #define DISPLAY_FORCE_SMALL_FONTS
#define TFT_BACKLIGHT_ON LOW
// Battery // Battery
@ -121,4 +122,4 @@
// cannot serve any extra function even if requested to LORA_DIO3 value is never used in src (as we are not using RF95), so no // cannot serve any extra function even if requested to LORA_DIO3 value is never used in src (as we are not using RF95), so no
// need to define, and DIO3_AS_TCXO_AT_1V8 is set so it cannot serve any extra function even if requested to (from 13.3.2.1 // need to define, and DIO3_AS_TCXO_AT_1V8 is set so it cannot serve any extra function even if requested to (from 13.3.2.1
// DioxMask in SX1262 datasheet: Note that if DIO2 or DIO3 are used to control the RF Switch or the TCXO, the IRQ will not be // DioxMask in SX1262 datasheet: Note that if DIO2 or DIO3 are used to control the RF Switch or the TCXO, the IRQ will not be
// generated even if it is mapped to the pins.) // generated even if it is mapped to the pins.)