I want to use an Arduino Nano 33 IoT to constantly get the status of a Shelly device using MQTT and the MQTT broker HiveMQ or another free easy to use broker.
The Shelly device Shelly 1 is already setup in HiveMQ and I can subscribe to the topic and get the status in the HiveMQ broker.
I am not good at programming and I am looking for a similar arduino code that I can adapt according to my needs and learn from it. Unfortunately I have not found anything for the Nano 33 IoT so far.
Basically the following is needed:
Establish WiFI connection
Connect to MQTT broker and MQTT client
Subscibe to topic
Evaluate the device status {"connected":false} and {"connected":true} and display any change in subscribed topics in the serial monitor
Send an alarm message to a mail adress in case of {"connected":false}
Never used that library. But, perhaps it's a better one for beginners as the examples include establishing a WiFi connections. Note, to the best of my knowledge, HiveMQ requires a secure connection and using a TSL Certificate.
Nice.
The next challenge may then be establishing a secure connection and supplying the TSL Certificate. I've only done that with ESP32, it's likely similar with Nano 33 IOT although perhaps not identical.
Judging from the original post, @piotrowski is looking for a copy / paste solution which may not exist.
I want to use a cloud MQTT broker because I can't have an MQTT broker running on a server that is online all the time. If HiveMQ cloud is not working for this, do you know if there are other cloud brokers that will do for my project?
Or is it just the wrong attempt to solve this little problem?
I asked chatGPT and it wrote the following code which actually works! (scary stuff...)
It connects and when I unplug my shelly device, the message "....connected: false" appears in the serial monitor.
Now I will try to solve the next step with the email alert...
#include <WiFiNINA.h>
#include <PubSubClient.h>
// Replace these with your network credentials
const char* ssid = "mydata";
const char* password = "mydata";
// HiveMQ Cloud configuration
const char* mqtt_server = "mydata";
const int mqtt_port = 8883; // Use 8883 for SSL/TLS
const char* mqtt_user = "mydata";
const char* mqtt_password = "mydata";
// MQTT topics
const char* publish_topic = "shelly1g3-5432046e856c";
const char* subscribe_topic = "#"; //"shelly1g3-5432046e856c/status"; // use "#"; to get all messages
// WiFi and MQTT client objects
WiFiSSLClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
Serial.begin(9600);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (unsigned int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ArduinoNano33IoTClient", mqtt_user, mqtt_password)) {
Serial.println("connected");
client.subscribe(subscribe_topic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup() {
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// Publish a message every 10 seconds
static unsigned long lastMsg = 0;
unsigned long now = millis();
if (now - lastMsg > 10000) {
lastMsg = now;
String msg = "Hello from Arduino Nano 33 IoT";
Serial.print("Publish message: ");
Serial.println(msg);
client.publish(publish_topic, msg.c_str());
}
}
It's a message created by the Shelly device and because I subscribed to the topic "#" all messages from this client are received. At least that's how I understand it...
Looks like both you and chatGPT got lucky that WiFi boards supported by WiFiNINA come preloaded with SSL Certificates and apply them even if you don't know enough to do it yourself: WiFiNINA API
I am still on this and I am stuck again. Now it's about the "sendEmail();" function.
If I put the "sendEmail();" in the void setup() block, it send me the email once (this is to test iw it works). So far it works and I receive the Mail.
As soon as I put it into the IF statement, the mail does not get sent. Why?? See the code below:
// Message arrived [shelly1g3-5432046e856c/status/ws] {"connected":false}
#include <WiFiNINA.h>
#include <PubSubClient.h>
#include <EMailSender.h>
// Replace these with your network credentials
const char* ssid = "xxxxxx";
const char* password = "xxxxx";
// Mail configuration
char eMailUser[] = "xxxxxxxxxxxxxxxxxxxxxx"; // account must have correct settings (see video)
char eMailPass[] = "xxxxxxxxxxxxxxxx "; // has to be an app password (see video)
char eMailRecipient[] = "xxxxxxxxxxxxxxxxxxxxxxxxxx"; // if you want to send an email
char phoneRecipient[] = "1234567890@txt.att.net"; // if you want to send an text (formatted for at&t)
//1234567890@vtext.com (formatted for verizon)
//1234567890@tmomail.net (formatted for tmobile)
const String TEXT = "The Shelly device is offline"; // main body text of the email
const char SUBJ[] = "SCL FI Monitor Alarm"; // subject of the email
// HiveMQ Cloud configuration
const char* mqtt_server = "a766053533df41398ab1a5b7589d257d.s1.eu.hivemq.cloud";
const int mqtt_port = 8883; // Use 8883 for SSL/TLS
const char* mqtt_user = "xxxxxxxxxxxxxxxxxxx";
const char* mqtt_password = "xxxxxxxxxxxxxxxxx";
// MQTT topics
const char* publish_topic = "ArduinoNano33IOT/messageFromArduino";
const char* subscribe_topic = "shelly1g3-5432046e856c/online"; //"shelly1g3-5432046e856c/status"; // use "#"; to get all messages
bool sendEmailFlag = false;
// WiFi and MQTT client objects
WiFiSSLClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
Serial.begin(9600);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void sendEmail(){
// sends an email or text depending on which recipient you choose
char senderName[] = "SENDER"; // the name it will display who the email is from
// the actual stuff that sends the email:
EMailSender emailSend(eMailUser, eMailPass, eMailUser, senderName);
EMailSender::EMailMessage msg;
EMailSender::Response resp;
Serial.println("Sending email...");
msg.subject = SUBJ;
msg.message = TEXT;
resp = emailSend.send(eMailRecipient, msg); // change eMailRecipient to phoneRecipient to send a text instead
// all of this just prints the info
Serial.println("Sending status: ");
Serial.print(resp.status);
Serial.println(resp.code);
Serial.println(resp.desc);
Serial.println("");
Serial.print("FROM: ");
Serial.println(eMailUser);
Serial.print("TO: ");
Serial.println(eMailRecipient);
Serial.print("SUBJECT: ");
Serial.println(SUBJ);
Serial.print("DATA:");
Serial.println(TEXT);
Serial.println("");
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic); // die message "Message arrived [shellyplusht-c049ef871e5c/status/ws] {"connected":false}" kommt aus diesem topic
Serial.print("] ");
for (unsigned int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Extract text for alarm Mail in case of "Message arrived [shellyplusht-c049ef871e5c/online] false"
//
String message;
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
//Serial.println(message);
if (message == "false") { // {"connected":false} geht nicht
Serial.println("Alarm Alarm Alarm "); // for testing!
sendEmailFlag = true; // Set the flag to send the email in the main loop
//sendEmail(); does not work inside callback loop
// sendEmailFlag = true; // Set the flag to send the email in the main loop
}
//
//
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ArduinoNano33IoTClient", mqtt_user, mqtt_password)) {
Serial.println("connected");
client.subscribe(subscribe_topic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup() {
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
//sendEmail(); // just to test if it works and it worked
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
/*
if (sendEmailFlag) {
sendEmail();
sendEmailFlag = false; // Reset the flag after sending the email
}
*/
//delay(5000);
/*
// Publish a message every 10 seconds
static unsigned long lastMsg = 0;
unsigned long now = millis();
if (now - lastMsg > 10000) {
lastMsg = now;
String msg = "Hello from Arduino Nano 33 IoT";
//Serial.print("Publish message: ");
//Serial.println(msg);
//client.publish(publish_topic, msg.c_str());
}
*/
}