I don't like this formatting but I need trunk to STFU

This commit is contained in:
Ben Meadors
2023-01-18 14:51:48 -06:00
parent b218ea9ec7
commit 9046dacec8
39 changed files with 802 additions and 780 deletions

View File

@@ -2,8 +2,8 @@
#if HAS_SCREEN
#include "CannedMessageModule.h"
#include "FSCommon.h"
#include "NodeDB.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h" // neede for button bypass
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
@@ -149,10 +149,10 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
this->lastTouchMillis = 0;
validEvent = true;
}
if ((event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
if ((event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
(event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
(event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
LOG_DEBUG("Canned message event (%x)\n",event->kbchar);
LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
// pass the pressed key
this->payload = event->kbchar;
@@ -163,7 +163,8 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
if (event->inputEvent == static_cast<char>(ANYKEY)) {
LOG_DEBUG("Canned message event any key pressed\n");
// when inactive, this will switch to the freetext mode
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) ||
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
}
// pass the pressed key
@@ -176,7 +177,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
// this will send the text immediately on matrix press
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
this->payload = MATRIXKEY;
this->currentMessageIndex = event->kbchar -1;
this->currentMessageIndex = event->kbchar - 1;
this->lastTouchMillis = millis();
validEvent = true;
}
@@ -224,7 +225,8 @@ int32_t CannedMessageModule::runOnce()
this->cursor = 0;
this->destSelect = false;
this->notifyObservers(&e);
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) &&
((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
// Reset module
LOG_DEBUG("Reset due to lack of activity.\n");
e.frameChanged = true;
@@ -245,7 +247,7 @@ int32_t CannedMessageModule::runOnce()
}
} else {
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
if(strcmp (this->messages[this->currentMessageIndex], "~") == 0) {
if (strcmp(this->messages[this->currentMessageIndex], "~") == 0) {
powerFSM.trigger(EVENT_PRESS);
return INT32_MAX;
} else {
@@ -264,7 +266,7 @@ int32_t CannedMessageModule::runOnce()
this->destSelect = false;
this->notifyObservers(&e);
return 2000;
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
this->currentMessageIndex = 0;
LOG_DEBUG("First touch (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
e.frameChanged = true;
@@ -290,81 +292,81 @@ int32_t CannedMessageModule::runOnce()
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
e.frameChanged = true;
switch (this->payload) {
case 0xb4: // left
if (this->destSelect){
size_t numNodes = nodeDB.getNumNodes();
if(this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum();
}
for (unsigned int i = 0; i < numNodes; i++) {
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
this->dest = (i > 0) ? nodeDB.getNodeByIndex(i-1)->num : nodeDB.getNodeByIndex(numNodes-1)->num;
break;
}
}
if(this->dest == nodeDB.getNodeNum()) {
this->dest = NODENUM_BROADCAST;
}
}else{
if (this->cursor > 0) {
this->cursor--;
case 0xb4: // left
if (this->destSelect) {
size_t numNodes = nodeDB.getNumNodes();
if (this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum();
}
for (unsigned int i = 0; i < numNodes; i++) {
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
this->dest = (i > 0) ? nodeDB.getNodeByIndex(i - 1)->num : nodeDB.getNodeByIndex(numNodes - 1)->num;
break;
}
}
break;
case 0xb7: // right
if (this->destSelect){
size_t numNodes = nodeDB.getNumNodes();
if(this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum();
}
for (unsigned int i = 0; i < numNodes; i++) {
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
this->dest = (i < numNodes-1) ? nodeDB.getNodeByIndex(i+1)->num : nodeDB.getNodeByIndex(0)->num;
break;
}
}
if(this->dest == nodeDB.getNodeNum()) {
this->dest = NODENUM_BROADCAST;
}
}else{
if (this->cursor < this->freetext.length()) {
this->cursor++;
}
if (this->dest == nodeDB.getNodeNum()) {
this->dest = NODENUM_BROADCAST;
}
break;
case 0x08: // backspace
if (this->freetext.length() > 0) {
if(this->cursor == this->freetext.length()) {
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
} else {
this->freetext = this->freetext.substring(0, this->cursor - 1) + this->freetext.substring(this->cursor, this->freetext.length());
}
} else {
if (this->cursor > 0) {
this->cursor--;
}
break;
case 0x09: // tab
if(this->destSelect) {
this->destSelect = false;
}
break;
case 0xb7: // right
if (this->destSelect) {
size_t numNodes = nodeDB.getNumNodes();
if (this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum();
}
for (unsigned int i = 0; i < numNodes; i++) {
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
this->dest = (i < numNodes - 1) ? nodeDB.getNodeByIndex(i + 1)->num : nodeDB.getNodeByIndex(0)->num;
break;
}
}
if (this->dest == nodeDB.getNodeNum()) {
this->dest = NODENUM_BROADCAST;
}
} else {
if (this->cursor < this->freetext.length()) {
this->cursor++;
}
}
break;
case 0x08: // backspace
if (this->freetext.length() > 0) {
if (this->cursor == this->freetext.length()) {
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
} else {
this->destSelect = true;
this->freetext = this->freetext.substring(0, this->cursor - 1) +
this->freetext.substring(this->cursor, this->freetext.length());
}
break;
default:
if(this->cursor == this->freetext.length()) {
this->freetext += this->payload;
} else {
this->freetext = this->freetext.substring(0, this->cursor)
+ this->payload
+ this->freetext.substring(this->cursor);
}
this->cursor += 1;
if (this->freetext.length() > Constants_DATA_PAYLOAD_LEN) {
this->cursor = Constants_DATA_PAYLOAD_LEN;
this->freetext = this->freetext.substring(0, Constants_DATA_PAYLOAD_LEN);
}
break;
this->cursor--;
}
break;
case 0x09: // tab
if (this->destSelect) {
this->destSelect = false;
} else {
this->destSelect = true;
}
break;
default:
if (this->cursor == this->freetext.length()) {
this->freetext += this->payload;
} else {
this->freetext =
this->freetext.substring(0, this->cursor) + this->payload + this->freetext.substring(this->cursor);
}
this->cursor += 1;
if (this->freetext.length() > Constants_DATA_PAYLOAD_LEN) {
this->cursor = Constants_DATA_PAYLOAD_LEN;
this->freetext = this->freetext.substring(0, Constants_DATA_PAYLOAD_LEN);
}
break;
}
this->lastTouchMillis = millis();
this->notifyObservers(&e);
return INACTIVATE_AFTER_MS;
@@ -376,7 +378,7 @@ int32_t CannedMessageModule::runOnce()
return INACTIVATE_AFTER_MS;
}
return INT32_MAX;
return INT32_MAX;
}
const char *CannedMessageModule::getCurrentMessage()
@@ -391,14 +393,15 @@ const char *CannedMessageModule::getNextMessage()
{
return this->messages[this->getNextIndex()];
}
const char* CannedMessageModule::getNodeName(NodeNum node) {
if (node == NODENUM_BROADCAST){
const char *CannedMessageModule::getNodeName(NodeNum node)
{
if (node == NODENUM_BROADCAST) {
return "Broadcast";
}else{
} else {
NodeInfo *info = nodeDB.getNode(node);
if(info != NULL) {
if (info != NULL) {
return info->user.long_name;
}else{
} else {
return "Unknown";
}
}
@@ -444,7 +447,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
}else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
if (this->destSelect) {
@@ -460,7 +463,9 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->drawString(x + display->getWidth() - display->getStringWidth(buffer) - 1, y + 0, buffer);
}
display->setColor(WHITE);
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
display->drawStringMaxWidth(
0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(),
cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
} else {
if (this->messagesCount > 0) {
display->setTextAlignment(TEXT_ALIGN_LEFT);
@@ -479,7 +484,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
void CannedMessageModule::loadProtoForModule()
{
if (!nodeDB.loadProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(CannedMessageModuleConfig),
&CannedMessageModuleConfig_msg, &cannedMessageModuleConfig)) {
&CannedMessageModuleConfig_msg, &cannedMessageModuleConfig)) {
installDefaultCannedMessageModuleConfig();
}
}
@@ -498,8 +503,8 @@ bool CannedMessageModule::saveProtoForModule()
FS.mkdir("/prefs");
#endif
okay &= nodeDB.saveProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size,
&CannedMessageModuleConfig_msg, &cannedMessageModuleConfig);
okay &= nodeDB.saveProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, &CannedMessageModuleConfig_msg,
&cannedMessageModuleConfig);
return okay;
}
@@ -549,13 +554,13 @@ AdminMessageHandleResult CannedMessageModule::handleAdminMessageForModule(const
void CannedMessageModule::handleGetCannedMessageModuleMessages(const MeshPacket &req, AdminMessage *response)
{
LOG_DEBUG("*** handleGetCannedMessageModuleMessages\n");
if(req.decoded.want_response) {
if (req.decoded.want_response) {
response->which_payload_variant = AdminMessage_get_canned_message_module_messages_response_tag;
strncpy(response->get_canned_message_module_messages_response, cannedMessageModuleConfig.messages, sizeof(response->get_canned_message_module_messages_response));
strncpy(response->get_canned_message_module_messages_response, cannedMessageModuleConfig.messages,
sizeof(response->get_canned_message_module_messages_response));
} // Don't send anything if not instructed to. Better than asserting.
}
void CannedMessageModule::handleSetCannedMessageModuleMessages(const char *from_msg)
{
int changed = 0;
@@ -573,9 +578,7 @@ void CannedMessageModule::handleSetCannedMessageModuleMessages(const char *from_
String CannedMessageModule::drawWithCursor(String text, int cursor)
{
String result = text.substring(0, cursor)
+ "_"
+ text.substring(cursor);
String result = text.substring(0, cursor) + "_" + text.substring(cursor);
return result;
}

View File

@@ -58,19 +58,19 @@ int32_t ExternalNotificationModule::runOnce()
// If the output is turned on, turn it back off after the given period of time.
if (isNagging) {
if (externalTurnedOn[0] + (moduleConfig.external_notification.output_ms
? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < millis()) {
if (externalTurnedOn[0] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
getExternal(0) ? setExternalOff(0) : setExternalOn(0);
}
if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms
? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < millis()) {
if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
getExternal(1) ? setExternalOff(1) : setExternalOn(1);
}
if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms
? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < millis()) {
if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
}
}
@@ -93,18 +93,18 @@ void ExternalNotificationModule::setExternalOn(uint8_t index)
externalCurrentState[index] = 1;
externalTurnedOn[index] = millis();
switch(index) {
case 1:
if(moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, true);
break;
case 2:
if(moduleConfig.external_notification.output_buzzer)
digitalWrite(moduleConfig.external_notification.output_buzzer, true);
break;
default:
digitalWrite(output, (moduleConfig.external_notification.active ? true : false));
break;
switch (index) {
case 1:
if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, true);
break;
case 2:
if (moduleConfig.external_notification.output_buzzer)
digitalWrite(moduleConfig.external_notification.output_buzzer, true);
break;
default:
digitalWrite(output, (moduleConfig.external_notification.active ? true : false));
break;
}
}
@@ -113,18 +113,18 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
externalCurrentState[index] = 0;
externalTurnedOn[index] = millis();
switch(index) {
case 1:
if(moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, false);
break;
case 2:
if(moduleConfig.external_notification.output_buzzer)
digitalWrite(moduleConfig.external_notification.output_buzzer, false);
break;
default:
digitalWrite(output, (moduleConfig.external_notification.active ? false : true));
break;
switch (index) {
case 1:
if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, false);
break;
case 2:
if (moduleConfig.external_notification.output_buzzer)
digitalWrite(moduleConfig.external_notification.output_buzzer, false);
break;
default:
digitalWrite(output, (moduleConfig.external_notification.active ? false : true));
break;
}
}
@@ -133,7 +133,8 @@ bool ExternalNotificationModule::getExternal(uint8_t index)
return externalCurrentState[index];
}
void ExternalNotificationModule::stopNow() {
void ExternalNotificationModule::stopNow()
{
rtttl::stop();
nagCycleCutoff = 1; // small value
isNagging = false;
@@ -161,40 +162,39 @@ ExternalNotificationModule::ExternalNotificationModule()
// moduleConfig.external_notification.output_buzzer = 10; // RAK4631 IO6
// moduleConfig.external_notification.output_vibra = 28; // RAK4631 IO7
// moduleConfig.external_notification.nag_timeout = 300;
if (moduleConfig.external_notification.enabled) {
if (!nodeDB.loadProto(rtttlConfigFile, RTTTLConfig_size, sizeof(RTTTLConfig), &RTTTLConfig_msg, &rtttlConfig)) {
memset(rtttlConfig.ringtone, 0, sizeof(rtttlConfig.ringtone));
strncpy(rtttlConfig.ringtone, "a:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#", sizeof(rtttlConfig.ringtone));
strncpy(rtttlConfig.ringtone,
"a:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#",
sizeof(rtttlConfig.ringtone));
}
LOG_INFO("Initializing External Notification Module\n");
output = moduleConfig.external_notification.output
? moduleConfig.external_notification.output
: EXT_NOTIFICATION_MODULE_OUTPUT;
output = moduleConfig.external_notification.output ? moduleConfig.external_notification.output
: EXT_NOTIFICATION_MODULE_OUTPUT;
// Set the direction of a pin
LOG_INFO("Using Pin %i in digital mode\n", output);
pinMode(output, OUTPUT);
setExternalOff(0);
externalTurnedOn[0] = 0;
if(moduleConfig.external_notification.output_vibra) {
if (moduleConfig.external_notification.output_vibra) {
LOG_INFO("Using Pin %i for vibra motor\n", moduleConfig.external_notification.output_vibra);
pinMode(moduleConfig.external_notification.output_vibra, OUTPUT);
setExternalOff(1);
externalTurnedOn[1] = 0;
}
if(moduleConfig.external_notification.output_buzzer) {
if (moduleConfig.external_notification.output_buzzer) {
if (!moduleConfig.external_notification.use_pwm) {
LOG_INFO("Using Pin %i for buzzer\n", moduleConfig.external_notification.output_buzzer);
pinMode(moduleConfig.external_notification.output_buzzer, OUTPUT);
setExternalOff(2);
externalTurnedOn[2] = 0;
} else {
config.device.buzzer_gpio = config.device.buzzer_gpio
? config.device.buzzer_gpio
: PIN_BUZZER;
config.device.buzzer_gpio = config.device.buzzer_gpio ? config.device.buzzer_gpio : PIN_BUZZER;
// in PWM Mode we force the buzzer pin if it is set
LOG_INFO("Using Pin %i in PWM mode\n", config.device.buzzer_gpio);
}
@@ -274,7 +274,6 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
}
}
if (moduleConfig.external_notification.alert_message_vibra) {
LOG_INFO("externalNotificationModule - Notification Module (Vibra)\n");
isNagging = true;
@@ -300,7 +299,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms;
}
}
setIntervalFromNow(0); // run once so we know if we should do something
}
@@ -320,7 +319,8 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
* @return AdminMessageHandleResult HANDLED if message was handled
* HANDLED_WITH_RESULT if a result is also prepared.
*/
AdminMessageHandleResult ExternalNotificationModule::handleAdminMessageForModule(const MeshPacket &mp, AdminMessage *request, AdminMessage *response)
AdminMessageHandleResult ExternalNotificationModule::handleAdminMessageForModule(const MeshPacket &mp, AdminMessage *request,
AdminMessage *response)
{
AdminMessageHandleResult result;
@@ -347,13 +347,12 @@ AdminMessageHandleResult ExternalNotificationModule::handleAdminMessageForModule
void ExternalNotificationModule::handleGetRingtone(const MeshPacket &req, AdminMessage *response)
{
LOG_INFO("*** handleGetRingtone\n");
if(req.decoded.want_response) {
if (req.decoded.want_response) {
response->which_payload_variant = AdminMessage_get_ringtone_response_tag;
strncpy(response->get_ringtone_response, rtttlConfig.ringtone, sizeof(response->get_ringtone_response));
} // Don't send anything if not instructed to. Better than asserting.
}
void ExternalNotificationModule::handleSetRingtone(const char *from_msg)
{
int changed = 0;

View File

@@ -1,7 +1,7 @@
#pragma once
#include "ProtobufModule.h"
#include "mesh/generated/meshtastic/remote_hardware.pb.h"
#include "concurrency/OSThread.h"
#include "mesh/generated/meshtastic/remote_hardware.pb.h"
/**
* A module that provides easy low-level remote access to device hardware.
@@ -9,13 +9,14 @@
class RemoteHardwareModule : public ProtobufModule<HardwareMessage>, private concurrency::OSThread
{
/// The current set of GPIOs we've been asked to watch for changes
uint64_t watchGpios = 0;
uint64_t watchGpios = 0;
/// The previously read value of watched pins
uint64_t previousWatch = 0;
/// The timestamp of our last watch event (we throttle watches to 1 change every 30 seconds)
uint32_t lastWatchMsec = 0;
public:
/** Constructor
* name is for debugging output
@@ -32,7 +33,7 @@ class RemoteHardwareModule : public ProtobufModule<HardwareMessage>, private con
/**
* Periodically read the gpios we have been asked to WATCH, if they have changed,
* broadcast a message with the change information.
*
*
* The method that will be called each time our thread gets a chance to run
*
* Returns desired period for next invocation (or RUN_SAME for no change)

View File

@@ -9,13 +9,12 @@
#include "main.h"
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
#include "MeshService.h"
int32_t DeviceTelemetryModule::runOnce()
{
uint32_t now = millis();
if ((lastSentToMesh == 0 ||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) &&
if ((lastSentToMesh == 0 ||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) &&
airTime->isTxAllowedChannelUtil() && airTime->isTxAllowedAirUtil()) {
sendTelemetry();
lastSentToMesh = now;
@@ -31,13 +30,10 @@ bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemet
{
if (t->which_variant == Telemetry_device_metrics_tag) {
const char *sender = getSenderShortName(mp);
LOG_INFO("(Received from %s): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
sender,
t->variant.device_metrics.air_util_tx,
t->variant.device_metrics.channel_utilization,
t->variant.device_metrics.battery_level,
t->variant.device_metrics.voltage);
LOG_INFO("(Received from %s): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n", sender,
t->variant.device_metrics.air_util_tx, t->variant.device_metrics.channel_utilization,
t->variant.device_metrics.battery_level, t->variant.device_metrics.voltage);
lastMeasurementPacket = packetPool.allocCopy(mp);
@@ -58,11 +54,9 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
t.variant.device_metrics.channel_utilization = myNodeInfo.channel_utilization;
t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
LOG_INFO("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
t.variant.device_metrics.air_util_tx,
t.variant.device_metrics.channel_utilization,
t.variant.device_metrics.battery_level,
t.variant.device_metrics.voltage);
LOG_INFO("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
t.variant.device_metrics.air_util_tx, t.variant.device_metrics.channel_utilization,
t.variant.device_metrics.battery_level, t.variant.device_metrics.voltage);
MeshPacket *p = allocDataProtobuf(t);
p->to = dest;

View File

@@ -11,8 +11,8 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
DeviceTelemetryModule()
: concurrency::OSThread("DeviceTelemetryModule"), ProtobufModule("DeviceTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
{
lastMeasurementPacket = nullptr;
setIntervalFromNow(10 * 1000);
lastMeasurementPacket = nullptr;
setIntervalFromNow(10 * 1000);
}
virtual bool wantUIFrame() { return false; }

View File

@@ -9,18 +9,17 @@
#include "main.h"
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
#include "MeshService.h"
// Sensors
#include "Sensor/BMP280Sensor.h"
#include "Sensor/BME280Sensor.h"
#include "Sensor/BME680Sensor.h"
#include "Sensor/MCP9808Sensor.h"
#include "Sensor/INA260Sensor.h"
#include "Sensor/BMP280Sensor.h"
#include "Sensor/INA219Sensor.h"
#include "Sensor/SHTC3Sensor.h"
#include "Sensor/INA260Sensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
#include "Sensor/SHT31Sensor.h"
#include "Sensor/SHTC3Sensor.h"
BMP280Sensor bmp280Sensor;
BME280Sensor bme280Sensor;
@@ -59,13 +58,12 @@ int32_t EnvironmentTelemetryModule::runOnce()
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
// moduleConfig.telemetry.environment_measurement_enabled = 1;
// moduleConfig.telemetry.environment_screen_enabled = 1;
// moduleConfig.telemetry.environment_update_interval = 45;
if (!(moduleConfig.telemetry.environment_measurement_enabled ||
moduleConfig.telemetry.environment_screen_enabled)) {
if (!(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) {
// If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it
return disable();
}
@@ -78,15 +76,15 @@ int32_t EnvironmentTelemetryModule::runOnce()
LOG_INFO("Environment Telemetry: Initializing\n");
// it's possible to have this module enabled, only for displaying values on the screen.
// therefore, we should only enable the sensor loop if measurement is also enabled
if (bmp280Sensor.hasSensor())
if (bmp280Sensor.hasSensor())
result = bmp280Sensor.runOnce();
if (bme280Sensor.hasSensor())
if (bme280Sensor.hasSensor())
result = bme280Sensor.runOnce();
if (bme680Sensor.hasSensor())
if (bme680Sensor.hasSensor())
result = bme680Sensor.runOnce();
if (mcp9808Sensor.hasSensor())
if (mcp9808Sensor.hasSensor())
result = mcp9808Sensor.runOnce();
if (ina260Sensor.hasSensor())
if (ina260Sensor.hasSensor())
result = ina260Sensor.runOnce();
if (ina219Sensor.hasSensor())
result = ina219Sensor.runOnce();
@@ -105,8 +103,8 @@ int32_t EnvironmentTelemetryModule::runOnce()
return result;
uint32_t now = millis();
if ((lastSentToMesh == 0 ||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval)) &&
if ((lastSentToMesh == 0 ||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval)) &&
airTime->isTxAllowedAirUtil()) {
sendTelemetry();
lastSentToMesh = now;
@@ -173,13 +171,15 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
}
display->drawString(x, y += fontHeight(FONT_MEDIUM) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
display->drawString(x, y += fontHeight(FONT_SMALL) - 2,
"Temp/Hum: " + last_temp + " / " + String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%");
"Temp/Hum: " + last_temp + " / " +
String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%");
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0)
display->drawString(x, y += fontHeight(FONT_SMALL),
"Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA");
"Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA");
if (lastMeasurement.variant.environment_metrics.voltage != 0)
display->drawString(x, y += fontHeight(FONT_SMALL),
"Volt/Cur: " + String(lastMeasurement.variant.environment_metrics.voltage, 0) + "V / " + String(lastMeasurement.variant.environment_metrics.current, 0) + "mA");
"Volt/Cur: " + String(lastMeasurement.variant.environment_metrics.voltage, 0) + "V / " +
String(lastMeasurement.variant.environment_metrics.current, 0) + "mA");
}
bool EnvironmentTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t)
@@ -187,14 +187,11 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Te
if (t->which_variant == Telemetry_environment_metrics_tag) {
const char *sender = getSenderShortName(mp);
LOG_INFO("(Received from %s): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
sender,
t->variant.environment_metrics.barometric_pressure,
t->variant.environment_metrics.current,
t->variant.environment_metrics.gas_resistance,
t->variant.environment_metrics.relative_humidity,
t->variant.environment_metrics.temperature,
t->variant.environment_metrics.voltage);
LOG_INFO("(Received from %s): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, "
"temperature=%f, voltage=%f\n",
sender, t->variant.environment_metrics.barometric_pressure, t->variant.environment_metrics.current,
t->variant.environment_metrics.gas_resistance, t->variant.environment_metrics.relative_humidity,
t->variant.environment_metrics.temperature, t->variant.environment_metrics.voltage);
lastMeasurementPacket = packetPool.allocCopy(mp);
}
@@ -234,13 +231,11 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
if (ina260Sensor.hasSensor())
ina260Sensor.getMetrics(&m);
LOG_INFO("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
m.variant.environment_metrics.barometric_pressure,
m.variant.environment_metrics.current,
m.variant.environment_metrics.gas_resistance,
m.variant.environment_metrics.relative_humidity,
m.variant.environment_metrics.temperature,
m.variant.environment_metrics.voltage);
LOG_INFO(
"(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current,
m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity,
m.variant.environment_metrics.temperature, m.variant.environment_metrics.voltage);
sensor_read_error_count = 0;

View File

@@ -12,8 +12,8 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu
: concurrency::OSThread("EnvironmentTelemetryModule"),
ProtobufModule("EnvironmentTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
{
lastMeasurementPacket = nullptr;
setIntervalFromNow(10 * 1000);
lastMeasurementPacket = nullptr;
setIntervalFromNow(10 * 1000);
}
virtual bool wantUIFrame() override;
#if !HAS_SCREEN

View File

@@ -1,35 +1,33 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "BME280Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_BME280.h>
#include <typeinfo>
BME280Sensor::BME280Sensor() :
TelemetrySensor(TelemetrySensorType_BME280, "BME280")
{
}
BME280Sensor::BME280Sensor() : TelemetrySensor(TelemetrySensorType_BME280, "BME280") {}
int32_t BME280Sensor::runOnce() {
int32_t BME280Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = bme280.begin(nodeTelemetrySensorsMap[sensorType]);
bme280.setSampling( Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
Adafruit_BME280::SAMPLING_X1, // Pressure oversampling
Adafruit_BME280::SAMPLING_X1, // Humidity oversampling
Adafruit_BME280::FILTER_OFF,
Adafruit_BME280::STANDBY_MS_1000);
status = bme280.begin(nodeTelemetrySensorsMap[sensorType]);
bme280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
Adafruit_BME280::SAMPLING_X1, // Pressure oversampling
Adafruit_BME280::SAMPLING_X1, // Humidity oversampling
Adafruit_BME280::FILTER_OFF, Adafruit_BME280::STANDBY_MS_1000);
return initI2CSensor();
}
void BME280Sensor::setup() { }
void BME280Sensor::setup() {}
bool BME280Sensor::getMetrics(Telemetry *measurement) {
bool BME280Sensor::getMetrics(Telemetry *measurement)
{
LOG_DEBUG("BME280Sensor::getMetrics\n");
bme280.takeForcedMeasurement();
measurement->variant.environment_metrics.temperature = bme280.readTemperature();
@@ -37,4 +35,4 @@ bool BME280Sensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;
return true;
}
}

View File

@@ -2,15 +2,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_BME280.h>
class BME280Sensor : virtual public TelemetrySensor {
private:
class BME280Sensor : virtual public TelemetrySensor
{
private:
Adafruit_BME280 bme280;
protected:
protected:
virtual void setup() override;
public:
public:
BME280Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -1,15 +1,13 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "BME680Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_BME680.h>
BME680Sensor::BME680Sensor() :
TelemetrySensor(TelemetrySensorType_BME680, "BME680")
{
}
BME680Sensor::BME680Sensor() : TelemetrySensor(TelemetrySensorType_BME680, "BME680") {}
int32_t BME680Sensor::runOnce() {
int32_t BME680Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
@@ -19,9 +17,10 @@ int32_t BME680Sensor::runOnce() {
return initI2CSensor();
}
void BME680Sensor::setup() { }
void BME680Sensor::setup() {}
bool BME680Sensor::getMetrics(Telemetry *measurement) {
bool BME680Sensor::getMetrics(Telemetry *measurement)
{
bme680.performReading();
measurement->variant.environment_metrics.temperature = bme680.temperature;
measurement->variant.environment_metrics.relative_humidity = bme680.humidity;
@@ -29,4 +28,4 @@ bool BME680Sensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.gas_resistance = bme680.gas_resistance / 1000.0;
return true;
}
}

View File

@@ -2,15 +2,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_BME680.h>
class BME680Sensor : virtual public TelemetrySensor {
private:
class BME680Sensor : virtual public TelemetrySensor
{
private:
Adafruit_BME680 bme680;
protected:
protected:
virtual void setup() override;
public:
public:
BME680Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -1,38 +1,36 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "BMP280Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_BMP280.h>
#include <typeinfo>
BMP280Sensor::BMP280Sensor() :
TelemetrySensor(TelemetrySensorType_BMP280, "BMP280")
{
}
BMP280Sensor::BMP280Sensor() : TelemetrySensor(TelemetrySensorType_BMP280, "BMP280") {}
int32_t BMP280Sensor::runOnce() {
int32_t BMP280Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType]);
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType]);
bmp280.setSampling( Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
Adafruit_BMP280::SAMPLING_X1, // Pressure oversampling
Adafruit_BMP280::FILTER_OFF,
Adafruit_BMP280::STANDBY_MS_1000);
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
Adafruit_BMP280::SAMPLING_X1, // Pressure oversampling
Adafruit_BMP280::FILTER_OFF, Adafruit_BMP280::STANDBY_MS_1000);
return initI2CSensor();
}
void BMP280Sensor::setup() { }
void BMP280Sensor::setup() {}
bool BMP280Sensor::getMetrics(Telemetry *measurement) {
bool BMP280Sensor::getMetrics(Telemetry *measurement)
{
LOG_DEBUG("BMP280Sensor::getMetrics\n");
bmp280.takeForcedMeasurement();
measurement->variant.environment_metrics.temperature = bmp280.readTemperature();
measurement->variant.environment_metrics.barometric_pressure = bmp280.readPressure() / 100.0F;
return true;
}
}

View File

@@ -2,15 +2,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_BMP280.h>
class BMP280Sensor : virtual public TelemetrySensor {
private:
class BMP280Sensor : virtual public TelemetrySensor
{
private:
Adafruit_BMP280 bmp280;
protected:
protected:
virtual void setup() override;
public:
public:
BMP280Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -1,15 +1,13 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "INA219Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_INA219.h>
INA219Sensor::INA219Sensor() :
TelemetrySensor(TelemetrySensorType_INA219, "INA219")
{
}
INA219Sensor::INA219Sensor() : TelemetrySensor(TelemetrySensorType_INA219, "INA219") {}
int32_t INA219Sensor::runOnce() {
int32_t INA219Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
@@ -19,12 +17,11 @@ int32_t INA219Sensor::runOnce() {
return initI2CSensor();
}
void INA219Sensor::setup()
{
}
void INA219Sensor::setup() {}
bool INA219Sensor::getMetrics(Telemetry *measurement) {
bool INA219Sensor::getMetrics(Telemetry *measurement)
{
measurement->variant.environment_metrics.voltage = ina219.getBusVoltage_V();
measurement->variant.environment_metrics.current = ina219.getCurrent_mA();
return true;
}
}

View File

@@ -2,16 +2,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_INA219.h>
class INA219Sensor : virtual public TelemetrySensor {
private:
class INA219Sensor : virtual public TelemetrySensor
{
private:
Adafruit_INA219 ina219;
protected:
protected:
virtual void setup() override;
public:
public:
INA219Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -1,15 +1,13 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "INA260Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_INA260.h>
INA260Sensor::INA260Sensor() :
TelemetrySensor(TelemetrySensorType_INA260, "INA260")
{
}
INA260Sensor::INA260Sensor() : TelemetrySensor(TelemetrySensorType_INA260, "INA260") {}
int32_t INA260Sensor::runOnce() {
int32_t INA260Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
@@ -18,13 +16,12 @@ int32_t INA260Sensor::runOnce() {
return initI2CSensor();
}
void INA260Sensor::setup()
{
}
void INA260Sensor::setup() {}
bool INA260Sensor::getMetrics(Telemetry *measurement) {
bool INA260Sensor::getMetrics(Telemetry *measurement)
{
// mV conversion to V
measurement->variant.environment_metrics.voltage = ina260.readBusVoltage() / 1000;
measurement->variant.environment_metrics.current = ina260.readCurrent();
return true;
}
}

View File

@@ -2,16 +2,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_INA260.h>
class INA260Sensor : virtual public TelemetrySensor {
private:
class INA260Sensor : virtual public TelemetrySensor
{
private:
Adafruit_INA260 ina260 = Adafruit_INA260();
protected:
protected:
virtual void setup() override;
public:
public:
INA260Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -1,16 +1,14 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "LPS22HBSensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_LPS2X.h>
#include <Adafruit_Sensor.h>
LPS22HBSensor::LPS22HBSensor() :
TelemetrySensor(TelemetrySensorType_LPS22, "LPS22HB")
{
}
LPS22HBSensor::LPS22HBSensor() : TelemetrySensor(TelemetrySensorType_LPS22, "LPS22HB") {}
int32_t LPS22HBSensor::runOnce() {
int32_t LPS22HBSensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
@@ -19,12 +17,13 @@ int32_t LPS22HBSensor::runOnce() {
return initI2CSensor();
}
void LPS22HBSensor::setup()
void LPS22HBSensor::setup()
{
lps22hb.setDataRate(LPS22_RATE_10_HZ);
}
bool LPS22HBSensor::getMetrics(Telemetry *measurement) {
bool LPS22HBSensor::getMetrics(Telemetry *measurement)
{
sensors_event_t temp;
sensors_event_t pressure;
lps22hb.getEvent(&pressure, &temp);
@@ -33,4 +32,4 @@ bool LPS22HBSensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.barometric_pressure = pressure.pressure;
return true;
}
}

View File

@@ -3,15 +3,16 @@
#include <Adafruit_LPS2X.h>
#include <Adafruit_Sensor.h>
class LPS22HBSensor : virtual public TelemetrySensor {
private:
class LPS22HBSensor : virtual public TelemetrySensor
{
private:
Adafruit_LPS22 lps22hb;
protected:
protected:
virtual void setup() override;
public:
public:
LPS22HBSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -1,15 +1,13 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "MCP9808Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_MCP9808.h>
MCP9808Sensor::MCP9808Sensor() :
TelemetrySensor(TelemetrySensorType_MCP9808, "MCP9808")
{
}
MCP9808Sensor::MCP9808Sensor() : TelemetrySensor(TelemetrySensorType_MCP9808, "MCP9808") {}
int32_t MCP9808Sensor::runOnce() {
int32_t MCP9808Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
@@ -18,12 +16,14 @@ int32_t MCP9808Sensor::runOnce() {
return initI2CSensor();
}
void MCP9808Sensor::setup() {
void MCP9808Sensor::setup()
{
mcp9808.setResolution(2);
}
bool MCP9808Sensor::getMetrics(Telemetry *measurement) {
bool MCP9808Sensor::getMetrics(Telemetry *measurement)
{
LOG_DEBUG("MCP9808Sensor::getMetrics\n");
measurement->variant.environment_metrics.temperature = mcp9808.readTempC();
return true;
}
}

View File

@@ -2,15 +2,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h>
class MCP9808Sensor : virtual public TelemetrySensor {
private:
class MCP9808Sensor : virtual public TelemetrySensor
{
private:
Adafruit_MCP9808 mcp9808;
protected:
protected:
virtual void setup() override;
public:
public:
MCP9808Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -1,31 +1,30 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "SHT31Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_SHT31.h>
SHT31Sensor::SHT31Sensor() :
TelemetrySensor(TelemetrySensorType_SHT31, "SHT31")
{
}
SHT31Sensor::SHT31Sensor() : TelemetrySensor(TelemetrySensorType_SHT31, "SHT31") {}
int32_t SHT31Sensor::runOnce() {
int32_t SHT31Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = sht31.begin();
status = sht31.begin();
return initI2CSensor();
}
void SHT31Sensor::setup()
void SHT31Sensor::setup()
{
// Set up oversampling and filter initialization
}
bool SHT31Sensor::getMetrics(Telemetry *measurement) {
bool SHT31Sensor::getMetrics(Telemetry *measurement)
{
measurement->variant.environment_metrics.temperature = sht31.readTemperature();
measurement->variant.environment_metrics.relative_humidity = sht31.readHumidity();
return true;
}
}

View File

@@ -2,15 +2,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_SHT31.h>
class SHT31Sensor : virtual public TelemetrySensor {
private:
class SHT31Sensor : virtual public TelemetrySensor
{
private:
Adafruit_SHT31 sht31 = Adafruit_SHT31();
protected:
protected:
virtual void setup() override;
public:
public:
SHT31Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -1,29 +1,28 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "SHTC3Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_SHTC3.h>
SHTC3Sensor::SHTC3Sensor() :
TelemetrySensor(TelemetrySensorType_SHTC3, "SHTC3")
{
}
SHTC3Sensor::SHTC3Sensor() : TelemetrySensor(TelemetrySensorType_SHTC3, "SHTC3") {}
int32_t SHTC3Sensor::runOnce() {
int32_t SHTC3Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = shtc3.begin();
status = shtc3.begin();
return initI2CSensor();
}
void SHTC3Sensor::setup()
void SHTC3Sensor::setup()
{
// Set up oversampling and filter initialization
}
bool SHTC3Sensor::getMetrics(Telemetry *measurement) {
bool SHTC3Sensor::getMetrics(Telemetry *measurement)
{
sensors_event_t humidity, temp;
shtc3.getEvent(&humidity, &temp);
@@ -31,4 +30,4 @@ bool SHTC3Sensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
return true;
}
}

View File

@@ -2,15 +2,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_SHTC3.h>
class SHTC3Sensor : virtual public TelemetrySensor {
private:
class SHTC3Sensor : virtual public TelemetrySensor
{
private:
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();
protected:
protected:
virtual void setup() override;
public:
public:
SHTC3Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};
};

View File

@@ -19,7 +19,8 @@ class TelemetrySensor
TelemetrySensorType sensorType;
unsigned status;
int32_t initI2CSensor() {
int32_t initI2CSensor()
{
if (!status) {
LOG_WARN("Could not connect to detected %s sensor.\n Removing from nodeTelemetrySensorsMap.\n", sensorName);
nodeTelemetrySensorsMap[sensorType] = 0;
@@ -32,9 +33,7 @@ class TelemetrySensor
virtual void setup();
public:
bool hasSensor() {
return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0;
}
bool hasSensor() { return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0; }
virtual int32_t runOnce() = 0;
virtual bool getMetrics(Telemetry *measurement) = 0;

View File

@@ -63,7 +63,8 @@ void StoreForwardModule::populatePSRAM()
https://learn.upesy.com/en/programmation/psram.html#psram-tab
*/
LOG_DEBUG("*** Before PSRAM initilization: heap %d/%d PSRAM %d/%d\n", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getFreePsram(), ESP.getPsramSize());
LOG_DEBUG("*** Before PSRAM initilization: heap %d/%d PSRAM %d/%d\n", ESP.getFreeHeap(), ESP.getHeapSize(),
ESP.getFreePsram(), ESP.getPsramSize());
this->packetHistoryTXQueue =
static_cast<PacketHistoryStruct *>(ps_calloc(this->historyReturnMax, sizeof(PacketHistoryStruct)));
@@ -76,7 +77,8 @@ void StoreForwardModule::populatePSRAM()
this->packetHistory = static_cast<PacketHistoryStruct *>(ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct)));
LOG_DEBUG("*** After PSRAM initilization: heap %d/%d PSRAM %d/%d\n", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getFreePsram(), ESP.getPsramSize());
LOG_DEBUG("*** After PSRAM initilization: heap %d/%d PSRAM %d/%d\n", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getFreePsram(),
ESP.getPsramSize());
LOG_DEBUG("*** numberOfPackets for packetHistory - %u\n", numberOfPackets);
}
@@ -296,123 +298,125 @@ bool StoreForwardModule::handleReceivedProtobuf(const MeshPacket &mp, StoreAndFo
requests++;
switch (p->rr) {
case StoreAndForward_RequestResponse_CLIENT_ERROR:
case StoreAndForward_RequestResponse_CLIENT_ABORT:
if(is_server) {
// stop sending stuff, the client wants to abort or has another error
if ((this->busy) && (this->busyTo == getFrom(&mp))) {
LOG_ERROR("*** Client in ERROR or ABORT requested\n");
this->packetHistoryTXQueue_index = 0;
this->busy = false;
}
case StoreAndForward_RequestResponse_CLIENT_ERROR:
case StoreAndForward_RequestResponse_CLIENT_ABORT:
if (is_server) {
// stop sending stuff, the client wants to abort or has another error
if ((this->busy) && (this->busyTo == getFrom(&mp))) {
LOG_ERROR("*** Client in ERROR or ABORT requested\n");
this->packetHistoryTXQueue_index = 0;
this->busy = false;
}
break;
}
break;
case StoreAndForward_RequestResponse_CLIENT_HISTORY:
if(is_server) {
requests_history++;
LOG_INFO("*** Client Request to send HISTORY\n");
// Send the last 60 minutes of messages.
if (this->busy) {
storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_ROUTER_BUSY);
LOG_INFO("*** S&F - Busy. Try again shortly.\n");
case StoreAndForward_RequestResponse_CLIENT_HISTORY:
if (is_server) {
requests_history++;
LOG_INFO("*** Client Request to send HISTORY\n");
// Send the last 60 minutes of messages.
if (this->busy) {
storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_ROUTER_BUSY);
LOG_INFO("*** S&F - Busy. Try again shortly.\n");
} else {
if ((p->which_variant == StoreAndForward_history_tag) && (p->variant.history.window > 0)) {
storeForwardModule->historySend(p->variant.history.window * 60000, getFrom(&mp)); // window is in minutes
} else {
if ((p->which_variant == StoreAndForward_history_tag) && (p->variant.history.window > 0)){
storeForwardModule->historySend(p->variant.history.window * 60000, getFrom(&mp)); // window is in minutes
} else {
storeForwardModule->historySend(historyReturnWindow * 60000, getFrom(&mp)); // defaults to 4 hours
}
storeForwardModule->historySend(historyReturnWindow * 60000, getFrom(&mp)); // defaults to 4 hours
}
}
break;
}
break;
case StoreAndForward_RequestResponse_CLIENT_PING:
if(is_server) {
LOG_INFO("*** StoreAndForward_RequestResponse_CLIENT_PING\n");
// respond with a ROUTER PONG
storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_ROUTER_PONG);
case StoreAndForward_RequestResponse_CLIENT_PING:
if (is_server) {
LOG_INFO("*** StoreAndForward_RequestResponse_CLIENT_PING\n");
// respond with a ROUTER PONG
storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_ROUTER_PONG);
}
break;
case StoreAndForward_RequestResponse_CLIENT_PONG:
if (is_server) {
LOG_INFO("*** StoreAndForward_RequestResponse_CLIENT_PONG\n");
// The Client is alive, update NodeDB
nodeDB.updateFrom(mp);
}
break;
case StoreAndForward_RequestResponse_CLIENT_STATS:
if (is_server) {
LOG_INFO("*** Client Request to send STATS\n");
if (this->busy) {
storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_ROUTER_BUSY);
LOG_INFO("*** S&F - Busy. Try again shortly.\n");
} else {
storeForwardModule->statsSend(getFrom(&mp));
}
break;
}
break;
case StoreAndForward_RequestResponse_CLIENT_PONG:
if(is_server) {
LOG_INFO("*** StoreAndForward_RequestResponse_CLIENT_PONG\n");
// The Client is alive, update NodeDB
nodeDB.updateFrom(mp);
case StoreAndForward_RequestResponse_ROUTER_ERROR:
case StoreAndForward_RequestResponse_ROUTER_BUSY:
if (is_client) {
LOG_DEBUG("*** StoreAndForward_RequestResponse_ROUTER_BUSY\n");
// retry in messages_saved * packetTimeMax ms
retry_delay =
millis() + packetHistoryCurrent * packetTimeMax * (StoreAndForward_RequestResponse_ROUTER_ERROR ? 2 : 1);
}
break;
case StoreAndForward_RequestResponse_ROUTER_PONG:
// A router responded, this is equal to receiving a heartbeat
case StoreAndForward_RequestResponse_ROUTER_HEARTBEAT:
if (is_client) {
// register heartbeat and interval
if (p->which_variant == StoreAndForward_heartbeat_tag) {
heartbeatInterval = p->variant.heartbeat.period;
}
break;
lastHeartbeat = millis();
LOG_INFO("*** StoreAndForward Heartbeat received\n");
}
break;
case StoreAndForward_RequestResponse_CLIENT_STATS:
if(is_server) {
LOG_INFO("*** Client Request to send STATS\n");
if (this->busy) {
storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_ROUTER_BUSY);
LOG_INFO("*** S&F - Busy. Try again shortly.\n");
} else {
storeForwardModule->statsSend(getFrom(&mp));
}
case StoreAndForward_RequestResponse_ROUTER_PING:
if (is_client) {
LOG_DEBUG("*** StoreAndForward_RequestResponse_ROUTER_PING\n");
// respond with a CLIENT PONG
storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_CLIENT_PONG);
}
break;
case StoreAndForward_RequestResponse_ROUTER_STATS:
if (is_client) {
LOG_DEBUG("*** Router Response STATS\n");
// These fields only have informational purpose on a client. Fill them to consume later.
if (p->which_variant == StoreAndForward_stats_tag) {
this->packetHistoryMax = p->variant.stats.messages_total;
this->packetHistoryCurrent = p->variant.stats.messages_saved;
this->records = p->variant.stats.messages_max;
this->requests = p->variant.stats.requests;
this->requests_history = p->variant.stats.requests_history;
this->heartbeat = p->variant.stats.heartbeat;
this->historyReturnMax = p->variant.stats.return_max;
this->historyReturnWindow = p->variant.stats.return_window;
}
break;
}
break;
case StoreAndForward_RequestResponse_ROUTER_ERROR:
case StoreAndForward_RequestResponse_ROUTER_BUSY:
if(is_client) {
LOG_DEBUG("*** StoreAndForward_RequestResponse_ROUTER_BUSY\n");
// retry in messages_saved * packetTimeMax ms
retry_delay = millis() + packetHistoryCurrent * packetTimeMax * (StoreAndForward_RequestResponse_ROUTER_ERROR ? 2 : 1);
case StoreAndForward_RequestResponse_ROUTER_HISTORY:
if (is_client) {
// These fields only have informational purpose on a client. Fill them to consume later.
if (p->which_variant == StoreAndForward_history_tag) {
this->historyReturnWindow = p->variant.history.window / 60000;
LOG_INFO("*** Router Response HISTORY - Sending %d messages from last %d minutes\n",
p->variant.history.history_messages, this->historyReturnWindow);
}
break;
}
break;
case StoreAndForward_RequestResponse_ROUTER_PONG:
// A router responded, this is equal to receiving a heartbeat
case StoreAndForward_RequestResponse_ROUTER_HEARTBEAT:
if(is_client) {
// register heartbeat and interval
if (p->which_variant == StoreAndForward_heartbeat_tag) {
heartbeatInterval = p->variant.heartbeat.period;
}
lastHeartbeat = millis();
LOG_INFO("*** StoreAndForward Heartbeat received\n");
}
break;
case StoreAndForward_RequestResponse_ROUTER_PING:
if(is_client) {
LOG_DEBUG("*** StoreAndForward_RequestResponse_ROUTER_PING\n");
// respond with a CLIENT PONG
storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_CLIENT_PONG);
}
break;
case StoreAndForward_RequestResponse_ROUTER_STATS:
if(is_client) {
LOG_DEBUG("*** Router Response STATS\n");
// These fields only have informational purpose on a client. Fill them to consume later.
if (p->which_variant == StoreAndForward_stats_tag) {
this->packetHistoryMax = p->variant.stats.messages_total;
this->packetHistoryCurrent = p->variant.stats.messages_saved;
this->records = p->variant.stats.messages_max;
this->requests = p->variant.stats.requests;
this->requests_history = p->variant.stats.requests_history;
this->heartbeat = p->variant.stats.heartbeat;
this->historyReturnMax = p->variant.stats.return_max;
this->historyReturnWindow = p->variant.stats.return_window;
}
}
break;
case StoreAndForward_RequestResponse_ROUTER_HISTORY:
if(is_client) {
// These fields only have informational purpose on a client. Fill them to consume later.
if (p->which_variant == StoreAndForward_history_tag) {
this->historyReturnWindow = p->variant.history.window / 60000;
LOG_INFO("*** Router Response HISTORY - Sending %d messages from last %d minutes\n", p->variant.history.history_messages, this->historyReturnWindow);
}
}
break;
default:
assert(0); // unexpected state
default:
assert(0); // unexpected state
}
return true; // There's no need for others to look at this message.
}
@@ -437,7 +441,8 @@ StoreForwardModule::StoreForwardModule()
if (moduleConfig.store_forward.enabled) {
// Router
if ((config.device.role == Config_DeviceConfig_Role_ROUTER) || (config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT)) {
if ((config.device.role == Config_DeviceConfig_Role_ROUTER) ||
(config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT)) {
LOG_INFO("*** Initializing Store & Forward Module in Router mode\n");
if (ESP.getPsramSize() > 0) {
if (ESP.getFreePsram() >= 1024 * 1024) {
@@ -474,7 +479,8 @@ StoreForwardModule::StoreForwardModule()
// Client
}
if ((config.device.role == Config_DeviceConfig_Role_CLIENT) || (config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT)) {
if ((config.device.role == Config_DeviceConfig_Role_CLIENT) ||
(config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT)) {
is_client = true;
LOG_INFO("*** Initializing Store & Forward Module in Client mode\n");
}

View File

@@ -66,12 +66,12 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
*/
virtual bool wantPacket(const MeshPacket *p) override
{
switch(p->decoded.portnum) {
case PortNum_TEXT_MESSAGE_APP:
case PortNum_STORE_FORWARD_APP:
return true;
default:
return false;
switch (p->decoded.portnum) {
case PortNum_TEXT_MESSAGE_APP:
case PortNum_STORE_FORWARD_APP:
return true;
default:
return false;
}
}
@@ -79,10 +79,10 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
void populatePSRAM();
// S&F Defaults
uint32_t historyReturnMax = 250; // 250 records
uint32_t historyReturnMax = 250; // 250 records
uint32_t historyReturnWindow = 240; // 4 hours
uint32_t records = 0; // Calculated
bool heartbeat = false; // No heartbeat.
uint32_t records = 0; // Calculated
bool heartbeat = false; // No heartbeat.
// stats
uint32_t requests = 0;
@@ -100,7 +100,6 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
*/
virtual ProcessMessage handleReceived(const MeshPacket &mp) override;
virtual bool handleReceivedProtobuf(const MeshPacket &mp, StoreAndForward *p);
};
extern StoreForwardModule *storeForwardModule;