Compare commits

...

9 Commits

Author SHA1 Message Date
SpudGunMan
b92cf48fd0 fix update errors
removing this logic for now
2025-10-31 07:24:07 -07:00
SpudGunMan
227ffc94e6 Update update.sh 2025-10-31 07:22:58 -07:00
SpudGunMan
b9f5a0c7f9 refactor
https://github.com/SpudGunMan/meshing-around/issues/249
2025-10-31 07:04:21 -07:00
SpudGunMan
d56c1380c3 fix overload
floods node otherwise
2025-10-30 23:03:28 -07:00
SpudGunMan
e8a8eefcc2 leaderboard enhancment
dont count messages to bot
2025-10-30 22:47:28 -07:00
SpudGunMan
5738e8d306 fix 2025-10-30 20:14:29 -07:00
SpudGunMan
11359e4016 cleanup 2025-10-30 20:09:16 -07:00
SpudGunMan
7bb31af1d2 Update mesh_bot.py 2025-10-30 19:48:53 -07:00
SpudGunMan
fd115916f5 cleanup 2025-10-30 18:50:54 -07:00
9 changed files with 44 additions and 44 deletions

View File

@@ -401,9 +401,9 @@ enable_runShellCmd = False
# direct shell command handler the x: command in DMs
allowXcmd = False
# Enable 2 factor authentication for x: commands
2factor_enabled = True
twoFactor_enabled = True
# time in seconds to wait for the correct 2FA answer
2factor_timeout = 100
twoFactor_timeout = 100
[smtp]
# enable or disable the SMTP module

View File

@@ -2,7 +2,7 @@
# # Simulate meshing-around de K7MHI 2024
from modules.log import logger, getPrettyTime # Import the logger; ### --> If you are reading this put the script in the project root <-- ###
import time
import datetime
from datetime import datetime
import random
# Initialize the tool
@@ -51,8 +51,8 @@ def example_handler(message, nodeID, deviceID):
msg = f"Hello {get_name_from_number(nodeID)}, simulator ready for testing {projectName} project! on device {deviceID}"
msg += f" Your location is {location}"
msg += f" you said: {message}"
# Add timestamp
msg += f" [Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]"
return msg

View File

@@ -1996,12 +1996,12 @@ def onReceive(packet, interface):
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} found the Word of the Day🎊:\n {wordWas}, {metaWas}"
send_message(msg, channel_number, 0, rxNode)
if bingo_win:
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} scored BINGO!🥳 {bingo_message}"
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} scored word-search-BINGO!🥳 {bingo_message}"
send_message(msg, channel_number, 0, rxNode)
slotMachine = theWordOfTheDay.emojiMiniGame(message_string, emojiSeen=emojiSeen, nodeID=message_from_id, nodeInt=rxNode)
if slotMachine:
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} played the Slot Machine and got: {slotMachine} 🥳"
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} played the emote-Fruit-Machine and got: {slotMachine} 🥳"
send_message(msg, channel_number, 0, rxNode)
# add message to tts queue

View File

@@ -2,7 +2,7 @@
# Fetches DX spots from Spothole API based on user commands
# 2025 K7MHI Kelly Keeton
import requests
import datetime
from datetime import datetime, timedelta
from modules.log import logger
from modules.settings import latitudeValue, longitudeValue
@@ -69,7 +69,6 @@ def get_spothole_spots(source=None, band=None, mode=None, date=None, dx_call=Non
url = "https://spothole.app/api/v1/spots"
params = {}
fetched_count = 0
# Add administrative filters if provided
qrt = False # Always fetch active spots
@@ -83,7 +82,7 @@ def get_spothole_spots(source=None, band=None, mode=None, date=None, dx_call=Non
params["needs_sig"] = str(needs_sig).lower()
params["needs_sig_ref"] = 'true'
# Only get spots from last 9 hours
received_since_dt = datetime.datetime.utcnow() - datetime.timedelta(hours=9)
received_since_dt = datetime.utcnow() - timedelta(hours=9)
received_since = int(received_since_dt.timestamp())
params["received_since"] = received_since
@@ -170,7 +169,7 @@ def get_spothole_spots(source=None, band=None, mode=None, date=None, dx_call=Non
return spots
def handle_post_dxspot():
time = int(datetime.datetime.utcnow().timestamp())
time = int(datetime.utcnow().timestamp())
freq = 14200000 # 14 MHz
comment = "Test spot please ignore"
de_spot = "N0CALL"

View File

@@ -462,7 +462,6 @@ def alertBrodcastNOAA():
# broadcast the alerts send to wxBrodcastCh
elif currentAlert[0] not in wxAlertCacheNOAA:
# Check if the current alert is not in the weather alert cache
logger.debug("Location:Broadcasting weather alerts")
wxAlertCacheNOAA = currentAlert[0]
return currentAlert

View File

@@ -7,7 +7,7 @@ import html
from html.parser import HTMLParser
import bs4 as bs
import requests
import datetime
from datetime import datetime, timedelta
# Common User-Agent for all RSS requests
COMMON_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
@@ -146,7 +146,7 @@ def get_newsAPI(user_search="meshtastic"):
if not user_search:
user_search = "meshtastic"
try:
last_week = datetime.datetime.now() - datetime.timedelta(days=7)
last_week = datetime.now() - timedelta(days=7)
newsAPIurl = (
f"https://newsapi.org/v2/everything?"
f"q={user_search}&language=en&from={last_week.strftime('%Y-%m-%d')}&sortBy={newsAPIsort}shedAt&pageSize=5&apiKey={newsAPI_KEY}"

View File

@@ -344,7 +344,7 @@ try:
myStateFIPSList = config['location'].get('myFIPSList', '').split(',') # default empty
mySAMEList = config['location'].get('mySAMEList', '').split(',') # default empty
myRegionalKeysDE = config['location'].get('myRegionalKeysDE', '110000000000').split(',') # default city Berlin
eAlertBroadcastChannel = config['location'].getint('eAlertBroadcastChannel', '') # default empty
eAlertBroadcastChannel = config['location'].get('eAlertBroadcastCh', '').split(',') # default empty
# any US alerts enabled
usAlerts = (
@@ -459,8 +459,8 @@ try:
news_random_line_only = config['fileMon'].getboolean('news_random_line', False) # default False
enable_runShellCmd = config['fileMon'].getboolean('enable_runShellCmd', False) # default False
allowXcmd = config['fileMon'].getboolean('allowXcmd', False) # default False
xCmd2factorEnabled = config['fileMon'].getboolean('2factor_enabled', True) # default True
xCmd2factor_timeout = config['fileMon'].getint('2factor_timeout', 100) # default 100 seconds
xCmd2factorEnabled = config['fileMon'].getboolean('twoFactor_enabled', True) # default True
xCmd2factor_timeout = config['fileMon'].getint('twoFactor_timeout', 100) # default 100 seconds
# games
game_hop_limit = config['games'].getint('game_hop_limit', 5) # default 5 hops

View File

@@ -376,6 +376,9 @@ for i in range(1, 10):
logger.critical(f"System: abort. Initializing Interface{i} {e}")
exit()
# Get my node numbers for global use
my_node_ids = [globals().get(f'myNodeNum{i}') for i in range(1, 10)]
# Get the node number of the devices, check if the devices are connected meshtastic devices
for i in range(1, 10):
if globals().get(f'interface{i}') and globals().get(f'interface{i}_enabled'):
@@ -659,7 +662,7 @@ async def get_closest_nodes(nodeInt=1,returnCount=3, channel=publicChannel):
distance = round(geopy.distance.geodesic((latitudeValue, longitudeValue), (latitude, longitude)).m, 2)
if (distance < sentry_radius):
if (nodeID not in [globals().get(f'myNodeNum{i}') for i in range(1, 10)]) and str(nodeID) not in sentryIgnoreList:
if (nodeID not in my_node_ids) and str(nodeID) not in sentryIgnoreList:
node_list.append({'id': nodeID, 'latitude': latitude, 'longitude': longitude, 'distance': distance})
except Exception as e:
@@ -671,7 +674,7 @@ async def get_closest_nodes(nodeInt=1,returnCount=3, channel=publicChannel):
try:
logger.debug(f"System: Requesting location data for {node['id']}, lastHeard: {node.get('lastHeard', 'N/A')}")
# if not a interface node
if node['num'] in [globals().get(f'myNodeNum{i}') for i in range(1, 10)]:
if node['num'] in my_node_ids:
ignore = True
else:
# one idea is to send a ping to the node to request location data for if or when, ask again later
@@ -1169,9 +1172,15 @@ def handleAlertBroadcast(deviceID=1):
for alert_type, alert_msg, enabled in alert_types:
if enabled and alert_msg and NO_ALERTS not in alert_msg and ERROR_FETCHING_DATA not in alert_msg:
if should_send_alert(alert_type, alert_msg):
logger.debug(f"System: Sending {alert_type} alert to emergency responder channel {emergency_responder_alert_channel}")
send_message(alert_msg, emergency_responder_alert_channel, 0, emergency_responder_alert_interface)
if eAlertBroadcastChannel != '':
send_message(alert_msg, eAlertBroadcastChannel, 0, emergency_responder_alert_interface)
if eAlertBroadcastChannel:
for ch in eAlertBroadcastChannel:
ch = ch.strip()
if ch:
logger.debug(f"System: Sending {alert_type} alert to aux channel {ch}")
time.sleep(splitDelay)
send_message(alert_msg, int(ch), 0, emergency_responder_alert_interface)
except Exception as e:
logger.error(f"System: Error in handleAlertBroadcast: {e}")
return False
@@ -1371,11 +1380,13 @@ def consumeMetadata(packet, rxNode=0, channel=-1):
# Meta for most Messages leaderboard
if packet_type == 'TEXT_MESSAGE':
message_count = meshLeaderboard.get('nodeMessageCounts', {})
message_count[nodeID] = message_count.get(nodeID, 0) + 1
meshLeaderboard['nodeMessageCounts'] = message_count
if message_count[nodeID] > meshLeaderboard['mostMessages']['value']:
meshLeaderboard['mostMessages'] = {'nodeID': nodeID, 'value': message_count[nodeID], 'timestamp': time.time()}
# if packet isnt TO a my_node_id count it
if packet.get('to') not in my_node_ids:
message_count = meshLeaderboard.get('nodeMessageCounts', {})
message_count[nodeID] = message_count.get(nodeID, 0) + 1
meshLeaderboard['nodeMessageCounts'] = message_count
if message_count[nodeID] > meshLeaderboard['mostMessages']['value']:
meshLeaderboard['mostMessages'] = {'nodeID': nodeID, 'value': message_count[nodeID], 'timestamp': time.time()}
else:
tmessage_count = meshLeaderboard.get('nodeTMessageCounts', {})
tmessage_count[nodeID] = tmessage_count.get(nodeID, 0) + 1

View File

@@ -28,10 +28,18 @@ fi
# Fetch latest changes from GitHub
echo "Fetching latest changes from GitHub..."
if ! git fetch origin; then
echo "Error: Failed to fetch from GitHub, check your network connection."
echo "Error: Failed to fetch from GitHub, check your network connection. script expects to be run inside a git repository."
exit 1
fi
# Check for detached HEAD state
if [[ $(git symbolic-ref --short -q HEAD) == "" ]]; then
echo "WARNING: You are in a detached HEAD state."
echo "You may not be on a branch. To return to the main branch, run:"
echo " git checkout main"
echo "Proceed with caution; changes may not be saved to a branch."
fi
# git pull with rebase to avoid unnecessary merge commits
echo "Pulling latest changes from GitHub..."
if ! git pull origin main --rebase; then
@@ -63,24 +71,7 @@ if [[ -f "modules/custom_scheduler.py" ]]; then
echo "Including custom_scheduler.py in backup..."
cp modules/custom_scheduler.py data/
fi
# Check config.ini ownership and permissions
if [[ -f "config.ini" ]]; then
owner=$(stat -f "%Su" config.ini)
perms=$(stat -f "%A" config.ini)
if [[ "$owner" == "root" ]]; then
echo "config.ini is owned by: $owner"
echo "Warning: config.ini is owned by root check out the etc/set-permissions.sh script"
fi
if [[ $(stat -f "%Lp" config.ini) =~ .*[7,6,2]$ ]]; then
cho "config.ini permissions: $perms"
echo "Warning: config.ini is world-writable or world-readable! check out the etc/set-permissions.sh script"
fi
echo "Including config.ini in backup..."
cp config.ini data/config.backup
fi
#create the tar.gz backup
tar -czf "$backup_file" "$path2backup"
if [ $? -ne 0 ]; then