github.com/martinohmann/rfoutlet@v1.2.1-0.20220707195255-8a66aa411105/internal/statedrift/detector.go (about) 1 // Package statedrift provides a detector for listening to rf codes sent out by 2 // anything else than rfoutlet (e.g. the physical remote control for the 3 // outlet). 4 package statedrift 5 6 import ( 7 "github.com/martinohmann/rfoutlet/internal/command" 8 "github.com/martinohmann/rfoutlet/internal/outlet" 9 "github.com/martinohmann/rfoutlet/pkg/gpio" 10 "github.com/sirupsen/logrus" 11 ) 12 13 var log = logrus.WithField("component", "statedrift") 14 15 // Detector sniffs for sent out rf codes using the receiver and pushes state 16 // correction commands into the command queue if necessary. This allows for the 17 // detection of codes sent out by pressing buttons on a physical outlet remote 18 // control. 19 type Detector struct { 20 Registry *outlet.Registry 21 Receiver gpio.CodeReceiver 22 CommandQueue chan<- command.Command 23 } 24 25 // NewDetector creates a new *Detector. 26 func NewDetector(registry *outlet.Registry, receiver gpio.CodeReceiver, queue chan<- command.Command) *Detector { 27 return &Detector{ 28 Registry: registry, 29 Receiver: receiver, 30 CommandQueue: queue, 31 } 32 } 33 34 // Run runs the state drift detection loop until stopCh is closed. 35 func (d *Detector) Run(stopCh <-chan struct{}) { 36 for { 37 select { 38 case <-stopCh: 39 log.Info("shutting down state drift detector") 40 return 41 case result, ok := <-d.Receiver.Receive(): 42 if !ok { 43 log.Error("receiver was closed unexpectedly, shutting down state drift detector") 44 return 45 } 46 47 var found bool 48 49 for _, o := range d.Registry.GetOutlets() { 50 if result.Code == o.CodeOn && o.GetState() != outlet.StateOn { 51 found = true 52 d.CommandQueue <- command.StateCorrectionCommand{ 53 Outlet: o, 54 DesiredState: outlet.StateOn, 55 } 56 } else if result.Code == o.CodeOff && o.GetState() != outlet.StateOff { 57 found = true 58 d.CommandQueue <- command.StateCorrectionCommand{ 59 Outlet: o, 60 DesiredState: outlet.StateOff, 61 } 62 } 63 64 if found { 65 break 66 } 67 } 68 } 69 } 70 }