Browse Source

add state filtering to effect enforcer.

beelzebub
Gisle Aune 1 year ago
parent
commit
88036cfcae
  1. 12
      commands/state.go
  2. 71
      services/effectenforcer.go

12
commands/state.go

@ -30,7 +30,17 @@ func (c SetState) VerboseKey() string {
type SetStateBatch map[string]device.State
func (c SetStateBatch) CommandDescription() string {
return fmt.Sprintf("SetStateBatch(%d devices)", len(c))
b := strings.Builder{}
b.WriteByte('\n')
for key, value := range c {
b.WriteString(" ")
b.WriteString(key)
b.WriteString(": ")
b.WriteString(value.String())
b.WriteRune('\n')
}
return fmt.Sprintf("SetStateBatch(%s)", b.String())
}
func (c SetStateBatch) VerboseKey() string {

71
services/effectenforcer.go

@ -5,6 +5,7 @@ import (
"git.aiterp.net/lucifer3/server/commands"
"git.aiterp.net/lucifer3/server/device"
"git.aiterp.net/lucifer3/server/events"
"git.aiterp.net/lucifer3/server/internal/color"
"git.aiterp.net/lucifer3/server/internal/gentools"
"github.com/google/uuid"
"sync"
@ -18,6 +19,9 @@ func NewEffectEnforcer(resolver device.Resolver, sceneMap device.SceneMap) lucif
sceneMap: sceneMap,
list: make([]*effectEnforcerRun, 0, 16),
index: make(map[string]*effectEnforcerRun, 8),
supportFlags: make(map[string]device.SupportFlags),
colorFlags: make(map[string]device.ColorFlags),
}
return s
@ -28,6 +32,9 @@ type effectEnforcer struct {
resolver device.Resolver
sceneMap device.SceneMap
supportFlags map[string]device.SupportFlags
colorFlags map[string]device.ColorFlags
started uint32
list []*effectEnforcerRun
@ -40,6 +47,22 @@ func (s *effectEnforcer) Active() bool {
func (s *effectEnforcer) HandleEvent(_ *lucifer3.EventBus, event lucifer3.Event) {
switch event := event.(type) {
case events.HardwareState:
s.mu.Lock()
colorFlags := s.colorFlags
supportFlags := s.supportFlags
s.mu.Unlock()
colorFlags = gentools.CopyMap(colorFlags)
supportFlags = gentools.CopyMap(supportFlags)
colorFlags[event.ID] = event.ColorFlags
supportFlags[event.ID] = event.SupportFlags
s.mu.Lock()
s.colorFlags = colorFlags
s.supportFlags = supportFlags
s.mu.Unlock()
case events.DeviceReady:
// If the device is managed by the effect enforcer, cause the effect to be
// re-ran.
@ -127,6 +150,9 @@ func (s *effectEnforcer) runLoop(bus *lucifer3.EventBus) {
deleteIDs = deleteIDs[:0]
s.mu.Lock()
colorFlags := s.colorFlags
supportFlags := s.supportFlags
for i, run := range s.list {
if run.dead {
deleteIDs = append(deleteIDs, run.id)
@ -173,6 +199,51 @@ func (s *effectEnforcer) runLoop(bus *lucifer3.EventBus) {
}
if len(batch) > 0 {
for id, state := range batch {
sf := supportFlags[id]
if state.Power != nil && !sf.HasAny(device.SFlagPower) {
state.Power = nil
}
if state.Temperature != nil && !sf.HasAny(device.SFlagTemperature) {
state.Temperature = nil
}
if state.Intensity != nil && !sf.HasAny(device.SFlagIntensity) {
state.Intensity = nil
}
if state.Color != nil && !sf.HasAny(device.SFlagColor) {
state.Color = nil
} else {
cf := colorFlags[id]
invalid := (state.Color.K != nil && !cf.HasAll(device.CFlagKelvin)) ||
(state.Color.XY != nil && !cf.HasAll(device.CFlagXY)) ||
(state.Color.RGB != nil && !cf.HasAll(device.CFlagRGB)) ||
(state.Color.HS != nil && !cf.HasAll(device.CFlagHS))
if invalid {
var converted color.Color
var ok bool
switch {
case cf.HasAny(device.CFlagXY):
converted, ok = state.Color.ToXY()
case cf.HasAny(device.CFlagRGB):
converted, ok = state.Color.ToRGB()
case cf.HasAny(device.CFlagHS):
converted, ok = state.Color.ToHS()
}
if !ok {
state.Color = nil
} else {
state.Color = &converted
}
}
}
batch[id] = state
}
bus.RunCommand(batch)
batch = make(commands.SetStateBatch, 64)
}

Loading…
Cancel
Save