You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

135 lines
3.7 KiB

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)
}
}
}