Update config.py
Added a new ButtonConfig dataclass: enabled: bool = False pin: int = 17 (BCM pin for the button) long_press_seconds: float = 1.0 Extended the main Config dataclass with a button: ButtonConfig field. Updated load_config_from_json() to construct button_config from the "button" section in config.json. This allows enabling/disabling the button, changing the GPIO pin, and tuning the long-press threshold (and optional poll interval) without code changes.
This commit is contained in:
@@ -5,6 +5,9 @@ from dataclasses import dataclass, field
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
|
import logging
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Configuration Dataclasses
|
# Configuration Dataclasses
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@@ -16,6 +19,7 @@ class AudioConfig:
|
|||||||
input_block_size: int = 1024
|
input_block_size: int = 1024
|
||||||
output_device: Optional[str] = None
|
output_device: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class WakeWordConfig:
|
class WakeWordConfig:
|
||||||
"""Settings for wake word detection."""
|
"""Settings for wake word detection."""
|
||||||
@@ -25,12 +29,14 @@ class WakeWordConfig:
|
|||||||
refractory_seconds: float = 2.0
|
refractory_seconds: float = 2.0
|
||||||
download_dir: str = "local"
|
download_dir: str = "local"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ESPHomeConfig:
|
class ESPHomeConfig:
|
||||||
"""Settings for the ESPHome API server."""
|
"""Settings for the ESPHome API server."""
|
||||||
host: str = "0.0.0.0"
|
host: str = "0.0.0.0"
|
||||||
port: int = 6053
|
port: int = 6053
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class LedConfig:
|
class LedConfig:
|
||||||
"""Settings for the LED strip."""
|
"""Settings for the LED strip."""
|
||||||
@@ -38,7 +44,8 @@ class LedConfig:
|
|||||||
interface: str = "spi"
|
interface: str = "spi"
|
||||||
clock_pin: int = 13
|
clock_pin: int = 13
|
||||||
data_pin: int = 12
|
data_pin: int = 12
|
||||||
num_leds: int = 3 # Note: This will be overridden by 'preferences.json' if it exists
|
num_leds: int = 3 # Note: overridden by 'preferences.json' if it exists
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MqttConfig:
|
class MqttConfig:
|
||||||
@@ -49,6 +56,17 @@ class MqttConfig:
|
|||||||
username: Optional[str] = None
|
username: Optional[str] = None
|
||||||
password: Optional[str] = None
|
password: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ButtonConfig:
|
||||||
|
"""Settings for a hardware momentary button (e.g. ReSpeaker 2-Mic HAT)."""
|
||||||
|
enabled: bool = False
|
||||||
|
# BCM GPIO pin number for the button input.
|
||||||
|
pin: int = 17
|
||||||
|
# Press duration (in seconds) to be considered a "long press".
|
||||||
|
long_press_seconds: float = 1.0
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class AppConfig:
|
class AppConfig:
|
||||||
"""General application settings."""
|
"""General application settings."""
|
||||||
@@ -58,6 +76,7 @@ class AppConfig:
|
|||||||
preferences_file: str = "preferences.json"
|
preferences_file: str = "preferences.json"
|
||||||
debug: bool = False
|
debug: bool = False
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Config:
|
class Config:
|
||||||
"""Main configuration object."""
|
"""Main configuration object."""
|
||||||
@@ -67,6 +86,7 @@ class Config:
|
|||||||
esphome: ESPHomeConfig = field(default_factory=ESPHomeConfig)
|
esphome: ESPHomeConfig = field(default_factory=ESPHomeConfig)
|
||||||
led: LedConfig = field(default_factory=LedConfig)
|
led: LedConfig = field(default_factory=LedConfig)
|
||||||
mqtt: MqttConfig = field(default_factory=MqttConfig)
|
mqtt: MqttConfig = field(default_factory=MqttConfig)
|
||||||
|
button: ButtonConfig = field(default_factory=ButtonConfig)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Helper Function
|
# Helper Function
|
||||||
@@ -88,7 +108,9 @@ def load_config_from_json(config_path: Path) -> Config:
|
|||||||
|
|
||||||
# --- Step 2: Create config objects from raw data ---
|
# --- Step 2: Create config objects from raw data ---
|
||||||
if "app" not in raw_data:
|
if "app" not in raw_data:
|
||||||
raise ValueError("Configuration file must contain an 'app' section with a 'name'.")
|
raise ValueError(
|
||||||
|
"Configuration file must contain an 'app' section with a 'name'."
|
||||||
|
)
|
||||||
|
|
||||||
app_config = AppConfig(**raw_data.get("app", {}))
|
app_config = AppConfig(**raw_data.get("app", {}))
|
||||||
audio_config = AudioConfig(**raw_data.get("audio", {}))
|
audio_config = AudioConfig(**raw_data.get("audio", {}))
|
||||||
@@ -96,6 +118,7 @@ def load_config_from_json(config_path: Path) -> Config:
|
|||||||
esphome_config = ESPHomeConfig(**raw_data.get("esphome", {}))
|
esphome_config = ESPHomeConfig(**raw_data.get("esphome", {}))
|
||||||
led_config = LedConfig(**raw_data.get("led", {}))
|
led_config = LedConfig(**raw_data.get("led", {}))
|
||||||
mqtt_config = MqttConfig(**raw_data.get("mqtt", {}))
|
mqtt_config = MqttConfig(**raw_data.get("mqtt", {}))
|
||||||
|
button_config = ButtonConfig(**raw_data.get("button", {}))
|
||||||
|
|
||||||
# --- Step 3: Set MQTT 'enabled' flag ---
|
# --- Step 3: Set MQTT 'enabled' flag ---
|
||||||
if mqtt_config.host:
|
if mqtt_config.host:
|
||||||
@@ -109,7 +132,5 @@ def load_config_from_json(config_path: Path) -> Config:
|
|||||||
esphome=esphome_config,
|
esphome=esphome_config,
|
||||||
led=led_config,
|
led=led_config,
|
||||||
mqtt=mqtt_config,
|
mqtt=mqtt_config,
|
||||||
|
button=button_config,
|
||||||
)
|
)
|
||||||
|
|
||||||
import logging
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user