数据推送
parent
eb17f855dc
commit
e4b216a3db
|
|
@ -151,6 +151,8 @@ public final class JT808 {
|
||||||
public static JT808Message parseMessage(ByteBuf buf) {
|
public static JT808Message parseMessage(ByteBuf buf) {
|
||||||
JT808Message jt808Message = new JT808Message();
|
JT808Message jt808Message = new JT808Message();
|
||||||
|
|
||||||
|
byte[] h_b = ByteBufUtil.getBytes(buf);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. 消息ID (2字节)
|
// 1. 消息ID (2字节)
|
||||||
jt808Message.setMessageId(buf.readUnsignedShort());
|
jt808Message.setMessageId(buf.readUnsignedShort());
|
||||||
|
|
@ -184,14 +186,22 @@ public final class JT808 {
|
||||||
jt808Message.setMessageBody(array);
|
jt808Message.setMessageBody(array);
|
||||||
|
|
||||||
// 7. 校验码 (1字节)
|
// 7. 校验码 (1字节)
|
||||||
jt808Message.setCheckCode(buf.readByte());
|
byte checkCode = buf.readByte();
|
||||||
|
jt808Message.setCheckCode(checkCode);
|
||||||
|
|
||||||
// 验证校验码
|
|
||||||
if (!verifyCheckCode(jt808Message, buf)) {
|
if (jt808Message.getMessageId() == 0x704) {
|
||||||
log.error("校验码错误: {}", jt808Message);
|
log.info("报文:{}", h_b);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int code = 0;
|
||||||
|
for (int i = 0; i < h_b.length - 1; i++) {
|
||||||
|
code = code ^ h_b[i];
|
||||||
|
}
|
||||||
|
if (code != checkCode) {
|
||||||
|
log.error("校验码错误: {} {}", code, checkCode);
|
||||||
|
// return null;
|
||||||
|
}
|
||||||
return jt808Message;
|
return jt808Message;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ import lombok.Setter;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JT808协议消息实体类
|
* JT808协议消息实体类
|
||||||
* 用于存储解析后的JT808协议消息内容
|
* 用于存储解析后的JT808协议消息内容
|
||||||
|
|
@ -31,6 +34,7 @@ public class JT808Message {
|
||||||
private byte[] messageBody;
|
private byte[] messageBody;
|
||||||
// 校验码 (1字节)
|
// 校验码 (1字节)
|
||||||
private byte checkCode;
|
private byte checkCode;
|
||||||
|
|
||||||
public JT808Message() {
|
public JT808Message() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,6 +43,17 @@ public class JT808Message {
|
||||||
return messageBodyProps & 0x3FF;
|
return messageBodyProps & 0x3FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Integer> getBodyBytes() {
|
||||||
|
if (messageBody == null || messageBody.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ArrayList<Integer> integers = new ArrayList<>(messageBody.length);
|
||||||
|
for (byte b : messageBody) {
|
||||||
|
integers.add((int) b);
|
||||||
|
}
|
||||||
|
return integers;
|
||||||
|
}
|
||||||
|
|
||||||
// 从消息体属性中获取是否分包
|
// 从消息体属性中获取是否分包
|
||||||
public boolean isPackaged() {
|
public boolean isPackaged() {
|
||||||
return (messageBodyProps & 0x4000) != 0;
|
return (messageBodyProps & 0x4000) != 0;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ public class JT808MessageCenter {
|
||||||
|
|
||||||
Map<MessageType, Consumer<TerminalMessageBody>> m = listeners.computeIfPresent(localizerType, (k, v) -> {
|
Map<MessageType, Consumer<TerminalMessageBody>> m = listeners.computeIfPresent(localizerType, (k, v) -> {
|
||||||
MessageType messageType = MessageType.getMessageType(messageId);
|
MessageType messageType = MessageType.getMessageType(messageId);
|
||||||
|
if (messageType == MessageType.TerminalLocationBatchReport) {
|
||||||
|
log.info("批量上报:{}", message);
|
||||||
|
}
|
||||||
|
|
||||||
if (messageType == null) {
|
if (messageType == null) {
|
||||||
log.error("未找到消息类型,设备号:{},消息 Id:0x{}", terminalId, Integer.toHexString(messageId));
|
log.error("未找到消息类型,设备号:{},消息 Id:0x{}", terminalId, Integer.toHexString(messageId));
|
||||||
return v;
|
return v;
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,9 @@ public abstract class JT808MessageListener {
|
||||||
int speedThreshold = localizer.getSpeedThreshold();
|
int speedThreshold = localizer.getSpeedThreshold();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
int length = byteBuf.readUnsignedShort();
|
int length = byteBuf.readUnsignedShort();
|
||||||
|
/* if (length > 28) { // 有扩展信息
|
||||||
|
|
||||||
|
} */
|
||||||
LocationReportMessage locationReportMsg = new LocationReportMessage(byteBuf.slice(byteBuf.readerIndex(), length));
|
LocationReportMessage locationReportMsg = new LocationReportMessage(byteBuf.slice(byteBuf.readerIndex(), length));
|
||||||
byteBuf.skipBytes(length);
|
byteBuf.skipBytes(length);
|
||||||
double speed = locationReportMsg.getSpeed();
|
double speed = locationReportMsg.getSpeed();
|
||||||
|
|
@ -144,6 +147,8 @@ public abstract class JT808MessageListener {
|
||||||
Mqtt.publish(terminalId + "/track_location", realtimeLocationResult);
|
Mqtt.publish(terminalId + "/track_location", realtimeLocationResult);
|
||||||
Mqtt.publish(terminalId + "/track_location_real", realtimeLocationResult);
|
Mqtt.publish(terminalId + "/track_location_real", realtimeLocationResult);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("批量上报处理失败:{} {}", terminalId, message.getFlowId());
|
||||||
} finally {
|
} finally {
|
||||||
byteBuf.release();
|
byteBuf.release();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,10 @@ public class Hsoa {
|
||||||
param.setCityCode(defaultPlace.getCity())
|
param.setCityCode(defaultPlace.getCity())
|
||||||
.setCityName(defaultPlace.getCityName())
|
.setCityName(defaultPlace.getCityName())
|
||||||
;
|
;
|
||||||
|
if (StrUtil.isBlank(tnt) || StrUtil.isBlank(refTnt)) {
|
||||||
|
return new HsoaResult<>()
|
||||||
|
.setSuccess(false);
|
||||||
|
}
|
||||||
return API.pushVehicleTrajectory(param, new TokenParam().setTnt(tnt).setRefTnt(refTnt));
|
return API.pushVehicleTrajectory(param, new TokenParam().setTnt(tnt).setRefTnt(refTnt));
|
||||||
} finally {
|
} finally {
|
||||||
rlock.unlock();
|
rlock.unlock();
|
||||||
|
|
@ -64,6 +68,7 @@ public class Hsoa {
|
||||||
} else {
|
} else {
|
||||||
refTnt = "";
|
refTnt = "";
|
||||||
tnt = "";
|
tnt = "";
|
||||||
|
log.error("政务平台登录失败");
|
||||||
}
|
}
|
||||||
} else if (now - lastLoginTime > hsoaProperties.getExpire() - 60) {
|
} else if (now - lastLoginTime > hsoaProperties.getExpire() - 60) {
|
||||||
HsoaResult<LoginResult> loginResult = API.refreshToken(new RefreshTokenParam().setRefTnt(refTnt));
|
HsoaResult<LoginResult> loginResult = API.refreshToken(new RefreshTokenParam().setRefTnt(refTnt));
|
||||||
|
|
@ -75,6 +80,7 @@ public class Hsoa {
|
||||||
} else {
|
} else {
|
||||||
refTnt = "";
|
refTnt = "";
|
||||||
tnt = "";
|
tnt = "";
|
||||||
|
log.error("政务平台登录失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,17 @@ import com.njzscloud.common.core.utils.R;
|
||||||
import com.njzscloud.supervisory.hsoa.Hsoa;
|
import com.njzscloud.supervisory.hsoa.Hsoa;
|
||||||
import com.njzscloud.supervisory.hsoa.pojo.param.PushVehicleTrajectoryParam;
|
import com.njzscloud.supervisory.hsoa.pojo.param.PushVehicleTrajectoryParam;
|
||||||
import com.njzscloud.supervisory.hsoa.pojo.result.HsoaResult;
|
import com.njzscloud.supervisory.hsoa.pojo.result.HsoaResult;
|
||||||
|
import com.njzscloud.supervisory.hsoa.service.HsoaService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RequestMapping("/hsoa")
|
@RequestMapping("/hsoa")
|
||||||
public class HsoaController {
|
public class HsoaController {
|
||||||
|
|
||||||
|
private final HsoaService hsoaService;
|
||||||
|
|
||||||
@PostMapping("/push")
|
@PostMapping("/push")
|
||||||
public R<?> push(@RequestBody PushVehicleTrajectoryParam pushVehicleTrajectoryParam) {
|
public R<?> push(@RequestBody PushVehicleTrajectoryParam pushVehicleTrajectoryParam) {
|
||||||
HsoaResult<?> objectHsoaResult = Hsoa.pushVehicleTrajectory(pushVehicleTrajectoryParam);
|
HsoaResult<?> objectHsoaResult = Hsoa.pushVehicleTrajectory(pushVehicleTrajectoryParam);
|
||||||
|
|
@ -23,4 +23,9 @@ public class HsoaController {
|
||||||
}
|
}
|
||||||
return R.failed();
|
return R.failed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/push_order")
|
||||||
|
public R<?> pushOrder(@RequestParam Long orderId, @RequestParam Integer count) {
|
||||||
|
return R.success(hsoaService.pushOrder(orderId, count));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
package com.njzscloud.supervisory.hsoa.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.map.MapBuilder;
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.thread.ThreadUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.njzscloud.common.core.ex.Exceptions;
|
||||||
|
import com.njzscloud.supervisory.biz.pojo.entity.TruckLocationTrackEntity;
|
||||||
|
import com.njzscloud.supervisory.biz.service.TruckLocationTrackService;
|
||||||
|
import com.njzscloud.supervisory.hsoa.Hsoa;
|
||||||
|
import com.njzscloud.supervisory.hsoa.pojo.param.PushVehicleTrajectoryParam;
|
||||||
|
import com.njzscloud.supervisory.hsoa.pojo.result.HsoaResult;
|
||||||
|
import com.njzscloud.supervisory.order.pojo.result.OrderPagingResult;
|
||||||
|
import com.njzscloud.supervisory.order.service.OrderInfoService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class HsoaService {
|
||||||
|
private final OrderInfoService orderInfoService;
|
||||||
|
private final TruckLocationTrackService truckLocationTrackService;
|
||||||
|
private final AtomicBoolean run = new AtomicBoolean(false);
|
||||||
|
private final AtomicInteger succ = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger fail = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger total = new AtomicInteger(0);
|
||||||
|
private final AtomicLong order = new AtomicLong(0);
|
||||||
|
|
||||||
|
public synchronized Map<String, Object> pushOrder(Long orderId, Integer count) {
|
||||||
|
MapBuilder<String, Object> builder = MapUtil.<String, Object>builder();
|
||||||
|
|
||||||
|
if (run.get()) {
|
||||||
|
int i1 = total.get();
|
||||||
|
int i2 = succ.get();
|
||||||
|
int i3 = fail.get();
|
||||||
|
long v = order.get();
|
||||||
|
return builder
|
||||||
|
.put("订单", v)
|
||||||
|
.put("任务数量", i1)
|
||||||
|
.put("成功数量", i2)
|
||||||
|
.put("失败数量", i3)
|
||||||
|
.put("剩余数量", i1 - i2 - i3)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
OrderPagingResult orderDetail = orderInfoService.detail(orderId);
|
||||||
|
Assert.notNull(orderDetail, () -> Exceptions.clierr("订单不存在"));
|
||||||
|
String licensePlate = orderDetail.getLicensePlate();
|
||||||
|
String transCompanyName = orderDetail.getTransCompanyName();
|
||||||
|
List<TruckLocationTrackEntity> list = truckLocationTrackService.list(Wrappers.<TruckLocationTrackEntity>lambdaQuery().eq(TruckLocationTrackEntity::getOrderId, orderId));
|
||||||
|
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return builder
|
||||||
|
.put("订单", orderId)
|
||||||
|
.put("任务数量", 0)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
if (count == null || count == 0) {
|
||||||
|
count = list.size();
|
||||||
|
} else {
|
||||||
|
count = Math.min(count, list.size());
|
||||||
|
}
|
||||||
|
run.set(true);
|
||||||
|
order.set(orderId);
|
||||||
|
total.set(count);
|
||||||
|
succ.set(0);
|
||||||
|
fail.set(0);
|
||||||
|
int c = count;
|
||||||
|
Thread thread = new Thread(() -> {
|
||||||
|
for (int i = 0; i < c; i++) {
|
||||||
|
ThreadUtil.sleep(1000);
|
||||||
|
TruckLocationTrackEntity locationTrack = list.get(i);
|
||||||
|
boolean b = run.get();
|
||||||
|
if (!b) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Double longitude = locationTrack.getLongitude();
|
||||||
|
Double latitude = locationTrack.getLatitude();
|
||||||
|
Double speed = locationTrack.getSpeed();
|
||||||
|
Integer direction = locationTrack.getDirection();
|
||||||
|
LocalDateTime locationTime = locationTrack.getLocationTime();
|
||||||
|
String time = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(locationTime);
|
||||||
|
HsoaResult<?> result = Hsoa.pushVehicleTrajectory(new PushVehicleTrajectoryParam()
|
||||||
|
.setCompanyName(transCompanyName)
|
||||||
|
.setTransportLicense(orderDetail.getCertificateSn())
|
||||||
|
.setPlateNumber(licensePlate)
|
||||||
|
.setVehicleType(orderDetail.getTruckCategory())
|
||||||
|
.setLongitude(longitude + "")
|
||||||
|
.setLatitude(latitude + "")
|
||||||
|
.setSpeed(speed)
|
||||||
|
.setDirection(direction + 0.0)
|
||||||
|
.setStateType("正常行驶")
|
||||||
|
.setAlarmType("无")
|
||||||
|
.setLoadStatus("2")
|
||||||
|
.setSealedStatus("1")
|
||||||
|
.setLiftStatus("0")
|
||||||
|
.setAccStatus(1)
|
||||||
|
.setGpsTime(time)
|
||||||
|
.setLocationMode("WGS84")
|
||||||
|
);
|
||||||
|
if (result == null || !result.isSuccess()) {
|
||||||
|
fail.incrementAndGet();
|
||||||
|
log.error("推送定位数据失败,数据Id:{}", locationTrack.getId());
|
||||||
|
} else {
|
||||||
|
succ.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail.incrementAndGet();
|
||||||
|
log.error("推送定位数据失败,数据Id:{}", locationTrack.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run.set(false);
|
||||||
|
});
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
int i1 = total.get();
|
||||||
|
int i2 = succ.get();
|
||||||
|
int i3 = fail.get();
|
||||||
|
return builder
|
||||||
|
.put("订单", orderId)
|
||||||
|
.put("任务数量", i1)
|
||||||
|
.put("成功数量", i2)
|
||||||
|
.put("失败数量", i3)
|
||||||
|
.put("剩余数量", i1 - i2 - i3)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,6 +29,7 @@ spring:
|
||||||
- /biz_audit_config/copy
|
- /biz_audit_config/copy
|
||||||
- /order_info/gps_test
|
- /order_info/gps_test
|
||||||
- /wechatTemplateMessage/bind
|
- /wechatTemplateMessage/bind
|
||||||
|
- /hsoa/push_order
|
||||||
app:
|
app:
|
||||||
default-place:
|
default-place:
|
||||||
province: 320000
|
province: 320000
|
||||||
|
|
@ -93,4 +94,4 @@ mqtt:
|
||||||
hsoa:
|
hsoa:
|
||||||
base-url: http://60.173.195.121:9908
|
base-url: http://60.173.195.121:9908
|
||||||
username: chuz_trajectory
|
username: chuz_trajectory
|
||||||
password: e9t2YsgM5ug/kpIZpMdY9e9uXq60jyEQ30zQX+BzphI=
|
password: e9t2YsgM5ug%2FkpIZpMdY9e9uXq60jyEQ30zQX%2BBzphI%3D
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ spring:
|
||||||
- /district/areaList
|
- /district/areaList
|
||||||
- /biz_audit_config/copy
|
- /biz_audit_config/copy
|
||||||
- /wechatTemplateMessage/bind
|
- /wechatTemplateMessage/bind
|
||||||
|
- /hsoa/push_order
|
||||||
|
|
||||||
app:
|
app:
|
||||||
in-out-gap: 180
|
in-out-gap: 180
|
||||||
|
|
@ -83,4 +84,4 @@ localizer:
|
||||||
hsoa:
|
hsoa:
|
||||||
base-url: http://117.68.7.91:8088
|
base-url: http://117.68.7.91:8088
|
||||||
username: chuz_trajectory
|
username: chuz_trajectory
|
||||||
password: e9t2YsgM5ug/kpIZpMdY9e9uXq60jyEQ30zQX+BzphI=
|
password: e9t2YsgM5ug%2FkpIZpMdY9e9uXq60jyEQ30zQX%2BBzphI%3D
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue