From feb9a1d9b314098896aedd5d3298b3eb84815f5a Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Wed, 21 May 2025 16:18:46 -0700 Subject: [PATCH 1/9] FlightDetector high alt detection --- config.template | 2 ++ modules/settings.py | 1 + modules/system.py | 7 +++++++ 3 files changed, 10 insertions(+) diff --git a/config.template b/config.template index 1da8971..8a2e47b 100644 --- a/config.template +++ b/config.template @@ -103,6 +103,8 @@ SentryChannel = 2 SentryHoldoff = 9 # list of ignored nodes numbers ex: 2813308004,4258675309 sentryIgnoreList = +# HighFlying Node alert, if the node is above 2,000 meters +highFlyingAlert = True [bbs] enabled = True diff --git a/modules/settings.py b/modules/settings.py index 3583da4..6f79ba4 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -235,6 +235,7 @@ try: sentryIgnoreList = config['sentry'].get('sentryIgnoreList', '').split(',') sentry_radius = config['sentry'].getint('SentryRadius', 100) # default 100 meters email_sentry_alerts = config['sentry'].getboolean('emailSentryAlerts', False) # default False + highfly_enabled = config['sentry'].getboolean('highFlyingAlert', True) # default True # location location_enabled = config['location'].getboolean('enabled', True) diff --git a/modules/system.py b/modules/system.py index 79aba54..69ee994 100644 --- a/modules/system.py +++ b/modules/system.py @@ -978,6 +978,13 @@ def consumeMetadata(packet, rxNode=0): for key in keys: positionMetadata[nodeID][key] = position_data.get(key, 0) + + # if altitude is over 2000 send a log and message for high-flying nodes + if position_data.get('altitude', 0) > 2000 and highfly_enabled: + logger.warning(f"System: High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}") + if antiSpam and nodeID != globals().get(f'myNodeNum{rxNode}'): + send_message(f"High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}", secure_channel, 0, rxNode) + time.sleep(responseDelay) # Keep the positionMetadata dictionary at a maximum size of 20 if len(positionMetadata) > 20: From 60bb68c6b54a309bdd87ef618e50bce4c0782eb1 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Wed, 21 May 2025 16:20:54 -0700 Subject: [PATCH 2/9] Update system.py --- modules/system.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/system.py b/modules/system.py index 69ee994..89e5cfd 100644 --- a/modules/system.py +++ b/modules/system.py @@ -982,9 +982,8 @@ def consumeMetadata(packet, rxNode=0): # if altitude is over 2000 send a log and message for high-flying nodes if position_data.get('altitude', 0) > 2000 and highfly_enabled: logger.warning(f"System: High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}") - if antiSpam and nodeID != globals().get(f'myNodeNum{rxNode}'): - send_message(f"High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}", secure_channel, 0, rxNode) - time.sleep(responseDelay) + send_message(f"High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}", secure_channel, 0, rxNode) + time.sleep(responseDelay) # Keep the positionMetadata dictionary at a maximum size of 20 if len(positionMetadata) > 20: From f54d362ea01fff66406daa4b186cd4b306ec0361 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Wed, 21 May 2025 16:36:43 -0700 Subject: [PATCH 3/9] Update config.template --- config.template | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config.template b/config.template index 8a2e47b..27f0e4f 100644 --- a/config.template +++ b/config.template @@ -103,8 +103,10 @@ SentryChannel = 2 SentryHoldoff = 9 # list of ignored nodes numbers ex: 2813308004,4258675309 sentryIgnoreList = -# HighFlying Node alert, if the node is above 2,000 meters +# HighFlying Node alert highFlyingAlert = True +# Altitude in meters to trigger the alert +highFlyingAlertAltitude = 2000 [bbs] enabled = True @@ -293,7 +295,7 @@ splitDelay = 0.0 MESSAGE_CHUNK_SIZE = 160 # Request Acknowledgement of message OTA wantAck = False -# Max limit buffer for radio testing. 233 is hard limit 2.5+ firmware +# Max limit buffer for radio testing maxBuffer = 200 #Enable Extra logging of Hop count data enableHopLogs = False From 903767f4b30b1c908f3d0dd5cb5785bc404ae8e8 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Wed, 21 May 2025 16:36:46 -0700 Subject: [PATCH 4/9] Update settings.py --- modules/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/settings.py b/modules/settings.py index 6f79ba4..c7044ac 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -236,6 +236,7 @@ try: sentry_radius = config['sentry'].getint('SentryRadius', 100) # default 100 meters email_sentry_alerts = config['sentry'].getboolean('emailSentryAlerts', False) # default False highfly_enabled = config['sentry'].getboolean('highFlyingAlert', True) # default True + highfly_altitude = config['sentry'].getint('highFlyingAlertAltitude', 2000) # default 2000 meters # location location_enabled = config['location'].getboolean('enabled', True) From 0e0bda60ada0215703371064bd53ee83a4f155e4 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Wed, 21 May 2025 16:36:52 -0700 Subject: [PATCH 5/9] Update system.py --- modules/system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system.py b/modules/system.py index 89e5cfd..d9b0673 100644 --- a/modules/system.py +++ b/modules/system.py @@ -980,7 +980,7 @@ def consumeMetadata(packet, rxNode=0): positionMetadata[nodeID][key] = position_data.get(key, 0) # if altitude is over 2000 send a log and message for high-flying nodes - if position_data.get('altitude', 0) > 2000 and highfly_enabled: + if position_data.get('altitude', 0) > highfly_altitude and highfly_enabled: logger.warning(f"System: High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}") send_message(f"High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}", secure_channel, 0, rxNode) time.sleep(responseDelay) From 895fc3fd371654a214b88c99384c6b3f7e0f5880 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Wed, 21 May 2025 16:36:55 -0700 Subject: [PATCH 6/9] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index cf6bc9b..9df8f8b 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Welcome to the Mesh Bot project! This feature-rich bot is designed to enhance yo ### Proximity Alerts - **Location-Based Alerts**: Get notified when members arrive back at a configured lat/long, perfect for remote locations like campsites. +- **High Flying Alerts**: Get notified when nodes with high altitude are seen on mesh ### CheckList / Check In Out - **Asset Tracking**: Maintain a list of node/asset checkin and checkout. Usefull for accountability of people, assets. Radio-Net, FEMA, Trailhead. @@ -181,6 +182,8 @@ SentryRadius = 100 # radius in meters to detect someone close to the bot SentryChannel = 9 # holdoff time multiplied by seconds(20) of the watchdog SentryHoldoff = 2 # channel to send a message to when the watchdog is triggered sentryIgnoreList = # list of ignored nodes numbers ex: 2813308004,4258675309 +highFlyingAlert = True # HighFlying Node alert +highFlyingAlertAltitude = 2000 # Altitude in meters to trigger the alert ``` ### E-Mail / SMS Settings From 1be13be92aefe418a175553898d65875f3f92504 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Wed, 21 May 2025 16:43:56 -0700 Subject: [PATCH 7/9] highfly enhancements --- config.template | 2 ++ mesh_bot.py | 2 ++ modules/settings.py | 1 + modules/system.py | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/config.template b/config.template index 27f0e4f..92aa9cf 100644 --- a/config.template +++ b/config.template @@ -107,6 +107,8 @@ sentryIgnoreList = highFlyingAlert = True # Altitude in meters to trigger the alert highFlyingAlertAltitude = 2000 +# Channel to send Alert when the high flying node is detected +highFlyingAlertChannel = 2 [bbs] enabled = True diff --git a/mesh_bot.py b/mesh_bot.py index f424b61..0d142d0 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -1406,6 +1406,8 @@ async def start_rx(): logger.debug(f"System: MOTD Enabled using {MOTD}") if sentry_enabled: logger.debug(f"System: Sentry Mode Enabled {sentry_radius}m radius reporting to channel:{secure_channel}") + if highfly_enabled: + logger.debug(f"System: HighFly Enabled using {highfly_altitude}m limit reporting to channel:{highfly_channel}") if store_forward_enabled: logger.debug(f"System: Store and Forward Enabled using limit: {storeFlimit}") if useDMForResponse: diff --git a/modules/settings.py b/modules/settings.py index c7044ac..ce269d6 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -237,6 +237,7 @@ try: email_sentry_alerts = config['sentry'].getboolean('emailSentryAlerts', False) # default False highfly_enabled = config['sentry'].getboolean('highFlyingAlert', True) # default True highfly_altitude = config['sentry'].getint('highFlyingAlertAltitude', 2000) # default 2000 meters + highfly_channel = config['sentry'].getint('highFlyingAlertChannel', 2) # default 2 # location location_enabled = config['location'].getboolean('enabled', True) diff --git a/modules/system.py b/modules/system.py index d9b0673..a501bc6 100644 --- a/modules/system.py +++ b/modules/system.py @@ -982,7 +982,7 @@ def consumeMetadata(packet, rxNode=0): # if altitude is over 2000 send a log and message for high-flying nodes if position_data.get('altitude', 0) > highfly_altitude and highfly_enabled: logger.warning(f"System: High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}") - send_message(f"High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}", secure_channel, 0, rxNode) + send_message(f"High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}", highfly_channel, 0, rxNode) time.sleep(responseDelay) # Keep the positionMetadata dictionary at a maximum size of 20 From 118857ec15cc644f329c18cefdd212071500eaf7 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Wed, 21 May 2025 16:52:01 -0700 Subject: [PATCH 8/9] Update system.py --- modules/system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system.py b/modules/system.py index a501bc6..5611a7a 100644 --- a/modules/system.py +++ b/modules/system.py @@ -981,7 +981,7 @@ def consumeMetadata(packet, rxNode=0): # if altitude is over 2000 send a log and message for high-flying nodes if position_data.get('altitude', 0) > highfly_altitude and highfly_enabled: - logger.warning(f"System: High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}") + logger.info(f"System: High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}") send_message(f"High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}", highfly_channel, 0, rxNode) time.sleep(responseDelay) From 621f4ad91658df91640ab8e69e41718b523bab48 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Fri, 23 May 2025 19:10:15 -0700 Subject: [PATCH 9/9] enhance --- README.md | 1 + modules/system.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9df8f8b..a19dcc6 100644 --- a/README.md +++ b/README.md @@ -482,6 +482,7 @@ I used ideas and snippets from other responder bots and want to call them out! - **Josh**: For more bashing on installer! - **dj505**: trying it on windows! - **mikecarper**: ideas, and testing. hamtest +- **c.merphy360**: high altitude alerts - **Cisien, bitflip, **Woof**, **propstg**, **trs2982**, **Josh** and Hailo1999**: For testing and feature ideas on Discord and GitHub. - **Meshtastic Discord Community**: For tossing out ideas and testing code. diff --git a/modules/system.py b/modules/system.py index 5611a7a..324bbc1 100644 --- a/modules/system.py +++ b/modules/system.py @@ -982,7 +982,7 @@ def consumeMetadata(packet, rxNode=0): # if altitude is over 2000 send a log and message for high-flying nodes if position_data.get('altitude', 0) > highfly_altitude and highfly_enabled: logger.info(f"System: High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}") - send_message(f"High Altitude {position_data['altitude']}m on Device: {rxNode} NodeID: {nodeID}", highfly_channel, 0, rxNode) + send_message(f"High Altitude {position_data['altitude']}m on Device:{rxNode} Node:{get_name_from_number(nodeID,'short',rxNode)}", highfly_channel, 0, rxNode) time.sleep(responseDelay) # Keep the positionMetadata dictionary at a maximum size of 20 @@ -1157,7 +1157,7 @@ async def retry_interface(nodeID): if interface_type == 'serial': globals()[f'interface{nodeID}'] = meshtastic.serial_interface.SerialInterface(globals().get(f'port{nodeID}')) elif interface_type == 'tcp': - globals()[f'interface{nodeID}'] = meshtastic.tcp_interface.TCPInterface(globals().get(f'hostname{nodeID}')) + globals()[f'interface{nodeID}'] = meshtastic.tcp_interface.TCPInterface(globals().get(f'host{nodeID}')) elif interface_type == 'ble': globals()[f'interface{nodeID}'] = meshtastic.ble_interface.BLEInterface(globals().get(f'mac{nodeID}')) logger.debug(f"System: Interface{nodeID} Opened!")