- Python 100%
| .gitignore | ||
| __main__.py | ||
| app.py | ||
| config.py | ||
| LICENSE | ||
| models.py | ||
| README.md | ||
| requirements.txt | ||
| shortcuts.csv | ||
| shortcuts.py | ||
| utils.py | ||
| widgets.py | ||
EOS Terminal Remote — Textual TUI for ETC Eos over OSC
A lightweight Textual-based terminal UI to send OSC commands to an ETC Eos console and monitor incoming OSC messages in real time.
It's ideal for testing, debugging, and operating Eos remotely via OSC TCP.
The interface and log output include some German terms to fit existing production workflows.
✨ Features
- Live OSC session over TCP using
python-osc - Command line display that mirrors
/eos/out/user/{user}/cmd - Flexible input parser:
- Lines starting with
/are sent as raw OSC messages - Other lines are sent as Eos text commands via
/eos/user/{user}/newcmd
- Lines starting with
- Customizable shortcuts via CSV file for frequently-used commands
- Rich Textual TUI:
- Header, Footer, connection status, scrollable log, and command-line mirror
- Shortcut grid overlay (press
F2)
- Key bindings:
Ctrl+Q— QuitCtrl+Shift+C— Copy selected text to clipboard (OSC52 + wl-copy/xclip/xsel fallback)Ctrl+Y— Copy selected text to clipboard (fallback key if terminal capturesCtrl+Shift+C)Esc— Clear inputF2— Toggle shortcuts overlayEnter— Submit (or focus input)
🧰 Requirements
- Python: 3.10 or newer
- Platform: macOS, Linux, or Windows 10/11
- Network: Reachable ETC Eos console (default:
10.20.5.14:3032)
Python dependencies
All required packages are listed in requirements.txt:
textual
rich
python-osc
📁 Project Structure
osc_console/
├── __init__.py # Package initialization
├── __main__.py # Entry point (python -m osc_console)
├── config.py # Configuration constants and exceptions
├── models.py # Data classes and protocols
├── utils.py # OSC parsing and message building utilities
├── shortcuts.py # CSV reader for shortcut management
├── widgets.py # UI widgets and screens
└── app.py # Main application logic
shortcuts.csv # Shortcut configuration (optional)
⚙️ Setup with Virtual Environment (venv)
Run these commands in the project root folder.
macOS / Linux
# 1) Create virtual environment
python3 -m venv venv
# 2) Activate it
source venv/bin/activate
# 3) Upgrade pip (recommended)
python -m pip install --upgrade pip
# 4) Install dependencies from requirements.txt
pip install -r requirements.txt
# 5) Run the app
python -m osc_console
# OR
python app.py
Windows (PowerShell)
# 1) Create virtual environment
py -m venv venv
# 2) Activate it
.\venv\Scripts\Activate.ps1
# 3) Upgrade pip (recommended)
python -m pip install --upgrade pip
# 4) Install dependencies from requirements.txt
pip install -r requirements.txt
# 5) Run the app
python -m osc_console
# OR
python app.py
To deactivate later:
deactivate
🚀 Usage
Start the app:
# As a module
python -m osc_console
# Or directly
python app.py
You'll see:
- A status line showing connection state and show name
- A scrolling log of all OSC traffic
- A command-line display showing the live Eos cmdline for the current user
- An input field at the bottom
Sending commands
- Eos command (sent to
/eos/user/{user}/newcmd):Group 1 @ Full #
To send a Terminated Command you must type
#orEnteras the Enter Key on EOS
- Raw OSC message (starts with
/):/eos/key/go_0 /eos/cue/1/fire /eos/cue/1/label "Intro" /custom/address 1 2 3 true 0xFF
Arguments are automatically typed (int, float, bool, hex).
Internal commands
| Command | Action |
|---|---|
:quit or :exit |
Graceful shutdown |
:user <number> |
Switch to different Eos user (e.g., :user 3) |
:reload_shortcuts |
Reload shortcuts from CSV file |
:copy_last |
Copy last non-empty log line to clipboard |
:connect <ip> <port> [mode] |
Reconnect to different console (e.g., :connect 192.168.1.100 3032 1.1) |
Controls
| Key / Action | Description |
|---|---|
Ctrl+Q |
Quit the app |
Ctrl+Shift+C |
Copy selected text (system clipboard fallback on Linux) |
Ctrl+Y |
Copy selected text (fallback key) |
Esc |
Clear input field |
F2 |
Toggle shortcuts overlay |
Enter |
Submit command or refocus input |
🎛️ Shortcuts
Create a shortcuts.csv file in the project root to define custom shortcut buttons:
CSV Format
label,address,args
Macro 8400,/eos/macro/fire,8400
Cue 1 Go,/eos/cue/1/fire,
Go,/eos/key/go_0,
Blackout,/eos/key/blackout,
Preset 1 @ 50,/eos/user/5/newcmd,Preset 1 @ 50
Columns:
label— Button text (required)address— OSC address (required)args— Optional arguments, semicolon-separated for multiple values (e.g.,1;2;3)
Features:
- Arguments are auto-typed:
true→ bool,0xFF→ int,3.14→ float - Press
F2to show/hide shortcuts grid - Use
:reload_shortcutsto reload CSV without restarting
⚙️ Configuration
Default settings are defined in config.py:
class Config:
DEFAULT_EOS_USER = 5
DEFAULT_HOST = "10.20.5.14"
DEFAULT_PORT = 3032
DEFAULT_PROMPT = ">> "
DEFAULT_SHORTCUTS_CSV = "shortcuts.csv"
DEFAULT_OSC_MODE = "1.1"
PING_INTERVAL_SECONDS = 20
You can override these when starting the app:
# In app.py or __main__.py
if __name__ == "__main__":
OSCConsole(
ip="192.168.1.100",
port=3032,
prompt="EOS> ",
shortcuts_csv="my_shortcuts.csv",
osc_mode="1.1"
).run()
Parameters:
ip— Target Eos console IPport— OSC TCP port (default: 3032)prompt— Input prompt textshortcuts_csv— Path to shortcuts CSV fileosc_mode— OSC protocol mode (default: "1.1")
🧩 How It Works
- Opens a TCP OSC client (
AsyncSimpleTCPClient) to the target IP/port - Sends
/eos/subscribewhen connected - Listens for OSC packets and logs them in real-time
- Filters
/eos/out/user/{user}/cmdto update the command-line display - Filters
/eos/out/show/nameto display the current show name - Parses user input via
shlexand builds OSC messages dynamically - Sends periodic
/eos/pingmessages (every 20 seconds) to keep connection alive
Architecture
The application uses a modular architecture:
- config.py — Constants, OSC addresses, exceptions
- models.py — Data structures (ShortcutSpec, OSCSessionState)
- utils.py — OSC message parsing and building
- shortcuts.py — CSV-based shortcut configuration
- widgets.py — Textual UI components
- app.py — Main application and OSC session management
🧰 Troubleshooting
| Problem | Solution |
|---|---|
| No connection / timeout | Check IP and TCP port (3032). Verify OSC TCP is enabled on the console. |
| No cmdline updates | Ensure Eos is publishing /eos/out/user/{user}/cmd. Check user number with :user <number>. |
| Shortcuts not loading | Check shortcuts.csv format. Use :reload_shortcuts to reload. Check log for errors. |
| Strange characters in display | ANSI and control codes are stripped, but malformed OSC messages may still display unexpected bytes. |
| Activation policy error (Windows) | Run PowerShell as Admin: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser |
| Import errors | Ensure all modules are in the same directory and virtual environment is activated. |
🗺️ Roadmap / TODO
- Runtime commands for:
- Change Eos user (
:user <number>) - Reload shortcuts (
:reload_shortcuts) - (Re)connect to console (
:connect <ip> <port> [mode]) - Switch between inline / newline commands
- Change Eos user (
- UI improvements:
- Customizable shortcuts via CSV
- Macro overview panel
- Customizable "Direct Select" view
- Improved command echo formatting
- Color-coded OSC message types
- Advanced features:
- Multiple Eos console support
- Save/load session history
- OSC message filtering
- Export logs to file
🧾 License — MIT
Copyright (c) 2025
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.