Basic MQTT framework

This commit is contained in:
Scott Bezek 2023-02-04 14:20:54 -08:00
parent acfc85f72b
commit 157ac009b1
6 changed files with 124 additions and 1 deletions

1
firmware/src/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
secrets.h

View File

@ -3,6 +3,7 @@
#include "display_task.h"
#include "interface_task.h"
#include "motor_task.h"
#include "mqtt_task.h"
#if SK_DISPLAY
static DisplayTask display_task(0);
@ -15,6 +16,10 @@ static MotorTask motor_task(1);
InterfaceTask interface_task(0, motor_task, display_task_p);
#if SK_MQTT
static MQTTTask mqtt_task(0, motor_task, interface_task);
#endif
void setup() {
#if SK_DISPLAY
display_task.setLogger(&interface_task);
@ -27,6 +32,7 @@ void setup() {
motor_task.setLogger(&interface_task);
motor_task.begin();
interface_task.begin();
mqtt_task.begin();
// Free up the Arduino loop task
vTaskDelete(NULL);

View File

@ -0,0 +1,65 @@
#if SK_MQTT
#include "mqtt_task.h"
#include "motor_task.h"
#include "secrets.h"
MQTTTask::MQTTTask(const uint8_t task_core, MotorTask& motor_task, Logger& logger) :
Task("MQTT", 4096, 1, task_core),
motor_task_(motor_task),
logger_(logger),
wifi_client_(),
mqtt_client_(wifi_client_) {
auto callback = [this](char *topic, byte *payload, unsigned int length) { mqttCallback(topic, payload, length); };
mqtt_client_.setCallback(callback);
}
void MQTTTask::connectWifi() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
logger_.log("Establishing connection to WiFi..");
}
char buf[256];
snprintf(buf, sizeof(buf), "Connected to network %s", WIFI_SSID);
logger_.log(buf);
}
void MQTTTask::mqttCallback(char *topic, byte *payload, unsigned int length) {
char buf[256];
snprintf(buf, sizeof(buf), "Received mqtt callback for topic %s, length %u", topic, length);
logger_.log(buf);
}
void MQTTTask::connectMQTT() {
char buf[256];
mqtt_client_.setServer(MQTT_SERVER, 1883);
logger_.log("Attempting MQTT connection...");
if (mqtt_client_.connect(HOSTNAME "-" MQTT_USER, MQTT_USER, MQTT_PASSWORD)) {
logger_.log("MQTT connected");
mqtt_client_.subscribe(MQTT_COMMAND_TOPIC);
} else {
snprintf(buf, sizeof(buf), "MQTT failed rc=%d will try again in 5 seconds", mqtt_client_.state());
logger_.log(buf);
}
}
void MQTTTask::run() {
connectWifi();
connectMQTT();
while(1) {
long now = millis();
if (!mqtt_client_.connected() && (now - mqtt_last_connect_time_) > 5000) {
logger_.log("Reconnecting MQTT");
mqtt_last_connect_time_ = now;
connectMQTT();
}
mqtt_client_.loop();
delay(1);
}
}
#endif

35
firmware/src/mqtt_task.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#if SK_MQTT
#include <Arduino.h>
#include <PubSubClient.h>
#include <WiFi.h>
#include "logger.h"
#include "motor_task.h"
#include "task.h"
class MQTTTask : public Task<MQTTTask> {
friend class Task<MQTTTask>; // Allow base Task to invoke protected run()
public:
MQTTTask(const uint8_t task_core, MotorTask& motor_task, Logger& logger);
protected:
void run();
private:
MotorTask& motor_task_;
Logger& logger_;
WiFiClient wifi_client_;
PubSubClient mqtt_client_;
int mqtt_last_connect_time_ = 0;
void connectWifi();
void connectMQTT();
void mqttCallback(char *topic, byte *payload, unsigned int length);
};
#endif

View File

@ -0,0 +1,12 @@
// Rename this file to secrets.h and add your secret details.
// Network setup
#define WIFI_SSID "myssid"
#define WIFI_PASSWORD "supersecretpassword"
#define HOSTNAME "smartknob" // e.g. smartknob.local
#define MQTT_SERVER "10.0.0.2"
#define MQTT_USER "mqttuser"
#define MQTT_PASSWORD "megasecretpassword"
#define MQTT_COMMAND_TOPIC "smartknob"

View File

@ -42,11 +42,12 @@ lib_deps =
bogde/HX711 @ 0.7.5
adafruit/Adafruit VEML7700 Library @ 1.1.1
bakercp/PacketSerial @ 1.4.0
nanopb/Nanopb @ 0.4.6 ; Ideally this would reference the nanopb submodule, but that would require
nanopb/Nanopb @ 0.4.7 ; Ideally this would reference the nanopb submodule, but that would require
; everyone to check out submodules to just compile, so we use the library
; registry for the runtime. The submodule is available for manually updating
; the pre-compiled (checked in) .pb.h/c files when proto files change, but is
; otherwise not used during application firmware compilation.
knolleary/PubSubClient @ 2.8
build_flags =
${base_config.build_flags}
@ -66,6 +67,9 @@ build_flags =
; Ambient light sensor (VEML7700) enabled: 1=enable (display/LEDs match ambient brightness), 0=disable (100% brightness all the time)
-DSK_ALS=1
; Enable MQTT (wifi must be configured in secrets.h first)
-DSK_MQTT=1
; Pin configurations
-DPIN_UH=26
-DPIN_UL=25