Lobster Radio Node

Lobster Radio Node

Current System Documentation

Overview

Lobster is a queue-driven audio beacon and radio-style automation node. It combines locally scheduled WAV playback with Spotify Connect playback, Mount Washington forecast insertion, system status visibility, and a browser-based control interface.

The system is designed around a simple operational model:

  • Spotify runs continuously as the background audio source
  • the loop periodically ducks Spotify and inserts local audio
  • queued WAV files rotate in order
  • a Mount Washington forecast can replace the normal queued item every 8th loop
  • the entire node is controlled and observed through a Flask web application and JSON state files

Functional Summary

The node currently supports:

  • Spotify Connect playback on the device lobster-radio
  • local WAV upload, conversion, normalization, and queuing
  • round-robin playback of queued WAV files
  • fallback playback of a default WAV when the queue is empty
  • Mount Washington forecast insertion every 8th loop when forecast audio is available
  • ducking control for Spotify during TTS, queued WAV playback, and station ID playback
  • adjustable loop interval from the web interface
  • current Spotify track visibility
  • next Spotify track visibility when available
  • Spotify playback controls from the web interface
  • playback history
  • merged logs for loop activity, Spotify control activity, and Spotify track-change events
  • stale-loop detection and basic service health display

Core Components

Loop engine

The main playback engine is:

  • dtmf_loop.sh

This script determines playback order, timing, forecast insertion, and runtime status output.

Web control server

  • app.py

Provides the web UI, JSON APIs, queue control, settings storage, logs, Spotify control, and system status.

Web interface

  • static/index.html

Displays system state, queue, history, logs, Spotify info, and provides all control inputs.

Spotify token helper

  • oauth.py

Handles loading and refreshing Spotify access tokens.

Spotify control utility

  • spotify_activate.py

Ensures the Spotify device exists, restarts the player service if needed, transfers playback, and controls play/pause/start actions.

Spotify status utility

  • spotify_current.py

Fetches current and next track info and logs track-change events.

Upload processor

  • upload_handler.py

Handles WAV uploads, conversion, normalization, metadata storage, and queue insertion.

Runtime Model

Playback Loop

Each loop cycle:

  1. reads loop interval from settings
  2. determines forecast slot
  3. selects main audio item
  4. writes runtime status
  5. generates time TTS
  6. ducks Spotify for TTS
  7. plays time message
  8. ducks Spotify for main audio
  9. plays:
    • queued WAV
    • default fallback WAV
    • forecast WAV
  10. plays station ID
  11. restores Spotify level
  12. calculates remaining sleep time
  13. updates runtime status
  14. sleeps until next cycle

Queue Behavior

Queue is stored in queue_order.json.

Selection logic:

  • forecast slot overrides queue if forecast exists
  • otherwise next queue item plays
  • fallback WAV used if queue is empty

Queue playback is round-robin.

Forecast Behavior

  • occurs every 8th loop
  • morning vs evening file chosen based on time of day
  • fallback to alternate if preferred file missing

Data Files and State

Workspace paths

  • /root/.openclaw/workspace/wav_queue
  • /root/.openclaw/workspace/wav_files_original
  • /root/.openclaw/workspace/wav_files_converted
  • /root/.openclaw/workspace/mw_forecast_audio
  • /root/.openclaw/workspace/web_control

runtime_status.json

Contains:

  • timestamps
  • loop counter
  • current WAV info
  • forecast state
  • loop stats
  • mixer levels
  • settings snapshot
  • next 8 items
  • history
  • errors

queue_order.json

{
  "order": ["file1.wav", "file2.wav"],
  "updated_at": 1710000000
}

queue_state.json

{
  "next_index": 2,
  "updated_at": 1710000000
}

settings.json

Contains:

  • wavduckingpercent
  • ttsduckingpercent
  • restorespotifypercent
  • defaultwavpercent
  • forecastwavpercent
  • stationidwav_percent
  • loopintervalseconds

play_history.json

Stores playback history with timestamps and status.

spotify_events.json

Stores Spotify change events only.

spotifylaststate.json

Tracks last known Spotify state signature.

spotify_token.json

Stores Spotify token data.

metadata.json

Stores WAV metadata including:

  • original name
  • paths
  • hash
  • upload time
  • duration
  • bitrate

Audio Sources

Spotify

Background audio via Spotify Connect device:

  • lobster-radio

Time TTS

  • ttstimemessage.wav

Main segment

  • queue WAV
  • default fallback WAV
  • forecast WAV

Station ID

  • tts_48k.wav

Default fallback

  • willyoumarrymebeckydtmf48k_conv.wav

Web API

/

Serves UI.

/volume/

GET and POST for ALSA mixer control.

/queue

GET queue.

/queue/reorder

POST new queue order.

/queue/remove

POST remove item.

/upload

POST WAV upload.

/settings

GET and POST settings.

/status

GET runtime status.

/logs

GET merged logs.

/system/status

GET system and freshness state.

/health

GET compact system summary.

/spotify/current

GET current and next track.

/spotify/events

GET Spotify event log.

/spotify/control/status

POST Spotify state check.

/spotify/control/ensure-device

POST ensure device exists.

/spotify/control/resume

POST resume playback.

/spotify/control/pause

POST pause playback.

/spotify/control/start

POST start playlist.

Web Interface

Now Playing

  • current item
  • countdown
  • forecast status
  • loop stats

Service Status

  • loop freshness
  • Spotify service state
  • API status
  • stale warning

Spotify

  • current track
  • next track
  • device
  • state
  • progress

Mixer Controls

  • Spotify level
  • WAV level

Spotify Control

  • ensure device
  • resume
  • pause
  • start playlist

Upload WAV

Upload audio into queue.

Next 8 Scheduled

Shows upcoming playback order.

Playback Ducking

Controls ducking levels.

Loop Timing

Controls loop interval.

Queue Order

View and modify queue.

Recently Played

Playback history.

Logs

Merged system logs.

Spotify Operations

Token Handling

Uses refresh token to obtain access tokens.

Device Recovery

Ensures lobster-radio exists, restarts service if missing.

Track Data

  • current: /me/player
  • next: /me/player/queue

Logging

Loop logs

  • dtmf-loop

Spotify control logs

  • spotify-activate

Spotify events

  • spotify_events.json

Operational Logic

Fresh vs stale

Loop considered stale if runtime status is not updated within:

  • max(loop_interval * 2, 120)

Countdown

Calculated from:

  • updated_at
  • nextsleepfor

Upload Pipeline

  1. accept file
  2. validate
  3. save original
  4. hash file
  5. convert with ffmpeg
  6. probe metadata
  7. store metadata
  8. create queue symlink
  9. update queue order

Naming Model

  • display name: original filename
  • converted name: SHA-256 hash

Dependencies

  • Python 3
  • Flask
  • requests
  • ffmpeg / ffprobe
  • ALSA (amixer, aplay)
  • systemctl
  • journalctl
  • spotify-player.service

Environment Variables

  • SPOTIFYCLIENTID
  • SPOTIFYCLIENTSECRET

Strengths

  • clear architecture
  • persistent queue
  • runtime control
  • real-time status visibility
  • integrated Spotify recovery
  • usable UI
  • controlled logging

Operational Risks

  • token dependency
  • external WAV file presence
  • ALSA control naming
  • loop supervision
  • forecast file availability

Suggested Checks

  • loop freshness
  • Spotify service state
  • device availability
  • current track visibility
  • queue correctness
  • logs show successful playback

Summary

Lobster is a browser-controlled, queue-driven radio automation node combining Spotify playback with scheduled local inserts, forecast rotation, and persistent system state. It provides real-time control, observability, and a functional radio-style automation workflow.

More from dickie
All posts