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

  1. package variables
  2. import (
  3. lucifer3 "git.aiterp.net/lucifer3/server"
  4. "git.aiterp.net/lucifer3/server/events"
  5. "git.aiterp.net/lucifer3/server/services"
  6. )
  7. func NewService(resolver *services.Resolver) lucifer3.Service {
  8. return &service{
  9. resolver: resolver,
  10. temperatures: map[string]float64{},
  11. motions: map[string]float64{},
  12. }
  13. }
  14. type service struct {
  15. resolver *services.Resolver
  16. temperatures map[string]float64
  17. motions map[string]float64
  18. }
  19. func (s *service) Active() bool {
  20. return true
  21. }
  22. func (s *service) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) {
  23. var patchEvents []lucifer3.Event
  24. switch event := event.(type) {
  25. case events.MotionSensed:
  26. s.motions[event.ID] = event.SecondsSince
  27. patchEvents = s.updateDevice(event.ID)
  28. case events.TemperatureChanged:
  29. s.temperatures[event.ID] = event.Temperature
  30. patchEvents = s.updateDevice(event.ID)
  31. case events.AliasAdded:
  32. patchEvents = s.updateDevice(event.ID)
  33. case events.AliasRemoved:
  34. patchEvents = s.updateDevice(event.ID)
  35. }
  36. bus.RunEvents(patchEvents)
  37. }
  38. func (s *service) updateDevice(id string) []lucifer3.Event {
  39. ptr := s.resolver.GetByID(id)
  40. if ptr == nil {
  41. return nil
  42. }
  43. res := make([]lucifer3.Event, 0, len(ptr.Aliases)+1)
  44. for _, alias := range append([]string{ptr.ID}, ptr.Aliases...) {
  45. patch := PropertyPatch{Key: alias}
  46. motionSamples := 0.0
  47. motionTotal := 0.0
  48. temperatureSamples := 0.0
  49. temperatureTotal := 0.0
  50. for _, ptr := range s.resolver.Resolve(alias) {
  51. if temp, ok := s.temperatures[ptr.ID]; ok {
  52. if patch.Temperature == nil {
  53. patch.Temperature = &AvgMinMax{}
  54. if temp < patch.Temperature.Min || temperatureSamples == 0.0 {
  55. patch.Temperature.Min = temp
  56. }
  57. if temp > patch.Temperature.Max {
  58. patch.Temperature.Max = temp
  59. }
  60. temperatureSamples += 1.0
  61. temperatureTotal += temp
  62. }
  63. }
  64. if motion, ok := s.motions[ptr.ID]; ok {
  65. if patch.Motion == nil {
  66. patch.Motion = &AvgMinMax{}
  67. if motion < patch.Motion.Min || motionSamples == 0.0 {
  68. patch.Motion.Min = motion
  69. }
  70. if motion > patch.Motion.Max {
  71. patch.Motion.Max = motion
  72. }
  73. motionSamples += 1.0
  74. motionTotal += motion
  75. }
  76. }
  77. }
  78. if temperatureSamples > 0.5 {
  79. patch.Temperature.Avg = temperatureTotal / temperatureSamples
  80. }
  81. if motionSamples > 0.5 {
  82. patch.Motion.Avg = motionTotal / motionSamples
  83. }
  84. res = append(res, patch)
  85. }
  86. return res
  87. }