From 2443468eb4b2d2508e92589cfb7d5885bd0be433 Mon Sep 17 00:00:00 2001 From: Sven van Heugten Date: Mon, 5 Jan 2026 22:48:42 +0100 Subject: [PATCH] Fix the bug by keeping state --- NightLight.Core/NightLightStateMachine.fs | 35 ++++++++++++++++------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/NightLight.Core/NightLightStateMachine.fs b/NightLight.Core/NightLightStateMachine.fs index 5a66ec4..556300f 100644 --- a/NightLight.Core/NightLightStateMachine.fs +++ b/NightLight.Core/NightLightStateMachine.fs @@ -11,14 +11,17 @@ open FsToolkit.ErrorHandling let internal tryFindLight friendlyName = Seq.tryFind (fun light -> light.FriendlyName = friendlyName) lights -let internal generateZigbeeCommandToFixLight partOfDay light = +let internal generateZigbeeCommandsToFixLight state partOfDay light = let color, brightness = getDesiredMood light.Room partOfDay |> getDesiredColorAndBrightness light.Bulb - generateZigbeeCommand color brightness light + seq { + generateZigbeeCommand color brightness light + generateStateCommand state light + } -type NightLightStateMachine private (maybeTime: DateTime option) = - new() = NightLightStateMachine None +type NightLightStateMachine private (maybeTime: DateTime option, lightToState: Map) = + new() = NightLightStateMachine(None, lights |> Seq.map (fun light -> light, On) |> Map.ofSeq) member this.OnEventReceived(event: Event) : Result = result { @@ -29,28 +32,38 @@ type NightLightStateMachine private (maybeTime: DateTime option) = let! zigbeeEvent = parseZigbeeEvent payload |> Result.mapError ParseZigbeeEventError return - this, match zigbeeEvent with | DeviceAnnounce friendlyName -> let maybeLight = tryFindLight friendlyName + this, match maybeLight with - | Some light -> generateZigbeeCommandToFixLight partOfDay light |> Seq.singleton + | Some light -> generateZigbeeCommandsToFixLight lightToState[light] partOfDay light | None -> Seq.empty | ButtonPress action -> + let desiredLightState = + match action with + | PressedOn -> On + | PressedOff -> Off + let remoteControlledLights = lights |> Seq.filter _.ControlledWithRemote - match action with - | PressedOn -> remoteControlledLights |> Seq.map (generateStateCommand On) - | PressedOff -> remoteControlledLights |> Seq.map (generateStateCommand Off) + let newLightToState = + remoteControlledLights + |> Seq.fold (fun acc key -> Map.add key desiredLightState acc) lightToState + + NightLightStateMachine(maybeTime, newLightToState), + remoteControlledLights |> Seq.map (generateStateCommand desiredLightState) | TimeChanged newTime, maybePartOfDay -> - let newState = NightLightStateMachine(Some newTime) + let newState = NightLightStateMachine(Some newTime, lightToState) let newPartOfDay = getPartOfDay newTime return newState, if maybePartOfDay <> Some newPartOfDay then - lights |> Seq.map (generateZigbeeCommandToFixLight newPartOfDay) + lights + |> Seq.collect (fun light -> + generateZigbeeCommandsToFixLight lightToState[light] newPartOfDay light) else Seq.empty | _, None -> return! Error TimeIsUnknown