Add .env support for transport and sound device configuration

- Add python-dotenv support to control_server.py and sound.py
- Load TRANSPORT from environment variable (default: spi)
- Load AUDIO_INPUT_DEVICE from environment variable (default: 7)
- Load all port configurations from environment variables
- Update .env.example with comprehensive configuration options
- Create .env file with sensible defaults for Pi
- Transport, sound device, and network settings now configurable via .env
This commit is contained in:
Pi User
2025-10-03 20:19:55 +13:00
parent fbf4205c87
commit e78a8727b2
6 changed files with 68 additions and 11 deletions

9
.env Normal file
View File

@@ -0,0 +1,9 @@
# Lighting Controller Configuration
CONTROL_SERVER_URI=ws://localhost:8765
CONTROL_SERVER_PORT=8765
TRANSPORT=spi
AUDIO_INPUT_DEVICE=7
MIDI_TCP_HOST=127.0.0.1
MIDI_TCP_PORT=65432
SOUND_CONTROL_HOST=127.0.0.1
SOUND_CONTROL_PORT=65433

View File

@@ -1,5 +1,8 @@
# Lighting Controller Configuration
# ==============================
# WebSocket Configuration
# ==============================
# WebSocket URI for the control server
# Used by UI client and test scripts to connect to the control server
#
@@ -11,3 +14,27 @@ CONTROL_SERVER_URI=ws://10.42.0.1:8765
#
# For custom IP (if your Pi has a different address):
# CONTROL_SERVER_URI=ws://YOUR_PI_IP:8765
# Control server WebSocket port
CONTROL_SERVER_PORT=8765
# ==============================
# Transport Configuration
# ==============================
# Transport method for LED communication
# Options: spi, websocket
TRANSPORT=spi
# ==============================
# Sound Detection Configuration
# ==============================
# Audio input device index (use sound.py to list available devices)
AUDIO_INPUT_DEVICE=7
# MIDI TCP configuration
MIDI_TCP_HOST=127.0.0.1
MIDI_TCP_PORT=65432
# Sound control server configuration
SOUND_CONTROL_HOST=127.0.0.1
SOUND_CONTROL_PORT=65433

View File

@@ -13,6 +13,7 @@ python-rtmidi = "*"
pyaudio = "*"
aubio = "*"
websocket-client = "*"
python-dotenv = "*"
[dev-packages]

10
Pipfile.lock generated
View File

@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "3f3ca9af45dd4382aac3c649ae11cefbe97059ad14f40172735213c4919baada"
"sha256": "db66b0f2b4e51e5a0bc2edc0d89af123c03928c72add32c16ba955eaefc34da7"
},
"pipfile-spec": 6,
"requires": {
@@ -162,6 +162,14 @@
"index": "pypi",
"version": "==0.2.14"
},
"python-dotenv": {
"hashes": [
"sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc",
"sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab"
],
"index": "pypi",
"version": "==1.1.1"
},
"python-rtmidi": {
"hashes": [
"sha256:052c89933cae4fca354012d8ca7248f4f9e1e3f062471409d48415a7f7d7e59e",

View File

@@ -13,17 +13,22 @@ import socket
import threading
import time
import argparse
import os
from dotenv import load_dotenv
from bar_config import LED_BAR_NAMES, DEFAULT_BAR_SETTINGS
from color_utils import adjust_brightness
from networking import SPIClient, WebSocketClient
# Load environment variables from .env file
load_dotenv()
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Configuration
CONTROL_SERVER_PORT = 8765
SOUND_CONTROL_HOST = "127.0.0.1"
SOUND_CONTROL_PORT = 65433
CONTROL_SERVER_PORT = int(os.getenv("CONTROL_SERVER_PORT", "8765"))
SOUND_CONTROL_HOST = os.getenv("SOUND_CONTROL_HOST", "127.0.0.1")
SOUND_CONTROL_PORT = int(os.getenv("SOUND_CONTROL_PORT", "65433"))
# Pattern name mapping for shorter JSON payloads
PATTERN_NAMES = {
@@ -463,11 +468,12 @@ def parse_arguments():
# Transport selection
transport_group = parser.add_argument_group("Transport Options")
default_transport = os.getenv("TRANSPORT", "spi")
transport_group.add_argument(
"--transport",
choices=["spi", "websocket"],
default="spi",
help="Transport method for LED communication (default: spi)"
default=default_transport,
help=f"Transport method for LED communication (default from .env or {default_transport})"
)
# Control options

View File

@@ -11,18 +11,23 @@ import time
import logging # Added logging import
import asyncio # Re-added asyncio import
import threading # Added threading for control server
import os
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Configure logging
DEBUG_MODE = True # Set to False for INFO level logging
logging.basicConfig(level=logging.DEBUG if DEBUG_MODE else logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# TCP Server Configuration (assuming midi.py runs this)
MIDI_TCP_HOST = "127.0.0.1"
MIDI_TCP_PORT = 65432
MIDI_TCP_HOST = os.getenv("MIDI_TCP_HOST", "127.0.0.1")
MIDI_TCP_PORT = int(os.getenv("MIDI_TCP_PORT", "65432"))
# Sound Control Server Configuration (for midi.py to control sound.py)
SOUND_CONTROL_HOST = "127.0.0.1"
SOUND_CONTROL_PORT = 65433
SOUND_CONTROL_HOST = os.getenv("SOUND_CONTROL_HOST", "127.0.0.1")
SOUND_CONTROL_PORT = int(os.getenv("SOUND_CONTROL_PORT", "65433"))
class SoundBeatDetector:
def __init__(self, tcp_host: str, tcp_port: int, *, input_device: int | None = None):
@@ -35,7 +40,8 @@ class SoundBeatDetector:
self.bufferSize = 512
self.windowSizeMultiple = 2
self.audioInputDeviceIndex = 7 if input_device is None else int(input_device)
default_device = int(os.getenv("AUDIO_INPUT_DEVICE", "7"))
self.audioInputDeviceIndex = default_device if input_device is None else int(input_device)
self.audioInputChannels = 1
self.pa = pyaudio.PyAudio()