Merge branch 'lab2' into lab

This commit is contained in:
Kelly
2025-01-05 21:14:55 -08:00
committed by GitHub
14 changed files with 289 additions and 173 deletions
+6 -2
View File
@@ -70,8 +70,12 @@ def call_external_script(message, script="runShell.sh"):
script_path = os.path.join(current_working_directory, script)
if not os.path.exists(script_path):
logger.warning(f"FileMon: Script not found: {script_path}")
return "sorry I can't do that"
# try the raw script name
script_path = script
if not os.path.exists(script_path):
logger.warning(f"FileMon: Script not found: {script_path}")
return "sorry I can't do that"
output = os.popen(f"bash {script_path} {message}").read()
return output
except Exception as e:
+1
View File
@@ -357,6 +357,7 @@ def getWeatherAlertsNOAA(lat=0, lon=0, useDefaultLatLon=False):
alerts = ""
alertxml = xml.dom.minidom.parseString(alert_data.text)
for i in alertxml.getElementsByTagName("entry"):
title = i.getElementsByTagName("title")[0].childNodes[0].nodeValue
area_desc = i.getElementsByTagName("cap:areaDesc")[0].childNodes[0].nodeValue
+8 -3
View File
@@ -3,6 +3,11 @@ from logging.handlers import TimedRotatingFileHandler
import re
from datetime import datetime
from modules.settings import *
# if LOGGING_LEVEL is not set in settings.py, default to DEBUG
if not LOGGING_LEVEL:
LOGGING_LEVEL = "DEBUG"
LOGGING_LEVEL = getattr(logging, LOGGING_LEVEL)
class CustomFormatter(logging.Formatter):
grey = '\x1b[38;21m'
@@ -41,7 +46,7 @@ class plainFormatter(logging.Formatter):
# Create logger
logger = logging.getLogger("MeshBot System Logger")
logger.setLevel(logging.DEBUG)
logger.setLevel(LOGGING_LEVEL)
logger.propagate = False
msgLogger = logging.getLogger("MeshBot Messages Logger")
@@ -56,7 +61,7 @@ today = datetime.now()
# Create stdout handler for logging to the console
stdout_handler = logging.StreamHandler()
# Set level for stdout handler (logs DEBUG level and above)
stdout_handler.setLevel(logging.DEBUG)
stdout_handler.setLevel(LOGGING_LEVEL)
# Set format for stdout handler
stdout_handler.setFormatter(CustomFormatter(logFormat))
# Add handlers to the logger
@@ -65,7 +70,7 @@ logger.addHandler(stdout_handler)
if syslog_to_file:
# Create file handler for logging to a file
file_handler_sys = TimedRotatingFileHandler('logs/meshbot.log', when='midnight', backupCount=log_backup_count)
file_handler_sys.setLevel(logging.DEBUG) # DEBUG used by default for system logs to disk
file_handler_sys.setLevel(LOGGING_LEVEL) # DEBUG used by default for system logs to disk
file_handler_sys.setFormatter(plainFormatter(logFormat))
logger.addHandler(file_handler_sys)
+1 -1
View File
@@ -189,6 +189,7 @@ try:
log_messages_to_file = config['general'].getboolean('LogMessagesToFile', False) # default off
log_backup_count = config['general'].getint('LogBackupCount', 32) # default 32 days
syslog_to_file = config['general'].getboolean('SyslogToFile', True) # default on
LOGGING_LEVEL = config['general'].get('sysloglevel', 'DEBUG') # default DEBUG
urlTimeoutSeconds = config['general'].getint('urlTimeout', 10) # default 10 seconds
store_forward_enabled = config['general'].getboolean('StoreForward', True)
storeFlimit = config['general'].getint('StoreLimit', 3) # default 3 messages for S&F
@@ -208,7 +209,6 @@ try:
llm_enabled = config['general'].getboolean('ollama', False) # https://ollama.com
llmModel = config['general'].get('ollamaModel', 'gemma2:2b') # default gemma2:2b
ollamaHostName = config['general'].get('ollamaHostName', 'http://localhost:11434') # default localhost
# emergency response
emergency_responder_enabled = config['emergencyHandler'].getboolean('enabled', False)
emergency_responder_alert_channel = config['emergencyHandler'].getint('alert_channel', 2) # default 2
+83 -80
View File
@@ -1,7 +1,7 @@
# helper functions and init for system related tasks
# K7MHI Kelly Keeton 2024
import meshtastic.serial_interface #pip install meshtastic
import meshtastic.serial_interface #pip install meshtastic or use launch.sh for venv
import meshtastic.tcp_interface
import meshtastic.ble_interface
import time
@@ -12,6 +12,7 @@ import io # for suppressing output on watchdog
from modules.log import *
# Global Variables
debugMetadata = False # packet debug for non text messages
trap_list = ("cmd","cmd?") # default trap list
help_message = "Bot CMD?:"
asyncLoop = asyncio.new_event_loop()
@@ -75,7 +76,7 @@ if location_enabled:
trap_list = trap_list + trap_list_location # items tide, whereami, wxc, wx
help_message = help_message + ", whereami, wx, wxc, rlist"
if enableGBalerts:
from modules.locationdata_eu import * # from the spudgunman/meshing-around repo
from modules.globalalert import * # from the spudgunman/meshing-around repo
trap_list = trap_list + trap_list_location_eu
#help_message = help_message + ", ukalert, ukwx, ukflood"
@@ -685,7 +686,7 @@ def handleAlertBroadcast(deviceID=1):
ukAlert = alertUk
if emergencyAlertBrodcastEnabled:
if NO_ALERTS not in femaAlert:
if NO_ALERTS not in femaAlert and ERROR_FETCHING_DATA not in femaAlert:
if isinstance(emergencyAlertBroadcastCh, list):
for channel in emergencyAlertBroadcastCh:
send_message(femaAlert, int(channel), 0, deviceID)
@@ -834,90 +835,92 @@ def displayNodeTelemetry(nodeID=0, rxNode=0, userRequested=False):
positionMetadata = {}
def consumeMetadata(packet, rxNode=0):
# keep records of recent telemetry data
debugMetadata = False
packet_type = ''
if packet.get('decoded'):
packet_type = packet['decoded']['portnum']
nodeID = packet['from']
try:
# keep records of recent telemetry data
packet_type = ''
if packet.get('decoded'):
packet_type = packet['decoded']['portnum']
nodeID = packet['from']
# TELEMETRY packets
if packet_type == 'TELEMETRY_APP':
#if debugMetadata: print(f"DEBUG TELEMETRY_APP: {packet}\n\n")
# get the telemetry data
telemetry_packet = packet['decoded']['telemetry']
if telemetry_packet.get('deviceMetrics'):
deviceMetrics = telemetry_packet['deviceMetrics']
if telemetry_packet.get('localStats'):
localStats = telemetry_packet['localStats']
# Check if 'numPacketsTx' and 'numPacketsRx' exist and are not zero
if localStats.get('numPacketsTx') is not None and localStats.get('numPacketsRx') is not None and localStats['numPacketsTx'] != 0:
# Assign the values to the telemetry dictionary
keys = [
'numPacketsTx', 'numPacketsRx', 'numOnlineNodes',
'numOfflineNodes', 'numPacketsTxErr', 'numPacketsRxErr', 'numTotalNodes']
# TELEMETRY packets
if packet_type == 'TELEMETRY_APP':
if debugMetadata: print(f"DEBUG TELEMETRY_APP: {packet}\n\n")
# get the telemetry data
telemetry_packet = packet['decoded']['telemetry']
if telemetry_packet.get('deviceMetrics'):
deviceMetrics = telemetry_packet['deviceMetrics']
if telemetry_packet.get('localStats'):
localStats = telemetry_packet['localStats']
# Check if 'numPacketsTx' and 'numPacketsRx' exist and are not zero
if localStats.get('numPacketsTx') is not None and localStats.get('numPacketsRx') is not None and localStats['numPacketsTx'] != 0:
# Assign the values to the telemetry dictionary
keys = [
'numPacketsTx', 'numPacketsRx', 'numOnlineNodes',
'numOfflineNodes', 'numPacketsTxErr', 'numPacketsRxErr', 'numTotalNodes']
for key in keys:
if localStats.get(key) is not None:
telemetryData[rxNode][key] = localStats.get(key)
# POSITION_APP packets
if packet_type == 'POSITION_APP':
if debugMetadata: print(f"DEBUG POSITION_APP: {packet}\n\n")
# get the position data
keys = ['altitude', 'groundSpeed', 'precisionBits']
position_data = packet['decoded']['position']
try:
if nodeID not in positionMetadata:
positionMetadata[nodeID] = {}
for key in keys:
if localStats.get(key) is not None:
telemetryData[rxNode][key] = localStats.get(key)
# POSITION_APP packets
if packet_type == 'POSITION_APP':
if debugMetadata: print(f"DEBUG POSITION_APP: {packet}\n\n")
# get the position data
keys = ['altitude', 'groundSpeed', 'precisionBits']
position_data = packet['decoded']['position']
try:
if nodeID not in positionMetadata:
positionMetadata[nodeID] = {}
for key in keys:
positionMetadata[nodeID][key] = position_data.get(key, 0)
# Keep the positionMetadata dictionary at 5 records
if len(positionMetadata) > 20:
# Remove the oldest entry
oldest_nodeID = next(iter(positionMetadata))
del positionMetadata[oldest_nodeID]
except Exception as e:
logger.debug(f"System: POSITION_APP decode error: {e} packet {packet}")
positionMetadata[nodeID][key] = position_data.get(key, 0)
# Keep the positionMetadata dictionary at 5 records
if len(positionMetadata) > 20:
# Remove the oldest entry
oldest_nodeID = next(iter(positionMetadata))
del positionMetadata[oldest_nodeID]
except Exception as e:
logger.debug(f"System: POSITION_APP decode error: {e} packet {packet}")
# WAYPOINT_APP packets
if packet_type == 'WAYPOINT_APP':
if debugMetadata: print(f"DEBUG WAYPOINT_APP: {packet['decoded']['waypoint']}\n\n")
# get the waypoint data
waypoint_data = packet['decoded']['waypoint']
keys = ['latitude', 'longitude',]
# WAYPOINT_APP packets
if packet_type == 'WAYPOINT_APP':
if debugMetadata: print(f"DEBUG WAYPOINT_APP: {packet['decoded']['waypoint']}\n\n")
# get the waypoint data
waypoint_data = packet['decoded']
# NEIGHBORINFO_APP
if packet_type == 'NEIGHBORINFO_APP':
if debugMetadata: print(f"DEBUG NEIGHBORINFO_APP: {packet}\n\n")
# get the neighbor info data
neighbor_data = packet['decoded']['neighborInfo']
# TRACEROUTE_APP
if packet_type == 'TRACEROUTE_APP':
if debugMetadata: print(f"DEBUG TRACEROUTE_APP: {packet}\n\n")
# get the traceroute data
traceroute_data = packet['decoded']['traceroute']
# NEIGHBORINFO_APP
if packet_type == 'NEIGHBORINFO_APP':
if debugMetadata: print(f"DEBUG NEIGHBORINFO_APP: {packet}\n\n")
# get the neighbor info data
neighbor_data = packet['decoded']
# TRACEROUTE_APP
if packet_type == 'TRACEROUTE_APP':
if debugMetadata: print(f"DEBUG TRACEROUTE_APP: {packet}\n\n")
# get the traceroute data
traceroute_data = packet['decoded']
# DETECTION_SENSOR_APP
if packet_type == 'DETECTION_SENSOR_APP':
if debugMetadata: print(f"DEBUG DETECTION_SENSOR_APP: {packet}\n\n")
# get the detection sensor data
detection_data = packet['decoded']['detectionSensor']
# DETECTION_SENSOR_APP
if packet_type == 'DETECTION_SENSOR_APP':
if debugMetadata: print(f"DEBUG DETECTION_SENSOR_APP: {packet}\n\n")
# get the detection sensor data
detection_data = packet['decoded']
# PAXCOUNTER_APP
if packet_type == 'PAXCOUNTER_APP':
if debugMetadata: print(f"DEBUG PAXCOUNTER_APP: {packet}\n\n")
# get the paxcounter data
paxcounter_data = packet['decoded']['paxcounter']
# PAXCOUNTER_APP
if packet_type == 'PAXCOUNTER_APP':
if debugMetadata: print(f"DEBUG PAXCOUNTER_APP: {packet}\n\n")
# get the paxcounter data
paxcounter_data = packet['decoded']
# REMOTE_HARDWARE_APP
if packet_type == 'REMOTE_HARDWARE_APP':
if debugMetadata: print(f"DEBUG REMOTE_HARDWARE_APP: {packet}\n\n")
# get the remote hardware data
remote_hardware_data = packet['decoded']['remoteHardware']
# REMOTE_HARDWARE_APP
if packet_type == 'REMOTE_HARDWARE_APP':
if debugMetadata: print(f"DEBUG REMOTE_HARDWARE_APP: {packet}\n\n")
# get the remote hardware data
remote_hardware_data = packet['decoded']
except KeyError as e:
logger.critical(f"System: Error consuming metadata: {e} Device:{rxNode}")
logger.debug(f"System: Error Packet = {packet}")
def get_sysinfo(nodeID=0, deviceID=1):
# Get the system telemetry data for return on the sysinfo command