This document describes the main configuration file (confs/main_config.json) which contains global settings that apply across all stations.
Overview
The confs/main_config.json file is optional. If it doesn't exist, FieldStation42 uses built-in defaults. Any settings you specify will override the defaults.
Example Configuration
{
"server_host": "0.0.0.0",
"server_port": 4242,
"normalize_titles": true,
"day_parts": {
"morning": {"start_hour": 6, "end_hour": 10},
"daytime": {"start_hour": 10, "end_hour": 18},
"prime": {"start_hour": 18, "end_hour": 23},
"late": {"start_hour": 23, "end_hour": 2},
"overnight": {"start_hour": 2, "end_hour": 6}
}
}
Configuration Options
| Property | Type | Default | Description |
|---|---|---|---|
server_host |
string | "0.0.0.0" |
Host address for the web server |
server_port |
integer | 4242 |
Port for the web server |
channel_socket |
string | "runtime/channel.socket" |
Unix socket for channel control |
status_socket |
string | "runtime/play_status.socket" |
Unix socket for status updates |
time_format |
string | "%H:%M" |
Format for displaying times (strftime format) |
date_time_format |
string | "%Y-%m-%dT%H:%M:%S" |
Format for date/time values (strftime format) |
start_mpv |
boolean | true |
Whether to start mpv player automatically |
db_path |
string | "runtime/fs42_fluid.db" |
Path to the SQLite database |
normalize_titles |
boolean | false |
Enable automatic title normalization from filenames |
title_patterns |
array | [] |
Custom regex patterns for title parsing (see below) |
schedule_agent |
object | none | Background agent for proactive schedule generation (see below) |
Live Schedule Agent
The live schedule agent runs in the background and automatically extends channel schedules before they expire, preventing the schedule_panic fallback from ever needing to fire during normal operation.
Configuration
Add a schedule_agent block to main_config.json:
{
"schedule_agent": {
"trigger_add_at": "day",
"amount_to_add": "week"
}
}
| Property | Options | Description |
|---|---|---|
trigger_add_at |
"day", "week", "month" |
How close a channel's schedule can get to expiring before the agent extends it. "day" triggers when less than 24 hours remain; "week" when less than 7 days remain; "month" when less than 30 days remain. |
amount_to_add |
"day", "week", "month" |
How much schedule to generate when triggered. |
How It Works
- The agent checks all channel schedules approximately once per hour during playback
- If any channel's schedule ends within the
trigger_add_atthreshold, a background process is spawned to extend it byamount_to_add - Schedule generation runs in a separate process so playback is not interrupted
- Once the build finishes, schedules are reloaded automatically on the next check
- A shared lock prevents conflicts between the background agent and the
schedule_panicfallback
schedule_panic still fires if you tune to a channel with no schedule at all. The agent is proactive; schedule_panic is the last resort.
Behavior Without Configuration
If schedule_agent is not present in your config, the agent does not activate and behavior is identical to before: schedule_panic handles everything on-demand.
Validation and Error Handling
When FieldStation42 loads main_config.json:
- Pattern validation: Each regex pattern is compiled to check for syntax errors
- Required fields: Patterns must have both
patternandgroupfields - Logging: Successfully loaded patterns are logged with their descriptions
- Error recovery: Invalid patterns are logged and skipped (they won't crash the system)
Check your logs on startup to verify your patterns loaded correctly:
INFO: Loaded custom title pattern: Studio releases with year and episode
INFO: Loaded custom title pattern: Remastered editions
INFO: Loaded 2 custom title pattern(s)
Day Parts
Day parts define time periods used for scheduling purposes. Each day part has a start and end hour (0-23).
Configuration
{
"day_parts": {
"morning": {"start_hour": 6, "end_hour": 10},
"daytime": {"start_hour": 10, "end_hour": 18},
"prime": {"start_hour": 18, "end_hour": 23},
"late": {"start_hour": 23, "end_hour": 2},
"overnight": {"start_hour": 2, "end_hour": 6}
}
}
Wrapping Midnight
When end_hour is less than start_hour, the period wraps around midnight. For example, late runs from 11 PM to 2 AM.
Custom Title Patterns
When normalize_titles is enabled, FieldStation42 automatically parses video filenames to extract clean, display-ready titles. You can add custom regex patterns to handle special naming conventions in your media library.
Why Use Custom Patterns?
The built-in patterns handle common formats like:
- Show Name - s01e05.mp4 -> "Show Name"
- Movie (2020).mp4 -> "Movie"
- [Group] Title - 03.mkv -> "Title"
But if your files use a unique naming scheme, you can add custom patterns to parse them correctly.
Pattern Format
Each pattern is an object with three fields:
{
"pattern": "regex pattern here",
"group": 1,
"description": "What this pattern matches"
}
- pattern: A regular expression string (remember to escape backslashes in JSON!)
- group: The capture group number containing the title (usually
1) - description: Optional human-readable description
Example Patterns
{
"title_patterns": [
{
"pattern": "^\\[Studio\\][\\s._-]+(.+?)[\\s._-]+Special.*$",
"group": 1,
"description": "Studio specials with [Studio] prefix"
},
{
"pattern": "^(.+?)[\\s._-]+HD[\\s._-]+\\d+p.*$",
"group": 1,
"description": "Videos with HD quality markers"
},
{
"pattern": "^(.+?)_REMASTER_\\d{4}.*$",
"group": 1,
"description": "Remastered content"
}
]
}
How It Works
- Custom patterns are tried first, in the order you specify
- If a custom pattern matches, that title is used
- If no custom pattern matches, built-in patterns are tried
- The first matching pattern wins
Example:
Filename: [Studio] My Great Show - Special Edition.mp4
- Without custom pattern: "My Great Show Special Edition"
- With pattern above: "My Great Show"
JSON Regex Escaping Guide
JSON requires backslashes to be escaped. Here's a quick reference:
| Regex Pattern | In JSON String |
|---|---|
\d (any digit) |
"\\d" |
\s (whitespace) |
"\\s" |
\w (word character) |
"\\w" |
\. (literal period) |
"\\." |
\[ (literal bracket) |
"\\[" |
[abc] (character class) |
"[abc]" (no escape) |
(group) (capture group) |
"(group)" (no escape) |
.* (zero or more) |
".*" (no escape) |
.+? (non-greedy) |
".+?" (no escape) |
Common Separator Pattern
Many patterns use a "separator" regex to match spaces, dots, underscores, and dashes:
"pattern": "^(.+?)[\\s._-]+Episode[\\s._-]+\\d+$"
This matches titles like:
- Show Title Episode 05.mp4
- Show.Title.Episode.05.mp4
- Show_Title_Episode_05.mp4
- Show-Title-Episode-05.mp4
Testing Your Patterns
Before adding patterns to your config:
- Test your regex using a tool like regex101.com
- Make sure to select the Python flavor
- Remember to add the JSON escaping when copying to your config
- Check the FieldStation42 logs on startup - they will show if patterns fail to compile
Example: Complete Configuration
{
"server_port": 4242,
"normalize_titles": true,
"title_patterns": [
{
"pattern": "^\\[STUDIO\\][\\s._-]+(.+?)[\\s._-]+\\d{4}[\\s._-]+\\d+.*$",
"group": 1,
"description": "Studio releases with year and episode"
},
{
"pattern": "^(.+?)[\\s._-]+REMASTERED[\\s._-]+.*$",
"group": 1,
"description": "Remastered editions"
}
],
"day_parts": {
"morning": {"start_hour": 6, "end_hour": 10},
"daytime": {"start_hour": 10, "end_hour": 18},
"prime": {"start_hour": 18, "end_hour": 23},
"late": {"start_hour": 23, "end_hour": 2},
"overnight": {"start_hour": 2, "end_hour": 6}
},
"schedule_agent": {
"trigger_add_at": "day",
"amount_to_add": "week"
}
}
Best Practices
- Start simple: Add one pattern at a time and test it
- Order matters: Put more specific patterns first
- Be precise: Use
^and$anchors to match the whole filename - Use non-greedy:
.+?instead of.+to avoid over-matching - Document: Always include a description for future reference
- Test filenames: Verify your patterns work with actual filenames from your library