github.com/martinohmann/rfoutlet@v1.2.1-0.20220707195255-8a66aa411105/internal/outlet/switch.go (about)

     1  package outlet
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/martinohmann/rfoutlet/pkg/gpio"
     7  	"github.com/sirupsen/logrus"
     8  )
     9  
    10  var log = logrus.WithField("component", "outlet")
    11  
    12  // Switcher defines the interface for an outlet switcher.
    13  type Switcher interface {
    14  	// Switch switches an outlet to the desired state.
    15  	Switch(outlet *Outlet, state State) error
    16  }
    17  
    18  // Switch switches outlets by sending out codes using an gpio transmitter.
    19  type Switch struct {
    20  	Transmitter gpio.CodeTransmitter
    21  }
    22  
    23  // NewSwitch creates a new *Switch.
    24  func NewSwitch(transmitter gpio.CodeTransmitter) *Switch {
    25  	return &Switch{
    26  		Transmitter: transmitter,
    27  	}
    28  }
    29  
    30  // Switch switches an outlet to the provided state.
    31  func (s *Switch) Switch(o *Outlet, state State) error {
    32  	if o.Protocol < 1 || o.Protocol > len(gpio.DefaultProtocols) {
    33  		return fmt.Errorf("protocol %d does not exist", o.Protocol)
    34  	}
    35  
    36  	proto := gpio.DefaultProtocols[o.Protocol-1]
    37  
    38  	code := o.getCodeForState(state)
    39  
    40  	log.WithFields(logrus.Fields{
    41  		"outletID":     o.ID,
    42  		"outletState":  o.GetState(),
    43  		"desiredState": state,
    44  		"protocol":     o.Protocol,
    45  		"pulseLength":  o.PulseLength,
    46  	}).Debugf("transmitting code %d", code)
    47  
    48  	s.Transmitter.Transmit(code, proto, o.PulseLength)
    49  	o.SetState(state)
    50  
    51  	return nil
    52  }
    53  
    54  // FakeSwitch can be used in tests,
    55  type FakeSwitch struct {
    56  	// Err is the error that should be returned by Switch. If non-nil, the
    57  	// state of any passed in *Outlet will not be altered.
    58  	Err error
    59  }
    60  
    61  // Switch implements Switcher.
    62  //
    63  // It will only set the outlet state or return the configured error.
    64  func (s *FakeSwitch) Switch(outlet *Outlet, state State) error {
    65  	if s.Err != nil {
    66  		return s.Err
    67  	}
    68  
    69  	outlet.SetState(state)
    70  
    71  	return nil
    72  }