Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions cmd/confighandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strconv"
"strings"
"time"

"github.com/volkszaehler/mbmd/server"
"github.com/volkszaehler/mbmd/meters"
"github.com/volkszaehler/mbmd/meters/rs485"
"github.com/volkszaehler/mbmd/meters/sunspec"
Expand Down Expand Up @@ -65,15 +65,17 @@ type DeviceConfig struct {

// DeviceConfigHandler creates map of meter managers from given configuration
type DeviceConfigHandler struct {
DefaultDevice string
Managers map[string]*meters.Manager
DefaultDevice string
Managers map[string]*meters.Manager
Names server.NameMap
}

// NewDeviceConfigHandler creates a configuration handler
func NewDeviceConfigHandler() *DeviceConfigHandler {
conf := &DeviceConfigHandler{
Managers: make(map[string]*meters.Manager),
}
Managers: make(map[string]*meters.Manager),
Names: make(server.NameMap),
}
return conf
}

Expand Down Expand Up @@ -155,7 +157,6 @@ func (conf *DeviceConfigHandler) createDeviceForManager(
// CreateDevice creates new device and adds it to the connection manager
func (conf *DeviceConfigHandler) CreateDevice(devConf DeviceConfig) {
if devConf.Adapter == "" {
// find default adapter
if len(conf.Managers) == 1 {
for a := range conf.Managers {
log.Printf("config: using default adapter %s for device %v", a, devConf)
Expand All @@ -170,8 +171,20 @@ func (conf *DeviceConfigHandler) CreateDevice(devConf DeviceConfig) {
if !ok {
log.Fatalf("Missing adapter configuration for device %v", devConf)
}

meter := conf.createDeviceForManager(manager, devConf.Type, devConf.SubDevice)


if devConf.Name != "" {
if conf.Names[devConf.Adapter] == nil {
conf.Names[devConf.Adapter] = make(map[uint8]map[int]string)
}
if conf.Names[devConf.Adapter][devConf.ID] == nil {
conf.Names[devConf.Adapter][devConf.ID] = make(map[int]string)
}
conf.Names[devConf.Adapter][devConf.ID][devConf.SubDevice] = devConf.Name
}

if err := manager.Add(devConf.ID, meter); err != nil {
log.Fatalf("Error adding device %v: %v.", devConf, err)
}
Expand All @@ -190,7 +203,6 @@ func (conf *DeviceConfigHandler) CreateDeviceFromSpec(deviceDef string, timeout
if len(deviceSplit) == 2 {
connSpec = deviceSplit[1]
}

if connSpec == "" {
log.Fatalf("Cannot parse connect string- missing physical device or connection for %s. See -h for help.", deviceDef)
}
Expand Down Expand Up @@ -222,12 +234,10 @@ func (conf *DeviceConfigHandler) CreateDeviceFromSpec(deviceDef string, timeout
log.Fatalf("Error parsing device id %s: %v. See -h for help.", devID, err)
}

// If this is an RTU over TCP device, a default RTU over TCP should already
// have been created of the --rtu flag was specified. We'll not re-check this here.
manager := conf.ConnectionManager(connSpec, false, 0, "", timeout)

meter := conf.createDeviceForManager(manager, meterType, subdevice)

if err := manager.Add(uint8(id), meter); err != nil {
log.Fatalf("Error adding device %s: %v. See -h for help.", meterDef, err)
}
}
}
2 changes: 1 addition & 1 deletion cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func run(cmd *cobra.Command, args []string) {
}

// query engine
qe := server.NewQueryEngine(confHandler.Managers)
qe := server.NewQueryEngine(confHandler.Managers, confHandler.Names)

// results- and control channels
rc := make(chan server.QuerySnip)
Expand Down
55 changes: 37 additions & 18 deletions server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
"log"
"math"
"time"

"regexp"
"strings"
"github.com/volkszaehler/mbmd/meters"
)

Expand All @@ -17,33 +18,51 @@ const (
initDelay = 3 * time.Second
)

type NameMap map[string]map[uint8]map[int]string

func sanitizeName(s string) string {
s = strings.TrimSpace(s)
s = strings.ReplaceAll(s, " ", "_")
re := regexp.MustCompile(`[^A-Za-z0-9_-]+`)
return re.ReplaceAllString(s, "_")
}

// Handler is responsible for querying a single connection
type Handler struct {
ID int
Manager *meters.Manager
status map[string]*RuntimeInfo
Conn string
ID int
Manager *meters.Manager
status map[string]*RuntimeInfo
names NameMap
}

// NewHandler creates a connection handler. The handler is responsible
// for querying all devices attached to the connection.
func NewHandler(id int, m *meters.Manager) *Handler {
handler := &Handler{
ID: id,
Manager: m,
status: make(map[string]*RuntimeInfo),
}

return handler
func NewHandler(conn string, id int, m *meters.Manager, names NameMap) *Handler {
return &Handler{
Conn: conn,
ID: id,
Manager: m,
status: make(map[string]*RuntimeInfo),
names: names,
}
}

// deviceID creates a unique id per device
func (h *Handler) deviceID(id uint8, dev meters.Device) string {
desc := dev.Descriptor()
devID := fmt.Sprintf("%s%d.%d", desc.Type, h.ID, id)
if desc.SubDevice > 0 {
devID = fmt.Sprintf("%s.%d", devID, desc.SubDevice)
}
return devID
desc := dev.Descriptor()
devID := fmt.Sprintf("%s%d.%d", desc.Type, h.ID, id)
if desc.SubDevice > 0 {
devID = fmt.Sprintf("%s.%d", devID, desc.SubDevice)
}
if sub1, ok := h.names[h.Conn]; ok {
if sub2, ok2 := sub1[id]; ok2 {
if name, ok3 := sub2[desc.SubDevice]; ok3 && name != "" {
return sanitizeName(name)
}
}
}
return devID
}

// Run initializes and queries every device attached to the handler's connection
Expand Down
4 changes: 2 additions & 2 deletions server/queryengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type QueryEngine struct {
}

// NewQueryEngine creates new query engine
func NewQueryEngine(managers map[string]*meters.Manager) *QueryEngine {
func NewQueryEngine(managers map[string]*meters.Manager, names NameMap) *QueryEngine {
handlers := make(map[string]*Handler)

// sort handlers by name
Expand All @@ -36,7 +36,7 @@ func NewQueryEngine(managers map[string]*meters.Manager) *QueryEngine {
continue
}

handlers[conn] = NewHandler(len(handlers)+1, m)
handlers[conn] = NewHandler(conn, len(handlers)+1, m, names)
}

qe := &QueryEngine{
Expand Down
Loading