From a7aaeabc7873a0eafb4a7ecad7f65b018b7a9bc9 Mon Sep 17 00:00:00 2001
From: sean.zhou <sean.zhou@dji.com>
Date: Fri, 24 Feb 2023 19:31:23 +0800
Subject: [PATCH] What's new? 1. Add license for dock. 2. Modify the logic corresponding to the firmware file and device type. 3. Add multiple mqtt clients options. 4. Modify the structure of the interface for obtaining the device list. 5. Fixed some issues.

---
 src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java |  177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 173 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java
index 61c13ee..de1d03f 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java
@@ -43,6 +43,8 @@
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
@@ -61,17 +63,66 @@
     private ObjectMapper objectMapper;
 
     @Autowired
-    private RedisOpsUtils redisOps;
-
-    @Autowired
     private SendMessageServiceImpl sendMessageService;
 
     @Autowired
     private WebSocketManageServiceImpl webSocketManageService;
 
+    private static final Pattern PATTERN_KEY = Pattern.compile(
+            HmsEnum.FormatKeyEnum.KEY_START +
+                    "(" +
+                    Arrays.stream(HmsEnum.FormatKeyEnum.values())
+                            .map(HmsEnum.FormatKeyEnum::getKey)
+                            .collect(Collectors.joining("|")) +
+                    ")");
+
     @Override
     @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_HMS)
     public void handleHms(CommonTopicReceiver receiver, MessageHeaders headers) {
+        String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString();
+        String sn  = topic.substring((TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT).length(),
+                topic.indexOf(TopicConst.EVENTS_SUF));
+
+        DeviceHmsEntity entity = DeviceHmsEntity.builder()
+                .bid(receiver.getBid())
+                .tid(receiver.getTid())
+                .createTime(receiver.getTimestamp())
+                .updateTime(0L)
+                .sn(sn)
+                .build();
+        String key = RedisConst.HMS_PREFIX + sn;
+        // Query all unread hms messages of the device in redis.
+        Set<String> hmsMap = RedisOpsUtils.listGetAll(key).stream().map(String::valueOf).collect(Collectors.toSet());
+
+        DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + sn);
+
+        List<DeviceHmsDTO> unReadList = new ArrayList<>();
+        objectMapper.convertValue(((Map) (receiver.getData())).get(MapKeyConst.LIST),
+                new TypeReference<List<DeviceHmsReceiver>>() {})
+                .forEach(hmsReceiver -> {
+                    final DeviceHmsEntity hms = entity.clone();
+                    this.fillEntity(hms, hmsReceiver);
+                    // The same unread hms are no longer incremented.
+                    if (hmsMap.contains(hms.getHmsKey())) {
+                        return;
+                    }
+                    this.fillMessage(hms, hmsReceiver.getArgs());
+                    unReadList.add(entity2Dto(hms));
+                    mapper.insert(hms);
+                });
+
+        if (unReadList.isEmpty()) {
+            return;
+        }
+        RedisOpsUtils.listRPush(key, unReadList.stream().map(DeviceHmsDTO::getKey).toArray(String[]::new));
+        // push to the web
+        Collection<ConcurrentWebSocketSession> sessions = webSocketManageService.getValueWithWorkspaceAndUserType(
+                device.getWorkspaceId(), UserTypeEnum.WEB.getVal());
+        sendMessageService.sendBatch(sessions, CustomWebSocketMessage.builder()
+                .bizCode(BizCodeEnum.DEVICE_HMS.getCode())
+                .data(TelemetryDTO.<List<DeviceHmsDTO>>builder().sn(sn).host(unReadList).build())
+                .timestamp(System.currentTimeMillis())
+                .build());
     }
 
     @Override
@@ -107,7 +158,8 @@
                 new LambdaUpdateWrapper<DeviceHmsEntity>()
                         .eq(DeviceHmsEntity::getSn, deviceSn)
                         .eq(DeviceHmsEntity::getUpdateTime, 0L));
-        redisOps.del(RedisConst.HMS_PREFIX + deviceSn);
+        // Delete unread messages cached in redis.
+        RedisOpsUtils.del(RedisConst.HMS_PREFIX + deviceSn);
     }
 
     private DeviceHmsDTO entity2Dto(DeviceHmsEntity entity) {
@@ -130,4 +182,121 @@
                 .build();
     }
 
+    /**
+     * Populate the received data into the entity. Please refer to the documentation for splicing rules.
+     * @param dto
+     * @param receiver
+     */
+    private void fillEntity(DeviceHmsEntity dto, DeviceHmsReceiver receiver) {
+        dto.setLevel(receiver.getLevel());
+        dto.setModule(receiver.getModule());
+        dto.setHmsId(UUID.randomUUID().toString());
+
+        if (HmsEnum.DomainType.DRONE_NEST.getDomain().equals(receiver.getDomainType())) {
+            dto.setHmsKey(HmsEnum.HmsFaqIdEnum.DOCK_TIP.getText() + receiver.getCode());
+            return;
+        }
+        StringBuilder key = new StringBuilder(HmsEnum.HmsFaqIdEnum.FPV_TIP.getText()).append(receiver.getCode());
+
+        if (receiver.getInTheSky() == HmsEnum.IN_THE_SKY.getVal()) {
+            key.append(HmsEnum.IN_THE_SKY.getText());
+        }
+        dto.setHmsKey(key.toString());
+    }
+
+    /**
+     * Replace wildcards in messages according to the relevant rules.
+     * Please refer to the documentation for splicing rules.
+     * @param dto
+     * @param args
+     */
+    private void fillMessage(DeviceHmsEntity dto, HmsArgsReceiver args) {
+        HmsMessage hmsMessage = HmsJsonUtil.get(dto.getHmsKey());
+        String zh = StringUtils.hasText(hmsMessage.getZh()) ? hmsMessage.getZh() : String.format("未知错误(%s)", dto.getHmsKey());
+        String en = StringUtils.hasText(hmsMessage.getEn()) ? hmsMessage.getEn() : String.format("Unknown(%s)", dto.getHmsKey());//
+
+        dto.setMessageZh(format(Locale.CHINESE.getLanguage(), zh, args));
+        dto.setMessageEn(format(Locale.ENGLISH.getLanguage(), en, args));
+    }
+
+    /**
+     * Set the matching parameters for key.
+     * @param l     language: zh or en
+     * @param hmsArgs
+     * @return
+     */
+    private List<String> fillKeyArgs(String l, HmsArgsReceiver hmsArgs) {
+        List<String> args = new ArrayList<>();
+        args.add(Objects.nonNull(hmsArgs.getAlarmId()) ? Long.toHexString(hmsArgs.getAlarmId()) : null);
+        args.add(Objects.nonNull(hmsArgs.getComponentIndex()) ? String.valueOf(hmsArgs.getComponentIndex() + 1) : null);
+        if (Objects.nonNull(hmsArgs.getSensorIndex())) {
+            args.add(String.valueOf(hmsArgs.getSensorIndex() + 1));
+
+            HmsEnum.HmsBatteryIndexEnum hmsBatteryIndexEnum = HmsEnum.HmsBatteryIndexEnum.find(hmsArgs.getSensorIndex());
+            HmsEnum.HmsDockCoverIndexEnum hmsDockCoverIndexEnum = HmsEnum.HmsDockCoverIndexEnum.find(hmsArgs.getSensorIndex());
+            HmsEnum.HmsChargingRodIndexEnum hmsChargingRodIndexEnum = HmsEnum.HmsChargingRodIndexEnum.find(hmsArgs.getSensorIndex());
+
+            switch (l) {
+                case "zh":
+                    args.add(hmsBatteryIndexEnum.getZh());
+                    args.add(hmsDockCoverIndexEnum.getZh());
+                    args.add(hmsChargingRodIndexEnum.getZh());
+                    break;
+                case "en":
+                    args.add(hmsBatteryIndexEnum.getEn());
+                    args.add(hmsDockCoverIndexEnum.getEn());
+                    args.add(hmsChargingRodIndexEnum.getEn());
+                    break;
+                default:
+                    break;
+            }
+
+        }
+        return args;
+    }
+
+    /**
+     * Returns a formatted string using the specified locale, format string, and arguments.
+     * @param l language: zh or en
+     * @param format
+     * @param hmsArgs
+     * @return
+     */
+    private String format(String l, String format, HmsArgsReceiver hmsArgs) {
+        List<String> args = fillKeyArgs(l, hmsArgs);
+        List<String> list = parse(format);
+        StringBuilder sb = new StringBuilder();
+        for (String word : list) {
+            if (!StringUtils.hasText(word)) {
+                continue;
+            }
+            HmsEnum.FormatKeyEnum keyEnum = HmsEnum.FormatKeyEnum.find(word.substring(1));
+            sb.append(HmsEnum.FormatKeyEnum.KEY_START != word.charAt(0) || HmsEnum.FormatKeyEnum.UNKNOWN == keyEnum ?
+                    word : args.get(keyEnum.getIndex()));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Finds format specifiers in the format string.
+     * @param s
+     * @return
+     */
+    private List<String> parse(String s) {
+        List<String> list = new ArrayList<>();
+        Matcher matcher = PATTERN_KEY.matcher(s);
+        for (int i = 0; i < s.length(); ) {
+            if (matcher.find(i)) {
+                if (matcher.start() != i) {
+                    list.add(s.substring(i, matcher.start()));
+                }
+                list.add(matcher.group());
+                i = matcher.end();
+            } else {
+                list.add(s.substring(i));
+                break;
+            }
+        }
+        return list;
+    }
 }

--
Gitblit v1.9.3