mirror of
https://github.com/meshtastic/firmware.git
synced 2026-09-29 01:36:26 -04:00
Add waypoint & geofence support with notifications for BaseUI and InkHUD (#10920)
* Implement GeofenceModule for waypoint crossing notifications and integrate with existing modules * Waypoint Applet Initial Support on InkHUD * undo tile change * Update screen when Waypoint shows or dissapears * Merge branch 'develop' into waypoint-geofence * Geofence on InkHUD * Update MapTile.h * Update WaypointStore.cpp * Notifications * remove GF from waypoint screen * Prevent Focus from closing the notifiaction banner * Trunk fix * cleanup * undo merge conflix mistake * Waypoint screen on BaseUI * Focus preserve fix * UI bugs * Allow Inkhud to remove waypoint * Respect Locked Waypoints * Trunk fix * Update WaypointStore.cpp * Use 8-digit hex formatting for waypoint IDs. 0x%x was inconsistent with the repo's own convention (0x%08x for 32-bit IDs, used elsewhere in this file). Fixed here and in two other spots I found with the same issue (WaypointModule.cpp, GeofenceModule.cpp). * Update ExternalNotificationModule.cpp * Reject invalid surrogate codepoints in waypoint icon rendering * Update WaypointModule.cpp * Update WaypointStore.cpp * Update WaypointStore.cpp * Update WaypointStore.cpp * trunk fix * fix warnings * power.h rename to Power.h * Update Power.h * Fix executable bit on bin/lint-ifdef-complexity.sh Lost during a prior merge from develop (Windows checkout doesn't preserve file mode), causing "execve failed: Permission denied" in the Trunk Check Runner CI job. develop has this file at 100755; restoring that here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Update README.md * Clean up waypoint and geofence integration * Minimize waypoint and geofence implementation * removed unnecessary gating * Geofence alert * trunk fix * Update test_main.cpp * Update WaypointStore.cpp --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
51 files changed
+3005
-222
No files matched your search
@@ -449,11 +449,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
(moduleConfig.external_notification.alert_message_buzzer && !is_muted)));
|
||||
|
||||
if (genericShouldAlert || vibraShouldAlert || buzzerShouldAlert) {
|
||||
nagCycleCutoff = millis() + (moduleConfig.external_notification.nag_timeout
|
||||
? (moduleConfig.external_notification.nag_timeout * 1000)
|
||||
: moduleConfig.external_notification.output_ms);
|
||||
LOG_INFO("Toggling nagCycleCutoff to %lu", nagCycleCutoff);
|
||||
isNagging = true;
|
||||
armNagCycle();
|
||||
}
|
||||
|
||||
if (genericShouldAlert) {
|
||||
@@ -463,19 +459,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
|
||||
if (vibraShouldAlert) {
|
||||
LOG_INFO("externalNotificationModule - Vibra alert");
|
||||
#ifdef HAS_DRV2605
|
||||
// Set DRV2605 waveform when vibration alert is triggered
|
||||
drv.setWaveform(0, 16); // Long buzzer 100%
|
||||
drv.setWaveform(1, 0); // Pause
|
||||
drv.setWaveform(2, 16);
|
||||
drv.setWaveform(3, 0);
|
||||
drv.setWaveform(4, 16);
|
||||
drv.setWaveform(5, 0);
|
||||
drv.setWaveform(6, 16);
|
||||
drv.setWaveform(7, 0);
|
||||
drv.go();
|
||||
#endif
|
||||
setExternalState(1, true);
|
||||
triggerVibraOutput();
|
||||
}
|
||||
|
||||
if (buzzerShouldAlert) {
|
||||
@@ -484,15 +468,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
LOG_INFO("Buzzer suppressed: mode DIRECT_MSG_ONLY");
|
||||
} else {
|
||||
// Buzz if buzzer mode is not in DIRECT_MSG_ONLY or is DM to us
|
||||
if (moduleConfig.external_notification.use_i2s_as_buzzer) {
|
||||
#ifdef HAS_I2S
|
||||
audioThread->beginRttl(rtttlConfig.ringtone, strlen_P(rtttlConfig.ringtone));
|
||||
#endif
|
||||
} else if (moduleConfig.external_notification.use_pwm) {
|
||||
rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone);
|
||||
} else {
|
||||
setExternalState(2, true);
|
||||
}
|
||||
triggerBuzzerOutput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,6 +481,80 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
void ExternalNotificationModule::triggerBuzzerOutput()
|
||||
{
|
||||
if (moduleConfig.external_notification.use_i2s_as_buzzer) {
|
||||
#ifdef HAS_I2S
|
||||
audioThread->beginRttl(rtttlConfig.ringtone, strlen_P(rtttlConfig.ringtone));
|
||||
#endif
|
||||
} else if (moduleConfig.external_notification.use_pwm) {
|
||||
rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone);
|
||||
} else {
|
||||
setExternalState(2, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalNotificationModule::triggerVibraOutput()
|
||||
{
|
||||
#ifdef HAS_DRV2605
|
||||
drv.setWaveform(0, 16);
|
||||
drv.setWaveform(1, 0);
|
||||
drv.setWaveform(2, 16);
|
||||
drv.setWaveform(3, 0);
|
||||
drv.setWaveform(4, 16);
|
||||
drv.setWaveform(5, 0);
|
||||
drv.setWaveform(6, 16);
|
||||
drv.setWaveform(7, 0);
|
||||
drv.go();
|
||||
#endif
|
||||
setExternalState(1, true);
|
||||
}
|
||||
|
||||
void ExternalNotificationModule::armNagCycle()
|
||||
{
|
||||
const uint32_t durationMs = moduleConfig.external_notification.nag_timeout
|
||||
? moduleConfig.external_notification.nag_timeout * 1000UL
|
||||
: moduleConfig.external_notification.output_ms;
|
||||
nagCycleCutoff = millis() + durationMs;
|
||||
LOG_INFO("Toggling nagCycleCutoff to %lu", nagCycleCutoff);
|
||||
isNagging = true;
|
||||
}
|
||||
|
||||
void ExternalNotificationModule::startNotification()
|
||||
{
|
||||
if (!moduleConfig.external_notification.enabled || isSilenced)
|
||||
return;
|
||||
|
||||
// Waypoint and geofence events are neither direct messages nor bells.
|
||||
const bool buzzerModeIsDirectOnly = (config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY);
|
||||
|
||||
const bool generic = moduleConfig.external_notification.alert_message;
|
||||
const bool vibra = moduleConfig.external_notification.alert_message_vibra;
|
||||
const bool buzzer = canBuzz() && moduleConfig.external_notification.alert_message_buzzer && !buzzerModeIsDirectOnly;
|
||||
if (canBuzz() && moduleConfig.external_notification.alert_message_buzzer && buzzerModeIsDirectOnly)
|
||||
LOG_INFO("Non-message buzzer was suppressed because buzzer mode DIRECT_MSG_ONLY");
|
||||
if (!generic && !vibra && !buzzer)
|
||||
return;
|
||||
|
||||
buzzerShouldAlert |= buzzer;
|
||||
|
||||
armNagCycle();
|
||||
|
||||
if (generic) {
|
||||
LOG_INFO("externalNotificationModule - Generic alert");
|
||||
setExternalState(0, true);
|
||||
}
|
||||
if (vibra) {
|
||||
LOG_INFO("externalNotificationModule - Vibra alert");
|
||||
triggerVibraOutput();
|
||||
}
|
||||
if (buzzer) {
|
||||
LOG_INFO("externalNotificationModule - Buzzer alert");
|
||||
triggerBuzzerOutput();
|
||||
}
|
||||
|
||||
setIntervalFromNow(0); // run once so the nag/stop lifecycle in runOnce() takes over
|
||||
}
|
||||
/**
|
||||
* @brief An admin message arrived to AdminModule. We are asked whether we want to handle that.
|
||||
*
|
||||
|
||||
Reference in new issue
Block a user