Merge branch 'master' into master

This commit is contained in:
Jonathan Bennett 2024-09-19 19:43:05 -05:00 committed by GitHub
commit 82f1be33aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 94 additions and 26 deletions

View File

@ -13,7 +13,7 @@ jobs:
uses: ./.github/workflows/build_native.yml uses: ./.github/workflows/build_native.yml
package-native: package-native:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: build-native needs: build-native
steps: steps:
- name: Checkout code - name: Checkout code

View File

@ -13,7 +13,7 @@ jobs:
uses: ./.github/workflows/build_raspbian.yml uses: ./.github/workflows/build_raspbian.yml
package-raspbian: package-raspbian:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: build-raspbian needs: build-raspbian
steps: steps:
- name: Checkout code - name: Checkout code

View File

@ -13,7 +13,7 @@ jobs:
uses: ./.github/workflows/build_raspbian_armv7l.yml uses: ./.github/workflows/build_raspbian_armv7l.yml
package-raspbian_armv7l: package-raspbian_armv7l:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: build-raspbian_armv7l needs: build-raspbian_armv7l
steps: steps:
- name: Checkout code - name: Checkout code

View File

@ -4,7 +4,7 @@ on: pull_request
jobs: jobs:
semgrep-diff: semgrep-diff:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
container: container:
image: returntocorp/semgrep image: returntocorp/semgrep

View File

@ -5,7 +5,7 @@
}, },
"core": "nRF5", "core": "nRF5",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA", "extra_flags": "-DHELTEC_T114 -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
["0x239A", "0x4405"], ["0x239A", "0x4405"],

View File

@ -5,7 +5,7 @@
}, },
"core": "nRF5", "core": "nRF5",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA", "extra_flags": "-DME25LS01_4Y10TD -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
["0x239A", "0x8029"], ["0x239A", "0x8029"],

View File

@ -5,7 +5,7 @@
}, },
"core": "nRF5", "core": "nRF5",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA", "extra_flags": "-DMS24SF1 -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
["0x239A", "0x8029"], ["0x239A", "0x8029"],

View File

@ -5,7 +5,7 @@
}, },
"core": "nRF5", "core": "nRF5",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA", "extra_flags": "-DNORDIC_PCA10059 -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
["0x239A", "0x8029"], ["0x239A", "0x8029"],

View File

@ -89,8 +89,7 @@ monitor_speed = 115200
monitor_filters = direct monitor_filters = direct
lib_deps = lib_deps =
; jgromes/RadioLib@~6.6.0 jgromes/RadioLib@~7.0.0
https://github.com/jgromes/RadioLib.git#3115fc2d6700a9aee05888791ac930a910f2628f
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306 https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
@ -158,9 +157,9 @@ lib_deps =
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502 https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
boschsensortec/BME68x Sensor Library@^1.1.40407 boschsensortec/BME68x Sensor Library@^1.1.40407
https://github.com/KodinLanewave/INA3221@^1.0.0 https://github.com/KodinLanewave/INA3221@^1.0.0
lewisxhe/SensorLib@^0.2.0 lewisxhe/SensorLib@0.2.0
mprograms/QMC5883LCompass@^1.2.0 mprograms/QMC5883LCompass@^1.2.0
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1

@ -1 +1 @@
Subproject commit 164e598734a813ae00a2a74266e9e06438f030ce Subproject commit 5709c0a05eaefccbc9cb8ed3917adbf5fd134197

View File

@ -390,7 +390,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
@ -1142,4 +1142,4 @@ void loop()
} }
// if (didWake) LOG_DEBUG("wake!\n"); // if (didWake) LOG_DEBUG("wake!\n");
} }
#endif #endif

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

@ -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.)