Store a lot less state

This commit is contained in:
Sven van Heugten 2026-03-15 11:18:17 +01:00
parent 3507385d6c
commit 3913522cc3
3 changed files with 49 additions and 70 deletions

View file

@ -24,64 +24,43 @@ let internal generateZigbeeCommandsToFixLight (light: Light) (desiredLightSettin
type internal NightLightState =
{ Time: DateTime
Alarm: bool
LightToLightSettings: Map<Light, LightSettings> }
LightToManualState: Map<Light, State> }
let internal createOrUpdateNightLightState
(time: DateTime)
(alarm: bool)
(maybeOldLightToLightSettings: Map<Light, LightSettings> option)
=
let partOfDay = getPartOfDay time
let internal computeLightSettings (light: Light) (nightLightState: NightLightState) =
let partOfDay = getPartOfDay nightLightState.Time
let lightToLightSettings =
lights
|> Seq.map (fun light ->
let color, brightness =
getDesiredMood (lightProps light).Room partOfDay
|> getDesiredColorAndBrightness (lightProps light).Bulb
let color, brightness =
getDesiredMood (lightProps light).Room partOfDay
|> getDesiredColorAndBrightness (lightProps light).Bulb
let previousState =
maybeOldLightToLightSettings
|> Option.map (fun lightToLightSettings -> lightToLightSettings[light].State)
|> Option.defaultValue On
light,
{ Color = color
Brightness =
if alarm && (light = RightBedroomLamp || light = LeftBedroomLamp) then
brightness.Scale(getAlarmWeight time)
else
brightness
State =
if alarm && (light = RightBedroomLamp || light = LeftBedroomLamp) then
On
else
previousState })
|> Map.ofSeq
{ Time = time
Alarm = alarm
LightToLightSettings = lightToLightSettings }
{ Color = color
Brightness =
if nightLightState.Alarm && (light = RightBedroomLamp || light = LeftBedroomLamp) then
brightness.Scale(getAlarmWeight nightLightState.Time)
else
brightness
State =
if nightLightState.Alarm && (light = RightBedroomLamp || light = LeftBedroomLamp) then
On
else
nightLightState.LightToManualState[light] }
let internal withStateFor (light: Light) (state: State) (oldNightLightState: NightLightState) =
let oldState = oldNightLightState.LightToLightSettings[light]
createOrUpdateNightLightState
oldNightLightState.Time
oldNightLightState.Alarm
(Map.add light { oldState with State = state } oldNightLightState.LightToLightSettings
|> Some)
{ oldNightLightState with
LightToManualState = Map.add light state oldNightLightState.LightToManualState }
let internal withAlarmOff (oldNightLightState: NightLightState) =
createOrUpdateNightLightState oldNightLightState.Time false (Some oldNightLightState.LightToLightSettings)
{ oldNightLightState with
Alarm = false }
let internal generateZigbeeCommandsForDifference (maybeBefore: NightLightState option) (after: NightLightState) =
after.LightToLightSettings
|> Seq.collect (fun (KeyValue(light, newState)) ->
let oldState = maybeBefore |> Option.map _.LightToLightSettings[light]
lights
|> Seq.collect (fun light ->
let oldLightSettings = maybeBefore |> Option.map (computeLightSettings light)
let newLightSettings = after |> computeLightSettings light
if oldState <> Some newState then
generateZigbeeCommandsToFixLight light after.LightToLightSettings[light]
if oldLightSettings <> Some newLightSettings then
generateZigbeeCommandsToFixLight light newLightSettings
else
Seq.empty)
@ -101,7 +80,10 @@ type NightLightStateMachine private (maybeState: NightLightState option) =
this,
match maybeLight with
| Some light -> generateZigbeeCommandsToFixLight light currentState.LightToLightSettings[light]
| Some light ->
currentState
|> computeLightSettings light
|> generateZigbeeCommandsToFixLight light
| None -> Seq.empty
| ButtonPress action ->
let newNightLightState =
@ -123,7 +105,6 @@ type NightLightStateMachine private (maybeState: NightLightState option) =
|> withStateFor LeftBedroomLamp On
| PressedRight ->
currentState
|> withAlarmOff
|> withStateFor LivingRoomWallLamp Off
|> withStateFor LivingRoomFloorLamp Off
@ -143,7 +124,12 @@ type NightLightStateMachine private (maybeState: NightLightState option) =
|| maybeCurrentState |> Option.map _.Alarm |> Option.defaultValue false
let newNightLightState =
createOrUpdateNightLightState newTime alarm (maybeCurrentState |> Option.map _.LightToLightSettings)
{ Time = newTime
Alarm = alarm
LightToManualState =
maybeCurrentState
|> Option.map _.LightToManualState
|> Option.defaultValue (lights |> Seq.map (fun light -> light, On) |> Map.ofSeq) }
return
NightLightStateMachine(Some newNightLightState),