wjc
2023-08-21 0a18a8180bc6040c941b07df1be1f7b726b4c155
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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
package com.hdl.sdk.link.core.connect;
 
 
import android.text.TextUtils;
 
import com.hdl.sdk.link.common.config.TopicConstant;
import com.hdl.sdk.link.common.event.EventDispatcher;
import com.hdl.sdk.link.common.event.EventListener;
import com.hdl.sdk.link.common.exception.HDLLinkCode;
import com.hdl.sdk.link.common.exception.HDLLinkException;
import com.hdl.sdk.link.common.utils.LogUtils;
import com.hdl.sdk.link.core.bean.LinkRequest;
import com.hdl.sdk.link.core.bean.LinkResponse;
import com.hdl.sdk.link.core.bean.ModbusResponse;
import com.hdl.sdk.link.core.bean.ZigbeeResponse;
import com.hdl.sdk.link.core.bean.gateway.GatewayBean;
import com.hdl.sdk.link.core.callback.ModbusCallBack;
import com.hdl.sdk.link.core.callback.ZigbeeCallBack;
import com.hdl.sdk.link.core.config.HDLLinkConfig;
import com.hdl.sdk.link.gateway.HDLLinkLocalGateway;
 
/**
 * Created by hxb on 2021/12/8.
 * 原生通讯相关接口
 */
public class HDLModBusConnect {
 
    private static final String TAG = "HDLModbusConnect";
    private static HDLModBusConnect instance;
    /**
     * 内部用,主要是处理处理掉透传主题及link主题后,还原modbus原生数据及主题用
     */
    private final String allTopic = "/Modbus";
 
    /**
     * 返回当前实例,不存在就创建并同时注册监听事件
     *
     * @return
     */
    public static HDLModBusConnect getInstance() {
        if (null == instance) {
            instance = new HDLModBusConnect();
            instance.initEventListener();
        }
        return instance;
    }
 
    /**
     * 注册监听Zigbee所有原生主题及数据
     *
     * @param eventListener
     */
    public void registerListener(EventListener eventListener) {
        if (null == eventListener) {
            return;
        }
        EventDispatcher.getInstance().register(allTopic, eventListener);
    }
 
    /**
     * 移除监听Zigbee原生主题及数据
     *
     * @param eventListener
     */
    public void removeListener(EventListener eventListener) {
        if (null == eventListener) {
            return;
        }
        EventDispatcher.getInstance().remove(allTopic, eventListener);
    }
 
    /**
     * 初始化监听事件
     */
    private void initEventListener() {
        final EventListener eventListener = new EventListener() {
            @Override
            public void onMessage(Object msg) {
                try {
                    if (msg instanceof LinkResponse) {
                        LinkResponse linkResponse = (LinkResponse) msg;
                        if (linkResponse.getTopic() == null || !linkResponse.getTopic().contains("custom/native/inverter/up")) {
                            return;
                        }
                        byte[] data = linkResponse.getByteData();
                        ModbusResponse modbusResponse = new ModbusResponse();
                        int a=data[0]&0xff;
                        int b=data[1]&0xff;
                        String topic = "Modbus" + data[0] + data[1];
                        modbusResponse.setTopic(topic);
                        modbusResponse.setData(data);
                        String oid = null;
                        //是否是通过主网关透传主题
                        if (linkResponse.getTopic().contains("/slaveoid/")) {
                            oid = linkResponse.getTopic().split("/")[8];
                        } else {
                            oid = linkResponse.getTopic().split("/")[2];
                        }
                        modbusResponse.setOid(oid);
                        for (GatewayBean gatewayBean : HDLLinkLocalGateway.getInstance().getGatewayList()) {
                            if (oid.equals(gatewayBean.getGatewayId()) || oid.equals(gatewayBean.getDevice_mac()) || oid.equals(gatewayBean.getOid())) {
                                //上面的oid可能是网关id或者mac或者是oid,不管是哪个统一使用oid表示方式
                                modbusResponse.setOid(gatewayBean.getOid());
                                break;
                            }
                        }
 
                        EventDispatcher.getInstance().post(topic, modbusResponse);
                        //发布Zigbee原生主题及数据
//                        EventDispatcher.getInstance().post(allTopic, modbusResponse);
                    }
                } catch (Exception e) {
                    LogUtils.e(TAG, "LinkResponse转ModbusResponse异常:" + e.getMessage());
                }
            }
        };
        //注册直接通讯的主题,包括直接和主网关通讯或者直接和从网关通讯
        registerListener(String.format(TopicConstant.NATIVE_MODBUS_UP, "+"), eventListener);
        //registerListener(String.format(TopicConstant.NATIVE_MODBUS_DOWN_REPLY, "+"), eventListener);
        //registerListener(String.format(TopicConstant.NATIVE_ZIGBEE_UP_SLAVE, "+", "+"), eventListener);
    }
 
    /**
     * 发送原生数据
     *
     * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id
     * @param payload               发送数据
     * @param baseCallBack          结果回调
     */
    public void Send(String gatewayOidOrGatewayId, byte[] payload, final ModbusCallBack baseCallBack) {
        //如果本地有链接这个网关,则用本地连接
        GatewayBean gatewayBean = HDLLinkLocalGateway.getInstance().getGatewayByOidOrGatewayId(gatewayOidOrGatewayId);
        if (null == gatewayBean) {
            LogUtils.i("找不到网关,Oid是" + gatewayOidOrGatewayId);
            if (null != baseCallBack) {
                baseCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GATEWAY_NOT_EXIST));
            }
            return;
        }
 
        String tempTopic = String.format(TopicConstant.NATIVE_MODBUS_DOWN, gatewayOidOrGatewayId);
        LinkRequest request = new LinkRequest(tempTopic, payload, gatewayBean.getIsLocalEncrypt());
 
//        if ("true".equals(gatewayBean.getMaster())) {
        request.setCloudTopic(String.format(TopicConstant.NATIVE_MODBUS_DOWN, HDLLinkConfig.getInstance().getGatewayId()));
//        } else {
//            request.setCloudTopic(String.format(TopicConstant.NATIVE_MODBUS_DOWN_SLAVE, HDLLinkConfig.getInstance().getGatewayId(), gatewayOidOrGatewayId));
//        }
        request.setReplyTopic("Modbus" + payload[0] + payload[1]);
        long timeout = 2 * 1000;
 
        new HDLConnectHelper(timeout, 1, gatewayBean.getIp_address(), 8586, request, new HDLConnectHelper.HdlSocketListener() {
            @Override
            public void onSucceed(Object msg) {
                if (msg instanceof int[]) {
                    if (null != baseCallBack) {
                        baseCallBack.onSuccess((int[]) msg);
                    }
                } else {
                    LogUtils.e("发送Modbus回调对象类型非数组类型,类型是" + msg.getClass());
                }
            }
 
            @Override
            public void onFailure(HDLLinkCode hdlLinkCode) {
                if (null != baseCallBack) {
                    baseCallBack.onError(HDLLinkException.getErrorWithCode(hdlLinkCode));
                }
            }
        }, true).send();
    }
 
 
    /**
     * 发送原生透传命令数据
     *
     * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id
     * @param responeTopic          回复主题
     * @param payload               发送数据
     * @param zigbeeCallBack        结果回调
     */
    public void SendThrough(String gatewayOidOrGatewayId, String responeTopic, String payload, final ZigbeeCallBack zigbeeCallBack) {
//        //如果本地有链接这个网关,则用本地连接
//        GatewayBean gatewayBean = HDLLinkLocalGateway.getInstance().getGatewayByOidOrGatewayId(gatewayOidOrGatewayId);
//        if (null == gatewayBean) {
//            LogUtils.i("找不到网关,Oid是" + gatewayOidOrGatewayId);
//            if (null != zigbeeCallBack) {
//                zigbeeCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GATEWAY_NOT_EXIST));
//            }
//            return;
//        }
//        boolean isLocal = gatewayBean.getIsLocalGateway();
//        //如果是本地通讯
//        if (isLocal == true) {
//
//            String tempTopic = String.format("/user/%s/custom/native/zigbee/down", gatewayOidOrGatewayId);
//            String tempTopicReply = String.format("/user/%s/custom/native/zigbee/up", gatewayOidOrGatewayId);
//
//            final boolean[] isCallBack = {false};
//            //透传命令主题处理
//            final EventListener eventListener = new EventListener() {
//                @Override
//                public void onMessage(Object msg) {
//                    if (msg instanceof LinkResponse) {
//                        LinkResponse linkResponse = (LinkResponse) msg;
//                        //TODO 如果配置从网关的信息,通过主网关转达,这里oid要判断下
//                        String body = getZigbeeData(responeTopic, linkResponse);
//                        if (null != body) {
//                            isCallBack[0] = true;
//                            removeListener(tempTopicReply, this);
//                            if (null != zigbeeCallBack) {
//                                zigbeeCallBack.onSuccess(body);
//                            }
//                        }
//                    }
//                }
//            };
//            //注册监听
//            registerListener(tempTopicReply, eventListener);
//
//            //一定时间后还没有接收到数据,就回调失败
//            ScheduledExecutorService scheduledExecutorService = ThreadToolUtils.getInstance().newScheduledThreadPool(1);
//            scheduledExecutorService.schedule(new Runnable() {
//                @Override
//                public void run() {
//                    removeListener(tempTopicReply, eventListener);
//                    scheduledExecutorService.shutdownNow();
//                    if (!isCallBack[0]) {
//                        if (null != zigbeeCallBack) {
//                            zigbeeCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GET_Zigbee_FAILURE_ERROR));
//                        }
//                    }
//                }
//            }, 5, TimeUnit.SECONDS);
//
//            //本地发送
//            LinkRequest request = new LinkRequest(tempTopic, payload, gatewayBean.getIsLocalEncrypt());
//            new HDLConnectHelper(gatewayBean.getIp_address(), request,true).send();
//        } else {
//            //请求主题
//            String tempTopic = null;
//            //回复主题
//            String tempTopicReply = null;
//
//            //远程发送
//            if ("true".equals(gatewayBean.getMaster())) {
//                tempTopic = String.format("/user/%s/custom/native/zigbee/down", com.hdl.sdk.link.core.config.HDLLinkConfig.getInstance().getGatewayId());
//                tempTopicReply = String.format("/user/%s/custom/native/zigbee/up", com.hdl.sdk.link.core.config.HDLLinkConfig.getInstance().getGatewayId());
//            } else {
//                tempTopic = String.format("/user/%s/custom/native/zigbee/slaveoid/%s/down", com.hdl.sdk.link.core.config.HDLLinkConfig.getInstance().getGatewayId(), gatewayOidOrGatewayId);
//                tempTopicReply = String.format("/user/%s/custom/native/zigbee/slaveoid/%s/up", com.hdl.sdk.link.core.config.HDLLinkConfig.getInstance().getGatewayId(), "+");
//            }
//            //TODO 后续完善云端的发送接收方法
//        }
    }
 
 
    /**
     * 处理zigbee回复的数据
     *
     * @param responeTopic 回复主题
     * @param linkResponse 回复的透传数据
     */
    private static String getZigbeeData(String responeTopic, LinkResponse linkResponse) {
        //主题为空不处理
        if (TextUtils.isEmpty(responeTopic)) {
            return null;
        }
 
        String body = linkResponse.getData();
        int index = body.indexOf("{");
        //zigbee回复的数据前有主题,后面才是数据
        if (index <= 0)
            return null;
 
        String zigbeeTopic = body.substring(0, index).trim();
        //zigbee的负载数据
        String bodyData = body.substring(index);
 
        //不是当前请求的数据,不处理
        if (!zigbeeTopic.startsWith(responeTopic)) {
            return null;
        }
 
        return bodyData;
        //Zigbee以前的接收逻辑
//        HdlZbGatewayReceiveLogic.Current.ZigbeeOldReceiveLogic(reportTopic, bodyData, gatewayMac);
    }
 
    /**
     * 注册监听
     */
    static void registerListener(String responseTopic, EventListener eventListener) {
        if (!TextUtils.isEmpty(responseTopic)) {
            EventDispatcher.getInstance().register(responseTopic, eventListener);
        }
    }
 
    /**
     * 移除监听
     */
    static void removeListener(String responseTopic, EventListener eventListener) {
        if (!TextUtils.isEmpty(responseTopic)) {
            EventDispatcher.getInstance().remove(responseTopic, eventListener);
        }
    }
}