mirror of
https://github.com/jpeletier/koolnova2mqtt.git
synced 2026-01-12 03:24:23 +00:00
115 lines
3.5 KiB
Go
115 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"koolnova2mqtt/kn"
|
|
"koolnova2mqtt/modbus"
|
|
"koolnova2mqtt/mqtt"
|
|
"log"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
MqttClient *mqtt.Client
|
|
slaves map[byte]string
|
|
BridgeTemplateConfig *kn.Config
|
|
}
|
|
|
|
func generateNodeName(slaveID string, port string) string {
|
|
reg, err := regexp.Compile("[^a-zA-Z0-9]+")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
hostname, _ := os.Hostname()
|
|
|
|
port = strings.Replace(port, "/dev/", "", -1)
|
|
port = reg.ReplaceAllString(port, "")
|
|
return strings.ToLower(fmt.Sprintf("%s_%s_%s", hostname, port, slaveID))
|
|
|
|
}
|
|
|
|
func parseModbusSlaveInfo(slaveIDs, slaveNames string, modbusPort string) map[byte]string {
|
|
slaveIDStrList := strings.Split(slaveIDs, ",")
|
|
var slaveNameList []string
|
|
|
|
if slaveNames == "" {
|
|
for _, slaveIDStr := range slaveIDStrList {
|
|
slaveNameList = append(slaveNameList, generateNodeName(slaveIDStr, modbusPort))
|
|
}
|
|
} else {
|
|
slaveNameList = strings.Split(slaveNames, ",")
|
|
if len(slaveIDStrList) != len(slaveNameList) {
|
|
log.Fatalf("modbusSlaveIDs and modbusSlaveNames lists must have the same length")
|
|
}
|
|
}
|
|
|
|
slaves := make(map[byte]string)
|
|
for i, slaveIDStr := range slaveIDStrList {
|
|
slaveID, err := strconv.Atoi(slaveIDStr)
|
|
if err != nil {
|
|
log.Fatalf("Error parsing slaveID list")
|
|
}
|
|
slaves[byte(slaveID)] = slaveNameList[i]
|
|
}
|
|
return slaves
|
|
}
|
|
|
|
func ParseCommandLine() *Config {
|
|
hostname, _ := os.Hostname()
|
|
|
|
server := flag.String("server", "tcp://127.0.0.1:1883", "The full url of the MQTT server to connect to ex: tcp://127.0.0.1:1883")
|
|
clientid := flag.String("clientid", hostname+strconv.Itoa(time.Now().Second()), "A clientid for the connection")
|
|
username := flag.String("username", "", "A username to authenticate to the MQTT server")
|
|
password := flag.String("password", "", "Password to match username")
|
|
prefix := flag.String("prefix", "koolnova2mqtt", "MQTT topic root where to publish/read topics")
|
|
hassPrefix := flag.String("hassPrefix", "homeassistant", "Home assistant discovery prefix")
|
|
modbusPort := flag.String("modbusPort", "/dev/ttyUSB0", "Serial port where modbus hardware is connected")
|
|
modbusPortBaudRate := flag.Int("modbusRate", 9600, "Modbus port data rate")
|
|
modbusDataBits := flag.Int("modbusDataBits", 8, "Modbus port data bits")
|
|
modbusPortParity := flag.String("modbusParity", "E", "N - None, E - Even, O - Odd (default E) (The use of no parity requires 2 stop bits.)")
|
|
modbusStopBits := flag.Int("modbusStopBits", 1, "Modbus port stop bits")
|
|
modbusSlaveList := flag.String("modbusSlaveIDs", "49", "Comma-separated list of modbus slave IDs to manage")
|
|
modbusSlaveNames := flag.String("modbusSlaveNames", "", "Comma-separated list of modbus slave names. Defaults to 'slave#'")
|
|
|
|
flag.Parse()
|
|
|
|
slaves := parseModbusSlaveInfo(*modbusSlaveList, *modbusSlaveNames, *modbusPort)
|
|
|
|
mb, err := modbus.New(&modbus.Config{
|
|
Port: *modbusPort,
|
|
BaudRate: *modbusPortBaudRate,
|
|
DataBits: *modbusDataBits,
|
|
Parity: *modbusPortParity,
|
|
StopBits: *modbusStopBits,
|
|
Timeout: 200 * time.Millisecond,
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("Error initializing modbus: %s", err)
|
|
}
|
|
defer mb.Close()
|
|
|
|
mqttClient := mqtt.New(&mqtt.Config{
|
|
Server: *server,
|
|
ClientID: *clientid,
|
|
Username: *username,
|
|
Password: *password,
|
|
})
|
|
|
|
return &Config{
|
|
slaves: slaves,
|
|
MqttClient: mqttClient,
|
|
BridgeTemplateConfig: &kn.Config{
|
|
Mqtt: mqttClient,
|
|
Modbus: mb,
|
|
TopicPrefix: *prefix,
|
|
HassPrefix: *hassPrefix,
|
|
},
|
|
}
|
|
|
|
}
|