Merge remote-tracking branch 'origin/master'
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.amqp; |
| | | |
| | | import org.apache.commons.codec.binary.Base64; |
| | | import org.apache.qpid.jms.JmsConnection; |
| | | |
| | | import javax.crypto.Mac; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | import javax.jms.*; |
| | | import javax.naming.Context; |
| | | import javax.naming.InitialContext; |
| | | import java.util.Hashtable; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/2 17:18 |
| | | * ampq订é
客æ·ç«¯ |
| | | */ |
| | | public class AmqpClient { |
| | | |
| | | private final AmqpConnectionListener amqpConnectionListener = new AmqpConnectionListener(); |
| | | private final AmqpMessageListener amqpMessageListener = new AmqpMessageListener(); |
| | | |
| | | private IAmqpSubscriptionConfig config; |
| | | |
| | | public AmqpClient(IAmqpSubscriptionConfig config) { |
| | | this.config = config; |
| | | } |
| | | |
| | | /** |
| | | * å¯å¨ampq订é
客æ·ç«¯ |
| | | * |
| | | * @throws Exception |
| | | */ |
| | | public void execute() throws Exception { |
| | | for (int i = 0; i < config.getConnectionCount(); i++) { |
| | | long timeStamp = System.currentTimeMillis(); |
| | | //ç¾åæ¹æ³ï¼æ¯æhmacmd5ãhmacsha1åhmacsha256ã |
| | | String signMethod = "hmacsha1"; |
| | | |
| | | // userNameç»è£
æ¹æ³ï¼è¯·åè§AMQP客æ·ç«¯æ¥å
¥è¯´æææ¡£ã |
| | | String userName = config.getClientId() + "-" + i + "|authMode=aksign" |
| | | + ",signMethod=" + signMethod |
| | | + ",timestamp=" + timeStamp |
| | | + ",authId=" + config.getAccessKey() |
| | | + ",iotInstanceId=" + config.getIotInstanceId() |
| | | + ",consumerGroupId=" + config.getConsumerGroupId() |
| | | + "|"; |
| | | //计ç®ç¾åï¼passwordç»è£
æ¹æ³ï¼è¯·åè§AMQP客æ·ç«¯æ¥å
¥è¯´æææ¡£ã |
| | | String signContent = "authId=" + config.getAccessKey() + "×tamp=" + timeStamp; |
| | | String password = doSign(signContent, config.getAccessSecret(), signMethod); |
| | | String connectionUrl = "failover:(amqps://" + config.getHost() + ":5671?amqp.idleTimeout=80000)" |
| | | + "?failover.reconnectDelay=30"; |
| | | |
| | | Hashtable<String, String> hashtable = new Hashtable<>(); |
| | | hashtable.put("connectionfactory.SBCF", connectionUrl); |
| | | hashtable.put("queue.QUEUE", "default"); |
| | | hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory"); |
| | | Context context = new InitialContext(hashtable); |
| | | ConnectionFactory cf = (ConnectionFactory) context.lookup("SBCF"); |
| | | Destination queue = (Destination) context.lookup("QUEUE"); |
| | | // åå»ºè¿æ¥ã |
| | | Connection connection = cf.createConnection(userName, password); |
| | | // connections.add(connection); |
| | | |
| | | ((JmsConnection) connection).addConnectionListener(amqpConnectionListener); |
| | | // å建ä¼è¯ã |
| | | // Session.CLIENT_ACKNOWLEDGE: æ¶å°æ¶æ¯åï¼éè¦æå¨è°ç¨message.acknowledge()ã |
| | | // Session.AUTO_ACKNOWLEDGE: SDKèªå¨ACKï¼æ¨èï¼ã |
| | | Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); |
| | | |
| | | connection.start(); |
| | | // å建Receiverè¿æ¥ã |
| | | MessageConsumer consumer = session.createConsumer(queue); |
| | | consumer.setMessageListener(amqpMessageListener); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ç¾åæ ¡éª |
| | | */ |
| | | public String doSign(String toSignString, String secret, String signMethod) throws Exception { |
| | | SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), signMethod); |
| | | Mac mac = Mac.getInstance(signMethod); |
| | | mac.init(signingKey); |
| | | byte[] rawHmac = mac.doFinal(toSignString.getBytes()); |
| | | return Base64.encodeBase64String(rawHmac); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.amqp; |
| | | |
| | | import org.apache.qpid.jms.JmsConnectionListener; |
| | | import org.apache.qpid.jms.message.JmsInboundMessageDispatch; |
| | | |
| | | import javax.jms.MessageConsumer; |
| | | import javax.jms.MessageProducer; |
| | | import javax.jms.Session; |
| | | import java.net.URI; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/2 17:31 |
| | | */ |
| | | public class AmqpConnectionListener implements JmsConnectionListener { |
| | | @Override |
| | | public void onConnectionEstablished(URI uri) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onConnectionFailure(Throwable throwable) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onConnectionInterrupted(URI uri) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onConnectionRestored(URI uri) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onInboundMessage(JmsInboundMessageDispatch jmsInboundMessageDispatch) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onSessionClosed(Session session, Throwable throwable) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onConsumerClosed(MessageConsumer messageConsumer, Throwable throwable) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onProducerClosed(MessageProducer messageProducer, Throwable throwable) { |
| | | |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.amqp; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.report.*; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonReportMessage; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5C3ReportEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightReportEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5OrderEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.FrameUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import javax.jms.Message; |
| | | import javax.jms.MessageListener; |
| | | import java.util.Map; |
| | | import java.util.concurrent.*; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/2 17:33 |
| | | * å¤çamqp订é
æ¶æ¯ |
| | | */ |
| | | @Slf4j |
| | | public class AmqpMessageListener implements MessageListener { |
| | | |
| | | protected final static ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor( |
| | | Runtime.getRuntime().availableProcessors(), |
| | | Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS, |
| | | new LinkedBlockingQueue<>(50000), new NameTreadFactory()); |
| | | |
| | | static class NameTreadFactory implements ThreadFactory { |
| | | |
| | | private final AtomicInteger mThreadNum = new AtomicInteger(1); |
| | | |
| | | @Override |
| | | public Thread newThread(Runnable r) { |
| | | return new Thread(r, "ampq-msg-thread-" + mThreadNum.getAndIncrement()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void onMessage(Message message) { |
| | | EXECUTOR_SERVICE.submit(() -> processMessage(message)); |
| | | } |
| | | |
| | | /** |
| | | * å¨è¿éå¤çæ¨æ¶å°æ¶æ¯åçå
·ä½ä¸å¡é»è¾ã |
| | | */ |
| | | private void processMessage(Message message) { |
| | | try { |
| | | |
| | | byte[] body = message.getBody(byte[].class); |
| | | String content = new String(body); |
| | | Map map = JSON.parseObject(content, Map.class); |
| | | String topic = message.getStringProperty("topic"); |
| | | String messageId = message.getStringProperty("messageId"); |
| | | |
| | | // log.info("æ¶å°è®¢é
" + topic + "," + messageId); |
| | | // log.info(content); |
| | | |
| | | if (null != map.get("status")) { |
| | | // ä¸ä¸çº¿ä¸æ¥å¤ç |
| | | } else { |
| | | // è®¾å¤æ°æ®ä¸æ¥ |
| | | CommonReportMessage commonReportMessage = JSON.parseObject(content, CommonReportMessage.class); |
| | | |
| | | CommonFrame connectFrame = FrameUtils.transformMessageToFrame(commonReportMessage.getItems().getParams().getValue()); |
| | | |
| | | processTask(commonReportMessage.getProductKey(), commonReportMessage.getDeviceName(), connectFrame); |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¤çä»»å¡ |
| | | * |
| | | * @param productKey 产åç |
| | | * @param deviceName 产ååç§° |
| | | * @param frame 䏿¥å¸§ |
| | | */ |
| | | private void processTask(String productKey, String deviceName, CommonFrame frame) { |
| | | if (frame == null) { |
| | | return; |
| | | } |
| | | log.info("å¤ç订é
"); |
| | | log.info(frame.toString()); |
| | | if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_LIGHT_DATA.getCode())) { |
| | | // åç¯æ°æ®ä¸æ¥å¤ç |
| | | lightDataReportAnalysis(productKey, deviceName, frame); |
| | | } else if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_C3_DATA.getCode())) { |
| | | // C3å
çµæ¡©ä¸æ¥å¤ç |
| | | c3ChargingReportAnalysis(productKey, deviceName, frame); |
| | | } else if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_ATMOSPHERE_DATA.getCode())) { |
| | | // å¤§æ°æ°æ®æä»¤ä¸æ¥ |
| | | atmosphereAnalysis(productKey, deviceName, frame); |
| | | } |
| | | } |
| | | |
| | | private void c3ChargingReportAnalysis(String productKey, String deviceName, CommonFrame frame) { |
| | | String functionCode = frame.getPayload().substring(2, 4); |
| | | if (A5C3ReportEnum.NETWORK_REQUEST.getCode().equals(functionCode)) { |
| | | A5C3CommonReportInnerFrame netRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload()); |
| | | } else if (A5C3ReportEnum.QR_CODE_REQUEST.getCode().equals(functionCode)) { |
| | | A5C3CommonReportInnerFrame codeRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload()); |
| | | } else if (A5C3ReportEnum.HEART_BEAT.getCode().equals(functionCode)) { |
| | | A5C3HeartbeatReportInnerFrame heartbeatReportInnerFrame = new A5C3HeartbeatReportInnerFrame().transformFrame(frame.getPayload()); |
| | | } else if (A5C3ReportEnum.CHARGE_COMPLETE.getCode().equals(functionCode)) { |
| | | A5C3CommonReportInnerFrame completeRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload()); |
| | | |
| | | } else if (A5C3ReportEnum.CHARGE_STOP.getCode().equals(functionCode)) { |
| | | A5C3CommonReportInnerFrame stopRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload()); |
| | | |
| | | } else if (A5C3ReportEnum.ERROR_CODE.getCode().equals(functionCode)) { |
| | | A5C3ErrorCodeReportInnerFrame errorCodeRequestFrame = new A5C3ErrorCodeReportInnerFrame().transformFrame(frame.getPayload()); |
| | | |
| | | } |
| | | } |
| | | |
| | | private void atmosphereAnalysis(String productKey, String deviceName, CommonFrame frame) { |
| | | A5AtmosphereHeartbeatReportInnerFrame transformFrame = new A5AtmosphereHeartbeatReportInnerFrame().transformFrame(frame.getPayload()); |
| | | // log.info("大æ°å¿è·³ä¸æ¥"); |
| | | // log.info(transformFrame.toString()); |
| | | } |
| | | |
| | | private void lightDataReportAnalysis(String productKey, String deviceName, CommonFrame frame) { |
| | | String functionCode = frame.getPayload().substring(2, 4); |
| | | if (A5LightReportEnum.HeartBeat_Data.getCode().equals(functionCode)) { |
| | | // log.info("å¿è·³ç¸åº"); |
| | | A5LightHeartbeatReportInnerFrame heartbeatReportInnerFrame = new A5LightHeartbeatReportInnerFrame().transformFrame(frame.getPayload()); |
| | | // log.info(heartbeatReportInnerFrame.toString()); |
| | | } else if (A5LightReportEnum.Time_Synchronized.getCode().equals(functionCode)) { |
| | | // log.info("è¯·æ±æ¶é´åæ¥"); |
| | | A5LightTimeSyncReportInnerFrame syncRespInnerFrame = new A5LightTimeSyncReportInnerFrame().transformFrame(frame.getPayload()); |
| | | // log.info(syncRespInnerFrame.toString()); |
| | | } else if (A5LightReportEnum.Error_Code.getCode().equals(functionCode)) { |
| | | // log.info("æ
éç 䏿¥"); |
| | | A5LightErrorCodeReportInnerFrame codeRespInnerFrame = new A5LightErrorCodeReportInnerFrame().transformFrame(frame.getPayload()); |
| | | // log.info(codeRespInnerFrame.toString()); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.amqp; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/2 16:24 |
| | | * amqpæå¡å¨è®¢é
éè¦çåæ° https://help.aliyun.com/document_detail/143601.html |
| | | */ |
| | | public interface IAmqpSubscriptionConfig { |
| | | |
| | | /** |
| | | * ç»å½ç©èç½å¹³å°æ§å¶å°ï¼å°é¼ æ ç§»è³è´¦å·å¤´åä¸ï¼ç¶ååå»AccessKey管çï¼è·åAccessKey IDåAccessKey Secretã |
| | | * |
| | | * @return AccessKey |
| | | */ |
| | | String getAccessKey(); |
| | | |
| | | /** |
| | | * ç»å½ç©èç½å¹³å°æ§å¶å°ï¼å°é¼ æ ç§»è³è´¦å·å¤´åä¸ï¼ç¶ååå»AccessKey管çï¼è·åAccessKey IDåAccessKey Secretã |
| | | * |
| | | * @return accessSecret |
| | | */ |
| | | String getAccessSecret(); |
| | | |
| | | /** |
| | | * ç»å½ç©èç½å¹³å°æ§å¶å°ï¼å¨å¯¹åºå®ä¾çè§å弿 > æå¡ç«¯è®¢é
> æ¶è´¹ç»å表æ¥çæ¨çæ¶è´¹ç»IDã |
| | | * |
| | | * @return æ¶è´¹ç»IDã |
| | | */ |
| | | String getConsumerGroupId(); |
| | | |
| | | /** |
| | | * å®ä¾IDãè·åIDæ¹æ³ï¼è¯·åè§å¦ä½è·åå®ä¾IDï¼ã |
| | | * æ¨å¯ç»å½ç©èç½å¹³å°æ§å¶å°ï¼æ¾å°å¯¹åºçå®ä¾ï¼åå»å®ä¾ï¼è¿å
¥å®ä¾è¯¦æ
页颿¥çå®ä¾IDã |
| | | * |
| | | * @return å®ä¾ID |
| | | */ |
| | | String getIotInstanceId(); |
| | | |
| | | /** |
| | | * 表示客æ·ç«¯IDï¼å»ºè®®ä½¿ç¨æ¨çAMQP客æ·ç«¯æå¨æå¡å¨UUIDãMACå°åãIPçå¯ä¸æ è¯ãé¿åº¦ä¸å¯è¶
è¿64个å符ã |
| | | * |
| | | * @return 客æ·ç«¯ID |
| | | */ |
| | | String getClientId(); |
| | | |
| | | /** |
| | | * å¯å¨AMQP客æ·ç«¯çè¿æ¥æ°ï¼æå¤§ä¸è¶
è¿64个ãç¨äºå®æ¶æ¶æ¯æ¨éçæ©å®¹ã |
| | | * æ¶è´¹ç»è¯¦æ
页é¢ä¼ä»¥${clientId}+"-"+æ°åå½¢å¼ï¼æ¾ç¤ºè¿æ¥ç客æ·ç«¯ãå
¶ä¸æ°åæå°å¼ä¸º0ã |
| | | * |
| | | * @return è¿æ¥æ° |
| | | */ |
| | | Integer getConnectionCount(); |
| | | |
| | | /** |
| | | * AMQPæ¥å
¥ååã |
| | | * ${YourHost}详ç»è¯´æï¼è¯·åè§æ¥çå®ä¾ç»ç«¯èç¹ã |
| | | * |
| | | * @return AMQPæ¥å
¥åå |
| | | */ |
| | | String getHost(); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.amqp; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.PostConstruct; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/2 17:45 |
| | | */ |
| | | @Component |
| | | @AllArgsConstructor |
| | | public class InitAmqpListener { |
| | | |
| | | private final MqttMainBoardConfig mqttMainBoardConfig; |
| | | |
| | | @PostConstruct |
| | | public void initListener() throws Exception { |
| | | new AmqpClient( |
| | | mqttMainBoardConfig |
| | | ).execute(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.amqp; |
| | | |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/2 17:02 |
| | | * iot产åé
置类 |
| | | */ |
| | | @Configuration |
| | | public class MqttMainBoardConfig implements IAmqpSubscriptionConfig { |
| | | |
| | | public final static String ACCESS_KEY = "LTAI4G27Af8MZEF55phdMQ4y"; |
| | | public final static String ACCESS_SECRET = "KUc2yOtr7TRB4FuF5Wr0dWeTblbEuh"; |
| | | |
| | | @Override |
| | | public String getAccessKey() { |
| | | return ACCESS_KEY; |
| | | } |
| | | |
| | | @Override |
| | | public String getAccessSecret() { |
| | | return ACCESS_SECRET; |
| | | } |
| | | |
| | | @Override |
| | | public String getConsumerGroupId() { |
| | | // return "oOS84YAW41j6S3za2eIk000100"; |
| | | return "vKqsPWhrUiEXDI0WEGA9000100"; |
| | | } |
| | | |
| | | /** |
| | | * æ§çå
Œ
±å®ä¾åºå䏿¾ç¤ºå
·ä½IDå¼ï¼ |
| | | * 使ç¨ç©èç½å¹³å°çäºç«¯SDKè°ç¨APIæ¶ï¼æ éä¼ å
¥å®ä¾IDï¼IotInstanceIdï¼ï¼è¯·å é¤IotInstanceIdç¸å
³ç请æ±ä»£ç ã |
| | | * æ¥å
¥è®¾å¤åAMQP客æ·ç«¯æ¶ï¼éä¼ å
¥ç©ºå¼ï¼ä¾å¦iotInstanceId = ""ã |
| | | */ |
| | | @Override |
| | | public String getIotInstanceId() { |
| | | return ""; |
| | | } |
| | | |
| | | @Override |
| | | public String getClientId() { |
| | | return "MQTT_MAIN_BOARD_CLIENT"; |
| | | } |
| | | |
| | | @Override |
| | | public Integer getConnectionCount() { |
| | | return 1; |
| | | } |
| | | |
| | | @Override |
| | | public String getHost() { |
| | | return "1371426293786326.iot-amqp.cn-shanghai.aliyuncs.com"; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A1OrderEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.FunctionCodeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 13:54 |
| | | * A1 åè½å°è£
ç帧 |
| | | */ |
| | | public class A1Frame extends BaseRequestFrame implements IRequestFrame { |
| | | |
| | | private String orderType; |
| | | private String payloadLength; |
| | | private String payload; |
| | | |
| | | public A1Frame(String orderType, IRequestInnerFrame innerFrame) { |
| | | this.orderType = orderType; |
| | | this.payloadLength = SupplementUtils.suppleZero(Integer.toHexString((innerFrame.getEncodeFrame().length() / 2)).toUpperCase(), 4); |
| | | this.payload = innerFrame.getEncodeFrame(); |
| | | } |
| | | |
| | | @Override |
| | | public String getConnectType() { |
| | | return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode(); |
| | | } |
| | | |
| | | @Override |
| | | public String getFunctionCode() { |
| | | return FunctionCodeEnum.MAIN_BOARD_CONFIG.getCode(); |
| | | } |
| | | |
| | | @Override |
| | | public String getOrderType() { |
| | | return orderType; |
| | | } |
| | | |
| | | @Override |
| | | public String getPayloadLength() { |
| | | return payloadLength; |
| | | } |
| | | |
| | | @Override |
| | | public String getPayload() { |
| | | return payload; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.FunctionCodeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 13:54 |
| | | * A1 åè½å°è£
ç帧 |
| | | */ |
| | | public class A2Frame extends BaseRequestFrame implements IRequestFrame { |
| | | |
| | | private String orderType; |
| | | private String payloadLength; |
| | | private String payload; |
| | | |
| | | public A2Frame(String orderType, IRequestInnerFrame innerFrame) { |
| | | this.orderType = orderType; |
| | | this.payloadLength = SupplementUtils.suppleZero(Integer.toHexString((innerFrame.getEncodeFrame().length() / 2)).toUpperCase(), 4); |
| | | this.payload = innerFrame.getEncodeFrame(); |
| | | } |
| | | |
| | | @Override |
| | | public String getConnectType() { |
| | | return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode(); |
| | | } |
| | | |
| | | @Override |
| | | public String getFunctionCode() { |
| | | return FunctionCodeEnum.MAIN_BOARD_CONTROL.getCode(); |
| | | } |
| | | |
| | | @Override |
| | | public String getOrderType() { |
| | | return orderType; |
| | | } |
| | | |
| | | @Override |
| | | public String getPayloadLength() { |
| | | return payloadLength; |
| | | } |
| | | |
| | | @Override |
| | | public String getPayload() { |
| | | return payload; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5OrderEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.FunctionCodeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A1OrderEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 13:54 |
| | | * A5 åè½å°è£
ç帧 |
| | | */ |
| | | public class A5Frame extends BaseRequestFrame { |
| | | |
| | | private String orderType; |
| | | private String payloadLength; |
| | | private String payload; |
| | | |
| | | public A5Frame(String orderType, IRequestInnerFrame innerFrame) { |
| | | this.orderType = orderType; |
| | | this.payloadLength = SupplementUtils.suppleZero(Integer.toHexString((innerFrame.getEncodeFrame().length() / 2)).toUpperCase(), 4); |
| | | this.payload = innerFrame.getEncodeFrame(); |
| | | } |
| | | |
| | | @Override |
| | | public String getConnectType() { |
| | | return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode(); |
| | | } |
| | | |
| | | @Override |
| | | public String getFunctionCode() { |
| | | return FunctionCodeEnum.DATA_TRANSPORT_DATA.getCode(); |
| | | } |
| | | |
| | | @Override |
| | | public String getOrderType() { |
| | | return orderType; |
| | | } |
| | | |
| | | @Override |
| | | public String getPayloadLength() { |
| | | return payloadLength; |
| | | } |
| | | |
| | | @Override |
| | | public String getPayload() { |
| | | return payload; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.FrameUtils; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 15:06 |
| | | */ |
| | | public abstract class BaseRequestFrame implements IRequestFrame { |
| | | |
| | | @Override |
| | | public String getEncodeFrame() { |
| | | StringBuilder build = new StringBuilder(); |
| | | String tmp = build.append(getFunctionCode()).append(getOrderType()).append(getPayloadLength()).append(getPayload()).toString().toUpperCase(); |
| | | String crc32 = CRC32Utils.getCRC32(tmp); |
| | | String frame = getConnectType() + tmp + crc32; |
| | | return FrameUtils.encodeReportMessage(frame); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.FunctionCodeEnum; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 17:02 |
| | | * æå»ºä¸ä¸ªè¯·æ±å¸§ |
| | | */ |
| | | public class FrameBuilder { |
| | | |
| | | private IRequestFrame iRequestFrame; |
| | | private IRequestInnerFrame innerFrame; |
| | | |
| | | private String functionCode; |
| | | private String orderType; |
| | | |
| | | private FrameBuilder(String functionCode) { |
| | | this.functionCode = functionCode; |
| | | } |
| | | |
| | | public static FrameBuilder builderA1() { |
| | | return new FrameBuilder(FunctionCodeEnum.MAIN_BOARD_CONFIG.getCode()); |
| | | } |
| | | public static FrameBuilder builderA2() { |
| | | return new FrameBuilder(FunctionCodeEnum.MAIN_BOARD_CONTROL.getCode()); |
| | | } |
| | | |
| | | public static FrameBuilder builderA5() { |
| | | return new FrameBuilder(FunctionCodeEnum.DATA_TRANSPORT_DATA.getCode()); |
| | | } |
| | | |
| | | public FrameBuilder orderType(String orderType) { |
| | | this.orderType = orderType; |
| | | return this; |
| | | } |
| | | |
| | | public FrameBuilder innerFrame(IRequestInnerFrame innerFrame) { |
| | | this.innerFrame = innerFrame; |
| | | return this; |
| | | } |
| | | |
| | | public IRequestFrame build() { |
| | | if (orderType == null || innerFrame == null) { |
| | | throw new RuntimeException("åæ°ä¸è½ä¸ºç©º"); |
| | | } |
| | | if (FunctionCodeEnum.MAIN_BOARD_CONFIG.getCode().equals(functionCode)) { |
| | | iRequestFrame = new A1Frame(orderType, innerFrame); |
| | | } else if (FunctionCodeEnum.MAIN_BOARD_CONTROL.getCode().equals(functionCode)) { |
| | | iRequestFrame = new A2Frame(orderType, innerFrame); |
| | | } else if (FunctionCodeEnum.DATA_TRANSPORT_DATA.getCode().equals(functionCode)) { |
| | | iRequestFrame = new A5Frame(orderType, innerFrame); |
| | | } else { |
| | | throw new RuntimeException("æ¾ä¸å°ç¬¦åæ¡ä»¶ç请æ±å¸§"); |
| | | } |
| | | return iRequestFrame; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 13:47 |
| | | * æ»ä½å¸§ |
| | | */ |
| | | public interface IRequestFrame { |
| | | |
| | | /** |
| | | * è·åå¾
åéçç¼ç 帧 |
| | | * |
| | | * @return ç¼ç åç帧 |
| | | */ |
| | | String getEncodeFrame(); |
| | | |
| | | /** |
| | | * è·åè¿æ¥ç±»å {{@link com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum}} |
| | | * |
| | | * @return è¿æ¥ç±»å |
| | | */ |
| | | String getConnectType(); |
| | | |
| | | /** |
| | | * è·ååè½ç ï¼A1-A5 |
| | | * |
| | | * @return åè½ç |
| | | */ |
| | | String getFunctionCode(); |
| | | |
| | | /** |
| | | * è·åå½ä»¤ç ï¼æ¯ä¸ªåè½é½æä¸åå½ä»¤ |
| | | * |
| | | * @return å½ä»¤ç |
| | | */ |
| | | String getOrderType(); |
| | | |
| | | /** |
| | | * è´è·é¿åº¦ |
| | | * |
| | | * @return è´è·é¿åº¦ |
| | | */ |
| | | String getPayloadLength(); |
| | | |
| | | /** |
| | | * è·åè´è· |
| | | * |
| | | * @return è´è· |
| | | */ |
| | | String getPayload(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner; |
| | | |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 17:40 |
| | | * å
é¨å¸§ ååºå®ä½ç±» ææååºé½è¦ç»§æ¿å® |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | @ToString |
| | | public abstract class BaseResponseInnerFrame<T> implements IResponseInnerFrame<T> { |
| | | /** |
| | | * è¿æ¥ç±»å 1 |
| | | */ |
| | | protected String connectType; |
| | | /** |
| | | * åè½ç 1 |
| | | */ |
| | | protected String functionCode; |
| | | /** |
| | | * è´è·é¿åº¦ 2 |
| | | */ |
| | | protected String payloadLength; |
| | | /** |
| | | * CRCæ ¡éª 4 |
| | | */ |
| | | private String crc32; |
| | | /** |
| | | * æ¯å¦éè¿CRCæ ¡éª |
| | | */ |
| | | private boolean isValidate; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 13:49 |
| | | * è´è·å¸§ |
| | | */ |
| | | public interface IRequestInnerFrame { |
| | | /** |
| | | * è·åå¾
åéçç¼ç 帧 |
| | | * |
| | | * @return ç¼ç åç帧 |
| | | */ |
| | | String getEncodeFrame(); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 13:49 |
| | | * å
æ |
| | | */ |
| | | public interface IResponseInnerFrame<T> { |
| | | /** |
| | | * 转å为å
·ä½çå
é¨å¸§å®ä½ç±» |
| | | * @param hex 设å¤è¿åç æ»ä½å¸§è´è·payload |
| | | * @return è§£ç åçå®ä½ç±» |
| | | */ |
| | | T transformFrame(String hex); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.report; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 18:20 |
| | | * A5-84-01 |
| | | * 大æ°å¿è·³å
åºç |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5AtmosphereHeartbeatReportInnerFrame extends BaseResponseInnerFrame<A5AtmosphereHeartbeatReportInnerFrame> { |
| | | |
| | | // ç®æ å°å 2 |
| | | private String destinationAddress; |
| | | // å¿è·³å
æ°æ® 58 |
| | | private HeartBeatDataPackage heartBeatDataPackage; |
| | | |
| | | private String originFrame; |
| | | |
| | | @Override |
| | | public A5AtmosphereHeartbeatReportInnerFrame transformFrame(String hex) { |
| | | // é¿åº¦ä¸ä¸è´æ¶ï¼è¿ånull |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 12)); |
| | | |
| | | String heartBeatData = hex.substring(12, 76); |
| | | HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage(); |
| | | heartBeatDataPackage.transformFrame(heartBeatData); |
| | | setHeartBeatDataPackage(heartBeatDataPackage); |
| | | |
| | | setCrc32(hex.substring(hex.length() - 8)); |
| | | // æ ¡éªCRC32 |
| | | String frame = hex.substring(2, hex.length() - 8); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | |
| | | @Data |
| | | public static class HeartBeatDataPackage implements IResponseInnerFrame<HeartBeatDataPackage> { |
| | | // 设å¤åå· 2 |
| | | private String deviceType; |
| | | // 模åé¢çç¶ææ å¿ 1 |
| | | private String moduleWarmUpStatusFlag; |
| | | // æ¸©åº¦å¼ |
| | | private Double temperature; |
| | | // æ¹¿åº¦å¼ |
| | | private Double humidity; |
| | | // é£é |
| | | private Double windSpeed; |
| | | // é£å |
| | | private Double windDirection; |
| | | // 大æ°å |
| | | private Integer pressure; |
| | | // å
强 |
| | | private Integer lightIntensity; |
| | | // åªé³ |
| | | private Integer noise; |
| | | // PM2.5 |
| | | private Integer pm25; |
| | | // PM10 |
| | | private Integer pm10; |
| | | // æ»æ¬æµ®é¢ç²ç©ï¼TSPï¼ |
| | | private Integer tsp; |
| | | // SO2äºæ°§åç¡«/ç²éç¸å¯¹å¼ |
| | | private Integer so2; |
| | | private Integer ech2o; |
| | | // NO2äºæ°§åæ°®/TVOC |
| | | private Integer no2; |
| | | private Integer tvoc; |
| | | // CO䏿°§å碳 /äºæ°§å碳 |
| | | private Integer co; |
| | | private Integer co2; |
| | | // O3èæ°§ |
| | | private Integer o3; |
| | | // Fæ°åç© |
| | | private Integer fluoride; |
| | | |
| | | @Override |
| | | public HeartBeatDataPackage transformFrame(String hex) { |
| | | if (hex.length() != 64) { |
| | | return null; |
| | | } |
| | | Integer type = 0; |
| | | this.deviceType = hex.substring(0, 4); |
| | | if(this.deviceType.equals(DeviceType.SENSOR_V1.getType())) { |
| | | type = 1; |
| | | } |
| | | this.moduleWarmUpStatusFlag = hex.substring(4, 6); |
| | | this.temperature = Double.parseDouble( |
| | | parseVal(hex,6,8) |
| | | + "." |
| | | + parseVal(hex,8,10) |
| | | ); |
| | | this.humidity = Double.parseDouble( |
| | | parseVal(hex,10,12) |
| | | + "." |
| | | + parseVal(hex,12,14) |
| | | ); |
| | | this.windSpeed = parseVal(hex,14,18) * .1; |
| | | this.windDirection = parseVal(hex,18,22) * .1; |
| | | this.pressure = parseVal(hex,22,26); |
| | | this.lightIntensity = parseVal(hex,26,32); |
| | | this.noise = parseVal(hex,32, 36); |
| | | this.pm25 = parseVal(hex,36, 40); |
| | | this.pm10 = parseVal(hex,40,44); |
| | | this.tsp = parseVal(hex,44,48); |
| | | |
| | | /** |
| | | * 以ä¸åºåçæ¬ |
| | | */ |
| | | if(type.equals(1)) { |
| | | this.ech2o = parseVal(hex,48, 52); |
| | | this.tvoc = parseVal(hex,52, 56); |
| | | this.co2 = parseVal(hex,56, 60); |
| | | } else { |
| | | this.so2 = parseVal(hex,48, 52); |
| | | this.ech2o = parseVal(hex,48, 52); |
| | | this.tvoc = parseVal(hex,52, 56); |
| | | this.no2 = parseVal(hex,52, 56); |
| | | this.co = parseVal(hex,56, 60); |
| | | this.co2 = parseVal(hex,56, 60); |
| | | } |
| | | |
| | | this.o3 = parseVal(hex,60, 62); |
| | | this.fluoride = parseVal(hex,62, 64); |
| | | |
| | | return this; |
| | | } |
| | | |
| | | private Integer parseVal (String frame, int start, int end) { |
| | | return Integer.parseInt(frame.substring(start,end),16); |
| | | } |
| | | } |
| | | |
| | | public enum DeviceType { |
| | | |
| | | SENSOR_V1("0101"); |
| | | |
| | | private String type; |
| | | |
| | | DeviceType(String type) { |
| | | this.type = type; |
| | | } |
| | | |
| | | public String getType() { |
| | | return type; |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.report; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 18:20 |
| | | * A5-82-40/41/43/44 |
| | | * c3å
çµæ¡© 䏿¥ ç½ç»è¯·æ±/äºç»´ç 请æ±/䏿¥å
çµç»æ/䏿¥å
çµä¸æ |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5C3CommonReportInnerFrame extends BaseResponseInnerFrame<A5C3CommonReportInnerFrame> { |
| | | |
| | | // ç®æ å°å 4 |
| | | private String destinationAddress; |
| | | |
| | | @Override |
| | | public A5C3CommonReportInnerFrame transformFrame(String hex) { |
| | | // é¿åº¦ä¸ä¸è´æ¶ï¼è¿ånull |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 16)); |
| | | |
| | | setCrc32(hex.substring(hex.length() - 8)); |
| | | // æ ¡éªCRC32 |
| | | String frame = hex.substring(2, hex.length() - 8); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.report; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 14:46 |
| | | * A5-81-42 |
| | | * åç¯ä¸æ¥ampq æ
éç |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5C3ErrorCodeReportInnerFrame extends BaseResponseInnerFrame<A5C3ErrorCodeReportInnerFrame> { |
| | | |
| | | /** |
| | | * ç®æ å°å 2 |
| | | */ |
| | | private String destinationAddress; |
| | | /** |
| | | * æ
éç |
| | | */ |
| | | private String errorCode; |
| | | |
| | | @Override |
| | | public A5C3ErrorCodeReportInnerFrame transformFrame(String hex) { |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 16)); |
| | | |
| | | setErrorCode(hex.substring(16, hex.length() - 8)); |
| | | setCrc32(hex.substring(hex.length() - 8)); |
| | | // æ ¡éªCRC32 |
| | | String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getErrorCode(); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.report; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 18:20 |
| | | * A5-82-45 |
| | | * c3å
çµæ¡©æ
éç 䏿¥ |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5C3HeartbeatReportInnerFrame extends BaseResponseInnerFrame<A5C3HeartbeatReportInnerFrame> { |
| | | |
| | | // ç®æ å°å 4 |
| | | private String destinationAddress; |
| | | // å¿è·³å
æ°æ® |
| | | private HeartBeatDataPackage heartBeatDataPackage; |
| | | |
| | | @Override |
| | | public A5C3HeartbeatReportInnerFrame transformFrame(String hex) { |
| | | // é¿åº¦ä¸ä¸è´æ¶ï¼è¿ånull |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 16)); |
| | | |
| | | String heartBeatData = hex.substring(16, hex.length() - 8); |
| | | HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage(); |
| | | heartBeatDataPackage.transformFrame(heartBeatData); |
| | | setHeartBeatDataPackage(heartBeatDataPackage); |
| | | |
| | | setCrc32(hex.substring(hex.length() - 8)); |
| | | // æ ¡éªCRC32 |
| | | String frame = hex.substring(2, hex.length() - 8); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | |
| | | @Data |
| | | public static class HeartBeatDataPackage implements IResponseInnerFrame<HeartBeatDataPackage> { |
| | | // c3Mac(id hex) |
| | | private String c3Mac; |
| | | // å¹´ |
| | | private String year; |
| | | // æ |
| | | private String month; |
| | | // æ¥ |
| | | private String day; |
| | | // æ¶ |
| | | private String hour; |
| | | // å |
| | | private String min; |
| | | // ç§ |
| | | private String sec; |
| | | // å
çµæ¡©å£ |
| | | private String chargingPort; |
| | | // å
çµæ¡©å£ç¶æä½ |
| | | private String statusBit; |
| | | // è®¾å¤æ¸©åº¦ 0.1â |
| | | private String deviceTemperature; |
| | | // çµç½çµå 0.1V |
| | | private String gridVoltage; |
| | | // çµç½çµæµ 0.1A |
| | | private String gridCurrent; |
| | | // é¢ç 0.01Hz |
| | | private String frequency; |
| | | // åçå ç´ 0.001 |
| | | private String powerFactor; |
| | | // æååç 0.1KW |
| | | private String activePower; |
| | | // æ ååç 0.1KFar |
| | | private String reactivePower; |
| | | // å·²å
çµé 0.01KWh |
| | | private String chargedCapacity; |
| | | // é¢çº¦çµé 1KWh |
| | | private String reservedCapacity; |
| | | // å©ä½éé¢ 0.1å
|
| | | private String remainingAmount; |
| | | // å·²å
æ¶é¿ |
| | | private String alreadyChargingTime; |
| | | |
| | | @Override |
| | | public HeartBeatDataPackage transformFrame(String hex) { |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | this.year = hex.substring(0, 2); |
| | | this.month = hex.substring(2, 4); |
| | | this.day = hex.substring(4, 6); |
| | | this.hour = hex.substring(6, 8); |
| | | this.min = hex.substring(8, 10); |
| | | this.sec = hex.substring(10, 12); |
| | | this.chargingPort = hex.substring(12, 16); |
| | | this.statusBit = hex.substring(16, 18); |
| | | this.deviceTemperature = hex.substring(18, 22); |
| | | this.gridVoltage = hex.substring(22, 26); |
| | | this.gridCurrent = hex.substring(26, 30); |
| | | this.frequency = hex.substring(30, 34); |
| | | this.powerFactor = hex.substring(34, 38); |
| | | this.activePower = hex.substring(38, 42); |
| | | this.reactivePower = hex.substring(42, 46); |
| | | this.chargedCapacity = hex.substring(46, 50); |
| | | this.reservedCapacity = hex.substring(50, 54); |
| | | this.remainingAmount = hex.substring(54, 58); |
| | | this.alreadyChargingTime = hex.substring(58, 64); |
| | | |
| | | return this; |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.report; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 14:46 |
| | | * A5-81-42 |
| | | * åç¯ä¸æ¥ampq æ
éç |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5LightErrorCodeReportInnerFrame extends BaseResponseInnerFrame<A5LightErrorCodeReportInnerFrame> { |
| | | |
| | | /** |
| | | * ç®æ å°å 2 |
| | | */ |
| | | private String destinationAddress; |
| | | /** |
| | | * æ
éç |
| | | */ |
| | | private String errorCode; |
| | | |
| | | @Override |
| | | public A5LightErrorCodeReportInnerFrame transformFrame(String hex) { |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 12)); |
| | | |
| | | setErrorCode(hex.substring(12, 16)); |
| | | setCrc32(hex.substring(hex.length() - 8)); |
| | | // æ ¡éªCRC32 |
| | | String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getErrorCode(); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.report; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 18:20 |
| | | * A5-81-40 |
| | | * ç¯è¯»å¿è·³å
䏿¥ |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5LightHeartbeatReportInnerFrame extends BaseResponseInnerFrame<A5LightHeartbeatReportInnerFrame> { |
| | | |
| | | // ç®æ å°å 2 |
| | | private String destinationAddress; |
| | | // å¿è·³å
æ°æ® 58 |
| | | private HeartBeatDataPackage heartBeatDataPackage; |
| | | |
| | | private String originFrame; |
| | | |
| | | @Override |
| | | public A5LightHeartbeatReportInnerFrame transformFrame(String hex) { |
| | | // é¿åº¦ä¸ä¸è´æ¶ï¼è¿ånull |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 12)); |
| | | |
| | | String heartBeatData = hex.substring(12, 108); |
| | | HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage(); |
| | | heartBeatDataPackage.transformFrame(heartBeatData); |
| | | setHeartBeatDataPackage(heartBeatDataPackage); |
| | | |
| | | setCrc32(hex.substring(108, 116)); |
| | | // æ ¡éªCRC32 |
| | | String frame = hex.substring(2, hex.length() - 8); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | |
| | | @Data |
| | | public static class HeartBeatDataPackage implements IResponseInnerFrame<HeartBeatDataPackage> { |
| | | // å¹´RTC 1 |
| | | private String year; |
| | | // æRTC 1 |
| | | private String month; |
| | | // æ¥RTC 1 |
| | | private String day; |
| | | // æ¶RTC 1 |
| | | private String hour; |
| | | // åRTC 1 |
| | | private String min; |
| | | // ç§RTC 1 |
| | | private String sec; |
| | | // è®¾å¤æ¸©åº¦ 2 1åèæ´æ°1åèå°æ° |
| | | private String deviceTemperature; |
| | | // 亮度ç¾åæ¯ 1 |
| | | private String lightPercent; |
| | | // çµç½çµå 2 1åèæ´æ°1åèå°æ° |
| | | private String gridVol; |
| | | // çµç½çµæµ 2 1åèæ´æ°1åèå°æ° |
| | | private String gridCur; |
| | | // 赫å
¹ 2 1åèæ´æ°1åèå°æ° |
| | | private String hertz; |
| | | // åçå ç´ 2 1åèæ´æ°1åèå°æ° |
| | | private String powerFactor; |
| | | // æååç 2 1åèæ´æ°1åèå°æ° |
| | | private String activePower; |
| | | // æ ååç 2 1åèæ´æ°1åèå°æ° |
| | | private String reactivePower; |
| | | // æè¿ä¸æ¬¡äº®ç¯æ¶é´ 4 ç§ |
| | | private String recentlyLightSec; |
| | | // ç´¯è®¡äº®ç¯æ¶é´ 4 |
| | | private String totalLightTime; |
| | | // æè¿ä¸æ¬¡ç¨çµçµé 4 |
| | | private String recentlyUsingPower; |
| | | // 累计ç¨çµçµé 4 |
| | | private String totalUsingPower; |
| | | // ä¿ç 11 |
| | | private String retain; |
| | | // å帧 |
| | | private String originFrame; |
| | | |
| | | @Override |
| | | public HeartBeatDataPackage transformFrame(String hex) { |
| | | this.originFrame = hex; |
| | | this.year = hex.substring(0, 2); |
| | | this.month = hex.substring(2, 4); |
| | | this.day = hex.substring(4, 6); |
| | | this.hour = hex.substring(6, 8); |
| | | this.min = hex.substring(8, 10); |
| | | this.sec = hex.substring(10, 12); |
| | | |
| | | this.deviceTemperature = hex.substring(12, 16); |
| | | this.lightPercent = hex.substring(16, 18); |
| | | this.gridVol = hex.substring(18, 22); |
| | | this.gridCur = hex.substring(22, 26); |
| | | this.hertz = hex.substring(26, 30); |
| | | this.powerFactor = hex.substring(30, 34); |
| | | this.activePower = hex.substring(34, 38); |
| | | this.reactivePower = hex.substring(38, 42); |
| | | this.recentlyLightSec = hex.substring(42, 50); |
| | | this.totalLightTime = hex.substring(50, 58); |
| | | this.recentlyUsingPower = hex.substring(58, 66); |
| | | this.totalUsingPower = hex.substring(66, 74); |
| | | this.retain = hex.substring(74, 96); |
| | | return this; |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.report; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 14:46 |
| | | * A5-81-41 |
| | | * åç¯ä¸æ¥ampq è¯·æ±æ¶é´åæ¥ |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5LightTimeSyncReportInnerFrame extends BaseResponseInnerFrame<A5LightTimeSyncReportInnerFrame> { |
| | | |
| | | /** |
| | | * ç®æ å°å 2 |
| | | */ |
| | | private String destinationAddress; |
| | | /** |
| | | * 0x00ï¼è¯·æ±åæ¥ |
| | | */ |
| | | private String responseStatus; |
| | | |
| | | @Override |
| | | public A5LightTimeSyncReportInnerFrame transformFrame(String hex) { |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 12)); |
| | | |
| | | setResponseStatus(hex.substring(12, hex.length() - 8)); |
| | | setCrc32(hex.substring(hex.length() - 8)); |
| | | // æ ¡éªCRC32 |
| | | String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getResponseStatus(); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.request; |
| | | |
| | | import cn.hutool.core.util.HexUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 14:46 |
| | | * A1->0A/0B/0C |
| | | * 设置é¿éäºä¸å
ç ProductKey DeviceName DeviceSecret |
| | | */ |
| | | public class A1TernaryCodeReqInnerFrame implements IRequestInnerFrame { |
| | | |
| | | private final String ternaryCodeHex; |
| | | |
| | | /** |
| | | * @param ternaryCode ProductKey/DeviceName/DeviceSecret |
| | | */ |
| | | public A1TernaryCodeReqInnerFrame(String ternaryCode) { |
| | | ternaryCodeHex = HexUtil.encodeHexStr(ternaryCode); |
| | | } |
| | | |
| | | @Override |
| | | public String getEncodeFrame() { |
| | | if (this.ternaryCodeHex.length() % 2 != 0) { |
| | | return "0" + ternaryCodeHex; |
| | | } |
| | | return ternaryCodeHex; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.request; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 14:46 |
| | | * A5->01->01 |
| | | * "å¼/å
³ç¯(å³äº®åº¦å¼ï¼ |
| | | * 0x00ï¼å
³ç¯ |
| | | * å
¶å®ï¼å¼ç¯&亮度å¼" |
| | | */ |
| | | public class A5LightBrightnessReqInnerFrame implements IRequestInnerFrame { |
| | | |
| | | private final String payload; |
| | | |
| | | /** |
| | | * @param lightLevel 亮度ç级 [0,100] |
| | | */ |
| | | public A5LightBrightnessReqInnerFrame(Integer lightLevel) { |
| | | String destinationAddress = "FFFF"; |
| | | // å°æ´å亮度转æ¢ä¸ºHex |
| | | if (lightLevel < 0) { |
| | | lightLevel = 0; |
| | | } else if (lightLevel > 100) { |
| | | lightLevel = 100; |
| | | } |
| | | payload = destinationAddress + SupplementUtils.suppleZero(Integer.toHexString(lightLevel), 2); |
| | | } |
| | | |
| | | @Override |
| | | public String getEncodeFrame() { |
| | | String functionCode = A5LightDataEnum.LightControl.getCode(); |
| | | String payloadLength = "0003"; |
| | | String frame = functionCode + payloadLength + payload; |
| | | return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase()); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.request; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 18:16 |
| | | * A5->01->02 读å¿è·³å
|
| | | */ |
| | | public class A5LightHeartbeatReqInnerFrame implements IRequestInnerFrame { |
| | | @Override |
| | | public String getEncodeFrame() { |
| | | String functionCode = A5LightDataEnum.ReadHeartBeat.getCode(); |
| | | String payloadLength = "0002"; |
| | | String payload = "FFFF"; |
| | | String frame = functionCode + payloadLength + payload; |
| | | return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase()); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.request; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 18:16 |
| | | * A5->01->25 æ¸
é¤åç¯ç´¯è®¡æ°æ® |
| | | */ |
| | | public class A5LightResetReqInnerFrame implements IRequestInnerFrame { |
| | | @Override |
| | | public String getEncodeFrame() { |
| | | String functionCode = A5LightDataEnum.LightReset.getCode(); |
| | | String payloadLength = "0002"; |
| | | String payload = "FFFF"; |
| | | String frame = functionCode + payloadLength + payload; |
| | | return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase()); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.request; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 15:44 |
| | | * éç¨ç空帧 |
| | | */ |
| | | public class EmptyRequestInnerFrame implements IRequestInnerFrame { |
| | | @Override |
| | | public String getEncodeFrame() { |
| | | return ""; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.response; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 14:46 |
| | | * A1->0x89 |
| | | * 0x89ï¼è¯»åè¯çå¯ä¸è®¾å¤å°ååºç |
| | | * 12åè 1åè è§£éï¼è®¾å¤ç±»å00代表MQTT串å£ï¼01代表CAT1 |
| | | * 硬件MAC 设å¤ç±»å |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A1DeviceMacRespInnerFrame extends BaseResponseInnerFrame<A1DeviceMacRespInnerFrame> { |
| | | |
| | | /** |
| | | * 12åè 硬件MAC |
| | | */ |
| | | private String mac; |
| | | |
| | | /** |
| | | * 1åè 设å¤ç±»å 设å¤ç±»å00代表MQTT串å£ï¼01代表CAT1 |
| | | */ |
| | | private String type; |
| | | |
| | | @Override |
| | | public A1DeviceMacRespInnerFrame transformFrame(String payload) { |
| | | mac = payload.substring(0, 24); |
| | | type = payload.substring(24); |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.response; |
| | | |
| | | import cn.hutool.core.util.HexUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 14:46 |
| | | * A1->8A/8B/8C |
| | | * 设置é¿éäºä¸å
ç ProductKey DeviceName DeviceSecret ååºå
容 |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A1TernaryCodeRespInnerFrame extends BaseResponseInnerFrame<A1TernaryCodeRespInnerFrame> { |
| | | |
| | | /** |
| | | * ä¸å
ç |
| | | */ |
| | | private String ternaryCode; |
| | | |
| | | @Override |
| | | public A1TernaryCodeRespInnerFrame transformFrame(String hex) { |
| | | ternaryCode = HexUtil.decodeHexStr(hex); |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.response; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 14:46 |
| | | * A5-81-01ç¯äº®åº¦æ§å¶ åºç |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5LightBrightnessRespInnerFrame extends BaseResponseInnerFrame<A5LightBrightnessRespInnerFrame> { |
| | | |
| | | /** |
| | | * ç®æ å°å 2 |
| | | */ |
| | | private String destinationAddress; |
| | | /** |
| | | * åç¯äº®åº¦ç¶æ 1 |
| | | */ |
| | | private String responseStatus; |
| | | |
| | | @Override |
| | | public A5LightBrightnessRespInnerFrame transformFrame(String hex) { |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 12)); |
| | | |
| | | setResponseStatus(hex.substring(12, 14)); |
| | | setCrc32(hex.substring(14, 22)); |
| | | // æ ¡éªCRC32 |
| | | String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getResponseStatus(); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.frame.inner.response; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.IResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 18:20 |
| | | * A5-81-02 |
| | | * ç¯è¯»å¿è·³å
åºç |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class A5LightHeartbeatRespInnerFrame extends BaseResponseInnerFrame<A5LightHeartbeatRespInnerFrame> { |
| | | |
| | | // ç®æ å°å 2 |
| | | private String destinationAddress; |
| | | // å¿è·³å
æ°æ® 58 |
| | | private HeartBeatDataPackage heartBeatDataPackage; |
| | | |
| | | private String originFrame; |
| | | |
| | | @Override |
| | | public A5LightHeartbeatRespInnerFrame transformFrame(String hex) { |
| | | // é¿åº¦ä¸ä¸è´æ¶ï¼è¿ånull |
| | | if (StrUtil.isBlank(hex)) { |
| | | return null; |
| | | } |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | setFunctionCode(hex.substring(2, 4)); |
| | | // è´è·é¿åº¦(2) |
| | | setPayloadLength(hex.substring(4, 8)); |
| | | |
| | | setDestinationAddress(hex.substring(8, 12)); |
| | | |
| | | String heartBeatData = hex.substring(12, 108); |
| | | HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage(); |
| | | heartBeatDataPackage.transformFrame(heartBeatData); |
| | | setHeartBeatDataPackage(heartBeatDataPackage); |
| | | |
| | | setCrc32(hex.substring(108, 116)); |
| | | // æ ¡éªCRC32 |
| | | String frame = hex.substring(2, hex.length() - 8); |
| | | this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); |
| | | return this; |
| | | } |
| | | |
| | | @Data |
| | | public static class HeartBeatDataPackage implements IResponseInnerFrame<HeartBeatDataPackage> { |
| | | // å¹´RTC 1 |
| | | private String year; |
| | | // æRTC 1 |
| | | private String month; |
| | | // æ¥RTC 1 |
| | | private String day; |
| | | // æ¶RTC 1 |
| | | private String hour; |
| | | // åRTC 1 |
| | | private String min; |
| | | // ç§RTC 1 |
| | | private String sec; |
| | | // è®¾å¤æ¸©åº¦ 2 1åèæ´æ°1åèå°æ° |
| | | private String deviceTemperature; |
| | | // 亮度ç¾åæ¯ 1 |
| | | private String lightPercent; |
| | | // çµç½çµå 2 1åèæ´æ°1åèå°æ° |
| | | private String gridVol; |
| | | // çµç½çµæµ 2 1åèæ´æ°1åèå°æ° |
| | | private String gridCur; |
| | | // 赫å
¹ 2 1åèæ´æ°1åèå°æ° |
| | | private String hertz; |
| | | // åçå ç´ 2 1åèæ´æ°1åèå°æ° |
| | | private String powerFactor; |
| | | // æååç 2 1åèæ´æ°1åèå°æ° |
| | | private String activePower; |
| | | // æ ååç 2 1åèæ´æ°1åèå°æ° |
| | | private String reactivePower; |
| | | // æè¿ä¸æ¬¡äº®ç¯æ¶é´ 4 ç§ |
| | | private String recentlyLightSec; |
| | | // ç´¯è®¡äº®ç¯æ¶é´ 4 |
| | | private String totalLightTime; |
| | | // æè¿ä¸æ¬¡ç¨çµçµé 4 |
| | | private String recentlyUsingPower; |
| | | // 累计ç¨çµçµé 4 |
| | | private String totalUsingPower; |
| | | // ä¿ç 11 |
| | | private String retain; |
| | | // å帧 |
| | | private String originFrame; |
| | | |
| | | @Override |
| | | public HeartBeatDataPackage transformFrame(String hex) { |
| | | this.originFrame = hex; |
| | | this.year = hex.substring(0, 2); |
| | | this.month = hex.substring(2, 4); |
| | | this.day = hex.substring(4, 6); |
| | | this.hour = hex.substring(6, 8); |
| | | this.min = hex.substring(8, 10); |
| | | this.sec = hex.substring(10, 12); |
| | | |
| | | this.deviceTemperature = hex.substring(12, 16); |
| | | this.lightPercent = hex.substring(16, 18); |
| | | this.gridVol = hex.substring(18, 22); |
| | | this.gridCur = hex.substring(22, 26); |
| | | this.hertz = hex.substring(26, 30); |
| | | this.powerFactor = hex.substring(30, 34); |
| | | this.activePower = hex.substring(34, 38); |
| | | this.reactivePower = hex.substring(38, 42); |
| | | this.recentlyLightSec = hex.substring(42, 50); |
| | | this.totalLightTime = hex.substring(50, 58); |
| | | this.recentlyUsingPower = hex.substring(58, 66); |
| | | this.totalUsingPower = hex.substring(66, 74); |
| | | this.retain = hex.substring(74, 96); |
| | | return this; |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.aliyuncs.AcsRequest; |
| | | import com.aliyuncs.AcsResponse; |
| | | import com.aliyuncs.exceptions.ClientException; |
| | | import com.aliyuncs.iot.model.v20180120.*; |
| | | import com.sandu.common.execption.BusinessException; |
| | | import com.sandu.ximon.admin.manager.iot.frame.IRequestFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.InvokeParam; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.WrapResponseCommonFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.topic.IBaseTopic; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.topic.ICustomizeTopic; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/2 18:21 |
| | | */ |
| | | public abstract class BaseInvokeSyncService implements IInvoke, IBaseTopic, ICustomizeTopic { |
| | | |
| | | /** |
| | | * åérrpc è¯·æ± |
| | | * |
| | | * @param deviceName 设å¤å |
| | | * @param iRequestFrame ç¼ç 帧 |
| | | * @param clz å
é¨å¸§ååºå®ä½ç±» 妿䏿³èªå·±è§£æ å¯å¸¦ä¸ |
| | | * @return è¿åçè§£ç 帧å®ä½ç±» åæ¶æå
é¨å¸§è§£ç ä¹å乿ºå¸¦ä¸ |
| | | */ |
| | | public abstract <T extends BaseResponseInnerFrame<T>> WrapResponseCommonFrame<T> sendRRPC(String deviceName, IRequestFrame iRequestFrame, Class<T> clz); |
| | | |
| | | /** |
| | | * åºç¡éä¿¡åæ¥è°ç¨ |
| | | * |
| | | * @param request 请æ±å°è£
|
| | | * @param <T> è¿åç±»å |
| | | * @return è¿åç»æ |
| | | */ |
| | | protected <T extends AcsResponse> T invokeSync(AcsRequest<T> request) { |
| | | // è·å¾æå¡è°ç¨ååº |
| | | T response = null; |
| | | try { |
| | | response = getClient().getAcsResponse(request); |
| | | } catch (ClientException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return response; |
| | | } |
| | | |
| | | @Override |
| | | public RegisterDeviceResponse.Data registerDevice(String deviceName) { |
| | | RegisterDeviceRequest request = new RegisterDeviceRequest(); |
| | | request.setDeviceName(deviceName); |
| | | request.setProductKey(getProductKey()); |
| | | RegisterDeviceResponse response = invokeSync(request); |
| | | if (response != null && response.getSuccess()) { |
| | | return response.getData(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public boolean deleteDevice(String deviceName) { |
| | | DeleteDeviceRequest request = new DeleteDeviceRequest(); |
| | | request.setDeviceName(deviceName); |
| | | request.setProductKey(getProductKey()); |
| | | DeleteDeviceResponse response = invokeSync(request); |
| | | return response != null && response.getSuccess(); |
| | | } |
| | | |
| | | @Override |
| | | public QueryDeviceDetailResponse.Data queryDeviceDetail(String deviceName, String lotId) { |
| | | QueryDeviceDetailRequest request = new QueryDeviceDetailRequest(); |
| | | request.setIotId(lotId); |
| | | request.setDeviceName(deviceName); |
| | | request.setProductKey(getProductKey()); |
| | | QueryDeviceDetailResponse response = invokeSync(request); |
| | | if (response != null && response.getSuccess()) { |
| | | return response.getData(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public List<BatchQueryDeviceDetailResponse.DataItem> batchQueryDeviceDetail(List<String> deviceNames) { |
| | | BatchQueryDeviceDetailRequest request = new BatchQueryDeviceDetailRequest(); |
| | | request.setDeviceNames(deviceNames); |
| | | request.setProductKey(getProductKey()); |
| | | BatchQueryDeviceDetailResponse response = invokeSync(request); |
| | | if (response != null && response.getSuccess()) { |
| | | return response.getData(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public boolean saveDeviceProp(String deviceName, String props) { |
| | | throw new BusinessException("æªå®ç°"); |
| | | // SaveDevicePropRequest request = new SaveDevicePropRequest(); |
| | | // request.setDeviceName(deviceName); |
| | | // request.setProductKey(PRODUCT_KEY); |
| | | // request.setProps(JSON.); |
| | | } |
| | | |
| | | @Override |
| | | public List<BatchGetDeviceStateResponse.DeviceStatus> batchGetDeviceState(List<String> deviceNames) { |
| | | BatchGetDeviceStateRequest request = new BatchGetDeviceStateRequest(); |
| | | request.setDeviceNames(deviceNames); |
| | | request.setProductKey(getProductKey()); |
| | | BatchGetDeviceStateResponse response = invokeSync(request); |
| | | if (response != null && response.getSuccess()) { |
| | | return response.getDeviceStatusList(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è°ç¨èªå®ä¹topic |
| | | * https://help.aliyun.com/document_detail/69584.htm?spm=a2c4g.11186623.0.0.25b33982bSQSom#reference-snk-mrz-wdb |
| | | * |
| | | * @param deviceName 设å¤å |
| | | * @param param åæ° |
| | | * @return 设å¤è¿åçç»æ |
| | | */ |
| | | protected InvokeThingServiceResponse.Data invokeThing(String deviceName, InvokeParam param) { |
| | | // å¡«å
æå¡è°ç¨çåæ° |
| | | InvokeThingServiceRequest request = new InvokeThingServiceRequest(); |
| | | // 设å¤è¯ä¹¦ä¹productKey |
| | | request.setProductKey(getProductKey()); |
| | | // 设å¤è¯ä¹¦ä¹deviceName |
| | | request.setDeviceName(deviceName); |
| | | // è¦è°ç¨çæå¡æ è¯ç¬¦ï¼åå³äºæå¡ç«¯å®ä¹ ç®årrpcæ è¯ä»£è¡¨åæ¥è°ç¨ |
| | | request.setIdentifier("rrpc"); |
| | | request.setArgs(JSON.toJSONString(param)); |
| | | |
| | | // è·å¾æå¡è°ç¨ååº |
| | | InvokeThingServiceResponse response = null; |
| | | try { |
| | | response = getClient().getAcsResponse(request); |
| | | } catch (ClientException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | if (response == null) { |
| | | throw new BusinessException("è°ç¨rrpc失败"); |
| | | } |
| | | if (!response.getSuccess()) { |
| | | throw new BusinessException("è°ç¨rrpc失败ï¼" + response.getErrorMessage()); |
| | | } |
| | | // æå¡è°ç¨æåï¼ä»
代表åéæå¡æä»¤çæåï¼ä¸ä»£è¡¨æ§è¡æå¡æ¬èº«æ¯å¦æå |
| | | if (response.getSuccess()) { |
| | | // ä»
忥æå¡æresult |
| | | return response.getData(); |
| | | } |
| | | return null; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc; |
| | | |
| | | import com.aliyuncs.DefaultAcsClient; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 11:11 |
| | | */ |
| | | public interface IInvoke { |
| | | |
| | | /** |
| | | * è·å RRPC 客æ·ç«¯ |
| | | * @return RRPC 客æ·ç«¯ |
| | | * @return |
| | | */ |
| | | DefaultAcsClient getClient(); |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 16:50 |
| | | * åèï¼1 1 2 ä¸å®é¿ 4 |
| | | * åè½ç A å½ä»¤ç±»åA è´è·é¿åº¦A è´è·æ°æ®A å¸§æ ¡éªA |
| | | * |
| | | * æ»ä½å¸§ |
| | | */ |
| | | @Data |
| | | public class CommonFrame { |
| | | |
| | | /** |
| | | * MQTTéä¿¡æ¹å¼ {{@link com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum}} |
| | | */ |
| | | private String connectType; |
| | | |
| | | /** |
| | | * åè½ç ï¼1åè |
| | | */ |
| | | private String functionCode; |
| | | |
| | | /** |
| | | * å½ä»¤ç±»å ï¼1åè |
| | | */ |
| | | private String orderType; |
| | | /** |
| | | * è´è·é¿åº¦,2åè |
| | | */ |
| | | private String payloadLength; |
| | | /** |
| | | * ååºpayload ä¸å®åè |
| | | */ |
| | | private String payload; |
| | | /** |
| | | * æ ¡éªç ï¼4åè |
| | | */ |
| | | private String crc32; |
| | | |
| | | /** |
| | | * æ¯å¦éè¿æ ¡éª |
| | | */ |
| | | private boolean isValidate; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 17:27 |
| | | * amqpæ¶æ¯å®ä½ç±» |
| | | */ |
| | | @Data |
| | | public class CommonReportMessage { |
| | | |
| | | private String deviceType; |
| | | private String iotId; |
| | | private String requestId; |
| | | private String productKey; |
| | | private String deviceName; |
| | | private Items items; |
| | | |
| | | @Data |
| | | public static class Items { |
| | | private Params params; |
| | | } |
| | | @Data |
| | | public static class Params { |
| | | private Long time; |
| | | private String value; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 11:19 |
| | | */ |
| | | @Data |
| | | public class InvokeParam { |
| | | |
| | | /** |
| | | * // æä½æ è¯ç |
| | | * // 100:转åå
çµæ¡© |
| | | * // 127:æ´æ°å°å |
| | | * // 110:宿¶ä»»å¡ |
| | | * // 111:䏲壿§å¶ |
| | | * // 116:ç¡¬ä»¶ç¶ææ¥è¯¢ |
| | | * // 125:æ´æ°å¤§æ°æ°æ® |
| | | * // 130:å¼å¯ç¯å¸¦ |
| | | * // 131:å
³éç¯å¸¦ |
| | | */ |
| | | private String operate; |
| | | /** |
| | | * æ°æ®å¸§ |
| | | */ |
| | | private String frame; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.dto; |
| | | |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import lombok.Data; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 16:50 |
| | | * ååºæ»ä½å¸§ |
| | | * éé¢çè´è·payload å·²ç»è½¬åæç¸åºç±»åçresponseInnerFrameå®ä½ç±» |
| | | */ |
| | | @Data |
| | | @ToString(callSuper = true) |
| | | public class WrapResponseCommonFrame<T extends BaseResponseInnerFrame<T>> extends CommonFrame { |
| | | |
| | | private T responseInnerFrame; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * ä¸»æ¿æ¨¡åé
ç½®(A1)ä¸çå½ä»¤ |
| | | */ |
| | | public enum A1OrderEnum { |
| | | //-------------------------------------------- æå¡å¨ä¸å----------------------------------------------------// |
| | | /** |
| | | * åé
置信æ¯è¯·æ± |
| | | */ |
| | | REQUEST_WRITE_CONFIG("01"), |
| | | /** |
| | | * 读é
置信æ¯è¯·æ± |
| | | */ |
| | | REQUEST_READ_CONFIG("02"), |
| | | /** |
| | | * è¯»çæ¬ä¿¡æ¯è¯·æ± |
| | | */ |
| | | REQUEST_READ_VERSION("03"), |
| | | /** |
| | | * æ¶é´åæ¥é
ç½® |
| | | */ |
| | | REQUEST_SYNCHRONIZATION_TIME("04"), |
| | | /** |
| | | * å¿è·³å
é´éæ¶é´é
ç½® |
| | | */ |
| | | REQUEST_HEART_INTERVAL_TIME("05"), |
| | | /** |
| | | * 读串å£é
置信æ¯è¯·æ± |
| | | */ |
| | | REQUEST_READ_SERIAL_PORT("06"), |
| | | /** |
| | | * å串å£é
置信æ¯è¯·æ± |
| | | */ |
| | | REQUEST_WRITE_SERIAL_PORT("07"), |
| | | /** |
| | | * ç½ç»è¿æ¥æ¨¡å¼åæ¢é
ç½® |
| | | */ |
| | | REQUEST_CONNECTION_SWITCH("08"), |
| | | /** |
| | | * 读åè¯çå¯ä¸è®¾å¤å°å |
| | | */ |
| | | REQUEST_READ_DEVICE_UNIQUE_MAC("09"), |
| | | /** |
| | | * 设置é¿éäºä¸å
ç ProductKey |
| | | */ |
| | | REQUEST_SET_PRODUCT_KEY("0A"), |
| | | /** |
| | | * 设置é¿éäºä¸å
ç DeviceName |
| | | */ |
| | | REQUEST_SET_DEVICE_NAME("0B"), |
| | | /** |
| | | * 设置é¿éäºä¸å
ç DeviceSecret |
| | | */ |
| | | REQUEST_SET_DEVICE_SECRET("0C"), |
| | | |
| | | //-------------------------------------------- 主æ¿ä¸æ¥----------------------------------------------------// |
| | | /** |
| | | * åé
置信æ¯åºç |
| | | */ |
| | | RESPONSE_WRITE_CONFIG("81"), |
| | | /** |
| | | * 读é
置信æ¯åºç |
| | | */ |
| | | RESPONSE_READ_CONFIG("82"), |
| | | /** |
| | | * è¯»çæ¬ä¿¡æ¯åºç |
| | | */ |
| | | RESPONSE_READ_VERSION("83"), |
| | | /** |
| | | * æ¶é´åæ¥é
ç½®åºç/è¯·æ± |
| | | */ |
| | | RESPONSE_SYNCHRONIZATION_TIME("84"), |
| | | /** |
| | | * å¿è·³å
é´éæ¶é´é
ç½®åºç |
| | | */ |
| | | RESPONSE_HEART_INTERVAL_TIME("85"), |
| | | /** |
| | | * 读串å£é
置信æ¯åºç |
| | | */ |
| | | RESPONSE_READ_SERIAL_PORT("86"), |
| | | /** |
| | | * å串å£é
置信æ¯åºç |
| | | */ |
| | | RESPONSE_WRITE_SERIAL_PORT("87"), |
| | | /** |
| | | * ç½ç»è¿æ¥æ¨¡å¼åæ¢é
ç½®åºç |
| | | */ |
| | | RESPONSE_CONNECTION_SWITCH("88"), |
| | | /** |
| | | * 读åè¯çå¯ä¸è®¾å¤å°å |
| | | */ |
| | | RESPONSE_READ_DEVICE_UNIQUE_MAC("89"), |
| | | /** |
| | | * 设置é¿éäºä¸å
ç ProductKey |
| | | */ |
| | | RESPONSE_SET_PRODUCT_KEY("8A"), |
| | | /** |
| | | * 设置é¿éäºä¸å
ç DeviceName |
| | | */ |
| | | RESPONSE_SET_DEVICE_NAME("8B"), |
| | | /** |
| | | * 设置é¿éäºä¸å
ç DeviceSecret |
| | | */ |
| | | RESPONSE_SET_DEVICE_SECRET("8C"); |
| | | |
| | | A1OrderEnum(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | private final String code; |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * ä¸»æ¿æ¨¡åæ§å¶å½ä»¤(A2)ä¸çå½ä»¤ |
| | | */ |
| | | public enum A2OrderEnum { |
| | | //-------------------------------------------- æå¡å¨ä¸å----------------------------------------------------// |
| | | /** |
| | | * 主æ¿èªæå¤ä½å½ä»¤ |
| | | */ |
| | | REQUEST_MAIN_BOARD_RESET("01"), |
| | | /** |
| | | * å
¨é¨å¤è®¾çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_ALL_DEVICE_POWER_CONTROL("02"), |
| | | /** |
| | | * åç¯æ§å¶å¨çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_SINGLE_LAMP_POWER_CONTROL("03"), |
| | | /** |
| | | * å¤§æ°æ°æ®çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_ATMOSPHERE_POWER_CONTROL("04"), |
| | | /** |
| | | * å
çµæ¡©C2çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_C2_POWER_CONTROL("05"), |
| | | /** |
| | | * å
çµæ¡©C3çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_C3_POWER_CONTROL("06"), |
| | | /** |
| | | * æä½å¾æçæµçµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_POLE_MONITOR_POWER_CONTROL("07"), |
| | | /** |
| | | * æåå¤´çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_CAMERA_POWER_CONTROL("08"), |
| | | /** |
| | | * LEDå±çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_LED_POWER_CONTROL("09"), |
| | | /** |
| | | * APçµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_AP_POWER_CONTROL("0A"), |
| | | /** |
| | | * ä¸é®æå©çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_HELP_POWER_CONTROL("0B"), |
| | | /** |
| | | * IP鳿±çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_BROADCAST_POWER_CONTROL("0C"), |
| | | /** |
| | | * ç»§çµå¨1çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_RELAY1_POWER_CONTROL("0D"), |
| | | /** |
| | | * ç»§çµå¨2çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | REQUEST_RELAY2_POWER_CONTROL("0E"), |
| | | /** |
| | | * (é¢çï¼ |
| | | */ |
| | | REQUEST_CONTAIN("0F"), |
| | | /** |
| | | * å¯å¨å¤è®¾æ³¨åå½ä»¤ |
| | | */ |
| | | REQUEST_START_DEVICE_REGISTER("30"), |
| | | |
| | | //-------------------------------------------- 主æ¿ä¸æ¥----------------------------------------------------// |
| | | /** |
| | | * 主æ¿èªæå¤ä½å½ä»¤ |
| | | */ |
| | | RESPONSE_MAIN_BOARD_RESET("81"), |
| | | /** |
| | | * å
¨é¨å¤è®¾çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_ALL_DEVICE_POWER_CONTROL("82"), |
| | | /** |
| | | * åç¯æ§å¶å¨çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_SINGLE_LAMP_POWER_CONTROL("83"), |
| | | /** |
| | | * å¤§æ°æ°æ®çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_ATMOSPHERE_POWER_CONTROL("84"), |
| | | /** |
| | | * å
çµæ¡©C2çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_C2_POWER_CONTROL("85"), |
| | | /** |
| | | * å
çµæ¡©C3çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_C3_POWER_CONTROL("86"), |
| | | /** |
| | | * æä½å¾æçæµçµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_POLE_MONITOR_POWER_CONTROL("87"), |
| | | /** |
| | | * æåå¤´çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_CAMERA_POWER_CONTROL("88"), |
| | | /** |
| | | * LEDå±çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_LED_POWER_CONTROL("89"), |
| | | /** |
| | | * APçµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_AP_POWER_CONTROL("8A"), |
| | | /** |
| | | * ä¸é®æå©çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_HELP_POWER_CONTROL("8B"), |
| | | /** |
| | | * IP鳿±çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_BROADCAST_POWER_CONTROL("8C"), |
| | | /** |
| | | * ç»§çµå¨1çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_RELAY1_POWER_CONTROL("8D"), |
| | | /** |
| | | * ç»§çµå¨2çµæºæ§å¶å½ä»¤ |
| | | */ |
| | | RESPONSE_RELAY2_POWER_CONTROL("8E"), |
| | | /** |
| | | * (é¢çï¼ |
| | | */ |
| | | RESPONSE_CONTAIN("8F"), |
| | | /** |
| | | * å¯å¨å¤è®¾æ³¨åå½ä»¤ |
| | | */ |
| | | RESPONSE_START_DEVICE_REGISTER("B0"); |
| | | |
| | | A2OrderEnum(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | private final String code; |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * A5-84 大æ°ä¸æ¥ï¼ï¼MQTT弿¥ï¼ |
| | | */ |
| | | public enum A5AtmosphereReportEnum { |
| | | // 䏿¥å¿è·³å
|
| | | HeartBeat_Data("01"), |
| | | ; |
| | | |
| | | |
| | | A5AtmosphereReportEnum(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | private final String code; |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * A5-83 C3å
çµæ¡©ä¸æ¥ï¼ï¼amqpï¼ |
| | | */ |
| | | public enum A5C3ReportEnum { |
| | | /** |
| | | *ç½ç»è¯·æ± |
| | | */ |
| | | NETWORK_REQUEST("40"), |
| | | /** |
| | | * äºç»´ç è¯·æ± |
| | | */ |
| | | QR_CODE_REQUEST("41"), |
| | | /** |
| | | * 䏿¥å¿è·³å
|
| | | */ |
| | | HEART_BEAT("42"), |
| | | /** |
| | | * 䏿¥å
çµç»æ |
| | | */ |
| | | CHARGE_COMPLETE("43"), |
| | | /** |
| | | * 䏿¥å
çµä¸æ |
| | | */ |
| | | CHARGE_STOP("44"), |
| | | /** |
| | | * 䏿¥æ
éç |
| | | */ |
| | | ERROR_CODE("45") |
| | | ; |
| | | |
| | | |
| | | A5C3ReportEnum(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | private final String code; |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * A5-01 åç¯æ°æ®æä»¤ å表 |
| | | */ |
| | | public enum A5LightDataEnum { |
| | | // åç¯æ§å¶ |
| | | LightControl("01"), |
| | | // 读å¿è·³å
|
| | | ReadHeartBeat("02"), |
| | | // 宿¶æ§å¶ |
| | | TimingLightControl("03"), |
| | | // å
ææ§å¶ |
| | | LightSensorControl("04"), |
| | | |
| | | // æ¸
é¤åç¯ç´¯è®¡æ°æ® |
| | | LightReset("25"); |
| | | |
| | | A5LightDataEnum(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | private final String code; |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * A5-81 åç¯ä¸»å¨ä¸æ¥ï¼ï¼amqpï¼ |
| | | */ |
| | | public enum A5LightReportEnum { |
| | | // 䏿¥å¿è·³å
|
| | | HeartBeat_Data("40"), |
| | | // è¯·æ±æ¶é´åæ¥ |
| | | Time_Synchronized("41"), |
| | | // æ
éç |
| | | Error_Code("42"), |
| | | // æ¬å°å®æ¶/å
æ§å¼å
³ç¯å¨ä½ä¸æ¥ |
| | | Timing_LightSwitch_Report("43"), |
| | | // 请æ±é讯å议模å¼ï¼ä¸çµå10ç§ä¸æ¬¡ï¼å6æ¬¡ï¼ |
| | | Protocol_Model_Request("44"); |
| | | |
| | | |
| | | A5LightReportEnum(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | private final String code; |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * 主å¤è®¾æ°æ®(A5)ä¸çå½ä»¤ |
| | | */ |
| | | public enum A5OrderEnum { |
| | | //-------------------------------------------- æå¡å¨ä¸å----------------------------------------------------// |
| | | /** |
| | | *åç¯æ°æ®æä»¤ |
| | | */ |
| | | REQUEST_LIGHT_DATA("01"), |
| | | // å¤§æ°æ°æ®æä»¤ |
| | | REQUEST_ATMOSPHERE_DATA("04"), |
| | | // å
çµæ¡©C2æ°æ®æä»¤ |
| | | REQUEST_C2_DATA("03"), |
| | | // å
çµæ¡©C3æ°æ®æä»¤ |
| | | REQUEST_C3_DATA("02"), |
| | | // æä½çæµæ°æ®æä»¤ |
| | | REQUEST_POLE_MONITOR_DATA("05"), |
| | | // LORAæ¨¡åæ°æ®æä»¤ |
| | | REQUEST_LORA_DATA("06"), |
| | | // GPSæ¨¡åæ°æ®æä»¤ |
| | | REQUEST_GPS_DATA("07"), |
| | | |
| | | //-------------------------------------------- 设å¤ä¸æ¥----------------------------------------------------// |
| | | // åç¯æ°æ®æä»¤ä¸æ¥ |
| | | RESPONSE_LIGHT_DATA("81"), |
| | | // å¤§æ°æ°æ®æä»¤ä¸æ¥ |
| | | RESPONSE_ATMOSPHERE_DATA("84"), |
| | | // å
çµæ¡©C2æ°æ®æä»¤ä¸æ¥ |
| | | RESPONSE_C2_DATA("83"), |
| | | // å
çµæ¡©C3æ°æ®æä»¤ä¸æ¥ |
| | | RESPONSE_C3_DATA("82"), |
| | | // æä½çæµæ°æ®æä»¤ä¸æ¥ |
| | | RESPONSE_POLE_MONITOR_DATA("85"), |
| | | // LORAæ¨¡åæ°æ®æä»¤ä¸æ¥ |
| | | RESPONSE_LORA_DATA("86"), |
| | | // GPSæ¨¡åæ°æ®æä»¤ä¸æ¥ |
| | | RESPONSE_GPS_DATA("87"); |
| | | |
| | | A5OrderEnum(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | private final String code; |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * åè½ç ä¸çº§åç±» |
| | | */ |
| | | public enum FunctionCodeEnum { |
| | | |
| | | /** |
| | | * ä¸»æ¿æ¨¡åé
ç½® ç¨äºè®¾ç½®ä¸»æ¿çé
ç½®åæ°ç |
| | | */ |
| | | MAIN_BOARD_CONFIG("A1"), |
| | | /** |
| | | * ä¸»æ¿æ¨¡åæ§å¶å½ä»¤ ç¨äºæ§å¶ä¸»æ¿çæ¥å£å½ä»¤ |
| | | */ |
| | | MAIN_BOARD_CONTROL("A2"), |
| | | /** |
| | | * ä¸»æ¿æ¨¡åè°è¯ä¿¡æ¯ ç¨äºè®¾ç½®æè¯»åºä¸äºè°è¯æµè¯ä¿¡æ¯ç |
| | | */ |
| | | MAIN_BOARD_TEST("A3"), |
| | | /** |
| | | * è¿ç¨å级å½ä»¤ ç¨äºMQTT模åè¿ç¨å级åè½ |
| | | */ |
| | | REMOTE_UPDATE("A4"), |
| | | /** |
| | | * å¤è®¾æ°æ® ç¨äºå¤è®¾æ°æ®ä¼ è¾ä½¿ç¨æ¥å£ |
| | | */ |
| | | DATA_TRANSPORT_DATA("A5"); |
| | | |
| | | private final String code; |
| | | |
| | | FunctionCodeEnum(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.enums; |
| | | /** |
| | | * MQTTéä¿¡æ¹å¼ |
| | | * (å导ç ) |
| | | * @author chenjiantian |
| | | */ |
| | | public enum MQTTConnectTypeEnum { |
| | | |
| | | /** |
| | | * 忥 |
| | | */ |
| | | SYNCHRONIZATION("FE"), |
| | | /** |
| | | * 弿¥ |
| | | */ |
| | | ASYNCHRONOUS("F0"), |
| | | /** |
| | | * 广æ |
| | | */ |
| | | BROADCAST("FA"); |
| | | |
| | | MQTTConnectTypeEnum(String code){ |
| | | this.code = code; |
| | | } |
| | | |
| | | private final String code; |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.mainboard; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.aliyuncs.DefaultAcsClient; |
| | | import com.aliyuncs.iot.model.v20180120.InvokeThingServiceResponse; |
| | | import com.aliyuncs.profile.DefaultProfile; |
| | | import com.aliyuncs.profile.IClientProfile; |
| | | import com.sandu.common.execption.BusinessException; |
| | | import com.sandu.ximon.admin.manager.iot.amqp.MqttMainBoardConfig; |
| | | import com.sandu.ximon.admin.manager.iot.frame.IRequestFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.BaseInvokeSyncService; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.InvokeParam; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.WrapResponseCommonFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.util.FrameUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 11:31 |
| | | * 主æ¿rrpcéä¿¡å®ç°ç±» |
| | | */ |
| | | public class MainBoardInvokeSyncService extends BaseInvokeSyncService { |
| | | private static volatile DefaultAcsClient client = null; |
| | | |
| | | private final static String PRODUCT_KEY = "a1JsfPG4iKW"; |
| | | |
| | | @Override |
| | | public String getProductKey() { |
| | | return PRODUCT_KEY; |
| | | } |
| | | |
| | | @Override |
| | | public CommonFrame sendRRPC(String deviceName, IRequestFrame iRequestFrame) { |
| | | InvokeParam param = new InvokeParam(); |
| | | param.setOperate("1001"); |
| | | param.setFrame(iRequestFrame.getEncodeFrame()); |
| | | InvokeThingServiceResponse.Data data = invokeThing(deviceName, param); |
| | | if (data == null) { |
| | | return null; |
| | | } |
| | | String result = data.getResult(); |
| | | result = result.replace("\\", ""); |
| | | Map map = JSON.parseObject(result, Map.class); |
| | | result = (String) map.get("msg"); |
| | | CommonFrame connectFrame = FrameUtils.transformMessageToFrame(result); |
| | | return connectFrame; |
| | | } |
| | | |
| | | @Override |
| | | public <T extends BaseResponseInnerFrame<T>> WrapResponseCommonFrame<T> sendRRPC(String deviceName, IRequestFrame iRequestFrame, Class<T> clz) { |
| | | CommonFrame commonFrame = sendRRPC(deviceName, iRequestFrame); |
| | | if (commonFrame == null) { |
| | | throw new BusinessException("rrpc请æ±å¤±è´¥"); |
| | | } |
| | | WrapResponseCommonFrame<T> responseCommonFrame = new WrapResponseCommonFrame<>(); |
| | | BeanUtils.copyProperties(commonFrame, responseCommonFrame); |
| | | try { |
| | | responseCommonFrame.setResponseInnerFrame(clz.newInstance().transformFrame(responseCommonFrame.getPayload())); |
| | | } catch (InstantiationException | IllegalAccessException e) { |
| | | throw new BusinessException(String.format("æ¾ä¸å°%sçæé 彿°", clz.getName())); |
| | | } |
| | | return responseCommonFrame; |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | String s = "FEA581000BFE010003FFFF004597147735AB2D28"; |
| | | System.out.println(FrameUtils.decodeReportMessage(s)); |
| | | } |
| | | |
| | | private static class SingletonClassInstance { |
| | | private static final MainBoardInvokeSyncService INSTANCE = new MainBoardInvokeSyncService(); |
| | | } |
| | | |
| | | private MainBoardInvokeSyncService() { |
| | | } |
| | | |
| | | public static MainBoardInvokeSyncService getInstance() { |
| | | return SingletonClassInstance.INSTANCE; |
| | | } |
| | | |
| | | @Override |
| | | public DefaultAcsClient getClient() { |
| | | if (client == null) { |
| | | synchronized (MainBoardInvokeSyncService.class) { |
| | | if (client == null) { |
| | | IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", MqttMainBoardConfig.ACCESS_KEY, MqttMainBoardConfig.ACCESS_SECRET); |
| | | DefaultProfile.addEndpoint("cn-shanghai", "Iot", "iot.cn-shanghai.aliyuncs.com"); |
| | | client = new DefaultAcsClient(profile); |
| | | } |
| | | } |
| | | } |
| | | return client; |
| | | } |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.topic; |
| | | |
| | | import com.aliyuncs.iot.model.v20180120.BatchGetDeviceStateResponse; |
| | | import com.aliyuncs.iot.model.v20180120.BatchQueryDeviceDetailResponse; |
| | | import com.aliyuncs.iot.model.v20180120.QueryDeviceDetailResponse; |
| | | import com.aliyuncs.iot.model.v20180120.RegisterDeviceResponse; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 11:42 |
| | | * åºç¡éä¿¡topic |
| | | */ |
| | | public interface IBaseTopic { |
| | | |
| | | /** |
| | | * 注åè®¾å¤ |
| | | * https://help.aliyun.com/document_detail/69470.htm?spm=a2c4g.11186623.0.0.25b366d8EyOkmb#reference-pc2-kpz-wdb |
| | | * 注åè®¾å¤æå¨ç©èç½å¹³å°äº§å䏿·»å 设å¤ã卿å®äº§å䏿忳¨å设å¤åï¼é¿éäºç©èç½å¹³å°ä¸ºè®¾å¤é¢åå
¨å±å¯ä¸ç设å¤IDï¼IotIdï¼ï¼ç¨æ¥æ è¯è¯¥è®¾å¤ãå¨è¿è¡ä¸è®¾å¤ç¸å
³çæä½æ¶ï¼æ¨å¯è½éè¦æä¾ç®æ 设å¤çIotIdã |
| | | * æ¨ä¹å¯ä»¥ä½¿ç¨ProductKeyåDeviceNameç»åæ¥æ è¯ä¸ä¸ªè®¾å¤ãå
¶ä¸ProductKeyæ¯æ°å»ºäº§åæ¶ï¼ç©èç½å¹³å°ä¸ºäº§åé¢åçProductKeyï¼DeviceNameæ¯æ³¨åè®¾å¤æ¶ï¼ç±æ¨æå®æç±ç³»ç»éæºçæç设å¤åç§°ãIotIdçä¼å
级é«äºProductKeyåDeviceNameç»åã |
| | | * @param deviceName 设å¤å 妿ä¸ä¼ å
¥è¯¥åæ°ï¼åç±ç³»ç»éæºçæè®¾å¤åç§°ã |
| | | * @return è¿åçç»æ |
| | | */ |
| | | RegisterDeviceResponse.Data registerDevice(String deviceName); |
| | | |
| | | /** |
| | | * å é¤è®¾å¤ |
| | | * @param deviceName 设å¤å |
| | | * @return æ¯å¦æåã |
| | | */ |
| | | boolean deleteDevice(String deviceName); |
| | | |
| | | // /** |
| | | // * æ¥è¯¢è®¾å¤å±æ§å¿«ç
§ |
| | | // * @param deviceName 设å¤å |
| | | // * @param lotId è¦æ¥è¯¢å±æ§æå±ç设å¤IDææ°ååªçèç¹IDï¼å¦æä¼ å
¥è¯¥åæ°ï¼åæ éä¼ å
¥ProductKeyåDeviceNameãIotIdä½ä¸ºè®¾å¤å¯ä¸æ è¯ç¬¦ï¼åProductKeyä¸DeviceNameç»åæ¯ä¸ä¸å¯¹åºçå
³ç³»ã妿æ¨åæ¶ä¼ å
¥IotIdåProductKeyä¸DeviceNameç»åï¼å以IotId为åã |
| | | // */ |
| | | // void queryDeviceProperty(String deviceName,String lotId); |
| | | |
| | | /** |
| | | * https://help.aliyun.com/document_detail/69594.htm?spm=a2c4g.11186623.0.0.25b366d8EyOkmb#reference-rrg-lpz-wdb |
| | | * è°ç¨è¯¥æ¥å£æ¥è¯¢æå®è®¾å¤ç详ç»ä¿¡æ¯ã |
| | | * å个é¿éäºè´¦å·è°ç¨è¯¥æ¥å£çæ¯ç§è¯·æ±æ°ï¼QPSï¼æå¤§éå¶ä¸º50ã |
| | | * @param deviceName 设å¤å |
| | | * @param lotId è¦æ¥è¯¢å±æ§æå±ç设å¤IDææ°ååªçèç¹IDï¼å¦æä¼ å
¥è¯¥åæ°ï¼åæ éä¼ å
¥ProductKeyåDeviceNameãIotIdä½ä¸ºè®¾å¤å¯ä¸æ è¯ç¬¦ï¼åProductKeyä¸DeviceNameç»åæ¯ä¸ä¸å¯¹åºçå
³ç³»ã妿æ¨åæ¶ä¼ å
¥IotIdåProductKeyä¸DeviceNameç»åï¼å以IotId为åã |
| | | * @return 设å¤è¯¦æ
|
| | | */ |
| | | QueryDeviceDetailResponse.Data queryDeviceDetail(String deviceName, String lotId); |
| | | |
| | | /** |
| | | * https://help.aliyun.com/document_detail/123470.htm?spm=a2c4g.11186623.0.0.25b366d8EyOkmb#doc-api-Iot-BatchQueryDeviceDetail |
| | | * 忬¡è°ç¨æå¤è½æ¥è¯¢100个设å¤ã |
| | | * åªè½æ¹éæ¥è¯¢å½åé¿éäºè´¦å·ä¸ç设å¤è¯¦æ
ãå¦æä¼ å
¥ç设å¤ä¿¡æ¯ä¸ï¼æè®¾å¤ä¸å±äºå½åè´¦å·ï¼åç´æ¥è¿åå¤±è´¥ç»æã |
| | | * è¥ä¼ å
¥ç设å¤ä¿¡æ¯ä¸ï¼å
å«ä¸åå¨ç设å¤ï¼ååªè¿ååå¨ç设å¤è¯¦æ
ã |
| | | * å个é¿éäºè´¦å·è°ç¨è¯¥æ¥å£çæ¯ç§è¯·æ±æ°ï¼QPSï¼æå¤§éå¶ä¸º5ã |
| | | * @param deviceNames 设å¤åå表 |
| | | * @return 设å¤è¯¦æ
å表 |
| | | */ |
| | | List<BatchQueryDeviceDetailResponse.DataItem> batchQueryDeviceDetail(List<String> deviceNames); |
| | | |
| | | /** |
| | | * 为æå®è®¾å¤è®¾ç½®æ ç¾ã å个é¿éäºè´¦å·è°ç¨è¯¥æ¥å£çæ¯ç§è¯·æ±æ°ï¼QPSï¼æå¤§éå¶ä¸º50ã |
| | | * Propsçæ»å¤§å°ä¸è¶
è¿5 KBãå个设å¤çè®¾å¤æ ç¾æ»æ°ä¸è¶
è¿100个ã忬¡ä¿®æ¹ææ°å¢çè®¾å¤æ ç¾æ°ä¸è¶
è¿100个 |
| | | * https://help.aliyun.com/document_detail/69618.htm?spm=a2c4g.11186623.0.0.25b366d8EyOkmb#reference-xd3-qrz-wdb |
| | | * @param deviceName 设å¤å |
| | | * @param props JSONæ ¼å¼{"color":"red","shape":"round"} |
| | | * @return æ¯å¦æå |
| | | */ |
| | | boolean saveDeviceProp(String deviceName,String props); |
| | | |
| | | /** |
| | | * æ¥çåä¸äº§å䏿å®è®¾å¤çè¿è¡ç¶æã |
| | | * 该æ¥å£ç¨äºæ¥çä¸ä¸ªäº§åä¸å¤ä¸ªè®¾å¤çè¿è¡ç¶æï¼å次æå¤å¯æ¥è¯¢50个设å¤ã |
| | | * å个é¿éäºè´¦å·è°ç¨è¯¥æ¥å£çæ¯ç§è¯·æ±æ°ï¼QPSï¼æå¤§éå¶ä¸º50ã |
| | | * @param deviceNames 设å¤åå表 |
| | | * @return 设å¤ç¶æå表 |
| | | */ |
| | | List<BatchGetDeviceStateResponse.DeviceStatus> batchGetDeviceState(List<String> deviceNames); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.topic; |
| | | |
| | | import com.aliyuncs.iot.model.v20180120.InvokeThingServiceResponse; |
| | | import com.sandu.ximon.admin.manager.iot.frame.IRequestFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.InvokeParam; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/6 11:11 |
| | | * èªå®ä¹toic |
| | | */ |
| | | public interface ICustomizeTopic { |
| | | |
| | | /** |
| | | * è·å产åå |
| | | * |
| | | * @return 产åå |
| | | */ |
| | | String getProductKey(); |
| | | |
| | | /** |
| | | * åérrpc è¯·æ± |
| | | * |
| | | * @param deviceName 设å¤å |
| | | * @param iRequestFrame ç¼ç 帧 |
| | | * @return è¿åçè§£ç 帧å®ä½ç±» |
| | | */ |
| | | CommonFrame sendRRPC(String deviceName, IRequestFrame iRequestFrame); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.util; |
| | | |
| | | import cn.hutool.core.util.HexUtil; |
| | | |
| | | import java.util.zip.CRC32; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 18:43 |
| | | */ |
| | | public class CRC32Utils { |
| | | public static String getCRC32(String hex) { |
| | | CRC32 crc32 = new CRC32(); |
| | | byte[] bytes = HexUtil.decodeHex(hex); |
| | | crc32.update(bytes); |
| | | long value = crc32.getValue(); |
| | | return SupplementUtils.suppleZero(Long.toHexString(value).toUpperCase(),8); |
| | | } |
| | | |
| | | public static boolean validateFrame(String frame, String crc32) { |
| | | String crc32Validate = getCRC32(frame); |
| | | if(crc32.equals(crc32Validate)){ |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.util; |
| | | |
| | | import cn.hutool.core.codec.Base64; |
| | | import cn.hutool.core.util.HexUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | * @date 2021/12/3 17:36 |
| | | */ |
| | | public class FrameUtils { |
| | | |
| | | /** |
| | | * æä¸æ¥çå
容 转åæå¸§å®ä½ç±» |
| | | * @param value 䏿¥å
容 {{@link com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonReportMessage.Params}} |
| | | * @return 帧å®ä½ç±» |
| | | */ |
| | | public static CommonFrame transformMessageToFrame(String value) { |
| | | String hex = decodeReportMessage(value); |
| | | if (hex == null || hex.length() < 18) { |
| | | return null; |
| | | } |
| | | // å°åå
è¿å¶æ°è½¬ä¸ºå¤§å |
| | | hex = hex.toUpperCase(); |
| | | CommonFrame frame = new CommonFrame(); |
| | | // MQTTéä¿¡æ¹å¼(1) |
| | | frame.setConnectType(hex.substring(0, 2)); |
| | | // åè½ç (1) |
| | | frame.setFunctionCode(hex.substring(2, 4)); |
| | | // å½ä»¤ç±»å(1) |
| | | frame.setOrderType(hex.substring(4, 6)); |
| | | // è´è·é¿åº¦(2) |
| | | frame.setPayloadLength(hex.substring(6, 10)); |
| | | // ååºpayload |
| | | frame.setPayload(hex.substring(10, hex.length() - 8)); |
| | | // æ ¡éªç (4) |
| | | frame.setCrc32(hex.substring(hex.length() - 8)); |
| | | // å¤ææ ¡éªæ¯å¦éè¿ |
| | | String content = hex.substring(2, hex.length() - 8); |
| | | frame.setValidate(CRC32Utils.validateFrame(content, frame.getCrc32())); |
| | | |
| | | return frame; |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | System.out.println(transformMessageToFrame("/qWEACrwAQAi//8BAQEYAB4CAAAAAAAAAApcAAAAEAAVAAAAAwAQAagAAMPfU3KbHyny").toString()); |
| | | } |
| | | |
| | | /** |
| | | * å°è®¾å¤ä¸æ¥çå
容解ç |
| | | * |
| | | * @param value 设å¤ä¸æ¥çå
容 |
| | | * @return è§£ç åçå
容ï¼16è¿å¶ |
| | | */ |
| | | public static String decodeReportMessage(String value) { |
| | | if (StrUtil.isBlank(value)) { |
| | | return null; |
| | | } |
| | | byte[] decode = Base64.decode(value.getBytes()); |
| | | return HexUtil.encodeHexStr(decode); |
| | | } |
| | | |
| | | /** |
| | | * å°åå¤åéçå
容ç¼ç |
| | | * @param value å¾
ç¼ç å
容 |
| | | * @return ç¼ç åçå
容 å符串 |
| | | */ |
| | | public static String encodeReportMessage(String value) { |
| | | if (StrUtil.isBlank(value)) { |
| | | return null; |
| | | } |
| | | byte[] bytes = HexUtil.decodeHex(value); |
| | | String encode = Base64.encode(bytes); |
| | | return encode; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin.manager.iot.rrpc.util; |
| | | |
| | | /** |
| | | * @author chenjiantian |
| | | */ |
| | | public class SupplementUtils { |
| | | |
| | | |
| | | /** |
| | | * æªåæå®é¿åº¦çå符串ï¼ä¸è¶³ä»¥0å¡«å
åé¢ |
| | | * @param hex å符串 |
| | | * @param totalBit æªåé¿åº¦ |
| | | * @return æªååçå符串 |
| | | */ |
| | | public static String suppleZero(String hex, Integer totalBit) { |
| | | |
| | | if (hex.length() > totalBit) { |
| | | return hex.substring(0, totalBit); |
| | | } else if (hex.length() == totalBit) { |
| | | return hex; |
| | | } |
| | | totalBit = totalBit - hex.length(); |
| | | |
| | | StringBuilder hexBuilder = new StringBuilder(hex); |
| | | for (int i = 0; i < totalBit; i++) { |
| | | hexBuilder.insert(0, "0"); |
| | | } |
| | | hex = hexBuilder.toString(); |
| | | return hex; |
| | | } |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.sandu.ximon.admin; |
| | | |
| | | import com.aliyuncs.iot.model.v20180120.QueryDeviceDetailResponse; |
| | | import com.aliyuncs.iot.model.v20180120.RegisterDeviceResponse; |
| | | import com.sandu.common.execption.BusinessException; |
| | | import com.sandu.ximon.admin.manager.iot.frame.A1Frame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.A5Frame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.FrameBuilder; |
| | | import com.sandu.ximon.admin.manager.iot.frame.IRequestFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.request.*; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.response.A1DeviceMacRespInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.response.A1TernaryCodeRespInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.response.A5LightBrightnessRespInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.frame.inner.response.A5LightHeartbeatRespInnerFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.dto.WrapResponseCommonFrame; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A1OrderEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A2OrderEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5OrderEnum; |
| | | import com.sandu.ximon.admin.manager.iot.rrpc.mainboard.MainBoardInvokeSyncService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | |
| | | @SpringBootTest |
| | | @Slf4j |
| | | class BaseTopicTests { |
| | | |
| | | |
| | | @Test |
| | | void queryDeviceDetail() { |
| | | QueryDeviceDetailResponse.Data data = MainBoardInvokeSyncService.getInstance().queryDeviceDetail("32313243305007ff3055ffff01", null); |
| | | System.out.println(data.toString()); |
| | | } |
| | | |
| | | @Test |
| | | void rrpcLightControl() { |
| | | A5LightBrightnessReqInnerFrame lightControlFrame = new A5LightBrightnessReqInnerFrame(80); |
| | | A5Frame a5Frame = new A5Frame(A5OrderEnum.REQUEST_LIGHT_DATA.getCode(), lightControlFrame); |
| | | WrapResponseCommonFrame<A5LightBrightnessRespInnerFrame> frame = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC("32313243305008ff1a06ffff", a5Frame, A5LightBrightnessRespInnerFrame.class); |
| | | // LightControlResponseInnerFrame lightControlResponseInnerFrame = new LightControlResponseInnerFrame(); |
| | | // LightControlResponseInnerFrame innerFrame = lightControlResponseInnerFrame.transformFrame(commonFrame.getPayload()); |
| | | System.out.println(frame.toString()); |
| | | |
| | | } |
| | | |
| | | @Test |
| | | void readDeviceUniqueMac() { |
| | | A1Frame a1Frame = new A1Frame(A1OrderEnum.REQUEST_READ_DEVICE_UNIQUE_MAC.getCode(), new EmptyRequestInnerFrame()); |
| | | CommonFrame commonFrame = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC("baseDevice", a1Frame); |
| | | System.out.println(commonFrame.toString()); |
| | | } |
| | | |
| | | @Test |
| | | void register() { |
| | | String baseMac = "baseDevice"; |
| | | String MAINBOARD_PDK = "a1JsfPG4iKW"; |
| | | A1Frame a1Frame = new A1Frame(A1OrderEnum.REQUEST_READ_DEVICE_UNIQUE_MAC.getCode(), new EmptyRequestInnerFrame()); |
| | | CommonFrame commonFrame = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC(baseMac, a1Frame); |
| | | if(commonFrame == null){ |
| | | throw new BusinessException("读å设å¤å¯ä¸ID失败"); |
| | | } |
| | | A1DeviceMacRespInnerFrame a1DeviceMacRespInnerFrame = new A1DeviceMacRespInnerFrame().transformFrame(commonFrame.getPayload()); |
| | | |
| | | log.info(commonFrame.toString()); |
| | | String uniqueMac = a1DeviceMacRespInnerFrame.getMac(); |
| | | uniqueMac = uniqueMac.toLowerCase(); |
| | | log.info("å¯ä¸ç {}",uniqueMac); |
| | | MainBoardInvokeSyncService.getInstance().registerDevice(uniqueMac); |
| | | QueryDeviceDetailResponse.Data deviceDetail = MainBoardInvokeSyncService.getInstance().queryDeviceDetail(uniqueMac, null); |
| | | if(deviceDetail == null){ |
| | | throw new BusinessException("注å失败"); |
| | | } |
| | | |
| | | log.info(deviceDetail.toString()); |
| | | WrapResponseCommonFrame<A1TernaryCodeRespInnerFrame> productKeyResp = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC(baseMac, |
| | | FrameBuilder.builderA1().innerFrame(new A1TernaryCodeReqInnerFrame(MAINBOARD_PDK)) |
| | | .orderType(A1OrderEnum.REQUEST_SET_PRODUCT_KEY.getCode()).build(), |
| | | A1TernaryCodeRespInnerFrame.class); |
| | | A1TernaryCodeRespInnerFrame responseInnerFrame = productKeyResp.getResponseInnerFrame(); |
| | | if(!MAINBOARD_PDK.equals(responseInnerFrame.getTernaryCode())){ |
| | | throw new BusinessException("设å¤é
置ProductKey失败"); |
| | | } |
| | | |
| | | WrapResponseCommonFrame<A1TernaryCodeRespInnerFrame> responseCommonFrame = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC(baseMac, |
| | | FrameBuilder.builderA1().innerFrame(new A1TernaryCodeReqInnerFrame(uniqueMac)) |
| | | .orderType(A1OrderEnum.REQUEST_SET_DEVICE_NAME.getCode()).build(), |
| | | A1TernaryCodeRespInnerFrame.class); |
| | | A1TernaryCodeRespInnerFrame deviceNameFrame = responseCommonFrame.getResponseInnerFrame(); |
| | | if(!uniqueMac.equals(deviceNameFrame.getTernaryCode())){ |
| | | throw new BusinessException("设å¤é
ç½®å失败"); |
| | | } |
| | | |
| | | WrapResponseCommonFrame<A1TernaryCodeRespInnerFrame> wrapResponseCommonFrame = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC(baseMac, |
| | | FrameBuilder.builderA1().innerFrame(new A1TernaryCodeReqInnerFrame(deviceDetail.getDeviceSecret())) |
| | | .orderType(A1OrderEnum.REQUEST_SET_DEVICE_SECRET.getCode()).build(), |
| | | A1TernaryCodeRespInnerFrame.class); |
| | | A1TernaryCodeRespInnerFrame deviceSecretFrame = wrapResponseCommonFrame.getResponseInnerFrame(); |
| | | if (!deviceDetail.getDeviceSecret().equals(deviceSecretFrame.getTernaryCode())) { |
| | | throw new BusinessException("设å¤å¯é¥å¤±è´¥"); |
| | | } |
| | | |
| | | CommonFrame rebootFrame = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC(baseMac, |
| | | FrameBuilder.builderA2().innerFrame(new EmptyRequestInnerFrame()) |
| | | .orderType(A2OrderEnum.REQUEST_MAIN_BOARD_RESET.getCode()).build()); |
| | | if (rebootFrame.getPayload().equals("00")) { |
| | | System.out.println("é坿å"); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | void LightHeartbeat() { |
| | | IRequestFrame build = FrameBuilder.builderA5() |
| | | .orderType(A5OrderEnum.REQUEST_LIGHT_DATA.getCode()) |
| | | .innerFrame(new A5LightHeartbeatReqInnerFrame()) |
| | | .build(); |
| | | WrapResponseCommonFrame<A5LightHeartbeatRespInnerFrame> responseCommonFrame = MainBoardInvokeSyncService.getInstance().sendRRPC("32313243305008ff1a06ffff", build, A5LightHeartbeatRespInnerFrame.class); |
| | | System.out.println("responseCommonFrame.toString()"); |
| | | System.out.println(responseCommonFrame.toString()); |
| | | } |
| | | |
| | | @Test |
| | | void LightReset() { |
| | | String deviceName = "32313243305007ff3055ffff01"; |
| | | IRequestFrame build = FrameBuilder.builderA5() |
| | | .orderType(A5OrderEnum.REQUEST_LIGHT_DATA.getCode()) |
| | | .innerFrame(new A5LightResetReqInnerFrame()) |
| | | .build(); |
| | | CommonFrame commonFrame = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC(deviceName, build); |
| | | System.out.println(commonFrame.toString()); |
| | | CommonFrame rebootFrame = MainBoardInvokeSyncService.getInstance() |
| | | .sendRRPC(deviceName, |
| | | FrameBuilder.builderA2().innerFrame(new EmptyRequestInnerFrame()) |
| | | .orderType(A2OrderEnum.REQUEST_MAIN_BOARD_RESET.getCode()).build()); |
| | | if (rebootFrame.getPayload().equals("00")) { |
| | | System.out.println("é坿å"); |
| | | } |
| | | |
| | | } |
| | | } |