Near-Real-Time Location Tracking with RSSI ESP8266 and Mendix

In the world of IoT, accurate and efficient location tracking is more important than ever. This article explores how to achieve near-real-time location tracking using RSSI (Received Signal Strength Indicator) with the ESP8266 microcontroller and Mendix. Whether you’re an IoT enthusiast or a developer, this guide will help you implement a reliable tracking system by integrating these technologies.

Overview

We’ll walk you through the process in two main steps:

  1. Mendix Configuration
  2. NodeMCU Programming

1. Mendix Configuration

To start, you need to configure your Mendix application to receive and process the data from your ESP8266 device.

  • Create an Entity: Begin by creating an entity in your Mendix application that will store the tracking data. Make sure to design the corresponding overview pages to manage this data effectively.
  • Expose as REST Resource: After creating the entity, expose it as a REST resource. Ensure that you enable the security section and assign the necessary roles. The security configuration may vary depending on your specific requirements.
  • Testing and Deployment: Use local Swagger to test the REST endpoint and confirm it’s working correctly. Once verified, deploy it to your preferred environment.

Create your entity and generate overview pages.

Configure your endpoint with your security requirements.

2. NodeMCU Programming

The second part focuses on programming the ESP8266 (NodeMCU) to send location tracking data to your Mendix application. If your Mendix instance is running on an SSL-enabled server, remember to use HTTPS libraries. Below is an example code snippet that you can use as a reference. This code has been used in the demo video as well.

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266HTTPClient.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// Root certificate
const char IRG_Root_X1 [] PROGMEM = R"CERT(
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
)CERT";

const char* ssid = "*****";
const char* password = "***********";

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

unsigned long epochTime;

// Function to get the current epoch time
unsigned long getTime() {
  timeClient.update();
  return timeClient.getEpochTime();
}

// Create a list of certificates with the server certificate
X509List cert(IRG_Root_X1);

void setup() {
  Serial.begin(115200);

  // Connect to Wi-Fi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }

  // Set time via NTP, required for x.509 validation
  configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");

  Serial.print("Waiting for NTP time sync: ");
  time_t now = time(nullptr);
  while (now < 8 * 3600 * 2) {
    delay(500);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println();
  struct tm timeinfo;
  gmtime_r(&now, &timeinfo);
  Serial.print("Current time: ");
  Serial.print(asctime(&timeinfo));
}

void loop() {
  WiFiClientSecure client;
  epochTime = getTime();
  Serial.print("Epoch Time: ");
  Serial.println(epochTime);

  if (WiFi.status() == WL_CONNECTED) {
    client.setTrustAnchors(&cert);

    HTTPClient https;
    Serial.print("[HTTPS] begin...\n");

    if (https.begin(client, "https://XXXXXXXXXXXXXXX/esp8266")) {  // HTTPS

      // Prepare JSON data
      String httpRequestData = "{\"Time\":" + String(epochTime) + ",\"Name\":\"Arda\",\"Rssi\":" + String(WiFi.RSSI()) + "}";

      https.addHeader("Content-Type", "application/json");
      https.addHeader("Accept", "application/json");
      https.addHeader("Authorization", "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");

      Serial.println(httpRequestData);

      int httpCode = https.POST(httpRequestData);

      // Check if the request was successful
      if (httpCode > 0) {
        Serial.printf("[HTTPS] POST... code: %d\n", httpCode);

        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = https.getString();
          Serial.println(payload);
        }
      } else {
        Serial.printf("[HTTPS] POST... failed, error: %s\n", https.errorToString(httpCode).c_str());
      }

      https.end();
    } else {
      Serial.printf("[HTTPS] Unable to connect\n");
    }
  }

  Serial.println();
  Serial.println("Waiting 5 seconds before the next round...");
  delay(5000);
}

After you first run the nodemcu your serial monitor will look like below.

Explanations on NodeMCU Section

This code is designed to run on an ESP8266 microcontroller and accomplishes the following tasks:

  1. Connect to a Wi-Fi Network: Establishes a connection to your specified Wi-Fi network.
  2. Obtain Current Time: Retrieves the current time using an NTP (Network Time Protocol) server.
  3. Establish a Secure HTTPS Connection: Creates a secure connection to your Mendix server using the provided root certificate.
  4. Send Location Data: Sends an HTTP POST request with JSON data, including the current epoch time, device name, and RSSI value, to the Mendix application.
  5. Repeat Process: The loop repeats every 5 seconds, providing near-real-time updates.

With this guide, you can integrate RSSI-based tracking into your IoT projects using the ESP8266 and Mendix, making it easier to carry out straightforward and effective proof-of-concepts.