|
|
package uistate
import ( lucifer3 "git.aiterp.net/lucifer3/server" "git.aiterp.net/lucifer3/server/commands" "git.aiterp.net/lucifer3/server/effects" "git.aiterp.net/lucifer3/server/events" "git.aiterp.net/lucifer3/server/internal/gentools" "sync" )
func NewService() lucifer3.ActiveService { return &service{} }
type service struct { mu sync.Mutex data Data listener []chan Patch }
func (s *service) Active() bool { return true }
func (s *service) HandleCommand(bus *lucifer3.EventBus, command lucifer3.Command) { var patches []Patch
switch command := command.(type) { case commands.SetState: patches = []Patch{{Device: &DevicePatch{ID: command.ID, DesiredState: &command.State}}} case commands.SetStateBatch: for id, state := range command { patches = append(patches, Patch{ Device: &DevicePatch{ID: id, DesiredState: gentools.ShallowCopy(&state)}, }) } }
if len(patches) > 0 { s.mu.Lock() s.data = s.data.WithPatch(patches...) s.mu.Unlock()
for _, patch := range patches { bus.RunEvent(patch) } } }
func (s *service) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) { var patches []Patch
switch event := event.(type) { case events.AliasAdded: patches = []Patch{{Device: &DevicePatch{ID: event.ID, AddAlias: &event.Alias}}} case events.AliasRemoved: patches = []Patch{{Device: &DevicePatch{ID: event.ID, RemoveAlias: &event.Alias}}} case events.HardwareState: patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWState: &event}}} if event.State.Color != nil { rgb, _ := event.State.Color.ToRGB() patches = append(patches, Patch{Device: &DevicePatch{ ID: event.ID, ActiveColorRGB: gentools.Ptr(rgb.RGB.Round()), }}) } else { patches = append(patches, Patch{Device: &DevicePatch{ ID: event.ID, ClearActiveColorRGB: false, }}) } case events.HardwareMetadata: patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWMetadata: &event}}} case events.AssignmentCreated: patches = []Patch{{Assignment: &AssignmentPatch{ ID: event.ID, Effect: &effects.Serializable{Effect: event.Effect}, }}} case events.AssignmentRemoved: patches = []Patch{{Assignment: &AssignmentPatch{ ID: event.ID, Delete: true, }}} case events.MotionSensed: patches = []Patch{{Device: &DevicePatch{ ID: event.ID, Sensors: &DeviceSensors{LastMotion: gentools.Ptr(event.SecondsSince)}, }}} case events.TemperatureChanged: patches = []Patch{{Device: &DevicePatch{ ID: event.ID, Sensors: &DeviceSensors{Temperature: gentools.Ptr(event.Temperature)}, }}} case events.DeviceAssigned: // Un-assign from current assignment (if any)
if d, ok := s.data.Devices[event.DeviceID]; ok && d.Assignment != nil { patches = append(patches, Patch{Assignment: &AssignmentPatch{ ID: *d.Assignment, RemoveDeviceID: &d.ID, }}) }
// Assign to current assignment (if it's not cleared)
if event.AssignmentID != nil { patches = append(patches, Patch{Assignment: &AssignmentPatch{ ID: *event.AssignmentID, AddDeviceID: &event.DeviceID, }}) }
// Always set the assignment
patches = append(patches, Patch{Device: &DevicePatch{ ID: event.DeviceID, Assignment: gentools.ShallowCopy(event.AssignmentID), ClearAssignment: event.AssignmentID == nil, }}) case events.AssignmentVariables: // Always set the assignment
patches = append(patches, Patch{Assignment: &AssignmentPatch{ ID: event.ID, Variables: event.Map, }}) }
if len(patches) > 0 { s.mu.Lock() s.data = s.data.WithPatch(patches...) s.mu.Unlock()
for _, patch := range patches { bus.RunEvent(patch) } } }
|