This week, just like I mentioned in class, I re-soldered the circuit board and redesigned the device enclosure.

image.png

image.png

Shentong told me she would take full responsibility for the MQTT part. I said sure—why not—especially right in the middle of midterm season, when everything is deadline-driven. It definitely reduced my workload a lot.

But I didn’t want to completely miss out on MQTT as a mechanism. In my opinion, one of the most important parts of this class is learning how to use protocols so our devices can communicate. So this blog post isn’t really about what I “made” this week. Instead, it’s about how I used the code and blog Shentong shared—and my conversations with her—to understand how the MQTT system in our project actually works.

From the Week 4 lecture, we learned that an MQTT broker works like a giant loudspeaker: it broadcasts messages sent to the broker, and any client that subscribes to a topic can receive those messages. That part is clear. Our Arduino sends the sensor data it collects to Tom’s MQTT relay.

The key question is: how do we capture the information broadcast via MQTT and ultimately present it on a web page? At first I assumed our approach would be to host the web page on the same server, then run a program that directly writes the subscribed data into a JSON file, and finally have the web page read that file.

image.png

But Shentong seems to have used a different approach. She apparently created a virtual machine using Google Cloud VM, and installed a Node.js runtime environment on that server. I didn’t know what Node.js was.

it seemed like node.js is a like platform or a frame to build the program that will run everyday.

I get the knowledge from this video: https://www.youtube.com/watch?v=TlB_eWDSMt4

client.on("connect", function () {
    console.log("Connected to MQTT broker");
    client.subscribe("shentong/shtc3");
});

At the same time, Node.js is also responsible for writing data into a JSONL file.

const mqtt = require("mqtt");
const fs = require("fs");
const path = require("path");

const DATA_DIR = "data";

// create data folder if it does not exist
if (!fs.existsSync(DATA_DIR)) {
    fs.mkdirSync(DATA_DIR);
}

// function to generate today's JSONL file name
function getTodayFile() {
    const now = new Date();
    const date = now.toISOString().slice(0, 10); // YYYY-MM-DD
    return path.join(DATA_DIR, "mqtt-" + date + ".jsonl");
}

// when a message arrives
client.on("message", function (topic, message) {
    const entry = {
        timestamp: new Date().toISOString(),
        topic: topic,
        message: message.toString()
    };

    const file = getTodayFile();

    // append each message as one JSON line into today's file
    fs.appendFile(file, JSON.stringify(entry) + "\\n", function (err) {
        if (err) {
            console.error("Error writing to file:", err);
        } else {
            console.log("Saved message to", file);
        }
    });
});

She also used an Express API to send data to the web page. From what I understand, Express is like a framework that handles some backend logic. I used AI to extract and annotate parts of her code to explain how the script works.