add state filtering to effect enforcer.
This commit is contained in:
+11
-1
@@ -30,7 +30,17 @@ func (c SetState) VerboseKey() string {
|
|||||||
type SetStateBatch map[string]device.State
|
type SetStateBatch map[string]device.State
|
||||||
|
|
||||||
func (c SetStateBatch) CommandDescription() string {
|
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 {
|
func (c SetStateBatch) VerboseKey() string {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"git.aiterp.net/lucifer3/server/commands"
|
"git.aiterp.net/lucifer3/server/commands"
|
||||||
"git.aiterp.net/lucifer3/server/device"
|
"git.aiterp.net/lucifer3/server/device"
|
||||||
"git.aiterp.net/lucifer3/server/events"
|
"git.aiterp.net/lucifer3/server/events"
|
||||||
|
"git.aiterp.net/lucifer3/server/internal/color"
|
||||||
"git.aiterp.net/lucifer3/server/internal/gentools"
|
"git.aiterp.net/lucifer3/server/internal/gentools"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -18,6 +19,9 @@ func NewEffectEnforcer(resolver device.Resolver, sceneMap device.SceneMap) lucif
|
|||||||
sceneMap: sceneMap,
|
sceneMap: sceneMap,
|
||||||
list: make([]*effectEnforcerRun, 0, 16),
|
list: make([]*effectEnforcerRun, 0, 16),
|
||||||
index: make(map[string]*effectEnforcerRun, 8),
|
index: make(map[string]*effectEnforcerRun, 8),
|
||||||
|
|
||||||
|
supportFlags: make(map[string]device.SupportFlags),
|
||||||
|
colorFlags: make(map[string]device.ColorFlags),
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
@@ -28,6 +32,9 @@ type effectEnforcer struct {
|
|||||||
resolver device.Resolver
|
resolver device.Resolver
|
||||||
sceneMap device.SceneMap
|
sceneMap device.SceneMap
|
||||||
|
|
||||||
|
supportFlags map[string]device.SupportFlags
|
||||||
|
colorFlags map[string]device.ColorFlags
|
||||||
|
|
||||||
started uint32
|
started uint32
|
||||||
|
|
||||||
list []*effectEnforcerRun
|
list []*effectEnforcerRun
|
||||||
@@ -40,6 +47,22 @@ func (s *effectEnforcer) Active() bool {
|
|||||||
|
|
||||||
func (s *effectEnforcer) HandleEvent(_ *lucifer3.EventBus, event lucifer3.Event) {
|
func (s *effectEnforcer) HandleEvent(_ *lucifer3.EventBus, event lucifer3.Event) {
|
||||||
switch event := event.(type) {
|
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:
|
case events.DeviceReady:
|
||||||
// If the device is managed by the effect enforcer, cause the effect to be
|
// If the device is managed by the effect enforcer, cause the effect to be
|
||||||
// re-ran.
|
// re-ran.
|
||||||
@@ -127,6 +150,9 @@ func (s *effectEnforcer) runLoop(bus *lucifer3.EventBus) {
|
|||||||
deleteIDs = deleteIDs[:0]
|
deleteIDs = deleteIDs[:0]
|
||||||
|
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
|
colorFlags := s.colorFlags
|
||||||
|
supportFlags := s.supportFlags
|
||||||
|
|
||||||
for i, run := range s.list {
|
for i, run := range s.list {
|
||||||
if run.dead {
|
if run.dead {
|
||||||
deleteIDs = append(deleteIDs, run.id)
|
deleteIDs = append(deleteIDs, run.id)
|
||||||
@@ -173,6 +199,51 @@ func (s *effectEnforcer) runLoop(bus *lucifer3.EventBus) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(batch) > 0 {
|
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)
|
bus.RunCommand(batch)
|
||||||
batch = make(commands.SetStateBatch, 64)
|
batch = make(commands.SetStateBatch, 64)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user