Modular ESP Firmware - MQTT - Individual Functions
Revision as of 17:39, 26 December 2020 by Tinker (talk | contribs) (→void MQTT_callback(char *topic, byte *payload, int length);)
Main Functions
void setup_mqtt();
Called from inside setup() to configure your MQTT connection.
1 void setup_mqtt()
2 {
3 MQTT_client.setServer(MQTT_broker, 1883);
4 MQTT_client.setCallback(MQTT_callback);
5
6 // Build the topic names
7 strcpy(MQTT_inTopic, "cmnd/"); // in - Commands
8 strcat(MQTT_inTopic, MQTT_ClientName);
9 strcat(MQTT_inTopic, "/#");
10 strcpy(MQTT_teleTopic, "tele/"); // out - Telemetry
11 strcat(MQTT_teleTopic, MQTT_ClientName);
12 strcpy(MQTT_statTopic, "stat/"); // out - Status
13 strcat(MQTT_statTopic, MQTT_ClientName);
14 strcpy(MQTT_outTopic, "noti/"); // out - Notifications
15 strcat(MQTT_outTopic, MQTT_ClientName);
16 }
void MQTT_callback(char *topic, byte *payload, int length);
Actually... Called by the libraries built-in client.loop(); function.
1 void MQTT_callback(char *topic, byte *payload, int length)
2 {
3
4 char MQTT_msg_in[MQTT_BUFFER_SIZE];
5 char *MQTT_command = strrchr(topic, '/');
6
7 #ifdef DEBUG
8 Serial.printf("| |\n");
9 Serial.printf("| Message arrived |\n");
10 Serial.printf("| Command: %28s |\n", MQTT_command);
11 #endif
12
13 if (length < MQTT_BUFFER_SIZE)
14 {
15 for (int i = 0; i < length; i++)
16 {
17 MQTT_msg_in[i] = (char)payload[i];
18 MQTT_msg_in[i + 1] = '\0';
19 }
20
21 #ifdef DEBUG
22 Serial.printf("| Message: %28s |\n", MQTT_msg_in);
23 #endif
24 /////////////////////////////////////////////////////
25 // Message handling goes here...
26 /////////////////////////////////////////////////////
27 if (strcmp(MQTT_command, "/lights") == 0)
28 {
29 DoLights(MQTT_msg_in);
30 }
31 else if (strcmp(MQTT_command, "/respond") == 0)
32 {
33 DoAnswer(MQTT_msg_in);
34 }
35 else if (strcmp(MQTT_command, "/control") == 0)
36 {
37 DoControl(MQTT_msg_in);
38 }
39 else
40 {
41 #ifdef DEBUG
42 Serial.printf("| Dunno Whatcha want... |\n");
43 #endif
44 }
45 }
46 else
47 {
48 #ifdef DEBUG
49 Serial.printf("| But, it's TOO Bloody Big! |\n");
50 #endif
51 }
52 }
void MQTT_reconnect();
Called from inside loop() to ensure persistant communications.
if (!MQTT_client.connected()) { MQTT_reconnect(); }
Can also be called once inside setup() just to show connection details at bootup.
1 void MQTT_reconnect()
2 {
3 // Loop until we're reconnected
4 while (!MQTT_client.connected())
5 {
6 Serial.printf("| |\n");
7 Serial.printf("| Attempting MQTT connection... |\n");
8 // Create a random client ID
9 String clientId = MQTT_ClientName;
10 clientId += String(random(0xffff), HEX);
11 // Attempt to connect
12 if (MQTT_client.connect(clientId.c_str()))
13 {
14 Serial.printf("| connected to %-24s |\n", MQTT_broker);
15 Serial.printf("| My Name: %-27s |\n", MQTT_ClientName);
16 // Once connected, publish an announcement...
17 MQTT_client.publish(MQTT_statTopic, "hello world");
18 // ... and resubscribe
19 MQTT_client.subscribe(MQTT_inTopic);
20 }
21 else
22 {
23 Serial.printf("| |\n");
24 Serial.printf("| failed, rc=%d |\n", MQTT_client.state());
25 Serial.printf("| trying again in 5 seconds |\n");
26 // Wait 5 seconds before retrying
27 delay(5000);
28 }
29 }
30 }
void MQTT_beacon();
Called inside loop() to provide reassurance that things are alive.
1 void MQTT_beacon()
2 {
3 /* Beacon signal published at set interval to indicate the device
4 * is still powered up and actively connected to MQTT...
5 * A keepalive of sorts
6 * also updates state within MQTT so it can be captured for
7 * indicator light elsewhere
8 */
9 if (getTimer(beacon_timer, BEACON_INTERVAL))
10 {
11 MQTT_client.publish(MQTT_teleTopic, "boop");
12 blinkLED();
13 }
14 }
Supplimentary Functions
bool getTimer(unsigned long &timer, unsigned long interval);
1 bool getTimer(unsigned long &timer, unsigned long interval)
2 /* Global timer function, used a lot
3 *
4 * @param unsigned long time - The current timer
5 * @param unsigned long interval - Length of time to run timer
6 *
7 * @return bool True when timer is complete
8 * @return bool False when timer is counting
9 */
10 {
11
12 if (timer < 1)
13 {
14 timer = millis();
15 }
16
17 if (millis() - timer >= interval)
18 {
19 timer = 0;
20 return true;
21 }
22
23 return false;
24 }
void blinkLED(); // Just a little function to blink the LED for the beacon function.
1 void blinkLED() // Just a little function to blink the on-board LED for the beacon function.
2 {
3 digitalWrite(LED_BUILTIN, LOW);
4 delay(10);
5 digitalWrite(LED_BUILTIN, HIGH);
6 delay(10);
7 digitalWrite(LED_BUILTIN, LOW);
8 delay(10);
9 digitalWrite(LED_BUILTIN, HIGH);
10 }
Some CMND Handlers
void DoLights(char *WhatToDo); // Turn LED on/off
1 void DoLights(char *WhatToDo) // Turn LED on/off
2 {
3 Serial.printf("[- Lights - %3s -]\n", WhatToDo);
4 if (strcmp(WhatToDo, "ON") == 0)
5 digitalWrite(LED_BUILTIN, LOW);
6 if (strcmp(WhatToDo, "OFF") == 0)
7 digitalWrite(LED_BUILTIN, HIGH);
8 }
void DoAnswer(char *WhatToDo); // Send back text
1 void DoAnswer(char *WhatToDo) // Send back text
2 {
3 Serial.printf("[- Responding: %-23s -]\n", WhatToDo);
4 MQTT_client.publish(MQTT_outTopic, WhatToDo);
5 }
void DoControl(char *WhatToDo); // Send MQTT to another device/topic
1 void DoControl(char *WhatToDo) // Send MQTT to another device/topic
2 {
3 /*
4 Should be something along the lines of,
5
6 MQTT_client.publish(TopicFromMessage, MessageFromMessage);
7
8 Where
9 TopicFromMessage
10 is an MQTT topic for sending to another device
11 and
12 MessageFromMessage
13 is the message to publish to that topic...
14 */
15 }