2021与蓝度共同重构项目,服务端
liuhaonan
2022-10-14 43e2e8143bd715e80598f92e1f78972b95a2a2b2
ximon-admin/src/main/java/com/sandu/ximon/admin/service/LightService.java
@@ -3,6 +3,8 @@
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.iot.model.v20180120.BatchGetDeviceStateResponse;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
@@ -14,25 +16,28 @@
import com.sandu.ximon.admin.dto.LightTaskDto;
import com.sandu.ximon.admin.manager.iot.frame.A5Frame;
import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5LightHeartbeatReportInnerFrame;
import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5LightOperationReportInnerFrame;
import com.sandu.ximon.admin.manager.iot.frame.inner.request.A5LightBrightnessReqInnerFrame;
import com.sandu.ximon.admin.manager.iot.frame.inner.request.A5LightSetCalendarReqInnerFrame;
import com.sandu.ximon.admin.manager.iot.frame.inner.response.A5LightBrightnessRespInnerFrame;
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.A5OrderEnum;
import com.sandu.ximon.admin.manager.iot.rrpc.mainboard.MainBoardInvokeSyncService;
import com.sandu.ximon.admin.param.LightControlParam;
import com.sandu.ximon.admin.param.LightPowerSettingParam;
import com.sandu.ximon.admin.param.LightRemarkParam;
import com.sandu.ximon.admin.redis.DeviceRedisKey;
import com.sandu.ximon.admin.redis.LightKey;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.admin.utils.RedisUtils;
import com.sandu.ximon.admin.utils.StoreOperationRecordsUtils;
import com.sandu.ximon.admin.vo.ControlLightCommandVO;
import com.sandu.ximon.admin.vo.EquipmentInfomation;
import com.sandu.ximon.admin.vo.RedisDeviceStatus;
import com.sandu.ximon.dao.bo.LightBo;
import com.sandu.ximon.dao.bo.PoleTaskLightPowerBo;
import com.sandu.ximon.dao.domain.Light;
import com.sandu.ximon.dao.domain.LightReportData;
import com.sandu.ximon.dao.domain.Pole;
import com.sandu.ximon.dao.domain.PoleBinding;
import com.sandu.ximon.dao.domain.*;
import com.sandu.ximon.dao.enums.DeviceRespStatusEnums;
import com.sandu.ximon.dao.enums.OrderByEnums;
import com.sandu.ximon.dao.mapper.LightMapper;
@@ -43,8 +48,6 @@
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@@ -62,6 +65,7 @@
    private final LightReportDataService lightReportDataService;
    private final PoleBindingService bindingService;
    private final PoleService poleService;
    private final RedisUtils redisUtils;
    /**
     * 录入当前设备码的路灯数据
@@ -198,13 +202,17 @@
     */
    public Light getLight(String deviceCode) {
        Light one = getOne(Wrappers.<Light>lambdaQuery().eq(Light::getDeviceCode, deviceCode));
        Object o = redisService.get(LightKey.REPORT_MAC.key(deviceCode));
        if (o != null) {
            one.setOnlineStatus(1);
        if (one == null) {
            return null;
        } else {
            one.setOnlineStatus(0);
            Object o = redisService.get(LightKey.REPORT_MAC.key(deviceCode));
            if (o != null) {
                one.setOnlineStatus(1);
            } else {
                one.setOnlineStatus(0);
            }
            return one;
        }
        return one;
    }
    /**
@@ -304,151 +312,6 @@
         */
        return resultList;
    }
    /**
     * 单灯节能率
     *
     * @return
     */
    public List controlEnergySaving() {
        //获取到正在执行的任务列表
        List<LightTaskDto> lightTaskDtos = SpringContextHolder.getBean(LightTaskService.class).listTask();
        LocalDateTime now = LocalDateTime.now();
        List<LightTaskDto> list1 = new ArrayList<>();
        List<LightTaskDto> list2 = new ArrayList<>();
        List<LightTaskDto> list3 = new ArrayList<>();
        List<LightTaskDto> list4 = new ArrayList<>();
        List<LightTaskDto> list5 = new ArrayList<>();
        List<LightTaskDto> list6 = new ArrayList<>();
        List<LightTaskDto> list7 = new ArrayList<>();
        for (LightTaskDto lightTaskDto : lightTaskDtos) {
            List<Integer> weekList = lightTaskDto.getWeekList();
            for (Integer one : weekList) {
                switch (one) {
                    case 1:
                        list1.add(lightTaskDto);
                        break;
                    case 2:
                        list2.add(lightTaskDto);
                        break;
                    case 4:
                        list3.add(lightTaskDto);
                        break;
                    case 8:
                        list4.add(lightTaskDto);
                        break;
                    case 16:
                        list5.add(lightTaskDto);
                        break;
                    case 32:
                        list6.add(lightTaskDto);
                        break;
                    case 64:
                        list7.add(lightTaskDto);
                        break;
                    default:
                }
            }
        }
        //获取当前星期几 1-7
        int currentWeekValue = now.getDayOfWeek().getValue();
        Map map;
        List<Map> temp = new ArrayList<>();
        //获取日期 精确到天
        LocalDateTime localDateTime = now.with(LocalTime.MIN);
        for (int i = 1; i < 8; i++) {
            currentWeekValue--;
            if (currentWeekValue < 1) {
                currentWeekValue = 7;
            }
            map = new LinkedHashMap();
            map.put("time", localDateTime.minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            map.put("value", getlist(currentWeekValue));
            temp.add(map);
        }
        return temp;
    }
    /**
     * 单灯能耗
     *
     * @return
     */
    public List controlEnergy() {
        //获取到正在执行的任务列表
        List<LightTaskDto> lightTaskDtos = SpringContextHolder.getBean(LightTaskService.class).listTask();
        LocalDateTime now = LocalDateTime.now();
        List<LightTaskDto> list1 = new ArrayList<>();
        List<LightTaskDto> list2 = new ArrayList<>();
        List<LightTaskDto> list3 = new ArrayList<>();
        List<LightTaskDto> list4 = new ArrayList<>();
        List<LightTaskDto> list5 = new ArrayList<>();
        List<LightTaskDto> list6 = new ArrayList<>();
        List<LightTaskDto> list7 = new ArrayList<>();
        for (LightTaskDto lightTaskDto : lightTaskDtos) {
            List<Integer> weekList = lightTaskDto.getWeekList();
            System.out.println(weekList + "===========================");
            for (Integer one : weekList) {
                switch (one) {
                    case 1:
                        list1.add(lightTaskDto);
                        break;
                    case 2:
                        list2.add(lightTaskDto);
                        break;
                    case 4:
                        list3.add(lightTaskDto);
                        break;
                    case 8:
                        list4.add(lightTaskDto);
                        break;
                    case 16:
                        list5.add(lightTaskDto);
                        break;
                    case 32:
                        list6.add(lightTaskDto);
                        break;
                    case 64:
                        list7.add(lightTaskDto);
                        break;
                    default:
                }
            }
        }
        Integer currentWeekValue = now.getDayOfWeek().getValue();
        Map map;
        List<Map> temp = new ArrayList<>();
        //获取当前日期  格式为yyyy-MM-dd
        LocalDateTime localDateTime = now.with(LocalTime.MIN);
        for (int i = 1; i < 8; i++) {
            currentWeekValue--;
            if (currentWeekValue < 1) {
                currentWeekValue = 7;
            }
            map = new LinkedHashMap();
            map.put("time", localDateTime.minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            map.put("value", getlistEnergy(currentWeekValue));
            temp.add(map);
        }
        return temp;
    }
@@ -636,7 +499,7 @@
     *
     * @return
     */
    public BigDecimal jisuan(LightTaskDto Task) {
    public BigDecimal jisuan(LightTaskDto Task, LightTaskPoleRelation bean) {
        final BigDecimal[] bigDecimalResult = {new BigDecimal(0.00)};
        /**
         * 节能率计算开始
@@ -758,9 +621,10 @@
     * 一天的能耗
     *
     * @param
     * @param bean
     * @return
     */
    public BigDecimal jisuanEnergy(LightTaskDto Task) {
    public BigDecimal jisuanEnergy(LightTaskDto Task, LightTaskPoleRelation bean) {
        //存放能耗
        final BigDecimal[] bigEnergy = {new BigDecimal(0.00)};
@@ -779,9 +643,21 @@
        }
        /**
         * 节能率计算开始
         * 能耗计算开始
         */
        List<PoleTaskLightPowerBo> poleTaskLightPowerBos = SpringContextHolder.getBean(LightTaskMapper.class).listLightTaskByTaskId(Task.getTaskId());
//        List<PoleTaskLightPowerBo> poleTaskLightPowerBos = SpringContextHolder.getBean(LightTaskMapper.class).listLightTaskByTaskId(Task.getTaskId());
        List<PoleTaskLightPowerBo> poleTaskLightPowerBos = new ArrayList<>();
        PoleTaskLightPowerBo poleTaskLightPowerBo = new PoleTaskLightPowerBo();
        Light one = getOne(Wrappers.lambdaQuery(Light.class).eq(Light::getDeviceCode, bean.getDeviceCode()));
        if (one != null) {
            if ("0001".equals(bean.getLightAddress())) {
                poleTaskLightPowerBo.setPower1(one.getPower1());
            } else {
                poleTaskLightPowerBo.setPower2(one.getPower2());
            }
        }
        poleTaskLightPowerBos.add(poleTaskLightPowerBo);
        ControlLightCommandVO startTime = parseSwitchLightCommand(Task.getOpenOrder());
        ControlLightCommandVO endTime = parseSwitchLightCommand(Task.getCloseOrder());
        //获取到单灯任务的节能率
@@ -1009,14 +885,14 @@
    /**
     * 获取用户所有的设备码
     */
    public CommonPage<String> listDeviceCode(int pageNo, int pageSize, String keyword, String deviceCode) {
    public CommonPage<String> listDeviceCode(int pageNo, int pageSize, String keyword, String deviceCode, String orderBy) {
        List<String> list;
        if (SecurityUtils.getClientId() != null) {
            PageHelper.startPage(pageNo, pageSize);
            list = baseMapper.listCode(SecurityUtils.getUserId(), keyword, deviceCode);
        } else {
            PageHelper.startPage(pageNo, pageSize);
            PageHelper.startPage(pageNo, pageSize, orderBy);
            list = baseMapper.listCode(null, keyword, deviceCode);
        }
@@ -1053,4 +929,206 @@
        });
        return updateBatchById(lights);
    }
    /**
     * 向Redis中存入设备状态
     */
    public void setCacheData() {
        List<String> collect = list().stream().map(Light::getDeviceCode).collect(Collectors.toList());
//        collect.forEach(
//                code -> {
//                    redisUtils.delete(DeviceRedisKey.LIGHT_DEVICE + code);
//                }
//        );
        List<List<String>> split = CollectionUtil.split(collect, 100);
        List<BatchGetDeviceStateResponse.DeviceStatus> deviceStatuses = new ArrayList<>();
        List<RedisDeviceStatus> statusList = new ArrayList<>();
        for (List<String> splist : split) {
            deviceStatuses = MainBoardInvokeSyncService.getInstance().batchGetDeviceState(splist);
            if (deviceStatuses != null) {
                for (BatchGetDeviceStateResponse.DeviceStatus deviceStatus : deviceStatuses) {
                    RedisDeviceStatus device = new RedisDeviceStatus();
                    device.setDeviceId(deviceStatus.getDeviceName());
                    if ("ONLINE".equals(deviceStatus.getStatus())) {
                        device.setStatus(0);
                    } else if ("OFFLINE".equals(deviceStatus.getStatus())) {
                        device.setStatus(1);
                    } else if ("UNACTIVE".equals(deviceStatus.getStatus())) {
                        device.setStatus(0);
                    } else if ("DISABLE".equals(deviceStatus.getStatus())) {
                        device.setStatus(0);
                    } else {
                        device.setStatus(2);
                    }
                    statusList.add(device);
                }
            }
        }
        statusList.forEach(status -> {
            redisUtils.set(DeviceRedisKey.LIGHT_DEVICE + status.getDeviceId(), JSON.toJSONString(status));
        });
    }
    /**
     * 设置日历(同心跳包中的6字节日期时间)
     *
     * @return
     */
    public String SetCalendar(Long lightId, String address) {
        Calendar cal = Calendar.getInstance();
        //获取当前时间
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH);
        int day = cal.get(Calendar.DATE);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int min = cal.get(Calendar.MINUTE);
        int sec = cal.get(Calendar.SECOND);
        if (!"0001".equals(address) && !"0002".equals(address)) {
            throw new BusinessException("灯头地址错误!");
        }
        Light one = getById(lightId);
        if (one == null) {
            System.out.println("单灯不存在!");
        }
        A5LightSetCalendarReqInnerFrame setCalendarReqInnerFrame =
                new A5LightSetCalendarReqInnerFrame(address, year % 100, month + 1, day, hour, min, sec);
        A5Frame a5Frame = new A5Frame(A5OrderEnum.REQUEST_LIGHT_DATA.getCode(), setCalendarReqInnerFrame);
        System.out.println(a5Frame + "            -----a5Frame");
        CommonFrame commonFrame;
        commonFrame = MainBoardInvokeSyncService.getInstance().sendRRPC(one.getDeviceCode(), a5Frame);
        StoreOperationRecordsUtils.storeInnerFrameData(one.getDeviceCode(), "单灯帧-设置日历", a5Frame, commonFrame);
        System.out.println(commonFrame + "            -----commonFrame");
        A5LightOperationReportInnerFrame operationReportInnerFrame = new A5LightOperationReportInnerFrame().transformFrame(commonFrame.getPayload());
        if (operationReportInnerFrame.isValidate()) {
            return operationReportInnerFrame.getState();
        } else {
            throw new BusinessException("数据校验错误,请重新请求");
        }
    }
    /**
     * 单灯主动同步时间请求
     */
    public void timeSynchronizationInitiative(String deviceCode, String lightAddress) {
        //单灯信息
        Light light = getLight(deviceCode);
        if (light == null) {
            log.error("单灯主动同步时间请求异常,单灯信息不存在!");
            return;
        }
        //单灯任务信息
        LightTaskPoleRelation lightTaskPoleRelation = SpringContextHolder.getBean(LightTaskPoleRelationService.class)
                .getOne(Wrappers.lambdaQuery(LightTaskPoleRelation.class)
                        .eq(LightTaskPoleRelation::getDeviceCode, deviceCode).eq(LightTaskPoleRelation::getLightAddress, lightAddress));
        LightTask lightTask = null;
        //灯头没有任务
        if (lightTaskPoleRelation != null) {
            if (lightTaskPoleRelation.getDeviceScheduled() != null) {
                lightTask = JSONObject.parseObject(lightTaskPoleRelation.getDeviceScheduled(), LightTask.class);
            }
        }
        timeSynchronization(light, lightAddress, lightTask);
    }
    /**
     * 单灯时间同步
     *
     * @param light     单灯信息实体
     * @param lightTask 单灯任务实体(为空标识单灯没有定时任务)
     */
    public void timeSynchronization(Light light, String lightAddress, LightTask lightTask) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //获取当前时间时、分
                Calendar cal = Calendar.getInstance();
                if (lightTask != null) {
                    String closeOrder = lightTask.getCloseOrder();
                    String openOrder = lightTask.getOpenOrder();
                    String controlOrder = lightTask.getControlOrder() == null ? null : lightTask.getControlOrder();
                    List<String> timeList = new ArrayList<>();
                    timeList.add(openOrder.substring(0, 4));
                    timeList.add(closeOrder.substring(0, 4));
                    if (controlOrder != null && controlOrder.length() % 7 == 0) {
                        for (int i = 0; i < controlOrder.length() / 7; i++) {
                            timeList.add(controlOrder.substring(i * 7, i * 7 + 4));
                        }
                    } else {
                        log.error("控灯指令不正确,数据长度不为7的倍数!");
                        return;
                    }
                    //时间排序
                    timeList = timeList.stream().sorted().collect(Collectors.toList());
                    int count = 0;
                    boolean haveTime = false;
                    while (!haveTime && count <= 144) {
                        haveTime = judgeTime(cal, timeList);
                        cal.add(Calendar.MINUTE, 10);
                        count++;
                    }
                    if (haveTime) {
                        try {
                            long longTime = cal.getTimeInMillis() - System.currentTimeMillis();
                            log.error("睡眠时间(毫秒):" + longTime);
                            Thread.sleep(longTime);
                            SetCalendar(light.getLightId(), lightAddress);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        log.error("灯杆ID为:" + light.getLightId() + ",灯头地址为:" + lightAddress + "没有找到可同步的时间,请检查任务!");
                    }
                } else {
                    SetCalendar(light.getLightId(), lightAddress);
                }
            }
        }).start();
    }
    /**
     * 判断时间是否可以执行同步指令
     *
     * @param time
     * @param timeList
     * @return true 可以执行  ,false  不可执行
     */
    private boolean judgeTime(Calendar time, List<String> timeList) {
        int hour = time.get(Calendar.HOUR_OF_DAY);
        int min = time.get(Calendar.MINUTE);
        int allMin = hour * 60 + min;
        for (String value : timeList) {
            int targetHour = Integer.valueOf(value.substring(0, 2));
            int targetMin = Integer.valueOf(value.substring(2, 4));
            int allTargetMin = targetHour * 60 + targetMin;
            if (allMin >= allTargetMin - 10 && allMin <= allTargetMin + 10) {
                return false;
            } else {
                continue;
            }
        }
        return true;
    }
}