117 lines
3.4 KiB
JavaScript
117 lines
3.4 KiB
JavaScript
/**
|
|
* MQTT 模拟数据发送器
|
|
* 用于模拟水质监测设备发送数据
|
|
*
|
|
* 使用方法:
|
|
* 1. 确保MQTT Broker已启动 (node server.js)
|
|
* 2. 在新终端运行: node simulator.js
|
|
*/
|
|
|
|
const mqtt = require('mqtt');
|
|
|
|
// MQTT配置
|
|
const MQTT_CONFIG = {
|
|
host: 'localhost',
|
|
port: 1883,
|
|
username: 'admin',
|
|
password: 'admin',
|
|
clientId: 'water-quality-simulator',
|
|
topic: 'sea_status'
|
|
};
|
|
|
|
// 水质数据范围配置
|
|
const DATA_RANGES = {
|
|
temp: { min: 15, max: 30, unit: '°C' },
|
|
ph: { min: 6.5, max: 8.5, unit: '' },
|
|
conductivity: { min: 500, max: 1500, unit: 'μS/cm' },
|
|
cod: { min: 10, max: 40, unit: 'mg/L' },
|
|
ammoniaNitrogen: { min: 0, max: 1.0, unit: 'mg/L' },
|
|
residualChlorine: { min: 0.1, max: 0.8, unit: 'mg/L' }
|
|
};
|
|
|
|
// 发送间隔(毫秒)
|
|
const SEND_INTERVAL = 3000;
|
|
|
|
// 生成随机水质数据
|
|
function generateWaterQualityData() {
|
|
const generateValue = (range) => {
|
|
const value = range.min + Math.random() * (range.max - range.min);
|
|
return Math.round(value * 100) / 100; // 保留2位小数
|
|
};
|
|
|
|
return {
|
|
temp: generateValue(DATA_RANGES.temp),
|
|
ph: generateValue(DATA_RANGES.ph),
|
|
conductivity: Math.round(generateValue(DATA_RANGES.conductivity)),
|
|
cod: generateValue(DATA_RANGES.cod),
|
|
ammoniaNitrogen: generateValue(DATA_RANGES.ammoniaNitrogen),
|
|
residualChlorine: generateValue(DATA_RANGES.residualChlorine),
|
|
timestamp: Date.now()
|
|
};
|
|
}
|
|
|
|
// 连接MQTT服务器
|
|
const client = mqtt.connect({
|
|
host: MQTT_CONFIG.host,
|
|
port: MQTT_CONFIG.port,
|
|
username: MQTT_CONFIG.username,
|
|
password: MQTT_CONFIG.password,
|
|
clientId: MQTT_CONFIG.clientId
|
|
});
|
|
|
|
// 连接成功
|
|
client.on('connect', () => {
|
|
console.log('========================================');
|
|
console.log(' 水质数据模拟器已连接');
|
|
console.log('========================================');
|
|
console.log(`MQTT服务器: mqtt://${MQTT_CONFIG.host}:${MQTT_CONFIG.port}`);
|
|
console.log(`发布主题: ${MQTT_CONFIG.topic}`);
|
|
console.log(`发送间隔: ${SEND_INTERVAL / 1000}秒`);
|
|
console.log('----------------------------------------');
|
|
console.log('按 Ctrl+C 停止发送');
|
|
console.log('========================================\n');
|
|
|
|
// 定时发送数据
|
|
let count = 1;
|
|
const interval = setInterval(() => {
|
|
const data = generateWaterQualityData();
|
|
const payload = JSON.stringify(data);
|
|
|
|
client.publish(MQTT_CONFIG.topic, payload, { qos: 0 }, (err) => {
|
|
if (err) {
|
|
console.error(`[发送失败] ${err.message}`);
|
|
} else {
|
|
console.log(`[第${count}次发送] ${new Date().toLocaleTimeString()}`);
|
|
console.log(` 温度: ${data.temp} °C`);
|
|
console.log(` pH值: ${data.ph}`);
|
|
console.log(` 电导率: ${data.conductivity} μS/cm`);
|
|
console.log(` COD: ${data.cod} mg/L`);
|
|
console.log(` 氨氮: ${data.ammoniaNitrogen} mg/L`);
|
|
console.log(` 余氯: ${data.residualChlorine} mg/L`);
|
|
console.log('---');
|
|
count++;
|
|
}
|
|
});
|
|
}, SEND_INTERVAL);
|
|
|
|
// 处理退出
|
|
process.on('SIGINT', () => {
|
|
clearInterval(interval);
|
|
client.end(() => {
|
|
console.log('\n模拟器已停止');
|
|
process.exit(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
// 连接错误
|
|
client.on('error', (err) => {
|
|
console.error('MQTT连接错误:', err.message);
|
|
console.error('请确保MQTT Broker正在运行 (node server.js)');
|
|
process.exit(1);
|
|
});
|
|
|
|
// 断开连接
|
|
client.on('close', () => {
|
|
console.log('MQTT连接已断开');
|
|
}); |