2026-04-24

Tutorial: Automating OBS with Arduino on Ubuntu (KDE/Wayland)

This guide explains how to set up OBS Studio to launch on startup and run a background Python watchdog script that listens for Arduino serial commands to toggle projectors.

Prerequisites

  • OBS Studio installed.

  • obs-websocket enabled in OBS (Tools > obs-websocket Settings).

  • Python libraries: pip install obsws-python pyserial.

  • User Groups: Ensure your user can access serial ports: sudo usermod -a -G dialout $USER (Log out and back in after running).


1. Create the OBS Startup Service

We use a systemd user service to ensure OBS starts after the graphical interface is ready and restarts automatically if it crashes.

File: ~/.config/systemd/user/obs-autostart.service

Ini, TOML
[Unit]
Description=OBS Startup Projector
After=graphical-session.target

[Service]
Type=simple
ExecStart=/usr/bin/obs --scene "Scene" --startprojector preview --projector-monitor 0 --minimize-to-tray
Restart=always
RestartSec=5

[Install]
WantedBy=graphical-session.target

2. Create the Python Watchdog Service

This service runs your obsarduino.py script. It includes environment variables necessary for Python to communicate with the Wayland display and KDE's shortcut system (qdbus).

File: ~/.config/systemd/user/obs-python.service

Ini, TOML
[Unit]
Description=OBS Arduino Python Script
# Wait for OBS to be up before starting the script
After=obs-autostart.service

[Service]
Type=simple
WorkingDirectory=%h/Documents
ExecStart=/usr/bin/python3 %h/Documents/obsarduino.py

# Critical for Wayland/KDE API access
Environment=DISPLAY=:0
Environment=XDG_RUNTIME_DIR=/run/user/1000
Environment=XDG_SESSION_TYPE=wayland

Restart=always
RestartSec=5

[Install]
# Using default.target avoids "ordering cycles" with the graphical session
WantedBy=default.target

Note: %h is a shortcut for your home directory. If your User ID is not 1000, check it by running id -u and update the XDG_RUNTIME_DIR accordingly.


3. The Python Logic (obsarduino.py)

Ensure your script is saved in ~/Documents/obsarduino.py. The script handles:

  1. Opening the Projector: Via obsws_python.

  2. Closing the Projector: Via qdbus by triggering the "Window Close" shortcut in KDE.

Python
import serial
import obsws_python as obs
import time
import subprocess

SERIAL_PORT = '/dev/ttyACM0'
BAUD_RATE = 9600

cl = obs.ReqClient(host="localhost", port=4455, auth="")

def close_projector_window():
    try:
        # Triggers KDE global 'Window Close' shortcut
        subprocess.run([
            "qdbus", "org.kde.kglobalaccel", "/component/kwin", 
            "org.kde.kglobalaccel.Component.invokeShortcut", "Window Close"
        ], check=True)
    except Exception as e:
        print(f"Error closing window: {e}")

def handle_projector(val):
    try:
        if val == "1":
            cl.open_video_mix_projector(
                video_mix_type="OBS_WEBSOCKET_VIDEO_MIX_TYPE_PROGRAM",
                monitor_index=0 
            )
        elif val == "0":
            time.sleep(0.2)
            close_projector_window()
    except Exception as e:
        print(f"OBS Error: {e}")

try:
    ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
    time.sleep(2)
except Exception:
    exit() # Systemd will restart the script automatically

while True:
    if ser.in_waiting > 0:
        line = ser.readline().decode('utf-8').strip()
        if line in ["1", "0"]:
            handle_projector(line)

4. Activation and Commands

Run these commands to register and start your new automation:

ActionCommand
Reload Systemdsystemctl --user daemon-reload
Enable Servicessystemctl --user enable obs-autostart.service obs-python.service
Start Nowsystemctl --user start obs-autostart.service obs-python.service
Check Logsjournalctl --user -u obs-python.service -f
Restart Scriptsystemctl --user restart obs-python.service

Troubleshooting Tips

  • Ordering Cycle Error: If the services refuse to start due to a "cycle," ensure the Python script [Install] section uses WantedBy=default.target and not graphical-session.target.

  • Arduino Path: If your Arduino changes address (e.g., to /dev/ttyUSB0), update the SERIAL_PORT variable in your .py file and run the restart command.

  • KDE Shortcuts: Ensure your KDE system actually has a "Window Close" shortcut defined (default is usually Alt+F4).


Tiada ulasan:

Catat Ulasan

LinkWithin

Related Posts Plugin for WordPress, Blogger...