1
0
Fork 0
mirror of https://github.com/Luzifer/culmqtt.git synced 2024-12-22 10:41:19 +00:00

Initial version

This commit is contained in:
Knut Ahlers 2018-07-06 20:57:55 +02:00
commit 3df2537c8d
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
4 changed files with 155 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
culmqtt

46
fs20.go Normal file
View file

@ -0,0 +1,46 @@
package main
import (
"fmt"
"strings"
mqtt "github.com/eclipse/paho.mqtt.golang"
log "github.com/sirupsen/logrus"
)
func processFS20Message(housecode, device, command string) error {
log.WithFields(log.Fields{
"housecode": housecode,
"device": device,
"command": command,
}).Info("FS20 status received")
return publishFS20ToMQTT(housecode, device, command)
}
func publishFS20ToCUL(client mqtt.Client, msg mqtt.Message) {
addr := strings.Split(msg.Topic(), "/")[1]
cmd := string(msg.Payload())
logger := log.WithFields(log.Fields{
"address": addr,
"command": cmd,
})
if _, err := fmt.Fprintf(port, "F%s%s\n", addr, cmd); err != nil {
logger.WithError(err).Error("Unable to send message through CUL")
}
logger.Info("Message sent")
}
func publishFS20ToMQTT(housecode, device, command string) error {
tok := brokerClient.Publish(
strings.Join([]string{"culmqtt", fmt.Sprintf("%s%s", housecode, device), "state"}, "/"),
0x01, // QOS Level 1: At least once
true,
command,
)
tok.Wait()
return tok.Error()
}

91
main.go Normal file
View file

@ -0,0 +1,91 @@
package main
import (
"bufio"
"fmt"
"io"
"os"
"github.com/Luzifer/rconfig"
"github.com/jacobsa/go-serial/serial"
log "github.com/sirupsen/logrus"
)
var (
cfg = struct {
CULDevice string `flag:"cul-device" default:"/dev/ttyACM0" env:"CUL_DEVICE" description:"TTY of the CUL to connect to"`
LogLevel string `flag:"log-level" default:"info" description:"Log level (debug, info, warn, error, fatal)"`
MQTTHost string `flag:"mqtt-host" default:"tcp://127.0.0.1:1883" env:"MQTT_HOST" description:"Connection URI for the broker"`
MQTTUser string `flag:"mqtt-user" default:"" env:"MQTT_USER" description:"Username for broker connection"`
MQTTPass string `flag:"mqtt-pass" default:"" env:"MQTT_PASS" description:"Password for broker connection"`
VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"`
}{}
port io.ReadWriteCloser
version = "dev"
)
func init() {
if err := rconfig.ParseAndValidate(&cfg); err != nil {
log.Fatalf("Unable to parse commandline options: %s", err)
}
if cfg.VersionAndExit {
fmt.Printf("culmqtt %s\n", version)
os.Exit(0)
}
if l, err := log.ParseLevel(cfg.LogLevel); err != nil {
log.WithError(err).Fatal("Unable to parse log level")
} else {
log.SetLevel(l)
}
}
func main() {
options := serial.OpenOptions{
PortName: cfg.CULDevice,
BaudRate: 19200,
DataBits: 8,
StopBits: 1,
MinimumReadSize: 4,
}
// Open the port.
var err error
if port, err = serial.Open(options); err != nil {
log.Fatalf("serial.Open: %v", err)
}
// Make sure to close it later.
defer port.Close()
for {
scanner := bufio.NewScanner(port)
for scanner.Scan() {
if err := processMessage(scanner.Text()); err != nil {
log.WithError(err).Fatal("Unable to process message")
}
}
}
}
func processMessage(message string) error {
logger := log.WithField("message", message)
switch message[0] {
case 'F':
return processFS20Message(
message[1:5], // House code: 4 hex digits
message[5:7], // Device code: 2 hex digits
message[7:9], // Command: 2 hex digits
)
case 'V':
// Version information, discard
return nil
default:
logger.Error("Unknown message specifier")
return nil
}
}

17
mqtt.go Normal file
View file

@ -0,0 +1,17 @@
package main
import mqtt "github.com/eclipse/paho.mqtt.golang"
var brokerClient mqtt.Client
func init() {
opts := mqtt.NewClientOptions().AddBroker(cfg.MQTTHost)
if cfg.MQTTUser != "" || cfg.MQTTPass != "" {
opts.SetUsername(cfg.MQTTUser).SetPassword(cfg.MQTTPass)
}
brokerClient = mqtt.NewClient(opts)
brokerClient.Connect().Wait()
brokerClient.Subscribe("culmqtt/+/send", 0x01, publishFS20ToCUL)
}