diff --git a/device.go b/device.go new file mode 100644 index 0000000..9eac67b --- /dev/null +++ b/device.go @@ -0,0 +1,75 @@ +package main + +import ( + "os" + "os/exec" + "time" +) + +// deviceManager handles periodic maintenance of the Meshtastic device +func deviceManager(shutdown chan struct{}, dryRun bool) { + logInfo("device", "Starting device manager", map[string]interface{}{ + "rebootInterval": DEVICE_REBOOT_INTERVAL.String(), + "dryRun": dryRun, + }) + + // Wait some time before first reboot to allow system startup + initialDelay := 5 * time.Minute + logInfo("device", "Waiting before first device reboot", map[string]interface{}{ + "initialDelay": initialDelay.String(), + }) + + select { + case <-time.After(initialDelay): + // Continue after delay + case <-shutdown: + logInfo("device", "Shutdown signal received during initial delay", nil) + return + } + + // Reboot immediately after startup delay + rebootDevice(dryRun) + + // Then run on interval + ticker := time.NewTicker(DEVICE_REBOOT_INTERVAL) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + rebootDevice(dryRun) + case <-shutdown: + logInfo("device", "Shutting down device manager", nil) + return + } + } +} + +// rebootDevice executes the meshtastic --reboot command +func rebootDevice(dryRun bool) { + cmdStr := "meshtastic --reboot" + + logInfo("device", "Rebooting Meshtastic device", map[string]interface{}{ + "command": cmdStr, + "dryRun": dryRun, + "time": time.Now().Format("15:04:05 MST"), + }) + + if dryRun { + logInfo("device", "DRY RUN - would execute device reboot", nil) + return + } + + // Execute the reboot command + cmd := exec.Command("meshtastic", "--reboot") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + logInfo("device", "Device reboot failed", map[string]interface{}{ + "error": err.Error(), + }) + } else { + logInfo("device", "Device reboot successful", nil) + } +} diff --git a/main.go b/main.go index 75a5956..962a99f 100644 --- a/main.go +++ b/main.go @@ -125,6 +125,13 @@ func main() { logCleanupWorker(shutdown) }() + // Start device manager goroutine for periodic device maintenance + wg.Add(1) + go func() { + defer wg.Done() + deviceManager(shutdown, *dryRun) + }() + // Wait for all goroutines to finish wg.Wait() logInfo("shutdown", "All goroutines stopped, exiting", nil) diff --git a/models.go b/models.go index 32e1f9a..8074dbd 100644 --- a/models.go +++ b/models.go @@ -51,16 +51,19 @@ Never rate over 90 unless it is a massive event such as: war outbreak, revolution, death of a head of state, large-scale natural disaster, mass casualty terrorism, etc. -IMPORTANT: Rank any headlines primarily promoting commercial products or +Rank any headlines primarily promoting commercial products or services as 1 (lowest importance). Rank any article with a headline that poses a question without providing an answer (as an attempt to lure a reader into clicking a link) as 1 (lowest importance). -IMPORTANT: Boost the importance score by 10-20 points for breaking news that is less -than 60 minutes old based on its original publication date (which is provided for each article). -This helps ensure timely distribution of very recent news. +Boost the importance score by 10 points for breaking news that is less than 60 +minutes old based on its original publication date (which is provided for each +article), but only for events that need to be reported in minutes, such as +emeregencies or other critical breaking news. + +Do not editorialize or otherwise label the summary. For each article, return a JSON object with "id", "summary", and "importance" fields. Return your response as a JSON array of objects like: [{"id": @@ -78,6 +81,7 @@ Here are the articles: SUMMARIZE_INTERVAL = 10 * time.Second BROADCAST_INTERVAL = 1 * time.Hour BROADCAST_CHECK_INTERVAL = 10 * time.Second // Interval to check if broadcasting is needed + DEVICE_REBOOT_INTERVAL = 6 * time.Hour // Interval to reboot Meshtastic device STARTUP_DELAY = 60 * time.Second // Delay before first broadcast BROADCAST_PREPARATION_DELAY = 30 * time.Second // Delay before executing broadcast command ARTICLE_FRESHNESS_WINDOW = 24 * time.Hour // Time window for considering articles fresh