-
Notifications
You must be signed in to change notification settings - Fork 1
/
mqtt.ino
144 lines (100 loc) · 3.48 KB
/
mqtt.ino
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
137
138
139
140
141
142
143
144
void MQTT_setup(){
Serial.println(F("[MQTT] MQTT setup"));
MQTT_client.setServer(MQTT_BROKER_ADDRESS, MQTT_PORT);
MQTT_client.setCallback(MQTT_message_callback);
}
boolean mqtt_connected(){
return MQTT_client.connected();
}
void MQTT_connection_manager(){
static boolean last_connection_state = false;
static long last_connection_attempt;
if(mqtt_connected() != last_connection_state) {
last_connection_state = mqtt_connected();
if(mqtt_connected()){
// Changed from disconnected to connected
Serial.println(F("[MQTT] Connected"));
Serial.println(F("[MQTT] Subscribing to topics"));
MQTT_client.subscribe(MQTT_LOCK_STATUS_TOPIC);
}
else {
// Changed from connected to disconnected
Serial.print(F("[MQTT] Disconnected: "));
Serial.println(MQTT_client.state());
if(wifi_connected()) display_image(mqtt_disconnected);
}
}
// Kind of similar to the pubsubclient example, one connection attempt every 5 seconds
if(!mqtt_connected()){
if(millis() - last_connection_attempt > MQTT_RECONNECT_PERIOD){
last_connection_attempt = millis();
// No need to do anything if not connected to WiFi
if(!wifi_connected()) return;
Serial.println("[MQTT] Connecting");
MQTT_client.connect(
get_device_name().c_str(),
MQTT_USERNAME,
MQTT_PASSWORD
);
}
}
}
void MQTT_message_callback(char* topic, byte* payload, unsigned int len) {
// listening to lock states
// Debugging
Serial.print(F("[MQTT] message received on "));
Serial.print(topic);
Serial.print(F(", payload: "));
for (int i = 0; i < len; i++) Serial.print((char)payload[i]);
Serial.println();
static boolean locked_previous = false;
// Create a JSON object to hold the message
// Note: size is limited by MQTT library
StaticJsonDocument<MQTT_MAX_PACKET_SIZE> inbound_JSON_message;
// Copy the message into the JSON object
deserializeJson(inbound_JSON_message, payload);
if(inbound_JSON_message.containsKey("state")){
Serial.println("[MQTTT] Payload is JSON with state");
// Check what the command is and act accordingly
// Use strdup so as to use strlwr later on
char* command = strdup(inbound_JSON_message["state"]);
if( strcmp(strlwr(command), "locked") == 0 ) {
locked = true;
}
else if( strcmp(strlwr(command), "unlocked") == 0 ) {
locked = false;
}
free(command);
}
if(locked != locked_previous){
locked_previous = locked;
display_lock_state();
buzzer_lock_state_changed();
}
}
void MQTT_publish_toggle(){
//Send the payload
StaticJsonDocument<MQTT_MAX_PACKET_SIZE> outbound_JSON_message;
if(locked) {
outbound_JSON_message["state"] = "unlocked";
}
else {
outbound_JSON_message["state"] = "locked";
}
char mqtt_payload[MQTT_MAX_PACKET_SIZE];
serializeJson(outbound_JSON_message, mqtt_payload, sizeof(mqtt_payload));
MQTT_client.publish(MQTT_LOCK_COMMAND_TOPIC, mqtt_payload, MQTT_RETAIN);
}
void MQTT_publish_event(){
// Publishing event for automation or logging
StaticJsonDocument<MQTT_MAX_PACKET_SIZE> outbound_JSON_message;
if(locked) {
outbound_JSON_message["action"] = "unlocking";
}
else {
outbound_JSON_message["action"] = "locking";
}
char mqtt_payload[MQTT_MAX_PACKET_SIZE];
serializeJson(outbound_JSON_message, mqtt_payload, sizeof(mqtt_payload));
MQTT_client.publish(MQTT_EVENTS_TOPIC, mqtt_payload, MQTT_RETAIN);
}