wjc
2025-03-12 e59cc427b89f752e50d243db96ddbad6a6afe9b8
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
package com.hdl.sdk.link.core.connect;
 
 
import android.text.TextUtils;
 
import com.hdl.link.error.HDLLinkCode;
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.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.gateway.GatewayBean;
import com.hdl.sdk.link.core.callback.ModbusCallBack;
import com.hdl.sdk.link.core.config.HDLLinkConfig;
import com.hdl.sdk.link.core.utils.ByteUtils;
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[] payload = linkResponse.getByteData();
                        ModbusResponse modbusResponse = new ModbusResponse();
                        String topic;
                        if (10 < payload.length) {
                            topic = String.format("Modbus %s", ByteUtils.encodeHexString(new byte[]{payload[0], payload[1], payload[6], payload[7], payload[8], payload[9]}));//序号+oid
                        } else {
                            topic = String.format("Modbus %s", ByteUtils.encodeHexString(new byte[]{payload[0], payload[1]}));
                        }
                        modbusResponse.setTopic(topic);
                        modbusResponse.setData(payload);
                        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) {
        Send(gatewayOidOrGatewayId, payload, 4, baseCallBack, false);
    }
 
    /**
     * 发送原生数据,子线程回调
     *
     * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id
     * @param payload               发送数据
     * @param baseCallBack          结果回调
     */
    public void asyncSend(String gatewayOidOrGatewayId, byte[] payload, final ModbusCallBack baseCallBack) {
        Send(gatewayOidOrGatewayId, payload, 4, baseCallBack, true);
    }
 
    /**
     * 发送原生数据
     *
     * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id
     * @param payload               发送数据
     * @param timeout               超时时间(s)
     * @param baseCallBack          结果回调
     */
    public void Send(String gatewayOidOrGatewayId, byte[] payload, int timeout, final ModbusCallBack baseCallBack, boolean useSubThread) {
        if (payload == null || payload.length == 0) {
            if (baseCallBack != null) {
                baseCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR));
                System.out.println("发送数据时负载数据是空的--->");
            }
            return;
        }
        //如果本地有链接这个网关,则用本地连接
        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.isLocalEncrypt());
 
        request.setCloudTopic(String.format(TopicConstant.NATIVE_MODBUS_DOWN, gatewayBean.getGatewayId()));
        if (10 < payload.length) {
            request.setReplyTopic(String.format("Modbus %s", ByteUtils.encodeHexString(new byte[]{payload[0], payload[1], payload[6], payload[7], payload[8], payload[9]})));//序号+oid
        } else {
            request.setReplyTopic(String.format("Modbus %s", ByteUtils.encodeHexString(new byte[]{payload[0], payload[1]})));
        }
        long awaitTime = timeout * 1000L;
 
        HDLConnectHelper hdlConnectHelper = new HDLConnectHelper(awaitTime, 2, gatewayBean.getIp_address(), 8586, request, new HDLConnectHelper.HdlSocketListener() {
            @Override
            public void onSucceed(Object msg) {
                if (msg instanceof ModbusResponse) {
                    if (null != baseCallBack) {
                        baseCallBack.onSuccess(((ModbusResponse) msg).getData());
                    }
                } else {
                    LogUtils.e("发送Modbus回调对象类型非数组类型,类型是" + msg.getClass());
                }
            }
 
            @Override
            public void onFailure(HDLLinkCode hdlLinkCode) {
                if (null != baseCallBack) {
                    baseCallBack.onError(HDLLinkException.getErrorWithCode(hdlLinkCode));
                }
            }
        }, true, gatewayBean.getDevice_mac(),true);
//        hdlConnectHelper.setUseSubThread(useSubThread);
        hdlConnectHelper.send();
    }
 
    /**
     * 注册监听
     */
    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);
        }
    }
}