mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-15 17:42:12 +00:00
ExternalNotifications now observe inputBroker
This commit is contained in:
parent
b9f5ff08fc
commit
a4ead96c39
@ -5,7 +5,6 @@
|
|||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
#endif
|
#endif
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "PowerFSM.h"
|
|
||||||
#include "RadioLibInterface.h"
|
#include "RadioLibInterface.h"
|
||||||
#include "buzz.h"
|
#include "buzz.h"
|
||||||
#include "input/InputBroker.h"
|
#include "input/InputBroker.h"
|
||||||
@ -217,8 +216,6 @@ int32_t ButtonThread::runOnce()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (btnEvent != BUTTON_EVENT_NONE) {
|
if (btnEvent != BUTTON_EVENT_NONE) {
|
||||||
if (screen) {
|
|
||||||
#if HAS_SCREEN
|
|
||||||
switch (btnEvent) {
|
switch (btnEvent) {
|
||||||
case BUTTON_EVENT_PRESSED: {
|
case BUTTON_EVENT_PRESSED: {
|
||||||
LOG_WARN("press!");
|
LOG_WARN("press!");
|
||||||
@ -234,47 +231,12 @@ int32_t ButtonThread::runOnce()
|
|||||||
evt.touchY = 0;
|
evt.touchY = 0;
|
||||||
evt.inputEvent = INPUT_BROKER_USER_PRESS;
|
evt.inputEvent = INPUT_BROKER_USER_PRESS;
|
||||||
this->notifyObservers(&evt);
|
this->notifyObservers(&evt);
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BUTTON_EVENT_LONG_PRESSED: {
|
|
||||||
LOG_WARN("Long press!");
|
|
||||||
|
|
||||||
// Play beep sound
|
|
||||||
playBeep();
|
|
||||||
|
|
||||||
// Forward long press to InputBroker (but NOT as DOWN/SELECT, just forward a "button long press" event)
|
|
||||||
if (inputBroker) {
|
|
||||||
InputEvent evt = {"button", INPUT_BROKER_SELECT, 0, 0, 0};
|
|
||||||
this->notifyObservers(&evt);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// Ignore all other events on screen devices
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
btnEvent = BUTTON_EVENT_NONE;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
// On devices without screen: full legacy logic
|
|
||||||
switch (btnEvent) {
|
|
||||||
case BUTTON_EVENT_PRESSED: {
|
|
||||||
LOG_BUTTON("press!");
|
|
||||||
|
|
||||||
// Play boop sound for every button press
|
|
||||||
playBoop();
|
|
||||||
|
|
||||||
// If a nag notification is running, stop it and prevent other actions
|
|
||||||
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
|
|
||||||
externalNotificationModule->stopNow();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start tracking for potential combination
|
// Start tracking for potential combination
|
||||||
|
if (!screen) {
|
||||||
waitingForLongPress = true;
|
waitingForLongPress = true;
|
||||||
shortPressTime = millis();
|
shortPressTime = millis();
|
||||||
|
}
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,19 +249,10 @@ int32_t ButtonThread::runOnce()
|
|||||||
// Reset combination tracking
|
// Reset combination tracking
|
||||||
waitingForLongPress = false;
|
waitingForLongPress = false;
|
||||||
|
|
||||||
#ifdef ELECROW_ThinkNode_M1
|
|
||||||
// If a nag notification is running, stop it and prevent other actions
|
|
||||||
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
|
|
||||||
externalNotificationModule->stopNow();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
case BUTTON_EVENT_DOUBLE_PRESSED: { // not wired in if screen detected
|
||||||
LOG_BUTTON("Double press!");
|
LOG_BUTTON("Double press!");
|
||||||
|
|
||||||
// Play boop sound for every button press
|
// Play boop sound for every button press
|
||||||
@ -308,21 +261,13 @@ int32_t ButtonThread::runOnce()
|
|||||||
// Reset combination tracking
|
// Reset combination tracking
|
||||||
waitingForLongPress = false;
|
waitingForLongPress = false;
|
||||||
|
|
||||||
#ifdef ELECROW_ThinkNode_M1
|
|
||||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Send GPS position immediately
|
// Send GPS position immediately
|
||||||
sendAdHocPosition();
|
sendAdHocPosition();
|
||||||
|
|
||||||
// Show temporary on-screen confirmation banner for 3 seconds
|
|
||||||
if (screen)
|
|
||||||
screen->showOverlayBanner("Ad-hoc Ping Sent", 3000);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BUTTON_EVENT_MULTI_PRESSED: {
|
case BUTTON_EVENT_MULTI_PRESSED: { // not wired in when screen is present
|
||||||
LOG_BUTTON("Mulitipress! %hux", multipressClickCount);
|
LOG_BUTTON("Mulitipress! %hux", multipressClickCount);
|
||||||
|
|
||||||
// Play boop sound for every button press
|
// Play boop sound for every button press
|
||||||
@ -366,16 +311,13 @@ int32_t ButtonThread::runOnce()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward long press to InputBroker (but NOT as DOWN/SELECT, just forward a "button long press" event)
|
||||||
|
InputEvent evt = {"button", INPUT_BROKER_SELECT, 0, 0, 0};
|
||||||
|
this->notifyObservers(&evt);
|
||||||
|
|
||||||
// Reset combination tracking
|
// Reset combination tracking
|
||||||
waitingForLongPress = false;
|
waitingForLongPress = false;
|
||||||
|
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
|
|
||||||
if (screen) {
|
|
||||||
// Show shutdown message as a temporary overlay banner
|
|
||||||
screen->showOverlayBanner("Shutting Down..."); // Display for 3 seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lead-up sound already played during button hold
|
// Lead-up sound already played during button hold
|
||||||
// Just a simple beep to confirm long press threshold reached
|
// Just a simple beep to confirm long press threshold reached
|
||||||
playBeep();
|
playBeep();
|
||||||
@ -385,6 +327,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
// Do actual shutdown when button released, otherwise the button release
|
// Do actual shutdown when button released, otherwise the button release
|
||||||
// may wake the board immediatedly.
|
// may wake the board immediatedly.
|
||||||
case BUTTON_EVENT_LONG_RELEASED: {
|
case BUTTON_EVENT_LONG_RELEASED: {
|
||||||
|
if (!screen) {
|
||||||
LOG_INFO("Shutdown from long press");
|
LOG_INFO("Shutdown from long press");
|
||||||
|
|
||||||
// Reset combination tracking
|
// Reset combination tracking
|
||||||
@ -394,6 +337,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
delay(3000);
|
delay(3000);
|
||||||
power->shutdown();
|
power->shutdown();
|
||||||
nodeDB->saveToDisk();
|
nodeDB->saveToDisk();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,10 +351,6 @@ int32_t ButtonThread::runOnce()
|
|||||||
// Reset combination tracking
|
// Reset combination tracking
|
||||||
waitingForLongPress = false;
|
waitingForLongPress = false;
|
||||||
|
|
||||||
// Ignore if: no screen
|
|
||||||
if (!screen)
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef TTGO_T_ECHO
|
#ifdef TTGO_T_ECHO
|
||||||
// Ignore if: TX in progress
|
// Ignore if: TX in progress
|
||||||
// Uncommon T-Echo hardware bug, LoRa TX triggers touch button
|
// Uncommon T-Echo hardware bug, LoRa TX triggers touch button
|
||||||
@ -418,12 +358,6 @@ int32_t ButtonThread::runOnce()
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Wake if asleep
|
|
||||||
if (powerFSM.getState() == &stateDARK)
|
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
|
|
||||||
// Update display (legacy behaviour)
|
|
||||||
screen->forceDisplay();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif // BUTTON_PIN_TOUCH
|
#endif // BUTTON_PIN_TOUCH
|
||||||
@ -446,7 +380,6 @@ int32_t ButtonThread::runOnce()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
btnEvent = BUTTON_EVENT_NONE;
|
btnEvent = BUTTON_EVENT_NONE;
|
||||||
} // (!screen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 50;
|
return 50;
|
||||||
|
@ -106,7 +106,6 @@ class ButtonThread : public Observable<const InputEvent *>, public concurrency::
|
|||||||
static void sendAdHocPosition();
|
static void sendAdHocPosition();
|
||||||
|
|
||||||
// IRQ callbacks
|
// IRQ callbacks
|
||||||
static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; }
|
|
||||||
static void userButtonPressedScreen() { btnEvent = BUTTON_EVENT_PRESSED_SCREEN; }
|
static void userButtonPressedScreen() { btnEvent = BUTTON_EVENT_PRESSED_SCREEN; }
|
||||||
static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; }
|
static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; }
|
||||||
static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid
|
static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h" // needed for button bypass
|
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "buzz.h"
|
#include "buzz.h"
|
||||||
#include "detect/ScanI2C.h"
|
#include "detect/ScanI2C.h"
|
||||||
@ -587,7 +586,6 @@ bool CannedMessageModule::handleMessageSelectorInput(const InputEvent *event, bo
|
|||||||
|
|
||||||
// Normal canned message selection
|
// Normal canned message selection
|
||||||
if (runState == CANNED_MESSAGE_RUN_STATE_INACTIVE || runState == CANNED_MESSAGE_RUN_STATE_DISABLED) {
|
if (runState == CANNED_MESSAGE_RUN_STATE_INACTIVE || runState == CANNED_MESSAGE_RUN_STATE_DISABLED) {
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
} else {
|
} else {
|
||||||
payload = runState;
|
payload = runState;
|
||||||
runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
||||||
@ -1002,7 +1000,6 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
}
|
}
|
||||||
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
|
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;
|
return INT32_MAX;
|
||||||
} else {
|
} else {
|
||||||
sendText(this->dest, this->channel, this->messages[this->currentMessageIndex], true);
|
sendText(this->dest, this->channel, this->messages[this->currentMessageIndex], true);
|
||||||
|
@ -350,6 +350,9 @@ ExternalNotificationModule::ExternalNotificationModule()
|
|||||||
// moduleConfig.external_notification.alert_message_buzzer = true;
|
// moduleConfig.external_notification.alert_message_buzzer = true;
|
||||||
|
|
||||||
if (moduleConfig.external_notification.enabled) {
|
if (moduleConfig.external_notification.enabled) {
|
||||||
|
if (inputBroker) // put our callback in the inputObserver list
|
||||||
|
inputObserver.observe(inputBroker);
|
||||||
|
|
||||||
if (nodeDB->loadProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, sizeof(meshtastic_RTTTLConfig),
|
if (nodeDB->loadProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, sizeof(meshtastic_RTTTLConfig),
|
||||||
&meshtastic_RTTTLConfig_msg, &rtttlConfig) != LoadFileResult::LOAD_SUCCESS) {
|
&meshtastic_RTTTLConfig_msg, &rtttlConfig) != LoadFileResult::LOAD_SUCCESS) {
|
||||||
memset(rtttlConfig.ringtone, 0, sizeof(rtttlConfig.ringtone));
|
memset(rtttlConfig.ringtone, 0, sizeof(rtttlConfig.ringtone));
|
||||||
@ -596,3 +599,13 @@ void ExternalNotificationModule::handleSetRingtone(const char *from_msg)
|
|||||||
nodeDB->saveProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, &meshtastic_RTTTLConfig_msg, &rtttlConfig);
|
nodeDB->saveProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, &meshtastic_RTTTLConfig_msg, &rtttlConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ExternalNotificationModule::handleInputEvent(const InputEvent *event)
|
||||||
|
{
|
||||||
|
LOG_WARN("ExternalNotification Handle Input");
|
||||||
|
if (nagCycleCutoff != UINT32_MAX) {
|
||||||
|
stopNow();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -3,6 +3,8 @@
|
|||||||
#include "SinglePortModule.h"
|
#include "SinglePortModule.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "input/InputBroker.h"
|
||||||
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(CONFIG_IDF_TARGET_ESP32C6)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||||
#include <NonBlockingRtttl.h>
|
#include <NonBlockingRtttl.h>
|
||||||
#else
|
#else
|
||||||
@ -27,11 +29,15 @@ class rtttl
|
|||||||
*/
|
*/
|
||||||
class ExternalNotificationModule : public SinglePortModule, private concurrency::OSThread
|
class ExternalNotificationModule : public SinglePortModule, private concurrency::OSThread
|
||||||
{
|
{
|
||||||
|
CallbackObserver<ExternalNotificationModule, const InputEvent *> inputObserver =
|
||||||
|
CallbackObserver<ExternalNotificationModule, const InputEvent *>(this, &ExternalNotificationModule::handleInputEvent);
|
||||||
uint32_t output = 0;
|
uint32_t output = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExternalNotificationModule();
|
ExternalNotificationModule();
|
||||||
|
|
||||||
|
int handleInputEvent(const InputEvent *arg);
|
||||||
|
|
||||||
uint32_t nagCycleCutoff = 1;
|
uint32_t nagCycleCutoff = 1;
|
||||||
|
|
||||||
void setExternalState(uint8_t index = 0, bool on = false);
|
void setExternalState(uint8_t index = 0, bool on = false);
|
||||||
|
Loading…
Reference in New Issue
Block a user