package com.sandu.ximon.admin.service;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.util.HexUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.alibaba.fastjson.JSONObject;
|
import com.aliyuncs.iot.model.v20180120.BatchGetDeviceStateResponse;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.github.pagehelper.PageHelper;
|
import com.sandu.common.domain.CommonPage;
|
import com.sandu.common.execption.BusinessException;
|
import com.sandu.common.redis.RedisService;
|
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.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.*;
|
import com.sandu.ximon.dao.enums.DeviceRespStatusEnums;
|
import com.sandu.ximon.dao.enums.OrderByEnums;
|
import com.sandu.ximon.dao.mapper.LightMapper;
|
import com.sandu.ximon.dao.mapper.LightTaskMapper;
|
import lombok.AllArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @author chenjiantian
|
* @date 2021/12/13 16:00
|
* 灯设备service
|
*/
|
@Service
|
@Slf4j
|
@AllArgsConstructor
|
public class LightService extends BaseServiceImpl<LightMapper, Light> {
|
|
private final RedisService redisService;
|
private final LightReportDataService lightReportDataService;
|
private final PoleBindingService bindingService;
|
private final PoleService poleService;
|
private final RedisUtils redisUtils;
|
|
/**
|
* 录入当前设备码的路灯数据
|
*
|
* @param deviceName mac
|
* @param heartBeatDataPackage 心跳数据
|
*/
|
public void saveLight(String deviceName, A5LightHeartbeatReportInnerFrame.HeartBeatDataPackage heartBeatDataPackage) {
|
Boolean hasKey = redisService.hasKey(LightKey.REPORT_MAC.key(deviceName));
|
if (!hasKey) {
|
int count = count(Wrappers.lambdaQuery(Light.class).eq(Light::getDeviceCode, deviceName));
|
log.info("redis查不到路灯数据 数量:{}={}", count, deviceName);
|
// 当前路灯表没有录入设备吗
|
if (count == 0) {
|
Light light = new Light();
|
light.setDeviceCode(deviceName);
|
light.setLightPercent(heartBeatDataPackage.getLightPercent());
|
light.setLight2Percent(heartBeatDataPackage.getLight2Percent());
|
save(light);
|
log.info("新增路灯");
|
}
|
redisService.set(LightKey.REPORT_MAC.key(deviceName), 1, LightKey.REPORT_MAC.expireSeconds());
|
} else {
|
Light light = new Light();
|
light.setLightPercent(heartBeatDataPackage.getLightPercent());
|
light.setLight2Percent(heartBeatDataPackage.getLight2Percent());
|
boolean update = update(light, Wrappers.lambdaUpdate(Light.class).eq(Light::getDeviceCode, deviceName));
|
log.info("更新路灯亮度 {}", update);
|
}
|
}
|
|
/**
|
* 获取路灯列表
|
*
|
* @return 返回组合数据dto
|
*/
|
public List<LightBo> listLight(int pageNo, int pageSize, String keyword, Integer order, Integer seq) {
|
Long clientId = SecurityUtils.getClientId();
|
|
//排序字段
|
String orderByResult = "light_id";
|
//正序、倒叙
|
String orderBySeq = OrderByEnums.ASC.getCode();
|
if (order != null) {
|
switch (order) {
|
case 1:
|
orderByResult = OrderByEnums.LIGHT_POLE_NAME.getCode();
|
break;
|
case 2:
|
orderByResult = OrderByEnums.LIGHT_UPDATE_TIME.getCode();
|
break;
|
case 3:
|
orderByResult = OrderByEnums.LIGHT_CREATE_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(pageNo, pageSize, orderBy);
|
|
List<LightBo> listLight = baseMapper.listLight(clientId, keyword);
|
|
// 获取最近的上报时间
|
List<String> deviceCodeList = listLight.stream().map(Light::getDeviceCode).collect(Collectors.toList());
|
//拆分list
|
List<List<String>> split = CollectionUtil.split(deviceCodeList, 100);
|
|
List<BatchGetDeviceStateResponse.DeviceStatus> deviceStatuses = null;
|
for (List<String> splist : split) {
|
deviceStatuses = MainBoardInvokeSyncService.getInstance().batchGetDeviceState(splist);
|
if (deviceStatuses != null) {
|
for (LightBo lightBo : listLight) {
|
for (BatchGetDeviceStateResponse.DeviceStatus deviceStatus : deviceStatuses) {
|
|
if (lightBo.getDeviceCode() != null && lightBo.getDeviceCode().equals(deviceStatus.getDeviceName())) {
|
if ("ONLINE".equals(deviceStatus.getStatus())) {
|
lightBo.setOnlineStatus(0);
|
} else if ("OFFLINE".equals(deviceStatus.getStatus())) {
|
lightBo.setOnlineStatus(1);
|
} else {
|
lightBo.setOnlineStatus(2);
|
}
|
|
}
|
}
|
|
}
|
}
|
}
|
if (CollectionUtil.isNotEmpty(deviceCodeList)) {
|
List<LightReportData> reportDataList = lightReportDataService.getNewestReportByDeviceCode(deviceCodeList);
|
for (LightBo lightBo : listLight) {
|
deviceCodeList.forEach(code -> {
|
PoleBinding bind = bindingService.getPoleIdByMac(code);
|
if (bind != null && lightBo.getDeviceCode().equals(bind.getDeviceCode())) {
|
Long poleId = bind.getPoleId();
|
Pole pole = poleService.getById(poleId);
|
lightBo.setPoleId(pole.getId());
|
lightBo.setPoleCode(pole.getDeviceCode());
|
lightBo.setPoleName(pole.getPoleName());
|
}
|
});
|
for (LightReportData lightReportData : reportDataList) {
|
if (StrUtil.equals(lightBo.getDeviceCode(), lightReportData.getDeviceCode())) {
|
lightBo.setReportTime(lightReportData.getCreateTime1());
|
break;
|
}
|
}
|
}
|
}
|
|
return listLight;
|
}
|
|
/**
|
* 获取单个路灯信息
|
*
|
* @param deviceCode 设备码
|
* @return
|
*/
|
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);
|
} else {
|
one.setOnlineStatus(0);
|
}
|
return one;
|
}
|
|
/**
|
* 首页灯杆绑定信息
|
*
|
* @param deviceCode
|
* @return
|
*/
|
public EquipmentInfomation getLightInfo(String deviceCode) {
|
EquipmentInfomation equipmentInfo = new EquipmentInfomation();
|
equipmentInfo.setEquipmentType("单灯");
|
if (deviceCode == null || deviceCode.trim().length() == 0) {
|
return equipmentInfo;
|
}
|
Light one = getOne(Wrappers.<Light>lambdaQuery().eq(Light::getDeviceCode, deviceCode));
|
if (one != null) {
|
equipmentInfo.setEquipmentMac(one.getDeviceCode());
|
equipmentInfo.setEquipmentCreateTime(one.getCreateTime());
|
}
|
|
Object o = redisService.get(LightKey.REPORT_MAC.key(deviceCode));
|
if (o != null) {
|
equipmentInfo.setEquipmentState("在线");
|
} else {
|
equipmentInfo.setEquipmentState("离线");
|
}
|
return equipmentInfo;
|
}
|
|
public boolean addRemark(LightRemarkParam param) {
|
Light light = getById(param.getLightId());
|
if (light == null) {
|
throw new BusinessException("找不到路灯");
|
}
|
Light update = new Light();
|
update.setLightId(param.getLightId());
|
update.setRemark(param.getRemark());
|
return updateById(update);
|
}
|
|
/**
|
* 单灯亮度控制
|
*
|
* @return com.sandu.ximon.dao.enums.DeviceRespStatusEnums
|
*/
|
public List<Map<String, Object>> controlBrightness(List<LightControlParam> paramList) {
|
if (CollectionUtil.isEmpty(paramList)) {
|
throw new BusinessException("参数不能为空");
|
}
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
for (LightControlParam param : paramList) {
|
A5LightBrightnessReqInnerFrame lightControlFrame = new A5LightBrightnessReqInnerFrame(param.getBrightness(), param.getLightAddress());
|
A5Frame a5Frame = new A5Frame(A5OrderEnum.REQUEST_LIGHT_DATA.getCode(), lightControlFrame);
|
Map<String, Object> map = new HashMap<>();
|
try {
|
map.put("deviceCode", param.getDeviceCode());
|
WrapResponseCommonFrame<A5LightBrightnessRespInnerFrame> frame
|
= MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), a5Frame, A5LightBrightnessRespInnerFrame.class);
|
//存储控制帧指令
|
StoreOperationRecordsUtils.storeInnerFrameData(param.getDeviceCode(), "单灯帧-亮度控制", a5Frame, frame);
|
|
if (frame == null) {
|
map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
|
resultList.add(map);
|
continue;
|
}
|
String responseStatus = frame.getResponseInnerFrame().getResponseStatus();
|
int status = HexUtil.hexToInt(responseStatus);
|
map.put("status", status);
|
resultList.add(map);
|
|
// 更新亮度成功,修改到数据库
|
if (DeviceRespStatusEnums.SUCCESS.getCode().equals(status)) {
|
Light light = new Light();
|
light.setLightPercent(param.getBrightness());
|
update(light, Wrappers.lambdaUpdate(Light.class).eq(Light::getDeviceCode, param.getDeviceCode()));
|
}
|
} catch (BusinessException e) {
|
map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
|
resultList.add(map);
|
}
|
}
|
|
/**
|
* 服务端批量控灯日志记录开始
|
*/
|
String content = "{控灯请求:" + paramList.toString()
|
+ ", 控灯结果:" + resultList.toString() + "}";
|
List<String> codeList = new ArrayList<>();
|
for (LightControlParam bean : paramList) {
|
codeList.add(bean.getDeviceCode());
|
}
|
StoreOperationRecordsUtils.storeOperationData(codeList, null, "服务端批量控灯", content);
|
/**
|
* 服务端批量控灯日志记录结束
|
*/
|
|
return resultList;
|
}
|
|
|
public BigDecimal getlist(Integer week) {
|
|
Long clientId = SecurityUtils.getClientId();
|
// List<LightBo> listLight = baseMapper.listLight(clientId, null);
|
// List<String> deviceCodeList = listLight.stream().map(LightBo::getDeviceCode).collect(Collectors.toList());
|
|
//获取到正在执行的任务列表
|
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:
|
}
|
}
|
}
|
if (week == 1) {
|
return jisuan(list1);
|
} else if (week == 2) {
|
return jisuan(list2);
|
} else if (week == 3) {
|
return jisuan(list3);
|
} else if (week == 4) {
|
return jisuan(list4);
|
} else if (week == 5) {
|
return jisuan(list5);
|
} else if (week == 6) {
|
return jisuan(list6);
|
} else if (week == 7) {
|
return jisuan(list7);
|
}
|
|
return null;
|
}
|
|
|
public BigDecimal getlistEnergy(Integer week) {
|
|
|
//获取到正在执行的任务列表
|
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:
|
}
|
}
|
}
|
if (week == 1) {
|
return jisuanEnergy(list1);
|
} else if (week == 2) {
|
return jisuanEnergy(list2);
|
} else if (week == 3) {
|
return jisuanEnergy(list3);
|
} else if (week == 4) {
|
return jisuanEnergy(list4);
|
} else if (week == 5) {
|
return jisuanEnergy(list5);
|
} else if (week == 6) {
|
return jisuanEnergy(list6);
|
} else if (week == 7) {
|
return jisuanEnergy(list7);
|
}
|
|
return null;
|
}
|
|
/**
|
* 一天的节能率
|
*
|
* @param list
|
* @return
|
*/
|
public BigDecimal jisuan(List<LightTaskDto> list) {
|
final BigDecimal[] bigDecimalResult = {new BigDecimal(0.00)};
|
/**
|
* 节能率计算开始
|
*/
|
list.forEach(Task -> {
|
// List<BigDecimal> saving = new ArrayList<>();
|
ControlLightCommandVO startTime = parseSwitchLightCommand(Task.getOpenOrder());
|
ControlLightCommandVO endTime = parseSwitchLightCommand(Task.getCloseOrder());
|
//存放节能率
|
//获取到单灯任务的节能率
|
if (Task.getControlOrder() != null && !Task.getControlOrder().isEmpty()) {//有控等指令 拆分计算
|
List<ControlLightCommandVO> controlLightCommandVOS = parseControlLightCommand(Task.getControlOrder());
|
|
for (int i = 0; i < controlLightCommandVOS.size(); i++) {
|
BigDecimal bigDecimal = calculateEnergySaving(startTime, controlLightCommandVOS.get(i));
|
bigDecimalResult[0] = bigDecimalResult[0].add(bigDecimal);
|
if (controlLightCommandVOS.size() == (i + 1)) {
|
BigDecimal bigDecimal1 = calculateEnergySaving(controlLightCommandVOS.get(i), endTime);
|
// System.out.println(bigDecimal1 + "===========================");
|
// saving.add(bigDecimal1);
|
bigDecimalResult[0] = bigDecimalResult[0].add(bigDecimal1);
|
break;
|
}
|
startTime = controlLightCommandVOS.get(i);
|
// saving.add(bigDecimal);
|
}
|
} else {//无控灯指令 直接计算
|
BigDecimal bigDecimal = calculateEnergySaving(startTime, endTime);
|
// saving.add(bigDecimal);
|
bigDecimalResult[0] = bigDecimalResult[0].add(bigDecimal);
|
}
|
});
|
return bigDecimalResult[0];
|
|
/**
|
* 节能率计算结束
|
*/
|
}
|
|
/**
|
* 单个任务一天的节能率
|
*
|
* @return
|
*/
|
public BigDecimal jisuan(LightTaskDto Task, LightTaskPoleRelation bean) {
|
final BigDecimal[] bigDecimalResult = {new BigDecimal(0.00)};
|
/**
|
* 节能率计算开始
|
*/
|
//获取昨天的星期数
|
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime yesterday = now.minusDays(1);
|
int week = yesterday.getDayOfWeek().getValue();
|
|
//判断Task.getWeekList()是否包含昨天的星期数 不包含直接返回0 不进行计算
|
if (Task.getWeekList() != null && !Task.getWeekList().isEmpty()) {
|
if (!Task.getWeekList().contains(week)) {
|
return new BigDecimal(1);
|
}
|
} else {
|
return new BigDecimal(1);
|
}
|
|
|
ControlLightCommandVO startTime = parseSwitchLightCommand(Task.getOpenOrder());
|
ControlLightCommandVO endTime = parseSwitchLightCommand(Task.getCloseOrder());
|
//存放节能率
|
//获取到单灯任务的节能率
|
if (Task.getControlOrder() != null && !Task.getControlOrder().isEmpty()) {//有控等指令 拆分计算
|
List<ControlLightCommandVO> controlLightCommandVOS = parseControlLightCommand(Task.getControlOrder());
|
|
for (int i = 0; i < controlLightCommandVOS.size(); i++) {
|
BigDecimal bigDecimal = calculateEnergySaving(startTime, controlLightCommandVOS.get(i));
|
bigDecimalResult[0] = bigDecimalResult[0].add(bigDecimal);
|
if (controlLightCommandVOS.size() == (i + 1)) {
|
BigDecimal bigDecimal1 = calculateEnergySaving(controlLightCommandVOS.get(i), endTime);
|
bigDecimalResult[0] = bigDecimalResult[0].add(bigDecimal1);
|
break;
|
}
|
startTime = controlLightCommandVOS.get(i);
|
// saving.add(bigDecimal);
|
}
|
} else {//无控灯指令 直接计算
|
BigDecimal bigDecimal = calculateEnergySaving(startTime, endTime);
|
// saving.add(bigDecimal);
|
bigDecimalResult[0] = bigDecimalResult[0].add(bigDecimal);
|
}
|
return bigDecimalResult[0];
|
|
/**
|
* 节能率计算结束
|
*/
|
}
|
|
|
/**
|
* 一天的能耗
|
*
|
* @param list
|
* @return
|
*/
|
public BigDecimal jisuanEnergy(List<LightTaskDto> list) {
|
//存放能耗
|
final BigDecimal[] bigEnergy = {new BigDecimal(0.00)};
|
/**
|
* 节能率计算开始
|
*/
|
list.forEach(Task -> {
|
List<PoleTaskLightPowerBo> poleTaskLightPowerBos = SpringContextHolder.getBean(LightTaskMapper.class).listLightTaskByTaskId(Task.getTaskId());
|
ControlLightCommandVO startTime = parseSwitchLightCommand(Task.getOpenOrder());
|
ControlLightCommandVO endTime = parseSwitchLightCommand(Task.getCloseOrder());
|
//获取到单灯任务的节能率
|
if (!Task.getControlOrder().isEmpty()) {//有控等指令 拆分计算
|
List<ControlLightCommandVO> controlLightCommandVOS = parseControlLightCommand(Task.getControlOrder());
|
|
|
for (int i = 0; i < controlLightCommandVOS.size(); i++) {
|
//得到时长*亮度
|
BigDecimal bigEnergy1 = calculateEnergyConsumption(startTime, controlLightCommandVOS.get(i));
|
//判断 Energy==0 则不计算
|
if (bigEnergy1.compareTo(new BigDecimal(0)) != 0) {
|
//计算能耗(总 时长*亮度*功率)
|
BigDecimal totalEnergy = totalEnergy(bigEnergy1, Task.getLightAdress(), poleTaskLightPowerBos);
|
bigEnergy[0] = bigEnergy[0].add(totalEnergy);
|
}
|
if (controlLightCommandVOS.size() == (i + 1)) {
|
BigDecimal bigEnergy2 = calculateEnergyConsumption(controlLightCommandVOS.get(i), endTime);
|
|
System.out.println(bigEnergy2 + "时长*亮度===========================");
|
|
//计算能耗(总 时长*亮度*功率)
|
if (bigEnergy2.compareTo(new BigDecimal(0)) != 0) {
|
BigDecimal totalEnergy3 = totalEnergy(bigEnergy2, Task.getLightAdress(), poleTaskLightPowerBos);
|
bigEnergy[0] = bigEnergy[0].add(totalEnergy3);
|
}
|
break;
|
}
|
startTime = controlLightCommandVOS.get(i);
|
//计算能耗(总 时长*亮度*功率)
|
}
|
} else {//无控灯指令 直接计算
|
//计算能耗(部分 时长*亮度)
|
BigDecimal Energy = calculateEnergyConsumption(startTime, endTime);
|
//计算能耗(总 时长*亮度*功率)
|
//判断 Energy==0 则不计算
|
if (Energy.compareTo(new BigDecimal(0)) != 0) {
|
BigDecimal totalEnergy = totalEnergy(Energy, Task.getLightAdress(), poleTaskLightPowerBos);
|
bigEnergy[0] = bigEnergy[0].add(totalEnergy);
|
}
|
|
// saving.add(bigDecimal);
|
|
}
|
});
|
return bigEnergy[0];
|
|
/**
|
* 计算能耗结束
|
*/
|
}
|
|
|
/**
|
* 一天的能耗
|
*
|
* @param
|
* @param bean
|
* @return
|
*/
|
public BigDecimal jisuanEnergy(LightTaskDto Task, LightTaskPoleRelation bean) {
|
//存放能耗
|
final BigDecimal[] bigEnergy = {new BigDecimal(0.00)};
|
|
//获取昨天的星期数
|
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime yesterday = now.minusDays(1);
|
int week = yesterday.getDayOfWeek().getValue();
|
|
//判断Task.getWeekList()是否包含昨天的星期数 不包含直接返回0 不进行计算
|
if (Task.getWeekList() != null && !Task.getWeekList().isEmpty()) {
|
if (!Task.getWeekList().contains(week)) {
|
return BigDecimal.ZERO;
|
}
|
} else {
|
return BigDecimal.ZERO;
|
}
|
|
/**
|
* 能耗计算开始
|
*/
|
// 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());
|
//获取到单灯任务的节能率
|
if (!Task.getControlOrder().isEmpty()) {//有控等指令 拆分计算
|
List<ControlLightCommandVO> controlLightCommandVOS = parseControlLightCommand(Task.getControlOrder());
|
|
|
for (int i = 0; i < controlLightCommandVOS.size(); i++) {
|
//得到时长*亮度
|
BigDecimal bigEnergy1 = calculateEnergyConsumption(startTime, controlLightCommandVOS.get(i));
|
//判断 Energy==0 则不计算
|
if (bigEnergy1.compareTo(new BigDecimal(0)) != 0) {
|
//计算能耗(总 时长*亮度*功率)
|
BigDecimal totalEnergy = totalEnergy(bigEnergy1, Task.getLightAdress(), poleTaskLightPowerBos);
|
bigEnergy[0] = bigEnergy[0].add(totalEnergy);
|
}
|
if (controlLightCommandVOS.size() == (i + 1)) {
|
BigDecimal bigEnergy2 = calculateEnergyConsumption(controlLightCommandVOS.get(i), endTime);
|
|
System.out.println(bigEnergy2 + "时长*亮度===========================");
|
|
//计算能耗(总 时长*亮度*功率)
|
if (bigEnergy2.compareTo(new BigDecimal(0)) != 0) {
|
BigDecimal totalEnergy3 = totalEnergy(bigEnergy2, Task.getLightAdress(), poleTaskLightPowerBos);
|
bigEnergy[0] = bigEnergy[0].add(totalEnergy3);
|
}
|
break;
|
}
|
startTime = controlLightCommandVOS.get(i);
|
//计算能耗(总 时长*亮度*功率)
|
}
|
} else {//无控灯指令 直接计算
|
//计算能耗(部分 时长*亮度)
|
BigDecimal Energy = calculateEnergyConsumption(startTime, endTime);
|
//计算能耗(总 时长*亮度*功率)
|
//判断 Energy==0 则不计算
|
if (Energy.compareTo(new BigDecimal(0)) != 0) {
|
BigDecimal totalEnergy = totalEnergy(Energy, Task.getLightAdress(), poleTaskLightPowerBos);
|
bigEnergy[0] = bigEnergy[0].add(totalEnergy);
|
}
|
|
// saving.add(bigDecimal);
|
|
}
|
return bigEnergy[0];
|
|
/**
|
* 计算能耗结束
|
*/
|
}
|
|
|
private BigDecimal totalEnergy(BigDecimal bigEnergy2, String lightAdress, List<PoleTaskLightPowerBo> poleTaskLightPowerBos) {
|
|
//poleTaskLightPowerBos 包含该任务所有的灯的功率
|
//计算功率之和
|
BigDecimal totalPower = new BigDecimal(0.00);
|
if ("FFFF".equals(lightAdress)) {
|
int totalPower1 = poleTaskLightPowerBos.stream().mapToInt(PoleTaskLightPowerBo::getPower1).sum();
|
int totalPower2 = poleTaskLightPowerBos.stream().mapToInt(PoleTaskLightPowerBo::getPower2).sum();
|
totalPower = new BigDecimal(totalPower1 + totalPower2);
|
} else if ("0001".equals(lightAdress)) {
|
int totalPower1 = poleTaskLightPowerBos.stream().mapToInt(PoleTaskLightPowerBo::getPower1).sum();
|
totalPower = new BigDecimal(totalPower1);
|
} else if ("0002".equals(lightAdress)) {
|
int totalPower2 = poleTaskLightPowerBos.stream().mapToInt(PoleTaskLightPowerBo::getPower2).sum();
|
totalPower = new BigDecimal(totalPower2);
|
} else {
|
return null;
|
}
|
return totalPower.multiply(bigEnergy2);
|
}
|
|
/**
|
* 解析开关灯指令
|
*/
|
public ControlLightCommandVO parseSwitchLightCommand(String command) {
|
char[] chars = command.toCharArray();
|
ControlLightCommandVO vo = new ControlLightCommandVO();
|
if (chars.length == 7) {
|
int hour = Integer.valueOf(command.substring(0, 2));
|
int min = Integer.valueOf(command.substring(2, 4));
|
int brightness = Integer.valueOf(command.substring(4, 7));
|
vo.setHour(hour);
|
vo.setMin(min);
|
vo.setBrightness(brightness);
|
}
|
return vo;
|
}
|
|
/**
|
* 解析控灯指令
|
*/
|
public List<ControlLightCommandVO> parseControlLightCommand(String command) {
|
char[] chars = command.toCharArray();
|
int i = chars.length / 7;
|
|
List<ControlLightCommandVO> list = new ArrayList<>();
|
|
for (int j = 0; j < i; j++) {
|
int hour = Integer.valueOf(command.substring(0 + (j * 7), 2 + (j * 7)));
|
int min = Integer.valueOf(command.substring(2 + (j * 7), 4 + (j * 7)));
|
int brightness = Integer.valueOf(command.substring(4 + (j * 7), 7 + (j * 7)));
|
ControlLightCommandVO vo = new ControlLightCommandVO();
|
vo.setHour(hour);
|
vo.setMin(min);
|
vo.setBrightness(brightness);
|
list.add(vo);
|
}
|
return list;
|
}
|
|
//计算节能率
|
public BigDecimal calculateEnergySaving(ControlLightCommandVO v1, ControlLightCommandVO v2) {
|
|
// BigDecimal hour = BigDecimal.valueOf((v2.getHour() - v1.getHour()));
|
// BigDecimal hour;
|
if (v1.getBrightness() == 0) {
|
return new BigDecimal(1);
|
}
|
double hour;
|
double min;
|
//计算时长
|
if (v2.getHour() > v1.getHour()) {
|
hour = v2.getHour() - v1.getHour();
|
} else if (v2.getHour() < v1.getHour()) {
|
hour = 24 + (v2.getHour() - v1.getHour());
|
} else {
|
hour = 0;
|
}
|
//计算分钟
|
|
if (v2.getMin() > v1.getMin()) {
|
min = v2.getMin() - v1.getMin();
|
} else if (v2.getMin() < v1.getMin()) {
|
min = 60 + (v1.getMin() - v2.getMin());
|
hour = hour - 1;
|
} else {
|
min = 0;
|
}
|
//计算时长
|
BigDecimal totalTime = BigDecimal.valueOf(hour * 60 + min);
|
|
|
//计算节能率 ( (1-v1.getBrightness()/100)*totalTime/1440 ) 保留两位小数
|
// 计算 1-v1.getBrightness()/100的值
|
BigDecimal Brightness = BigDecimal.valueOf(100 - v1.getBrightness());
|
//Brightness/100*totalTime/1440 保留两位小数 Brightness没有除以100 在总时间*100
|
BigDecimal energySaving = Brightness.multiply(totalTime).divide(new BigDecimal(144000), 2, BigDecimal.ROUND_HALF_UP);
|
|
System.out.println(energySaving + "节能率");
|
return energySaving;
|
}
|
|
|
//计算能耗(部分 时长*亮度)
|
public BigDecimal calculateEnergyConsumption(ControlLightCommandVO v1, ControlLightCommandVO v2) {
|
|
if (v1.getBrightness() == 0) {
|
return BigDecimal.ZERO;
|
}
|
double hour;
|
double min;
|
//计算时长
|
if (v2.getHour() > v1.getHour()) {
|
hour = v2.getHour() - v1.getHour();
|
} else if (v2.getHour() < v1.getHour()) {
|
hour = 24 + (v2.getHour() - v1.getHour());
|
} else {
|
hour = 0;
|
}
|
//计算分钟
|
|
if (v2.getMin() > v1.getMin()) {
|
min = v2.getMin() - v1.getMin();
|
} else if (v2.getMin() < v1.getMin()) {
|
min = 60 + (v1.getMin() - v2.getMin());
|
hour = hour - 1;
|
} else {
|
min = 0;
|
}
|
//计算时长
|
BigDecimal totalTime = BigDecimal.valueOf(hour + min / 60);
|
//计算亮灯时长*亮度
|
BigDecimal energyConsumption = totalTime.multiply(BigDecimal.valueOf(v1.getBrightness())).divide(BigDecimal.valueOf(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
|
return energyConsumption;
|
}
|
|
|
/**
|
* 用户拥有的路灯
|
*
|
* @return
|
*/
|
public List<Light> listLight() {
|
List<LightBo> listLight;
|
if (SecurityUtils.getClientId() != null) {
|
listLight = baseMapper.listLight(SecurityUtils.getUserId(), null);
|
} else {
|
listLight = baseMapper.listLight(null, null);
|
}
|
List<Light> lightList = new ArrayList<>();
|
for (LightBo bean : listLight) {
|
Light light = getLight(bean.getDeviceCode());
|
lightList.add(light);
|
}
|
return lightList;
|
}
|
|
/**
|
* 用户拥有的路灯(用于首页数据统计)
|
*
|
* @return
|
*/
|
public List<LightBo> listLightOnHome() {
|
List<LightBo> listLight;
|
if (SecurityUtils.getClientId() != null) {
|
listLight = baseMapper.listLight(SecurityUtils.getUserId(), null);
|
} else {
|
listLight = baseMapper.listLight(null, null);
|
}
|
return listLight;
|
}
|
|
/**
|
* 获取用户所有的设备码
|
*/
|
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, orderBy);
|
list = baseMapper.listCode(null, keyword, deviceCode);
|
}
|
|
return CommonPage.restPage(list);
|
}
|
|
public boolean setPower(LightPowerSettingParam lightPowerSettingParam) {
|
if (lightPowerSettingParam.getLightIds().size() == 0) {
|
throw new BusinessException("灯杆ID不能为空");
|
}
|
List<Light> lights = listByIds(lightPowerSettingParam.getLightIds());
|
lights.forEach(light -> {
|
light.setPower1(lightPowerSettingParam.getPower1());
|
light.setPower2(lightPowerSettingParam.getPower2());
|
//存在非0功率 即为存在该灯头
|
if (lightPowerSettingParam.getPower1() != null || lightPowerSettingParam.getPower1() != 0) {
|
light.setLight1(1);
|
} else if (lightPowerSettingParam.getPower1() == 0) {
|
//手动设置灯头功率为0 即不存在该灯头
|
light.setLight1(0);
|
} else {
|
light.setLight1(0);
|
}
|
//存在非0功率 即为存在该灯头
|
if (lightPowerSettingParam.getPower2() != null || lightPowerSettingParam.getPower2() != 0) {
|
light.setLight2(1);
|
} else if (lightPowerSettingParam.getPower2() == 0) {
|
//手动设置灯头功率为0 即不存在该灯头
|
light.setLight2(0);
|
} else {
|
light.setLight2(0);
|
}
|
light.setLightCount(lightPowerSettingParam.getLightCount());
|
});
|
return updateBatchById(lights);
|
}
|
|
|
/**
|
* 向Redis中存入设备状态
|
*/
|
public void setCacheData() {
|
|
List<String> collect = list().stream().map(Light::getDeviceCode).collect(Collectors.toList());
|
List<List<String>> split = CollectionUtil.split(collect, 100);
|
|
List<BatchGetDeviceStateResponse.DeviceStatus> deviceStatuses = null;
|
List<RedisDeviceStatus> statusList = null;
|
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 {
|
device.setStatus(2);
|
}
|
statusList.add(device);
|
}
|
|
}
|
}
|
|
statusList.forEach(status -> {
|
redisUtils.set(DeviceRedisKey.LIGHT_DEVICE + status.getDeviceId(), 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("单灯主动同步时间请求异常,单灯信息不存在!");
|
}
|
//单灯任务信息
|
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;
|
}
|
}
|