Commit b2c7f8a8 authored by duanruiming's avatar duanruiming

[add] 海信方案环相位解析

parent d0734422
package net.wanji.utc.common.typeenum;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Objects;
/**
* @author duanruiming
* @date 2024/11/12 15:14
*/
@Getter
@AllArgsConstructor
public enum HisenseTurnEnum {
/**
*
*/
TURN_1(1, 1, "左"),
TURN_2(2, 2, "直"),
TURN_3(3, 3, "右"),
TURN_4(4, 4, "调头"),
TURN_5(5, 1, "左调头"),
TURN_6(6, 2, "左直"),
TURN_7(7, 1, "左右"),
TURN_8(8, 2, "直右"),
TURN_9(9, 2, "左直右"),
TURN_11(11, 21, "入口行人"),
TURN_10(10, 2, "直调头"),
TURN_12(12, 22, "出口行人"),
TURN_13(13, 20, "出入口行人"),
TURN_14(14, 2, "左直调头"),
TURN_15(15, 3, "右调头"),
TURN_16(16, 1, "左右调头"),
TURN_17(17, 2, "直右掉头"),
TURN_18(18, 2, "左直右掉头");
private Integer hisenseTurn;
private Integer wjLightsTurn;
private String desc;
public static Integer getWjLightsTurn(Integer hisenseTurn) {
for (HisenseTurnEnum value : HisenseTurnEnum.values()) {
if (Objects.equals(hisenseTurn, value.getHisenseTurn())) {
return value.getWjLightsTurn();
}
}
return 0;
}
}
package net.wanji.utc.common.typeenum;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* @author duanruiming
* @date 2024/11/12 15:04
*/
@Getter
@AllArgsConstructor
public enum HiseseDirEnum {
// '灯组方向:1北;2东北;3东;4东南;5南;6西南;7西;8西北',
ZERO(0,1, "北"),
ONE(1,3, "东"),
TWO(2,5, "南"),
THREE(3,7, "西"),
FOUR(4,2, "东北"),
FIVE(5,4, "东南"),
SIX(6,6, "西南"),
SEVEN(7,8, "西北");
private Integer hisenseDir;
private Integer wjLightsDir;
private String desc;
public static Integer getWjLightsDir(Integer hisenseDir) {
for (HiseseDirEnum value : HiseseDirEnum.values()) {
if (Objects.equals(hisenseDir, value.getHisenseDir())) {
return value.getWjLightsDir();
}
}
return 0;
}
public static void main(String[] args) throws Exception {
String format = String.format("%16s", Integer.toBinaryString(26)).replace(' ', '0');
char[] chars = format.toCharArray();
List<Integer> result = new ArrayList<>();
int length = chars.length;
for (int i = 0; i < length; i++) {
if (chars[i] == '1') {
result.add(length - i);
}
}
Collections.sort(result);
result.forEach(i -> {
System.err.println(i);
});
}
}
...@@ -2,6 +2,8 @@ package net.wanji.utc.dto.ring; ...@@ -2,6 +2,8 @@ package net.wanji.utc.dto.ring;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* @author duanruiming * @author duanruiming
* @date 2025/03/28 14:41 * @date 2025/03/28 14:41
...@@ -9,8 +11,18 @@ import lombok.Data; ...@@ -9,8 +11,18 @@ import lombok.Data;
@Data @Data
public class RingPhaseInfoDTO { public class RingPhaseInfoDTO {
private Integer schemeNo;
private Integer offset;
private Integer cycleLen;
private Integer ringNo;
private Integer phaseId; private Integer phaseId;
private Integer sort;
private Integer phaseTime; private Integer phaseTime;
private Integer redTime; private Integer redTime;
...@@ -23,6 +35,10 @@ public class RingPhaseInfoDTO { ...@@ -23,6 +35,10 @@ public class RingPhaseInfoDTO {
private Integer maxGTime; private Integer maxGTime;
/**
* 字段 Direction 和 ChannelDim 都表示相位的放行方向,但 Direction 不包含行人放行
* 信息,因此,建议使用 ChannelDim 字段,保留 Direction 字段仅为兼容之前版本。
*/
private Integer direction; private Integer direction;
private Integer channel; private Integer channel;
...@@ -30,4 +46,15 @@ public class RingPhaseInfoDTO { ...@@ -30,4 +46,15 @@ public class RingPhaseInfoDTO {
private Integer concurrent; private Integer concurrent;
private Integer phaseStatus; private Integer phaseStatus;
private List<DirTurn> dirTurnInfoList;
/**
* 转换后万集的方向转向,不包含行人
*/
@Data
public static class DirTurn {
private Integer dir;
private Integer turn;
}
} }
...@@ -6,13 +6,18 @@ import lombok.extern.slf4j.Slf4j; ...@@ -6,13 +6,18 @@ import lombok.extern.slf4j.Slf4j;
import net.wanji.common.framework.rest.JsonViewObject; import net.wanji.common.framework.rest.JsonViewObject;
import net.wanji.common.utils.tool.JacksonUtils; import net.wanji.common.utils.tool.JacksonUtils;
import net.wanji.common.utils.tool.StringUtils; import net.wanji.common.utils.tool.StringUtils;
import net.wanji.databus.dao.entity.CrossLightsPO;
import net.wanji.databus.dao.entity.CrossPhaseLightsPO;
import net.wanji.databus.dto.CrossSchemeRingsDTO; import net.wanji.databus.dto.CrossSchemeRingsDTO;
import net.wanji.databus.po.CrossInfoPO; import net.wanji.databus.po.CrossInfoPO;
import net.wanji.databus.po.CrossSchemeRings; import net.wanji.databus.po.CrossSchemeRings;
import net.wanji.feign.service.common.FeignCommon; import net.wanji.feign.service.common.FeignCommon;
import net.wanji.utc.cache.CrossInfoCache; import net.wanji.utc.cache.CrossInfoCache;
import net.wanji.utc.cache.UtcFeignClientCache; import net.wanji.utc.cache.UtcFeignClientCache;
import net.wanji.utc.common.typeenum.HisenseTurnEnum;
import net.wanji.utc.common.typeenum.HiseseDirEnum;
import net.wanji.utc.dto.ring.RingPhaseInfoDTO; import net.wanji.utc.dto.ring.RingPhaseInfoDTO;
import net.wanji.utc.util.CommonUtils;
import net.wanji.utc.util.RedisUtil; import net.wanji.utc.util.RedisUtil;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -25,7 +30,7 @@ import java.util.stream.Collectors; ...@@ -25,7 +30,7 @@ import java.util.stream.Collectors;
/** /**
* @author duanruiming * @author duanruiming
* @date 2025/03/26 10:00 * @date 2025/03/26 10:00
* @description 每半小时同步海信信号机方案环图请求 * @description 每十分钟同步海信信号机方案环图请求
*/ */
@Component @Component
@Slf4j @Slf4j
...@@ -38,14 +43,13 @@ public class HisenseSchemeRingTask { ...@@ -38,14 +43,13 @@ public class HisenseSchemeRingTask {
@Resource @Resource
private UtcFeignClientCache utcFeignClientCache; private UtcFeignClientCache utcFeignClientCache;
@Scheduled(fixedRate = 1000, initialDelay = 30 * 1000) @Scheduled(fixedRate = 10 * 60 * 1000, initialDelay = 30 * 1000)
public void getSchemeRing() throws Exception { public void getSchemeRing() throws Exception {
List<CrossInfoPO> crossInfoList = CrossInfoCache.crossInfoList; List<CrossInfoPO> crossInfoList = CrossInfoCache.crossInfoList;
ObjectMapper mapper = JacksonUtils.getInstance(); ObjectMapper mapper = JacksonUtils.getInstance();
if (!CollectionUtils.isEmpty(crossInfoList)) { if (!CollectionUtils.isEmpty(crossInfoList)) {
List<CrossInfoPO> collect = crossInfoList.stream().filter(po -> Objects.equals(22, po.getManufacturerId())).collect(Collectors.toList()); List<CrossInfoPO> collect = crossInfoList.stream().filter(po -> Objects.equals(22, po.getManufacturerId())).collect(Collectors.toList());
List<CrossInfoPO> testList = crossInfoList.stream().filter(po -> Objects.equals("13MOD0B5SI0", po.getId())).collect(Collectors.toList()); for (CrossInfoPO crossInfoPO : collect) {
for (CrossInfoPO crossInfoPO : testList) {
String crossId = crossInfoPO.getId(); String crossId = crossInfoPO.getId();
String manufacturerCode = crossInfoCache.getManufacturerCodeByCrossId(crossId); String manufacturerCode = crossInfoCache.getManufacturerCodeByCrossId(crossId);
FeignCommon utcFeignClientService = utcFeignClientCache.getUtcFeignClientService(manufacturerCode); FeignCommon utcFeignClientService = utcFeignClientCache.getUtcFeignClientService(manufacturerCode);
...@@ -54,7 +58,6 @@ public class HisenseSchemeRingTask { ...@@ -54,7 +58,6 @@ public class HisenseSchemeRingTask {
JsonViewObject jsonViewObject = null; JsonViewObject jsonViewObject = null;
try { try {
jsonViewObject = utcFeignClientService.crossSchemeRings(crossSchemeRingsDTO); jsonViewObject = utcFeignClientService.crossSchemeRings(crossSchemeRingsDTO);
log.info("方案环图请求,crossId:{}, result:{}", crossId, jsonViewObject);
if (Objects.nonNull(jsonViewObject) && Objects.equals(200, jsonViewObject.getCode())) { if (Objects.nonNull(jsonViewObject) && Objects.equals(200, jsonViewObject.getCode())) {
Object content = jsonViewObject.getContent(); Object content = jsonViewObject.getContent();
String contentStr = mapper.writeValueAsString(content); String contentStr = mapper.writeValueAsString(content);
...@@ -85,41 +88,94 @@ public class HisenseSchemeRingTask { ...@@ -85,41 +88,94 @@ public class HisenseSchemeRingTask {
} }
List<CrossSchemeRings.Phase> phaseList = crossSchemeRings.getPhaseList(); List<CrossSchemeRings.Phase> phaseList = crossSchemeRings.getPhaseList();
if (!CollectionUtils.isEmpty(phaseList)) { if (!CollectionUtils.isEmpty(phaseList)) {
List<Integer> greenTime = new ArrayList<>(); List<Integer> greenTimeList = new ArrayList<>();
List<Integer> yellowTime = new ArrayList<>(); List<Integer> yellowTimeList = new ArrayList<>();
List<Integer> redTime = new ArrayList<>(); List<Integer> redTimeList = new ArrayList<>();
List<Integer> maxGTime = new ArrayList<>(); List<Integer> maxGTimeList = new ArrayList<>();
List<Integer> minGTime = new ArrayList<>(); List<Integer> minGTimeList = new ArrayList<>();
List<Integer> direction = new ArrayList<>(); List<Integer> directionList = new ArrayList<>();
List<Integer> channelDim = new ArrayList<>(); List<Integer> channelDimList = new ArrayList<>();
List<Integer> concurrent = new ArrayList<>(); List<Integer> concurrentList = new ArrayList<>();
for (CrossSchemeRings.Phase phase : phaseList) { for (CrossSchemeRings.Phase phase : phaseList) {
String greenTimeStr = phase.getGreenTime(); String greenTimeStr = phase.getGreenTime();
String yellowTimeStr = phase.getYellowTime(); String yellowTimeStr = phase.getYellowTime();
String redTimeStr = phase.getRedTime(); String redTimeStr = phase.getRedTime();
String maxGTimeStr = phase.getMaxGTime(); String maxGTimeStr = phase.getMaxGTime();
String minGTimeStr = phase.getMinGTime(); String minGTimeStr = phase.getMinGTime();
String directionStr = phase.getDirection(); //String directionStr = phase.getDirection();
String channelDimStr = phase.getChannelDim(); String channelDimStr = phase.getChannelDim();
String concurrentStr = phase.getConcurrent(); String concurrentStr = phase.getConcurrent();
greenTime = getListInt(greenTimeStr); greenTimeList = getListInt(greenTimeStr);
yellowTime = getListInt(yellowTimeStr); yellowTimeList = getListInt(yellowTimeStr);
redTime = getListInt(redTimeStr); redTimeList = getListInt(redTimeStr);
maxGTime = getListInt(maxGTimeStr); maxGTimeList = getListInt(maxGTimeStr);
minGTime = getListInt(minGTimeStr); minGTimeList = getListInt(minGTimeStr);
direction = getListInt(directionStr); //directionList = getListInt(directionStr);
channelDim = getListInt(channelDimStr); channelDimList = getListInt(channelDimStr);
concurrent = getListInt(concurrentStr); concurrentList = getListInt(concurrentStr);
} }
List<RingPhaseInfoDTO> RingPhaseInfoDTOS = new ArrayList<RingPhaseInfoDTO>(16); List<RingPhaseInfoDTO> ringPhaseInfoDTOS = new ArrayList<RingPhaseInfoDTO>(16);
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
RingPhaseInfoDTO ringPhaseInfoDTO = new RingPhaseInfoDTO(); RingPhaseInfoDTO ringPhaseInfoDTO = new RingPhaseInfoDTO();
ringPhaseInfoDTO.setPhaseId(i); Integer phaseId = i + 1;
ringPhaseInfoDTO.setPhaseId(phaseId);
Integer curRingNo = 0;
Integer sort = -1;
for (Map.Entry<Integer, List<Integer>> entry : ringPhaseMap.entrySet()) {
List<Integer> value = entry.getValue();
if (value.contains(phaseId)) {
sort = value.indexOf(phaseId);
curRingNo = entry.getKey();
}
}
if (!Objects.equals(-1, sort)) {
ringPhaseInfoDTO.setSort(sort + 1);
}
ringPhaseInfoDTO.setSchemeNo((Integer.valueOf(schemeNo) + 2) / 3);
ringPhaseInfoDTO.setOffset(Integer.valueOf(offset));
ringPhaseInfoDTO.setCycleLen(Integer.valueOf(cycleLen));
ringPhaseInfoDTO.setRingNo(curRingNo);
Integer greenTime = greenTimeList.get(i);
Integer yellowTime = yellowTimeList.get(i);
Integer redTime = redTimeList.get(i);
ringPhaseInfoDTO.setPhaseTime(greenTime + redTime + yellowTime);
ringPhaseInfoDTO.setGreenTime(greenTime);
ringPhaseInfoDTO.setYellowTime(yellowTime);
ringPhaseInfoDTO.setRedTime(redTime);
ringPhaseInfoDTO.setMaxGTime(maxGTimeList.get(i));
ringPhaseInfoDTO.setMinGTime(minGTimeList.get(i));
//ringPhaseInfoDTO.setDirection(directionList.get(i));
Integer channel = channelDimList.get(i);
String binaryString = Long.toBinaryString(channel);
//获取方向转向分组
List<String> binaryList = CommonUtils.groupStringFromRight(binaryString);
List<RingPhaseInfoDTO.DirTurn> dirTurnList = new ArrayList<>();
for (String readUtf8Line : binaryList) {
RingPhaseInfoDTO.DirTurn dirTurn = new RingPhaseInfoDTO.DirTurn();
// 高三位 方向
String dir = readUtf8Line.substring(0, 3);
// 低五位 转向
String turn = readUtf8Line.substring(3);
Integer wjLightsDir = HiseseDirEnum.getWjLightsDir(Integer.parseInt(dir, 2));
Integer wjLightsTurn = HisenseTurnEnum.getWjLightsTurn(Integer.parseInt(turn, 2));
// 不需要行人,不需要右转
if (Objects.equals(0, wjLightsDir) || Objects.equals(0, wjLightsTurn)
|| Objects.equals(20, wjLightsTurn) || Objects.equals(3, wjLightsTurn)){
continue;
}
dirTurn.setDir(wjLightsDir);
dirTurn.setTurn(wjLightsTurn);
dirTurnList.add(dirTurn);
}
ringPhaseInfoDTO.setDirTurnInfoList(dirTurnList);
ringPhaseInfoDTO.setChannel(channel);
ringPhaseInfoDTO.setConcurrent(concurrentList.get(i));
ringPhaseInfoDTOS.add(ringPhaseInfoDTO);
} }
log.info("路口编号:{},当前环相位列表:{}", crossId, mapper.writeValueAsString(ringPhaseInfoDTOS));
redisUtil.setHash("utc-hisense-ring-phase", crossId, mapper.writeValueAsString(ringPhaseInfoDTOS));
} }
} }
//redisUtil.setHash("utc_scheme_offset", crossId, mapper.writeValueAsString(crossSchemeRings));
} else { } else {
log.error("海信环图请求异常:{}", jsonViewObject); log.error("海信环图请求异常:{}", jsonViewObject);
} }
......
package net.wanji.utc.util;
import cn.hutool.core.util.HexUtil;
import freemarker.template.utility.StringUtil;
import net.wanji.common.utils.tool.ScheduleUtil;
import net.wanji.utc.common.typeenum.HisenseTurnEnum;
import net.wanji.utc.common.typeenum.HiseseDirEnum;
import java.util.ArrayList;
import java.util.List;
/**
* @author duanruiming
* @date 2023/06/20 15:07
*/
public class CommonUtils {
/**
* 将数组转化为16进制字符串
*
* @param array
* @return
*/
public static String getHex4Array(int[] array) {
StringBuilder sb = new StringBuilder();
for (int i : array) {
sb.append(i);
}
Integer binary = Integer.valueOf(sb.reverse().toString(), 2);
return HexUtil.toHex(binary);
}
/**
* 将时间转化为16进制 00:00 --> 061E0
*
* @param time
* @return
*/
public static String getHourMinuteHex(String time) {
StringBuffer sb = new StringBuffer();
String[] split = time.split(":");
String hour = String.format("%02x", Integer.valueOf(split[0]));
String minute = String.format("%02x", Integer.valueOf(split[1]));
return sb.append(hour).append(minute).toString();
}
/**
* 将相位转化为64位数组,在转化为16位的16进制
*
* @param param
* @return
*/
public static String getBinary(Integer param) {
int[] array = new int[64];
array[param - 1] = 1;
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < array.length / 8; i++) {
StringBuffer sb = new StringBuffer();
for (int j = 0; j < 8; j++) {
sb.append(array[i * 8 + j]);
}
String hex = String.format("%02x", Integer.parseInt(sb.reverse().toString(), 2));
resultSb.insert(0, hex);
}
return StringUtil.leftPad(resultSb.toString(), 16, "0");
}
/**
* 将单个参数转化为4位二进制
*
* @param param
* @return
*/
public static Integer get4BinaryInteger(Integer param) {
int[] array = new int[4];
int index = param % 4;
if (param % 4 != 0) {
array[4 - index] = 1;
} else {
array[0] = 1;
}
StringBuffer sb = new StringBuffer();
for (int j = 0; j < 4; j++) {
sb.append(array[j]);
}
return Integer.parseInt(sb.toString(), 2);
}
/**
* 通过灯组编号获取灯组转向, 1 左转 2 直 3 右 20 行人
*
* @param lightId
* @return
*/
public static Integer getTurnByLightsId(Integer lightId) {
Integer turn = null;
if (lightId % 4 == 0) {
turn = 1;
}
if (lightId % 4 == 1) {
turn = 2;
}
if (lightId % 4 == 2) {
turn = 3;
}
if (lightId % 4 == 3) {
turn = 20;
}
return turn;
}
public static Integer getDirByLightsId(Integer lightsId) {
Integer dir = null;
if (lightsId < 4) {
dir = 1;
}
if (lightsId >= 4 && lightsId < 8) {
dir = 3;
}
if (lightsId >= 8 && lightsId < 12) {
dir = 5;
}
if (lightsId >= 12 && lightsId < 16) {
dir = 7;
}
return dir;
}
/**
* @Description 将字符串分成八个一组,不够的最前面补0
* @Param [input]
* @return java.util.List<java.lang.String>
**/
public static List<String> groupStringFromRight(String input) {
List<String> list = new ArrayList<>();
if (input == null || input.isEmpty()) {
return null;
}
// 计算需要多少个完整的8字符组
int fullGroups = input.length() / 8;
// 计算最后一个组中的字符数
int lastGroupSize = input.length() % 8;
StringBuilder result = new StringBuilder(input);
String str = "";
if (lastGroupSize > 0) {
// 计算需要补多少个0
int padding = 8 - lastGroupSize;
for (int i = 0; i < padding; i++) {
str = str+"0";
}
}
input = str+result.toString();
int size =input.length()/8;
for (int i = 0; i < size; i++) {
String substring = input.substring(i * 8, (i + 1) * 8);
list.add(substring);
}
return list;
}
public static void main(String[] args) {
int l = 6442253;
String binaryString = Integer.toBinaryString(l);
List<String> readUtf8Lines = groupStringFromRight(binaryString);
System.out.println(readUtf8Lines.size());
for (String readUtf8Line : readUtf8Lines) {
System.out.println(readUtf8Line);
String dir = readUtf8Line.substring(0, 3); // 高三位 方向
String turn = readUtf8Line.substring(3); // 低五位 转向
System.out.println(ScheduleUtil.binaryIntToDecimalism(dir)+"_"+ScheduleUtil.binaryIntToDecimalism(turn));
Integer wjLightsDir = HiseseDirEnum.getWjLightsDir(Integer.parseInt(dir, 2));
Integer wjLightsTurn = HisenseTurnEnum.getWjLightsTurn(Integer.parseInt(turn, 2));
System.out.println("wjLightsDir "+wjLightsDir);
System.out.println("wjLightsTurn "+wjLightsTurn);
System.out.println("======================================");
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment