Gisle Aune
2 years ago
11 changed files with 126 additions and 219 deletions
-
2cmd/lucifer4-server/main.go
-
13events/assignment.go
-
9internal/gentools/maps.go
-
133services/effectenforcer/service.go
-
2services/hue/bridge.go
-
11services/uistate/data.go
-
19services/uistate/patch.go
-
9services/uistate/service.go
-
27services/variables/data.go
-
17services/variables/patch.go
-
103services/variables/service.go
@ -1,27 +0,0 @@ |
|||||
package variables |
|
||||
|
|
||||
import "git.aiterp.net/lucifer3/server/internal/gentools" |
|
||||
|
|
||||
type Variables struct { |
|
||||
Temperature map[string]AvgMinMax `json:"temperature"` |
|
||||
Motion map[string]AvgMinMax `json:"motion"` |
|
||||
} |
|
||||
|
|
||||
func (v Variables) WithPropertyPatch(patch PropertyPatch) Variables { |
|
||||
if patch.Motion != nil { |
|
||||
v.Motion = gentools.CopyMap(v.Motion) |
|
||||
v.Motion[patch.Key] = *patch.Motion |
|
||||
} |
|
||||
if patch.Temperature != nil { |
|
||||
v.Temperature = gentools.CopyMap(v.Temperature) |
|
||||
v.Temperature[patch.Key] = *patch.Temperature |
|
||||
} |
|
||||
|
|
||||
return v |
|
||||
} |
|
||||
|
|
||||
type AvgMinMax struct { |
|
||||
Avg float64 `json:"avg"` |
|
||||
Min float64 `json:"min"` |
|
||||
Max float64 `json:"max"` |
|
||||
} |
|
@ -1,17 +0,0 @@ |
|||||
package variables |
|
||||
|
|
||||
import "fmt" |
|
||||
|
|
||||
type PropertyPatch struct { |
|
||||
Key string `json:"id"` |
|
||||
Temperature *AvgMinMax `json:"temperature,omitempty"` |
|
||||
Motion *AvgMinMax `json:"motion,omitempty"` |
|
||||
} |
|
||||
|
|
||||
func (e PropertyPatch) VerboseKey() string { |
|
||||
return "variables.PropertyPatch" |
|
||||
} |
|
||||
|
|
||||
func (e PropertyPatch) EventDescription() string { |
|
||||
return fmt.Sprintf("variables.PropertyPatch(key=%s)", e.Key) |
|
||||
} |
|
@ -1,103 +0,0 @@ |
|||||
package variables |
|
||||
|
|
||||
import ( |
|
||||
lucifer3 "git.aiterp.net/lucifer3/server" |
|
||||
"git.aiterp.net/lucifer3/server/events" |
|
||||
"git.aiterp.net/lucifer3/server/services" |
|
||||
) |
|
||||
|
|
||||
func NewService(resolver *services.Resolver) lucifer3.Service { |
|
||||
return &service{ |
|
||||
resolver: resolver, |
|
||||
temperatures: map[string]float64{}, |
|
||||
motions: map[string]float64{}, |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
type service struct { |
|
||||
resolver *services.Resolver |
|
||||
temperatures map[string]float64 |
|
||||
motions map[string]float64 |
|
||||
} |
|
||||
|
|
||||
func (s *service) Active() bool { |
|
||||
return true |
|
||||
} |
|
||||
|
|
||||
func (s *service) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) { |
|
||||
var patchEvents []lucifer3.Event |
|
||||
|
|
||||
switch event := event.(type) { |
|
||||
case events.MotionSensed: |
|
||||
s.motions[event.ID] = event.SecondsSince |
|
||||
patchEvents = s.updateDevice(event.ID) |
|
||||
case events.TemperatureChanged: |
|
||||
s.temperatures[event.ID] = event.Temperature |
|
||||
patchEvents = s.updateDevice(event.ID) |
|
||||
case events.AliasAdded: |
|
||||
patchEvents = s.updateDevice(event.ID) |
|
||||
case events.AliasRemoved: |
|
||||
patchEvents = s.updateDevice(event.ID) |
|
||||
} |
|
||||
|
|
||||
bus.RunEvents(patchEvents) |
|
||||
} |
|
||||
|
|
||||
func (s *service) updateDevice(id string) []lucifer3.Event { |
|
||||
ptr := s.resolver.GetByID(id) |
|
||||
if ptr == nil { |
|
||||
return nil |
|
||||
} |
|
||||
|
|
||||
res := make([]lucifer3.Event, 0, len(ptr.Aliases)+1) |
|
||||
|
|
||||
for _, alias := range append([]string{ptr.ID}, ptr.Aliases...) { |
|
||||
patch := PropertyPatch{Key: alias} |
|
||||
motionSamples := 0.0 |
|
||||
motionTotal := 0.0 |
|
||||
temperatureSamples := 0.0 |
|
||||
temperatureTotal := 0.0 |
|
||||
|
|
||||
for _, ptr := range s.resolver.Resolve(alias) { |
|
||||
if temp, ok := s.temperatures[ptr.ID]; ok { |
|
||||
if patch.Temperature == nil { |
|
||||
patch.Temperature = &AvgMinMax{} |
|
||||
if temp < patch.Temperature.Min || temperatureSamples == 0.0 { |
|
||||
patch.Temperature.Min = temp |
|
||||
} |
|
||||
if temp > patch.Temperature.Max { |
|
||||
patch.Temperature.Max = temp |
|
||||
} |
|
||||
|
|
||||
temperatureSamples += 1.0 |
|
||||
temperatureTotal += temp |
|
||||
} |
|
||||
} |
|
||||
if motion, ok := s.motions[ptr.ID]; ok { |
|
||||
if patch.Motion == nil { |
|
||||
patch.Motion = &AvgMinMax{} |
|
||||
if motion < patch.Motion.Min || motionSamples == 0.0 { |
|
||||
patch.Motion.Min = motion |
|
||||
} |
|
||||
if motion > patch.Motion.Max { |
|
||||
patch.Motion.Max = motion |
|
||||
} |
|
||||
|
|
||||
motionSamples += 1.0 |
|
||||
motionTotal += motion |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if temperatureSamples > 0.5 { |
|
||||
patch.Temperature.Avg = temperatureTotal / temperatureSamples |
|
||||
} |
|
||||
if motionSamples > 0.5 { |
|
||||
patch.Motion.Avg = motionTotal / motionSamples |
|
||||
} |
|
||||
|
|
||||
res = append(res, patch) |
|
||||
} |
|
||||
|
|
||||
return res |
|
||||
} |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue