================================================================================
  Experiment 9: Dual MQTT Communication (HiveMQ & Mosquitto)
================================================================================

FULL QUESTION:
Implement MQTT communication using both an online MQTT broker (HiveMQ) and a local offline MQTT broker (Eclipse Mosquitto) to publish, receive, and display IoT sensor data.

SHORT QUESTION:
Dual MQTT communication across public cloud broker (HiveMQ) and local offline broker (Mosquitto).

================================================================================
README & SETUP INSTRUCTIONS:
================================================================================
# Experiment 9: Dual MQTT Communication (HiveMQ & Mosquitto)

## Objective
Demonstrate MQTT publish/subscribe communication using both a cloud public broker (HiveMQ) and a local offline broker (Eclipse Mosquitto).

## Requirements
- Python library: `pip install paho-mqtt`
- Local Broker: Eclipse Mosquitto installed and running (`mosquitto -v` or Windows Service).

## How to Run
```bash
python dual_broker.py
```

================================================================================
SOURCE CODE FILES:
================================================================================

1. dual_broker.py
--------------------------------------------------------------------------------
import time
import json
import paho.mqtt.client as mqtt

LOCAL_BROKER = "127.0.0.1"
ONLINE_BROKER = "broker.hivemq.com"
PORT = 1883
TOPIC = "iot_lab_test/dual_broker"

def on_connect(client, userdata, flags, rc, *extra):
    label = userdata.get("label", "Broker")
    if rc == 0:
        print(f"[{label}] Connected successfully.")
        client.subscribe(TOPIC)
    else:
        print(f"[{label}] Connection failed with code: {rc}")

def on_message(client, userdata, msg):
    label = userdata.get("label", "Broker")
    print(f"[{label} Received] {msg.topic}: {msg.payload.decode()}")

try:
    client_local = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, userdata={"label": "Local-Mosquitto"})
    client_online = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, userdata={"label": "Online-HiveMQ"})
except AttributeError:
    client_local = mqtt.Client(userdata={"label": "Local-Mosquitto"})
    client_online = mqtt.Client(userdata={"label": "Online-HiveMQ"})

client_local.on_connect = on_connect
client_local.on_message = on_message

client_online.on_connect = on_connect
client_online.on_message = on_message

try:
    client_local.connect(LOCAL_BROKER, PORT, 60)
    client_local.loop_start()
except Exception as e:
    print("Local Mosquitto not reachable (ensure service is running):", e)

try:
    client_online.connect(ONLINE_BROKER, PORT, 60)
    client_online.loop_start()
except Exception as e:
    print("Online HiveMQ not reachable:", e)

time.sleep(2)

sample_data = json.dumps({"temperature": 28.4, "humidity": 65.0})
print("\nPublishing test packet to both brokers...")
try:
    client_local.publish(TOPIC, sample_data)
except Exception:
    pass
client_online.publish(TOPIC, sample_data)

time.sleep(3)
client_local.loop_stop()
client_online.loop_stop()
print("Execution finished.")
--------------------------------------------------------------------------------
