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.
 
 
 
 
 
 

103 lines
2.4 KiB

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
}