diff --git a/util/modbus/modbus.go b/util/modbus/modbus.go index 004346007..1c881f8fe 100644 --- a/util/modbus/modbus.go +++ b/util/modbus/modbus.go @@ -63,6 +63,7 @@ func (s *Settings) String() string { type meterConnection struct { meters.Connection + proto Protocol *logger } @@ -71,23 +72,28 @@ var ( mu sync.Mutex ) -func registeredConnection(key string, newConn meters.Connection) *meterConnection { +func registeredConnection(key string, proto Protocol, newConn meters.Connection) (*meterConnection, error) { mu.Lock() defer mu.Unlock() if conn, ok := connections[key]; ok { - return conn + if conn.proto != proto { + return nil, fmt.Errorf("connection already registered with different protocol: %s", key) + } + + return conn, nil } connection := &meterConnection{ Connection: newConn, + proto: proto, logger: new(logger), } newConn.Logger(connection.logger) connections[key] = connection - return connection + return connection, nil } // NewConnection creates physical modbus device from config @@ -111,8 +117,6 @@ func NewConnection(uri, device, comset string, baudrate int, proto Protocol, sla } func physicalConnection(proto Protocol, cfg Settings) (*meterConnection, error) { - var conn *meterConnection - if (cfg.Device != "") == (cfg.URI != "") { return nil, errors.New("invalid modbus configuration: must have either uri or device") } @@ -131,28 +135,24 @@ func physicalConnection(proto Protocol, cfg Settings) (*meterConnection, error) } if proto == Ascii { - conn = registeredConnection(cfg.Device, meters.NewASCII(cfg.Device, cfg.Baudrate, cfg.Comset)) + return registeredConnection(cfg.Device, Ascii, meters.NewASCII(cfg.Device, cfg.Baudrate, cfg.Comset)) } else { - conn = registeredConnection(cfg.Device, meters.NewRTU(cfg.Device, cfg.Baudrate, cfg.Comset)) + return registeredConnection(cfg.Device, Rtu, meters.NewRTU(cfg.Device, cfg.Baudrate, cfg.Comset)) } } - if cfg.URI != "" { - cfg.URI = util.DefaultPort(cfg.URI, 502) + uri := util.DefaultPort(cfg.URI, 502) - switch proto { - case Udp: - conn = registeredConnection(cfg.URI, meters.NewRTUOverUDP(cfg.URI)) - case Rtu: - conn = registeredConnection(cfg.URI, meters.NewRTUOverTCP(cfg.URI)) - case Ascii: - conn = registeredConnection(cfg.URI, meters.NewASCIIOverTCP(cfg.URI)) - default: - conn = registeredConnection(cfg.URI, meters.NewTCP(cfg.URI)) - } + switch proto { + case Udp: + return registeredConnection(uri, Udp, meters.NewRTUOverUDP(uri)) + case Rtu: + return registeredConnection(uri, Rtu, meters.NewRTUOverTCP(uri)) + case Ascii: + return registeredConnection(uri, Ascii, meters.NewASCIIOverTCP(uri)) + default: + return registeredConnection(uri, Tcp, meters.NewTCP(uri)) } - - return conn, nil } // NewDevice creates physical modbus device from config