#include <ArduinoMqttClient.h>
#include <WiFi.h>
int max_handeled_commands_per_loop;
struct DeviceCommand
{
int deviceType;
int deviceId;
bool turnOn;
};
typedef void (*CommandHandler)(DeviceCommand*);
#define ARDUINO_LED_PIN 2
#define ARDUINO_ON_LED_POWER 200
#define ARDUINO_OFF_LED_POWER 0
#define MAX_WIFI_RETRIES 5
#define MAX_COMMANDS_SIZE 10
#define MAX_HANDLED_COMMANDS_PER_LOOP 10;
#define MQTT_BROKER "0cd5c4fc8a9d45468efdcc59f176a76d.s2.eu.hivemq.cloud"
#define MQTT_PORT 8883
#define MQTT_USER "idiryacine"
#define MQTT_PASS "Idiryacine34"
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASS ""
#define MQTT_COMMANDS_TOPIC "home/commands"
#define MQTT_REPLIES_TOPIC "home/replies"
static DeviceCommand* commandsQueue[MAX_COMMANDS_SIZE];
static CommandHandler commandHandler;
void registerCommand(DeviceCommand* command) {
for ( int i = 0 ; i < MAX_COMMANDS_SIZE ; i++) {
if (commandsQueue[i] == nullptr) {
commandsQueue[i] = command;
break;
}
}
}
void registerCommandHandler(CommandHandler handler) {
commandHandler = handler;
}
void handleCommands(int* maxHandledCommands) {
int handeledCount = 0 ;
int currIndex = 0 ;
DeviceCommand* command;
while ((currIndex < MAX_COMMANDS_SIZE) && (handeledCount < *maxHandledCommands)) {
command = commandsQueue[currIndex];
if (command != nullptr) {
commandHandler(command);
handeledCount++;
}
currIndex++;
}
}
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
boolean connectToMqttBroker()
{
int wifiRetires = MAX_WIFI_RETRIES;
connectToWifi(&wifiRetires);
boolean connectedToBroker = mqttClient.connect(MQTT_BROKER, MQTT_PORT);
if (!connectedToBroker)
{
Serial.print("Couldn't connect to MQTT broker, retrying in 5 seconds");
delay(5000);
return false;
}
mqttClient.onMessage(onMessageReceived);
mqttClient.subscribe(MQTT_COMMANDS_TOPIC);
return true;
}
static void connectToWifi(int *maxRetries)
{
if (WiFi.status() == WL_CONNECTED)
{
return;
}
int retriesCount = 0;
Serial.println("Connecting to WiFi");
WiFi.begin("Wokwi-GUEST", "", 6);
boolean wifiConnected;
isConnectedToWifi(&wifiConnected);
while ((!wifiConnected) )
{
Serial.println("Couldn't connect to WiFi, retrying in 5 seconds");
WiFi.begin("Wokwi-GUEST", "", 6);
isConnectedToWifi(&wifiConnected);
retriesCount++;
delay(5000);
}
}
static void isConnectedToWifi(boolean *isConnected)
{
*isConnected = WiFi.status() == WL_CONNECTED;
}
static void onMessageReceived(int messageSize)
{
Serial.println("Received a message with topic '");
Serial.print(mqttClient.messageTopic());
Serial.print("', length ");
Serial.print(messageSize);
Serial.println(" bytes:");
// uint8_t buffer;
// mqttClient.readBytes(&buffer, messageSize);
// DeviceCommand command;
// memcpy(&command, &buffer, messageSize);
// registerCommand(&command);
Serial.println();
}
void setupOutputPins() {
pinMode(ARDUINO_LED_PIN, OUTPUT) ; //Set pin 2 as output
}
void dummyCommandHandler(DeviceCommand* command) {
analogWrite(ARDUINO_LED_PIN, ARDUINO_ON_LED_POWER) ; //setting pwm to 25
}
void setup()
{
Serial.begin(115200);
setupOutputPins();
connectToMqttBroker();
max_handeled_commands_per_loop = MAX_HANDLED_COMMANDS_PER_LOOP;
registerCommandHandler(dummyCommandHandler);
}
void loop()
{
handleCommands(&max_handeled_commands_per_loop);
}