Introduce generateZigbeeCommandsForDifference

This commit is contained in:
Sven van Heugten 2026-01-17 16:07:12 +01:00
parent 9fa7037f0e
commit bc421bc1a7

View file

@ -37,13 +37,23 @@ let internal withStateForRemoteControlledLights (state: State) (oldNightLightSta
remoteControlledLights remoteControlledLights
|> Seq.fold (fun acc light -> acc |> withStateFor light state) oldNightLightState |> Seq.fold (fun acc light -> acc |> withStateFor light state) oldNightLightState
let internal generateZigbeeCommandsForDifference (maybeBefore: NightLightState option) (after: NightLightState) =
after.LightToState
|> Seq.collect (fun (KeyValue(light, newState)) ->
let oldState = maybeBefore |> Option.map _.LightToState[light]
if oldState <> Some newState then
generateZigbeeCommandsToFixLight newState light
else
Seq.empty)
type NightLightStateMachine private (maybeState: NightLightState option) = type NightLightStateMachine private (maybeState: NightLightState option) =
new() = NightLightStateMachine None new() = NightLightStateMachine None
member this.OnEventReceived(event: Event) : Result<NightLightStateMachine * Message seq, OnEventReceivedError> = member this.OnEventReceived(event: Event) : Result<NightLightStateMachine * Message seq, OnEventReceivedError> =
result { result {
match event, maybeState with match event, maybeState with
| ReceivedZigbeeEvent payload, Some state -> | ReceivedZigbeeEvent payload, Some currentState ->
let! zigbeeEvent = parseZigbeeEvent payload |> Result.mapError ParseZigbeeEventError let! zigbeeEvent = parseZigbeeEvent payload |> Result.mapError ParseZigbeeEventError
return return
@ -53,32 +63,30 @@ type NightLightStateMachine private (maybeState: NightLightState option) =
this, this,
match maybeLight with match maybeLight with
| Some light -> generateZigbeeCommandsToFixLight state.LightToState[light] light | Some light -> generateZigbeeCommandsToFixLight currentState.LightToState[light] light
| None -> Seq.empty | None -> Seq.empty
| ButtonPress action -> | ButtonPress action ->
let newState = let newNightLightState =
match action with match action with
| PressedOn -> state |> withStateForRemoteControlledLights On | PressedOn -> currentState |> withStateForRemoteControlledLights On
| PressedOff -> state |> withStateForRemoteControlledLights Off | PressedOff -> currentState |> withStateForRemoteControlledLights Off
| PressedLeft -> | PressedLeft ->
let lightThatShouldBeOn = let lightThatShouldBeOn =
remoteControlledLights remoteControlledLights
|> Seq.find (fun light -> light.ControlledWithRemote = RemoteLeft) |> Seq.find (fun light -> light.ControlledWithRemote = RemoteLeft)
state currentState
|> withStateForRemoteControlledLights Off |> withStateForRemoteControlledLights Off
|> withStateFor lightThatShouldBeOn On |> withStateFor lightThatShouldBeOn On
NightLightStateMachine(Some newState), NightLightStateMachine(Some newNightLightState),
remoteControlledLights generateZigbeeCommandsForDifference (Some currentState) newNightLightState
|> Seq.collect (fun light -> | TimeChanged newTime, maybeCurrentState ->
generateZigbeeCommandsToFixLight newState.LightToState[light] light)
| TimeChanged newTime, maybeState ->
let newPartOfDay = getPartOfDay newTime let newPartOfDay = getPartOfDay newTime
let partOfDayChanged = let partOfDayChanged =
let maybePreviousPartOfDay = let maybePreviousPartOfDay =
maybeState |> Option.map _.Time |> Option.map getPartOfDay maybeCurrentState |> Option.map _.Time |> Option.map getPartOfDay
maybePreviousPartOfDay <> Some newPartOfDay maybePreviousPartOfDay <> Some newPartOfDay
@ -90,7 +98,9 @@ type NightLightStateMachine private (maybeState: NightLightState option) =
|> getDesiredColorAndBrightness light.Bulb |> getDesiredColorAndBrightness light.Bulb
let previousState = let previousState =
maybeState |> Option.map _.LightToState[light].State |> Option.defaultValue On maybeCurrentState
|> Option.map _.LightToState[light].State
|> Option.defaultValue On
let newState = let newState =
if partOfDayChanged && newPartOfDay = Day then if partOfDayChanged && newPartOfDay = Day then
@ -104,18 +114,12 @@ type NightLightStateMachine private (maybeState: NightLightState option) =
State = newState }) State = newState })
|> Map.ofSeq |> Map.ofSeq
let newNightLightStateMachine = let newNightLightState =
{ Time = newTime { Time = newTime
LightToState = newLightToState } LightToState = newLightToState }
|> Some
|> NightLightStateMachine
return return
newNightLightStateMachine, NightLightStateMachine(Some newNightLightState),
if partOfDayChanged then generateZigbeeCommandsForDifference maybeCurrentState newNightLightState
lights
|> Seq.collect (fun light -> generateZigbeeCommandsToFixLight newLightToState[light] light)
else
Seq.empty
| _, None -> return! Error TimeIsUnknown | _, None -> return! Error TimeIsUnknown
} }