Phase 4

Build MQTT Dashboard Practically

Is phase me dashboard ready-made nahi milega. Pehle broker me WebSocket enable karenge, phir dashboard.html file banayenge, terminal se MQTT data bhejenge, aur browser dashboard par live receive/send test karenge.

Architecture Overview

Yeh diagram show karta hai ki MQTT data Terminal, Broker aur Browser Dashboard ke beech kaise flow karta hai.

Terminal Publisher topic: phase4/chat/terminal payload: {"temp":31.2} MQTT Broker TCP: 1883 WebSocket: 9001 Browser Dashboard Live Data temp: 31.2°C Terminal Subscriber mosquitto_sub -h 192.168.1.6 -t "phase4/#" -v phase4/chat/terminal phase4/data/terminal phase4/# ws://192.168.1.6:9001 phase4/chat/dashboard phase4/# MQTT Phase 4 Demo Architecture ESP32 is not required in this demo. Same MQTT data flow will later be used for DHT sensor data.

Lesson Flow

Step 1

MQTT broker ko browser WebSocket ke liye ready karna.

Step 2

Ek new dashboard.html file create karke code paste karna.

Step 3

Terminal se chat aur JSON data publish karna.

Step 4

Dashboard se message bhejkar terminal me receive karna.

Step 1: WebSocket Broker Config

Browser direct MQTT TCP port 1883 se connect nahi karta. Browser ke liye Mosquitto me WebSocket listener 9001 enable karna hota hai.

listener 1883 0.0.0.0
protocol mqtt

listener 9001 0.0.0.0
protocol websockets

allow_anonymous true
persistence false
log_type all
brew services stop mosquitto
mosquitto -c phase4-mosquitto.conf -v

Terminal me output aana chahiye: Opening ipv4 listen socket on port 1883 aur Opening ipv4 listen socket on port 9001.

Step 2: Create dashboard.html

New file banao: dashboard.html. Neeche ka complete code paste karo. Ye dashboard terminal aur browser ke beech two-way MQTT chat/data demo karega.

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>MQTT Dashboard Demo</title>
  <script src="https://unpkg.com/mqtt@5.10.4/dist/mqtt.min.js"></script>
  <style>
    * { box-sizing: border-box; }
    body {
      margin: 0;
      font-family: Arial, sans-serif;
      background: #101827;
      color: #e7eef8;
      padding: 20px;
    }
    .wrap { max-width: 920px; margin: 0 auto; }
    .panel {
      background: #172235;
      border: 1px solid #2d425f;
      border-radius: 8px;
      padding: 16px;
      margin-bottom: 16px;
    }
    input, textarea, button {
      width: 100%;
      padding: 10px;
      margin-top: 8px;
      border-radius: 6px;
      border: 1px solid #38516f;
      font-size: 16px;
    }
    input, textarea { background: #0d1524; color: #e7eef8; }
    button {
      background: #35d2ff;
      color: #06121d;
      font-weight: bold;
      cursor: pointer;
    }
    .row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
    .status { font-weight: bold; color: #ff6574; }
    .status.connected { color: #42d79f; }
    #messages {
      min-height: 260px;
      max-height: 360px;
      overflow: auto;
      background: #08111f;
      border-radius: 8px;
      padding: 12px;
    }
    .msg {
      border: 1px solid #2d425f;
      border-radius: 6px;
      padding: 10px;
      margin-bottom: 8px;
      white-space: pre-wrap;
      word-break: break-word;
    }
    .topic { color: #35d2ff; font-size: 13px; margin-bottom: 4px; }
    .data-box {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 10px;
      margin-top: 10px;
    }
    .metric {
      background: #0d1524;
      border: 1px solid #2d425f;
      border-radius: 6px;
      padding: 12px;
    }
    .metric span { display: block; color: #97a8bd; font-size: 13px; }
    .metric strong { display: block; color: #35d2ff; font-size: 24px; margin-top: 6px; }
    @media (max-width: 700px) {
      .row, .data-box { grid-template-columns: 1fr; }
    }
  </style>
</head>
<body>
  <div class="wrap">
    <h1>MQTT Dashboard Demo</h1>

    <div class="panel">
      <p>Status: <span id="status" class="status">Disconnected</span></p>
      <div class="row">
        <div>
          <label>Broker WebSocket URL</label>
          <input id="brokerUrl" value="ws://192.168.1.6:9001">
        </div>
        <div>
          <label>Client ID</label>
          <input id="clientId" value="dashboard-client">
        </div>
      </div>
      <button onclick="connectBroker()">Connect MQTT</button>
    </div>

    <div class="panel">
      <h2>Received Messages</h2>
      <div id="messages"></div>
    </div>

    <div class="panel">
      <h2>Send Chat From Dashboard</h2>
      <textarea id="chatText">Hello from dashboard</textarea>
      <button onclick="sendChat()">Send Chat</button>
    </div>

    <div class="panel">
      <h2>Send / Receive Data</h2>
      <textarea id="dataText">{"temperature":28.5,"humidity":62,"source":"dashboard"}</textarea>
      <button onclick="sendData()">Send Data</button>
      <div class="data-box">
        <div class="metric"><span>Temperature</span><strong id="temp">--</strong></div>
        <div class="metric"><span>Humidity</span><strong id="hum">--</strong></div>
        <div class="metric"><span>Source</span><strong id="source">--</strong></div>
      </div>
    </div>
  </div>

  <script>
    let client = null;

    function connectBroker() {
      const brokerUrl = document.getElementById('brokerUrl').value;
      const clientId = document.getElementById('clientId').value;

      client = mqtt.connect(brokerUrl, {
        clientId: clientId,
        clean: true,
        reconnectPeriod: 2000
      });

      client.on('connect', function () {
        setStatus(true);
        addMessage('system', 'Connected to broker');
        client.subscribe('phase4/#');
      });

      client.on('message', function (topic, message) {
        const payload = message.toString();
        addMessage(topic, payload);

        if (topic.startsWith('phase4/data/')) {
          updateData(payload);
        }
      });

      client.on('error', function (error) {
        addMessage('error', error.message);
      });

      client.on('close', function () {
        setStatus(false);
      });
    }

    function sendChat() {
      publishMessage('phase4/chat/dashboard', document.getElementById('chatText').value);
    }

    function sendData() {
      publishMessage('phase4/data/dashboard', document.getElementById('dataText').value);
    }

    function publishMessage(topic, payload) {
      if (!client || !client.connected) {
        addMessage('error', 'Dashboard MQTT broker se connected nahi hai');
        return;
      }

      client.publish(topic, payload);
      addMessage(topic, payload);
    }

    function updateData(payload) {
      try {
        const data = JSON.parse(payload);
        if (data.temperature !== undefined) document.getElementById('temp').textContent = data.temperature + ' C';
        if (data.humidity !== undefined) document.getElementById('hum').textContent = data.humidity + '%';
        if (data.source !== undefined) document.getElementById('source').textContent = data.source;
      } catch (error) {
        addMessage('error', 'Data JSON format me nahi hai');
      }
    }

    function setStatus(connected) {
      const status = document.getElementById('status');
      status.textContent = connected ? 'Connected' : 'Disconnected';
      status.className = connected ? 'status connected' : 'status';
    }

    function addMessage(topic, payload) {
      const box = document.getElementById('messages');
      const item = document.createElement('div');
      item.className = 'msg';
      item.innerHTML = '<div class="topic">' + escapeHtml(topic) + '</div>' + escapeHtml(payload);
      box.appendChild(item);
      box.scrollTop = box.scrollHeight;
    }

    function escapeHtml(value) {
      return String(value)
        .replaceAll('&', '&amp;')
        .replaceAll('<', '&lt;')
        .replaceAll('>', '&gt;')
        .replaceAll('"', '&quot;')
        .replaceAll("'", '&#039;');
    }
  </script>
</body>
</html>
python3 -m http.server 5500
http://127.0.0.1:5500/dashboard.html

Step 3: Terminal Se Dashboard Par Message Bhejo

mosquitto_sub -h 192.168.1.6 -t "phase4/#" -v
mosquitto_pub -h 192.168.1.6 -t "phase4/chat/terminal" -m "Hello from terminal"
mosquitto_pub -h 192.168.1.6 -t "phase4/data/terminal" -m '{"temperature":31.2,"humidity":58,"source":"terminal"}'

Dashboard connected rahega to terminal se bheja hua chat aur data browser me live show hoga. Yehi pattern baad me DHT sensor ke data ke liye use hoga.

Step 4: Dashboard Se Terminal Par Message Bhejo

Dashboard me Send Chat click karne par Terminal 1 me ye topic dikhega:

phase4/chat/dashboard Hello from dashboard

Dashboard me Send Data click karne par Terminal 1 me JSON payload dikhega:

phase4/data/dashboard {"temperature":28.5,"humidity":62,"source":"dashboard"}

Topics Used

phase4/chat/terminal
Terminal se browser dashboard par chat.
phase4/chat/dashboard
Dashboard se terminal par chat.
phase4/data/terminal
Terminal se JSON data dashboard par.
phase4/data/dashboard
Dashboard se JSON data terminal par.