From 0b6e2fae749fefa0261233b3c7dcbfeb1e1ea7c2 Mon Sep 17 00:00:00 2001 From: Gene Johnson Date: Thu, 19 Mar 2026 00:59:29 -0700 Subject: [PATCH] feat(figment): add trigger protocol and command types Co-Authored-By: Claude Sonnet 4.6 --- engine/figment_trigger.py | 36 +++++++++++++++++++++++++++++++ tests/test_figment_trigger.py | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 engine/figment_trigger.py create mode 100644 tests/test_figment_trigger.py diff --git a/engine/figment_trigger.py b/engine/figment_trigger.py new file mode 100644 index 0000000..d3aac9c --- /dev/null +++ b/engine/figment_trigger.py @@ -0,0 +1,36 @@ +""" +Figment trigger protocol and command types. + +Defines the extensible input abstraction for triggering figment displays +from any control surface (ntfy, MQTT, serial, etc.). +""" + +from __future__ import annotations + +from dataclasses import dataclass +from enum import Enum +from typing import Protocol + + +class FigmentAction(Enum): + TRIGGER = "trigger" + SET_INTENSITY = "set_intensity" + SET_INTERVAL = "set_interval" + SET_COLOR = "set_color" + STOP = "stop" + + +@dataclass +class FigmentCommand: + action: FigmentAction + value: float | str | None = None + + +class FigmentTrigger(Protocol): + """Protocol for figment trigger sources. + + Any input source (ntfy, MQTT, serial) can implement this + to trigger and control figment displays. + """ + + def poll(self) -> FigmentCommand | None: ... diff --git a/tests/test_figment_trigger.py b/tests/test_figment_trigger.py new file mode 100644 index 0000000..989a0bb --- /dev/null +++ b/tests/test_figment_trigger.py @@ -0,0 +1,40 @@ +"""Tests for engine.figment_trigger module.""" + +from enum import Enum + +from engine.figment_trigger import FigmentAction, FigmentCommand + + +class TestFigmentAction: + def test_is_enum(self): + assert issubclass(FigmentAction, Enum) + + def test_has_trigger(self): + assert FigmentAction.TRIGGER.value == "trigger" + + def test_has_set_intensity(self): + assert FigmentAction.SET_INTENSITY.value == "set_intensity" + + def test_has_set_interval(self): + assert FigmentAction.SET_INTERVAL.value == "set_interval" + + def test_has_set_color(self): + assert FigmentAction.SET_COLOR.value == "set_color" + + def test_has_stop(self): + assert FigmentAction.STOP.value == "stop" + + +class TestFigmentCommand: + def test_trigger_command(self): + cmd = FigmentCommand(action=FigmentAction.TRIGGER) + assert cmd.action == FigmentAction.TRIGGER + assert cmd.value is None + + def test_set_intensity_command(self): + cmd = FigmentCommand(action=FigmentAction.SET_INTENSITY, value=0.8) + assert cmd.value == 0.8 + + def test_set_color_command(self): + cmd = FigmentCommand(action=FigmentAction.SET_COLOR, value="orange") + assert cmd.value == "orange"