Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | import { MqttClient } from 'mqtt';
export class MqttMessageHandler {
private client: MqttClient | null;
constructor(client: MqttClient | null) {
this.client = client;
}
public setClient(client: MqttClient) {
this.client = client;
}
// Store last air-sensing data for each MAC address
private lastAirSensingData: Record<string, {
temperature?: number;
humidity?: number;
co2?: number;
pm1_0?: number;
pm2_5?: number;
pm10?: number;
timestamp?: Date;
}> = {};
// Store tag data for each MAC address
private tagData: Record<string, {
timestamp: Date;
beacons: Array<{ id: number; rssi: number, floor_id: number }>;
}> = {};
public async handleMessage(topic: string, mqttMessage: string): Promise<void> {
try {
const value = parseFloat(mqttMessage); // Parse the payload as a number
Iif (topic.startsWith('smartclassroom/tag/')) {
const segments = topic.split('/');
const macAddress = segments[2]; // Extract the MAC address (3rd segment)
Iif (!macAddress) {
console.error('[MQTT] Invalid topic format: Missing MAC address');
return;
}
const message = JSON.parse(mqttMessage);
Iif (!message.beaconData || !message.beaconData.Beacons) {
console.error('[MQTT] Invalid message format: Missing beacon data');
return;
}
const { Beacons } = message.beaconData;
// Map Beacons to include floor_id (defaulting to 0 or another value if not provided)
const beacons = Beacons.map((beacon: { id: number; rssi: number; floor_id: number; }) => ({
id: beacon.id,
rssi: beacon.rssi,
floor_id: beacon.floor_id,
}));
// Store the tag data by MAC address
this.tagData[macAddress] = {
timestamp: new Date(),
beacons: beacons,
};
console.log(`[MQTT] Logged beacon data for tag ${macAddress}`);
}
Iif (topic.startsWith('smartclassroom/air-sensing/')) {
const segments = topic.split('/');
let macAddress = segments[2]; // Extract the MAC address (3rd segment)
const dataType = segments[3]; // Extract the data type (e.g., temperature, humidity, co2, etc.)
Iif (!macAddress || !dataType) {
console.error('[MQTT] Invalid topic format: Missing MAC address or data type');
return;
}
// Normalize the MAC address (trim and convert to lowercase)
macAddress = macAddress.trim().toLowerCase();
// Initialize the data object for the MAC address if it doesn't exist
Iif (!this.lastAirSensingData[macAddress]) {
this.lastAirSensingData[macAddress] = {};
}
// Update the corresponding field in the lastAirSensingData object
switch (dataType) {
case 'temperature':
this.lastAirSensingData[macAddress].temperature = value;
break;
case 'humidity':
this.lastAirSensingData[macAddress].humidity = value;
break;
case 'co2':
this.lastAirSensingData[macAddress].co2 = value;
break;
case 'air-quality-pm1_0':
this.lastAirSensingData[macAddress].pm1_0 = value;
break;
case 'air-quality-pm2_5':
this.lastAirSensingData[macAddress].pm2_5 = value;
break;
case 'air-quality-pm10':
this.lastAirSensingData[macAddress].pm10 = value;
break;
default:
console.warn(`[MQTT] Unhandled data type: ${dataType}`);
return;
}
}
} catch (err) {
console.error('[MQTT] Failed to process message:', err);
}
}
public getAllAirSensingData(): Record<string, {
temperature?: number;
humidity?: number;
co2?: number;
pm1_0?: number;
pm2_5?: number;
pm10?: number;
timestamp?: Date; // Include timestamp for each MAC address
}> {
// Add a timestamp to each MAC address entry
for (const macAddress in this.lastAirSensingData) {
Iif (this.lastAirSensingData.hasOwnProperty(macAddress)) {
this.lastAirSensingData[macAddress].timestamp = new Date(); // Set the current timestamp
}
}
// Store the current data to return
const dataToReturn = { ...this.lastAirSensingData };
// Clear the lastAirSensingData after sending
this.lastAirSensingData = {};
return dataToReturn;
}
// Method to get all tag data by MAC address
public getAllTagData(): Record<string, {
timestamp: Date;
beacons: Array<{ id: number; rssi: number, floor_id: number }>;
}> {
for (const macAddress in this.tagData) {
Iif (this.tagData.hasOwnProperty(macAddress)) {
this.tagData[macAddress].timestamp = new Date(); // Set the current timestamp
}
}
// Store the current data to return
const dataToReturn = { ...this.tagData };
// Clear the lastAirSensingData after sending
this.tagData = {};
return dataToReturn;
}
public sendMessage(topic: string, message: string): void {
if (this.client) {
this.client.publish(topic, message, { qos: 1 }, (err) => {
if (err) {
console.error(`[MQTT] Publish error for topic ${topic}:`, err.message);
} else {
console.log(`[MQTT] Published to: ${topic}`);
}
});
} else {
console.error('[MQTT] Client not connected. Cannot publish message.');
}
}
} |