mirror of
https://github.com/Luzifer/culmqtt.git
synced 2024-12-22 18:51:22 +00:00
Initial version
This commit is contained in:
commit
3df2537c8d
4 changed files with 155 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
culmqtt
|
46
fs20.go
Normal file
46
fs20.go
Normal 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
91
main.go
Normal 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
17
mqtt.go
Normal 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)
|
||||
}
|
Loading…
Reference in a new issue