relayController.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. const pool = require('../config/db');
  2. const { client } = require('../mqttClient');
  3. const logger = require('../logger');
  4. // 控制继电器状态
  5. const toggleRelay = async (req, res) => {
  6. const { state } = req.params; // 获取状态参数(on 或 off)
  7. const { roomId } = req.query; // 获取房间 ID
  8. logger.info(`尝试设置房间 ${roomId} 的继电器状态为 ${state}`);
  9. // 校验 state 参数
  10. if (state.toLowerCase() !== 'on' && state.toLowerCase() !== 'off') {
  11. logger.warn(`无效的继电器状态参数: ${state}`);
  12. return res.status(400).send('无效的状态参数,请使用 "on" 或 "off"');
  13. }
  14. // 校验 roomId 参数
  15. if (!roomId) {
  16. logger.warn('缺少房间ID参数');
  17. return res.status(400).send('房间 ID 不能为空');
  18. }
  19. try {
  20. // 查询房间的继电器设备
  21. const query = `
  22. SELECT device_id
  23. FROM devices
  24. WHERE room_id = ? AND status = 'online' AND device_id LIKE '%ESP32%'
  25. LIMIT 1
  26. `;
  27. const [results] = await pool.promise().query(query, [roomId]);
  28. if (results.length === 0) {
  29. logger.warn(`房间 ${roomId} 没有在线的继电器设备`);
  30. return res.status(404).send('该房间没有在线的继电器设备');
  31. }
  32. const deviceId = results[0].device_id;
  33. const relayTopic = `device/${deviceId}/relay/control`;
  34. if (!client.connected) {
  35. logger.error('MQTT客户端未连接');
  36. return res.status(500).send('MQTT 客户端未连接');
  37. }
  38. // 发布 MQTT 消息
  39. client.publish(relayTopic, state.toUpperCase(), (err) => {
  40. if (err) {
  41. logger.error('MQTT消息发送失败:', err);
  42. return res.status(500).send('发布消息失败: ' + err.message);
  43. }
  44. logger.info(`成功发送继电器控制命令: 房间=${roomId}, 状态=${state}`);
  45. res.send(`房间 ${roomId} 的继电器状态已设置为 ${state}`);
  46. });
  47. } catch (err) {
  48. logger.error('控制继电器失败:', err);
  49. res.status(500).send('控制继电器失败');
  50. }
  51. };
  52. // 下发继电器ID给人体存在传感器
  53. const sendRelayIdToSensor = async (req, res) => {
  54. const { roomId } = req.params;
  55. logger.info(`尝试为房间 ${roomId} 的人体传感器配置继电器ID`);
  56. try {
  57. // 查询房间的人体传感器和继电器设备
  58. const query = `
  59. SELECT
  60. (SELECT device_id FROM devices WHERE room_id = ? AND device_id LIKE '%24G-%' LIMIT 1) AS humanSensorDeviceId,
  61. (SELECT device_id FROM devices WHERE room_id = ? AND device_id LIKE '%ESP32%' LIMIT 1) AS relayDeviceId
  62. `;
  63. const [results] = await pool.promise().query(query, [roomId, roomId]);
  64. if (!results[0].humanSensorDeviceId) {
  65. logger.warn(`房间 ${roomId} 未绑定人体传感器模块`);
  66. return res.status(404).json({ success: false, message: '该房间未绑定人体传感器模块' });
  67. }
  68. if (!results[0].relayDeviceId) {
  69. logger.warn(`房间 ${roomId} 未绑定继电器模块`);
  70. return res.status(404).json({ success: false, message: '该房间未绑定继电器模块' });
  71. }
  72. const { humanSensorDeviceId, relayDeviceId } = results[0];
  73. const controlTopic = `device/${humanSensorDeviceId}/control`;
  74. // 发布 MQTT 消息
  75. client.publish(controlTopic, relayDeviceId, (err) => {
  76. if (err) {
  77. logger.error('MQTT消息发送失败:', err);
  78. return res.status(500).json({ success: false, message: 'MQTT 消息发布失败' });
  79. }
  80. logger.info(`成功配置继电器ID: 传感器=${humanSensorDeviceId}, 继电器=${relayDeviceId}`);
  81. res.status(200).json({
  82. success: true,
  83. message: `已将继电器 ${relayDeviceId} 配置给人体传感器模块`
  84. });
  85. });
  86. } catch (error) {
  87. logger.error('配置继电器ID失败:', error);
  88. res.status(500).json({ success: false, message: '处理人体传感器模块时出错' });
  89. }
  90. };
  91. module.exports = {
  92. toggleRelay,
  93. sendRelayIdToSensor,
  94. };