diff --git a/src/engine.py b/src/engine.py index 0816805..32c3800 100644 --- a/src/engine.py +++ b/src/engine.py @@ -4,20 +4,18 @@ import math from models import ( EngineFixture, - EngineKeyframe, EngineTrack, Flickr, + FlickrApiInterface, Interpolation, - Keyframe, KeyframeValue, - Parameter, ) class Engine: """Render a lightshow.""" - def __init__(self, flickr: Flickr, apis: dict[str, str]) -> None: + def __init__(self, flickr: Flickr, apis: dict[str, FlickrApiInterface]) -> None: self.apis = apis self.flickr = flickr self.tracks: list[EngineTrack] = [] @@ -90,7 +88,7 @@ class Engine: """Forward new fixture states to APIs.""" for f in self.fixtures.values(): api = self.apis[f.fixture.api] - # TODO: Pass update to API + api.update_fixture(f) def get_current_value(self, track: EngineTrack) -> KeyframeValue: """Interpolate between current keyframes of track and return the interpolated value.""" diff --git a/src/hue.py b/src/hue.py new file mode 100644 index 0000000..5b530db --- /dev/null +++ b/src/hue.py @@ -0,0 +1,33 @@ +import logging +from models import Capabilities, EngineFixture, FlickrApiInterface +from phue import Bridge + + +class HueApi(FlickrApiInterface): + def __init__(self, ip: str) -> None: + super().__init__() + self.bridge = Bridge(ip) + self.bridge.connect() + + def update_fixture(self, fixture: EngineFixture) -> bool: + command = { + "on": bool(fixture.on), + "transitiontime": int(fixture.transition * 10), + } + + # Set values based on capabilities + if fixture.fixture.capabilities in [ + Capabilities.BRIGHTNESS, + Capabilities.COLOR, + Capabilities.TEMPERATURE, + ]: + command["bri"] = fixture.brightness * 255 + if fixture.fixture.capabilities in [Capabilities.COLOR]: + command["sat"] = fixture.brightness * 255 + command["hue"] = fixture.hue * 65535 + if fixture.fixture.capabilities in [Capabilities.TEMPERATURE]: + command["ct"] = fixture.temperature + + # Apply update + self.bridge.set_light(fixture.fixture.api_id, command) + return True diff --git a/src/models.py b/src/models.py index cc7693e..c4040d4 100644 --- a/src/models.py +++ b/src/models.py @@ -87,16 +87,16 @@ class EngineFixture: """On state.""" brightness: float = 0 - """Brightness state.""" + """Brightness state. [0, 1]""" hue: float = 0 - """Hue state.""" + """Hue state. [0, 1]""" saturation: float = 0 - """Saturation state.""" + """Saturation state. [0, 1]""" temperature: float = 0 - """Temperature state.""" + """Temperature state, in Kelvin.""" transition: float = 0 """Transition time in seconds.""" @@ -298,6 +298,12 @@ class Flickr: return Flickr.schema().loads(json) # type: ignore +class FlickrApiInterface: + def update_fixture(self, fixture: EngineFixture) -> bool: + """Update fixture state in API. Returns true if successful.""" + raise NotImplementedError("'update_fixture' not yet implemented.") + + if __name__ == "__main__": # Small test f = Flickr(