package com.sandu.ximon.admin.service; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.sandu.common.execption.BusinessException; import com.sandu.common.object.BaseConditionVO; import com.sandu.common.service.impl.BaseServiceImpl; import com.sandu.common.util.SpringContextHolder; import com.sandu.ximon.admin.dto.LightTaskDto; import com.sandu.ximon.admin.dto.SingleLightOrderDto; 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.A5LightTimerReqInnerFrame; import com.sandu.ximon.admin.manager.iot.frame.inner.response.A5LightTimerRespInnerFrame; import com.sandu.ximon.admin.manager.iot.rrpc.dto.WrapResponseCommonFrame; import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5OrderEnum; import com.sandu.ximon.admin.manager.iot.rrpc.mainboard.MainBoardInvokeSyncService; import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils; import com.sandu.ximon.admin.param.LightTaskIssueParam; import com.sandu.ximon.admin.param.LightTaskParam; import com.sandu.ximon.admin.security.SecurityUtils; import com.sandu.ximon.admin.utils.StoreOperationRecordsUtils; import com.sandu.ximon.admin.utils.TaskOrderUtil; import com.sandu.ximon.admin.vo.LightTaskInfoVO; import com.sandu.ximon.admin.vo.LightTaskRelationVO; import com.sandu.ximon.admin.vo.LightTaskVO; import com.sandu.ximon.dao.domain.LightEnergyData; import com.sandu.ximon.dao.domain.LightTask; import com.sandu.ximon.dao.domain.LightTaskPoleRelation; import com.sandu.ximon.dao.domain.Pole; import com.sandu.ximon.dao.enums.DeviceRespStatusEnums; import com.sandu.ximon.dao.enums.OrderByEnums; import com.sandu.ximon.dao.mapper.LightTaskMapper; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; /** * @author chenjiantian * @date 2021/12/15 16:33 * 路灯任务操作 */ @Service @Slf4j @AllArgsConstructor public class LightTaskService extends BaseServiceImpl { private final PoleService poleService; private final LightTaskPoleRelationService lightTaskPoleRelationService; private final LightTaskMapper lightTaskMapper; private final ClientService clientService; private final LightEnergyDataService lightEnergyDataService; /** * 新增路灯任务 * * @param param * @return */ @Transactional(rollbackFor = Exception.class) public String AddLightTask(LightTaskParam param) { if (StrUtil.length(param.getControlOrder()) % LightTaskParam.REQUEST_ORDER_LENGTH != 0) { throw new BusinessException("灯控命令格式不正确"); } if (!"0001".equals(param.getLightAddress()) && !"0002".equals(param.getLightAddress())) { throw new BusinessException("灯头地址格式不正确"); } int week = 0; for (Integer w : param.getWeekList()) { week |= w; } LightTask newLightTask = new LightTask(); newLightTask.setTaskName(param.getTaskName()); newLightTask.setClientId(clientService.getClientId(SecurityUtils.getUserId())); newLightTask.setUserId(SecurityUtils.getUserId()); newLightTask.setWeek(week); newLightTask.setCreateUser(SecurityUtils.getUsername()); newLightTask.setControlOrder(param.getControlOrder()); newLightTask.setOpenOrder(param.getOpenOrder()); newLightTask.setCloseOrder(param.getCloseOrder()); newLightTask.setLightAdress(param.getLightAddress()); newLightTask.setUpdateTime(LocalDateTime.now()); newLightTask.setFramePayload(buildControlFramePayload(param.getOpenOrder(), param.getCloseOrder(), param.getControlOrder(), week)); if (!save(newLightTask)) { throw new BusinessException("保存路灯任务失败"); } List poleCodeList = new ArrayList<>(); //传入的灯杆id集合 List poleIdList = new ArrayList<>(); //去重 for (Long item : param.getPoleIdList()) { if (!poleIdList.contains(item)) { poleIdList.add(item); } } if (CollectionUtil.isNotEmpty(poleIdList)) { List poleList = SpringContextHolder.getBean(PoleService.class).listByIds(poleIdList); if (CollectionUtil.isNotEmpty(poleList)) { poleCodeList = poleList.stream().map(Pole::getDeviceCode).collect(Collectors.toList()); } } String content = "{任务ID:" + newLightTask.getTaskId() + ", 任务名:" + newLightTask.getTaskName() + "},{内帧指令" + newLightTask.getFramePayload() + ", 灯杆ID:" + poleIdList.toString() + ", 控制的灯头地址:" + param.getLightAddress() + " }"; StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "新增路灯任务", content); //记录这些灯杆原先的任务 List oldLightTaskStatusAndPoles = lightTaskPoleRelationService.list(Wrappers.lambdaQuery(LightTaskPoleRelation.class) .in(LightTaskPoleRelation::getPoleId, poleIdList).eq(LightTaskPoleRelation::getLightAddress, param.getLightAddress())); List newPoleMap = new ArrayList<>(); if (!poleIdList.isEmpty()) { //新灯杆下发新任务 newPoleMap = sendControllerFrame(newLightTask, poleIdList, newLightTask.getFramePayload(), param.getLightAddress()); } newPoleMap.forEach( commend -> { //开关灯时间 commend.setSysScheduled(JSON.toJSONString(newLightTask)); System.out.println(commend.getIssueStatus() + "状态"); if (commend.getIssueStatus() == 0) { //下发成功 更新系统定时和硬件定时 commend.setDeviceScheduled(JSON.toJSONString(newLightTask)); } else { //下发失败 更新系统定时 保留硬件定时 硬件定时 // commend.setSysScheduled(s); oldLightTaskStatusAndPoles.forEach(task -> { if (task.getLightAddress().equals(commend.getLightAddress()) && task.getDeviceCode().equals(commend.getDeviceCode())) { //同一个灯头 commend.setDeviceScheduled(task.getDeviceScheduled()); } }); } } ); /** * 下发路灯任务日志记录开始 */ String content1 = "{任务ID:" + newLightTask.getTaskId() + ", 任务名:" + newLightTask.getTaskName() + "}," + " 灯杆ID:" + poleIdList.toString() + " }"; StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "下发路灯任务", content1); /** * 下发路灯任务日志记录结束 */ //删除旧的关系 lightTaskPoleRelationService.remove(Wrappers.lambdaQuery(LightTaskPoleRelation.class) .in(LightTaskPoleRelation::getPoleId, poleIdList).eq(LightTaskPoleRelation::getLightAddress, newLightTask.getLightAdress())); boolean b = true; //保存任务关系 if (!newPoleMap.isEmpty()) { b = lightTaskPoleRelationService.saveBatch(newPoleMap); } if (!b) { //所有灯杆都下发失败 新增的任务不保留 removeById(newLightTask); throw new BusinessException("指令下发失败,请检查灯杆状态后重新新增任务"); } else { return "任务新增成功"; } } /** * 编辑路灯任务 * * @param taskId * @param param * @return */ @Transactional(rollbackFor = Exception.class) public String newUpdateLightTask(Long taskId, LightTaskParam param) { if (StrUtil.length(param.getControlOrder()) % LightTaskParam.REQUEST_ORDER_LENGTH != 0) { throw new BusinessException("灯控命令格式不正确"); } if (!"0001".equals(param.getLightAddress()) && !"0002".equals(param.getLightAddress())) { throw new BusinessException("灯头地址格式不正确"); } LightTask newLightTask = getById(taskId); if (newLightTask == null) { throw new BusinessException("找不到路灯任务"); } int week = 0; for (Integer w : param.getWeekList()) { week |= w; } newLightTask.setTaskName(param.getTaskName()); newLightTask.setClientId(clientService.getClientId(SecurityUtils.getUserId())); newLightTask.setUserId(SecurityUtils.getUserId()); newLightTask.setWeek(week); newLightTask.setCreateUser(SecurityUtils.getUsername()); newLightTask.setControlOrder(param.getControlOrder()); newLightTask.setOpenOrder(param.getOpenOrder()); newLightTask.setCloseOrder(param.getCloseOrder()); newLightTask.setLightAdress(param.getLightAddress()); newLightTask.setUpdateTime(LocalDateTime.now()); newLightTask.setFramePayload(buildControlFramePayload(param.getOpenOrder(), param.getCloseOrder(), param.getControlOrder(), week)); updateById(newLightTask); //编辑后灯杆ID集合 List poleIdList = new ArrayList<>(); //去重 for (Long item : param.getPoleIdList()) { if (!poleIdList.contains(item)) { poleIdList.add(item); } } //记录任务编辑器前灯杆ID集合 // List oldLightTaskStatusAndPoles = lightTaskPoleRelationService.listPoleAndStatusIdByTaskId(taskId); List oldLightTaskStatusAndPoles = lightTaskPoleRelationService.list(Wrappers.lambdaQuery(LightTaskPoleRelation.class).eq(LightTaskPoleRelation::getTaskId, taskId)); List oldList = oldLightTaskStatusAndPoles.stream().map(LightTaskPoleRelation::getPoleId).collect(Collectors.toList()); //判断poleIdList中是否有旧的灯杆ID (直接下发) List newPoleIdList = poleIdList.stream().filter(poleId -> !oldList.contains(poleId)).collect(Collectors.toList()); //判断poleIdList中是否有新的灯杆ID (覆盖操作) List oldPoleIdList = poleIdList.stream().filter(poleId -> oldList.contains(poleId)).collect(Collectors.toList()); //oldList中有的灯杆ID,但是poleIdList中没有 (关灯操作) List closeLight = oldList.stream().filter(poleId -> !poleIdList.contains(poleId)).collect(Collectors.toList()); //取出覆盖操作的关系信息 //记录这些灯杆原先的任务 List oldRelation = new ArrayList<>(); if (CollectionUtil.isNotEmpty(oldPoleIdList)) { List oldRelationList = new ArrayList<>(); oldRelationList.addAll(oldPoleIdList); oldRelationList.addAll(closeLight); oldRelation = lightTaskPoleRelationService.list(Wrappers.lambdaQuery(LightTaskPoleRelation.class).in(LightTaskPoleRelation::getPoleId, oldRelationList) .ne(LightTaskPoleRelation::getTaskId, taskId).eq(LightTaskPoleRelation::getLightAddress, param.getLightAddress())); } //取出任务中原有的任务信息 List relations = lightTaskPoleRelationService.list(Wrappers.lambdaQuery(LightTaskPoleRelation.class) .eq(LightTaskPoleRelation::getTaskId, taskId).eq(LightTaskPoleRelation::getLightAddress, param.getLightAddress())); relations.addAll(oldRelation); List newPoleAll = new ArrayList<>(); List newPoleSuccess = new ArrayList<>(); List newPoleFail = new ArrayList<>(); if (CollectionUtil.isNotEmpty(newPoleIdList)) { //新灯杆下发新任务 Map> newPoleMap = sendControllerFrame(newPoleIdList, newLightTask.getFramePayload(), param.getLightAddress()); if (newPoleMap != null) { //newPoleAll集合后面用于存储关系表 newPoleAll = newPoleMap.getOrDefault("all", new ArrayList<>()); newPoleSuccess = newPoleMap.getOrDefault("success", new ArrayList<>()); newPoleFail = newPoleMap.getOrDefault("fail", new ArrayList<>()); } } List oldPoleFail = new ArrayList<>(); List oldPoleSuccess = new ArrayList<>(); if (CollectionUtil.isNotEmpty(oldPoleIdList)) { //覆盖操作灯杆 Map> oldPoleMap = sendControllerFrame(oldPoleIdList, newLightTask.getFramePayload(), param.getLightAddress()); if (oldPoleMap != null) { oldPoleFail = oldPoleMap.getOrDefault("fail", new ArrayList<>()); oldPoleSuccess = oldPoleMap.getOrDefault("success", new ArrayList<>()); } } List closePoleFail = new ArrayList<>(); List closePoleSuccess = new ArrayList<>(); System.out.println(closeLight + "closeLight"); if (CollectionUtil.isNotEmpty(closeLight) && closeLight != null && closeLight.get(0) != null) { //清除帧指令 String framePayloadClose = ""; //关灯操作灯杆 Map> closePoleMap = sendControllerFrame(closeLight, framePayloadClose, param.getLightAddress()); if (closePoleMap != null) { closePoleFail = closePoleMap.getOrDefault("fail", new ArrayList<>()); closePoleSuccess = closePoleMap.getOrDefault("success", new ArrayList<>()); } } /** * 编辑路灯任务日志记录开始 */ List poleCodeList = new ArrayList<>(); if (CollectionUtil.isNotEmpty(poleIdList)) { List poleList = SpringContextHolder.getBean(PoleService.class).listByIds(poleIdList); if (CollectionUtil.isNotEmpty(poleList)) { poleCodeList = poleList.stream().map(Pole::getDeviceCode).collect(Collectors.toList()); } } String content = "{任务ID:" + newLightTask.getTaskId() + ", 任务名:" + newLightTask.getTaskName() + "},{内帧指令" + newLightTask.getFramePayload() + ", 灯杆ID:" + poleIdList.toString() + ", 控制的灯头地址:" + param.getLightAddress() + " }"; StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "编辑路灯任务", content); /** * 编辑路灯任务日志记录结束 */ List all = new ArrayList<>(); all.addAll(newPoleSuccess); all.addAll(newPoleFail); all.addAll(oldPoleSuccess); all.addAll(oldPoleFail); if (closePoleFail.size() != 0) { List colesFail = new ArrayList<>(); //原来任务中本身就下发失败的任务 即硬件定时为空 编辑后进行关灯操作 可直接剔除任务关系 closePoleFail.forEach( close -> { relations.forEach( task -> { System.out.println(task.getLightAddress().equals(close.getLightAddress()) + " addressResult"); System.out.println(close.getLightAddress() + " close.getLightAddress()"); if (task.getLightAddress().equals(close.getLightAddress()) && task.getDeviceCode().equals(close.getDeviceCode()) && task.getDeviceScheduled() != null && !task.getDeviceScheduled().isEmpty()) { colesFail.add(close); } } ); all.addAll(colesFail); } ); } if (!all.isEmpty()) { List finalOldRelation = relations; all.forEach( commend -> { // 更新系统定时 commend.setSysScheduled(JSON.toJSONString(newLightTask)); commend.setTaskId(taskId); // 先设置硬件定时为上次的硬件定时 不论成功失败 finalOldRelation.forEach(task -> { if (task.getLightAddress().equals(commend.getLightAddress()) && task.getDeviceCode().equals(commend.getDeviceCode())) { //同一个灯头 commend.setDeviceScheduled(task.getDeviceScheduled()); if (commend.getIssueStatus() == 0) { //下发成功 更新系统定时和硬件定时 commend.setDeviceScheduled(JSON.toJSONString(newLightTask)); } } }); } ); } boolean b = true; //编辑前后所有的灯杆ID集合 poleIdList.addAll(oldList); //去重 List collect = poleIdList.stream().distinct().collect(Collectors.toList()); if (!collect.isEmpty()) { lightTaskPoleRelationService.remove(Wrappers.lambdaQuery(LightTaskPoleRelation.class) .in(LightTaskPoleRelation::getPoleId, collect).eq(LightTaskPoleRelation::getLightAddress, newLightTask.getLightAdress())); } if (!all.isEmpty()) { b = lightTaskPoleRelationService.saveBatch(all); } /** * 下发路灯任务日志记录开始 */ String content1 = "{任务ID:" + newLightTask.getTaskId() + ", 任务名:" + newLightTask.getTaskName() + "}," + " 灯杆ID:" + poleCodeList.toString() + " }"; StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "下发路灯任务", content1); /** * 下发路灯任务日志记录结束 */ if (b) { return "编辑成功"; } else { return "编辑失败"; } } /** * 发送灯控请求 * * @param framePayload 灯控参数 * @param deviceCode 设备吗 * @return 返回帧 */ public A5LightTimerRespInnerFrame sendTimeRRpc(String framePayload, String deviceCode, String lightAddress) { // IRequestFrame requestFrame = FrameBuilder. // builderA5(). // innerFrame( // new A5LightTimerReqInnerFrame // (framePayload, lightAddress) // ). // orderType(A5OrderEnum.REQUEST_LIGHT_DATA.getCode()). // build(); A5LightTimerReqInnerFrame a5LightTimerReqInnerFrame = new A5LightTimerReqInnerFrame(framePayload, lightAddress); System.out.println(JSON.toJSONString(a5LightTimerReqInnerFrame) + " --------a5LightTimerReqInnerFrame"); A5Frame requestFrame = new A5Frame(A5OrderEnum.REQUEST_LIGHT_DATA.getCode(), a5LightTimerReqInnerFrame); System.out.println(requestFrame + " --------requestFrame"); WrapResponseCommonFrame responseCommonFrame = MainBoardInvokeSyncService.getInstance().sendRRPC (deviceCode, requestFrame, A5LightTimerRespInnerFrame.class); System.out.println(responseCommonFrame + " -----------responseCommonFrame"); StoreOperationRecordsUtils.storeInnerFrameData(deviceCode, "单灯帧-控灯", requestFrame, responseCommonFrame); return Optional.ofNullable(responseCommonFrame).map(WrapResponseCommonFrame::getResponseInnerFrame).orElse(null); } public List listLightTask(BaseConditionVO conditionVO, String keyword, Integer order, Integer seq) { //排序字段 String orderByResult = "task_id"; //正序、倒叙 String orderBySeq = OrderByEnums.ASC.getCode(); if (order != null) { switch (order) { case 1: orderByResult = OrderByEnums.LIGHT_TASK_UPDATE_TIME.getCode(); break; default: } } if (seq != null) { switch (seq) { case 1: orderBySeq = OrderByEnums.ASC.getCode(); break; case 2: orderBySeq = OrderByEnums.DESC.getCode(); break; default: break; } } //排序方式 String orderBy = orderByResult + " " + orderBySeq; PageHelper.startPage(conditionVO.getPageNo(), conditionVO.getPageSize(), orderBy); List list = baseMapper.listTask(SecurityUtils.getClientId(), keyword, orderBy); Page page = new Page<>(); BeanUtils.copyProperties(list, page); for (LightTask lightTask : list) { LightTaskDto lightTaskDto = new LightTaskDto(); BeanUtils.copyProperties(lightTask, lightTaskDto); lightTaskDto.setWeekList(TaskOrderUtil.parseLightWeek2List(lightTask.getWeek())); //判断灯头是否存在任务 List lightTaskPoleRelationList = lightTaskPoleRelationService.list(Wrappers.lambdaQuery().eq(LightTaskPoleRelation::getTaskId, lightTask.getTaskId())); //下发成功的灯杆数量 Integer successCount = baseMapper.successCount(lightTaskDto.getTaskId()); ///任务中总的灯杆数量 Integer toTalCount = baseMapper.toTalCount(lightTaskDto.getTaskId()); if (successCount == null) { successCount = 0; } if (toTalCount == null) { toTalCount = 0; } if (toTalCount == 0) { //任务中没有灯杆 lightTaskDto.setSyncStatus("未同步"); } else { //任务中有灯杆 if (successCount == 0) { //下发成功未0 lightTaskDto.setSyncStatus("未同步"); } else if (successCount != 0 && successCount < toTalCount) { //存在下发成功 但并未全部成功 lightTaskDto.setSyncStatus("部分同步"); } else if (toTalCount.equals(successCount) && toTalCount != 0 && successCount != 0) { //全部成功 lightTaskDto.setSyncStatus("已同步"); } else { //未知类型 lightTaskDto.setSyncStatus("同步状态出错"); } } page.add(lightTaskDto); } return page; } /** * 执行中的路灯任务 * * @return */ public List listTask() { Long clientId = SecurityUtils.getClientId(); List lightTasks = lightTaskMapper.listLightTask(clientId); Page page = new Page<>(); BeanUtils.copyProperties(lightTasks, page); for (LightTask lightTask : lightTasks) { LightTaskDto lightTaskDto = new LightTaskDto(); BeanUtils.copyProperties(lightTask, lightTaskDto); lightTaskDto.setWeekList(TaskOrderUtil.parseLightWeek2List(lightTask.getWeek())); page.add(lightTaskDto); } return page; } /** * 用于任务新增,下发 * * @param lightTask * @param poleIdList * @param framePayload * @param lightAddress * @return */ private List sendControllerFrame(LightTask lightTask, List poleIdList, String framePayload, String lightAddress) { List lightTaskPoleRelationList = new ArrayList<>(); //成功 List success = new ArrayList<>(); //失败 List fail = new ArrayList<>(); Map map = new HashMap(); List poles = poleService.listByIds(poleIdList); if (CollectionUtil.isEmpty(poles)) { return null; } for (Pole pole : poles) { if (pole.getDeviceCode() == null || pole.getDeviceCode().equals("")) { removeById(lightTask.getTaskId()); throw new BusinessException("编辑的灯杆或原有任务的灯杆不存在mac,不能下发任务 请检查灯杆是否存在单灯"); } LightTaskPoleRelation lightTaskPoleRelation = new LightTaskPoleRelation(); lightTaskPoleRelation.setPoleId(pole.getId()); lightTaskPoleRelation.setTaskId(lightTask.getTaskId()); // rrpc 发生定时命令 lightTaskPoleRelation.setDeviceCode(pole.getDeviceCode()); lightTaskPoleRelation.setLightAddress(lightAddress); // rrpc 发生定时命令 try { A5LightTimerRespInnerFrame a5LightTimerRespInnerFrame = sendTimeRRpc(framePayload, pole.getDeviceCode(), lightAddress); if (a5LightTimerRespInnerFrame == null) { lightTaskPoleRelation.setIssueStatus(DeviceRespStatusEnums.OTHER_ERROR.getCode()); } else { lightTaskPoleRelation.setIssueStatus(HexUtil.hexToInt(a5LightTimerRespInnerFrame.getResponseStatus())); } } catch (BusinessException e) { e.printStackTrace(); lightTaskPoleRelation.setIssueStatus(DeviceRespStatusEnums.OTHER_ERROR.getCode()); } lightTaskPoleRelationList.add(lightTaskPoleRelation); } // } return lightTaskPoleRelationList; } /** * 用于任务编辑 * * @param poleIdList * @param framePayload * @param lightAddress * @return */ private Map> sendControllerFrame(List poleIdList, String framePayload, String lightAddress) { System.out.println("framePayload:" + framePayload); List lightTaskPoleRelationList = new ArrayList<>(); //成功 List success = new ArrayList<>(); //失败 List fail = new ArrayList<>(); Map> map = new HashMap(); List poles = poleService.listByIds(poleIdList); if (CollectionUtil.isEmpty(poles)) { return null; } for (Pole pole : poles) { if (pole.getDeviceCode() == null || pole.getDeviceCode().equals("")) { throw new BusinessException("编辑的灯杆或原有任务的灯杆不存在mac,不能下发任务 请检查灯杆是否存在单灯"); } LightTaskPoleRelation lightTaskPoleRelation = new LightTaskPoleRelation(); lightTaskPoleRelation.setPoleId(pole.getId()); //关系表插入灯头地址 lightTaskPoleRelation.setLightAddress(lightAddress); // rrpc 发生定时命令 lightTaskPoleRelation.setLightAddress(lightAddress); lightTaskPoleRelation.setDeviceCode(pole.getDeviceCode()); // rrpc 发生定时命令 try { A5LightTimerRespInnerFrame a5LightTimerRespInnerFrame = sendTimeRRpc(framePayload, pole.getDeviceCode(), lightAddress); if (a5LightTimerRespInnerFrame == null) { lightTaskPoleRelation.setIssueStatus(DeviceRespStatusEnums.OTHER_ERROR.getCode()); fail.add(lightTaskPoleRelation); } else { lightTaskPoleRelation.setIssueStatus(HexUtil.hexToInt(a5LightTimerRespInnerFrame.getResponseStatus())); success.add(lightTaskPoleRelation); } } catch (BusinessException e) { lightTaskPoleRelation.setIssueStatus(DeviceRespStatusEnums.OTHER_ERROR.getCode()); fail.add(lightTaskPoleRelation); } lightTaskPoleRelationList.add(lightTaskPoleRelation); } map.put("success", success); map.put("fail", fail); map.put("all", lightTaskPoleRelationList); log.error("发送控制器帧结果:{}", map); return map; } @Transactional(rollbackFor = Exception.class) public String delLightTask(Long taskId) { LightTask byId = getById(taskId); if (byId == null) { throw new BusinessException("找不到任务信息"); } //取出任务关系 List relations = lightTaskPoleRelationService.list(Wrappers.lambdaQuery(LightTaskPoleRelation.class).eq(LightTaskPoleRelation::getTaskId, taskId)); //取出灯杆id List poleIds = relations.stream().map(LightTaskPoleRelation::getPoleId).distinct().collect(Collectors.toList()); if (poleIds != null && poleIds.size() > 0) { //存在任务关系 下发清除任务指令 Map> ffff = sendControllerFrame(poleIds, "", byId.getLightAdress()); if (ffff == null) { throw new BusinessException("删除失败"); } /** * 删除控灯任务日志记录开始 */ String content = "{控灯任务id:" + taskId + " }"; StoreOperationRecordsUtils.storeOperationData(null, null, "删除控灯任务", content); /** * 删除控灯任务日志记录结束 */ if (ffff.get("fail").size() == 0) { //全部清除成功 删除全部任务关系 lightTaskPoleRelationService.remove(Wrappers.lambdaQuery(LightTaskPoleRelation.class).eq(LightTaskPoleRelation::getTaskId, taskId)); //删除任务 removeById(taskId); return "任务删除成功"; } else if (ffff.get("success").size() != ffff.get("all").size()) { //部分成功 删除成功部分的关系 保留任务 List relations1 = ffff.get("success"); if (relations1 != null && relations1.size() > 0) { relations1.forEach(lightTaskPoleRelation -> { lightTaskPoleRelationService.remove(Wrappers.lambdaUpdate(LightTaskPoleRelation.class) .eq(LightTaskPoleRelation::getPoleId, lightTaskPoleRelation.getPoleId()).eq(LightTaskPoleRelation::getTaskId, taskId)); }); } return "部分任务删除成功,清除任务失败的任务及数据保留!"; } else if (ffff.get("fail").size() == ffff.get("all").size()) { //全部失败 保留任务 return "任务删除失败 ,请检查硬件设备!"; } else { return "任务删除失败,未知错误类型!"; } } else { //不存在任务关系 空任务直接删除 removeById(taskId); return "任务删除成功"; } } /** * 任务详情 */ public Object detailLightTask(Long taskId) { LightTask lightTask = getById(taskId); if (lightTask == null) { throw new BusinessException("找不到任务"); } LightTaskInfoVO vo = new LightTaskInfoVO(); // LightTaskDto lightTaskDto = new LightTaskDto(); // BeanUtils.copyProperties(lightTask, lightTaskDto); lightTask.setWeekList(TaskOrderUtil.parseLightWeek2List(lightTask.getWeek())); vo.setLightTask(lightTask); List relations = new ArrayList<>(); List taskPoleRelations = lightTaskPoleRelationService.list(Wrappers.lambdaQuery(LightTaskPoleRelation.class) .eq(LightTaskPoleRelation::getTaskId, taskId)); if (taskPoleRelations != null && !taskPoleRelations.isEmpty()) { taskPoleRelations.forEach( relation -> { LightTaskRelationVO lightTaskRelationVO = new LightTaskRelationVO(); lightTaskRelationVO.setLightAddress(relation.getLightAddress()); lightTaskRelationVO.setIssueStatus(relation.getIssueStatus()); lightTaskRelationVO.setPoleId(relation.getPoleId()); Pole byId = poleService.getById(relation.getPoleId()); if (byId != null) { lightTaskRelationVO.setPoleName(byId.getPoleName()); } LightTaskVO sys = JSONObject.parseObject(relation.getSysScheduled(), LightTaskVO.class); sys.setWeekList(TaskOrderUtil.parseLightWeek2List(sys.getWeek())); lightTaskRelationVO.setSysScheduled(sys); LightTaskVO device = JSONObject.parseObject(relation.getDeviceScheduled(), LightTaskVO.class); if (device != null) { device.setWeekList(TaskOrderUtil.parseLightWeek2List(device.getWeek())); lightTaskRelationVO.setDeviceScheduled(device); } relations.add(lightTaskRelationVO); } ); vo.setRelations(relations); } // List lightTaskStatusAndPoles = lightTaskPoleRelationService.listPoleAndStatusIdByTaskId(taskId); // return MapUtil.builder().put("task", lightTask).put("poles", lightTaskStatusAndPoles).build(); return vo; } /** * 根据任务信息转成帧负荷 * * @return 路灯定时器列表 */ private String buildControlFramePayload(String openOrder, String closeOrder, String controlOrder, Integer week) { // 添加开灯定时器 SingleLightOrderDto openLightOrder = TaskOrderUtil.parseLightOrder(openOrder); SingleLightOrderDto closeLightOrder = TaskOrderUtil.parseLightOrder(closeOrder); String[] controlOrderArray = StrUtil.split(controlOrder, LightTaskParam.REQUEST_ORDER_LENGTH); Integer[] weekArrays = TaskOrderUtil.parseLightCronWeek2List(week).toArray(new Integer[0]); if (openLightOrder == null || closeLightOrder == null) { throw new BusinessException("解析单灯命令失败"); } if (ArrayUtil.isEmpty(weekArrays)) { throw new BusinessException("请设置星期"); } StringBuilder sb = new StringBuilder(); String weekHex = SupplementUtils.suppleZero(HexUtil.toHex(week), 2); // 拼接开灯命令 sb.append(weekHex); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(openLightOrder.getHour()), 2)); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(openLightOrder.getMinute()), 2)); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(openLightOrder.getBrightness()), 2)); // 拼接关灯命令 sb.append(weekHex); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(closeLightOrder.getHour()), 2)); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(closeLightOrder.getMinute()), 2)); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(closeLightOrder.getBrightness()), 2)); // 拼接亮度控灯命令 for (String controlOrderStr : controlOrderArray) { SingleLightOrderDto controlLightOrder = TaskOrderUtil.parseLightOrder(controlOrderStr); if (controlLightOrder != null) { sb.append(weekHex); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(controlLightOrder.getHour()), 2)); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(controlLightOrder.getMinute()), 2)); sb.append(SupplementUtils.suppleZero(HexUtil.toHex(controlLightOrder.getBrightness()), 2)); } } return sb.toString(); } /** * 下发单个灯杆的任务 */ public boolean issueLightTask(LightTaskIssueParam param) { LightTaskPoleRelation relation = lightTaskPoleRelationService.getOne(Wrappers.lambdaQuery(LightTaskPoleRelation.class) .eq(LightTaskPoleRelation::getPoleId, param.getPoleId()).eq(LightTaskPoleRelation::getTaskId, param.getTaskId())); if (relation == null) { throw new BusinessException("找不到任务关系,无法补发"); } LightTask lightTask = JSONObject.parseObject(relation.getSysScheduled(), LightTask.class); // LightTask lightTask = getById(param.getTaskId()); if (lightTask == null) { throw new BusinessException("找不到任务"); } //转换帧指令 String framePayload = buildControlFramePayload(lightTask.getOpenOrder(), lightTask.getCloseOrder(), lightTask.getControlOrder(), lightTask.getWeek()); //发送rrpc 得到发送结果 List lightTaskPoleRelationList = sendControllerFrame(lightTask, ListUtil.toList(param.getPoleId()), framePayload, lightTask.getLightAdress()); /** * 下发路灯任务日志记录开始 */ List poleCodeList = new ArrayList<>(); List list = SpringContextHolder.getBean(PoleService.class).list(Wrappers.lambdaQuery(Pole.class).eq(Pole::getId, param.getPoleId())); if (CollectionUtil.isNotEmpty(list)) { poleCodeList = list.stream().map(Pole::getDeviceCode).collect(Collectors.toList()); } String content = "{任务ID:" + lightTask.getTaskId() + ", 任务名:" + lightTask.getTaskName() + "}," + " 灯杆ID:" + param.getPoleId() + " }"; StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "下发路灯任务", content); /** * 下发路灯任务日志记录结束 */ if (CollectionUtil.isNotEmpty(lightTaskPoleRelationList)) { LightTaskPoleRelation lightTaskPoleRelation = lightTaskPoleRelationList.get(0); if (lightTaskPoleRelation.getIssueStatus() == 0) { //下发成功 更新硬件定时 返回成功 relation.setDeviceScheduled(JSON.toJSONString(lightTaskPoleRelation)); lightTaskPoleRelationService.updateById(relation); return true; } else { return false; } } return false; } /** * 计算功率及能耗 */ public void energy() { //所有存在任务的灯杆关系 List list = lightTaskPoleRelationService.list(); for (LightTaskPoleRelation bean : list) { if (bean.getDeviceScheduled() != null) { //存在硬件任务 LightTask lightTask = JSONObject.parseObject(bean.getDeviceScheduled(), LightTask.class); LightTaskDto lightTaskDto = new LightTaskDto(); BeanUtils.copyProperties(lightTask, lightTaskDto); lightTaskDto.setWeekList(TaskOrderUtil.parseLightWeek2List(lightTask.getWeek())); BigDecimal energySaving; BigDecimal energy; //获取昨天的星期数 LocalDateTime now = LocalDateTime.now(); LocalDateTime yesterday = now.minusDays(1); int week = yesterday.getDayOfWeek().getValue(); if (lightTaskDto.getWeekList().contains(week)) { //任务有该星期数 计算 energySaving = SpringContextHolder.getBean(LightService.class).jisuan(lightTaskDto, bean); energy = SpringContextHolder.getBean(LightService.class).jisuanEnergy(lightTaskDto, bean); System.out.println("能耗: " + energy + ", 节能率: " + energySaving); } else { //任务无该星期数 返回 energySaving = new BigDecimal(1); energy = BigDecimal.ZERO; } /** * 存储数据 */ System.out.println("能耗: " + energy + ", 节能率: " + energySaving); LightEnergyData lightEnergyData = new LightEnergyData(); lightEnergyData.setTaskId(lightTask.getTaskId()); lightEnergyData.setYtdTime(yesterday.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); lightEnergyData.setEnergySaving(energySaving); lightEnergyData.setEnergy(energy); lightEnergyData.setLightAdderss(lightTask.getLightAdress()); lightEnergyData.setUserId(lightTask.getUserId()); lightEnergyData.setClientId(lightTask.getClientId()); lightEnergyData.setPoleId(bean.getPoleId()); //保存能耗数据到数据库 lightEnergyDataService.save(lightEnergyData); } } } public boolean clearLightTask(List poleIds) { Map> ffff = sendControllerFrame(poleIds, "", "FFFF"); ffff.get("success").forEach(lightTaskPoleRelation -> { lightTaskPoleRelationService.remove(Wrappers.lambdaUpdate(LightTaskPoleRelation.class).eq(LightTaskPoleRelation::getPoleId, lightTaskPoleRelation.getPoleId()).eq(LightTaskPoleRelation::getTaskId, lightTaskPoleRelation.getTaskId())); }); return true; } public Map checkTask(LightTaskParam param) { /** * 重复任务的灯头 */ String lightAddress = param.getLightAddress(); List poleIdList = param.getPoleIdList(); List lightTaskPoleRelations = lightTaskPoleRelationService.list(Wrappers.lambdaQuery(LightTaskPoleRelation.class) .in(LightTaskPoleRelation::getPoleId, poleIdList).eq(LightTaskPoleRelation::getLightAddress, lightAddress)); //重复的任务id List taskIds = lightTaskPoleRelations.stream().map(LightTaskPoleRelation::getTaskId).collect(Collectors.toList()); //重复的灯杆id List oldPoleIds = lightTaskPoleRelations.stream().map(LightTaskPoleRelation::getPoleId).collect(Collectors.toList()); //未重复的灯杆id List finalOldPoleIds = oldPoleIds; //取出存在于poleIdList而不在oldPoleIds中的灯杆 List newPoleIds = poleIdList.stream().filter(id -> !finalOldPoleIds.contains(id)).collect(Collectors.toList()); //重复元素只保留一个 taskIds = taskIds.stream().distinct().collect(Collectors.toList()); oldPoleIds = oldPoleIds.stream().distinct().collect(Collectors.toList()); newPoleIds = newPoleIds.stream().distinct().collect(Collectors.toList()); Map map = new HashMap(); if (!lightTaskPoleRelations.isEmpty()) { map.put("result", "false"); map.put("newPoleIds", newPoleIds); map.put("oldPoleIds", oldPoleIds); map.put("taskIds", taskIds); } else { map.put("result", "true"); map.put("msg", "任务中无重复灯杆地址"); } return map; } }