| | |
| | | import com.dji.sample.component.oss.service.impl.OssServiceContext; |
| | | import com.dji.sample.component.redis.RedisConst; |
| | | import com.dji.sample.component.redis.RedisOpsUtils; |
| | | import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; |
| | | import com.dji.sample.component.websocket.model.CustomWebSocketMessage; |
| | | import com.dji.sample.component.websocket.model.BizCodeEnum; |
| | | import com.dji.sample.component.websocket.service.IWebSocketManageService; |
| | | import com.dji.sample.component.websocket.service.impl.SendMessageServiceImpl; |
| | | import com.dji.sample.manage.dao.IDeviceFirmwareMapper; |
| | |
| | | import com.dji.sample.manage.model.param.DeviceFirmwareQueryParam; |
| | | import com.dji.sample.manage.model.param.DeviceFirmwareUploadParam; |
| | | import com.dji.sample.manage.model.param.DeviceOtaCreateParam; |
| | | import com.dji.sample.manage.model.receiver.FirmwareProgressExtReceiver; |
| | | import com.dji.sample.manage.service.IDeviceFirmwareService; |
| | | import com.dji.sample.manage.service.IDeviceService; |
| | | import com.dji.sample.manage.service.IDeviceRedisService; |
| | | import com.dji.sample.manage.service.IFirmwareModelService; |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.integration.annotation.ServiceActivator; |
| | | import org.springframework.integration.mqtt.support.MqttHeaders; |
| | | import org.springframework.messaging.MessageHeaders; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.DigestUtils; |
| | |
| | | private IWebSocketManageService webSocketManageService; |
| | | |
| | | @Autowired |
| | | private IDeviceService deviceService; |
| | | |
| | | @Autowired |
| | | private OssServiceContext ossServiceContext; |
| | | |
| | | @Autowired |
| | | private IFirmwareModelService firmwareModelService; |
| | | |
| | | @Autowired |
| | | private IDeviceRedisService deviceRedisService; |
| | | |
| | | @Override |
| | | public Optional<DeviceFirmwareDTO> getFirmware(String workspaceId, String deviceName, String version) { |
| | |
| | | public List<DeviceOtaCreateParam> getDeviceOtaFirmware(String workspaceId, List<DeviceFirmwareUpgradeDTO> upgradeDTOS) { |
| | | List<DeviceOtaCreateParam> deviceOtaList = new ArrayList<>(); |
| | | upgradeDTOS.forEach(upgradeDevice -> { |
| | | boolean exist = deviceService.checkDeviceOnline(upgradeDevice.getSn()); |
| | | boolean exist = deviceRedisService.checkDeviceOnline(upgradeDevice.getSn()); |
| | | if (!exist) { |
| | | throw new IllegalArgumentException("Device is offline."); |
| | | throw new IllegalArgumentException("设备离线"); |
| | | } |
| | | Optional<DeviceFirmwareDTO> firmwareOpt = this.getFirmware( |
| | | workspaceId, upgradeDevice.getDeviceName(), upgradeDevice.getProductVersion()); |
| | | if (firmwareOpt.isEmpty()) { |
| | | throw new IllegalArgumentException("This firmware version does not exist or is not available."); |
| | | throw new IllegalArgumentException("此固件版本不存在或不可用"); |
| | | } |
| | | DeviceOtaCreateParam ota = dto2OtaCreateDto(firmwareOpt.get()); |
| | | ota.setSn(upgradeDevice.getSn()); |
| | |
| | | return deviceOtaList; |
| | | } |
| | | |
| | | @Override |
| | | @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_OTA_PROGRESS, outputChannel = ChannelName.OUTBOUND) |
| | | public void handleOtaProgress(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)); |
| | | @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_OTA_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) |
| | | public CommonTopicReceiver handleOtaProgress(CommonTopicReceiver receiver, MessageHeaders headers) { |
| | | String sn = receiver.getGateway(); |
| | | |
| | | EventsReceiver<EventsOutputReceiver> eventsReceiver = objectMapper.convertValue(receiver.getData(), |
| | | new TypeReference<EventsReceiver<EventsOutputReceiver>>(){}); |
| | | EventsReceiver<EventsOutputProgressReceiver<FirmwareProgressExtReceiver>> eventsReceiver = objectMapper.convertValue(receiver.getData(), |
| | | new TypeReference<EventsReceiver<EventsOutputProgressReceiver<FirmwareProgressExtReceiver>>>(){}); |
| | | eventsReceiver.setBid(receiver.getBid()); |
| | | |
| | | EventsOutputReceiver output = eventsReceiver.getOutput(); |
| | | EventsOutputProgressReceiver<FirmwareProgressExtReceiver> output = eventsReceiver.getOutput(); |
| | | log.info("SN: {}, {} ===> Upgrading progress: {}", |
| | | sn, receiver.getMethod(), output.getProgress().toString()); |
| | | |
| | |
| | | log.error("SN: {}, {} ===> Error code: {}", sn, receiver.getMethod(), eventsReceiver.getResult()); |
| | | } |
| | | |
| | | DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + sn); |
| | | String childDeviceSn = device.getChildDeviceSn(); |
| | | boolean upgrade = RedisOpsUtils.getExpire(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn) > 0; |
| | | boolean childUpgrade = RedisOpsUtils.getExpire(RedisConst.FIRMWARE_UPGRADING_PREFIX + childDeviceSn) > 0; |
| | | Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(sn); |
| | | if (deviceOpt.isEmpty()) { |
| | | return null; |
| | | } |
| | | |
| | | // Determine whether it is the ending state, delete the update state key in redis after the job ends. |
| | | EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus()); |
| | | Collection<ConcurrentWebSocketSession> sessions = webSocketManageService.getValueWithWorkspaceAndUserType( |
| | | device.getWorkspaceId(), UserTypeEnum.WEB.getVal()); |
| | | CustomWebSocketMessage<Object> build = CustomWebSocketMessage.builder() |
| | | .data(eventsReceiver) |
| | | .timestamp(System.currentTimeMillis()) |
| | | .bizCode(receiver.getMethod()) |
| | | .build(); |
| | | if (upgrade) { |
| | | if (statusEnum.getEnd()) { |
| | | // Delete the cache after the update is complete. |
| | | RedisOpsUtils.del(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn); |
| | | } else { |
| | | // Update the update progress of the dock in redis. |
| | | RedisOpsUtils.setWithExpire( |
| | | RedisConst.FIRMWARE_UPGRADING_PREFIX + sn, output.getProgress().getPercent(), |
| | | RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND); |
| | | } |
| | | eventsReceiver.setSn(sn); |
| | | webSocketMessageService.sendBatch(sessions, build); |
| | | } |
| | | if (childUpgrade) { |
| | | if (!StringUtils.hasText(eventsReceiver.getSn())) { |
| | | eventsReceiver.setSn(childDeviceSn); |
| | | webSocketMessageService.sendBatch(sessions, build); |
| | | } |
| | | if (statusEnum.getEnd()) { |
| | | RedisOpsUtils.del(RedisConst.FIRMWARE_UPGRADING_PREFIX + childDeviceSn); |
| | | } else { |
| | | // Update the update progress of the drone in redis. |
| | | RedisOpsUtils.setWithExpire( |
| | | RedisConst.FIRMWARE_UPGRADING_PREFIX + childDeviceSn, output.getProgress().getPercent(), |
| | | RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND); |
| | | } |
| | | } |
| | | DeviceDTO device = deviceOpt.get(); |
| | | handleProgress(device.getWorkspaceId(), sn, eventsReceiver, statusEnum.getEnd()); |
| | | handleProgress(device.getWorkspaceId(), device.getChildDeviceSn(), eventsReceiver, statusEnum.getEnd()); |
| | | |
| | | if (receiver.getNeedReply() != null && receiver.getNeedReply() == 1) { |
| | | String replyTopic = headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF; |
| | | messageSenderService.publish(replyTopic, |
| | | CommonTopicResponse.builder() |
| | | .tid(receiver.getTid()) |
| | | .bid(receiver.getBid()) |
| | | .method(receiver.getMethod()) |
| | | .timestamp(System.currentTimeMillis()) |
| | | .data(RequestsReply.success()) |
| | | .build()); |
| | | return receiver; |
| | | } |
| | | |
| | | private void handleProgress(String workspaceId, String sn, |
| | | EventsReceiver<EventsOutputProgressReceiver<FirmwareProgressExtReceiver>> events, boolean isEnd) { |
| | | boolean upgrade = deviceRedisService.getFirmwareUpgradingProgress(sn).isPresent(); |
| | | if (!upgrade) { |
| | | return; |
| | | } |
| | | if (isEnd) { |
| | | // Delete the cache after the update is complete. |
| | | deviceRedisService.delFirmwareUpgrading(sn); |
| | | } else { |
| | | // Update the update progress of the dock in redis. |
| | | deviceRedisService.setFirmwareUpgrading(sn, events); |
| | | } |
| | | events.setSn(sn); |
| | | webSocketMessageService.sendBatch(workspaceId, UserTypeEnum.WEB.getVal(), BizCodeEnum.OTA_PROGRESS.getCode(), events); |
| | | } |
| | | |
| | | @Override |
| | |
| | | String key = RedisConst.FILE_UPLOADING_PREFIX + workspaceId; |
| | | String existKey = key + file.getOriginalFilename(); |
| | | if (RedisOpsUtils.getExpire(existKey) > 0) { |
| | | throw new RuntimeException("Please try again later."); |
| | | throw new RuntimeException("请稍后再试"); |
| | | } |
| | | RedisOpsUtils.setWithExpire(existKey, true, RedisConst.DEVICE_ALIVE_SECOND); |
| | | try (InputStream is = file.getInputStream()) { |
| | |
| | | key += md5; |
| | | boolean exist = checkFileExist(workspaceId, md5); |
| | | if (exist) { |
| | | throw new RuntimeException("The file already exists."); |
| | | throw new RuntimeException("文件已存在"); |
| | | } |
| | | RedisOpsUtils.set(key, System.currentTimeMillis()); |
| | | Optional<DeviceFirmwareDTO> firmwareOpt = verifyFirmwareFile(file); |
| | | if (firmwareOpt.isEmpty()) { |
| | | throw new RuntimeException("The file format is incorrect."); |
| | | throw new RuntimeException("文件格式不正确"); |
| | | } |
| | | |
| | | String firmwareId = UUID.randomUUID().toString(); |