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 }