package sendMQTT; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import sendMQTT.HTTPUtils.ControlCommand; import set.Setsys; import user.Usrdell; import java.io.UnsupportedEncodingException; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; /** * 设备控制指令MQTT发送工具类 * 用于向设备发送控制指令(启动、停止、暂停、恢复、紧急停止等) */ public class ControlCommandSender { private static final String DEFAULT_HOST = "tcp://39.99.43.227:1883"; private static final String DEFAULT_CLIENT_ID_PREFIX = "control_"; private final String host; private final String clientId; /** * 构造函数 * @param host MQTT broker地址,例如 "tcp://39.99.43.227:1883" * @param clientId MQTT客户端ID */ public ControlCommandSender(String host, String clientId) { this.host = host != null ? host : DEFAULT_HOST; this.clientId = clientId != null ? clientId : (DEFAULT_CLIENT_ID_PREFIX + System.currentTimeMillis()); } /** * 使用默认配置创建发送器 * @return ControlCommandSender实例 */ public static ControlCommandSender createDefault() { return new ControlCommandSender(DEFAULT_HOST, DEFAULT_CLIENT_ID_PREFIX + System.currentTimeMillis()); } /** * 发送控制指令 * * @param msgId 消息唯一标识 * @param userId 用户ID * @param deviceId 设备编号 * @param command 控制命令:start(启动), stop(停止), pause(暂停), resume(恢复), emergency_stop(紧急停止) * @param value1 参数1(可选,Double类型) * @param value2 参数2(可选,String类型) * @param value3 参数3(可选,Integer类型) * @return 是否发送成功 * @throws MqttException MQTT发送异常 */ public boolean sendControlCommand(String msgId, String userId, String deviceId, String command, Double value1, String value2, Integer value3) throws MqttException { // 构建参数对象 ControlCommand.ControlParameters parameters = new ControlCommand.ControlParameters( value1, value2, value3 ); // 构建控制指令对象 long timestamp = System.currentTimeMillis(); ControlCommand controlCommand = new ControlCommand( msgId, timestamp, userId, deviceId, command, parameters ); // 转换为JSON字符串 String jsonString = toJsonString(controlCommand); if (jsonString == null) { throw new MqttException(new Exception("JSON序列化失败")); } // 发送MQTT消息 return sendMQTT(jsonString, userId, deviceId); } /** * 将ControlCommand对象转换为JSON字符串 */ private String toJsonString(ControlCommand command) { ObjectMapper objectMapper = new ObjectMapper(); try { return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(command); } catch (JsonProcessingException e) { e.printStackTrace(); return null; } } /** * 发送MQTT消息 * * @param messageJson JSON消息内容 * @param userId 用户ID * @param deviceId 设备编号 * @return 是否发送成功 * @throws MqttException MQTT发送异常 */ private boolean sendMQTT(String messageJson, String userId, String deviceId) throws MqttException { MqttClient client = null; try { // 构建主题:app/{user_id}/mower/{device_id}/control String topic = String.format("app/%s/mower/%s/control", userId, deviceId); // 创建MQTT连接选项 MqttConnectOptions options = new MqttConnectOptions(); options.setCleanSession(true); // 创建MQTT客户端并连接 client = new MqttClient(host, clientId); client.connect(options); // 创建消息并发送 MqttMessage message = new MqttMessage(); message.setPayload(messageJson.getBytes("UTF-8")); client.publish(topic, message); return true; } catch (UnsupportedEncodingException e) { throw new MqttException(e); } finally { // 断开连接 if (client != null && client.isConnected()) { try { client.disconnect(); client.close(); } catch (MqttException e) { // 忽略断开连接时的异常 } } } } static String msgId = "hxzkcontrol_hxzkcontrol_20151104" ; String userId=Usrdell.getUserEmail();//用户ID String deviceId=Setsys.getMowerIdValue();//设备ID private static double battery = 90.0; private static String token = "abcd123ds"; private static int type = 0; /** * 启动命令(start) * ●功能:开始执行预设的路径规划任务或从暂停状态继续运行 * ●应用场景:开始割草作业、继续被暂停的任务 * * @param userId 用户ID * @param deviceId 设备ID * @return 发送结果,true表示成功,false表示失败 */ public static boolean sendStartCommand(String userId, String deviceId) { try { ControlCommandSender sender = ControlCommandSender.createDefault(); boolean result = sender.sendControlCommand(msgId, userId, deviceId, "start", battery, token, type); return result; } catch (Exception e) { System.err.println("启动命令发送失败: " + e.getMessage()); e.printStackTrace(); return false; } } /** * 停止命令(stop) * ●功能:正常停止割草机运行,保存当前状态 * ●应用场景:完成作业后的正常停止、用户主动停止 * ●特点:平稳减速停止,记录停止位置 * * @param userId 用户ID * @param deviceId 设备ID * @return 发送结果,true表示成功,false表示失败 */ public static boolean sendStopCommand(String userId, String deviceId) { try { ControlCommandSender sender = ControlCommandSender.createDefault(); boolean result = sender.sendControlCommand(msgId, userId, deviceId, "stop", battery, token, type); return result; } catch (Exception e) { System.err.println("停止命令发送失败: " + e.getMessage()); e.printStackTrace(); return false; } } /** * 暂停命令(pause) * ●功能:临时暂停当前运行,保持设备就绪状态 * ●应用场景:临时检查、避让障碍物、用户临时中断 * ●特点:可快速恢复,无需重新初始化 * * @param userId 用户ID * @param deviceId 设备ID * @return 发送结果,true表示成功,false表示失败 */ public static boolean sendPauseCommand(String userId, String deviceId) { try { ControlCommandSender sender = ControlCommandSender.createDefault(); boolean result = sender.sendControlCommand(msgId, userId, deviceId, "pause", battery, token, type); return result; } catch (Exception e) { System.err.println("暂停命令发送失败: " + e.getMessage()); e.printStackTrace(); return false; } } /** * 恢复命令(resume) * ●功能:从暂停状态恢复之前的运行 * ●应用场景:暂停后继续作业 * ●特点:从暂停点继续执行,保持路径连续性 * * @param userId 用户ID * @param deviceId 设备ID * @return 发送结果,true表示成功,false表示失败 */ public static boolean sendResumeCommand(String userId, String deviceId) { try { ControlCommandSender sender = ControlCommandSender.createDefault(); boolean result = sender.sendControlCommand(msgId, userId, deviceId, "resume", battery, token, type); return result; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 紧急停止命令(emergency_stop) * ●功能:立即停止所有动作,切断动力输出 * ●应用场景:紧急情况、安全威胁、设备异常 * ●特点:最高优先级,需要手动复位才能重新启动 * * @param userId 用户ID * @param deviceId 设备ID * @return 发送结果,true表示成功,false表示失败 */ public static boolean sendEmergencyStopCommand(String userId, String deviceId) { try { ControlCommandSender sender = ControlCommandSender.createDefault(); boolean result = sender.sendControlCommand(msgId, userId, deviceId, "emergency_stop", battery, token, type); return result; } catch (Exception e) { System.err.println("紧急停止命令发送失败: " + e.getMessage()); e.printStackTrace(); return false; } } }