Refactored code and added support for kasa smart plugs
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
109
mqtt/mqtt.go
Normal file
109
mqtt/mqtt.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package mqtt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/eclipse/paho.mqtt.golang"
|
||||
)
|
||||
|
||||
type MQTT struct {
|
||||
Presence chan bool
|
||||
client mqtt.Client
|
||||
}
|
||||
|
||||
// This is the default message handler, it just prints out the topic and message
|
||||
var defaultHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
|
||||
fmt.Printf("TOPIC: %s\n", msg.Topic())
|
||||
fmt.Printf("MSG: %s\n", msg.Payload())
|
||||
}
|
||||
|
||||
// Handler got automation/presence/+
|
||||
func presenceHandler(presence chan bool) func(mqtt.Client, mqtt.Message) {
|
||||
devices := make(map[string]bool)
|
||||
var current *bool
|
||||
|
||||
return func(client mqtt.Client, msg mqtt.Message) {
|
||||
name := strings.Split(msg.Topic(), "/")[2]
|
||||
if len(msg.Payload()) == 0 {
|
||||
// @TODO What happens if we delete a device that does not exist
|
||||
delete(devices, name)
|
||||
} else {
|
||||
value, err := strconv.Atoi(string(msg.Payload()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
devices[name] = value == 1
|
||||
}
|
||||
|
||||
present := false
|
||||
fmt.Println(devices)
|
||||
for _, value := range devices {
|
||||
if value {
|
||||
present = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if current == nil || *current != present {
|
||||
current = &present
|
||||
presence <- present
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func Connect() MQTT {
|
||||
host, ok := os.LookupEnv("MQTT_HOST")
|
||||
if !ok {
|
||||
host = "localhost"
|
||||
}
|
||||
port, ok := os.LookupEnv("MQTT_PORT")
|
||||
if !ok {
|
||||
port = "1883"
|
||||
}
|
||||
user, ok := os.LookupEnv("MQTT_USER")
|
||||
if !ok {
|
||||
user = "test"
|
||||
}
|
||||
pass, ok := os.LookupEnv("MQTT_PASS")
|
||||
if !ok {
|
||||
pass = "test"
|
||||
}
|
||||
clientID, ok := os.LookupEnv("MQTT_CLIENT_ID")
|
||||
if !ok {
|
||||
clientID = "automation"
|
||||
}
|
||||
|
||||
opts := mqtt.NewClientOptions().AddBroker(fmt.Sprintf("%s:%s", host, port))
|
||||
opts.SetClientID(clientID)
|
||||
opts.SetDefaultPublishHandler(defaultHandler)
|
||||
opts.SetUsername(user)
|
||||
opts.SetPassword(pass)
|
||||
|
||||
client := mqtt.NewClient(opts)
|
||||
if token := client.Connect(); token.Wait() && token.Error() != nil {
|
||||
panic(token.Error())
|
||||
}
|
||||
|
||||
m := MQTT{client: client, Presence: make(chan bool)}
|
||||
|
||||
if token := client.Subscribe("automation/presence/+", 0, presenceHandler(m.Presence)); token.Wait() && token.Error() != nil {
|
||||
fmt.Println(token.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *MQTT) Disconnect() {
|
||||
if token := m.client.Unsubscribe("automation/presence/+"); token.Wait() && token.Error() != nil {
|
||||
fmt.Println(token.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
m.client.Disconnect(250)
|
||||
}
|
||||
Reference in New Issue
Block a user