From addef6213b189e17e309103192d85caaf7ff69ae Mon Sep 17 00:00:00 2001 From: Micha Date: Tue, 25 May 2021 22:26:03 +0200 Subject: [PATCH] SMA: make network interface for multicast configurable (#1075) Co-authored-by: andig --- detect/tasks/sma.go | 2 +- meter/sma.go | 10 ++++++---- meter/sma/listener.go | 18 ++++++++++++++---- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/detect/tasks/sma.go b/detect/tasks/sma.go index fb19bed12..e5eadd2f5 100644 --- a/detect/tasks/sma.go +++ b/detect/tasks/sma.go @@ -66,7 +66,7 @@ func (h *SMAHandler) Test(log *util.Logger, in ResultDetails) (res []ResultDetai } var err error - if h.listener, err = sma.New(log); err != nil { + if h.listener, err = sma.New(log, ""); err != nil { log.ERROR.Println("shm:", err) return nil } diff --git a/meter/sma.go b/meter/sma.go index aaa42d38c..d9399e187 100644 --- a/meter/sma.go +++ b/meter/sma.go @@ -27,6 +27,7 @@ type SMA struct { mux *util.Waiter uri string serial string + iface string values values powerO sma.Obis energyO sma.Obis @@ -42,18 +43,18 @@ func init() { // NewSMAFromConfig creates a SMA Meter from generic config func NewSMAFromConfig(other map[string]interface{}) (api.Meter, error) { cc := struct { - URI, Serial, Power, Energy string + URI, Serial, Interface, Power, Energy string }{} if err := util.DecodeOther(other, &cc); err != nil { return nil, err } - return NewSMA(cc.URI, cc.Serial, cc.Power, cc.Energy) + return NewSMA(cc.URI, cc.Serial, cc.Interface, cc.Power, cc.Energy) } // NewSMA creates a SMA Meter -func NewSMA(uri, serial, power, energy string) (api.Meter, error) { +func NewSMA(uri, serial, iface, power, energy string) (api.Meter, error) { log := util.NewLogger("sma") sm := &SMA{ @@ -61,13 +62,14 @@ func NewSMA(uri, serial, power, energy string) (api.Meter, error) { log: log, uri: uri, serial: serial, + iface: iface, powerO: sma.Obis(power), energyO: sma.Obis(energy), recv: make(chan sma.Telegram), } if sma.Instance == nil { - instance, err := sma.New(log) + instance, err := sma.New(log, iface) if err != nil { return nil, err } diff --git a/meter/sma/listener.go b/meter/sma/listener.go index 8a6bdf64b..13161b2be 100644 --- a/meter/sma/listener.go +++ b/meter/sma/listener.go @@ -104,15 +104,25 @@ type Listener struct { } // New creates a Listener -func New(log *util.Logger) (*Listener, error) { - // Parse the string address +func New(log *util.Logger, ifaceName string) (*Listener, error) { + var iface *net.Interface + if ifaceName != "" { + var err error + if iface, err = net.InterfaceByName(ifaceName); err != nil { + return nil, fmt.Errorf("error resolving network interface '%s': %w", ifaceName, err) + } + + log.DEBUG.Printf("listening on network interface %s for multicasts", iface.Name) + } + + // parse address gaddr, err := net.ResolveUDPAddr("udp4", multicastAddr) if err != nil { return nil, fmt.Errorf("error resolving udp address: %w", err) } - // Open up a connection - conn, err := net.ListenMulticastUDP("udp4", nil, gaddr) + // open connection + conn, err := net.ListenMulticastUDP("udp4", iface, gaddr) if err != nil { return nil, fmt.Errorf("error opening connecting: %w", err) }