Fix the bug by keeping state

This commit is contained in:
Sven van Heugten 2026-01-05 22:48:42 +01:00
parent bb528e9942
commit 2443468eb4

View file

@ -11,14 +11,17 @@ open FsToolkit.ErrorHandling
let internal tryFindLight friendlyName = let internal tryFindLight friendlyName =
Seq.tryFind (fun light -> light.FriendlyName = friendlyName) lights Seq.tryFind (fun light -> light.FriendlyName = friendlyName) lights
let internal generateZigbeeCommandToFixLight partOfDay light = let internal generateZigbeeCommandsToFixLight state partOfDay light =
let color, brightness = let color, brightness =
getDesiredMood light.Room partOfDay |> getDesiredColorAndBrightness light.Bulb 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) = type NightLightStateMachine private (maybeTime: DateTime option, lightToState: Map<Light, State>) =
new() = NightLightStateMachine None new() = NightLightStateMachine(None, lights |> Seq.map (fun light -> light, On) |> Map.ofSeq)
member this.OnEventReceived(event: Event) : Result<NightLightStateMachine * Message seq, OnEventReceivedError> = member this.OnEventReceived(event: Event) : Result<NightLightStateMachine * Message seq, OnEventReceivedError> =
result { result {
@ -29,28 +32,38 @@ type NightLightStateMachine private (maybeTime: DateTime option) =
let! zigbeeEvent = parseZigbeeEvent payload |> Result.mapError ParseZigbeeEventError let! zigbeeEvent = parseZigbeeEvent payload |> Result.mapError ParseZigbeeEventError
return return
this,
match zigbeeEvent with match zigbeeEvent with
| DeviceAnnounce friendlyName -> | DeviceAnnounce friendlyName ->
let maybeLight = tryFindLight friendlyName let maybeLight = tryFindLight friendlyName
this,
match maybeLight with match maybeLight with
| Some light -> generateZigbeeCommandToFixLight partOfDay light |> Seq.singleton | Some light -> generateZigbeeCommandsToFixLight lightToState[light] partOfDay light
| None -> Seq.empty | None -> Seq.empty
| ButtonPress action -> | ButtonPress action ->
let desiredLightState =
match action with
| PressedOn -> On
| PressedOff -> Off
let remoteControlledLights = lights |> Seq.filter _.ControlledWithRemote let remoteControlledLights = lights |> Seq.filter _.ControlledWithRemote
match action with let newLightToState =
| PressedOn -> remoteControlledLights |> Seq.map (generateStateCommand On) remoteControlledLights
| PressedOff -> remoteControlledLights |> Seq.map (generateStateCommand Off) |> Seq.fold (fun acc key -> Map.add key desiredLightState acc) lightToState
NightLightStateMachine(maybeTime, newLightToState),
remoteControlledLights |> Seq.map (generateStateCommand desiredLightState)
| TimeChanged newTime, maybePartOfDay -> | TimeChanged newTime, maybePartOfDay ->
let newState = NightLightStateMachine(Some newTime) let newState = NightLightStateMachine(Some newTime, lightToState)
let newPartOfDay = getPartOfDay newTime let newPartOfDay = getPartOfDay newTime
return return
newState, newState,
if maybePartOfDay <> Some newPartOfDay then if maybePartOfDay <> Some newPartOfDay then
lights |> Seq.map (generateZigbeeCommandToFixLight newPartOfDay) lights
|> Seq.collect (fun light ->
generateZigbeeCommandsToFixLight lightToState[light] newPartOfDay light)
else else
Seq.empty Seq.empty
| _, None -> return! Error TimeIsUnknown | _, None -> return! Error TimeIsUnknown