张世豪
5 小时以前 8d3989dff1164588d45dbb30506da1a6e1094005
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
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;
        }
    }
     
    
}