Added support for SMA device config by serial (#121)
* Added support for SMA device config by serial - The SMA Home Manager or Energy Meter device can now be either defined via its IP or its serial number - Only URI or serial number needs to be defined in the config file * Add fatal error when serial and uri are missing
This commit is contained in:
parent
08cee90ea8
commit
0c18e47d8f
3 changed files with 21 additions and 11 deletions
|
|
@ -69,7 +69,8 @@ meters:
|
|||
timeout: 3s # kill script after 3 seconds
|
||||
- name: sma
|
||||
type: sma # SMA Home Manager 2.0 or SMA Energy Meter 30
|
||||
uri: 192.168.1.4 # IP address of the device
|
||||
serial: 1234567890 # Serial number of the device, if this is defined uri is not needed!
|
||||
uri: 192.168.1.4 # IP address of the device, if this is defined serial is not needed!
|
||||
- name: sdm
|
||||
type: modbus
|
||||
model: sdm
|
||||
|
|
|
|||
19
meter/sma.go
19
meter/sma.go
|
|
@ -19,6 +19,7 @@ const (
|
|||
type SMA struct {
|
||||
log *util.Logger
|
||||
uri string
|
||||
serial string
|
||||
power float64
|
||||
energy float64
|
||||
powerO sma.Obis
|
||||
|
|
@ -32,30 +33,38 @@ type SMA struct {
|
|||
// NewSMAFromConfig creates a SMA Meter from generic config
|
||||
func NewSMAFromConfig(log *util.Logger, other map[string]interface{}) api.Meter {
|
||||
cc := struct {
|
||||
URI, Power, Energy string
|
||||
URI, Serial, Power, Energy string
|
||||
}{}
|
||||
util.DecodeOther(log, other, &cc)
|
||||
|
||||
return NewSMA(cc.URI, cc.Power, cc.Energy)
|
||||
return NewSMA(cc.URI, cc.Serial, cc.Power, cc.Energy)
|
||||
}
|
||||
|
||||
// NewSMA creates a SMA Meter
|
||||
func NewSMA(uri, power, energy string) api.Meter {
|
||||
func NewSMA(uri, serial, power, energy string) api.Meter {
|
||||
log := util.NewLogger("sma ")
|
||||
|
||||
sm := &SMA{
|
||||
log: log,
|
||||
uri: uri,
|
||||
serial: serial,
|
||||
powerO: sma.Obis(power),
|
||||
energyO: sma.Obis(energy),
|
||||
recv: make(chan sma.Telegram),
|
||||
}
|
||||
|
||||
if sma.Instance == nil {
|
||||
sma.Instance = sma.New(log, sm.uri)
|
||||
sma.Instance = sma.New(log)
|
||||
}
|
||||
|
||||
sma.Instance.Subscribe(uri, sm.recv)
|
||||
// we only need to subscribe to one of the two possible identifiers
|
||||
if uri != "" {
|
||||
sma.Instance.Subscribe(uri, sm.recv)
|
||||
} else if serial != "" {
|
||||
sma.Instance.Subscribe(serial, sm.recv)
|
||||
} else {
|
||||
log.FATAL.Fatalf("config: missing uri or serial")
|
||||
}
|
||||
|
||||
go sm.receive()
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ type Listener struct {
|
|||
}
|
||||
|
||||
// New creates a Listener
|
||||
func New(log *util.Logger, addr string) *Listener {
|
||||
func New(log *util.Logger) *Listener {
|
||||
// Parse the string address
|
||||
gaddr, err := net.ResolveUDPAddr("udp4", multicastAddr)
|
||||
if err != nil {
|
||||
|
|
@ -178,7 +178,7 @@ func (l *Listener) listen() {
|
|||
}
|
||||
|
||||
// Subscribe adds a client address and message channel
|
||||
func (l *Listener) Subscribe(addr string, c chan<- Telegram) {
|
||||
func (l *Listener) Subscribe(identifier string, c chan<- Telegram) {
|
||||
l.mux.Lock()
|
||||
defer l.mux.Unlock()
|
||||
|
||||
|
|
@ -186,15 +186,15 @@ func (l *Listener) Subscribe(addr string, c chan<- Telegram) {
|
|||
l.clients = make(map[string]chan<- Telegram)
|
||||
}
|
||||
|
||||
l.clients[addr] = c
|
||||
l.clients[identifier] = c
|
||||
}
|
||||
|
||||
func (l *Listener) send(msg Telegram) {
|
||||
l.mux.Lock()
|
||||
defer l.mux.Unlock()
|
||||
|
||||
for addr, client := range l.clients {
|
||||
if addr == msg.Addr {
|
||||
for identifier, client := range l.clients {
|
||||
if identifier == msg.Addr || identifier == msg.Serial {
|
||||
select {
|
||||
case client <- msg:
|
||||
default:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue