GITHUB REPOSITORY : EC25_MQTT_NORVI_GSM_SERIES #
NORVI devices are robust industrial controllers designed for IoT applications. When combined with the Quectel EC25 module, these devices can leverage cellular connectivity to communicate with cloud platforms securely using the MQTT protocol.
This guide provides an example implementation on how to use NORVI devices with the Quectel EC25 module to establish a connection with an MQTT broker using AT commands. The Quectel EC25 is a popular LTE module widely used in IoT applications for cellular communication. This guide will cover the necessary setup, code explanation, and essential AT commands.
MQTT PROTOCOL #
MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol designed for low-bandwidth, high-latency, or unreliable networks. It’s widely used in Internet of Things (IoT) and machine-to-machine (M2M) communication due to its simplicity and efficiency.
Check this link to understand more about the MQTT PROTOCOL.
Here are the components of MQTT,
Publisher-Subscriber Model #
- MQTT follows a publisher-subscriber model. In this model, there are two main entities, publishers and subscribers.
- Publishers are devices or applications that publish messages on a specific topic.
- Subscribers are devices or applications that receive messages by subscribing to specific topics.
Broker #
- MQTT communication is facilitated by a broker. The broker is a server responsible for receiving, routing, and delivering messages.
- Publishers and subscribers connect to the broker to send and receive messages.
- The broker is responsible for managing topics, subscribers, and message delivery.
Topics #
- Messages in MQTT are published to topics. Topics are hierarchical and can be thought of as addresses.
- Subscribers can subscribe to entire topics or specific subtopics using wildcards.
- For example, a topic could be sensors/temperature where sensors are the main topic and temperature is a subtopic.
Retained Messages #
- MQTT allows for retained messages, which are special messages that are stored by the broker and sent to new subscribers immediately upon subscription.
- This feature is useful for sending status updates or configuration information to new subscribers.
Quality of Service (QoS) #
- MQTT supports different levels of Quality of Service (QoS) for message delivery:
- QoS 0 (At most once): Messages are delivered at most once, without confirmation.
- QoS 1 (At least once): Messages are guaranteed to be delivered at least once, but duplicates may occur.
- QoS 2 (Exactly once): Messages are guaranteed to be delivered exactly once.
Understanding NORVI Devices with the Quectel EC25 Module #
NORVI devices are known for their reliability in industrial environments, featuring various input/output options, robust enclosures, and compatibility with multiple communication protocols. The integration of the Quectel EC25 module allows these devices to operate in areas where traditional Wi-Fi or Ethernet connections are not feasible. The Quectel EC25 module provides LTE connectivity, enabling NORVI devices to transmit data securely over cellular networks.
Setting Up NORVI GSM Series EC25 to MQTT #
Here we’ll be considering the NORVI GSM series EC25 device as a Publisher and “MQTT.FX” software as the Subscriber. With the NORVI device, we’ll be storing the I/O values in the MQTT Subscriber and the data visualization platform.
Key features of NORVI devices with the Quectel EC25 module,
- Industrial-grade design: Suitable for harsh environments.
- Versatile I/O options: Digital and analog inputs/outputs for various sensors and actuators.
- Cellular connectivity: LTE support via the Quectel EC25 module for remote monitoring and control.
Prerequisites
- Before you begin, ensure you have the following,
- NORVI Device with an integrated Quectel EC25 module
- Registered Sim card
- MQTT broker details (hostname, port, username, password)
- MQTT.fx software for testing and monitoring
- Arduino IDE and necessary libraries for programming the NORVI device.
- Data visualization platform (e.g., DATACAKE)
Required Libraries
- Arduino.h
- Wire.h
- WiFi.h
- ArduinoJson.h
Sensitive Information Handling
- Secret.h: This file should contain the MQTT username and password, which should be kept secure.
Hardware Setup #
Insert the registered SIM card to the module and upload the code.
Pin Connections
- MODEM_TX (TX Pin)
- MODEM_RX (RX Pin)
- GSM_RESET (Reset Pin)
- Digital Input Pins (D0, D1, D2, D3)
Understanding the Test program #
This code sets up an ESP32 microcontroller to connect to a GPRS network using a GSM module ( Quectel EC25), establish an MQTT connection, and handle sending and receiving MQTT messages. It uses the Arduino framework and various libraries to achieve this.
Download the example program.
1. Libraries and Includes
#include <Arduino.h> //Standard Arduino library.
#include <Wire.h> //Library for I2C communication.
#include <WiFi.h> // Include the WiFi library for MAC address
#include <ArduinoJson.h> //For handling JSON data.
#include "Secret.h" // Include the file to get the username and password of MQTT server
2. Definitions and Declarations
String gsm_send_serial(String command, int delay);
const char apn[] = "dialogbb"; // APN for the GPRS connection
//Address and port for the MQTT broker.
String broker = "*************"; //YOUR_MQTT_BROKER_ADDRESS
String MQTTport = "1881";
3. Pin Definitions and Sleep Settings
//Baud rate for serial communication with the EC25 module.
#define UART_BAUD 115200
//Pin assignments for the ESP32.
#define MODEM_TX 32
#define MODEM_RX 33
#define GSM_RESET 21
#define D0 34
#define D1 35
#define D2 14
#define D3 13
//Variables for storing the MAC address.
byte mac[6];
String str_macAddress;
//Used to control the timing of message publishing.
unsigned long prevMillis = 0;
const unsigned long interval = 60000; // Interval for sending messages
//Unique identifier for the device, used to filter incoming MQTT messages.
const char* deviceSerial = "3CE90E6C8F88"; // Replace with your device serial
4. Callback Function
This function checks if an incoming MQTT message is intended for the device by comparing MAC IDs. If they match, it processes the JSON payload and controls the relay (R0) based on the ‘state’ value.
void mqttCallback(char* topic, byte* payload, unsigned int len) {
SerialMon.print("Message arrived [");
SerialMon.print(topic);
SerialMon.print("]: ");
SerialMon.write(payload, len);
SerialMon.println();
// Extract serial number from the topic
String topicStr = String(topic);
int firstSlash = topicStr.indexOf('/');
int lastSlash = topicStr.lastIndexOf('/');
String MAC_ID = topicStr.substring(firstSlash + 1, lastSlash);
SerialMon.print("MAC ID: ");
SerialMon.println(MAC_ID);
if (MAC_ID == deviceSerial) {
// Decode the received message
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, payload, len);
if (error) {
SerialMon.print("deserializeJson() failed: ");
SerialMon.println(error.c_str());
return;
}
// Extract the payload
bool state = doc["state"];
SerialMon.print("STATE: ");
SerialMon.println(state);
// Handle state changes here
if (state == 0) {
digitalWrite(R0, LOW);
} else if (state == 1) {
digitalWrite(R0, HIGH);
}
} else {
SerialMon.println("Received message for a different serial number");
}
}
5. Setup Function
void setup() {
// Set console baud rate
Serial.begin(115200);
delay(10);
//initializes communication with the EC25 module.
SerialAT.begin(UART_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(2000);
pinMode(GSM_RESET, OUTPUT);
digitalWrite(GSM_RESET, HIGH); // RS-485
delay(2000);
pinMode(D0, INPUT);
pinMode(D1, INPUT);
pinMode(D2, INPUT);
pinMode(D3, INPUT);
//establish network and MQTT connections.
Init();
connectToGPRS();
connectToMQTT();
}
6. Main Loop
This loop ensures that the device regularly publishes its input states to the MQTT broker and stays connected to the network, handling any disconnections or errors as they occur.
void loop() {
//checks if the interval has passed since the last message was published.
if (millis() - prevMillis >= interval) {
prevMillis = millis();
// Read input values (assuming these are commented out for now)
bool IN1 = digitalRead(D0);
bool IN2 = digitalRead(D1);
bool IN3 = digitalRead(D2);
bool IN4 = digitalRead(D3);
// Create JSON object
StaticJsonDocument<200> doc;
doc["D0"] = IN1 ? 1 : 0;
doc["D1"] = IN2 ? 1 : 0;
doc["D2"] = IN3 ? 1 : 0;
doc["D3"] = IN4 ? 1 : 0;
String jsonString;
serializeJson(doc, jsonString);
WiFi.macAddress(mac);
str_macAddress = (String(mac[0] >> 4, HEX) + String(mac[0] & 0x0F, HEX)) +
(String(mac[1] >> 4, HEX) + String(mac[1] & 0x0F, HEX)) +
(String(mac[2] >> 4, HEX) + String(mac[2] & 0x0F, HEX)) +
(String(mac[3] >> 4, HEX) + String(mac[3] & 0x0F, HEX)) +
(String(mac[4] >> 4, HEX) + String(mac[4] & 0x0F, HEX)) +
(String(mac[5] >> 4, HEX) + String(mac[5] & 0x0F, HEX));
str_macAddress.toUpperCase();
String Digital_input = "NORVI/INPUTS/" + str_macAddress; //MQTT Topic
SerialMon.print("Published: ");
SerialMon.println(jsonString);
// Publish MQTT message and check the result
String publishResponse = publishMQTTMessage(Digital_input,jsonString, 1, 0);
// QoS 1, retain 0
// Check if the publish command was successful
if (publishResponse.indexOf("ERROR") != -1) {
SerialMon.println("MQTT publish failed. Reconnecting...");
connectToMQTT();
if (!isGPRSConnected()) {
SerialMon.println("GPRS connection lost. Reconnecting...");
connectToGPRS();
connectToMQTT();
}
if (!isNetworkConnected()) {
SerialMon.println("Network connection lost. Reconnecting...");
Init();
connectToGPRS();
connectToMQTT();
}
}
}
// Handle incoming MQTT messages
handleIncomingMessages();
}
7. Publishing MQTT Messages
This function facilitates publishing MQTT messages via the EC25 module by constructing and sending the appropriate AT commands and payload.
String publishMQTTMessage(String topic, String message, int qos, int retain) {
// Convert topic and message to be used with AT+QMTPUBEX
int topicLength = topic.length();
int messageLength = message.length();
// Publish command
String command = "AT+QMTPUBEX=0,1," + String(qos) + "," + String(retain) + ",\"" + topic + "\"," + String(messageLength);
String response = gsm_send_serial(command, 1000);
// Send the actual payload
response += gsm_send_serial(message + "\x1A", 1000);
// Append end-of-message character if needed
// Print response for debugging
SerialMon.print("Publish Response: ");
SerialMon.println(response);
return response; // Return response for further handling
}
8. Handling Incoming Messages
This function handles incoming MQTT messages by requesting them from the EC25 module, parsing the response, and then processing the message with a callback function.
void handleIncomingMessages() {
// Request messages from the EC25 module
String response = gsm_send_serial("AT+QMTRECV=0,1", 1000);
// Print the raw response for debugging
SerialMon.print("Raw MQTT Response: ");
SerialMon.println(response);
// Check if the response contains "+QMTRECV:"
int startPos = response.indexOf("+QMTRECV:");
if (startPos != -1) {
// Extract the part of the response containing the message
String messagePart = response.substring(startPos);
// Print the extracted message part for debugging
SerialMon.print("Extracted Message Part: ");
SerialMon.println(messagePart);
// Remove any extraneous text before "+QMTRECV:"
messagePart.trim();
// Check if the response is in the expected format
if (messagePart.startsWith("+QMTRECV:")) {
// Extract the part after "+QMTRECV:" (skip the "+QMTRECV:" prefix)
messagePart = messagePart.substring(messagePart.indexOf(':') + 1);
// Extract client_idx and msg_id
int firstComma = messagePart.indexOf(',');
int secondComma = messagePart.indexOf(',', firstComma + 1);
String client_idx = messagePart.substring(0, firstComma);
String msg_id = messagePart.substring(firstComma + 1, secondComma);
// Extract topic
int firstQuote = messagePart.indexOf('"', secondComma + 1);
int secondQuote = messagePart.indexOf('"', firstQuote + 1);
String topic = messagePart.substring(firstQuote + 1, secondQuote);
// Extract payload length
int thirdComma = messagePart.indexOf(',', secondQuote + 1);
int fourthComma = messagePart.indexOf(',', thirdComma + 1);
String payloadLengthStr = messagePart.substring(thirdComma + 1, fourthComma);
int payloadLength = payloadLengthStr.toInt();
// Extract payload
int thirdQuote = messagePart.indexOf('"', fourthComma + 1);
int fourthQuote = messagePart.indexOf('}', thirdQuote + 1);
int fifthQuote = messagePart.indexOf('"', fourthQuote + 1);
String payload = messagePart.substring(thirdQuote + 1, fifthQuote );
// Debug print
SerialMon.print("Received Topic: ");
SerialMon.println(topic);
SerialMon.print("Received Payload: ");
SerialMon.println(payload);
SerialMon.print("Payload Length: ");
SerialMon.println(payloadLength);
// Convert topic and payload to mutable char arrays
char topicArr[topic.length() + 1];
byte payloadArr[payload.length() + 1];
topic.toCharArray(topicArr, topic.length() + 1);
for (int i = 0; i < payload.length(); ++i) {
payloadArr[i] = (byte)payload[i];
}
payloadArr[payload.length()] = 'void handleIncomingMessages() {
// Request messages from the EC25 module
String response = gsm_send_serial("AT+QMTRECV=0,1", 1000);
// Print the raw response for debugging
SerialMon.print("Raw MQTT Response: ");
SerialMon.println(response);
// Check if the response contains "+QMTRECV:"
int startPos = response.indexOf("+QMTRECV:");
if (startPos != -1) {
// Extract the part of the response containing the message
String messagePart = response.substring(startPos);
// Print the extracted message part for debugging
SerialMon.print("Extracted Message Part: ");
SerialMon.println(messagePart);
// Remove any extraneous text before "+QMTRECV:"
messagePart.trim();
// Check if the response is in the expected format
if (messagePart.startsWith("+QMTRECV:")) {
// Extract the part after "+QMTRECV:" (skip the "+QMTRECV:" prefix)
messagePart = messagePart.substring(messagePart.indexOf(':') + 1);
// Extract client_idx and msg_id
int firstComma = messagePart.indexOf(',');
int secondComma = messagePart.indexOf(',', firstComma + 1);
String client_idx = messagePart.substring(0, firstComma);
String msg_id = messagePart.substring(firstComma + 1, secondComma);
// Extract topic
int firstQuote = messagePart.indexOf('"', secondComma + 1);
int secondQuote = messagePart.indexOf('"', firstQuote + 1);
String topic = messagePart.substring(firstQuote + 1, secondQuote);
// Extract payload length
int thirdComma = messagePart.indexOf(',', secondQuote + 1);
int fourthComma = messagePart.indexOf(',', thirdComma + 1);
String payloadLengthStr = messagePart.substring(thirdComma + 1, fourthComma);
int payloadLength = payloadLengthStr.toInt();
// Extract payload
int thirdQuote = messagePart.indexOf('"', fourthComma + 1);
int fourthQuote = messagePart.indexOf('}', thirdQuote + 1);
int fifthQuote = messagePart.indexOf('"', fourthQuote + 1);
String payload = messagePart.substring(thirdQuote + 1, fifthQuote );
// Debug print
SerialMon.print("Received Topic: ");
SerialMon.println(topic);
SerialMon.print("Received Payload: ");
SerialMon.println(payload);
SerialMon.print("Payload Length: ");
SerialMon.println(payloadLength);
// Convert topic and payload to mutable char arrays
char topicArr[topic.length() + 1];
byte payloadArr[payload.length() + 1];
topic.toCharArray(topicArr, topic.length() + 1);
for (int i = 0; i < payload.length(); ++i) {
payloadArr[i] = (byte)payload[i];
}
payloadArr[payload.length()] = '\0'; // Null-terminate byte array
// Call the MQTT callback function with the extracted values
mqttCallback(topicArr, payloadArr, payload.length());
} else {
SerialMon.println("Unexpected response format.");
}
} else {
SerialMon.println("No new MQTT messages or unexpected response format.");
}
}
'; // Null-terminate byte array
// Call the MQTT callback function with the extracted values
mqttCallback(topicArr, payloadArr, payload.length());
} else {
SerialMon.println("Unexpected response format.");
}
} else {
SerialMon.println("No new MQTT messages or unexpected response format.");
}
}
9. Network and MQTT Initialization
These functions manage the connection setup for GPRS and MQTT, including network registration, GPRS attachment, MQTT configuration, and topic subscription.
// Initialize network connection using AT commands
void Init(void) {
// Connecting with the network and GPRS
delay(5000);
gsm_send_serial("AT+CFUN=1", 10000);
gsm_send_serial("AT+CPIN?", 10000);
gsm_send_serial("AT+CSQ", 1000);
gsm_send_serial("AT+CREG?", 1000);
gsm_send_serial("AT+COPS?", 1000);
gsm_send_serial("AT+CGATT?", 1000);
gsm_send_serial("AT+CPSI?", 500);
gsm_send_serial("AT+CGDCONT=1,\"IP\",\"dialogbb\"", 1000);
gsm_send_serial("AT+CGACT=1,1", 1000);
gsm_send_serial("AT+CGATT?", 1000);
gsm_send_serial("AT+CGPADDR=1", 500);
}
// Connect to GPRS using AT commands
void connectToGPRS(void) {
gsm_send_serial("AT+CGATT=1", 1000);
gsm_send_serial("AT+CGDCONT=1,\"IP\",\"dialogbb\"", 1000);
gsm_send_serial("AT+CGACT=1,1", 1000);
gsm_send_serial("AT+CGPADDR=1", 500);
}
// Configure MQTT settings and connect to the broker using AT commands
// Subscribe to the necessary topics
void connectToMQTT(void) {
// Initialize MQTT configurations
gsm_send_serial("AT+QMTCFG=\"recv/mode\",0,0,1", 1000);
gsm_send_serial("AT+QMTOPEN=0,\"mqtt.sensoper.net\",1881", 1000);
delay(2000);
String command = "AT+QMTCONN=0,\"EC25 client\",\"" + username + "\",\"" + password + "\"";
gsm_send_serial(command, 1000);
delay(2000); // Wait for the connection to establish
// Subscribe to the downlink topic
String downlinkTopic = "NORVI/+/OUTPUT";
String subscribeCommand = "AT+QMTSUB=0,1,\"" + downlinkTopic + "\",0";
// QoS 1
gsm_send_serial(subscribeCommand, 1000);
delay(2000); // Allow time for subscription confirmation
// Check for subscription confirmation
String response = gsm_send_serial("AT+QMTSUB?", 1000);
// Check subscription status
SerialMon.print("Subscription Response: ");
SerialMon.println(response);
// Debug: Print MQTT connection status
String connStatus = gsm_send_serial("AT+QMTCONN?", 1000);
SerialMon.print("MQTT Connection Status: ");
SerialMon.println(connStatus);
}
10. Utility Functions
These functions handle network and GPRS connectivity checks and provide a utility function to send AT commands to the GSM module and retrieve responses.
// Check if the network is connected by sending AT command
bool isNetworkConnected() {
String response = gsm_send_serial("AT+CREG?", 3000);
return (response.indexOf("+CREG: 0,1") != -1 || response.indexOf("+CREG: 0,5") != -1);
}
// Check if the GPRS is connected by sending AT command
bool isGPRSConnected() {
String response = gsm_send_serial("AT+CGATT?", 3000);
return (response.indexOf("+CGATT: 1") != -1);
}
// Send AT command and return the response
String gsm_send_serial(String command, int timeout) {
String buff_resp = "";
Serial.println("Send ->: " + command);
SerialAT.println(command);
unsigned long startMillis = millis();
while (millis() - startMillis < timeout) {
while (SerialAT.available()) {
char c = SerialAT.read();
buff_resp += c;
}
delay(10); // Small delay to allow for incoming data to accumulate
}
Serial.println("Response ->: " + buff_resp);
return buff_resp;
}
Software Configurations #
Essential AT Commands #
After uploading the code to the NORVI device, it’s important to verify that the SIM card is correctly registered and the device is able to communicate with the network.
This can be done by checking the serial monitor for specific AT command responses.
Signal Quality Check (AT+CSQ),
- Good Signal: An RSSI value of 18 indicates strong signal strength.
- Weak Signal: A lower value, like 5, suggests weak signal strength, which could cause connection issues.
Network Registration Check (AT+CREG?),
- Registered: The 1 indicates the device is registered on its home network.
- Not Registered: A response of 0,0 means the device isn’t registered and isn’t searching for a network, possibly due to SIM or network issues.
Operator Selection Check (AT+COPS?),
- This response shows that the device is connected to the operator “Dialog.”
- The value “7” indicates the type of network (e.g., LTE).
- If the operator details are missing or incorrect, it may indicate a problem with network registration or SIM card compatibility.
Query MQTT Connection Status(AT+QMTCONN?)
- The 3 suggests that the MQTT connection is established and connected.
Query Attach Status(AT+CGATT?)
- This command output shows that the device is currently attached to the GPRS network.
- If the response were +CGATT: 0, it would indicate that the device isn’t connected, which would prevent any data transfer over the cellular network.
Query Packet-Switched Service Information(AT+CPSI?)
- This command is typically used to get information about the serving cell, including the network status, cell ID, and signal quality.
- The ‘ERROR’ response suggests that the command might not be supported or a configuration issue. Some modules may require different configurations or initialization before using this command.
Define PDP Context(AT+CGDCONT=1,”IP”,”dialogbb”)
- This command defines a PDP (Packet Data Protocol) context.
- It specifies the context identifier (1 in this case), PDP type (IP), and the APN (Access Point Name), which is dialog bb.
Activate/Deactivate PDP Context(AT+CGACT=1,1)
- This command activates the specified PDP context.
- The first 1 indicates the context identifier, and the second 1 specifies that it should be activated.
Query PDP Address(AT+CGPADDR=1)
- This command queries the IP address assigned to the specified PDP context.
The device has been assigned the IP address 100.93.86.213 for the PDP context 1.
Configure MQTT Receive Mode(AT+QMTCFG=”recv/mode”,0,0,1)
- The parameters typically include the mode of receiving messages (QoS 0 or 1).
- Indicates that there was an issue. This could be due to an incorrect parameter or an unsupported feature
Open MQTT Connection(AT+QMTOPEN=0,*”,1881)
- Opens an MQTT connection to the specified broker address (**) on port 1881.
- The 2 suggests that the connection is in progress
Connect to MQTT Broker( AT+QMTCONN=0,*****,******,****** )
- Connects to the MQTT broker with client ID, username , and password .
Subscribe to MQTT Topic( AT+QMTSUB=0,1,”NORVI/+/OUTPUT”,0)
- Subscribes to the MQTT topic “NORVI/+/OUTPUT” with QoS level 0.
- This response indicates that the subscription was successful.
Setting Up the MQTT Broker #
MQTT Broker Configuration
Use the MQTT.fx software as a Subscriber to set up the MQTT broker for the NORVI device. Below is the essential information required to configure the MQTT broker.
- MQTT Broker URL (IP or domain)
- Port number
- Client ID (optional but recommended)
- Username and Password (if authentication is required)
- Topic(s) to publish/subscribe to
String Digital_input = "NORVI/INPUTS/" + str_macAddress; //MQTT Topic
Steps to Configure in MQTT.fx
Check this link for detailed instructions on how to configure the MQTT broker and the Subscriber.
- Download MQTT.fx client and install it.
- Open the MQTT.fx and click the Settings icon.
- Click + to create a profile.
- Enter the Connection Profile and General information.
- Enter the User Credentials information
- After completing the above steps, click Apply > OK to save.
- Then, select the name of the file just created in the profile box and click Connect.
- If the round icon in the top-right corner is green, the connection to IoT Hub is successful, and publishing and subscribing operations can be performed.
- Select the Subscribe tab in the client, scan and select the topic name, and click Subscribe to subscribe to the topic.
- The subscribing result can be seen in the bottom right corner.
Integration with Data Visualization Platform #
The NORVI Devices can be connected to an IoT platform, allowing users to visualize data collected by the NORVI devices. The platform used in this case is DATACAKE. Here’s how to integrate the NORVI devices with DATACAKE.
Access the DATACAKE from this link and navigate the Datacake dashboard. Select the “Add Devices”.
For the MQTT integration select the API. This will add the device to the Datacake account.
Click on Configuration Scroll down a bit and go to the new panel “MQTT Configuration”. Press on “Add New MQTT Broker”. Fill in the server details and add.
Then link the MQTT device on the broker to the device in the DATACAKE by providing the MQTT upline decoder. Subscribe to the topic on the MQTT broker and write a payload decoder.
This decoder function is designed to decode incoming messages from a device and format them into a structure that can be sent to the Datacake API for display or storage.
This function starts by converting the incoming payload, Extracting the MAC ID from the Topic, presumably in JSON format, into a JavaScript object. It uses JSON.parse() to accomplish this.
function Decoder(topic, payload) {
var mac_id = topic.split("/")[2];
payload = JSON.parse(payload);
Convert the string representations of the digital input states (which might be “true” or “false”) into integers (0 or 1).
// Convert string "true"/"false" to integers (0 or 1)
var D0 = JSON.parse(payload.D0) ;
var D1 = JSON.parse(payload.D1) ;
var D2 = JSON.parse(payload.D2);
var D3 = JSON.parse(payload.D3);
Return an array of objects where each object contains:
device: A serial number or device ID (hard coded as “N123O456R789VI”).
field: The name of the digital input pin (“D0”, “D1”, “D2”, “D3”).
value: The state of the corresponding digital input pin (0 or 1).
//if(mac_id =="************")
return [
{ device: "Serial Number", // Serial Number or Device ID
field: "D0",
value: D0
},
{ device: "Serial Number", // Serial Number or Device ID
field: "D1",
value: D1
},
{ device: "Serial Number", // Serial Number or Device ID
field: "D2",
value: D2
},
{ device: "Serial Number", // Serial Number or Device ID
field: "D3",
value: D3
}
];
}
“Try Decoder Function” allows the decoder function to be tested to verify its functionality before deploying it. By entering sample data and observing the output, you can verify that the decoder is correctly parsing incoming payloads and formatting the data in a way that can be sent to the Datacake API.
To create a first database field, click on the “Add Field”. This will open another modal asking for some required input for the fields.
When typing the name for that field, the identifier auto-fills. This identifier is unique and cannot be changed. it’s required for accessing the field from within the payload decoder or API.
If the device is already sending data, an indication of incoming data can be seen in the “Last data” column.
After the settings in the configuration section, the dashboard can be created. Use the Tab Bar on the Device to navigate into the ”Dashboard” view.