Commit 415828e3 authored by duanruiming's avatar duanruiming

[update] 海信灯态获取方式优化,从滴滴数据大脑获取通过http

parent a488cc3f
spring:
application:
name: opt
datasource:
dynamic:
primary: master
datasource:
master:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://37.12.182.29:3306/t_signal_control_jinan?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&useSSL=false&useCursorFetch=true
username: root
password: Wanji300552
driverClassName: com.mysql.cj.jdbc.Driver
slave:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://37.12.182.29:3306/t_signal_control_jinan?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&useSSL=false&useCursorFetch=true
username: root
password: Wanji300552
driverClassName: com.mysql.cj.jdbc.Driver
redis:
host: 37.12.182.29
port: 14728
password: Wanji300552
jedis:
pool:
max-active: 200
max-wait: 5000
max-idle: 20
min-idle: 10
timeout: 5000
database: 3
kafka:
bootstrap-servers: 37.12.182.31:9092
#消费者配置
consumer:
max-poll-records: 1
broker-id: 1
auto-commit-interval: 1S
auto-offset-reset: earliest
enable-auto-commit: false
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
group-id: group
listener:
concurrency: 3
ack-mode: manual_immediate
jackson:
mapper:
accept_case_insensitive_properties: true
main:
allow-circular-references: true
mvc:
pathmatch:
matching-strategy: ant_path_matcher
service:
name: signal-optimize-service
mapper:
mappers:
- net.wanji.opt.dao.mapper.MyBaseMapper
not-empty: false
identity: MYSQL
pagehelper:
helper-dialect: mysql
reasonable: false
# pagehelper分页 配置参数 supportMethodsArguments 建议不要全局设置
# https://www.cnblogs.com/liran123/p/12889093.html
support-methods-arguments: false
params: count=countSql
mybatis-plus:
mapper-locations: classpath*:mapper/*.xml,classpath*:mapper/*/*.xml
typeAliasesPackage: net.wanji.opt.po.base
check-config-location: true
configuration:
#是否开启自动驼峰命名规则(camel case)映射
map-underscore-to-camel-case: true
#全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存
cache-enabled: false
call-setters-on-nulls: true
#配置JdbcTypeForNull, oracle数据库必须配置
jdbc-type-for-null: 'null'
#MyBatis 自动映射时未知列或未知属性处理策略 NONE:不做任何处理 (默认值), WARNING:以日志的形式打印相关警告信息, FAILING:当作映射失败处理,并抛出异常和详细信息
auto-mapping-unknown-column-behavior: warning
#SQL打印
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
mybatis:
type-aliases-package: net.wanji.*.model
mapper-locations: classpath*:mapper/*.xml,classpath*:mapper/*/*.xml
configuration:
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
#线程池配置
threadPoolConfig:
threadPoolName: ${spring.application.name}-threadPool-thread-%d
coreSize: 8
maxSize: 16
queueCapacity: 200
keepAliveTime: 6000
allowCoreTimeOut: false
server:
port: 39001
servlet:
display-name: Wanji
context-path: /opt
multipart:
max-file-size: 50MB
max-request-size: 50MB
tomcat:
threads:
max: 10000
#线程池配置
threadPool:
corePoolSize: 5
maxPoolSize: 200
queueCapacity: 5
keepAliveTime: 60000
#优化参数配置
crossOptParam:
#车头间距
maxVehheadDist: 20.0
minVehheadDist: 7.0
defaultVehheadDist: 9.0
#车头时距
maxVehheadTime: 5.0
minVehheadTime: 2.0
defaultVehheadTime: 2.8
\ No newline at end of file
......@@ -29,13 +29,25 @@ public class CrossInfoCache implements ApplicationRunner {
private static final Map<String, CrossInfoPO> crossInfoMap = new HashMap<>();
public Map<String, CrossInfoPO> getCrossInfoCache() {
public static Map<String, CrossInfoPO> getCrossInfoCache() {
if (!crossInfoMap.isEmpty()) {
return crossInfoMap;
}
return Collections.EMPTY_MAP;
}
public static CrossInfoPO getCrossInfoBySignalCode(String code) {
if (!crossInfoMap.isEmpty()) {
for (Map.Entry<String, CrossInfoPO> entry : crossInfoMap.entrySet()) {
CrossInfoPO value = entry.getValue();
if (StringUtils.equalsIgnoreCase(code, value.getCode())) {
return value;
}
}
}
return null;
}
public static CrossInfoPO getCrossInfoByIp(String ip) {
if (!crossInfoMap.isEmpty()) {
for (Map.Entry<String, CrossInfoPO> entry : crossInfoMap.entrySet()) {
......@@ -54,7 +66,7 @@ public class CrossInfoCache implements ApplicationRunner {
}
private void init() {
Integer manufacturerId = manufacturerInfoMapper.selectIdByCode(BaseEnum.VendorTypeEnum.DT.getNick());
Integer manufacturerId = manufacturerInfoMapper.selectIdByCode(BaseEnum.VendorTypeEnum.HS.getNick());
List<CrossInfoPO> CrossInfoPOS = crossInfoMapper.selectAll();
for (CrossInfoPO crossInfoPO : CrossInfoPOS) {
if (Objects.nonNull(manufacturerId) && Objects.equals(manufacturerId, crossInfoPO.getManufacturerId())) {
......
package net.wanji.utc.hisense.cache;
import net.wanji.databus.vo.LightsStatusVO;
import net.wanji.utc.hisense.pojo.convert.PhaseInfoPojo;
import net.wanji.utc.hisense.pojo.convert.PhaseStageInfoPojo;
import net.wanji.utc.hisense.pojo.convert.RunningLightsStatusPojo;
......@@ -21,4 +22,5 @@ public class SignalDataCache {
public static final Map<String, List<PhaseInfoPojo>> phaseInfoCache = new HashMap<>();
// 海信推送灯态数据
public static final Map<String, RunningLightsStatusPojo> runningStateInfoCache = new HashMap<>();
public static final Map<String, LightsStatusVO> runningStateInfoCache4DataBrain = new HashMap<>();
}
package net.wanji.utc.hisense.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Objects;
/**
* @author duanruiming
* @date 2023/08/30 14:57
* @description 来源滴滴数据大脑海信控制模式转换
*/
@Getter
@AllArgsConstructor
@RequiredArgsConstructor
public enum DataBrainControlModeEnum {
LOCK(2, 52, "锁定"),
ALL_RED(3, 12, "全红"),
YELLOW_FLASH(4, 13, "黄闪"),
CLOSED_FLASH(5, 11, "关灯"),
STEP_CONTROL(9, 52, "步进"),
FIX_CYCLE(11, 21, "定周期"),
TEMP_PLAN(255, 53, "临时方案");
private Integer wjControl;
private Integer hisenseControl;
private String message;
public static Integer getWjControlMode(Integer hisenseControl) {
for (DataBrainControlModeEnum value : DataBrainControlModeEnum.values()) {
if (Objects.equals(hisenseControl, value.getHisenseControl())) {
return value.getWjControl();
}
}
return null;
}
}
package net.wanji.utc.hisense.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Objects;
/**
* @author duanruiming
* @date 2023/08/30 15:41
*/
@Getter
@AllArgsConstructor
@RequiredArgsConstructor
public enum DataBrainDirEnum {
ZERO(0, 5),
ONE(1, 6),
TWO(2, 7),
THREE(3, 8),
FOUR(4, 1),
FIVE(5, 2),
SIX(6, 3),
SEVEN(7, 4);
private Integer hisenseDir;
private Integer wjLightsDir;
public static Integer getWjLightsDir(Integer hisenseDir) {
for (DataBrainDirEnum value : DataBrainDirEnum.values()) {
if (Objects.equals(hisenseDir, value.getHisenseDir())) {
return value.getWjLightsDir();
}
}
return null;
}
}
package net.wanji.utc.hisense.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
/**
* @author duanruiming
* @date 2023/08/30 15:24
*/
@Getter
@AllArgsConstructor
@RequiredArgsConstructor
public enum DataBrainLampStatusEnum {
RED("red", "21"),
YELLOW("yellow", "22"),
GREEN("green", "23");
private String wjLampStatus;
private String hisenseLamStatus;
public static String getWjLampStatus(String hisenseLamStatus) {
for (DataBrainLampStatusEnum value : DataBrainLampStatusEnum.values()) {
if (StringUtils.equals(hisenseLamStatus, value.getHisenseLamStatus())) {
return value.getWjLampStatus();
}
}
return null;
}
}
package net.wanji.utc.hisense.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Objects;
/**
* @author duanruiming
* @date 2023/08/30 15:48
*/
@Getter
@AllArgsConstructor
@RequiredArgsConstructor
public enum DataBrainTurnEnum {
LEFT(12, 1),
RIGHT(13, 2),
STRAIGHT(11, 3),
TURN(31, 4),
OTHER(99, 99);
private Integer hisenseTurn;
private Integer wjTurn;
public static Integer getWjTurn(Integer hisenseTurn) {
for (DataBrainTurnEnum value : DataBrainTurnEnum.values()) {
if (Objects.equals(hisenseTurn, value.getHisenseTurn())) {
return value.getWjTurn();
}
}
return null;
}
}
......@@ -10,13 +10,15 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import net.wanji.utc.hisense.service.SignalStatusService;
import net.wanji.common.annotation.aspect.AspectLog;
import net.wanji.common.enums.BaseEnum;
import net.wanji.common.framework.rest.JsonViewObject;
import net.wanji.databus.po.SignalStatusLogPO;
import net.wanji.databus.vo.LightsStatusVO;
import net.wanji.utc.hisense.pojo.convert.HisenseLightStatusPojo;
import net.wanji.utc.hisense.service.SignalStatusService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
......@@ -60,4 +62,13 @@ public class SignalStatusController {
JsonViewObject jsonViewObject = JsonViewObject.newInstance();
return jsonViewObject.success(lightsStatusVOList);
}
@AspectLog(description = "从滴滴数据大脑接收海信灯态", operationType = BaseEnum.OperationTypeEnum.QUERY)
@PostMapping(value = "/receiveLightStatus", produces = MediaType.APPLICATION_JSON)
@ApiOperation(value = "接收海信灯态", notes = "接收海信灯态", response = LightsStatusVO.class, produces = MediaType.APPLICATION_JSON)
public JsonViewObject receiveLightStatus(@RequestBody HisenseLightStatusPojo hisenseLightStatusPojo) throws Exception{
signalStatusService.receiveLightStatus(hisenseLightStatusPojo);
JsonViewObject jsonViewObject = JsonViewObject.newInstance();
return jsonViewObject.success("海信灯态接收成功");
}
}
package net.wanji.utc.hisense.pojo.convert;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @author duanruiming
* @date 2023/08/30 13:32
*/
@Data
@ApiModel(value = "来自滴滴海信灯态实体类")
public class HisenseLightStatusPojo {
private String headers;
private String body;
@ApiModel(value = "来自滴滴海信灯态实体类")
public static class Headers {
@ApiModelProperty(value = "数据名称")
private String name;
@ApiModelProperty(value = "滴滴数据大脑数据来源")
private String from;
@ApiModelProperty(value = "唯一标识")
private String taskId;
}
@Data
@ApiModel(value = "来自滴滴海信灯态实体类")
public static class Body {
@ApiModelProperty(value = "灯态数据内容")
private ContentBody content;
@ApiModelProperty(value = "数据源,固定字符串,比如 “haixin”")
private String source;
@ApiModelProperty(value = "数据类型,固定数字2,代表JSON格式")
private Integer type;
}
@Data
@ApiModel(value = "来自滴滴海信灯态实体类")
public static class ContentBody {
@ApiModelProperty(value = "城市名称拼音,如“yinchuan”")
private String cityCode;
@ApiModelProperty(value = "行政区编号,如“640104")
private String regionId;
@ApiModelProperty(value = "置信度,1.0代表100%可信,若遇早晚高峰动态配时,可以降低置信度")
private int confidence;
@ApiModelProperty(value = "控制模式,11:特殊控制-关灯,12:特殊控制-全红,13:特殊控制-黄闪,21:单点多时段控制," +
"22:单点感应控制,23:打点自适应控制,31:线协调控制,41:区域协调控制,51:干预控制-手动控制," +
"52:干预控制-锁定阶段控制,53:干预控制-指定方案,54:干预控制-锁定相位控制")
private int controlMode;
@ApiModelProperty(value = "路口编号,编号规则:6位行政区编号+5位数字,例如:64010400001")
private String crossId;
@ApiModelProperty(value = "信号机实时状态,0-正常1-掉线")
private int crossRealStatus;
@ApiModelProperty(value = "周期剩余时间")
private int cycleCountDown;
@ApiModelProperty(value = "灯态JSON Object")
private List<LampRealInfos> lampRealInfos;
@ApiModelProperty(value = "信号灯周期(单位:秒),所有信号阶段时长之和")
private int period;
@ApiModelProperty(value = "方案编号")
private int planId;
@ApiModelProperty(value = "数据产生时间戳,精确到毫秒,与北京时间校准务必准确")
private Long signalMachineStamp;
@Data
@ApiModel(value = "来自滴滴海信灯态实体类")
public static class LampRealInfos {
@ApiModelProperty(value = "当前灯色剩余时间,单位:秒,动态变化的具体数值,时效性要求高")
private Integer countDown;
@ApiModelProperty(value = "当前灯色,22-黄灯,23-绿灯,21-红灯")
private String lampStatus;
@ApiModelProperty(value = "下一灯色持续时长")
private Integer nextCountDown;
@ApiModelProperty(value = "下一灯色")
private Integer nextLampStatus;
/**
* 0 由北向南
* 1 东北向西南
* 2 由东向西
* 3 由东南向西北
* 4 由南向北 顺时针方向
*/
@ApiModelProperty(value = "交通流方向")
private Integer roadDirection;
@ApiModelProperty(value = "交通流流向,11:直行,12:左转,13:右转, 31:掉头,99:其他")
private Integer roadFlowDirection;
}
}
}
......@@ -2,6 +2,7 @@ package net.wanji.utc.hisense.service;
import net.wanji.databus.po.SignalStatusLogPO;
import net.wanji.databus.vo.LightsStatusVO;
import net.wanji.utc.hisense.pojo.convert.HisenseLightStatusPojo;
import java.util.List;
......@@ -20,4 +21,5 @@ public interface SignalStatusService {
List<SignalStatusLogPO> runningStatusAlarm(String crossId);
List<LightsStatusVO> lightStatus(String crossId);
void receiveLightStatus(HisenseLightStatusPojo hisenseLightStatusPojo) throws Exception;
}
package net.wanji.utc.hisense.service.impl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import net.wanji.common.utils.tool.JacksonUtils;
import net.wanji.databus.po.CrossInfoPO;
import net.wanji.databus.po.SignalStatusLogPO;
import net.wanji.databus.vo.LightsStatusVO;
import net.wanji.utc.hisense.cache.SignalDataCache;
import net.wanji.utc.hisense.cache.ComplexCrossCache;
import net.wanji.utc.hisense.common.enums.ControlModelEnum;
import net.wanji.utc.hisense.common.enums.PhaseLightColorEnum;
import net.wanji.utc.hisense.cache.CrossInfoCache;
import net.wanji.utc.hisense.cache.SignalDataCache;
import net.wanji.utc.hisense.common.enums.*;
import net.wanji.utc.hisense.pojo.convert.HisenseLightStatusPojo;
import net.wanji.utc.hisense.pojo.convert.RunningLightsStatusPojo;
import net.wanji.utc.hisense.service.SignalStatusService;
import net.wanji.utc.hisense.util.CommonUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author duanruiming
......@@ -97,4 +104,60 @@ public class SignalStatusServiceImpl implements SignalStatusService {
return lightsStatusVOS;
}
@Override
public void receiveLightStatus(HisenseLightStatusPojo hisenseLightStatusPojo) throws Exception {
ObjectMapper jackson = JacksonUtils.getInstance();
String bodyStr = hisenseLightStatusPojo.getBody();
List<HisenseLightStatusPojo.Body> bodies = jackson.readValue(bodyStr, new TypeReference<List<HisenseLightStatusPojo.Body>>() {});
if (!CollectionUtils.isEmpty(bodies)) {
for (HisenseLightStatusPojo.Body body : bodies) {
HisenseLightStatusPojo.ContentBody content = body.getContent();
LightsStatusVO lightsStatusVO = new LightsStatusVO();
String hiCrossId = content.getCrossId();
CrossInfoPO crossInfo = CrossInfoCache.getCrossInfoBySignalCode(hiCrossId);
if (Objects.isNull(crossInfo)) {
log.error("接收滴滴数据大脑海信灯态数据,当前路口编码不存在:{}", hiCrossId);
continue;
}
String crossId = crossInfo.getId();
int hiControlMode = content.getControlMode();
int period = content.getPeriod();
int planId = content.getPlanId();
int cycleCountDown = content.getCycleCountDown();
lightsStatusVO.setCrossId(hiCrossId);
lightsStatusVO.setSchemeId(String.valueOf(planId));
lightsStatusVO.setRunMode(String.valueOf(DataBrainControlModeEnum.getWjControlMode(hiControlMode)));
lightsStatusVO.setCycleCountDown(cycleCountDown);
lightsStatusVO.setCycleLen(period);
List<HisenseLightStatusPojo.ContentBody.LampRealInfos> lampRealInfos = content.getLampRealInfos();
if (!CollectionUtils.isEmpty(lampRealInfos)) {
Map<Integer, List<HisenseLightStatusPojo.ContentBody.LampRealInfos>> dirLampMap = lampRealInfos.stream().collect(Collectors.groupingBy(HisenseLightStatusPojo.ContentBody.LampRealInfos::getRoadDirection));
Map<String, Object> dirMap = new HashMap<>();
for (Map.Entry<Integer, List<HisenseLightStatusPojo.ContentBody.LampRealInfos>> dirEntry : dirLampMap.entrySet()) {
Integer roadDirection = dirEntry.getKey();
List<HisenseLightStatusPojo.ContentBody.LampRealInfos> dirLampList = dirEntry.getValue();
Map<String, String> turnMap = new HashMap<>();
for (HisenseLightStatusPojo.ContentBody.LampRealInfos lampRealInfo : dirLampList) {
String lampStatus = lampRealInfo.getLampStatus();
Integer countDown = lampRealInfo.getCountDown();
Integer roadFlowDirection = lampRealInfo.getRoadFlowDirection();
if (roadFlowDirection == 99) {
continue;
}
if (StringUtils.endsWithIgnoreCase(lampStatus, "23")) {
lightsStatusVO.setPhaseId("0");
lightsStatusVO.setCyclePhaseCountDown(countDown);
}
turnMap.put(String.valueOf(DataBrainTurnEnum.getWjTurn(roadFlowDirection)), DataBrainLampStatusEnum.getWjLampStatus(lampStatus));
}
dirMap.put(String.valueOf(DataBrainDirEnum.getWjLightsDir(roadDirection)), turnMap);
}
lightsStatusVO.setDirLampGroupMap(dirMap);
log.error(" ========== {}", lightsStatusVO);
SignalDataCache.runningStateInfoCache4DataBrain.put(crossId, lightsStatusVO);
}
}
}
}
}
......@@ -5,18 +5,18 @@ spring:
datasource:
master:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/t_signal_utc_jinan?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&useSSL=false&useCursorFetch=true
url: jdbc:mysql://37.12.182.29:3306/t_signal_utc_jinan?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&useSSL=false&useCursorFetch=true
username: root
password: d
password: Wanji300552
driverClassName: com.mysql.cj.jdbc.Driver
slave:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/t_signal_utc_jinan?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&useSSL=false&useCursorFetch=true
url: jdbc:mysql://37.12.182.29:3306/t_signal_utc_jinan?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&useSSL=false&useCursorFetch=true
username: root
password: d
password: Wanji300552
driverClassName: com.mysql.cj.jdbc.Driver
redis:
host: localhost
host: 37.12.182.29
port: 6379
password: Wanji300552
jedis:
......
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