-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
136 lines (106 loc) · 2.91 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"encoding/json"
"flag"
"fmt"
"log"
"os"
"os/signal"
"syscall"
mqtt "github.com/eclipse/paho.mqtt.golang"
rpio "github.com/stianeikeland/go-rpio"
)
var (
mqttBroker = flag.String("mqttBroker", "", "MQTT broker URI (mandatory). E.g.:192.168.1.1:1883")
topic = flag.String("topic", "", "Topic where hub-ctrl messages will be received (mandatory)")
user = flag.String("user", "", "MQTT username")
pwd = flag.String("password", "", "MQTT password")
)
//Message Used to hold MQTT JSON messages
type Message struct {
Type string
GPIO int
Mode string
Level string
}
type GPIO struct {
Pin rpio.Pin
Mode string
Level string
}
var gpioList map[int]GPIO
//Connect to the MQTT broker
func connectMQTT() (mqtt.Client, error) {
opts := mqtt.NewClientOptions().AddBroker("tcp://" + *mqttBroker)
if *user != "" && *pwd != "" {
opts.SetUsername(*user).SetPassword(*pwd)
}
client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
return nil, fmt.Errorf("%s", token.Error())
}
return client, nil
}
//Callback for MQTT messages received through the subscribed topic
func mqttCallback(client mqtt.Client, msg mqtt.Message) {
var jsonMessage Message
var gpioData GPIO
log.Printf("Message received: %s", msg.Payload())
err := json.Unmarshal(msg.Payload(), &jsonMessage)
if err != nil {
log.Printf("Error parsing JSON: %s", err)
}
typeMsg := jsonMessage.Type
switch typeMsg {
case "GPIOSetMode":
log.Printf("GPIO %d setting mode to %s ", jsonMessage.GPIO, jsonMessage.Mode)
gpio := jsonMessage.GPIO
gpioData.Mode = jsonMessage.Mode
gpioData.Pin = rpio.Pin(gpio)
if gpioData.Mode == "Output" {
gpioData.Pin.Output()
} else if gpioData.Mode == "Input" {
gpioData.Pin.Input()
}
gpioList[gpio] = gpioData
case "GPIOLevel":
log.Printf("GPIO %d setting level to %s", jsonMessage.GPIO, jsonMessage.Level)
gpio := jsonMessage.GPIO
gpioData = gpioList[gpio]
gpioData.Level = jsonMessage.Level
if gpioData.Level == "High" {
gpioData.Pin.High()
} else if gpioData.Level == "Low" {
gpioData.Pin.Low()
}
}
}
func init() {
flag.Parse()
gpioList = make(map[int]GPIO)
}
func main() {
//Check command line parameters
if *mqttBroker == "" || *topic == "" {
flag.PrintDefaults()
os.Exit(1)
}
//Channel used to block while receiving messages
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
clientMQTT, err := connectMQTT()
if err != nil {
log.Fatalf("Error connecting to MQTT broker: %s", err)
}
log.Printf("Connected to MQTT broker at %s", *mqttBroker)
if token := clientMQTT.Subscribe(*topic, 0, mqttCallback); token.Wait() && token.Error() != nil {
log.Fatalf("Error subscribing to topic %s : %s", *topic, err)
}
log.Printf("Subscribed to topic %s", *topic)
err = rpio.Open()
if err != nil {
log.Fatalf("Couldn't open GPIO: %s", err)
}
<-c
rpio.Close()
}