scheduler enhancment

this brings scheduler into the 19th century
This commit is contained in:
SpudGunMan
2025-10-26 07:26:54 -07:00
parent bbdccb382a
commit da144a2b89
3 changed files with 96 additions and 86 deletions
+39 -36
View File
@@ -3,50 +3,53 @@ from modules.log import logger
from modules.system import send_message
def setup_custom_schedules(send_message, tell_joke, welcome_message, handle_wxc, MOTD, schedulerChannel, schedulerInterface):
# custom scheduler job to run the schedule see examples below
logger.debug(f"System: Starting the custom_scheduler.py default to send reminder every Monday at noon on Device:{schedulerInterface} Channel:{schedulerChannel}")
schedule.every().monday.at("12:00").do(lambda: logger.info("System: Scheduled Broadcast Enabled Reminder"))
# Enhanced Examples of using the scheduler, Times here are in 24hr format
# https://schedule.readthedocs.io/en/stable/
"""
Set up all custom schedules. Edit this function to add or remove scheduled tasks.
"""
### Example schedules
# Send a joke every 2 minutes
#logger.debug(f"System: Custom Scheduler: Send a joke every 2 minutes on Device:{schedulerInterface} Channel:{schedulerChannel}")
#schedule.every(2).minutes.do(lambda: send_message(tell_joke(), schedulerChannel, 0, schedulerInterface))
#schedule.every(2).minutes.do(send_joke, send_message, tell_joke, schedulerChannel, schedulerInterface)
# Send a good morning message every day at 9 AM
#schedule.every().day.at("09:00").do(send_good_morning, send_message, schedulerChannel, schedulerInterface)
# Send weather update every day at 8 AM
#schedule.every().day.at("08:00").do(send_wx, send_message, handle_wxc, schedulerChannel, schedulerInterface)
# Send weather alerts every Wednesday at noon
#schedule.every().wednesday.at("12:00").do(send_weather_alert, send_message, schedulerChannel, schedulerInterface)
# Send configuration URL every 2 days at 10 AM
#schedule.every(2).days.at("10:00").do(send_config_url, send_message, schedulerChannel, schedulerInterface)
# Send net starting message every Wednesday at 7 PM
#schedule.every().wednesday.at("19:00").do(send_net_starting, send_message, schedulerChannel, schedulerInterface)
# Send welcome message every 2 days at 8 AM
#schedule.every(2).days.at("08:00").do(send_welcome, send_message, schedulerChannel, schedulerInterface)
# Send MOTD every day at 1 PM
#schedule.every().day.at("13:00").do(send_motd, send_message, MOTD, schedulerChannel, schedulerInterface)
# Send bbslink message every 2 days at 10 AM
#schedule.every(2).days.at("10:00").do(send_bbslink, send_message, schedulerChannel, schedulerInterface)
# Good Morning Every day at 09:00 using send_message function to channel 2 on device 1
#schedule.every().day.at("09:00").do(lambda: send_message("Good Morning", 2, 0, 1))
def send_joke(send_message, tell_joke, channel, interface):
send_message(tell_joke(), channel, 0, interface)
# Send WX every Morning at 08:00 using handle_wxc function to channel 2 on device 1
#logger.debug("System: Custom Scheduler: Send WX every Morning at 08:00")
#schedule.every().day.at("08:00").do(lambda: send_message(handle_wxc(0, 1, 'wx'), 2, 0, 1))
def send_good_morning(send_message, channel, interface):
send_message("Good Morning", channel, 0, interface)
# Send Weather Channel Notice Wed. Noon on channel 2, device 1
#schedule.every().wednesday.at("12:00").do(lambda: send_message("Weather alerts available on 'Alerts' channel with default 'AQ==' key.", 2, 0, 1))
def send_wx(send_message, handle_wxc, channel, interface):
send_message(handle_wxc(0, 1, 'wx'), channel, 0, interface)
# Send config URL for Medium Fast Network Use every other day at 10:00 to default channel 2 on device 1
#logger.debug("System: Custom Scheduler: Config URL for Medium Fast Network Use every other day at 10:00")
#schedule.every(2).days.at("10:00").do(lambda: send_message("Join us on Medium Fast https://meshtastic.org/e/#CgcSAQE6AggNEg4IARAEOAFAA0gBUB5oAQ", 2, 0, 1))
def send_weather_alert(send_message, channel, interface):
send_message("Weather alerts available on 'Alerts' channel with default 'AQ==' key.", channel, 0, interface)
# Send a Net Starting Now Message Every Wednesday at 19:00 using send_message function to channel 2 on device 1
#schedule.every().wednesday.at("19:00").do(lambda: send_message("Net Starting Now", 2, 0, 1))
def send_config_url(send_message, channel, interface):
send_message("Join us on Medium Fast https://meshtastic.org/e/#CgcSAQE6AggNEg4IARAEOAFAA0gBUB5oAQ", channel, 0, interface)
# Send a Welcome Notice for group on the 15th and 25th of the month at 12:00 using send_message function to channel 2 on device 1
#schedule.every().day.at("12:00").do(lambda: send_message("Welcome to the group", 2, 0, 1)).day(15, 25)
def send_net_starting(send_message, channel, interface):
send_message("Net Starting Now", channel, 0, interface)
# Send a Welcome Notice for group on the 15th and 25th of the month at 12:00
#logger.debug(f"System: Custom Scheduler: Welcome Notice for group on the 15th and 25th of the month at 12:00 on Device:{schedulerInterface} Channel:{schedulerChannel}")
#schedule.every().day.at("12:00").do(lambda: send_message("Welcome to the group", schedulerChannel, 0, schedulerInterface)).day(15, 25)
def send_welcome(send_message, channel, interface):
send_message("Welcome to the group", channel, 0, interface)
# Send a joke every 6 hours
#schedule.every(6).hours.do(lambda: send_message(tell_joke(), schedulerChannel, 0, schedulerInterface))
def send_motd(send_message, MOTD, channel, interface):
send_message(MOTD, channel, 0, interface)
# Send the Welcome Message every other day at 08:00
#schedule.every(2).days.at("08:00").do(lambda: send_message(welcome_message, schedulerChannel, 0, schedulerInterface))
# Send the MOTD every day at 13:00
#schedule.every().day.at("13:00").do(lambda: send_message(MOTD, schedulerChannel, 0, schedulerInterface))
# Send bbslink looking for peers every other day at 10:00
#logger.debug("System: Custom Scheduler: bbslink MeshBot looking for peers every other day at 10:00")
#schedule.every(2).days.at("10:00").do(lambda: send_message("bbslink MeshBot looking for peers", schedulerChannel, 0, schedulerInterface))
def send_bbslink(send_message, channel, interface):
send_message("bbslink MeshBot looking for peers", channel, 0, interface)
+1 -3
View File
@@ -1616,9 +1616,7 @@ def handle_boot(mesh=True):
logger.debug("System: Logging Metadata Stats Enabled, leaderboard")
if my_settings.scheduler_enabled:
logger.debug("System: Scheduler Enabled")
logger.debug(f"System: Scheduler Enabled. Default Device:{my_settings.schedulerInterface} Channel:{my_settings.schedulerChannel}")
except Exception as e:
logger.error(f"System: Error during boot: {e}")
+56 -47
View File
@@ -3,6 +3,7 @@
import asyncio
import schedule
from datetime import datetime
from functools import partial
from modules.log import logger
from modules.settings import MOTD
from modules.system import send_message
@@ -47,13 +48,21 @@ def extract_schedule_fields(jobs):
start = part.find('Every')
if start != -1:
# Find the start of 'do <lambda>()'
do_idx = part.find('do <lambda>()')
do_idx = part.find('do ')
if do_idx != -1:
summary = part[start:do_idx].strip()
# Find the (last run: ... next run: ...) part
paren_idx = part.find('(', do_idx)
if paren_idx != -1:
summary += ' ' + part[paren_idx:].strip()
while '<function ' in summary:
f_start = summary.find('<function ')
f_end = summary.find('>', f_start)
if f_end == -1:
break
func_str = summary[f_start+10:f_end]
func_name = func_str.split(' ')[0]
summary = summary[:f_start] + func_name + summary[f_end+1:]
results.append(summary)
return results
@@ -84,65 +93,65 @@ def setup_scheduler(
schedulerIntervalInt = safe_int(schedulerInterval, 5, type="interval")
try:
if schedulerMotd:
scheduler_message = MOTD
else:
scheduler_message = schedulerMessage
scheduler_message = MOTD if schedulerMotd else schedulerMessage
def send_sched_msg():
send_message(scheduler_message, schedulerChannel, 0, schedulerInterface)
# Basic Scheduler Options
basicOptions = ['day', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun', 'hour', 'min']
if any(option.lower() in schedulerValue.lower() for option in basicOptions):
# Basic scheduler job to run the schedule see examples below for custom schedules
if schedulerValue.lower() == 'day':
if schedulerTime != '':
schedule.every().day.at(schedulerTime).do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
if any(option in schedulerValue for option in basicOptions):
if schedulerValue == 'day':
if schedulerTime:
schedule.every().day.at(schedulerTime).do(send_sched_msg)
else:
schedule.every(schedulerIntervalInt).days.do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'mon' in schedulerValue.lower() and schedulerTime != '':
schedule.every().monday.at(schedulerTime).do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'tue' in schedulerValue.lower() and schedulerTime != '':
schedule.every().tuesday.at(schedulerTime).do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'wed' in schedulerValue.lower() and schedulerTime != '':
schedule.every().wednesday.at(schedulerTime).do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'thu' in schedulerValue.lower() and schedulerTime != '':
schedule.every().thursday.at(schedulerTime).do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'fri' in schedulerValue.lower() and schedulerTime != '':
schedule.every().friday.at(schedulerTime).do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'sat' in schedulerValue.lower() and schedulerTime != '':
schedule.every().saturday.at(schedulerTime).do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'sun' in schedulerValue.lower() and schedulerTime != '':
schedule.every().sunday.at(schedulerTime).do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'hour' in schedulerValue.lower():
schedule.every(schedulerIntervalInt).hours.do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
elif 'min' in schedulerValue.lower():
schedule.every(schedulerIntervalInt).minutes.do(lambda: send_message(scheduler_message, schedulerChannel, 0, schedulerInterface))
schedule.every(schedulerIntervalInt).days.do(send_sched_msg)
elif 'mon' in schedulerValue and schedulerTime:
schedule.every().monday.at(schedulerTime).do(send_sched_msg)
elif 'tue' in schedulerValue and schedulerTime:
schedule.every().tuesday.at(schedulerTime).do(send_sched_msg)
elif 'wed' in schedulerValue and schedulerTime:
schedule.every().wednesday.at(schedulerTime).do(send_sched_msg)
elif 'thu' in schedulerValue and schedulerTime:
schedule.every().thursday.at(schedulerTime).do(send_sched_msg)
elif 'fri' in schedulerValue and schedulerTime:
schedule.every().friday.at(schedulerTime).do(send_sched_msg)
elif 'sat' in schedulerValue and schedulerTime:
schedule.every().saturday.at(schedulerTime).do(send_sched_msg)
elif 'sun' in schedulerValue and schedulerTime:
schedule.every().sunday.at(schedulerTime).do(send_sched_msg)
elif 'hour' in schedulerValue:
schedule.every(schedulerIntervalInt).hours.do(send_sched_msg)
elif 'min' in schedulerValue:
schedule.every(schedulerIntervalInt).minutes.do(send_sched_msg)
logger.debug(f"System: Starting the basic scheduler to send '{scheduler_message}' on schedule '{schedulerValue}' every {schedulerIntervalInt} interval at time '{schedulerTime}' on Device:{schedulerInterface} Channel:{schedulerChannel}")
# value can also be 'joke' (interval), 'weather' (time), or 'link' (interval) for special auto messages
elif 'joke' in schedulerValue.lower():
# Schedule to send a joke every specified interval minutes
schedule.every(schedulerIntervalInt).minutes.do(lambda: send_message(tell_joke(), schedulerChannel, 0, schedulerInterface))
elif 'joke' in schedulerValue:
schedule.every(schedulerIntervalInt).minutes.do(
partial(send_message, tell_joke(), schedulerChannel, 0, schedulerInterface)
)
logger.debug(f"System: Starting the joke scheduler to send a joke every {schedulerIntervalInt} minutes on Device:{schedulerInterface} Channel:{schedulerChannel}")
elif 'link' in schedulerValue.lower():
# Schedule to send a link message every specified interval hours
schedule.every(schedulerIntervalInt).hours.do(lambda: send_message(handle_satpass(schedulerInterface, 'link'), schedulerChannel, 0, schedulerInterface))
elif 'link' in schedulerValue:
schedule.every(schedulerIntervalInt).hours.do(
partial(send_message, handle_satpass(schedulerInterface, 'link'), schedulerChannel, 0, schedulerInterface)
)
logger.debug(f"System: Starting the link scheduler to send link messages every {schedulerIntervalInt} hours on Device:{schedulerInterface} Channel:{schedulerChannel}")
elif 'weather' in schedulerValue.lower():
# Schedule to send weather updates every specified time every day
schedule.every().day.at(schedulerTime)(lambda: send_message(handle_wxc(0, schedulerInterface, 'wx'), schedulerChannel, 0, schedulerInterface))
elif 'weather' in schedulerValue:
schedule.every().day.at(schedulerTime).do(
partial(send_message, handle_wxc(0, schedulerInterface, 'wx'), schedulerChannel, 0, schedulerInterface)
)
logger.debug(f"System: Starting the weather scheduler to send weather updates every {schedulerIntervalInt} hours on Device:{schedulerInterface} Channel:{schedulerChannel}")
elif 'custom' in schedulerValue.lower():
# Import and setup custom schedules from custom_scheduler.py
elif 'custom' in schedulerValue:
try:
# This file is located in etc/custom_scheduler.py and copied to modules/custom_scheduler.py at install
from modules.custom_scheduler import setup_custom_schedules # type: ignore # pylance
from modules.custom_scheduler import setup_custom_schedules # type: ignore
setup_custom_schedules(
send_message, tell_joke, welcome_message, handle_wxc, MOTD,
schedulerChannel, schedulerInterface)
logger.debug("System: Custom scheduler file imported and custom schedules set up.")
logger.debug(f"System: Starting the custom_scheduler.py ")
schedule.every().monday.at("12:00").do(
lambda: logger.info("System: Scheduled Broadcast Enabled Reminder")
)
except Exception as e:
logger.debug(f"System: Failed to import custom scheduler. {e}")
logger.warning("Custom scheduler file not found or failed to import. cp etc/custom_scheduler.py modules/custom_scheduler.py")
except Exception as e:
logger.error(f"System: Scheduler Error {e}")
return True
return True