mirror of
https://gitee.com/pan648540858/wvp-GB28181-pro.git
synced 2026-05-23 21:47:49 +08:00
Compare commits
309 Commits
581007621c
...
1b0658d991
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b0658d991 | ||
|
|
5c25385d29 | ||
|
|
1da487f02a | ||
|
|
e555df52d3 | ||
|
|
c90836261a | ||
|
|
d7f5e7d771 | ||
|
|
0a19ce4f34 | ||
|
|
efbd302260 | ||
|
|
e272d25939 | ||
|
|
2ee9a3fa71 | ||
|
|
333965255f | ||
|
|
61a761e288 | ||
|
|
f3bd58acfe | ||
|
|
9e880786b3 | ||
|
|
0ed395ff2e | ||
|
|
4c97022c78 | ||
|
|
4fb04776f2 | ||
|
|
e9eeeeefd7 | ||
|
|
a79429115f | ||
|
|
34fb79093e | ||
|
|
43ef080f55 | ||
|
|
ee52b43c99 | ||
|
|
4cc399ce39 | ||
|
|
a69e3d5dde | ||
|
|
c0ab010475 | ||
|
|
79ee116174 | ||
|
|
045c14da0d | ||
|
|
0c78a9460b | ||
|
|
6e5cadd32b | ||
|
|
fb150da97a | ||
|
|
a4e20f0f50 | ||
|
|
9388c279e7 | ||
|
|
03b5c0241f | ||
|
|
a60eb082fe | ||
|
|
9d0678f765 | ||
|
|
9b0d091e4e | ||
|
|
ebd95250c0 | ||
|
|
47e4f2343b | ||
|
|
f7b35e8e14 | ||
|
|
8b17e97682 | ||
|
|
e730bf2d15 | ||
|
|
ca07935232 | ||
|
|
56b70d335a | ||
|
|
29802ccded | ||
|
|
3f2089f584 | ||
|
|
45af124eb0 | ||
|
|
5874d4d1fa | ||
|
|
d40bc5a034 | ||
|
|
44ed06bcbe | ||
|
|
be04660de8 | ||
|
|
e28141da6e | ||
|
|
04bcb6dcb8 | ||
|
|
9d47fe30f5 | ||
|
|
cefc87ad47 | ||
|
|
8c3e9320fa | ||
|
|
b7a2b6816b | ||
|
|
1655e5903b | ||
|
|
055bbc2dca | ||
|
|
3c6b715ce1 | ||
|
|
48eff320fd | ||
|
|
17c967ed4e | ||
|
|
fae839af05 | ||
|
|
93c24a74e6 | ||
|
|
a424f270e8 | ||
|
|
1bfb51c90e | ||
|
|
5bcdf5dfb6 | ||
|
|
bab5534134 | ||
|
|
537d86ca89 | ||
|
|
465e03d15d | ||
|
|
d15307533a | ||
|
|
1420fcfcd0 | ||
|
|
0c29c90d3b | ||
|
|
420b3889c5 | ||
|
|
7c5cee5d87 | ||
|
|
27d7f3cc6e | ||
|
|
592c1c2b71 | ||
|
|
5b89145337 | ||
|
|
6a2ecd937d | ||
|
|
98e6cfcc4c | ||
|
|
081a146f2a | ||
|
|
68f7d3ef74 | ||
|
|
1a7f517c5a | ||
|
|
e4a0a37f0b | ||
|
|
c4ab55a456 | ||
|
|
10c75036f5 | ||
|
|
3b7ba3eb46 | ||
|
|
e754d0d804 | ||
|
|
e284c3857c | ||
|
|
f0eb101130 | ||
|
|
fd5079a652 | ||
|
|
20135726eb | ||
|
|
242062bda3 | ||
|
|
0329c8f5d1 | ||
|
|
51f126e571 | ||
|
|
b05f770a57 | ||
|
|
4e48eb6cab | ||
|
|
1323d081e8 | ||
|
|
f528735119 | ||
|
|
d3d7ea8fbb | ||
|
|
991dd0ea41 | ||
|
|
1dfbb875b2 | ||
|
|
a4ca333abb | ||
|
|
e5fd66ef96 | ||
|
|
556f0ebf2f | ||
|
|
13b896ce23 | ||
|
|
f62b655602 | ||
|
|
46fa390387 | ||
|
|
277f2db137 | ||
|
|
601daa1092 | ||
|
|
03497c55f0 | ||
|
|
a5b48e5b19 | ||
|
|
b22e894e94 | ||
|
|
282e0db96e | ||
|
|
5db39a2265 | ||
|
|
edeea61318 | ||
|
|
a94b18bde9 | ||
|
|
5846a4ed5b | ||
|
|
358799a391 | ||
|
|
4ba04661ab | ||
|
|
36e15c80b0 | ||
|
|
449b215367 | ||
|
|
b034faad62 | ||
|
|
261945ca62 | ||
|
|
ff975b47ba | ||
|
|
93532a6b3b | ||
|
|
e0adc7306b | ||
|
|
291a87e1f7 | ||
|
|
46bf5b7a39 | ||
|
|
824690a37f | ||
|
|
3410fae879 | ||
|
|
c0dea69839 | ||
|
|
f564ff0aba | ||
|
|
a030c15c8f | ||
|
|
4b90298c99 | ||
|
|
b4dddb0b08 | ||
|
|
9c2c4a92b1 | ||
|
|
18cfba612b | ||
|
|
6074638f5b | ||
|
|
dbb2492640 | ||
|
|
7ffe773175 | ||
|
|
942a41c630 | ||
|
|
595d9be283 | ||
|
|
6ae623d639 | ||
|
|
0103d5819b | ||
|
|
972ef30f8d | ||
|
|
913d358a11 | ||
|
|
5d5d654410 | ||
|
|
f7d811a299 | ||
|
|
5c826ef449 | ||
|
|
0de2bb54cd | ||
|
|
83875a5905 | ||
|
|
3728219177 | ||
|
|
62ae1ee978 | ||
|
|
e8d832d0a5 | ||
|
|
89101b2731 | ||
|
|
56fdbd34f4 | ||
|
|
6efff9daf9 | ||
|
|
74c98c8636 | ||
|
|
15a551d983 | ||
|
|
2b1645729b | ||
|
|
84ef932964 | ||
|
|
2aef6ab6f1 | ||
|
|
de6a3ceb76 | ||
|
|
87ecf68332 | ||
|
|
01fbf102c2 | ||
|
|
3e9def7aac | ||
|
|
a945078788 | ||
|
|
9ece77d54a | ||
|
|
37b79633f0 | ||
|
|
98c62b93f7 | ||
|
|
bae9b2571a | ||
|
|
2c0c576d93 | ||
|
|
5011a6b74a | ||
|
|
271bb19c99 | ||
|
|
adfce4464d | ||
|
|
c8ddee905f | ||
|
|
8be6979911 | ||
|
|
1e9cdfe87f | ||
|
|
9817bf3fb7 | ||
|
|
82ab524fc4 | ||
|
|
e085258d74 | ||
|
|
2f1ebca335 | ||
|
|
b626a583f4 | ||
|
|
dcc20d0d15 | ||
|
|
6af9b8da1f | ||
|
|
e9562d7d31 | ||
|
|
b0e25ef784 | ||
|
|
7ddf066878 | ||
|
|
9161a090f6 | ||
|
|
7bf548492a | ||
|
|
e02a047eb2 | ||
|
|
aaa1d3a46f | ||
|
|
db4ba4035f | ||
|
|
cc71b7d9ca | ||
|
|
c6e3df685a | ||
|
|
ad67155d73 | ||
|
|
2112fffc26 | ||
|
|
364d613ccb | ||
|
|
c53e4f6fbc | ||
|
|
cc91db30c5 | ||
|
|
00749619da | ||
|
|
9280b57974 | ||
|
|
a3149139e2 | ||
|
|
58401b1444 | ||
|
|
4a5de5a2db | ||
|
|
faa0a01b9f | ||
|
|
5dd49b3d44 | ||
|
|
4011e54dd8 | ||
|
|
738b3b6a8e | ||
|
|
a5bfe5049d | ||
|
|
c946b97514 | ||
|
|
0fc0cd6e41 | ||
|
|
734f0c7e04 | ||
|
|
16bc3dabd6 | ||
|
|
7c833f3d12 | ||
|
|
e5acf7f1e4 | ||
|
|
eb43ffd98f | ||
|
|
e45b2479d3 | ||
|
|
7bdde6907a | ||
|
|
5be7c7636e | ||
|
|
76580d8fdc | ||
|
|
5b489d7c26 | ||
|
|
5a392372cb | ||
|
|
8aa97ba695 | ||
|
|
516c5ce3d1 | ||
|
|
9facff13b1 | ||
|
|
91b81ceb7a | ||
|
|
06b27beedc | ||
|
|
bc356849c7 | ||
|
|
225940825b | ||
|
|
62122f95f0 | ||
|
|
67b846fe2f | ||
|
|
714e1ff62c | ||
|
|
0058f1b0a9 | ||
|
|
34b6b516ab | ||
|
|
f9c22fcb3d | ||
|
|
c5ac7e218a | ||
|
|
975e94eee1 | ||
|
|
50e2565643 | ||
|
|
dd5ab573f2 | ||
|
|
a6236a2c13 | ||
|
|
16143a3fff | ||
|
|
fce96def9f | ||
|
|
570307669e | ||
|
|
205e529660 | ||
|
|
21e7ca0e46 | ||
|
|
6729df4992 | ||
|
|
c6bd4ac352 | ||
|
|
9f3cab6486 | ||
|
|
be787d1a14 | ||
|
|
8716160d96 | ||
|
|
9800fd6e7b | ||
|
|
4005a12403 | ||
|
|
59c91bdaf8 | ||
|
|
7d08b56267 | ||
|
|
05c83cf6ef | ||
|
|
1d36382986 | ||
|
|
bb350e847d | ||
|
|
d410a3ca18 | ||
|
|
b08f00104e | ||
|
|
2dc7eecb47 | ||
|
|
48a0e88b95 | ||
|
|
0077df29d4 | ||
|
|
5457407601 | ||
|
|
ae239c8848 | ||
|
|
9badf1c7fe | ||
|
|
d54787f323 | ||
|
|
8a2dc6031e | ||
|
|
9255ea802f | ||
|
|
349b0442d6 | ||
|
|
403eb4499d | ||
|
|
6757f4b719 | ||
|
|
8ba30e83ef | ||
|
|
98d9eb5314 | ||
|
|
a8a4aecc15 | ||
|
|
b649464753 | ||
|
|
ebdd9ab534 | ||
|
|
a1ab834875 | ||
|
|
4ec4d618d6 | ||
|
|
5fc1000fcc | ||
|
|
302eb98d51 | ||
|
|
984d8743be | ||
|
|
26bbeac6c7 | ||
|
|
81c2b5715c | ||
|
|
3e5da98539 | ||
|
|
a7b7371e74 | ||
|
|
0f420c43ac | ||
|
|
abc3766556 | ||
|
|
603ce18573 | ||
|
|
6acc395ad2 | ||
|
|
da33471dfd | ||
|
|
98199ec657 | ||
|
|
3e672ca38c | ||
|
|
9bc9dbe43b | ||
|
|
60d51cf23a | ||
|
|
93946407e8 | ||
|
|
23a72e94e6 | ||
|
|
d4c531dc12 | ||
|
|
dff7b8e31f | ||
|
|
e400c92f53 | ||
|
|
4eb0163e43 | ||
|
|
d78f76e58b | ||
|
|
44f17c723b | ||
|
|
18bd959541 | ||
|
|
dc38df6288 | ||
|
|
613452b3fc | ||
|
|
9494b6dc85 | ||
|
|
79dc7e79d2 | ||
|
|
6275372455 |
18
README.md
18
README.md
@ -1,5 +1,5 @@
|
||||

|
||||
# 开箱即用的28181协议视频平台
|
||||
# 开箱即用的国标28181和部标808+1078协议视频平台
|
||||
|
||||
[](https://travis-ci.org/xia-chu/ZLMediaKit)
|
||||
[](https://github.com/xia-chu/ZLMediaKit/blob/master/LICENSE)
|
||||
@ -8,7 +8,7 @@
|
||||
[](https://github.com/xia-chu/ZLMediaKit/pulls)
|
||||
|
||||
|
||||
WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的开箱即用的网络视频平台,负责实现核心信令与设备管理后台部分,支持NAT穿透,支持海康、大华、宇视等品牌的IPC、NVR接入。支持国标级联,支持将不带国标功能的摄像机/直播流/直播推流转发到其他国标平台。
|
||||
WEB VIDEO PLATFORM是一个基于GB28181-2016、部标808、部标1078标准实现的开箱即用的网络视频平台,负责实现核心信令与设备管理后台部分,支持NAT穿透,支持海康、大华、宇视等品牌的IPC、NVR接入。支持国标级联,支持将不带国标功能的摄像机/直播流/直播推流转发到其他国标平台。
|
||||
|
||||
流媒体服务基于@夏楚 ZLMediaKit [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)
|
||||
播放器使用@dexter jessibuca [https://github.com/langhuihui/jessibuca/tree/v3](https://github.com/langhuihui/jessibuca/tree/v3)
|
||||
@ -120,20 +120,22 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
||||
- [X] 支持Mysql,Postgresql,金仓等数据库
|
||||
- [X] 支持录制计划, 根据设定的时间对通道进行录制. 暂不支持将录制的内容转发到国标上级
|
||||
- [X] 支持国标信令集群
|
||||
- [X] 新增支持部标808和部标1078,大量新特性不一一列表了。支持作为网关被国标上级调用部标设备
|
||||
|
||||
|
||||
# 闭源内容
|
||||
- [X] 支持ONVIF协议,设备检索,支持点播,云台控制,国标级联点播,自动点播等。
|
||||
- [X] 支持部标1078+808协议,支持点播,云台控制,录像回放,位置上报,自动点播等。
|
||||
- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。
|
||||
- [X] 支持国网B接口协议。支持注册,获取资源,预览, 云台控制,预置位控制等,可免费定制支持语音对讲、录像回放和抓拍图像。
|
||||
- [X] 功能加强版本
|
||||
- [X] 国标增强版: 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。
|
||||
- [X] 全功能版:
|
||||
- [X] 支持开源所有功能
|
||||
- [X] 支持ONVIF协议,设备检索,支持点播,云台控制,国标级联点播,自动点播等。
|
||||
- [X] 支持国网B接口协议。支持注册,获取资源,预览, 云台控制,预置位控制等,可免费定制支持语音对讲、录像回放和抓拍图像。
|
||||
- [X] 支持按权限分配可以使用的通道
|
||||
- [X] 支持电子地图。支持展示通道位置,支持在地图上修改通道位置。可扩展接入高德地图API,支持搜索位置,附近设备。
|
||||
- [X] 支持表格导出
|
||||
- [X] 拉流代理支持按照品牌拼接url。
|
||||
- [X] 播放鉴权,更加安全。
|
||||
- [X] 功能持续扩展,可根据用户需要增加支持。
|
||||
- [X] 此版本后续开发功能支持直接更新提供,无需二次付费。
|
||||
- [X] 提供源码不限制部署次数和支持路数。
|
||||
|
||||
|
||||
# 授权协议
|
||||
|
||||
22
pom.xml
22
pom.xml
@ -342,6 +342,27 @@
|
||||
<version>32.1.3-jre</version>
|
||||
</dependency>
|
||||
|
||||
<!--ftp server-->
|
||||
<dependency>
|
||||
<groupId>org.apache.ftpserver</groupId>
|
||||
<artifactId>ftpserver-core</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.ftpserver</groupId>
|
||||
<artifactId>ftplet-api</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 自动化生成代码工具 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.30</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 自动化生成代码工具 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
@ -361,6 +382,7 @@
|
||||
<artifactId>log-viewer-spring-boot</artifactId>
|
||||
<version>1.0.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
@ -182,6 +182,7 @@ public class StreamInfo implements Serializable, Cloneable{
|
||||
if (callIdParam != null) {
|
||||
callIdParam = Objects.equals(callIdParam, "") ? callIdParam : callIdParam.replace("?", "&");
|
||||
}
|
||||
// String file = String.format("%s/%s?type=%s%s", app, stream, isPlay?"play":"push", callIdParam);
|
||||
String file = String.format("index/api/webrtc?app=%s&stream=%s&type=%s%s", app, stream, isPlay?"play":"push", callIdParam);
|
||||
if (port > 0) {
|
||||
this.rtc = new StreamURL("http", host, port, file);
|
||||
|
||||
@ -153,4 +153,15 @@ public class VideoManagerConstants {
|
||||
*/
|
||||
public static final String REDIS_RECORD_INFO_RES_COUNT_PRE = "GB_RECORD_INFO_RES_COUNT:";
|
||||
|
||||
//************************** 1078 ****************************************
|
||||
|
||||
|
||||
public static final String INVITE_INFO_1078_POSITION = "INVITE_INFO_1078_POSITION:";
|
||||
public static final String INVITE_INFO_1078_PLAY = "INVITE_INFO_1078_PLAY:";
|
||||
public static final String INVITE_INFO_1078_PLAYBACK = "INVITE_INFO_1078_PLAYBACK:";
|
||||
public static final String INVITE_INFO_1078_TALK = "INVITE_INFO_1078_TALK:";
|
||||
|
||||
|
||||
public static final String RECORD_LIST_1078 = "RECORD_LIST_1078:";
|
||||
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ public class ChannelDataType {
|
||||
public final static int GB28181 = 1;
|
||||
public final static int STREAM_PUSH = 2;
|
||||
public final static int STREAM_PROXY = 3;
|
||||
public final static int JT_1078 = 200;
|
||||
|
||||
public final static String PLAY_SERVICE = "sourceChannelPlayService";
|
||||
public final static String PLAYBACK_SERVICE = "sourceChannelPlaybackService";
|
||||
|
||||
@ -66,6 +66,9 @@ public class MediaConfig{
|
||||
@Value("${media.rtp-proxy-port:0}")
|
||||
private Integer rtpProxyPort = 0;
|
||||
|
||||
@Value("${media.jtt-proxy-port:0}")
|
||||
private Integer jttProxyPort = 0;
|
||||
|
||||
@Value("${media.rtsp-port:0}")
|
||||
private Integer rtspPort = 0;
|
||||
|
||||
@ -122,7 +125,7 @@ public class MediaConfig{
|
||||
public int getRtmpPort() {
|
||||
return rtmpPort;
|
||||
}
|
||||
|
||||
|
||||
public int getRtmpSSlPort() {
|
||||
return rtmpSSlPort;
|
||||
}
|
||||
@ -136,6 +139,14 @@ public class MediaConfig{
|
||||
|
||||
}
|
||||
|
||||
public Integer getJttProxyPort() {
|
||||
if (jttProxyPort == null) {
|
||||
return 0;
|
||||
}else {
|
||||
return jttProxyPort;
|
||||
}
|
||||
}
|
||||
|
||||
public int getRtspPort() {
|
||||
return rtspPort;
|
||||
}
|
||||
@ -159,7 +170,7 @@ public class MediaConfig{
|
||||
public String getRtpPortRange() {
|
||||
return rtpPortRange;
|
||||
}
|
||||
|
||||
|
||||
public int getRecordAssistPort() {
|
||||
return recordAssistPort;
|
||||
}
|
||||
@ -229,6 +240,7 @@ public class MediaConfig{
|
||||
mediaServer.setRtmpPort(rtmpPort);
|
||||
mediaServer.setRtmpSSlPort(rtmpSSlPort);
|
||||
mediaServer.setRtpProxyPort(getRtpProxyPort());
|
||||
mediaServer.setJttProxyPort(getJttProxyPort());
|
||||
mediaServer.setRtspPort(rtspPort);
|
||||
mediaServer.setRtspSSLPort(rtspSSLPort);
|
||||
mediaServer.setAutoConfig(autoConfig);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.conf;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.web.context.WebServerInitializedEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@ -9,17 +10,14 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class ServiceInfo implements ApplicationListener<WebServerInitializedEvent> {
|
||||
|
||||
@Getter
|
||||
private static int serverPort;
|
||||
|
||||
public static int getServerPort() {
|
||||
return serverPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(WebServerInitializedEvent event) {
|
||||
// 项目启动获取启动的端口号
|
||||
ServiceInfo.serverPort = event.getWebServer().getPort();
|
||||
log.info("项目启动获取启动的端口号: " + ServiceInfo.serverPort);
|
||||
log.info("项目启动获取启动的端口号: {}", ServiceInfo.serverPort);
|
||||
}
|
||||
|
||||
public void setServerPort(int serverPort) {
|
||||
|
||||
@ -98,4 +98,12 @@ public class SpringDocConfig {
|
||||
.packagesToScan("com.genersoft.iot.vmp.user")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GroupedOpenApi publicApi7() {
|
||||
return GroupedOpenApi.builder()
|
||||
.group("6. 部标设备")
|
||||
.packagesToScan("com.genersoft.iot.vmp.jt1078.controller")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface FileCallback {
|
||||
|
||||
OutputStream run(String path);
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import org.apache.ftpserver.ftplet.Authority;
|
||||
import org.apache.ftpserver.ftplet.AuthorizationRequest;
|
||||
|
||||
public class FtpAuthority implements Authority {
|
||||
|
||||
@Override
|
||||
public boolean canAuthorize(AuthorizationRequest authorizationRequest) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationRequest authorize(AuthorizationRequest authorizationRequest) {
|
||||
return authorizationRequest;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import org.apache.ftpserver.ftplet.FileSystemFactory;
|
||||
import org.apache.ftpserver.ftplet.FileSystemView;
|
||||
import org.apache.ftpserver.ftplet.FtpException;
|
||||
import org.apache.ftpserver.ftplet.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Component
|
||||
public class FtpFileSystemFactory implements FileSystemFactory {
|
||||
|
||||
private final Map<String, OutputStream> outputStreamMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public FileSystemView createFileSystemView(User user) throws FtpException {
|
||||
return new FtpFileSystemView(user, path -> {
|
||||
return outputStreamMap.get(path);
|
||||
});
|
||||
}
|
||||
|
||||
public void addOutputStream(String filePath, OutputStream outputStream) {
|
||||
outputStreamMap.put(filePath, outputStream);
|
||||
}
|
||||
|
||||
public void removeOutputStream(String filePath) {
|
||||
outputStreamMap.remove(filePath);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import org.apache.ftpserver.ftplet.FileSystemView;
|
||||
import org.apache.ftpserver.ftplet.FtpException;
|
||||
import org.apache.ftpserver.ftplet.FtpFile;
|
||||
import org.apache.ftpserver.ftplet.User;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class FtpFileSystemView implements FileSystemView {
|
||||
|
||||
private User user;
|
||||
|
||||
private FileCallback fileCallback;
|
||||
|
||||
public FtpFileSystemView(User user, FileCallback fileCallback) {
|
||||
this.user = user;
|
||||
this.fileCallback = fileCallback;
|
||||
}
|
||||
|
||||
public static String HOME_PATH = "root";
|
||||
|
||||
public FtpFile workDir = VirtualFtpFile.getDir(HOME_PATH);
|
||||
|
||||
@Override
|
||||
public FtpFile getHomeDirectory() throws FtpException {
|
||||
return VirtualFtpFile.getDir(HOME_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FtpFile getWorkingDirectory() throws FtpException {
|
||||
return workDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeWorkingDirectory(String dir) throws FtpException {
|
||||
workDir = VirtualFtpFile.getDir(dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FtpFile getFile(String file) throws FtpException {
|
||||
VirtualFtpFile ftpFile = VirtualFtpFile.getFile(file);
|
||||
if (fileCallback != null) {
|
||||
OutputStream outputStream = fileCallback.run(workDir.getName());
|
||||
if (outputStream != null) {
|
||||
ftpFile.setOutputStream(outputStream);
|
||||
}
|
||||
}
|
||||
return ftpFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRandomAccessible() throws FtpException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ftpserver.*;
|
||||
import org.apache.ftpserver.ftplet.FtpException;
|
||||
import org.apache.ftpserver.listener.Listener;
|
||||
import org.apache.ftpserver.listener.ListenerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "ftp.enable", havingValue = "true")
|
||||
@Slf4j
|
||||
public class FtpServerConfig {
|
||||
|
||||
@Autowired
|
||||
private UserManager userManager;
|
||||
|
||||
@Autowired
|
||||
private FtpFileSystemFactory fileSystemFactory;
|
||||
|
||||
@Autowired
|
||||
private Ftplet ftplet;
|
||||
|
||||
@Autowired
|
||||
private FtpSetting ftpSetting;
|
||||
|
||||
/**
|
||||
* ftp server init
|
||||
*/
|
||||
@Bean
|
||||
public FtpServer ftpServer() {
|
||||
FtpServerFactory serverFactory = new FtpServerFactory();
|
||||
ListenerFactory listenerFactory = new ListenerFactory();
|
||||
// 1、设置服务端口
|
||||
listenerFactory.setPort(ftpSetting.getPort());
|
||||
// 2、设置被动模式数据上传的接口范围,云服务器需要开放对应区间的端口给客户端
|
||||
DataConnectionConfigurationFactory dataConnectionConfFactory = new DataConnectionConfigurationFactory();
|
||||
dataConnectionConfFactory.setPassivePorts(ftpSetting.getPassivePorts());
|
||||
listenerFactory.setDataConnectionConfiguration(dataConnectionConfFactory.createDataConnectionConfiguration());
|
||||
// 4、替换默认的监听器
|
||||
Listener listener = listenerFactory.createListener();
|
||||
serverFactory.addListener("default", listener);
|
||||
// 5、配置自定义用户事件
|
||||
Map<String, org.apache.ftpserver.ftplet.Ftplet> ftpLets = new HashMap<>();
|
||||
ftpLets.put("ftpService", ftplet);
|
||||
serverFactory.setFtplets(ftpLets);
|
||||
// 6、读取用户的配置信息
|
||||
// 6.2、设置用信息
|
||||
serverFactory.setUserManager(userManager);
|
||||
serverFactory.setFileSystem(fileSystemFactory);
|
||||
// 7、实例化FTP Server
|
||||
FtpServer server = serverFactory.createServer();
|
||||
try {
|
||||
server.start();
|
||||
if (!server.isStopped()) {
|
||||
log.info("[FTP服务] 已启动, 端口: {}", ftpSetting.getPort());
|
||||
}
|
||||
} catch (FtpException e) {
|
||||
log.info("[FTP服务] 启动失败 ", e);
|
||||
}
|
||||
return server;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 配置文件 user-settings 映射的配置信息
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "ftp", ignoreInvalidFields = true)
|
||||
@Order(0)
|
||||
@Data
|
||||
public class FtpSetting {
|
||||
|
||||
private Boolean enable = Boolean.FALSE;
|
||||
|
||||
private int port = 21;
|
||||
private String passivePorts = "10000-10500";
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.event.FtpUploadEvent;
|
||||
import org.apache.ftpserver.ftplet.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
@Component
|
||||
public class Ftplet extends DefaultFtplet {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(Ftplet.class);
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Override
|
||||
public FtpletResult onUploadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException {
|
||||
FtpFile file = session.getFileSystemView().getFile(request.getArgument());
|
||||
if (file == null) {
|
||||
return super.onUploadEnd(session, request);
|
||||
}
|
||||
sendEvent(file.getAbsolutePath());
|
||||
return super.onUploadUniqueEnd(session, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FtpletResult onAppendEnd(FtpSession session, FtpRequest request) throws FtpException, IOException {
|
||||
FtpFile file = session.getFileSystemView().getFile(request.getArgument());
|
||||
if (file == null) {
|
||||
return super.onUploadEnd(session, request);
|
||||
}
|
||||
sendEvent(file.getAbsolutePath());
|
||||
return super.onUploadUniqueEnd(session, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FtpletResult onUploadUniqueEnd(FtpSession session, FtpRequest request) throws FtpException, IOException {
|
||||
FtpFile file = session.getFileSystemView().getFile(request.getArgument());
|
||||
if (file == null) {
|
||||
return super.onUploadEnd(session, request);
|
||||
}
|
||||
sendEvent(file.getAbsolutePath());
|
||||
return super.onUploadUniqueEnd(session, request);
|
||||
}
|
||||
|
||||
private void sendEvent(String filePath){
|
||||
FtpUploadEvent event = new FtpUploadEvent(this);
|
||||
logger.info("[文件已上传]: {}", filePath);
|
||||
event.setFileName(filePath);
|
||||
applicationEventPublisher.publishEvent(event);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.ftpserver.ftplet.*;
|
||||
import org.apache.ftpserver.usermanager.UsernamePasswordAuthentication;
|
||||
import org.apache.ftpserver.usermanager.impl.BaseUser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class UserManager implements org.apache.ftpserver.ftplet.UserManager {
|
||||
|
||||
private static final String PREFIX = "VMP_FTP_USER_";
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<Object, Object> redisTemplate;
|
||||
|
||||
|
||||
@Override
|
||||
public User getUserByName(String username) throws FtpException {
|
||||
return (BaseUser)redisTemplate.opsForValue().get(PREFIX + username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAllUserNames() throws FtpException {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String username) throws FtpException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(User user) throws FtpException {}
|
||||
|
||||
@Override
|
||||
public boolean doesExist(String username) throws FtpException {
|
||||
return redisTemplate.opsForValue().get(PREFIX + username) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User authenticate(Authentication authentication) throws AuthenticationFailedException {
|
||||
UsernamePasswordAuthentication usernamePasswordAuthentication = (UsernamePasswordAuthentication) authentication;
|
||||
BaseUser user = (BaseUser)redisTemplate.opsForValue().get(PREFIX + usernamePasswordAuthentication.getUsername());
|
||||
if (user != null && usernamePasswordAuthentication.getPassword().equals(user.getPassword())) {
|
||||
return user;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdminName() throws FtpException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdmin(String username) throws FtpException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public BaseUser getRandomUser(){
|
||||
BaseUser use = new BaseUser();
|
||||
use.setName(RandomStringUtils.randomAlphabetic(6).toLowerCase());
|
||||
use.setPassword(RandomStringUtils.randomAlphabetic(6).toLowerCase());
|
||||
use.setEnabled(true);
|
||||
use.setHomeDirectory("/");
|
||||
List<Authority> authorities = new ArrayList<>();
|
||||
authorities.add(new FtpAuthority());
|
||||
use.setAuthorities(authorities);
|
||||
String key = PREFIX + use.getName();
|
||||
|
||||
// 随机用户信息十分钟自动失效
|
||||
Duration duration = Duration.ofMinutes(10);
|
||||
redisTemplate.opsForValue().set(key, use, duration);
|
||||
return use;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,166 @@
|
||||
package com.genersoft.iot.vmp.conf.ftpServer;
|
||||
|
||||
import lombok.Setter;
|
||||
import org.apache.ftpserver.ftplet.FtpFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class VirtualFtpFile implements FtpFile {
|
||||
|
||||
@Setter
|
||||
private String name;
|
||||
|
||||
@Setter
|
||||
private boolean hidden = false;
|
||||
|
||||
@Setter
|
||||
private boolean directory = false;
|
||||
|
||||
@Setter
|
||||
private String ownerName;
|
||||
|
||||
private Long lastModified = null;
|
||||
|
||||
@Setter
|
||||
private long size = 0;
|
||||
|
||||
@Setter
|
||||
private OutputStream outputStream;
|
||||
|
||||
public static VirtualFtpFile getFile(String name) {
|
||||
VirtualFtpFile virtualFtpFile = new VirtualFtpFile();
|
||||
virtualFtpFile.setName(name);
|
||||
return virtualFtpFile;
|
||||
}
|
||||
|
||||
public static VirtualFtpFile getDir(String name) {
|
||||
if (name.endsWith("/")) {
|
||||
name = name.replaceAll("/", "");
|
||||
}
|
||||
VirtualFtpFile virtualFtpFile = new VirtualFtpFile();
|
||||
virtualFtpFile.setName(name);
|
||||
virtualFtpFile.setDirectory(true);
|
||||
return virtualFtpFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAbsolutePath() {
|
||||
return FtpFileSystemView.HOME_PATH + "/" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory() {
|
||||
return directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFile() {
|
||||
return !directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesExist() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWritable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemovable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOwnerName() {
|
||||
return ownerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroupName() {
|
||||
return "root";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLinkCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified() {
|
||||
if (lastModified == null) {
|
||||
lastModified = System.currentTimeMillis();
|
||||
}
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLastModified(long time) {
|
||||
lastModified = time;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPhysicalFile() {
|
||||
System.err.println("getPhysicalFile");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mkdir() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean move(FtpFile destination) {
|
||||
this.name = destination.getName();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends FtpFile> listFiles() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream createOutputStream(long offset) throws IOException {
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream createInputStream(long offset) throws IOException {
|
||||
System.out.println("createInputStream----");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ public class JwtUtils implements InitializingBean {
|
||||
private static IUserService userService;
|
||||
|
||||
private static IUserApiKeyService userApiKeyService;
|
||||
|
||||
|
||||
private static UserSetting userSetting;
|
||||
|
||||
public static String getApiKeyHeader() {
|
||||
@ -236,7 +236,7 @@ public class JwtUtils implements InitializingBean {
|
||||
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON);
|
||||
} else {
|
||||
jwtUser.setStatus(JwtUser.TokenStatus.NORMAL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
jwtUser.setStatus(JwtUser.TokenStatus.NORMAL);
|
||||
}
|
||||
|
||||
@ -100,6 +100,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
defaultExcludes.add("/index/hook/**");
|
||||
defaultExcludes.add("/api/device/query/snap/**");
|
||||
defaultExcludes.add("/index/hook/abl/**");
|
||||
defaultExcludes.add("/api/jt1078/playback/download");
|
||||
defaultExcludes.add("/api/jt1078/snap");
|
||||
|
||||
|
||||
|
||||
|
||||
@ -11,4 +11,7 @@ public class CommonRecordInfo {
|
||||
// 结束时间
|
||||
private String endTime;
|
||||
|
||||
// 文件大小 单位byte
|
||||
private String fileSize;
|
||||
|
||||
}
|
||||
|
||||
@ -2,15 +2,19 @@ package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description:设备录像信息bean
|
||||
/**
|
||||
* @description:设备录像信息bean
|
||||
* @author: swwheihei
|
||||
* @date: 2020年5月8日 下午2:05:56
|
||||
* @date: 2020年5月8日 下午2:05:56
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "设备录像查询结果信息")
|
||||
public class RecordInfo {
|
||||
|
||||
@ -36,67 +40,4 @@ public class RecordInfo {
|
||||
@Schema(description = "")
|
||||
private List<RecordItem> recordList;
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getSumNum() {
|
||||
return sumNum;
|
||||
}
|
||||
|
||||
public void setSumNum(int sumNum) {
|
||||
this.sumNum = sumNum;
|
||||
}
|
||||
|
||||
public List<RecordItem> getRecordList() {
|
||||
return recordList;
|
||||
}
|
||||
|
||||
public void setRecordList(List<RecordItem> recordList) {
|
||||
this.recordList = recordList;
|
||||
}
|
||||
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
}
|
||||
|
||||
public void setChannelId(String channelId) {
|
||||
this.channelId = channelId;
|
||||
}
|
||||
|
||||
public String getSn() {
|
||||
return sn;
|
||||
}
|
||||
|
||||
public void setSn(String sn) {
|
||||
this.sn = sn;
|
||||
}
|
||||
|
||||
public Instant getLastTime() {
|
||||
return lastTime;
|
||||
}
|
||||
|
||||
public void setLastTime(Instant lastTime) {
|
||||
this.lastTime = lastTime;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ public class RecordItem implements Comparable<RecordItem>{
|
||||
@Schema(description = "保密属性(必选)缺省为0;0:不涉密,1:涉密")
|
||||
private int secrecy;
|
||||
|
||||
@Schema(description = "录像产生类型(可选)time或alarm 或 manua")
|
||||
@Schema(description = "录像产生类型(可选)time或alarm 或 manual")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "录像触发者ID(可选)")
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SipSendFailEvent extends SipSubscribe.EventResult<String> {
|
||||
|
||||
private String callId;
|
||||
|
||||
private String msg;
|
||||
|
||||
public static SipSendFailEvent getInstance(String callId, String msg){
|
||||
SipSendFailEvent sipSendFailEvent = new SipSendFailEvent();
|
||||
sipSendFailEvent.setMsg(msg);
|
||||
sipSendFailEvent.setCallId(callId);
|
||||
return sipSendFailEvent;
|
||||
}
|
||||
}
|
||||
@ -308,7 +308,6 @@ public class ChannelController {
|
||||
wvpResult.setCode(code);
|
||||
wvpResult.setMsg(msg);
|
||||
}
|
||||
|
||||
result.setResult(wvpResult);
|
||||
}else {
|
||||
result.setResult(WVPResult.fail(code, msg));
|
||||
|
||||
@ -583,4 +583,18 @@ public interface CommonGBChannelMapper {
|
||||
|
||||
@Update("UPDATE wvp_device_channel SET stream_id = #{stream} where id = #{gbId}")
|
||||
void updateStream(int gbId, String stream);
|
||||
|
||||
@Update("<script> " +
|
||||
"<foreach collection='commonGBChannels' index='index' item='item' separator=';'> " +
|
||||
"UPDATE wvp_device_channel " +
|
||||
" SET gb_longitude=#{item.gbLongitude}" +
|
||||
", gb_latitude=#{item.gbLatitude} " +
|
||||
", gps_speed=#{item.gpsSpeed} " +
|
||||
", gps_altitude=#{item.gpsAltitude} " +
|
||||
", gps_direction=#{item.gpsDirection} " +
|
||||
", gps_time=#{item.gpsTime} " +
|
||||
"WHERE id = #{item.gbId}" +
|
||||
"</foreach> " +
|
||||
"</script>")
|
||||
void updateGps(List<CommonGBChannel> commonGBChannels);
|
||||
}
|
||||
|
||||
@ -96,4 +96,5 @@ public interface IGbChannelService {
|
||||
|
||||
void updateGPSFromGPSMsgInfo(List<GPSMsgInfo> gpsMsgInfoList);
|
||||
|
||||
void updateGPS(List<CommonGBChannel> channelList);
|
||||
}
|
||||
|
||||
@ -7,6 +7,9 @@ import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.CommonGBChannelMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.service.*;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelPlayService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPlayService;
|
||||
import com.genersoft.iot.vmp.jt1078.service.Ijt1078PlayService;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -30,6 +33,9 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
@Autowired
|
||||
private Map<String, ISourcePlayService> sourcePlayServiceMap;
|
||||
|
||||
@Autowired
|
||||
private Ijt1078PlayService jt1078PlayService;
|
||||
|
||||
@Autowired
|
||||
private Map<String, ISourcePlaybackService> sourcePlaybackServiceMap;
|
||||
|
||||
@ -79,6 +85,8 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void play(CommonGBChannel channel, Platform platform, Boolean record, ErrorCallback<StreamInfo> callback) {
|
||||
log.info("[通用通道] 播放, 类型: {}, 编号:{}", channel.getDataType(), channel.getGbDeviceId());
|
||||
|
||||
@ -771,4 +771,21 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
}
|
||||
commonGBChannelMapper.updateGpsByDeviceId(gpsMsgInfoList);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void updateGPS(List<CommonGBChannel> commonGBChannels) {
|
||||
int limitCount = 1000;
|
||||
if (commonGBChannels.size() > limitCount) {
|
||||
for (int i = 0; i < commonGBChannels.size(); i += limitCount) {
|
||||
int toIndex = i + limitCount;
|
||||
if (i + limitCount > commonGBChannels.size()) {
|
||||
toIndex = commonGBChannels.size();
|
||||
}
|
||||
commonGBChannelMapper.updateGps(commonGBChannels.subList(i, toIndex));
|
||||
}
|
||||
} else {
|
||||
commonGBChannelMapper.updateGps(commonGBChannels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,17 +684,11 @@ public class PlayServiceImpl implements IPlayService {
|
||||
* @param stream ssrc
|
||||
*/
|
||||
private void snapOnPlay(MediaServer mediaServerItemInuse, String deviceId, String channelId, String stream) {
|
||||
String streamUrl;
|
||||
if (mediaServerItemInuse.getRtspPort() != 0) {
|
||||
streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", stream);
|
||||
} else {
|
||||
streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.mp4", mediaServerItemInuse.getHttpPort(), "rtp", stream);
|
||||
}
|
||||
String path = "snap";
|
||||
String fileName = deviceId + "_" + channelId + ".jpg";
|
||||
// 请求截图
|
||||
log.info("[请求截图]: " + fileName);
|
||||
mediaServerService.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
|
||||
mediaServerService.getSnap(mediaServerItemInuse, "rtp", stream, 15, 1, path, fileName);
|
||||
}
|
||||
|
||||
public StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, MediaInfo mediaInfo, Device device, DeviceChannel channel) {
|
||||
@ -1643,17 +1637,11 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (inviteInfo != null) {
|
||||
if (inviteInfo.getStreamInfo() != null) {
|
||||
// 已存在线直接截图
|
||||
MediaServer mediaServerItemInuse = inviteInfo.getStreamInfo().getMediaServer();
|
||||
String streamUrl;
|
||||
if (mediaServerItemInuse.getRtspPort() != 0) {
|
||||
streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", inviteInfo.getStreamInfo().getStream());
|
||||
}else {
|
||||
streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.mp4", mediaServerItemInuse.getHttpPort(), "rtp", inviteInfo.getStreamInfo().getStream());
|
||||
}
|
||||
MediaServer mediaServer = inviteInfo.getStreamInfo().getMediaServer();
|
||||
String path = "snap";
|
||||
// 请求截图
|
||||
log.info("[请求截图]: " + fileName);
|
||||
mediaServerService.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
|
||||
mediaServerService.getSnap(mediaServer, "rtp", inviteInfo.getStreamInfo().getStream(), 15, 1, path, fileName);
|
||||
File snapFile = new File(path + File.separator + fileName);
|
||||
if (snapFile.exists()) {
|
||||
errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), snapFile.getAbsoluteFile());
|
||||
|
||||
@ -101,6 +101,7 @@ public class SourcePlaybackServiceForGbImpl implements ISourcePlaybackService {
|
||||
CommonRecordInfo recordInfo = new CommonRecordInfo();
|
||||
recordInfo.setStartTime(recordItem.getStartTime());
|
||||
recordInfo.setEndTime(recordItem.getEndTime());
|
||||
recordInfo.setFileSize(recordItem.getFileSize());
|
||||
recordInfoList.add(recordInfo);
|
||||
}
|
||||
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), recordInfoList);
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd;
|
||||
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.event.record.RecordInfoEventListener;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelPlayService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderForPlatform;
|
||||
@ -27,6 +25,8 @@ import javax.sip.RequestEvent;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@ -40,6 +40,9 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
|
||||
@Autowired
|
||||
private IGbChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private IGbChannelPlayService playService;
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@ -105,55 +108,105 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (channel.getDataType() != ChannelDataType.GB28181) {
|
||||
log.info("[平台查询录像记录] 只支持查询国标28181的录像数据 {}/{}", platform.getName(), channelId );
|
||||
try {
|
||||
responseAck(request, Response.NOT_IMPLEMENTED); // 回复未实现
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] 平台查询录像记录: {}", e.getMessage());
|
||||
if (channel.getDataType() == ChannelDataType.GB28181) {
|
||||
Device device = deviceService.getDevice(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
log.warn("[平台查询录像记录] 未找到通道对应的设备 {}/{}", platform.getName(), channelId );
|
||||
try {
|
||||
responseAck(request, Response.BAD_REQUEST);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] [平台查询录像记录] 未找到通道对应的设备: {}", e.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
Device device = deviceService.getDevice(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
log.warn("[平台查询录像记录] 未找到通道对应的设备 {}/{}", platform.getName(), channelId );
|
||||
// 获取通道的原始信息
|
||||
DeviceChannel deviceChannel = deviceChannelService.getOneForSourceById(channel.getGbId());
|
||||
// 接收录像数据
|
||||
recordInfoEventListener.addEndEventHandler(device.getDeviceId(), deviceChannel.getDeviceId(), (recordInfo)->{
|
||||
try {
|
||||
log.info("[国标级联] 录像查询收到数据, 通道: {},准备转发===", channelId);
|
||||
cmderFroPlatform.recordInfo(channel, platform, request.getFromTag(), recordInfo);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] 国标级联 回复录像数据: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
try {
|
||||
responseAck(request, Response.BAD_REQUEST);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] [平台查询录像记录] 未找到通道对应的设备: {}", e.getMessage());
|
||||
commander.recordInfoQuery(device, deviceChannel.getDeviceId(), DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(startTime),
|
||||
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTime), sn, secrecy, type, (eventResult -> {
|
||||
// 回复200 OK
|
||||
try {
|
||||
responseAck(request, Response.OK);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] 录像查询回复: {}", e.getMessage());
|
||||
}
|
||||
}),(eventResult -> {
|
||||
// 查询失败
|
||||
try {
|
||||
responseAck(request, eventResult.statusCode, eventResult.msg);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] 录像查询回复: {}", e.getMessage());
|
||||
}
|
||||
}));
|
||||
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||
log.error("[命令发送失败] 录像查询: {}", e.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 获取通道的原始信息
|
||||
DeviceChannel deviceChannel = deviceChannelService.getOneForSourceById(channel.getGbId());
|
||||
// 接收录像数据
|
||||
recordInfoEventListener.addEndEventHandler(device.getDeviceId(), deviceChannel.getDeviceId(), (recordInfo)->{
|
||||
}else {
|
||||
// 回复200 OK
|
||||
try {
|
||||
log.info("[国标级联] 录像查询收到数据, 通道: {},准备转发===", channelId);
|
||||
cmderFroPlatform.recordInfo(channel, platform, request.getFromTag(), recordInfo);
|
||||
responseAck(request, Response.OK);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] 国标级联 回复录像数据: {}", e.getMessage());
|
||||
log.error("[命令发送失败] 录像查询回复: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
try {
|
||||
commander.recordInfoQuery(device, deviceChannel.getDeviceId(), DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(startTime),
|
||||
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTime), sn, secrecy, type, (eventResult -> {
|
||||
// 回复200 OK
|
||||
try {
|
||||
responseAck(request, Response.OK);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] 录像查询回复: {}", e.getMessage());
|
||||
}
|
||||
}),(eventResult -> {
|
||||
// 查询失败
|
||||
try {
|
||||
responseAck(request, eventResult.statusCode, eventResult.msg);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] 录像查询回复: {}", e.getMessage());
|
||||
}
|
||||
}));
|
||||
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||
log.error("[命令发送失败] 录像查询: {}", e.getMessage());
|
||||
|
||||
playService.queryRecord(channel, DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(startTime),
|
||||
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTime),
|
||||
(code, msg, commonRecordInfoList) -> {
|
||||
RecordInfo recordInfo = new RecordInfo();
|
||||
recordInfo.setSumNum(commonRecordInfoList.size());
|
||||
recordInfo.setChannelId(channelId);
|
||||
recordInfo.setSn(sn + "");
|
||||
List<RecordItem> recordList = new ArrayList<>(commonRecordInfoList.size());
|
||||
for (int i = 0; i < commonRecordInfoList.size(); i++) {
|
||||
CommonRecordInfo commonRecordInfo = commonRecordInfoList.get(i);
|
||||
RecordItem recordItem = new RecordItem();
|
||||
recordItem.setDeviceId(channelId);
|
||||
recordItem.setName(commonRecordInfo.getStartTime());
|
||||
recordItem.setFilePath("/" + commonRecordInfo.getStartTime());
|
||||
recordItem.setAddress("/" + commonRecordInfo.getStartTime());
|
||||
recordItem.setStartTime(commonRecordInfo.getStartTime());
|
||||
recordItem.setEndTime(commonRecordInfo.getEndTime());
|
||||
recordItem.setSecrecy(0);
|
||||
recordItem.setRecorderId("");
|
||||
recordItem.setType("");
|
||||
recordItem.setFileSize(commonRecordInfo.getFileSize());
|
||||
recordList.add(recordItem);
|
||||
}
|
||||
recordInfo.setRecordList(recordList);
|
||||
|
||||
try {
|
||||
log.info("[国标级联] 录像查询收到数据, 通道: {},准备转发===", channelId);
|
||||
cmderFroPlatform.recordInfo(channel, platform, request.getFromTag(), recordInfo);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
log.error("[命令发送失败] 国标级联 回复录像数据: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// if (channel.getDataType() != ChannelDataType.GB28181) {
|
||||
// log.info("[平台查询录像记录] 只支持查询国标28181的录像数据 {}/{}", platform.getName(), channelId );
|
||||
// try {
|
||||
// responseAck(request, Response.NOT_IMPLEMENTED); // 回复未实现
|
||||
// } catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
// log.error("[命令发送失败] 平台查询录像记录: {}", e.getMessage());
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
264
src/main/java/com/genersoft/iot/vmp/jt1078/bean/JTAlarmSign.java
Normal file
264
src/main/java/com/genersoft/iot/vmp/jt1078/bean/JTAlarmSign.java
Normal file
@ -0,0 +1,264 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.config.JTDeviceSubConfig;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 报警标志
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "报警标志")
|
||||
public class JTAlarmSign implements JTDeviceSubConfig {
|
||||
|
||||
@Schema(description = "紧急报警,触动报警开关后触发")
|
||||
private boolean urgent;
|
||||
@Schema(description = "超速报警")
|
||||
private boolean alarmSpeeding;
|
||||
@Schema(description = "疲劳驾驶报警")
|
||||
private boolean alarmTired;
|
||||
@Schema(description = "危险驾驶行为报警")
|
||||
private boolean alarmDangerous;
|
||||
@Schema(description = "GNSS 模块发生故障报警")
|
||||
private boolean alarmGnssFault;
|
||||
@Schema(description = "GNSS 天线未接或被剪断报警")
|
||||
private boolean alarmGnssBreak;
|
||||
@Schema(description = "GNSS 天线短路报警")
|
||||
private boolean alarmGnssShortCircuited;
|
||||
@Schema(description = "终端主电源欠压报警")
|
||||
private boolean alarmUnderVoltage;
|
||||
@Schema(description = "终端主电源掉电报警")
|
||||
private boolean alarmPowerOff;
|
||||
@Schema(description = "终端 LCD或显示器故障报警")
|
||||
private boolean alarmLCD;
|
||||
@Schema(description = "TTS 模块故障报警")
|
||||
private boolean alarmTtsFault;
|
||||
@Schema(description = "摄像头故障报警")
|
||||
private boolean alarmCameraFault;
|
||||
@Schema(description = "道路运输证 IC卡模块故障报警")
|
||||
private boolean alarmIcFault;
|
||||
@Schema(description = "超速预警")
|
||||
private boolean warningSpeeding;
|
||||
@Schema(description = "疲劳驾驶预警")
|
||||
private boolean warningTired;
|
||||
@Schema(description = "违规行驶报警")
|
||||
private boolean alarmWrong;
|
||||
@Schema(description = "胎压预警")
|
||||
private boolean warningTirePressure;
|
||||
@Schema(description = "右转盲区异常报警")
|
||||
private boolean alarmBlindZone;
|
||||
@Schema(description = "当天累计驾驶超时报警")
|
||||
private boolean alarmDrivingTimeout;
|
||||
@Schema(description = "超时停车报警")
|
||||
private boolean alarmParkingTimeout;
|
||||
@Schema(description = "进出区域报警")
|
||||
private boolean alarmRegion;
|
||||
@Schema(description = "进出路线报警")
|
||||
private boolean alarmRoute;
|
||||
@Schema(description = "路段行驶时间不足/过长报警")
|
||||
private boolean alarmTravelTime;
|
||||
@Schema(description = "路线偏离报警")
|
||||
private boolean alarmRouteDeviation;
|
||||
@Schema(description = "车辆 VSS 故障")
|
||||
private boolean alarmVSS;
|
||||
@Schema(description = "车辆油量异常报警")
|
||||
private boolean alarmOil;
|
||||
@Schema(description = "车辆被盗报警(通过车辆防盗器)")
|
||||
private boolean alarmStolen;
|
||||
@Schema(description = "车辆非法点火报警")
|
||||
private boolean alarmIllegalIgnition;
|
||||
@Schema(description = "车辆非法位移报警")
|
||||
private boolean alarmIllegalDisplacement;
|
||||
@Schema(description = "碰撞侧翻报警")
|
||||
private boolean alarmRollover;
|
||||
@Schema(description = "侧翻预警")
|
||||
private boolean warningRollover;
|
||||
|
||||
public JTAlarmSign() {
|
||||
}
|
||||
|
||||
public JTAlarmSign(long alarmSignInt) {
|
||||
if (alarmSignInt == 0) {
|
||||
return;
|
||||
}
|
||||
// 解析alarm参数
|
||||
this.urgent = (alarmSignInt & 1) == 1;
|
||||
this.alarmSpeeding = (alarmSignInt >>> 1 & 1) == 1;
|
||||
this.alarmTired = (alarmSignInt >>> 2 & 1) == 1;
|
||||
this.alarmDangerous = (alarmSignInt >>> 3 & 1) == 1;
|
||||
this.alarmGnssFault = (alarmSignInt >>> 4 & 1) == 1;
|
||||
this.alarmGnssBreak = (alarmSignInt >>> 5 & 1) == 1;
|
||||
this.alarmGnssShortCircuited = (alarmSignInt >>> 6 & 1) == 1;
|
||||
this.alarmUnderVoltage = (alarmSignInt >>> 7 & 1) == 1;
|
||||
this.alarmPowerOff = (alarmSignInt >>> 8 & 1) == 1;
|
||||
this.alarmLCD = (alarmSignInt >>> 9 & 1) == 1;
|
||||
this.alarmTtsFault = (alarmSignInt >>> 10 & 1) == 1;
|
||||
this.alarmCameraFault = (alarmSignInt >>> 11 & 1) == 1;
|
||||
this.alarmIcFault = (alarmSignInt >>> 12 & 1) == 1;
|
||||
this.warningSpeeding = (alarmSignInt >>> 13 & 1) == 1;
|
||||
this.warningTired = (alarmSignInt >>> 14 & 1) == 1;
|
||||
this.alarmWrong = (alarmSignInt >>> 15 & 1) == 1;
|
||||
this.warningTirePressure = (alarmSignInt >>> 16 & 1) == 1;
|
||||
this.alarmBlindZone = (alarmSignInt >>> 17 & 1) == 1;
|
||||
this.alarmDrivingTimeout = (alarmSignInt >>> 18 & 1) == 1;
|
||||
this.alarmParkingTimeout = (alarmSignInt >>> 19 & 1) == 1;
|
||||
this.alarmRegion = (alarmSignInt >>> 20 & 1) == 1;
|
||||
this.alarmRoute = (alarmSignInt >>> 21 & 1) == 1;
|
||||
this.alarmTravelTime = (alarmSignInt >>> 22 & 1) == 1;
|
||||
this.alarmRouteDeviation = (alarmSignInt >>> 23 & 1) == 1;
|
||||
this.alarmVSS = (alarmSignInt >>> 24 & 1) == 1;
|
||||
this.alarmOil = (alarmSignInt >>> 25 & 1) == 1;
|
||||
this.alarmStolen = (alarmSignInt >>> 26 & 1) == 1;
|
||||
this.alarmIllegalIgnition = (alarmSignInt >>> 27 & 1) == 1;
|
||||
this.alarmIllegalDisplacement = (alarmSignInt >>> 28 & 1) == 1;
|
||||
this.alarmRollover = (alarmSignInt >>> 29 & 1) == 1;
|
||||
this.warningRollover = (alarmSignInt >>> 30 & 1) == 1;
|
||||
}
|
||||
|
||||
public static JTAlarmSign decode(ByteBuf byteBuf) {
|
||||
long alarmSignByte = byteBuf.readUnsignedInt();
|
||||
return new JTAlarmSign(alarmSignByte);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
// 限定容量 避免影响后续占位
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
int alarmSignValue = 0;
|
||||
if (urgent) {
|
||||
alarmSignValue = alarmSignValue | 1;
|
||||
}
|
||||
if (alarmSpeeding) {
|
||||
alarmSignValue = alarmSignValue | 1 << 1;
|
||||
}
|
||||
if (alarmTired) {
|
||||
alarmSignValue = alarmSignValue | 1 << 2;
|
||||
}
|
||||
if (alarmDangerous) {
|
||||
alarmSignValue = alarmSignValue | 1 << 3;
|
||||
}
|
||||
if (alarmGnssFault) {
|
||||
alarmSignValue = alarmSignValue | 1 << 4;
|
||||
}
|
||||
if (alarmGnssBreak) {
|
||||
alarmSignValue = alarmSignValue | 1 << 5;
|
||||
}
|
||||
if (alarmGnssShortCircuited) {
|
||||
alarmSignValue = alarmSignValue | 1 << 6;
|
||||
}
|
||||
if (alarmUnderVoltage) {
|
||||
alarmSignValue = alarmSignValue | 1 << 7;
|
||||
}
|
||||
if (alarmPowerOff) {
|
||||
alarmSignValue = alarmSignValue | 1 << 8;
|
||||
}
|
||||
if (alarmLCD) {
|
||||
alarmSignValue = alarmSignValue | 1 << 9;
|
||||
}
|
||||
if (alarmTtsFault) {
|
||||
alarmSignValue = alarmSignValue | 1 << 10;
|
||||
}
|
||||
if (alarmCameraFault) {
|
||||
alarmSignValue = alarmSignValue | 1 << 11;
|
||||
}
|
||||
if (alarmIcFault) {
|
||||
alarmSignValue = alarmSignValue | 1 << 12;
|
||||
}
|
||||
if (warningSpeeding) {
|
||||
alarmSignValue = alarmSignValue | 1 << 13;
|
||||
}
|
||||
if (warningTired) {
|
||||
alarmSignValue = alarmSignValue | 1 << 14;
|
||||
}
|
||||
if (alarmWrong) {
|
||||
alarmSignValue = alarmSignValue | 1 << 15;
|
||||
}
|
||||
if (warningTirePressure) {
|
||||
alarmSignValue = alarmSignValue | 1 << 16;
|
||||
}
|
||||
if (alarmBlindZone) {
|
||||
alarmSignValue = alarmSignValue | 1 << 17;
|
||||
}
|
||||
if (alarmDrivingTimeout) {
|
||||
alarmSignValue = alarmSignValue | 1 << 18;
|
||||
}
|
||||
if (alarmParkingTimeout) {
|
||||
alarmSignValue = alarmSignValue | 1 << 19;
|
||||
}
|
||||
if (alarmRegion) {
|
||||
alarmSignValue = alarmSignValue | 1 << 20;
|
||||
}
|
||||
if (alarmRoute) {
|
||||
alarmSignValue = alarmSignValue | 1 << 21;
|
||||
}
|
||||
if (alarmTravelTime) {
|
||||
alarmSignValue = alarmSignValue | 1 << 22;
|
||||
}
|
||||
if (alarmRouteDeviation) {
|
||||
alarmSignValue = alarmSignValue | 1 << 23;
|
||||
}
|
||||
if (alarmVSS) {
|
||||
alarmSignValue = alarmSignValue | 1 << 24;
|
||||
}
|
||||
if (alarmOil) {
|
||||
alarmSignValue = alarmSignValue | 1 << 25;
|
||||
}
|
||||
if (alarmStolen) {
|
||||
alarmSignValue = alarmSignValue | 1 << 26;
|
||||
}
|
||||
if (alarmIllegalIgnition) {
|
||||
alarmSignValue = alarmSignValue | 1 << 27;
|
||||
}
|
||||
if (alarmIllegalDisplacement) {
|
||||
alarmSignValue = alarmSignValue | 1 << 28;
|
||||
}
|
||||
if (alarmRollover) {
|
||||
alarmSignValue = alarmSignValue | 1 << 29;
|
||||
}
|
||||
if (warningRollover) {
|
||||
alarmSignValue = alarmSignValue | 1 << 30;
|
||||
}
|
||||
byteBuf.writeInt(alarmSignValue);
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "状态报警标志位:" +
|
||||
"\n 紧急报警:" + (urgent?"开":"关") +
|
||||
"\n 超速报警:" + (alarmSpeeding?"开":"关") +
|
||||
"\n 疲劳驾驶报警:" + (alarmTired?"开":"关") +
|
||||
"\n 危险驾驶行为报警:" + (alarmDangerous?"开":"关") +
|
||||
"\n GNSS 模块发生故障报警:" + (alarmGnssFault?"开":"关") +
|
||||
"\n GNSS 天线未接或被剪断报警:" + (alarmGnssBreak?"开":"关") +
|
||||
"\n GNSS 天线短路报警:" + (alarmGnssShortCircuited?"开":"关") +
|
||||
"\n 终端主电源欠压报警:" + (alarmUnderVoltage?"开":"关") +
|
||||
"\n 终端主电源掉电报警:" + (alarmPowerOff?"开":"关") +
|
||||
"\n 终端LCD或显示器故障报警:" + (alarmLCD?"开":"关") +
|
||||
"\n TTS 模块故障报警:" + (alarmTtsFault?"开":"关") +
|
||||
"\n 摄像头故障报警:" + (alarmCameraFault?"开":"关") +
|
||||
"\n 道路运输证IC卡模块故障报警:" + (alarmIcFault?"开":"关") +
|
||||
"\n 超速预警:" + (warningSpeeding?"开":"关") +
|
||||
"\n 疲劳驾驶预警:" + (warningTired?"开":"关") +
|
||||
"\n 违规行驶报警:" + (alarmWrong ?"开":"关") +
|
||||
"\n 胎压预警:" + (warningTirePressure?"开":"关") +
|
||||
"\n 右转盲区异常报警:" + (alarmBlindZone?"开":"关") +
|
||||
"\n 当天累计驾驶超时报警:" + (alarmDrivingTimeout?"开":"关") +
|
||||
"\n 超时停车报警:" + (alarmParkingTimeout?"开":"关") +
|
||||
"\n 进出区域报警:" + (alarmRegion?"开":"关") +
|
||||
"\n 进出路线报警:" + (alarmRoute?"开":"关") +
|
||||
"\n 路段行驶时间不足/过长报警:" + (alarmTravelTime?"开":"关") +
|
||||
"\n 路线偏离报警:" + (alarmRouteDeviation?"开":"关") +
|
||||
"\n 车辆 VSS 故障:" + (alarmVSS?"开":"关") +
|
||||
"\n 车辆油量异常报警:" + (alarmOil?"开":"关") +
|
||||
"\n 车辆被盗报警(通过车辆防盗器):" + (alarmStolen?"开":"关") +
|
||||
"\n 车辆非法点火报警:" + (alarmIllegalIgnition?"开":"关") +
|
||||
"\n 车辆非法位移报警:" + (alarmIllegalDisplacement?"开":"关") +
|
||||
"\n 碰撞侧翻报警:" + (alarmRollover?"开":"关") +
|
||||
"\n 侧翻预警:" + (warningRollover?"开":"关") +
|
||||
"\n ";
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,103 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "区域属性")
|
||||
public class JTAreaAttribute {
|
||||
|
||||
@Schema(description = "是否启用起始时间与结束时间的判断规则 ,false:否;true:是")
|
||||
private boolean ruleForTimeLimit;
|
||||
|
||||
@Schema(description = "是否启用最高速度、超速持续时间和夜间最高速度的判断规则 ,false:否;true:是")
|
||||
private boolean ruleForSpeedLimit;
|
||||
|
||||
@Schema(description = "进区域是否报警给驾驶员,false:否;true:是")
|
||||
private boolean ruleForAlarmToDriverWhenEnter;
|
||||
|
||||
@Schema(description = "进区域是否报警给平台 ,false:否;true:是")
|
||||
private boolean ruleForAlarmToPlatformWhenEnter;
|
||||
|
||||
@Schema(description = "出区域是否报警给驾驶员,false:否;true:是")
|
||||
private boolean ruleForAlarmToDriverWhenExit;
|
||||
|
||||
@Schema(description = "出区域是否报警给平台 ,false:否;true:是")
|
||||
private boolean ruleForAlarmToPlatformWhenExit;
|
||||
|
||||
@Schema(description = "false:北纬;true:南纬")
|
||||
private boolean southLatitude;
|
||||
|
||||
@Schema(description = "false:东经;true:西经")
|
||||
private boolean westLongitude;
|
||||
|
||||
@Schema(description = "false:允许开门;true:禁止开门")
|
||||
private boolean prohibitOpeningDoors;
|
||||
|
||||
@Schema(description = "false:进区域开启通信模块;true:进区域关闭通信模块")
|
||||
private boolean ruleForTurnOffCommunicationWhenEnter;
|
||||
|
||||
@Schema(description = "false:进区域不采集 GNSS 详细定位数据;true:进区域采集 GNSS 详细定位数据")
|
||||
private boolean ruleForGnssWhenEnter;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
short content = 0 ;
|
||||
if (ruleForTimeLimit) {
|
||||
content |= 1;
|
||||
}
|
||||
if (ruleForSpeedLimit) {
|
||||
content |= (1 << 1);
|
||||
}
|
||||
if (ruleForAlarmToDriverWhenEnter) {
|
||||
content |= (1 << 2);
|
||||
}
|
||||
if (ruleForAlarmToPlatformWhenEnter) {
|
||||
content |= (1 << 3);
|
||||
}
|
||||
if (ruleForAlarmToDriverWhenExit) {
|
||||
content |= (1 << 4);
|
||||
}
|
||||
if (ruleForAlarmToPlatformWhenExit) {
|
||||
content |= (1 << 5);
|
||||
}
|
||||
if (southLatitude) {
|
||||
content |= (1 << 6);
|
||||
}
|
||||
if (westLongitude) {
|
||||
content |= (byte) (1 << 7);
|
||||
}
|
||||
if (prohibitOpeningDoors) {
|
||||
content |= (1 << (0 + 8));
|
||||
}
|
||||
if (ruleForTurnOffCommunicationWhenEnter) {
|
||||
content |= (1 << (1 + 8));
|
||||
}
|
||||
if (ruleForGnssWhenEnter) {
|
||||
content |= (1 << (2 + 8));
|
||||
}
|
||||
byteBuf.writeShort((short)(content & 0xffff));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTAreaAttribute decode(int attributeInt) {
|
||||
JTAreaAttribute attribute = new JTAreaAttribute();
|
||||
attribute.setRuleForTimeLimit((attributeInt & 1) == 1);
|
||||
attribute.setRuleForSpeedLimit((attributeInt >> 1 & 1) == 1);
|
||||
attribute.setRuleForAlarmToDriverWhenEnter((attributeInt >> 2 & 1) == 1);
|
||||
attribute.setRuleForAlarmToPlatformWhenEnter((attributeInt >> 3 & 1) == 1);
|
||||
attribute.setRuleForAlarmToDriverWhenExit((attributeInt >> 4 & 1) == 1);
|
||||
attribute.setRuleForAlarmToPlatformWhenExit((attributeInt >> 5 & 1) == 1);
|
||||
attribute.setSouthLatitude((attributeInt >> 6 & 1) == 1);
|
||||
attribute.setWestLongitude((attributeInt >> 7 & 1) == 1);
|
||||
attribute.setProhibitOpeningDoors((attributeInt >> 8 & 1) == 1);
|
||||
attribute.setRuleForTurnOffCommunicationWhenEnter((attributeInt >> 9 & 1) == 1);
|
||||
attribute.setRuleForGnssWhenEnter((attributeInt >> 10 & 1) == 1);
|
||||
return attribute;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
public interface JTAreaOrRoute {
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* JT 通道
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "jt808通道")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class JTChannel extends CommonGBChannel {
|
||||
|
||||
@Schema(description = "数据库自增ID")
|
||||
private int id;
|
||||
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "设备的数据库ID")
|
||||
private int terminalDbId;
|
||||
|
||||
@Schema(description = "通道ID")
|
||||
private Integer channelId;
|
||||
|
||||
@Schema(description = "是否含有音频")
|
||||
private boolean hasAudio;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private String createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private String updateTime;
|
||||
|
||||
@Schema(description = "流信息")
|
||||
private String stream;
|
||||
|
||||
private Integer dataType = ChannelDataType.JT_1078;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTChannel{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
", terminalDbId=" + terminalDbId +
|
||||
", channelId=" + channelId +
|
||||
", createTime='" + createTime + '\'' +
|
||||
", updateTime='" + updateTime + '\'' +
|
||||
", hasAudio='" + hasAudio + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public CommonGBChannel buildCommonGBChannel() {
|
||||
if (ObjectUtils.isEmpty(this.getGbDeviceId())) {
|
||||
return null;
|
||||
}
|
||||
if (ObjectUtils.isEmpty(this.getGbName())) {
|
||||
this.setGbName(this.getName());
|
||||
}
|
||||
return this;
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Date;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "圆形区域")
|
||||
public class JTCircleArea implements JTAreaOrRoute{
|
||||
|
||||
@Schema(description = "区域 ID")
|
||||
private long id;
|
||||
|
||||
@Schema(description = "")
|
||||
private JTAreaAttribute attribute;
|
||||
|
||||
@Schema(description = "中心点纬度")
|
||||
private Double latitude;
|
||||
|
||||
@Schema(description = "中心点经度")
|
||||
private Double longitude;
|
||||
|
||||
@Schema(description = "半径,单位为米(m)")
|
||||
private long radius;
|
||||
|
||||
@Schema(description = "起始时间, yyyy-MM-dd HH:mm:ss")
|
||||
private String startTime;
|
||||
|
||||
@Schema(description = "结束时间, yyyy-MM-dd HH:mm:ss")
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "最高速度, 单位为千米每小时(km/h)")
|
||||
private int maxSpeed;
|
||||
|
||||
@Schema(description = "超速持续时间, 单位为秒(s)")
|
||||
private int overSpeedDuration;
|
||||
|
||||
@Schema(description = "夜间最高速度, 单位为千米每小时(km/h)")
|
||||
private int nighttimeMaxSpeed;
|
||||
|
||||
@Schema(description = "区域的名称")
|
||||
private String name;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeInt((int) (id & 0xffffffffL));
|
||||
byteBuf.writeBytes(attribute.encode());
|
||||
byteBuf.writeInt((int) (Math.round((latitude * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (Math.round((longitude * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (radius & 0xffffffffL));
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(startTime)));
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(endTime)));
|
||||
byteBuf.writeShort((short)(maxSpeed & 0xffff));
|
||||
byteBuf.writeByte(overSpeedDuration);
|
||||
byteBuf.writeShort((short)(nighttimeMaxSpeed & 0xffff));
|
||||
byteBuf.writeShort((short)(name.getBytes(Charset.forName("GBK")).length & 0xffff));
|
||||
byteBuf.writeCharSequence(name, Charset.forName("GBK"));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTCircleArea decode(ByteBuf buf) {
|
||||
|
||||
JTCircleArea area = new JTCircleArea();
|
||||
area.setId(buf.readUnsignedInt());
|
||||
int attributeInt = buf.readUnsignedShort();
|
||||
JTAreaAttribute areaAttribute = JTAreaAttribute.decode(attributeInt);
|
||||
area.setAttribute(areaAttribute);
|
||||
|
||||
area.setLatitude(buf.readUnsignedInt()/1000000D);
|
||||
area.setLongitude(buf.readUnsignedInt()/1000000D);
|
||||
area.setRadius(buf.readUnsignedInt());
|
||||
byte[] startTimeBytes = new byte[6];
|
||||
buf.readBytes(startTimeBytes);
|
||||
area.setStartTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(startTimeBytes)));
|
||||
byte[] endTimeBytes = new byte[6];
|
||||
buf.readBytes(endTimeBytes);
|
||||
area.setEndTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(endTimeBytes)));
|
||||
area.setMaxSpeed(buf.readUnsignedShort());
|
||||
area.setOverSpeedDuration(buf.readUnsignedByte());
|
||||
area.setNighttimeMaxSpeed(buf.readUnsignedShort());
|
||||
int nameLength = buf.readUnsignedShort();
|
||||
area.setName(buf.readCharSequence(nameLength, Charset.forName("GBK")).toString().trim());
|
||||
return area;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* JT 通信模块属性
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "JT通信模块属性")
|
||||
public class JTCommunicationModuleAttribute {
|
||||
|
||||
private boolean gprs ;
|
||||
private boolean cdma ;
|
||||
private boolean tdScdma ;
|
||||
private boolean wcdma ;
|
||||
private boolean cdma2000 ;
|
||||
private boolean tdLte ;
|
||||
private boolean other ;
|
||||
|
||||
|
||||
public static JTCommunicationModuleAttribute getInstance(short content) {
|
||||
boolean gprs = (content & 1) == 1;
|
||||
boolean cdma = (content >>> 1 & 1) == 1;
|
||||
boolean tdScdma = (content >>> 2 & 1) == 1;
|
||||
boolean wcdma = (content >>> 3 & 1) == 1;
|
||||
boolean cdma2000 = (content >>> 4 & 1) == 1;
|
||||
boolean tdLte = (content >>> 5 & 1) == 1;
|
||||
boolean other = (content >>> 7 & 1) == 1;
|
||||
return new JTCommunicationModuleAttribute(gprs, cdma, tdScdma, wcdma, cdma2000, tdLte, other);
|
||||
}
|
||||
|
||||
public JTCommunicationModuleAttribute(boolean gprs, boolean cdma, boolean tdScdma, boolean wcdma, boolean cdma2000, boolean tdLte, boolean other) {
|
||||
this.gprs = gprs;
|
||||
this.cdma = cdma;
|
||||
this.tdScdma = tdScdma;
|
||||
this.wcdma = wcdma;
|
||||
this.cdma2000 = cdma2000;
|
||||
this.tdLte = tdLte;
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JCommunicationModuleAttribute{" +
|
||||
"gprs=" + gprs +
|
||||
", cdma=" + cdma +
|
||||
", tdScdma=" + tdScdma +
|
||||
", wcdma=" + wcdma +
|
||||
", cdma2000=" + cdma2000 +
|
||||
", tdLte=" + tdLte +
|
||||
", other=" + other +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "人工确认报警类型")
|
||||
public class JTConfirmationAlarmMessageType {
|
||||
@Schema(description = "确认紧急报警")
|
||||
private boolean urgent;
|
||||
@Schema(description = "确认危险预警")
|
||||
private boolean alarmDangerous;
|
||||
@Schema(description = "确认进出区域报警")
|
||||
private boolean alarmRegion;
|
||||
@Schema(description = "确认进出路线报警")
|
||||
private boolean alarmRoute;
|
||||
@Schema(description = "确认路段行驶时间不足/过长报警")
|
||||
private boolean alarmTravelTime;
|
||||
@Schema(description = "确认车辆非法点火报警")
|
||||
private boolean alarmIllegalIgnition;
|
||||
@Schema(description = "确认车辆非法位移报警")
|
||||
private boolean alarmIllegalDisplacement;
|
||||
|
||||
public long encode(){
|
||||
long result = 0L;
|
||||
if (urgent) {
|
||||
result |= 0x01;
|
||||
}
|
||||
if (alarmDangerous) {
|
||||
result |= (0x01 << 3);
|
||||
}
|
||||
if (alarmRegion) {
|
||||
result |= (0x01 << 20);
|
||||
}
|
||||
if (alarmRoute) {
|
||||
result |= (0x01 << 21);
|
||||
}
|
||||
if (alarmTravelTime) {
|
||||
result |= (0x01 << 22);
|
||||
}
|
||||
if (alarmIllegalIgnition) {
|
||||
result |= (0x01 << 27);
|
||||
}
|
||||
if (alarmIllegalDisplacement) {
|
||||
result |= (0x01 << 28);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JConfirmationAlarmMessageType{" +
|
||||
"urgent=" + urgent +
|
||||
", alarmDangerous=" + alarmDangerous +
|
||||
", alarmRegion=" + alarmRegion +
|
||||
", alarmRoute=" + alarmRoute +
|
||||
", alarmTravelTime=" + alarmTravelTime +
|
||||
", alarmIllegalIgnition=" + alarmIllegalIgnition +
|
||||
", alarmIllegalDisplacement=" + alarmIllegalDisplacement +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* JT 设备
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "jt808设备")
|
||||
public class JTDevice {
|
||||
|
||||
private int id;
|
||||
|
||||
@Schema(description = "省域ID")
|
||||
private String provinceId;
|
||||
|
||||
@Schema(description = "省域文字描述")
|
||||
private String provinceText;
|
||||
|
||||
@Schema(description = "市县域ID")
|
||||
private String cityId;
|
||||
|
||||
@Schema(description = "市县域文字描述")
|
||||
private String cityText;
|
||||
|
||||
@Schema(description = "制造商ID")
|
||||
private String makerId;
|
||||
|
||||
@Schema(description = "终端型号")
|
||||
private String model;
|
||||
|
||||
@Schema(description = "终端手机号")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "终端ID")
|
||||
private String terminalId;
|
||||
|
||||
@Schema(description = "车牌颜色")
|
||||
private int plateColor;
|
||||
|
||||
@Schema(description = "车牌")
|
||||
private String plateNo;
|
||||
|
||||
@Schema(description = "鉴权码")
|
||||
private String authenticationCode;
|
||||
|
||||
@Schema(description = "经度")
|
||||
private Double longitude;
|
||||
|
||||
@Schema(description = "纬度")
|
||||
private Double latitude;
|
||||
|
||||
@Schema(description = "注册时间")
|
||||
private String registerTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private String createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private String updateTime;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private boolean status;
|
||||
|
||||
@Schema(description = "设备使用的媒体id, 默认为null")
|
||||
private String mediaServerId;
|
||||
|
||||
@Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02")
|
||||
private String geoCoordSys;
|
||||
|
||||
@Schema(description = "收流IP")
|
||||
private String sdpIp;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTDevice{" +
|
||||
" 终端手机号='" + phoneNumber + '\'' +
|
||||
", 省域ID='" + provinceId + '\'' +
|
||||
", 省域文字描述='" + provinceText + '\'' +
|
||||
", 市县域ID='" + cityId + '\'' +
|
||||
", 市县域文字描述='" + cityText + '\'' +
|
||||
", 制造商ID='" + makerId + '\'' +
|
||||
", 终端型号='" + model + '\'' +
|
||||
", 设备ID='" + terminalId + '\'' +
|
||||
", 车牌颜色=" + plateColor +
|
||||
", 车牌='" + plateNo + '\'' +
|
||||
", 注册时间='" + registerTime + '\'' +
|
||||
", status=" + status +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* JT 终端属性
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "JT终端属性")
|
||||
public class JTDeviceAttribute {
|
||||
|
||||
@Schema(description = "终端类型")
|
||||
private JTDeviceType type;
|
||||
|
||||
@Schema(description = "制造商 ID")
|
||||
private String makerId;
|
||||
|
||||
@Schema(description = "终端型号")
|
||||
private String deviceModel;
|
||||
|
||||
@Schema(description = "终端 ID")
|
||||
private String terminalId;
|
||||
|
||||
@Schema(description = "终端 SIM卡 ICCID")
|
||||
private String iccId;
|
||||
|
||||
@Schema(description = "终端硬件版本号")
|
||||
private String hardwareVersion;
|
||||
|
||||
@Schema(description = "固件版本号")
|
||||
private String firmwareVersion ;
|
||||
|
||||
@Schema(description = "GNSS 模块属性")
|
||||
private JTGnssAttribute gnssAttribute ;
|
||||
|
||||
@Schema(description = "通信模块属性")
|
||||
private JTCommunicationModuleAttribute communicationModuleAttribute ;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTDeviceAttribute{" +
|
||||
"type=" + type +
|
||||
", makerId='" + makerId + '\'' +
|
||||
", deviceModel='" + deviceModel + '\'' +
|
||||
", terminalId='" + terminalId + '\'' +
|
||||
", iccId='" + iccId + '\'' +
|
||||
", hardwareVersion='" + hardwareVersion + '\'' +
|
||||
", firmwareVersion='" + firmwareVersion + '\'' +
|
||||
", gnssAttribute=" + gnssAttribute +
|
||||
", communicationModuleAttribute=" + communicationModuleAttribute +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,380 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.common.ConfigAttribute;
|
||||
import com.genersoft.iot.vmp.jt1078.bean.config.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* JT 终端参数设置
|
||||
*/
|
||||
@Schema(description = "JT终端参数设置")
|
||||
@Data
|
||||
public class JTDeviceConfig {
|
||||
|
||||
@ConfigAttribute(id = 0x1, type="Long", description = "终端心跳发送间隔,单位为秒(s)")
|
||||
private Long keepaliveInterval;
|
||||
|
||||
@ConfigAttribute(id = 0x2, type="Long", description = "TCP消息应答超时时间,单位为秒(s)")
|
||||
private Long tcpResponseTimeout;
|
||||
|
||||
@ConfigAttribute(id = 0x3, type="Long", description = "TCP消息重传次数")
|
||||
private Long tcpRetransmissionCount;
|
||||
|
||||
@ConfigAttribute(id = 0x4, type="Long", description = "UDP消息应答超时时间,单位为秒(s)")
|
||||
private Long udpResponseTimeout;
|
||||
|
||||
@ConfigAttribute(id = 0x5, type="Long", description = "UDP消息重传次数")
|
||||
private Long udpRetransmissionCount;
|
||||
|
||||
@ConfigAttribute(id = 0x6, type="Long", description = "SMS 消息应答超时时间,单位为秒(s)")
|
||||
private Long smsResponseTimeout;
|
||||
|
||||
@ConfigAttribute(id = 0x7, type="Long", description = "SMS 消息重传次数")
|
||||
private Long smsRetransmissionCount;
|
||||
|
||||
@ConfigAttribute(id = 0x10, type="String", description = "主服务器APN无线通信拨号访问点,若网络制式为 CDMA,则该处 为 PPP拨号号码")
|
||||
private String apnMaster;
|
||||
|
||||
@ConfigAttribute(id = 0x11, type="String", description = "主服务器无线通信拨号用户名")
|
||||
private String dialingUsernameMaster;
|
||||
|
||||
@ConfigAttribute(id = 0x12, type="String", description = "主服务器无线通信拨号密码")
|
||||
private String dialingPasswordMaster;
|
||||
|
||||
@ConfigAttribute(id = 0x13, type="String", description = "主服务器地址IP或域名,以冒号分割主机和端口 多个服务器使用分号分割")
|
||||
private String addressMaster;
|
||||
|
||||
@ConfigAttribute(id = 0x14, type="String", description = "备份服务器APN")
|
||||
private String apnBackup;
|
||||
|
||||
@ConfigAttribute(id = 0x15, type="String", description = "备份服务器无线通信拨号用户名")
|
||||
private String dialingUsernameBackup;
|
||||
|
||||
@ConfigAttribute(id = 0x16, type="String", description = "备份服务器无线通信拨号密码")
|
||||
private String dialingPasswordBackup;
|
||||
|
||||
@ConfigAttribute(id = 0x17, type="String", description = "备用服务器备份地址IP或域名,以冒号分割主机和端口 多个服务器使用分号分割")
|
||||
private String addressBackup;
|
||||
|
||||
@ConfigAttribute(id = 0x1a, type="String", description = "道路运输证IC卡认证主服务器IP地址或域名")
|
||||
private String addressIcMaster;
|
||||
|
||||
@ConfigAttribute(id = 0x1b, type="Long", description = "道路运输证IC卡认证主服务器TCP端口")
|
||||
private Long tcpPortIcMaster;
|
||||
|
||||
@ConfigAttribute(id = 0x1c, type="Long", description = "道路运输证IC卡认证主服务器UDP端口")
|
||||
private Long udpPortIcMaster;
|
||||
|
||||
@ConfigAttribute(id = 0x1d, type="String", description = "道路运输证IC卡认证备份服务器IP地址或域名,端口同主服务器")
|
||||
private String addressIcBackup;
|
||||
|
||||
@ConfigAttribute(id = 0x20, type="Long", description = "位置汇报策略, 0定时汇报 1定距汇报 2定时和定距汇报")
|
||||
private Long locationReportingStrategy;
|
||||
|
||||
@ConfigAttribute(id = 0x21, type="Long", description = "位置汇报方案,0根据ACC状态 1根据登录状态和ACC状态,先判断登录状态,若登录再根据ACC状态")
|
||||
private Long locationReportingPlan;
|
||||
|
||||
@ConfigAttribute(id = 0x22, type="Long", description = "驾驶员未登录汇报时间间隔,单位为秒,值大于零")
|
||||
private Long reportingIntervalOffline;
|
||||
|
||||
@ConfigAttribute(id = 0x23, type="String", description = "从服务器 APN# 该值为空时 !终端应使用主服务器相同配置")
|
||||
private String apnSlave;
|
||||
|
||||
@ConfigAttribute(id = 0x24, type="String", description = "从服务器无线通信拨号用户名 # 该值为空时 !终端应使用主服务器 相同配置")
|
||||
private String dialingUsernameSlave;
|
||||
|
||||
@ConfigAttribute(id = 0x25, type="String", description = "从服务器无线通信拨号密码 # 该值为空时 !终端应使用主服务器相 同配置")
|
||||
private String dialingPasswordSlave;
|
||||
|
||||
@ConfigAttribute(id = 0x26, type="String", description = "从服务器备份地址 IP或域名 !主机和端口用冒号分割 !多个服务器 使用分号分割")
|
||||
private String addressSlave;
|
||||
|
||||
@ConfigAttribute(id = 0x27, type="Long", description = "休眠时汇报时间间隔 单位为秒 值大于0")
|
||||
private Long reportingIntervalDormancy;
|
||||
|
||||
@ConfigAttribute(id = 0x28, type="Long", description = "紧急报警时汇报时间间隔 单位为秒 值大于0")
|
||||
private Long reportingIntervalEmergencyAlarm;
|
||||
|
||||
@ConfigAttribute(id = 0x29, type="Long", description = "缺省时间汇报间隔 单位为秒 值大于0")
|
||||
private Long reportingIntervalDefault;
|
||||
|
||||
@ConfigAttribute(id = 0x2c, type="Long", description = "缺省距离汇报间隔 单位为米 值大于0")
|
||||
private Long reportingDistanceDefault;
|
||||
|
||||
@ConfigAttribute(id = 0x2d, type="Long", description = "驾驶员未登录汇报距离间隔 单位为米 值大于0")
|
||||
private Long reportingDistanceOffline;
|
||||
|
||||
@ConfigAttribute(id = 0x2e, type="Long", description = "休眠时汇报距离间隔 单位为米 值大于0")
|
||||
private Long reportingDistanceDormancy;
|
||||
|
||||
@ConfigAttribute(id = 0x2f, type="Long", description = "紧急报警时汇报距离间隔 单位为米 值大于0")
|
||||
private Long reportingDistanceEmergencyAlarm;
|
||||
|
||||
@ConfigAttribute(id = 0x30, type="Long", description = "拐点补传角度 ,值小于180")
|
||||
private Long inflectionPointAngle;
|
||||
|
||||
@ConfigAttribute(id = 0x31, type="Integer", description = "电子围栏半径(非法位移國值) ,单位为米(m)")
|
||||
private Integer fenceRadius;
|
||||
|
||||
@ConfigAttribute(id = 0x32, type="IllegalDrivingPeriods", description = "违规行驶时段范围 ,精确到分")
|
||||
private JTIllegalDrivingPeriods illegalDrivingPeriods;
|
||||
|
||||
@ConfigAttribute(id = 0x40, type="String", description = "监控平台电话号码")
|
||||
private String platformPhoneNumber;
|
||||
|
||||
@ConfigAttribute(id = 0x41, type="String", description = "复位电话号码 ,可采用此电话号码拨打终端电话让终端复位")
|
||||
private String phoneNumberForReset;
|
||||
|
||||
@ConfigAttribute(id = 0x42, type="String", description = "恢复出厂设置电话号码 ,可采用此电话号码拨打终端电话让终端恢 复出厂设置")
|
||||
private String phoneNumberForFactoryReset;
|
||||
|
||||
@ConfigAttribute(id = 0x42, type="String", description = "监控平台 SMS 电话号码")
|
||||
private String phoneNumberForSms;
|
||||
|
||||
@ConfigAttribute(id = 0x44, type="String", description = "接收终端 SMS 文本报警号码")
|
||||
private String phoneNumberForReceiveTextAlarm;
|
||||
|
||||
@ConfigAttribute(id = 0x45, type="Long", description = "终端电话接听策略 。0:自动接听;1:ACC ON时自动接听 ,OFF时手动接听")
|
||||
private Long phoneAnsweringPolicy;
|
||||
|
||||
@ConfigAttribute(id = 0x46, type="Long", description = "每次最长通话时间 ,单位为秒(s) ,0 为不允许通话 ,0xFFFFFFFF为不限制")
|
||||
private Long longestCallTimeForPerSession;
|
||||
|
||||
@ConfigAttribute(id = 0x47, type="Long", description = "当月最长通话时间 ,单位为秒(s) ,0 为不允许通话 ,0xFFFFFFFF为 不限制")
|
||||
private Long longestCallTimeInMonth;
|
||||
|
||||
@ConfigAttribute(id = 0x48, type="String", description = "监听电话号码")
|
||||
private String phoneNumbersForListen;
|
||||
|
||||
@ConfigAttribute(id = 0x49, type="String", description = "监管平台特权短信号码")
|
||||
private String privilegedSMSNumber;
|
||||
|
||||
@ConfigAttribute(id = 0x50, type="AlarmSign", description = "报警屏蔽字 ,与位置信息汇报消息中的报警标志相对应 ,相应位为 1 则相应报警被屏蔽")
|
||||
private JTAlarmSign alarmMaskingWord;
|
||||
|
||||
@ConfigAttribute(id = 0x51, type="AlarmSign", description = "报警发送文本 SMS 开关 , 与位置信息汇报消息中的报警标志相对 应 ,相应位为1 则相应报警时发送文本 SMS")
|
||||
private JTAlarmSign alarmSendsTextSmsSwitch;
|
||||
|
||||
@ConfigAttribute(id = 0x52, type="AlarmSign", description = "报警拍摄开关 ,与位置信息汇报消息中的报警标志相对应 ,相应位为 1 则相应报警时摄像头拍摄")
|
||||
private JTAlarmSign alarmShootingSwitch;
|
||||
|
||||
@ConfigAttribute(id = 0x53, type="AlarmSign", description = "报警拍摄存储标志 ,与位置信息汇报消息中的报警标志相对应 ,相应 位为1 则对相应报警时拍的照片进行存储 ,否则实时上传")
|
||||
private JTAlarmSign alarmShootingStorageFlags;
|
||||
|
||||
@ConfigAttribute(id = 0x54, type="AlarmSign", description = "关键标志 ,与位置信息汇报消息中的报警标志相对应 ,相应位为 1 则 对相应报警为关键报警")
|
||||
private JTAlarmSign KeySign;
|
||||
|
||||
@ConfigAttribute(id = 0x55, type="Long", description = "最高速度 ,单位为千米每小时(km/h)")
|
||||
private Long maxSpeed;
|
||||
|
||||
@ConfigAttribute(id = 0x56, type="Long", description = "超速持续时间 ,单位为秒(s)")
|
||||
private Long overSpeedDuration;
|
||||
|
||||
@ConfigAttribute(id = 0x57, type="Long", description = "连续驾驶时间门限 单位为秒(s)")
|
||||
private Long continuousDrivingTimeThreshold;
|
||||
|
||||
@ConfigAttribute(id = 0x58, type="Long", description = "当天累计驾驶时间门限 单位为秒(s)")
|
||||
private Long cumulativeDrivingTimeThresholdForTheDay;
|
||||
|
||||
@ConfigAttribute(id = 0x59, type="Long", description = "最小休息时间 单位为秒(s)")
|
||||
private Long minimumBreakTime;
|
||||
|
||||
@ConfigAttribute(id = 0x5a, type="Long", description = "最长停车时间 单位为秒(s)")
|
||||
private Long maximumParkingTime;
|
||||
|
||||
@ConfigAttribute(id = 0x5b, type="Integer", description = "超速预警差值 单位为1/10 千米每小时(1/10km/h)")
|
||||
private Integer overSpeedWarningDifference;
|
||||
|
||||
@ConfigAttribute(id = 0x5c, type="Integer", description = "疲劳驾驶预警差值 单位为秒 值大于零")
|
||||
private Integer drowsyDrivingWarningDifference;
|
||||
|
||||
@ConfigAttribute(id = 0x5d, type="CollisionAlarmParams", description = "碰撞报警参数设置")
|
||||
private JTCollisionAlarmParams collisionAlarmParams;
|
||||
|
||||
@ConfigAttribute(id = 0x5e, type="Integer", description = "侧翻报警参数设置:侧翻角度,单位为度,默认为30")
|
||||
private Integer rolloverAlarm;
|
||||
|
||||
@ConfigAttribute(id = 0x64, type="CameraTimer", description = "定时拍照控制")
|
||||
private JTCameraTimer cameraTimer;
|
||||
|
||||
@ConfigAttribute(id = 0x70, type="Long", description = "图像/视频质量 设置范围为1~10 1表示最优质量")
|
||||
private Long qualityForVideo;
|
||||
|
||||
@ConfigAttribute(id = 0x71, type="Long", description = "亮度,设置范围为0 ~ 255")
|
||||
private Long brightness;
|
||||
|
||||
@ConfigAttribute(id = 0x72, type="Long", description = "对比度,设置范围为0 ~ 127")
|
||||
private Long contrastRatio;
|
||||
|
||||
@ConfigAttribute(id = 0x73, type="Long", description = "饱和度,设置范围为0 ~ 127")
|
||||
private Long saturation;
|
||||
|
||||
@ConfigAttribute(id = 0x74, type="Long", description = "色度,设置范围为0 ~ 255")
|
||||
private Long chroma;
|
||||
|
||||
@ConfigAttribute(id = 0x75, type="VideoParam", description = "音视频参数设置")
|
||||
private JTVideoParam videoParam;
|
||||
|
||||
@ConfigAttribute(id = 0x76, type="ChannelListParam", description = "音视频通道列表设置")
|
||||
private JTChannelListParam channelListParam;
|
||||
|
||||
@ConfigAttribute(id = 0x77, type="ChannelParam", description = "单独视频通道参数设置")
|
||||
private JTChannelParam channelParam;
|
||||
|
||||
@ConfigAttribute(id = 0x79, type="AlarmRecordingParam", description = "特殊报警录像参数设置")
|
||||
private JTAlarmRecordingParam alarmRecordingParam;
|
||||
|
||||
@ConfigAttribute(id = 0x7a, type="VideoAlarmBit", description = "视频相关报警屏蔽字")
|
||||
private JTVideoAlarmBit videoAlarmBit;
|
||||
|
||||
@ConfigAttribute(id = 0x7b, type="AnalyzeAlarmParam", description = "图像分析报警参数设置")
|
||||
private JTAnalyzeAlarmParam analyzeAlarmParam;
|
||||
|
||||
@ConfigAttribute(id = 0x7c, type="AwakenParam", description = "终端休眠唤醒模式设置")
|
||||
private JTAwakenParam awakenParam;
|
||||
|
||||
@ConfigAttribute(id = 0x80, type="Long", description = "车辆里程表读数,单位'1/10km")
|
||||
private Long mileage;
|
||||
|
||||
@ConfigAttribute(id = 0x81, type="Integer", description = "车辆所在的省域ID")
|
||||
private Integer provincialId;
|
||||
|
||||
@ConfigAttribute(id = 0x82, type="Integer", description = "车辆所在的市域ID")
|
||||
private Integer cityId;
|
||||
|
||||
@ConfigAttribute(id = 0x83, type="String", description = "公安交通管理部门颁发的机动车号牌")
|
||||
private String licensePlate;
|
||||
|
||||
@ConfigAttribute(id = 0x84, type="Short", description = "车牌颜色,值按照JT/T697-7.2014中的规定,未上牌车辆填0")
|
||||
private Short licensePlateColor;
|
||||
|
||||
@ConfigAttribute(id = 0x90, type="GnssPositioningMode", description = "GNSS定位模式")
|
||||
private JTGnssPositioningMode gnssPositioningMode;
|
||||
|
||||
@ConfigAttribute(id = 0x91, type="Short", description = "GNSS 波特率,定义如下: 0: 4800, 1:9600, 2:19200, 3:38400, 4:57600, 5:115200")
|
||||
private Short gnssBaudRate;
|
||||
|
||||
@ConfigAttribute(id = 0x92, type="Short", description = "GNSS 模块详细定位数据输出频率,定义如下: 0: 500ms, 1:1000ms(默认值), 2:2000ms, 3:3000ms, 4:4000ms")
|
||||
private Short gnssOutputFrequency;
|
||||
|
||||
@ConfigAttribute(id = 0x93, type="Long", description = "GNSS 模块详细定位数据采集频率 ,单位为秒(s) ,默认为1")
|
||||
private Long gnssCollectionFrequency;
|
||||
|
||||
@ConfigAttribute(id = 0x94, type="Short", description = "GNSS 模块详细定位数据上传方式:,定义如下: " +
|
||||
"0: 本地存储 ,不上传(默认值) , " +
|
||||
"1:按时间间隔上传, " +
|
||||
"2:按距离间隔上传, " +
|
||||
"11:按累计时间上传 ,达到传输时间后自动停止上传, " +
|
||||
"12:按累计距离上传 ,达到距离后自动停止上传, " +
|
||||
"13:按累计条数上传 ,达到上传条数后自动停止上传")
|
||||
private Short gnssDataUploadMethod;
|
||||
|
||||
@ConfigAttribute(id = 0x95, type="Long", description = "GNSS 模块详细定位数据上传设置:,定义如下: " +
|
||||
"1:单位为秒(s), " +
|
||||
"2:单位为米(m) , " +
|
||||
"11:单位为 秒(s), " +
|
||||
"12:单位为米(m), " +
|
||||
"13:单位 为条")
|
||||
private Long gnssDataUploadMethodUnit;
|
||||
|
||||
@ConfigAttribute(id = 0x100, type="Long", description = "CAN总线通道1 采集时间间隔 ,单位为毫秒(ms) ,0 表示不采集")
|
||||
private Long canCollectionTimeForChannel1;
|
||||
|
||||
@ConfigAttribute(id = 0x101, type="Integer", description = "CAN总线通道1 上传时间间隔 ,单位为秒(s) ,0 表示不上传")
|
||||
private Integer canUploadIntervalForChannel1;
|
||||
|
||||
@ConfigAttribute(id = 0x102, type="Long", description = "CAN总线通道2 采集时间间隔 ,单位为毫秒(ms) ,0 表示不采集")
|
||||
private Long canCollectionTimeForChannel2;
|
||||
|
||||
@ConfigAttribute(id = 0x103, type="Integer", description = "CAN总线通道2 上传时间间隔 ,单位为秒(s) ,0 表示不上传")
|
||||
private Integer canUploadIntervalForChannel2;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTDeviceConfig{" +
|
||||
"终端心跳发送间隔: " + keepaliveInterval + "秒" +
|
||||
", TCP消息应答超时时间:" + tcpResponseTimeout + "秒" +
|
||||
", TCP消息重传次数: " + tcpRetransmissionCount + "秒" +
|
||||
", UDP消息应答超时时间: " + udpResponseTimeout +
|
||||
", UDP消息重传次数: " + udpRetransmissionCount +
|
||||
", SMS 消息应答超时时间: " + smsResponseTimeout + "秒" +
|
||||
", SMS 消息重传次数: " + smsRetransmissionCount +
|
||||
", 主服务器APN无线通信拨号访问点: " + apnMaster + '\'' +
|
||||
", 主服务器无线通信拨号用户名: " + dialingUsernameMaster +
|
||||
", 主服务器无线通信拨号密码: " + dialingPasswordMaster +
|
||||
", 主服务器地址IP或域名: " + addressMaster +
|
||||
", 备份服务器APN: " + apnBackup +
|
||||
", 备份服务器无线通信拨号用户名: " + dialingUsernameBackup +
|
||||
", 备份服务器无线通信拨号密码: " + dialingPasswordBackup +
|
||||
", 备用服务器备份地址IP或域名: " + addressBackup +
|
||||
", 道路运输证IC卡认证主服务器IP地址或域名: " + addressIcMaster +
|
||||
", 道路运输证IC卡认证主服务器TCP端口: " + tcpPortIcMaster +
|
||||
", 道路运输证IC卡认证主服务器UDP端口: " + udpPortIcMaster +
|
||||
", 道路运输证IC卡认证备份服务器IP地址或域名: " + addressIcBackup +
|
||||
", 位置汇报策略: " + locationReportingStrategy +
|
||||
", 位置汇报方案: " + locationReportingPlan +
|
||||
", 驾驶员未登录汇报时间间隔: " + reportingIntervalOffline + "秒" +
|
||||
", 从服务器 APN: " + apnSlave +
|
||||
", 从服务器无线通信拨号密码: " + dialingUsernameSlave +
|
||||
", 从服务器备份地址 IP或域名: " + dialingPasswordSlave +
|
||||
", 从服务器备份地址 IP或域名: " + addressSlave +
|
||||
", reportingIntervalDormancy: " + reportingIntervalDormancy +
|
||||
", reportingIntervalEmergencyAlarm: " + reportingIntervalEmergencyAlarm +
|
||||
", reportingIntervalDefault: " + reportingIntervalDefault +
|
||||
", reportingDistanceDefault: " + reportingDistanceDefault +
|
||||
", reportingDistanceOffline: " + reportingDistanceOffline +
|
||||
", reportingDistanceDormancy: " + reportingDistanceDormancy +
|
||||
", reportingDistanceEmergencyAlarm: " + reportingDistanceEmergencyAlarm +
|
||||
", inflectionPointAngle: " + inflectionPointAngle +
|
||||
", fenceRadius: " + fenceRadius +
|
||||
", illegalDrivingPeriods: " + illegalDrivingPeriods +
|
||||
", platformPhoneNumber: " + platformPhoneNumber +
|
||||
", phoneNumberForReset: " + phoneNumberForReset +
|
||||
", phoneNumberForFactoryReset: " + phoneNumberForFactoryReset +
|
||||
", phoneNumberForSms: " + phoneNumberForSms +
|
||||
", phoneNumberForReceiveTextAlarm: " + phoneNumberForReceiveTextAlarm +
|
||||
", phoneAnsweringPolicy: " + phoneAnsweringPolicy +
|
||||
", longestCallTimeForPerSession: " + longestCallTimeForPerSession +
|
||||
", longestCallTimeInMonth: " + longestCallTimeInMonth +
|
||||
", phoneNumbersForListen: " + phoneNumbersForListen +
|
||||
", privilegedSMSNumber: " + privilegedSMSNumber +
|
||||
", alarmMaskingWord: " + alarmMaskingWord +
|
||||
", alarmSendsTextSmsSwitch: " + alarmSendsTextSmsSwitch +
|
||||
", alarmShootingSwitch: " + alarmShootingSwitch +
|
||||
", alarmShootingStorageFlags: " + alarmShootingStorageFlags +
|
||||
", KeySign: " + KeySign +
|
||||
", topSpeed: " + maxSpeed +
|
||||
", overSpeedDuration: " + overSpeedDuration +
|
||||
", continuousDrivingTimeThreshold: " + continuousDrivingTimeThreshold +
|
||||
", cumulativeDrivingTimeThresholdForTheDay: " + cumulativeDrivingTimeThresholdForTheDay +
|
||||
", minimumBreakTime: " + minimumBreakTime +
|
||||
", maximumParkingTime: " + maximumParkingTime +
|
||||
", overSpeedWarningDifference: " + overSpeedWarningDifference +
|
||||
", drowsyDrivingWarningDifference: " + drowsyDrivingWarningDifference +
|
||||
", collisionAlarmParams: " + collisionAlarmParams +
|
||||
", rolloverAlarm: " + rolloverAlarm +
|
||||
", cameraTimer: " + cameraTimer +
|
||||
", qualityForVideo: " + qualityForVideo +
|
||||
", brightness: " + brightness +
|
||||
", contrastRatio: " + contrastRatio +
|
||||
", saturation: " + saturation +
|
||||
", chroma: " + chroma +
|
||||
", mileage: " + mileage +
|
||||
", provincialId: " + provincialId +
|
||||
", cityId: " + cityId +
|
||||
", licensePlate: " + licensePlate +
|
||||
", licensePlateColor: " + licensePlateColor +
|
||||
", gnssPositioningMode: " + gnssPositioningMode +
|
||||
", gnssBaudRate: " + gnssBaudRate +
|
||||
", gnssOutputFrequency: " + gnssOutputFrequency +
|
||||
", gnssCollectionFrequency: " + gnssCollectionFrequency +
|
||||
", gnssDataUploadMethod: " + gnssDataUploadMethod +
|
||||
", gnssDataUploadMethodUnit: " + gnssDataUploadMethodUnit +
|
||||
", canCollectionTimeForChannel1: " + canCollectionTimeForChannel1 +
|
||||
", canUploadIntervalForChannel1: " + canUploadIntervalForChannel1 +
|
||||
", canCollectionTimeForChannel2: " + canCollectionTimeForChannel2 +
|
||||
", canUploadIntervalForChannel2: " + canUploadIntervalForChannel2 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* JT 终端控制
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "终端控制")
|
||||
public class JTDeviceConnectionControl {
|
||||
|
||||
/**
|
||||
* false 表示切换到指定监管平台服务器 ,true 表示切换回原 缺省监控平台服务器
|
||||
*/
|
||||
private Boolean switchOn;
|
||||
/**
|
||||
* 监管平台鉴权码
|
||||
*/
|
||||
private String authentication;
|
||||
|
||||
/**
|
||||
* 拨号点名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 拨号用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 拨号密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* TCP端口
|
||||
*/
|
||||
private Integer tcpPort;
|
||||
|
||||
/**
|
||||
* UDP端口
|
||||
*/
|
||||
private Integer udpPort;
|
||||
|
||||
/**
|
||||
* 连接到指定服务器时限
|
||||
*/
|
||||
private Long timeLimit;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTDeviceConnectionControl{" +
|
||||
"switchOn=" + switchOn +
|
||||
", authentication='" + authentication + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", username='" + username + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", address='" + address + '\'' +
|
||||
", tcpPort=" + tcpPort +
|
||||
", udpPort=" + udpPort +
|
||||
", timeLimit=" + timeLimit +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* JT 终端类型
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "JT终端参数设置")
|
||||
public class JTDeviceType {
|
||||
|
||||
/**
|
||||
* 适用客运车辆
|
||||
*/
|
||||
private boolean passengerVehicles;
|
||||
|
||||
/**
|
||||
* 适用危险品车辆
|
||||
*/
|
||||
private boolean dangerousGoodsVehicles;
|
||||
|
||||
/**
|
||||
* 普通货运车辆
|
||||
*/
|
||||
private boolean freightVehicles;
|
||||
|
||||
/**
|
||||
* 出租车辆
|
||||
*/
|
||||
private boolean rentalVehicles;
|
||||
|
||||
/**
|
||||
* 支持硬盘录像
|
||||
*/
|
||||
private boolean hardDiskRecording;
|
||||
|
||||
/**
|
||||
* false:一体机 ,true:分体机
|
||||
*/
|
||||
private boolean splittingMachine;
|
||||
|
||||
/**
|
||||
* 适用挂车
|
||||
*/
|
||||
private boolean trailer;
|
||||
|
||||
public static JTDeviceType getInstance(int content) {
|
||||
boolean passengerVehicles = (content & 1) == 1;
|
||||
boolean dangerousGoodsVehicles = (content >>> 1 & 1) == 1;
|
||||
boolean freightVehicles = (content >>> 2 & 1) == 1;
|
||||
boolean rentalVehicles = (content >>> 3 & 1) == 1;
|
||||
boolean hardDiskRecording = (content >>> 6 & 1) == 1;
|
||||
boolean splittingMachine = (content >>> 7 & 1) == 1;
|
||||
boolean trailer = (content >>> 8 & 1) == 1;
|
||||
return new JTDeviceType(passengerVehicles, dangerousGoodsVehicles, freightVehicles, rentalVehicles, hardDiskRecording, splittingMachine, trailer);
|
||||
}
|
||||
|
||||
public JTDeviceType(boolean passengerVehicles, boolean dangerousGoodsVehicles, boolean freightVehicles, boolean rentalVehicles, boolean hardDiskRecording, boolean splittingMachine, boolean trailer) {
|
||||
this.passengerVehicles = passengerVehicles;
|
||||
this.dangerousGoodsVehicles = dangerousGoodsVehicles;
|
||||
this.freightVehicles = freightVehicles;
|
||||
this.rentalVehicles = rentalVehicles;
|
||||
this.hardDiskRecording = hardDiskRecording;
|
||||
this.splittingMachine = splittingMachine;
|
||||
this.trailer = trailer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTDeviceType{" +
|
||||
"passengerVehicles=" + passengerVehicles +
|
||||
", dangerousGoodsVehicles=" + dangerousGoodsVehicles +
|
||||
", freightVehicles=" + freightVehicles +
|
||||
", rentalVehicles=" + rentalVehicles +
|
||||
", hardDiskRecording=" + hardDiskRecording +
|
||||
", splittingMachine=" + splittingMachine +
|
||||
", trailer=" + trailer +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
@Data
|
||||
@Slf4j
|
||||
@Schema(description = "驾驶员身份信息")
|
||||
public class JTDriverInformation {
|
||||
|
||||
@Schema(description = "0x01:从业资格证 IC卡插入( 驾驶员上班);0x02:从 业资格证 IC卡拔出(驾驶员下班)")
|
||||
private int status;
|
||||
|
||||
@Schema(description = "插卡/拔卡时间 ,以下字段在状 态为0x01 时才有效并做填充")
|
||||
private String time;
|
||||
|
||||
@Schema(description = "IC卡读取结果:" +
|
||||
"0x00:IC卡读卡成功;" +
|
||||
"0x01:读卡失败 ,原因为卡片密钥认证未通过;" +
|
||||
"0x02:读卡失败 ,原因为卡片已被锁定;" +
|
||||
"0x03:读卡失败 ,原因为卡片被拔出;" +
|
||||
"0x04:读卡失败 ,原因为数据校验错误。" +
|
||||
"以下字段在 IC卡读取结果等于0x00 时才有效")
|
||||
private Integer result;
|
||||
|
||||
@Schema(description = "驾驶员姓名")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "从业资格证编码")
|
||||
private String certificateCode;
|
||||
|
||||
@Schema(description = "发证机构名称")
|
||||
private String certificateIssuanceMechanismName;
|
||||
|
||||
@Schema(description = "证件有效期")
|
||||
private String expire;
|
||||
|
||||
@Schema(description = "驾驶员身份证号")
|
||||
private String driverIdNumber;
|
||||
|
||||
public static JTDriverInformation decode(ByteBuf buf, boolean is2019) {
|
||||
JTDriverInformation jtDriverInformation = new JTDriverInformation();
|
||||
jtDriverInformation.setStatus(buf.readUnsignedByte());
|
||||
byte[] bytes = new byte[6];
|
||||
buf.readBytes(bytes);
|
||||
String timeStr = BCDUtil.transform(bytes);
|
||||
try {
|
||||
jtDriverInformation.setTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(timeStr));
|
||||
}catch (Exception e) {
|
||||
log.error("[JT-驾驶员身份信息] 解码时无法格式化时间: {}", timeStr);
|
||||
}
|
||||
|
||||
if (jtDriverInformation.getStatus() == 1) {
|
||||
int result = (int)buf.readUnsignedByte();
|
||||
jtDriverInformation.setResult(result);
|
||||
if (result == 0) {
|
||||
// IC卡读卡成功
|
||||
int nameLength = buf.readUnsignedByte();
|
||||
jtDriverInformation.setName(buf.readCharSequence(nameLength, Charset.forName("GBK")).toString().trim());
|
||||
jtDriverInformation.setCertificateCode(buf.readCharSequence(20, Charset.forName("GBK")).toString().trim());
|
||||
int certificateIssuanceMechanismNameLength = buf.readUnsignedByte();
|
||||
jtDriverInformation.setCertificateIssuanceMechanismName(buf.readCharSequence(
|
||||
certificateIssuanceMechanismNameLength, Charset.forName("GBK")).toString().trim());
|
||||
byte[] bytesForExpire = new byte[4];
|
||||
buf.readBytes(bytesForExpire);
|
||||
String bytesForExpireStr = BCDUtil.transform(bytesForExpire);
|
||||
try {
|
||||
jtDriverInformation.setExpire(DateUtil.jt1078dateToyyyy_MM_dd(bytesForExpireStr));
|
||||
}catch (Exception e) {
|
||||
log.error("[JT-驾驶员身份信息] 解码时无法格式化时间: {}", bytesForExpireStr);
|
||||
}
|
||||
if (is2019) {
|
||||
jtDriverInformation.setDriverIdNumber(buf.readCharSequence(20, Charset.forName("GBK")).toString().trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
return jtDriverInformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTDriverInformation{" +
|
||||
"status=" + status +
|
||||
", time='" + time + '\'' +
|
||||
", result=" + result +
|
||||
", name='" + name + '\'' +
|
||||
", certificateCode='" + certificateCode + '\'' +
|
||||
", certificateIssuanceMechanismName='" + certificateIssuanceMechanismName + '\'' +
|
||||
", expire='" + expire + '\'' +
|
||||
", driverIdNumber='" + driverIdNumber + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* JT GNSS 模块属性
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "JTGNSS 模块属性")
|
||||
public class JTGnssAttribute {
|
||||
|
||||
private boolean gps;
|
||||
|
||||
private boolean beidou;
|
||||
|
||||
private boolean glonass ;
|
||||
|
||||
private boolean gaLiLeo;
|
||||
|
||||
public static JTGnssAttribute getInstance(short content) {
|
||||
boolean gps = (content & 1) == 1;
|
||||
boolean beidou = (content >>> 1 & 1) == 1;
|
||||
boolean glonass = (content >>> 2 & 1) == 1;
|
||||
boolean gaLiLeo = (content >>> 3 & 1) == 1;
|
||||
return new JTGnssAttribute(gps, beidou, glonass, gaLiLeo);
|
||||
}
|
||||
|
||||
public JTGnssAttribute(boolean gps, boolean beidou, boolean glonass, boolean gaLiLeo) {
|
||||
this.gps = gps;
|
||||
this.beidou = beidou;
|
||||
this.glonass = glonass;
|
||||
this.gaLiLeo = gaLiLeo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JGnssAttribute{" +
|
||||
"gps=" + gps +
|
||||
", beidou=" + beidou +
|
||||
", glonass=" + glonass +
|
||||
", gaLiLeo=" + gaLiLeo +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.config.JTDeviceSubConfig;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 终端上传音视频属性
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTMediaAttribute implements JTDeviceSubConfig {
|
||||
|
||||
/**
|
||||
* 输入音频编码方式:
|
||||
* 1 G. 721
|
||||
* 2 G. 722
|
||||
* 3 G. 723
|
||||
* 4 G. 728
|
||||
* 5 G. 729
|
||||
* 6 G. 711A
|
||||
* 7 G. 711U
|
||||
* 8 G. 726
|
||||
* 9 G. 729A
|
||||
* 10 DVI4_3
|
||||
* 11 DVI4_4
|
||||
* 12 DVI4_8K
|
||||
* 13 DVI4_16K
|
||||
* 14 LPC
|
||||
* 15 S16BE_STEREO
|
||||
* 16 S16BE_MONO
|
||||
* 17 MPEGAUDIO
|
||||
* 18 LPCM
|
||||
* 19 AAC
|
||||
* 20 WMA9STD
|
||||
* 21 HEAAC
|
||||
* 22 PCM_VOICE
|
||||
* 23 PCM_AUDIO
|
||||
* 24 AACLC
|
||||
* 25 MP3
|
||||
* 26 ADPCMA
|
||||
* 27 MP4AUDIO
|
||||
* 28 AMR
|
||||
*/
|
||||
private int audioEncoder;
|
||||
|
||||
/**
|
||||
* 输入音频声道数
|
||||
*/
|
||||
private int audioChannels;
|
||||
|
||||
/**
|
||||
* 输入音频采样率:
|
||||
* 0:8 kHz;
|
||||
* 1:22. 05 kHz;
|
||||
* 2:44. 1 kHz;
|
||||
* 3:48 kHz
|
||||
*/
|
||||
private int audioSamplingRate;
|
||||
|
||||
/**
|
||||
* 输入音频采样位数:
|
||||
* 0:8 位;
|
||||
* 1:16 位;
|
||||
* 2:32 位
|
||||
*/
|
||||
private int audioSamplingBits;
|
||||
|
||||
/**
|
||||
* 音频帧长度: 范围 1 ~ 4 294 967 295
|
||||
*/
|
||||
private int audioFrameLength;
|
||||
|
||||
/**
|
||||
* 是否支持音频输出:
|
||||
* 0:不支持;1:支持
|
||||
*/
|
||||
private int audioOutputEnable;
|
||||
|
||||
/**
|
||||
* 视频编码方式:
|
||||
* 98 H. 264
|
||||
* 99 H. 265
|
||||
* 100 AVS
|
||||
* 101 SVAC
|
||||
*/
|
||||
private int videoEncoder;
|
||||
|
||||
/**
|
||||
* 终端支持的最大音频物理通道数量:
|
||||
*/
|
||||
private int audioChannelMax;
|
||||
|
||||
/**
|
||||
* 终端支持的最大视频物理通道数量:
|
||||
*/
|
||||
private int videoChannelMax;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(audioEncoder);
|
||||
byteBuf.writeByte(audioChannels);
|
||||
byteBuf.writeByte(audioSamplingRate);
|
||||
byteBuf.writeByte(audioSamplingBits);
|
||||
byteBuf.writeShort(audioFrameLength);
|
||||
byteBuf.writeByte(audioOutputEnable);
|
||||
byteBuf.writeByte(videoEncoder);
|
||||
byteBuf.writeByte(audioChannelMax);
|
||||
byteBuf.writeByte(videoChannelMax);
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTMediaAttribute decode(ByteBuf byteBuf) {
|
||||
JTMediaAttribute jtMediaAttribute = new JTMediaAttribute();
|
||||
jtMediaAttribute.setAudioEncoder(byteBuf.readUnsignedByte());
|
||||
jtMediaAttribute.setAudioChannels(byteBuf.readUnsignedByte());
|
||||
jtMediaAttribute.setAudioSamplingRate(byteBuf.readUnsignedByte());
|
||||
jtMediaAttribute.setAudioSamplingBits(byteBuf.readUnsignedByte());
|
||||
jtMediaAttribute.setAudioFrameLength(byteBuf.readUnsignedShort());
|
||||
jtMediaAttribute.setAudioOutputEnable(byteBuf.readUnsignedByte());
|
||||
jtMediaAttribute.setVideoEncoder(byteBuf.readUnsignedByte());
|
||||
jtMediaAttribute.setAudioChannelMax(byteBuf.readUnsignedByte());
|
||||
jtMediaAttribute.setVideoChannelMax(byteBuf.readUnsignedByte());
|
||||
return jtMediaAttribute;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "多媒体检索项数据")
|
||||
public class JTMediaDataInfo {
|
||||
|
||||
@Schema(description = "多媒体数据 ID")
|
||||
private long id;
|
||||
|
||||
@Schema(description = "多媒体类型, 0:图像;1:音频;2:视频")
|
||||
private int type;
|
||||
|
||||
@Schema(description = "事件项编码: 0:平台下发指令;1:定时动作;2:抢劫报警触发;3:碰 撞侧翻报警触发;4:门开拍照;5:门关拍照;6:车门由开 变关 ,车速从小于20km到超过20km;7:定距拍照")
|
||||
private int eventCode;
|
||||
|
||||
@Schema(description = "通道 ID")
|
||||
private int channelId;
|
||||
|
||||
@Schema(description = "表示拍摄或录制的起始时刻的汇报消息")
|
||||
private JTPositionBaseInfo positionBaseInfo;
|
||||
|
||||
public static JTMediaDataInfo decode(ByteBuf buf) {
|
||||
JTMediaDataInfo jtMediaEventInfo = new JTMediaDataInfo();
|
||||
jtMediaEventInfo.setId(buf.readUnsignedInt());
|
||||
jtMediaEventInfo.setType(buf.readUnsignedByte());
|
||||
jtMediaEventInfo.setChannelId(buf.readUnsignedByte());
|
||||
jtMediaEventInfo.setEventCode(buf.readUnsignedByte());
|
||||
jtMediaEventInfo.setPositionBaseInfo(JTPositionBaseInfo.decode(buf));
|
||||
return jtMediaEventInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTMediaDataInfo{" +
|
||||
"id=" + id +
|
||||
", type=" + type +
|
||||
", eventCode=" + eventCode +
|
||||
", channelId=" + channelId +
|
||||
", positionBaseInfo=" + positionBaseInfo +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "多媒体事件信息")
|
||||
public class JTMediaEventInfo {
|
||||
|
||||
@Schema(description = "多媒体数据 ID")
|
||||
private long id;
|
||||
|
||||
@Schema(description = "多媒体类型, 0:图像;1:音频;2:视频")
|
||||
private int type;
|
||||
|
||||
@Schema(description = "多媒体格式编码, 0:JPEG;1:TIF;2:MP3;3:WAV;4:WMV;其他保留")
|
||||
private int code;
|
||||
|
||||
@Schema(description = "事件项编码: 0:平台下发指令;1:定时动作;2:抢劫报警触发;3:碰 撞侧翻报警触发;4:门开拍照;5:门关拍照;6:车门由开 变关 ,车速从小于20km到超过20km;7:定距拍照")
|
||||
private int eventCode;
|
||||
|
||||
@Schema(description = "通道 ID")
|
||||
private int channelId;
|
||||
|
||||
@Schema(description = "媒体数据")
|
||||
private byte[] mediaData;
|
||||
|
||||
@Schema(description = "位置信息汇报")
|
||||
private JTPositionBaseInfo positionBaseInfo;
|
||||
|
||||
|
||||
public static JTMediaEventInfo decode(ByteBuf buf) {
|
||||
JTMediaEventInfo jtMediaEventInfo = new JTMediaEventInfo();
|
||||
jtMediaEventInfo.setId(buf.readUnsignedInt());
|
||||
jtMediaEventInfo.setType(buf.readUnsignedByte());
|
||||
jtMediaEventInfo.setCode(buf.readUnsignedByte());
|
||||
jtMediaEventInfo.setEventCode(buf.readUnsignedByte());
|
||||
jtMediaEventInfo.setChannelId(buf.readUnsignedByte());
|
||||
if (buf.readableBytes() > 28) {
|
||||
ByteBuf byteBuf = buf.readSlice(28);
|
||||
jtMediaEventInfo.setPositionBaseInfo(JTPositionBaseInfo.decode(byteBuf));
|
||||
byte[] bytes = new byte[buf.readableBytes()];
|
||||
buf.readBytes(bytes);
|
||||
jtMediaEventInfo.setMediaData(bytes);
|
||||
}
|
||||
return jtMediaEventInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTMediaEventInfo{" +
|
||||
"id=" + id +
|
||||
", type=" + type +
|
||||
", code=" + code +
|
||||
", eventCode=" + eventCode +
|
||||
", channelId=" + channelId +
|
||||
", fileSize=" + (mediaData == null ? 0 : mediaData.length) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
public enum JTMediaStreamType {
|
||||
PLAY,PLAYBACK,TALK
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.config.JTDeviceSubConfig;
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 终端上传乘客流量
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTPassengerNum implements JTDeviceSubConfig {
|
||||
|
||||
/**
|
||||
* 起始时间, YY-MM-DD-HH-MM-SS( GMT + 8 时间,本标准中之后涉及的时间均采用此时区)
|
||||
*/
|
||||
private String startTime;
|
||||
|
||||
/**
|
||||
* 结束时间, YY-MM-DD-HH-MM-SS( GMT + 8 时间,本标准中之后涉及的时间均采用此时区)
|
||||
*/
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 上车人数
|
||||
*/
|
||||
private int getIn;
|
||||
|
||||
/**
|
||||
* 下车人数
|
||||
*/
|
||||
private int getOut;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static JTPassengerNum decode(ByteBuf buf) {
|
||||
JTPassengerNum jtPassengerNum = new JTPassengerNum();
|
||||
byte[] bytes = new byte[6];
|
||||
buf.readBytes(bytes);
|
||||
jtPassengerNum.setStartTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(bytes)));
|
||||
buf.readBytes(bytes);
|
||||
jtPassengerNum.setEndTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(bytes)));
|
||||
jtPassengerNum.setGetIn(buf.readUnsignedShort());
|
||||
jtPassengerNum.setGetOut(buf.readUnsignedShort());
|
||||
return jtPassengerNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "终端上传乘客流量:" +
|
||||
" 时间: " + startTime + " 到 " + endTime +
|
||||
", 上车:" + getIn +
|
||||
", 下车:" + getOut
|
||||
;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "电话本联系人")
|
||||
public class JTPhoneBookContact {
|
||||
|
||||
@Schema(description = "1:呼入,2:呼出,3:呼入/呼出")
|
||||
private int sign;
|
||||
|
||||
@Schema(description = "电话号码")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "联系人")
|
||||
private String contactName;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
buffer.writeByte(sign);
|
||||
buffer.writeByte(phoneNumber.getBytes(Charset.forName("GBK")).length);
|
||||
buffer.writeCharSequence(phoneNumber, Charset.forName("GBK"));
|
||||
buffer.writeByte(contactName.getBytes(Charset.forName("GBK")).length);
|
||||
buffer.writeCharSequence(contactName, Charset.forName("GBK"));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTPhoneBookContact{" +
|
||||
"sign=" + sign +
|
||||
", phoneNumber='" + phoneNumber + '\'' +
|
||||
", contactName='" + contactName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "多边形区域")
|
||||
public class JTPolygonArea implements JTAreaOrRoute{
|
||||
|
||||
@Schema(description = "区域 ID")
|
||||
private long id;
|
||||
|
||||
@Schema(description = "")
|
||||
private JTAreaAttribute attribute;
|
||||
|
||||
@Schema(description = "起始时间, yyyy-MM-dd HH:mm:ss")
|
||||
private String startTime;
|
||||
|
||||
@Schema(description = "结束时间, yyyy-MM-dd HH:mm:ss")
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "最高速度, 单位为千米每小时(km/h)")
|
||||
private int maxSpeed;
|
||||
|
||||
@Schema(description = "超速持续时间, 单位为秒(s)")
|
||||
private int overSpeedDuration;
|
||||
|
||||
@Schema(description = "区域顶点")
|
||||
private List<JTPolygonPoint> polygonPoints;
|
||||
|
||||
@Schema(description = "夜间最高速度, 单位为千米每小时(km/h)")
|
||||
private int nighttimeMaxSpeed;
|
||||
|
||||
@Schema(description = "区域的名称")
|
||||
private String name;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeInt((int) (id & 0xffffffffL));
|
||||
byteBuf.writeBytes(attribute.encode());
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(startTime)));
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(endTime)));
|
||||
byteBuf.writeShort((short)(maxSpeed & 0xffff));
|
||||
byteBuf.writeByte(overSpeedDuration);
|
||||
|
||||
byteBuf.writeShort((short)(polygonPoints.size() & 0xffff));
|
||||
if (!polygonPoints.isEmpty()) {
|
||||
for (JTPolygonPoint polygonPoint : polygonPoints) {
|
||||
byteBuf.writeBytes(polygonPoint.encode());
|
||||
}
|
||||
}
|
||||
byteBuf.writeShort((short)(nighttimeMaxSpeed & 0xffff));
|
||||
byteBuf.writeShort((short)(name.getBytes(Charset.forName("GBK")).length & 0xffff));
|
||||
byteBuf.writeCharSequence(name, Charset.forName("GBK"));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTPolygonArea decode(ByteBuf buf) {
|
||||
JTPolygonArea area = new JTPolygonArea();
|
||||
area.setId(buf.readUnsignedInt());
|
||||
int attributeInt = buf.readUnsignedShort();
|
||||
JTAreaAttribute areaAttribute = JTAreaAttribute.decode(attributeInt);
|
||||
area.setAttribute(areaAttribute);
|
||||
byte[] startTimeBytes = new byte[6];
|
||||
buf.readBytes(startTimeBytes);
|
||||
area.setStartTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(startTimeBytes)));
|
||||
byte[] endTimeBytes = new byte[6];
|
||||
buf.readBytes(endTimeBytes);
|
||||
area.setEndTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(endTimeBytes)));
|
||||
area.setMaxSpeed(buf.readUnsignedShort());
|
||||
area.setOverSpeedDuration(buf.readUnsignedByte());
|
||||
int polygonPointsSize = buf.readUnsignedShort();
|
||||
List<JTPolygonPoint> polygonPointList = new ArrayList<>(polygonPointsSize);
|
||||
for (int i = 0; i < polygonPointsSize; i++) {
|
||||
JTPolygonPoint polygonPoint = new JTPolygonPoint();
|
||||
polygonPoint.setLatitude(buf.readUnsignedInt()/1000000D);
|
||||
polygonPoint.setLongitude(buf.readUnsignedInt()/1000000D);
|
||||
polygonPointList.add(polygonPoint);
|
||||
}
|
||||
area.setPolygonPoints(polygonPointList);
|
||||
area.setNighttimeMaxSpeed(buf.readUnsignedShort());
|
||||
int nameLength = buf.readUnsignedShort();
|
||||
area.setName(buf.readCharSequence(nameLength, Charset.forName("GBK")).toString().trim());
|
||||
return area;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "多边形区域的顶点")
|
||||
public class JTPolygonPoint {
|
||||
|
||||
@Schema(description = "顶点纬度")
|
||||
private Double latitude;
|
||||
|
||||
@Schema(description = "顶点经度")
|
||||
private Double longitude;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeInt((int) (Math.round((latitude * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (Math.round((longitude * 1000000)) & 0xffffffffL));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Schema(description = "位置附加信息")
|
||||
public class JTPositionAdditionalInfo {
|
||||
|
||||
@Schema(description = "里程, 单位为1/10km, 对应车上里程表读数")
|
||||
private int mileage;
|
||||
|
||||
@Schema(description = "油量, 单位为1/10L, 对应车上油量表读数")
|
||||
private int oil;
|
||||
|
||||
@Schema(description = "行驶记录功能获取的速度,单位为1/10km/h")
|
||||
private int speed;
|
||||
|
||||
@Schema(description = "报警事件的 ID")
|
||||
private int alarmId;
|
||||
// TODO 暂不支持胎压
|
||||
|
||||
@Schema(description = "车厢温度 ,单位为摄氏度")
|
||||
private int carriageTemperature;
|
||||
// TODO 暂不支持胎压
|
||||
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Slf4j
|
||||
@Schema(description = "位置基本信息")
|
||||
public class JTPositionBaseInfo {
|
||||
|
||||
/**
|
||||
* 报警标志
|
||||
*/
|
||||
@Schema(description = "报警标志")
|
||||
private JTAlarmSign alarmSign;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@Schema(description = "状态")
|
||||
private JTStatus status;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
@Schema(description = "经度")
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
@Schema(description = "纬度")
|
||||
private Double latitude;
|
||||
|
||||
/**
|
||||
* 高程
|
||||
*/
|
||||
@Schema(description = "高程")
|
||||
private Integer altitude;
|
||||
|
||||
/**
|
||||
* 速度
|
||||
*/
|
||||
@Schema(description = "速度")
|
||||
private Integer speed;
|
||||
|
||||
/**
|
||||
* 方向
|
||||
*/
|
||||
@Schema(description = "方向")
|
||||
private Integer direction;
|
||||
|
||||
/**
|
||||
* 时间
|
||||
*/
|
||||
@Schema(description = "时间")
|
||||
private String time;
|
||||
|
||||
/**
|
||||
* 视频报警
|
||||
*/
|
||||
@Schema(description = "视频报警")
|
||||
private JTVideoAlarm videoAlarm;
|
||||
|
||||
public static JTPositionBaseInfo decode(ByteBuf buf) {
|
||||
JTPositionBaseInfo positionInfo = new JTPositionBaseInfo();
|
||||
if (buf.readableBytes() < 17) {
|
||||
log.error("[位置基本信息] 解码失败,长度不足: {}", buf.readableBytes());
|
||||
return positionInfo;
|
||||
}
|
||||
positionInfo.setAlarmSign(new JTAlarmSign(buf.readUnsignedInt()));
|
||||
|
||||
positionInfo.setStatus(new JTStatus(buf.readUnsignedInt()));
|
||||
|
||||
positionInfo.setLatitude(buf.readInt() * 0.000001D);
|
||||
positionInfo.setLongitude(buf.readInt() * 0.000001D);
|
||||
positionInfo.setAltitude(buf.readUnsignedShort());
|
||||
positionInfo.setSpeed(buf.readUnsignedShort());
|
||||
positionInfo.setDirection(buf.readUnsignedShort());
|
||||
byte[] timeBytes = new byte[6];
|
||||
buf.readBytes(timeBytes);
|
||||
positionInfo.setTime(BCDUtil.transform(timeBytes));
|
||||
return positionInfo;
|
||||
}
|
||||
|
||||
|
||||
public String toSimpleString() {
|
||||
return "简略位置汇报信息: " +
|
||||
" \n 经度:" + longitude +
|
||||
" \n 纬度:" + latitude +
|
||||
" \n 高程: " + altitude +
|
||||
" \n 速度: " + speed +
|
||||
" \n 方向: " + direction +
|
||||
" \n 时间: " + time +
|
||||
" \n";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "位置汇报信息: " +
|
||||
" \n 报警标志:" + alarmSign.toString() +
|
||||
" \n 状态:" + status.toString() +
|
||||
" \n 经度:" + longitude +
|
||||
" \n 纬度:" + latitude +
|
||||
" \n 高程: " + altitude +
|
||||
" \n 速度: " + speed +
|
||||
" \n 方向: " + direction +
|
||||
" \n 时间: " + time +
|
||||
" \n";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Schema(description = "位置信息")
|
||||
public class JTPositionInfo {
|
||||
|
||||
/**
|
||||
* 位置基本信息
|
||||
*/
|
||||
@Schema(description = "位置基本信息")
|
||||
private JTPositionBaseInfo base;
|
||||
|
||||
/**
|
||||
* 位置基本信息
|
||||
*/
|
||||
@Schema(description = "位置附加信息")
|
||||
private JTPositionAdditionalInfo additional;
|
||||
|
||||
public void setBase(JTPositionBaseInfo base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public void setAdditional(JTPositionAdditionalInfo additional) {
|
||||
this.additional = additional;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "存储多媒体数据")
|
||||
public class JTQueryMediaDataCommand {
|
||||
|
||||
@Schema(description = "多媒体类型: 0:图像;1:音频;2:视频")
|
||||
private int type;
|
||||
|
||||
@Schema(description = "通道 ID, 0 表示检索该媒体类型的所有通道")
|
||||
private int chanelId;
|
||||
|
||||
@Schema(description = "事件项编码: 0:平台下发指令;1:定时动作;2:抢劫报警触发;3:碰 撞侧翻报警触发;其他保留")
|
||||
private int event;
|
||||
|
||||
@Schema(description = "开始时间")
|
||||
private String startTime;
|
||||
|
||||
@Schema(description = "结束时间")
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "删除标志, 0:保留;1:删除, 存储多媒体数据上传命令中使用")
|
||||
private Integer delete;
|
||||
|
||||
|
||||
public ByteBuf decode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(type);
|
||||
byteBuf.writeByte(chanelId);
|
||||
byteBuf.writeByte(event);
|
||||
if (startTime == null) {
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd("000000000000"));
|
||||
}else {
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(startTime)));
|
||||
}
|
||||
if (endTime == null) {
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd("000000000000"));
|
||||
}else {
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(endTime)));
|
||||
}
|
||||
if (delete != null) {
|
||||
byteBuf.writeByte(delete);
|
||||
}
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTQueryMediaDataCommand{" +
|
||||
"type=" + type +
|
||||
", chanelId=" + chanelId +
|
||||
", event=" + event +
|
||||
", startTime='" + startTime + '\'' +
|
||||
", endTime='" + endTime + '\'' +
|
||||
", delete='" + delete + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.proc.response.J9206;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class JTRecordDownloadCatch implements Delayed {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String phoneNumber;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String path;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private J9206 j9206;
|
||||
|
||||
/**
|
||||
* 超时时间(单位: 毫秒)
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private long delayTime;
|
||||
|
||||
@Override
|
||||
public long getDelay(@NotNull TimeUnit unit) {
|
||||
return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull Delayed o) {
|
||||
return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "矩形区域")
|
||||
public class JTRectangleArea implements JTAreaOrRoute{
|
||||
|
||||
@Schema(description = "区域 ID")
|
||||
private long id;
|
||||
|
||||
@Schema(description = "")
|
||||
private JTAreaAttribute attribute;
|
||||
|
||||
@Schema(description = "左上点纬度")
|
||||
private Double latitudeForUpperLeft;
|
||||
|
||||
@Schema(description = "左上点经度")
|
||||
private Double longitudeForUpperLeft;
|
||||
|
||||
@Schema(description = "右下点纬度")
|
||||
private Double latitudeForLowerRight;
|
||||
|
||||
@Schema(description = "右下点经度")
|
||||
private Double longitudeForLowerRight;
|
||||
|
||||
@Schema(description = "起始时间, yyyy-MM-dd HH:mm:ss")
|
||||
private String startTime;
|
||||
|
||||
@Schema(description = "结束时间, yyyy-MM-dd HH:mm:ss")
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "最高速度, 单位为千米每小时(km/h)")
|
||||
private int maxSpeed;
|
||||
|
||||
@Schema(description = "超速持续时间, 单位为秒(s)")
|
||||
private int overSpeedDuration;
|
||||
|
||||
@Schema(description = "夜间最高速度, 单位为千米每小时(km/h)")
|
||||
private int nighttimeMaxSpeed;
|
||||
|
||||
@Schema(description = "区域的名称")
|
||||
private String name;
|
||||
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeInt((int) (id & 0xffffffffL));
|
||||
byteBuf.writeBytes(attribute.encode());
|
||||
byteBuf.writeInt((int) (Math.round((latitudeForUpperLeft * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (Math.round((longitudeForUpperLeft * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (Math.round((latitudeForLowerRight * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (Math.round((longitudeForLowerRight * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(startTime)));
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(endTime)));
|
||||
byteBuf.writeShort((short)(maxSpeed & 0xffff));
|
||||
byteBuf.writeByte(overSpeedDuration);
|
||||
byteBuf.writeShort((short)(nighttimeMaxSpeed & 0xffff));
|
||||
byteBuf.writeShort((short)(name.getBytes(Charset.forName("GBK")).length & 0xffff));
|
||||
byteBuf.writeCharSequence(name, Charset.forName("GBK"));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTRectangleArea decode(ByteBuf buf) {
|
||||
JTRectangleArea area = new JTRectangleArea();
|
||||
area.setId(buf.readUnsignedInt());
|
||||
int attributeInt = buf.readUnsignedShort();
|
||||
JTAreaAttribute areaAttribute = JTAreaAttribute.decode(attributeInt);
|
||||
area.setAttribute(areaAttribute);
|
||||
area.setLatitudeForUpperLeft(buf.readUnsignedInt()/1000000D);
|
||||
area.setLongitudeForUpperLeft(buf.readUnsignedInt()/1000000D);
|
||||
area.setLatitudeForLowerRight(buf.readUnsignedInt()/1000000D);
|
||||
area.setLongitudeForLowerRight(buf.readUnsignedInt()/1000000D);
|
||||
byte[] startTimeBytes = new byte[6];
|
||||
buf.readBytes(startTimeBytes);
|
||||
area.setStartTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(startTimeBytes)));
|
||||
byte[] endTimeBytes = new byte[6];
|
||||
buf.readBytes(endTimeBytes);
|
||||
area.setEndTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(endTimeBytes)));
|
||||
area.setMaxSpeed(buf.readUnsignedShort());
|
||||
area.setOverSpeedDuration(buf.readUnsignedByte());
|
||||
area.setNighttimeMaxSpeed(buf.readUnsignedShort());
|
||||
int nameLength = buf.readUnsignedShort();
|
||||
area.setName(buf.readCharSequence(nameLength, Charset.forName("GBK")).toString().trim());
|
||||
return area;
|
||||
}
|
||||
|
||||
}
|
||||
90
src/main/java/com/genersoft/iot/vmp/jt1078/bean/JTRoute.java
Normal file
90
src/main/java/com/genersoft/iot/vmp/jt1078/bean/JTRoute.java
Normal file
@ -0,0 +1,90 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "路线")
|
||||
public class JTRoute implements JTAreaOrRoute{
|
||||
|
||||
@Schema(description = "路线 ID")
|
||||
private long id;
|
||||
|
||||
@Schema(description = "路线属性")
|
||||
private JTRouteAttribute attribute;
|
||||
|
||||
@Schema(description = "起始时间, yyyy-MM-dd HH:mm:ss")
|
||||
private String startTime;
|
||||
|
||||
@Schema(description = "结束时间, yyyy-MM-dd HH:mm:ss")
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "路线拐点")
|
||||
private List<JTRoutePoint> routePointList;
|
||||
|
||||
@Schema(description = "区域的名称")
|
||||
private String name;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeInt((int) (id & 0xffffffffL));
|
||||
byteBuf.writeBytes(attribute.encode());
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(startTime)));
|
||||
byteBuf.writeBytes(BCDUtil.strToBcd(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(endTime)));
|
||||
byteBuf.writeShort((short)(routePointList.size() & 0xffff));
|
||||
if (!routePointList.isEmpty()){
|
||||
for (JTRoutePoint jtRoutePoint : routePointList) {
|
||||
byteBuf.writeBytes(jtRoutePoint.encode());
|
||||
}
|
||||
}
|
||||
byteBuf.writeShort((short)(name.getBytes(Charset.forName("GBK")).length & 0xffff));
|
||||
byteBuf.writeCharSequence(name, Charset.forName("GBK"));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTRoute decode(ByteBuf buf) {
|
||||
JTRoute route = new JTRoute();
|
||||
route.setId(buf.readUnsignedInt());
|
||||
int attributeInt = buf.readUnsignedShort();
|
||||
JTRouteAttribute routeAttribute = JTRouteAttribute.decode(attributeInt);
|
||||
route.setAttribute(routeAttribute);
|
||||
byte[] startTimeBytes = new byte[6];
|
||||
buf.readBytes(startTimeBytes);
|
||||
route.setStartTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(startTimeBytes)));
|
||||
byte[] endTimeBytes = new byte[6];
|
||||
buf.readBytes(endTimeBytes);
|
||||
route.setEndTime(DateUtil.jt1078Toyyyy_MM_dd_HH_mm_ss(BCDUtil.transform(endTimeBytes)));
|
||||
|
||||
int routePointsSize = buf.readUnsignedShort();
|
||||
List<JTRoutePoint> jtRoutePoints = new ArrayList<>(routePointsSize);
|
||||
for (int i = 0; i < routePointsSize; i++) {
|
||||
jtRoutePoints.add(JTRoutePoint.decode(buf));
|
||||
}
|
||||
route.setRoutePointList(jtRoutePoints);
|
||||
int nameLength = buf.readUnsignedShort();
|
||||
route.setName(buf.readCharSequence(nameLength, Charset.forName("GBK")).toString().trim());
|
||||
return route;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTRoute{" +
|
||||
"id=" + id +
|
||||
", attribute=" + attribute +
|
||||
", startTime='" + startTime + '\'' +
|
||||
", endTime='" + endTime + '\'' +
|
||||
", routePointList=" + routePointList +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "路线属性")
|
||||
public class JTRouteAttribute {
|
||||
|
||||
@Schema(description = "是否启用起始时间与结束时间的判断规则 ,false:否;true:是")
|
||||
private boolean ruleForTimeLimit;
|
||||
|
||||
@Schema(description = "进区域是否报警给驾驶员,false:否;true:是")
|
||||
private boolean ruleForAlarmToDriverWhenEnter;
|
||||
|
||||
@Schema(description = "进区域是否报警给平台 ,false:否;true:是")
|
||||
private boolean ruleForAlarmToPlatformWhenEnter;
|
||||
|
||||
@Schema(description = "出区域是否报警给驾驶员,false:否;true:是")
|
||||
private boolean ruleForAlarmToDriverWhenExit;
|
||||
|
||||
@Schema(description = "出区域是否报警给平台 ,false:否;true:是")
|
||||
private boolean ruleForAlarmToPlatformWhenExit;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
short content = 0;
|
||||
if (ruleForTimeLimit) {
|
||||
content |= 1;
|
||||
}
|
||||
if (ruleForAlarmToDriverWhenEnter) {
|
||||
content |= (1 << 2);
|
||||
}
|
||||
if (ruleForAlarmToPlatformWhenEnter) {
|
||||
content |= (1 << 3);
|
||||
}
|
||||
if (ruleForAlarmToDriverWhenExit) {
|
||||
content |= (1 << 4);
|
||||
}
|
||||
if (ruleForAlarmToPlatformWhenExit) {
|
||||
content |= (1 << 5);
|
||||
}
|
||||
byteBuf.writeShort((short)(content & 0xffff));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTRouteAttribute decode(int attributeInt) {
|
||||
JTRouteAttribute attribute = new JTRouteAttribute();
|
||||
attribute.setRuleForTimeLimit((attributeInt & 1) == 1);
|
||||
attribute.setRuleForAlarmToDriverWhenEnter((attributeInt >> 2 & 1) == 1);
|
||||
attribute.setRuleForAlarmToPlatformWhenEnter((attributeInt >> 3 & 1) == 1);
|
||||
attribute.setRuleForAlarmToDriverWhenExit((attributeInt >> 4 & 1) == 1);
|
||||
attribute.setRuleForAlarmToPlatformWhenExit((attributeInt >> 5 & 1) == 1);
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTRouteAttribute{" +
|
||||
"ruleForTimeLimit=" + ruleForTimeLimit +
|
||||
", ruleForAlarmToDriverWhenEnter=" + ruleForAlarmToDriverWhenEnter +
|
||||
", ruleForAlarmToPlatformWhenEnter=" + ruleForAlarmToPlatformWhenEnter +
|
||||
", ruleForAlarmToDriverWhenExit=" + ruleForAlarmToDriverWhenExit +
|
||||
", ruleForAlarmToPlatformWhenExit=" + ruleForAlarmToPlatformWhenExit +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "路线拐点")
|
||||
public class JTRoutePoint {
|
||||
|
||||
@Schema(description = "拐点 ID")
|
||||
private long id;
|
||||
|
||||
@Schema(description = "路段 ID")
|
||||
private long routeSectionId;
|
||||
|
||||
@Schema(description = "拐点纬度")
|
||||
private Double latitude;
|
||||
|
||||
@Schema(description = "拐点经度")
|
||||
private Double longitude;
|
||||
|
||||
@Schema(description = "路段宽度")
|
||||
private int routeSectionAttributeWidth;
|
||||
|
||||
@Schema(description = "路段属性")
|
||||
private JTRouteSectionAttribute routeSectionAttribute;
|
||||
|
||||
@Schema(description = "路段行驶过长國值")
|
||||
private int routeSectionMaxLength;
|
||||
|
||||
@Schema(description = "路段行驶不足國值")
|
||||
private int routeSectionMinLength;
|
||||
|
||||
@Schema(description = "路段最高速度")
|
||||
private int routeSectionMaxSpeed;
|
||||
|
||||
@Schema(description = "路段超速持续时间")
|
||||
private int routeSectionOverSpeedDuration;
|
||||
|
||||
@Schema(description = "路段夜间最高速度")
|
||||
private int routeSectionNighttimeMaxSpeed;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeInt((int) (id & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (routeSectionId & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (Math.round((latitude * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeInt((int) (Math.round((longitude * 1000000)) & 0xffffffffL));
|
||||
byteBuf.writeByte(routeSectionAttributeWidth);
|
||||
byteBuf.writeByte(routeSectionAttribute.encode());
|
||||
byteBuf.writeShort((short)(routeSectionMaxLength & 0xffff));
|
||||
byteBuf.writeShort((short)(routeSectionMinLength & 0xffff));
|
||||
byteBuf.writeShort((short)(routeSectionMaxSpeed & 0xffff));
|
||||
byteBuf.writeByte(routeSectionOverSpeedDuration);
|
||||
byteBuf.writeShort((short)(routeSectionNighttimeMaxSpeed & 0xffff));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTRoutePoint decode(ByteBuf buf) {
|
||||
JTRoutePoint point = new JTRoutePoint();
|
||||
point.setId(buf.readUnsignedInt());
|
||||
point.setRouteSectionId(buf.readUnsignedInt());
|
||||
point.setLatitude(buf.readUnsignedInt()/1000000D);
|
||||
point.setLongitude(buf.readUnsignedInt()/1000000D);
|
||||
point.setRouteSectionAttributeWidth(buf.readUnsignedByte());
|
||||
|
||||
JTRouteSectionAttribute areaAttribute = JTRouteSectionAttribute.decode(buf.readUnsignedByte());
|
||||
point.setRouteSectionAttribute(areaAttribute);
|
||||
|
||||
point.setRouteSectionMaxLength(buf.readUnsignedShort());
|
||||
point.setRouteSectionMinLength(buf.readUnsignedShort());
|
||||
point.setRouteSectionMaxSpeed(buf.readUnsignedShort());
|
||||
point.setRouteSectionOverSpeedDuration(buf.readUnsignedByte());
|
||||
point.setRouteSectionNighttimeMaxSpeed(buf.readUnsignedShort());
|
||||
return point;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTRoutePoint{" +
|
||||
"id=" + id +
|
||||
", routeSectionId=" + routeSectionId +
|
||||
", latitude=" + latitude +
|
||||
", longitude=" + longitude +
|
||||
", routeSectionAttributeWidth=" + routeSectionAttributeWidth +
|
||||
", routeSectionAttribute=" + routeSectionAttribute +
|
||||
", routeSectionMaxLength=" + routeSectionMaxLength +
|
||||
", routeSectionMinLength=" + routeSectionMinLength +
|
||||
", routeSectionMaxSpeed=" + routeSectionMaxSpeed +
|
||||
", routeSectionOverSpeedDuration=" + routeSectionOverSpeedDuration +
|
||||
", routeSectionNighttimeMaxSpeed=" + routeSectionNighttimeMaxSpeed +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "路段属性")
|
||||
public class JTRouteSectionAttribute {
|
||||
|
||||
@Schema(description = "行驶时间 ,false:否;true:是")
|
||||
private boolean ruleForTimeLimit;
|
||||
|
||||
@Schema(description = "限速 ,false:否;true:是")
|
||||
private boolean ruleForSpeedLimit;
|
||||
|
||||
@Schema(description = "false:北纬;true:南纬")
|
||||
private boolean southLatitude;
|
||||
|
||||
@Schema(description = "false:东经;true:西经")
|
||||
private boolean westLongitude;
|
||||
|
||||
public byte encode(){
|
||||
byte attributeByte = 0;
|
||||
if (ruleForTimeLimit) {
|
||||
attributeByte |= 1;
|
||||
}
|
||||
if (ruleForSpeedLimit) {
|
||||
attributeByte |= (1 << 1);
|
||||
}
|
||||
if (southLatitude) {
|
||||
attributeByte |= (1 << 2);
|
||||
}
|
||||
if (westLongitude) {
|
||||
attributeByte |= (1 << 3);
|
||||
}
|
||||
return attributeByte;
|
||||
}
|
||||
|
||||
public static JTRouteSectionAttribute decode(short attributeShort) {
|
||||
JTRouteSectionAttribute attribute = new JTRouteSectionAttribute();
|
||||
attribute.setRuleForTimeLimit((attributeShort & 1) == 1);
|
||||
attribute.setRuleForSpeedLimit((attributeShort >> 1 & 1) == 1);
|
||||
attribute.setSouthLatitude((attributeShort >> 2 & 1) == 1);
|
||||
attribute.setWestLongitude((attributeShort >> 3 & 1) == 1);
|
||||
return attribute;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Schema(description = "拍摄命令参数")
|
||||
public class JTShootingCommand {
|
||||
|
||||
@Schema(description = "通道 ID")
|
||||
private int chanelId;
|
||||
|
||||
@Schema(description = "0:停止拍摄;0xFFFF:录像;其他:拍照张数")
|
||||
private int command;
|
||||
|
||||
@Schema(description = "拍照间隔/录像时间, 单位为秒(s) ,0 表示按最小间隔拍照或一直录像")
|
||||
private int time;
|
||||
|
||||
@Schema(description = "1:保存; 0:实时上传")
|
||||
private int save;
|
||||
|
||||
@Schema(description = "分辨率: " +
|
||||
"0x00:最低分辨率" +
|
||||
"0x01:320 x240;" +
|
||||
"0x02:640 x480;" +
|
||||
"0x03:800 x600;" +
|
||||
"0x04:1024 x768;" +
|
||||
"0x05:176 x144;" +
|
||||
"0x06:352 x288;" +
|
||||
"0x07:704 x288;" +
|
||||
"0x08:704 x576;" +
|
||||
"0xff:最高分辨率")
|
||||
private int resolvingPower;
|
||||
|
||||
@Schema(description = "图像/视频质量: 取值范围为 1 ~ 10 ,1 代表质量损失最小 ,10 表示压缩 比最大")
|
||||
private int quality;
|
||||
|
||||
@Schema(description = "亮度, 0 ~ 255")
|
||||
private int brightness;
|
||||
|
||||
@Schema(description = "对比度,0 ~ 127")
|
||||
private int contrastRatio;
|
||||
|
||||
@Schema(description = "饱和度,0 ~ 127")
|
||||
private int saturation;
|
||||
|
||||
@Schema(description = "色度,0 ~ 255")
|
||||
private int chroma;
|
||||
|
||||
public ByteBuf decode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(chanelId);
|
||||
byteBuf.writeShort((short)(command & 0xffff));
|
||||
byteBuf.writeShort((short)(time & 0xffff));
|
||||
byteBuf.writeByte(save);
|
||||
byteBuf.writeByte(resolvingPower);
|
||||
byteBuf.writeByte(quality);
|
||||
byteBuf.writeByte(brightness);
|
||||
byteBuf.writeByte(contrastRatio);
|
||||
byteBuf.writeByte(saturation);
|
||||
byteBuf.writeByte(chroma);
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JTShootingCommand{" +
|
||||
"chanelId=" + chanelId +
|
||||
", command=" + command +
|
||||
", time=" + time +
|
||||
", save=" + save +
|
||||
", resolvingPower=" + resolvingPower +
|
||||
", quality=" + quality +
|
||||
", brightness=" + brightness +
|
||||
", contrastRatio=" + contrastRatio +
|
||||
", saturation=" + saturation +
|
||||
", chroma=" + chroma +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
136
src/main/java/com/genersoft/iot/vmp/jt1078/bean/JTStatus.java
Normal file
136
src/main/java/com/genersoft/iot/vmp/jt1078/bean/JTStatus.java
Normal file
@ -0,0 +1,136 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "状态信息")
|
||||
public class JTStatus {
|
||||
|
||||
@Schema(description = "false:ACC关;true: ACC开")
|
||||
private boolean acc;
|
||||
|
||||
@Schema(description = "false:未定位;true: 定位")
|
||||
private boolean positioning;
|
||||
|
||||
@Schema(description = "false:北纬;true: 南纬")
|
||||
private boolean southLatitude;
|
||||
|
||||
@Schema(description = "false:东经;true: 西经")
|
||||
private boolean wesLongitude;
|
||||
|
||||
@Schema(description = "false:运营状态;true: 停运状态")
|
||||
private boolean outage;
|
||||
|
||||
@Schema(description = "false:经纬度未经保密插件加密;true: 经纬度已经保密插件加密")
|
||||
private boolean positionEncryption;
|
||||
|
||||
|
||||
@Schema(description = "true: 紧急刹车系统采集的前撞预警")
|
||||
private boolean warningFrontCrash;
|
||||
|
||||
@Schema(description = "true: 车道偏移预警")
|
||||
private boolean warningShifting;
|
||||
|
||||
@Schema(description = "00:空车;01:半载;10:保留;11:满载。可表示客车的空载状态 ,重车及货车的空载、满载状态 ,该状态可由人工输入或传感器获取")
|
||||
private int load;
|
||||
|
||||
@Schema(description = "false:车辆油路正常;true: 车辆油路断开")
|
||||
private boolean oilWayBreak;
|
||||
|
||||
@Schema(description = "false:车辆电路正常;true: 车辆电路断开")
|
||||
private boolean circuitBreak;
|
||||
|
||||
@Schema(description = "false:车门解锁;true: 车门加锁")
|
||||
private boolean doorLocking;
|
||||
|
||||
@Schema(description = "false:门1 关;true: 门1 开(前门)")
|
||||
private boolean door1Open;
|
||||
|
||||
@Schema(description = "false:门2 关;true: 门2 开(中门)")
|
||||
private boolean door2Open;
|
||||
|
||||
@Schema(description = "false:门3 关;true: 门3 开(后门)")
|
||||
private boolean door3Open;
|
||||
|
||||
@Schema(description = "false:门4 关;true: 门4 开(驾驶席门)")
|
||||
private boolean door4Open;
|
||||
|
||||
@Schema(description = "false:门5 关;true: 门5 开(自定义)")
|
||||
private boolean door5Open;
|
||||
|
||||
@Schema(description = "false:未使用 GPS 卫星进行定位;true:使用 GPS 卫星进行定位")
|
||||
private boolean gps;
|
||||
|
||||
@Schema(description = "false:未使用北斗卫星进行定位;true:使用北斗卫星进行定位")
|
||||
private boolean beidou;
|
||||
|
||||
@Schema(description = "false:未使用GLONASS 卫星进行定位;true:使用GLONASS 卫星进行定位")
|
||||
private boolean glonass;
|
||||
|
||||
@Schema(description = "false:未使用GaLiLeo 卫星进行定位;true:使用GaLiLeo 卫星进行定位")
|
||||
private boolean gaLiLeo;
|
||||
|
||||
@Schema(description = "false:车辆处于停止状态;true:车辆处于行驶状态")
|
||||
private boolean driving;
|
||||
|
||||
public JTStatus() {
|
||||
}
|
||||
|
||||
public JTStatus(long statusInt) {
|
||||
if (statusInt == 0) {
|
||||
return;
|
||||
}
|
||||
this.acc = (statusInt & 1) == 1;
|
||||
this.positioning = (statusInt >>> 1 & 1) == 1;
|
||||
this.southLatitude = (statusInt >>> 2 & 1) == 1;
|
||||
this.wesLongitude = (statusInt >>> 3 & 1) == 1;
|
||||
this.outage = (statusInt >>> 4 & 1) == 1;
|
||||
this.positionEncryption = (statusInt >>> 5 & 1) == 1;
|
||||
this.warningFrontCrash = (statusInt >>> 6 & 1) == 1;
|
||||
this.warningShifting = (statusInt >>> 7 & 1) == 1;
|
||||
this.load = (int)(statusInt >>> 8 & 3);
|
||||
this.oilWayBreak = (statusInt >>> 10 & 1) == 1;
|
||||
this.circuitBreak = (statusInt >>> 11 & 1) == 1;
|
||||
this.doorLocking = (statusInt >>> 12 & 1) == 1;
|
||||
this.door1Open = (statusInt >>> 13 & 1) == 1;
|
||||
this.door2Open = (statusInt >>> 14 & 1) == 1;
|
||||
this.door3Open = (statusInt >>> 15 & 1) == 1;
|
||||
this.door4Open = (statusInt >>> 16 & 1) == 1;
|
||||
this.door5Open = (statusInt >>> 17 & 1) == 1;
|
||||
this.gps = (statusInt >>> 18 & 1) == 1;
|
||||
this.beidou = (statusInt >>> 19 & 1) == 1;
|
||||
this.glonass = (statusInt >>> 20 & 1) == 1;
|
||||
this.gaLiLeo = (statusInt >>> 21 & 1) == 1;
|
||||
this.driving = (statusInt >>> 22 & 1) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "状态位:" +
|
||||
"\n acc状态:" + (acc?"开":"关") +
|
||||
"\n 定位状态:" + (positioning?"定位":"未定位") +
|
||||
"\n 南北纬:" + (southLatitude?"南纬":"北纬") +
|
||||
"\n 东西经:" + (wesLongitude?"西经":"东经") +
|
||||
"\n 运营状态:" + (outage?"停运":"运营") +
|
||||
"\n 经纬度保密:" + (positionEncryption?"加密":"未加密") +
|
||||
"\n 前撞预警:" + (warningFrontCrash?"紧急刹车系统采集的前撞预警":"无") +
|
||||
"\n 车道偏移预警:" + (warningShifting?"车道偏移预警":"无") +
|
||||
"\n 空/半/满载状态:" + (load == 0?"空车":(load == 1?"半载":(load == 3?"满载":"未定义状态"))) +
|
||||
"\n 车辆油路状态:" + (oilWayBreak?"车辆油路断开":"车辆油路正常") +
|
||||
"\n 车辆电路状态:" + (circuitBreak?"车辆电路断开":"车辆电路正常") +
|
||||
"\n 门锁状态:" + (doorLocking?"车门加锁":"车门解锁") +
|
||||
"\n 门1(前门)状态:" + (door1Open?"开":"关") +
|
||||
"\n 门2(中门)状态:" + (door2Open?"开":"关") +
|
||||
"\n 门3(后门)状态:" + (door3Open?"开":"关") +
|
||||
"\n 门4(驾驶席门)状态:" + (door4Open?"开":"关") +
|
||||
"\n 门5(自定义)状态:" + (door5Open?"开":"关") +
|
||||
"\n GPS卫星定位状态: " + (gps?"使用":"未使用") +
|
||||
"\n 北斗卫星定位状态: " + (beidou?"使用":"未使用") +
|
||||
"\n GLONASS卫星定位状态: " + (glonass?"使用":"未使用") +
|
||||
"\n GaLiLeo卫星定位状态: " + (gaLiLeo?"使用":"未使用") +
|
||||
"\n GaLiLeo卫星定位状态: " + (gaLiLeo?"使用":"未使用") +
|
||||
"\n 车辆行驶状态: " + (driving?"车辆行驶":"车辆停止") +
|
||||
"\n ";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 文本信息标志
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "文本信息标志")
|
||||
public class JTTextSign {
|
||||
|
||||
@Schema(description = "1紧急,2服务,3通知")
|
||||
private int type;
|
||||
|
||||
@Schema(description = "1终端显示器显示")
|
||||
private boolean terminalDisplay;
|
||||
|
||||
@Schema(description = "1广告屏显示")
|
||||
private boolean adScreen;
|
||||
|
||||
@Schema(description = "1终端 TTS 播读")
|
||||
private boolean tts;
|
||||
|
||||
@Schema(description = "false: 中心导航信息 true CAN故障码信息")
|
||||
private boolean source;
|
||||
|
||||
public byte encode(){
|
||||
byte byteSign = 0;
|
||||
byteSign |= (byte) type;
|
||||
if (terminalDisplay) {
|
||||
byteSign |= (0x1 << 2);
|
||||
}
|
||||
if (tts) {
|
||||
byteSign |= (0x1 << 3);
|
||||
}
|
||||
if (adScreen) {
|
||||
byteSign |= (0x1 << 4);
|
||||
}
|
||||
if (source) {
|
||||
byteSign |= (0x1 << 5);
|
||||
}
|
||||
return byteSign;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.common.ConfigAttribute;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 车辆控制类型
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTVehicleControl {
|
||||
|
||||
private int length;
|
||||
|
||||
private void setLength(Object value) {
|
||||
if (Objects.isNull(value)) {
|
||||
length--;
|
||||
}else {
|
||||
length ++;
|
||||
}
|
||||
}
|
||||
|
||||
@ConfigAttribute(id = 0X0001, type="Byte", description = "车门, 0:车门锁闭 1:车门开启")
|
||||
private Integer controlCarDoor;
|
||||
|
||||
public void setControlCarDoor(Integer controlCarDoor) {
|
||||
this.controlCarDoor = controlCarDoor;
|
||||
setLength(controlCarDoor);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "视频报警上报")
|
||||
public class JTVideoAlarm {
|
||||
|
||||
@Schema(description = "视频信号丢失报警的通道")
|
||||
private List<Integer> videoLossChannels;
|
||||
|
||||
@Schema(description = "视频信号遮挡报警的通道")
|
||||
private List<Integer> videoOcclusionChannels;
|
||||
|
||||
@Schema(description = "存储器故障报警状态,第 1-12 个主存储器,12-15 分别表示第 1-4 个灾备存储装置")
|
||||
private List<Integer> storageFaultAlarm;
|
||||
|
||||
@Schema(description = "异常驾驶行为-疲劳")
|
||||
private boolean drivingForFatigue;
|
||||
|
||||
@Schema(description = "异常驾驶行为-打电话")
|
||||
private boolean drivingForCall;
|
||||
|
||||
@Schema(description = "异常驾驶行为-抽烟")
|
||||
private boolean drivingSmoking;
|
||||
|
||||
@Schema(description = "其他视频设备故障")
|
||||
private boolean otherDeviceFailure;
|
||||
|
||||
@Schema(description = "客车超员报警")
|
||||
private boolean overcrowding;
|
||||
|
||||
@Schema(description = "特殊报警录像达到存储阈值报警")
|
||||
private boolean specialRecordFull;
|
||||
|
||||
public JTVideoAlarm() {
|
||||
}
|
||||
|
||||
public static JTVideoAlarm getInstance(int alarm, int loss, int occlusion, short storageFault, short driving) {
|
||||
JTVideoAlarm jtVideoAlarm = new JTVideoAlarm();
|
||||
if (alarm == 0) {
|
||||
return jtVideoAlarm;
|
||||
}
|
||||
boolean lossAlarm = (alarm & 1) == 1;
|
||||
boolean occlusionAlarm = (alarm >>> 1 & 1) == 1;
|
||||
boolean storageFaultAlarm = (alarm >>> 2 & 1) == 1;
|
||||
jtVideoAlarm.setOtherDeviceFailure((alarm >>> 3 & 1) == 1);
|
||||
jtVideoAlarm.setOvercrowding((alarm >>> 4 & 1) == 1);
|
||||
boolean drivingAlarm = (alarm >>> 5 & 1) == 1;
|
||||
jtVideoAlarm.setSpecialRecordFull((alarm >>> 6 & 1) == 1);
|
||||
if (lossAlarm && loss > 0) {
|
||||
List<Integer> videoLossChannels = new ArrayList<>();
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if ((loss >>> i & 1) == 1 ) {
|
||||
videoLossChannels.add(i);
|
||||
}
|
||||
}
|
||||
jtVideoAlarm.setVideoLossChannels(videoLossChannels);
|
||||
}
|
||||
if (occlusionAlarm && occlusion > 0) {
|
||||
List<Integer> videoOcclusionChannels = new ArrayList<>();
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if ((occlusion >>> i & 1) == 1) {
|
||||
videoOcclusionChannels.add(i);
|
||||
}
|
||||
}
|
||||
jtVideoAlarm.setVideoOcclusionChannels(videoOcclusionChannels);
|
||||
}
|
||||
if (storageFaultAlarm && storageFault > 0) {
|
||||
List<Integer> storageFaultAlarmContent = new ArrayList<>();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((storageFault >>> i & 1) == 1) {
|
||||
storageFaultAlarmContent.add(i);
|
||||
}
|
||||
}
|
||||
jtVideoAlarm.setStorageFaultAlarm(storageFaultAlarmContent);
|
||||
}
|
||||
if (drivingAlarm && driving > 0) {
|
||||
jtVideoAlarm.setDrivingForFatigue((driving & 1) == 1 );
|
||||
jtVideoAlarm.setDrivingForCall((driving >>> 1 & 1) == 1 );
|
||||
jtVideoAlarm.setDrivingSmoking((driving >>> 2 & 1) == 1 );
|
||||
}
|
||||
return jtVideoAlarm;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.common;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ConfigAttribute {
|
||||
|
||||
long id();
|
||||
|
||||
String type();
|
||||
|
||||
String description();
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 特殊报警录像参数
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTAlarmRecordingParam implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* 特殊报警录像存储阈值, 百分比,取值 特殊报警录像占用主存储器存储阈值百 1 ~ 99,默认值为 20
|
||||
*/
|
||||
private int storageLimit;
|
||||
|
||||
/**
|
||||
* 特殊报警录像持续时间,特殊报警录像的最长持续时间,单位为分钟(min) ,默认值为 5
|
||||
*/
|
||||
private int duration;
|
||||
|
||||
/**
|
||||
* 特殊报警标识起始时间, 特殊报警发生前进行标记的录像时间, 单位为分钟( min) ,默认值为 1
|
||||
*/
|
||||
private int startTime;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(storageLimit);
|
||||
byteBuf.writeByte(duration);
|
||||
byteBuf.writeByte(startTime);
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTAlarmRecordingParam decode(ByteBuf byteBuf) {
|
||||
JTAlarmRecordingParam alarmRecordingParam = new JTAlarmRecordingParam();
|
||||
alarmRecordingParam.setStorageLimit(byteBuf.readUnsignedByte());
|
||||
alarmRecordingParam.setDuration(byteBuf.readUnsignedByte());
|
||||
alarmRecordingParam.setStartTime(byteBuf.readUnsignedByte());
|
||||
return alarmRecordingParam;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 单独通道视频
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTAloneChanel implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* 逻辑通道号
|
||||
*/
|
||||
private int logicChannelId;
|
||||
|
||||
/**
|
||||
* 实时流编码模式
|
||||
* 0:CBR( 固定码率) ;
|
||||
* 1:VBR( 可变码率) ;
|
||||
* 2:ABR( 平均码率) ;
|
||||
* 100 ~ 127:自定义
|
||||
*/
|
||||
private int liveStreamCodeRateType;
|
||||
|
||||
/**
|
||||
* 实时流分辨率
|
||||
* 0:QCIF;
|
||||
* 1:CIF;
|
||||
* 2:WCIF;
|
||||
* 3:D1;
|
||||
* 4:WD1;
|
||||
* 5:720P;
|
||||
* 6:1 080P;
|
||||
* 100 ~ 127:自定义
|
||||
*/
|
||||
private int liveStreamResolving;
|
||||
|
||||
/**
|
||||
* 实时流关键帧间隔, 范围(1 ~ 1 000) 帧
|
||||
*/
|
||||
private int liveStreamIInterval;
|
||||
|
||||
/**
|
||||
* 实时流目标帧率,范围(1 ~ 120) 帧 / s
|
||||
*/
|
||||
private int liveStreamFrameRate;
|
||||
|
||||
/**
|
||||
* 实时流目标码率,单位为千位每秒( kbps)
|
||||
*/
|
||||
private long liveStreamCodeRate;
|
||||
|
||||
|
||||
/**
|
||||
* 存储流编码模式
|
||||
* 0:CBR( 固定码率) ;
|
||||
* 1:VBR( 可变码率) ;
|
||||
* 2:ABR( 平均码率) ;
|
||||
* 100 ~ 127:自定义
|
||||
*/
|
||||
private int storageStreamCodeRateType;
|
||||
|
||||
/**
|
||||
* 存储流分辨率
|
||||
* 0:QCIF;
|
||||
* 1:CIF;
|
||||
* 2:WCIF;
|
||||
* 3:D1;
|
||||
* 4:WD1;
|
||||
* 5:720P;
|
||||
* 6:1 080P;
|
||||
* 100 ~ 127:自定义
|
||||
*/
|
||||
private int storageStreamResolving;
|
||||
|
||||
/**
|
||||
* 存储流关键帧间隔, 范围(1 ~ 1 000) 帧
|
||||
*/
|
||||
private int storageStreamIInterval;
|
||||
|
||||
/**
|
||||
* 存储流目标帧率,范围(1 ~ 120) 帧 / s
|
||||
*/
|
||||
private int storageStreamFrameRate;
|
||||
|
||||
/**
|
||||
* 存储流目标码率,单位为千位每秒( kbps)
|
||||
*/
|
||||
private long storageStreamCodeRate;
|
||||
|
||||
/**
|
||||
* 字幕叠加设置
|
||||
*/
|
||||
private JTOSDConfig osd;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(logicChannelId);
|
||||
byteBuf.writeByte(liveStreamCodeRateType);
|
||||
byteBuf.writeByte(liveStreamResolving);
|
||||
byteBuf.writeShort((short)(liveStreamIInterval & 0xffff));
|
||||
byteBuf.writeByte(liveStreamFrameRate);
|
||||
byteBuf.writeInt((int) (liveStreamCodeRate & 0xffffffffL));
|
||||
|
||||
byteBuf.writeByte(storageStreamCodeRateType);
|
||||
byteBuf.writeByte(storageStreamResolving);
|
||||
byteBuf.writeShort((short)(storageStreamIInterval & 0xffff));
|
||||
byteBuf.writeByte(storageStreamFrameRate);
|
||||
byteBuf.writeInt((int) (storageStreamCodeRate & 0xffffffffL));
|
||||
byteBuf.writeBytes(osd.encode());
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTAloneChanel decode(ByteBuf buf) {
|
||||
JTAloneChanel jtAloneChanel = new JTAloneChanel();
|
||||
jtAloneChanel.setLogicChannelId(buf.readByte());
|
||||
jtAloneChanel.setLiveStreamCodeRateType(buf.readByte());
|
||||
jtAloneChanel.setLiveStreamResolving(buf.readByte());
|
||||
jtAloneChanel.setLiveStreamIInterval(buf.readUnsignedShort());
|
||||
jtAloneChanel.setLiveStreamFrameRate(buf.readByte());
|
||||
jtAloneChanel.setLiveStreamCodeRate(buf.readUnsignedInt());
|
||||
|
||||
jtAloneChanel.setStorageStreamCodeRateType(buf.readByte());
|
||||
jtAloneChanel.setStorageStreamResolving(buf.readByte());
|
||||
jtAloneChanel.setStorageStreamIInterval(buf.readUnsignedShort());
|
||||
jtAloneChanel.setStorageStreamFrameRate(buf.readByte());
|
||||
jtAloneChanel.setStorageStreamCodeRate(buf.readUnsignedInt());
|
||||
jtAloneChanel.setOsd(JTOSDConfig.decode(buf));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 视频分析报警参数
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTAnalyzeAlarmParam implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* 车辆核载人数
|
||||
*/
|
||||
private int numberForPeople;
|
||||
|
||||
|
||||
/**
|
||||
* 疲劳程度阈值
|
||||
*/
|
||||
private int fatigueThreshold;
|
||||
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(numberForPeople);
|
||||
byteBuf.writeByte(fatigueThreshold);
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTAnalyzeAlarmParam decode(ByteBuf byteBuf) {
|
||||
JTAnalyzeAlarmParam analyzeAlarmParam = new JTAnalyzeAlarmParam();
|
||||
analyzeAlarmParam.setNumberForPeople(byteBuf.readUnsignedByte());
|
||||
analyzeAlarmParam.setFatigueThreshold(byteBuf.readUnsignedByte());
|
||||
return analyzeAlarmParam;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,270 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.BCDUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 终端休眠唤醒模式设置
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTAwakenParam implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* 休眠唤醒模式-条件唤醒
|
||||
*/
|
||||
private boolean wakeUpModeByCondition;
|
||||
|
||||
/**
|
||||
* 休眠唤醒模式-定时唤醒
|
||||
*/
|
||||
private boolean wakeUpModeByTime;
|
||||
|
||||
/**
|
||||
* 休眠唤醒模式-手动唤醒
|
||||
*/
|
||||
private boolean wakeUpModeByManual;
|
||||
|
||||
/**
|
||||
* 唤醒条件类型-紧急报警
|
||||
*/
|
||||
private boolean wakeUpConditionsByAlarm;
|
||||
|
||||
/**
|
||||
* 唤醒条件类型-碰撞侧翻报警
|
||||
*/
|
||||
private boolean wakeUpConditionsByRollover;
|
||||
|
||||
/**
|
||||
* 唤醒条件类型-车辆开门
|
||||
*/
|
||||
private boolean wakeUpConditionsByOpenTheDoor;
|
||||
|
||||
/**
|
||||
* 定时唤醒日设置-周一
|
||||
*/
|
||||
private boolean awakeningDayForMonday;
|
||||
|
||||
/**
|
||||
* 定时唤醒日设置-周二
|
||||
*/
|
||||
private boolean awakeningDayForTuesday;
|
||||
|
||||
/**
|
||||
* 定时唤醒日设置-周三
|
||||
*/
|
||||
private boolean awakeningDayForWednesday;
|
||||
|
||||
/**
|
||||
* 定时唤醒日设置-周四
|
||||
*/
|
||||
private boolean awakeningDayForThursday;
|
||||
|
||||
/**
|
||||
* 定时唤醒日设置-周五
|
||||
*/
|
||||
private boolean awakeningDayForFriday;
|
||||
|
||||
/**
|
||||
* 定时唤醒日设置-周六
|
||||
*/
|
||||
private boolean awakeningDayForSaturday;
|
||||
|
||||
/**
|
||||
* 定时唤醒日设置-周日
|
||||
*/
|
||||
private boolean awakeningDayForSunday;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-启用时间段1
|
||||
*/
|
||||
private boolean time1Enable;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-时间段1开始时间
|
||||
*/
|
||||
private String time1StartTime;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-时间段1结束时间
|
||||
*/
|
||||
private String time1EndTime;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-启用时间段2
|
||||
*/
|
||||
private boolean time2Enable;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-时间段2开始时间
|
||||
*/
|
||||
private String time2StartTime;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-时间段2结束时间
|
||||
*/
|
||||
private String time2EndTime;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-启用时间段3
|
||||
*/
|
||||
private boolean time3Enable;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-时间段3开始时间
|
||||
*/
|
||||
private String time3StartTime;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-时间段3结束时间
|
||||
*/
|
||||
private String time3EndTime;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-启用时间段4
|
||||
*/
|
||||
private boolean time4Enable;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-时间段4开始时间
|
||||
*/
|
||||
private String time4StartTime;
|
||||
|
||||
/**
|
||||
* 日定时唤醒-时间段4结束时间
|
||||
*/
|
||||
private String time4EndTime;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byte wakeUpTypeByte = 0;
|
||||
byte wakeUpConditionsByte = 0;
|
||||
byte wakeDayByte = 0;
|
||||
if (wakeUpModeByCondition) {
|
||||
wakeUpTypeByte = (byte)(wakeUpTypeByte | 1);
|
||||
}
|
||||
if (wakeUpModeByTime) {
|
||||
wakeUpTypeByte = (byte)(wakeUpTypeByte | (1 << 1));
|
||||
}
|
||||
if (wakeUpModeByManual) {
|
||||
wakeUpTypeByte = (byte)(wakeUpTypeByte | (1 << 2));
|
||||
}
|
||||
byteBuf.writeByte(wakeUpTypeByte);
|
||||
if (wakeUpConditionsByAlarm) {
|
||||
wakeUpConditionsByte = (byte)(wakeUpConditionsByte | 1);
|
||||
}
|
||||
if (wakeUpConditionsByRollover) {
|
||||
wakeUpConditionsByte = (byte)(wakeUpConditionsByte | (1 << 1));
|
||||
}
|
||||
if (wakeUpConditionsByOpenTheDoor) {
|
||||
wakeUpConditionsByte = (byte)(wakeUpConditionsByte | (1 << 2));
|
||||
}
|
||||
byteBuf.writeByte(wakeUpConditionsByte);
|
||||
if (awakeningDayForMonday) {
|
||||
wakeDayByte = (byte)(wakeDayByte | 1);
|
||||
}
|
||||
if (awakeningDayForTuesday) {
|
||||
wakeDayByte = (byte)(wakeDayByte | (1 << 1));
|
||||
}
|
||||
if (awakeningDayForWednesday) {
|
||||
wakeDayByte = (byte)(wakeDayByte | (1 << 2));
|
||||
}
|
||||
if (awakeningDayForThursday) {
|
||||
wakeDayByte = (byte)(wakeDayByte | (1 << 3));
|
||||
}
|
||||
if (awakeningDayForFriday) {
|
||||
wakeDayByte = (byte)(wakeDayByte | (1 << 4));
|
||||
}
|
||||
if (awakeningDayForSaturday) {
|
||||
wakeDayByte = (byte)(wakeDayByte | (1 << 5));
|
||||
}
|
||||
if (awakeningDayForSunday) {
|
||||
wakeDayByte = (byte)(wakeDayByte | (1 << 6));
|
||||
}
|
||||
byteBuf.writeByte(wakeDayByte);
|
||||
byte enableByte = 0;
|
||||
if (time1Enable) {
|
||||
enableByte = (byte)(enableByte | 1);
|
||||
}
|
||||
if (time2Enable) {
|
||||
enableByte = (byte)(enableByte | (1 << 1));
|
||||
}
|
||||
if (time3Enable) {
|
||||
enableByte = (byte)(enableByte | (1 << 2));
|
||||
}
|
||||
if (time4Enable) {
|
||||
enableByte = (byte)(enableByte | (1 << 3));
|
||||
}
|
||||
byteBuf.writeByte(enableByte);
|
||||
byteBuf.writeBytes(transportTime(time1StartTime));
|
||||
byteBuf.writeBytes(transportTime(time1EndTime));
|
||||
byteBuf.writeBytes(transportTime(time2StartTime));
|
||||
byteBuf.writeBytes(transportTime(time2EndTime));
|
||||
byteBuf.writeBytes(transportTime(time3StartTime));
|
||||
byteBuf.writeBytes(transportTime(time3EndTime));
|
||||
byteBuf.writeBytes(transportTime(time4StartTime));
|
||||
byteBuf.writeBytes(transportTime(time4EndTime));
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
private byte[] transportTime(String time) {
|
||||
return BCDUtil.strToBcd(time.replace(":", ""));
|
||||
}
|
||||
|
||||
public static JTAwakenParam decode(ByteBuf byteBuf) {
|
||||
JTAwakenParam awakenParam = new JTAwakenParam();
|
||||
short wakeUpTypeByte = byteBuf.readUnsignedByte();
|
||||
awakenParam.wakeUpModeByCondition = ((wakeUpTypeByte & 1) == 1);
|
||||
awakenParam.wakeUpModeByTime = ((wakeUpTypeByte >>> 1 & 1) == 1);
|
||||
awakenParam.wakeUpModeByManual = ((wakeUpTypeByte >>> 2 & 1) == 1);
|
||||
|
||||
short wakeUpConditionsByte = byteBuf.readUnsignedByte();
|
||||
awakenParam.wakeUpConditionsByAlarm = ((wakeUpConditionsByte & 1) == 1);
|
||||
awakenParam.wakeUpConditionsByRollover = ((wakeUpConditionsByte >>> 1 & 1) == 1);
|
||||
awakenParam.wakeUpConditionsByOpenTheDoor = ((wakeUpConditionsByte >>> 2 & 1) == 1);
|
||||
|
||||
short wakeDayByte = byteBuf.readUnsignedByte();
|
||||
awakenParam.awakeningDayForMonday = ((wakeDayByte & 1) == 1);
|
||||
awakenParam.awakeningDayForTuesday = ((wakeDayByte >>> 1 & 1) == 1);
|
||||
awakenParam.awakeningDayForWednesday = ((wakeDayByte >>> 2 & 1) == 1);
|
||||
awakenParam.awakeningDayForThursday = ((wakeDayByte >>> 3 & 1) == 1);
|
||||
awakenParam.awakeningDayForFriday = ((wakeDayByte >>> 4 & 1) == 1);
|
||||
awakenParam.awakeningDayForSaturday = ((wakeDayByte >>> 5 & 1) == 1);
|
||||
awakenParam.awakeningDayForSunday = ((wakeDayByte >>> 6 & 1) == 1);
|
||||
short enableByte = byteBuf.readUnsignedByte();
|
||||
awakenParam.time1Enable = ((enableByte & 1) == 1);
|
||||
awakenParam.time2Enable = ((enableByte >>> 1 & 1) == 1);
|
||||
awakenParam.time3Enable = ((enableByte >>> 2 & 1) == 1);
|
||||
awakenParam.time4Enable = ((enableByte >>> 3 & 1) == 1);
|
||||
byte[] timeBytes = new byte[2];
|
||||
byteBuf.readBytes(timeBytes);
|
||||
awakenParam.time1StartTime = transportTime(timeBytes);
|
||||
byteBuf.readBytes(timeBytes);
|
||||
awakenParam.time1EndTime = transportTime(timeBytes);
|
||||
|
||||
byteBuf.readBytes(timeBytes);
|
||||
awakenParam.time2StartTime = transportTime(timeBytes);
|
||||
byteBuf.readBytes(timeBytes);
|
||||
awakenParam.time2EndTime = transportTime(timeBytes);
|
||||
|
||||
byteBuf.readBytes(timeBytes);
|
||||
awakenParam.time3StartTime = transportTime(timeBytes);
|
||||
byteBuf.readBytes(timeBytes);
|
||||
awakenParam.time3EndTime = transportTime(timeBytes);
|
||||
|
||||
byteBuf.readBytes(timeBytes);
|
||||
awakenParam.time4StartTime = transportTime(timeBytes);
|
||||
byteBuf.readBytes(timeBytes);
|
||||
awakenParam.time4EndTime = transportTime(timeBytes);
|
||||
return awakenParam;
|
||||
}
|
||||
|
||||
private static String transportTime(byte[] timeBytes) {
|
||||
String time1Str = BCDUtil.transform(timeBytes);
|
||||
return time1Str.replace(time1Str.substring(0, 2), time1Str.substring(0, 2) + ":");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 定时拍照控制
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTCameraTimer implements JTDeviceSubConfig{
|
||||
/**
|
||||
* 摄像通道1 定时拍照开关标志
|
||||
*/
|
||||
private boolean switchForChannel1;
|
||||
/**
|
||||
* 摄像通道2 定时拍照开关标志
|
||||
*/
|
||||
private boolean switchForChannel2;
|
||||
/**
|
||||
* 摄像通道3 定时拍照开关标志
|
||||
*/
|
||||
private boolean switchForChannel3;
|
||||
/**
|
||||
* 摄像通道4 定时拍照开关标志
|
||||
*/
|
||||
private boolean switchForChannel4;
|
||||
/**
|
||||
* 摄像通道5 定时拍照开关标志
|
||||
*/
|
||||
private boolean switchForChannel5;
|
||||
|
||||
/**
|
||||
* 摄像通道1 定时拍照存储标志, true: 上传, false: 存储
|
||||
*/
|
||||
private boolean storageFlagsForChannel1;
|
||||
|
||||
/**
|
||||
* 摄像通道2 定时拍照存储标志 true: 上传, false: 存储
|
||||
*/
|
||||
private boolean storageFlagsForChannel2;
|
||||
|
||||
/**
|
||||
* 摄像通道3 定时拍照存储标志 true: 上传, false: 存储
|
||||
*/
|
||||
private boolean storageFlagsForChannel3;
|
||||
|
||||
/**
|
||||
* 摄像通道4 定时拍照存储标志 true: 上传, false: 存储
|
||||
*/
|
||||
private boolean storageFlagsForChannel4;
|
||||
|
||||
/**
|
||||
* 摄像通道5 定时拍照存储标志 true: 上传, false: 存储
|
||||
*/
|
||||
private boolean storageFlagsForChannel5;
|
||||
|
||||
/**
|
||||
* 定时时间单位,true: 分, false: 秒,当数值小于5s时,终端按5s处理
|
||||
*/
|
||||
private boolean timeUnit;
|
||||
|
||||
/**
|
||||
* 定时时间间隔
|
||||
*/
|
||||
private Integer timeInterval;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byte[] bytes = new byte[4];
|
||||
bytes[0] = 0;
|
||||
if (switchForChannel1) {
|
||||
bytes[0] = (byte)(bytes[0] | 1);
|
||||
}
|
||||
if (switchForChannel2) {
|
||||
bytes[0] = (byte)(bytes[0] | 2);
|
||||
}
|
||||
if (switchForChannel3) {
|
||||
bytes[0] = (byte)(bytes[0] | 4);
|
||||
}
|
||||
if (switchForChannel4) {
|
||||
bytes[0] = (byte)(bytes[0] | 8);
|
||||
}
|
||||
if (switchForChannel5) {
|
||||
bytes[0] = (byte)(bytes[0] | 16);
|
||||
}
|
||||
bytes[1] = 0;
|
||||
if (storageFlagsForChannel1) {
|
||||
bytes[1] = (byte)(bytes[1] | 1);
|
||||
}
|
||||
if (storageFlagsForChannel2) {
|
||||
bytes[1] = (byte)(bytes[1] | 2);
|
||||
}
|
||||
if (storageFlagsForChannel3) {
|
||||
bytes[1] = (byte)(bytes[1] | 4);
|
||||
}
|
||||
if (storageFlagsForChannel4) {
|
||||
bytes[1] = (byte)(bytes[1] | 8);
|
||||
}
|
||||
if (storageFlagsForChannel5) {
|
||||
bytes[1] = (byte)(bytes[1] | 16);
|
||||
}
|
||||
bytes[3] = (byte)(timeInterval & 0xfe);
|
||||
if (timeUnit) {
|
||||
bytes[3] = (byte)(bytes[3] | 1);
|
||||
}
|
||||
byteBuf.writeBytes(bytes);
|
||||
return byteBuf;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 音视频通道
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTChanelConfig implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* 物理通道号 单独
|
||||
*/
|
||||
private int physicalChannelId;
|
||||
|
||||
/**
|
||||
* 逻辑通道号
|
||||
*/
|
||||
private int logicChannelId;
|
||||
|
||||
/**
|
||||
* 通道类型:
|
||||
* 0:音视频;
|
||||
* 1:音频
|
||||
* 2:视频
|
||||
*/
|
||||
private int channelType;
|
||||
/**
|
||||
* 是否连接云台: 通道类型为 0 和 2 时,此字段有效
|
||||
* 0:未连接;1:连接
|
||||
*/
|
||||
private int ptzEnable;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(physicalChannelId);
|
||||
byteBuf.writeByte(logicChannelId);
|
||||
byteBuf.writeByte(channelType);
|
||||
byteBuf.writeByte(ptzEnable);
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTChanelConfig decode(ByteBuf byteBuf) {
|
||||
JTChanelConfig jtChanel = new JTChanelConfig();
|
||||
jtChanel.setPhysicalChannelId(byteBuf.readUnsignedByte());
|
||||
jtChanel.setLogicChannelId(byteBuf.readUnsignedByte());
|
||||
jtChanel.setChannelType(byteBuf.readUnsignedByte());
|
||||
jtChanel.setPtzEnable(byteBuf.readUnsignedByte());
|
||||
return jtChanel;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 音视频通道列表设置
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTChannelListParam implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* 音视频通道总数
|
||||
*/
|
||||
private int videoAndAudioCount;
|
||||
|
||||
/**
|
||||
* 音频通道总数
|
||||
*/
|
||||
private int audioCount;
|
||||
|
||||
/**
|
||||
* 视频通道总数
|
||||
*/
|
||||
private int videoCount;
|
||||
|
||||
private List<JTChanelConfig> chanelList;
|
||||
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(videoAndAudioCount);
|
||||
byteBuf.writeByte(audioCount);
|
||||
byteBuf.writeByte(videoCount);
|
||||
for (JTChanelConfig jtChanel : chanelList) {
|
||||
byteBuf.writeBytes(jtChanel.encode());
|
||||
}
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTChannelListParam decode(ByteBuf byteBuf) {
|
||||
JTChannelListParam channelListParam = new JTChannelListParam();
|
||||
channelListParam.setVideoAndAudioCount(byteBuf.readUnsignedByte());
|
||||
channelListParam.setAudioCount(byteBuf.readUnsignedByte());
|
||||
channelListParam.setVideoCount(byteBuf.readUnsignedByte());
|
||||
int total = channelListParam.getVideoAndAudioCount() + channelListParam.getVideoCount() + channelListParam.getAudioCount();
|
||||
List<JTChanelConfig> chanelList = new ArrayList<>(total);
|
||||
for (int i = 0; i < total; i++) {
|
||||
chanelList.add(JTChanelConfig.decode(byteBuf));
|
||||
}
|
||||
channelListParam.setChanelList(chanelList);
|
||||
return channelListParam;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单独视频通道参数设置
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTChannelParam implements JTDeviceSubConfig {
|
||||
|
||||
/**
|
||||
* 单独通道视频参数设置列表
|
||||
*/
|
||||
private List<JTAloneChanel> jtAloneChanelList;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(jtAloneChanelList.size());
|
||||
for (JTAloneChanel jtAloneChanel : jtAloneChanelList) {
|
||||
if (jtAloneChanel == null) {
|
||||
continue;
|
||||
}
|
||||
byteBuf.writeBytes(jtAloneChanel.encode());
|
||||
}
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTChannelParam decode(ByteBuf byteBuf) {
|
||||
JTChannelParam channelParam = new JTChannelParam();
|
||||
int length = byteBuf.readUnsignedByte();
|
||||
List<JTAloneChanel> jtAloneChanelList = new ArrayList<>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
jtAloneChanelList.add(JTAloneChanel.decode(byteBuf));
|
||||
}
|
||||
channelParam.setJtAloneChanelList(jtAloneChanelList);
|
||||
return channelParam;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 碰撞报警参数设置
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTCollisionAlarmParams implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* 碰撞时间 单位为毫秒(ms)
|
||||
*/
|
||||
private int collisionAlarmTime;
|
||||
|
||||
/**
|
||||
* 碰撞加速度 单位为0.1g,设置范围为0~79,默认为10
|
||||
*/
|
||||
private int collisionAcceleration;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byte[] bytes = new byte[2];
|
||||
bytes[0] = (byte) (collisionAlarmTime & 0xff);
|
||||
bytes[1] = (byte) (collisionAcceleration & 0xff);
|
||||
byteBuf.writeBytes(bytes);
|
||||
return byteBuf;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public interface JTDeviceSubConfig {
|
||||
ByteBuf encode();
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* GNSS 定位模式
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTGnssPositioningMode implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* GPS 定位 true: 开启, false: 关闭
|
||||
*/
|
||||
private boolean gps;
|
||||
/**
|
||||
* 北斗定位 true: 开启, false: 关闭
|
||||
*/
|
||||
private boolean beidou;
|
||||
/**
|
||||
* GLONASS定位 true: 开启, false: 关闭
|
||||
*/
|
||||
private boolean glonass;
|
||||
/**
|
||||
* GaLiLeo定位 true: 开启, false: 关闭
|
||||
*/
|
||||
private boolean gaLiLeo;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byte[] bytes = new byte[1];
|
||||
bytes[0] = 0;
|
||||
if (gps) {
|
||||
bytes[0] = (byte)(bytes[0] | 1);
|
||||
}
|
||||
if (beidou) {
|
||||
bytes[0] = (byte)(bytes[0] | 2);
|
||||
}
|
||||
if (glonass) {
|
||||
bytes[0] = (byte)(bytes[0] | 4);
|
||||
}
|
||||
if (gaLiLeo) {
|
||||
bytes[0] = (byte)(bytes[0] | 8);
|
||||
}
|
||||
byteBuf.writeBytes(bytes);
|
||||
return byteBuf;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 违规行驶时段范围 ,精确到分
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTIllegalDrivingPeriods implements JTDeviceSubConfig{
|
||||
/**
|
||||
* 违规行驶时段-开始时间 HH:mm
|
||||
*/
|
||||
private String startTime;
|
||||
|
||||
/**
|
||||
* 违规行驶时段-结束时间 HH:mm
|
||||
*/
|
||||
private String endTime;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byte[] bytes = new byte[4];
|
||||
String[] startTimeArray = startTime.split(":");
|
||||
String[] endTimeArray = endTime.split(":");
|
||||
bytes[0] = (byte)Integer.parseInt(startTimeArray[0]);
|
||||
bytes[1] = (byte)Integer.parseInt(startTimeArray[1]);
|
||||
bytes[2] = (byte)Integer.parseInt(endTimeArray[0]);
|
||||
bytes[3] = (byte)Integer.parseInt(endTimeArray[1]);
|
||||
byteBuf.writeBytes(bytes);
|
||||
return byteBuf;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* OSD字幕叠加设置
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class JTOSDConfig {
|
||||
|
||||
/**
|
||||
* 日期和时间
|
||||
*/
|
||||
private boolean time;
|
||||
|
||||
/**
|
||||
* 车牌号码
|
||||
*/
|
||||
private boolean licensePlate;
|
||||
|
||||
/**
|
||||
* 逻辑通道号
|
||||
*/
|
||||
private boolean channelId;
|
||||
|
||||
/**
|
||||
* 经纬度
|
||||
*/
|
||||
private boolean position;
|
||||
|
||||
/**
|
||||
* 行驶记录速度
|
||||
*/
|
||||
private boolean speed;
|
||||
|
||||
/**
|
||||
* 卫星定位速度
|
||||
*/
|
||||
private boolean speedForGPS;
|
||||
|
||||
/**
|
||||
* 连续驾驶时间
|
||||
*/
|
||||
private boolean drivingTime;
|
||||
|
||||
public ByteBuf encode(){
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byte content = 0;
|
||||
if (time) {
|
||||
content = (byte)(content | 1);
|
||||
}
|
||||
if (licensePlate) {
|
||||
content = (byte)(content | (1 << 1));
|
||||
}
|
||||
if (channelId) {
|
||||
content = (byte)(content | (1 << 2));
|
||||
}
|
||||
if (position) {
|
||||
content = (byte)(content | (1 << 3));
|
||||
}
|
||||
if (speed) {
|
||||
content = (byte)(content | (1 << 4));
|
||||
}
|
||||
if (speedForGPS) {
|
||||
content = (byte)(content | (1 << 5));
|
||||
}
|
||||
if (drivingTime) {
|
||||
content = (byte)(content | (1 << 6));
|
||||
}
|
||||
byteBuf.writeByte(content);
|
||||
byteBuf.writeByte(0);
|
||||
return byteBuf;
|
||||
|
||||
}
|
||||
|
||||
public static JTOSDConfig decode(ByteBuf buf) {
|
||||
JTOSDConfig config = new JTOSDConfig();
|
||||
int content = buf.readUnsignedShort();
|
||||
config.setTime((content & 1) == 1);
|
||||
config.setLicensePlate((content >>> 1 & 1) == 1);
|
||||
config.setChannelId((content >>> 2 & 1) == 1);
|
||||
config.setPosition((content >>> 3 & 1) == 1);
|
||||
config.setSpeed((content >>> 4 & 1) == 1);
|
||||
config.setSpeedForGPS((content >>> 5 & 1) == 1);
|
||||
config.setDrivingTime((content >>> 6 & 1) == 1);
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,143 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
/**
|
||||
* 视频报警标志位
|
||||
*/
|
||||
public class JTVideoAlarmBit implements JTDeviceSubConfig{
|
||||
|
||||
/**
|
||||
* 视频信号丢失报警
|
||||
*/
|
||||
private boolean lossSignal;
|
||||
/**
|
||||
* 视频信号遮挡报警
|
||||
*/
|
||||
private boolean occlusionSignal;
|
||||
/**
|
||||
* 存储单元故障报警
|
||||
*/
|
||||
private boolean storageFault;
|
||||
/**
|
||||
* 其他视频设备故障报警
|
||||
*/
|
||||
private boolean otherDeviceFailure;
|
||||
/**
|
||||
* 客车超员报警
|
||||
*/
|
||||
private boolean overcrowding;
|
||||
/**
|
||||
* 异常驾驶行为报警
|
||||
*/
|
||||
private boolean abnormalDriving;
|
||||
/**
|
||||
* 特殊报警录像达到存储阈值报警
|
||||
*/
|
||||
private boolean storageLimit;
|
||||
|
||||
public boolean isLossSignal() {
|
||||
return lossSignal;
|
||||
}
|
||||
|
||||
public void setLossSignal(boolean lossSignal) {
|
||||
this.lossSignal = lossSignal;
|
||||
}
|
||||
|
||||
public boolean isOcclusionSignal() {
|
||||
return occlusionSignal;
|
||||
}
|
||||
|
||||
public void setOcclusionSignal(boolean occlusionSignal) {
|
||||
this.occlusionSignal = occlusionSignal;
|
||||
}
|
||||
|
||||
public boolean isStorageFault() {
|
||||
return storageFault;
|
||||
}
|
||||
|
||||
public void setStorageFault(boolean storageFault) {
|
||||
this.storageFault = storageFault;
|
||||
}
|
||||
|
||||
public boolean isOtherDeviceFailure() {
|
||||
return otherDeviceFailure;
|
||||
}
|
||||
|
||||
public void setOtherDeviceFailure(boolean otherDeviceFailure) {
|
||||
this.otherDeviceFailure = otherDeviceFailure;
|
||||
}
|
||||
|
||||
public boolean isOvercrowding() {
|
||||
return overcrowding;
|
||||
}
|
||||
|
||||
public void setOvercrowding(boolean overcrowding) {
|
||||
this.overcrowding = overcrowding;
|
||||
}
|
||||
|
||||
public boolean isAbnormalDriving() {
|
||||
return abnormalDriving;
|
||||
}
|
||||
|
||||
public void setAbnormalDriving(boolean abnormalDriving) {
|
||||
this.abnormalDriving = abnormalDriving;
|
||||
}
|
||||
|
||||
public boolean isStorageLimit() {
|
||||
return storageLimit;
|
||||
}
|
||||
|
||||
public void setStorageLimit(boolean storageLimit) {
|
||||
this.storageLimit = storageLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byte content = 0;
|
||||
if (lossSignal) {
|
||||
content = content |= 1;
|
||||
}
|
||||
if (occlusionSignal) {
|
||||
content = content |= (1 << 1);
|
||||
}
|
||||
if (storageFault) {
|
||||
content = content |= (1 << 2);
|
||||
}
|
||||
if (otherDeviceFailure) {
|
||||
content = content |= (1 << 3);
|
||||
}
|
||||
if (overcrowding) {
|
||||
content = content |= (1 << 4);
|
||||
}
|
||||
if (abnormalDriving) {
|
||||
content = content |= (1 << 5);
|
||||
}
|
||||
if (storageLimit) {
|
||||
content = content |= (1 << 6);
|
||||
}
|
||||
byteBuf.writeByte(content);
|
||||
byteBuf.writeByte(0);
|
||||
byteBuf.writeByte(0);
|
||||
byteBuf.writeByte(0);
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTVideoAlarmBit decode(ByteBuf byteBuf) {
|
||||
JTVideoAlarmBit videoAlarmBit = new JTVideoAlarmBit();
|
||||
byte content = byteBuf.readByte();
|
||||
videoAlarmBit.setLossSignal((content & 1) == 1);
|
||||
videoAlarmBit.setOcclusionSignal((content >>> 1 & 1) == 1);
|
||||
videoAlarmBit.setStorageFault((content >>> 2 & 1) == 1);
|
||||
videoAlarmBit.setOtherDeviceFailure((content >>> 3 & 1) == 1);
|
||||
videoAlarmBit.setOvercrowding((content >>> 4 & 1) == 1);
|
||||
videoAlarmBit.setAbnormalDriving((content >>> 5 & 1) == 1);
|
||||
videoAlarmBit.setStorageLimit((content >>> 6 & 1) == 1);
|
||||
byteBuf.readByte();
|
||||
byteBuf.readByte();
|
||||
byteBuf.readByte();
|
||||
return videoAlarmBit;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
package com.genersoft.iot.vmp.jt1078.bean.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 违规行驶时段范围 ,精确到分
|
||||
*/
|
||||
@Data
|
||||
public class JTVideoParam implements JTDeviceSubConfig{
|
||||
/**
|
||||
* 实时流编码模式
|
||||
* 0:CBR( 固定码率) ;
|
||||
* 1:VBR( 可变码率) ;
|
||||
* 2:ABR( 平均码率) ;
|
||||
* 100 ~ 127:自定义
|
||||
*/
|
||||
private int liveStreamCodeRateType;
|
||||
|
||||
/**
|
||||
* 实时流分辨率
|
||||
* 0:QCIF;
|
||||
* 1:CIF;
|
||||
* 2:WCIF;
|
||||
* 3:D1;
|
||||
* 4:WD1;
|
||||
* 5:720P;
|
||||
* 6:1 080P;
|
||||
* 100 ~ 127:自定义
|
||||
*/
|
||||
private int liveStreamResolving;
|
||||
|
||||
/**
|
||||
* 实时流关键帧间隔, 范围(1 ~ 1 000) 帧
|
||||
*/
|
||||
private int liveStreamIInterval;
|
||||
|
||||
/**
|
||||
* 实时流目标帧率,范围(1 ~ 120) 帧 / s
|
||||
*/
|
||||
private int liveStreamFrameRate;
|
||||
|
||||
/**
|
||||
* 实时流目标码率,单位为千位每秒( kbps)
|
||||
*/
|
||||
private long liveStreamCodeRate;
|
||||
|
||||
|
||||
/**
|
||||
* 存储流编码模式
|
||||
* 0:CBR( 固定码率)
|
||||
* 1:VBR( 可变码率)
|
||||
* 2:ABR( 平均码率)
|
||||
* 100 ~ 127:自定义
|
||||
*/
|
||||
private int storageStreamCodeRateType;
|
||||
|
||||
/**
|
||||
* 存储流分辨率
|
||||
* 0:QCIF;
|
||||
* 1:CIF;
|
||||
* 2:WCIF;
|
||||
* 3:D1;
|
||||
* 4:WD1;
|
||||
* 5:720P;
|
||||
* 6:1 080P;
|
||||
* 100 ~ 127:自定义
|
||||
*/
|
||||
private int storageStreamResolving;
|
||||
|
||||
/**
|
||||
* 存储流关键帧间隔, 范围(1 ~ 1 000) 帧
|
||||
*/
|
||||
private int storageStreamIInterval;
|
||||
|
||||
/**
|
||||
* 存储流目标帧率,范围(1 ~ 120) 帧 / s
|
||||
*/
|
||||
private int storageStreamFrameRate;
|
||||
|
||||
/**
|
||||
* 存储流目标码率,单位为千位每秒( kbps)
|
||||
*/
|
||||
private long storageStreamCodeRate;
|
||||
|
||||
/**
|
||||
* 字幕叠加设置
|
||||
*/
|
||||
private JTOSDConfig osd;
|
||||
|
||||
/**
|
||||
* 是否启用音频输出, 0:不启用;1:启用
|
||||
*/
|
||||
private int audioEnable;
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeByte(liveStreamCodeRateType);
|
||||
byteBuf.writeByte(liveStreamResolving);
|
||||
byteBuf.writeShort((short)(liveStreamIInterval & 0xffff));
|
||||
byteBuf.writeByte(liveStreamFrameRate);
|
||||
byteBuf.writeInt((int) (liveStreamCodeRate & 0xffffffffL));
|
||||
|
||||
byteBuf.writeByte(storageStreamCodeRateType);
|
||||
byteBuf.writeByte(storageStreamResolving);
|
||||
byteBuf.writeShort((short)(storageStreamIInterval & 0xffff));
|
||||
byteBuf.writeByte(storageStreamFrameRate);
|
||||
byteBuf.writeInt((int) (storageStreamCodeRate & 0xffffffffL));
|
||||
byteBuf.writeBytes(osd.encode());
|
||||
byteBuf.writeByte(audioEnable);
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
public static JTVideoParam decode(ByteBuf buf) {
|
||||
JTVideoParam videoParam = new JTVideoParam();
|
||||
videoParam.setLiveStreamCodeRateType(buf.readByte());
|
||||
videoParam.setLiveStreamResolving(buf.readByte());
|
||||
videoParam.setLiveStreamIInterval(buf.readUnsignedShort());
|
||||
videoParam.setLiveStreamFrameRate(buf.readByte());
|
||||
videoParam.setLiveStreamCodeRate(buf.readUnsignedInt());
|
||||
|
||||
videoParam.setStorageStreamCodeRateType(buf.readByte());
|
||||
videoParam.setStorageStreamResolving(buf.readByte());
|
||||
videoParam.setStorageStreamIInterval(buf.readUnsignedShort());
|
||||
videoParam.setStorageStreamFrameRate(buf.readByte());
|
||||
videoParam.setStorageStreamCodeRate(buf.readUnsignedInt());
|
||||
videoParam.setOsd(JTOSDConfig.decode(buf));
|
||||
videoParam.setAudioEnable(buf.readByte());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,11 @@
|
||||
package com.genersoft.iot.vmp.jt1078.cmd;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.entity.Cmd;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.response.*;
|
||||
import com.genersoft.iot.vmp.jt1078.session.SessionManager;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@ -11,28 +14,83 @@ import java.util.Random;
|
||||
* @date 2023/4/27 18:58
|
||||
* @email qingtaij@163.com
|
||||
*/
|
||||
@Component
|
||||
public class JT1078Template {
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
private static final String H8103 = "8103";
|
||||
private static final String H8104 = "8104";
|
||||
private static final String H8105 = "8105";
|
||||
private static final String H8106 = "8106";
|
||||
private static final String H8107 = "8107";
|
||||
private static final String H8201 = "8201";
|
||||
private static final String H8202 = "8202";
|
||||
private static final String H8203 = "8203";
|
||||
private static final String H8204 = "8204";
|
||||
private static final String H8300 = "8300";
|
||||
private static final String H8400 = "8400";
|
||||
private static final String H8401 = "8401";
|
||||
private static final String H8500 = "8500";
|
||||
private static final String H8600 = "8600";
|
||||
private static final String H8601 = "8601";
|
||||
private static final String H8602 = "8602";
|
||||
private static final String H8603 = "8603";
|
||||
private static final String H8604 = "8604";
|
||||
private static final String H8605 = "8605";
|
||||
private static final String H8606 = "8606";
|
||||
private static final String H8607 = "8607";
|
||||
private static final String H8608 = "8608";
|
||||
private static final String H8702 = "8702";
|
||||
private static final String H8801 = "8801";
|
||||
private static final String H8802 = "8802";
|
||||
private static final String H8803 = "8803";
|
||||
private static final String H8804 = "8804";
|
||||
private static final String H8805 = "8805";
|
||||
private static final String H9003 = "9003";
|
||||
private static final String H9101 = "9101";
|
||||
private static final String H9102 = "9102";
|
||||
private static final String H9201 = "9201";
|
||||
private static final String H9202 = "9202";
|
||||
private static final String H9205 = "9205";
|
||||
private static final String H9206 = "9206";
|
||||
private static final String H9207 = "9207";
|
||||
private static final String H9301 = "9301";
|
||||
private static final String H9302 = "9302";
|
||||
private static final String H9303 = "9303";
|
||||
private static final String H9304 = "9304";
|
||||
private static final String H9305 = "9305";
|
||||
private static final String H9306 = "9306";
|
||||
|
||||
private static final String H0001 = "0001";
|
||||
private static final String H0104 = "0104";
|
||||
private static final String H0107 = "0107";
|
||||
private static final String H0201 = "0201";
|
||||
private static final String H0500 = "0500";
|
||||
private static final String H0608 = "0608";
|
||||
private static final String H0702 = "0702";
|
||||
private static final String H0801 = "0801";
|
||||
private static final String H0802 = "0802";
|
||||
private static final String H0805 = "0805";
|
||||
private static final String H1003 = "1003";
|
||||
private static final String H1205 = "1205";
|
||||
|
||||
public void checkTerminalStatus(String devId){
|
||||
if (SessionManager.INSTANCE.get(devId) == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "终端不在线");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启直播视频
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9101 开启视频参数
|
||||
*/
|
||||
public String startLive(String devId, J9101 j9101, Integer timeOut) {
|
||||
public Object startLive(String devId, J9101 j9101, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setDevId(devId)
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9101)
|
||||
.setRespId(H0001)
|
||||
@ -47,9 +105,10 @@ public class JT1078Template {
|
||||
* @param devId 设备号
|
||||
* @param j9102 关闭视频参数
|
||||
*/
|
||||
public String stopLive(String devId, J9102 j9102, Integer timeOut) {
|
||||
public Object stopLive(String devId, J9102 j9102, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setDevId(devId)
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9102)
|
||||
.setRespId(H0001)
|
||||
@ -64,9 +123,10 @@ public class JT1078Template {
|
||||
* @param devId 设备号
|
||||
* @param j9205 查询音视频列表
|
||||
*/
|
||||
public String queryBackTime(String devId, J9205 j9205, Integer timeOut) {
|
||||
public Object queryBackTime(String devId, J9205 j9205, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setDevId(devId)
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9205)
|
||||
.setRespId(H1205)
|
||||
@ -81,9 +141,10 @@ public class JT1078Template {
|
||||
* @param devId 设备号
|
||||
* @param j9201 视频回放参数
|
||||
*/
|
||||
public String startBackLive(String devId, J9201 j9201, Integer timeOut) {
|
||||
public Object startBackLive(String devId, J9201 j9201, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setDevId(devId)
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9201)
|
||||
.setRespId(H1205)
|
||||
@ -98,9 +159,10 @@ public class JT1078Template {
|
||||
* @param devId 设备号
|
||||
* @param j9202 控制视频回放参数
|
||||
*/
|
||||
public String controlBackLive(String devId, J9202 j9202, Integer timeOut) {
|
||||
public Object controlBackLive(String devId, J9202 j9202, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setDevId(devId)
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9202)
|
||||
.setRespId(H0001)
|
||||
@ -109,7 +171,523 @@ public class JT1078Template {
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9206 文件上传参数
|
||||
*/
|
||||
public Object fileUpload(String devId, J9206 j9206, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9206)
|
||||
.setRespId(H0001)
|
||||
.setRs(j9206)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传控制
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9207 文件上传控制参数
|
||||
*/
|
||||
public Object fileUploadControl(String devId, J9207 j9207, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9207)
|
||||
.setRespId(H0001)
|
||||
.setRs(j9207)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台控制指令-云台旋转
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9301 云台旋转参数
|
||||
*/
|
||||
public Object ptzRotate(String devId, J9301 j9301, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9301)
|
||||
.setRespId(H0001)
|
||||
.setRs(j9301)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台控制指令-云台调整焦距控制
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9302 云台焦距控制参数
|
||||
*/
|
||||
public Object ptzFocal(String devId, J9302 j9302, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9302)
|
||||
.setRespId(H0001)
|
||||
.setRs(j9302)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台控制指令-云台调整光圈控制
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9303 云台光圈控制参数
|
||||
*/
|
||||
public Object ptzIris(String devId, J9303 j9303, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9303)
|
||||
.setRespId(H0001)
|
||||
.setRs(j9303)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台控制指令-云台雨刷控制
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9304 云台雨刷控制参数
|
||||
*/
|
||||
public Object ptzWiper(String devId, J9304 j9304, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9304)
|
||||
.setRespId(H0001)
|
||||
.setRs(j9304)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台控制指令-红外补光控制
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9305 云台红外补光控制参数
|
||||
*/
|
||||
public Object ptzSupplementaryLight(String devId, J9305 j9305, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9305)
|
||||
.setRespId(H0001)
|
||||
.setRs(j9305)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台控制指令-变倍控制
|
||||
*
|
||||
* @param devId 设备号
|
||||
* @param j9306 云台变倍控制参数
|
||||
*/
|
||||
public Object ptzZoom(String devId, J9306 j9306, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9306)
|
||||
.setRespId(H0001)
|
||||
.setRs(j9306)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询终端参数
|
||||
*
|
||||
* @param devId 设备号
|
||||
*/
|
||||
public Object getDeviceConfig(String devId, J8104 j8104, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8104)
|
||||
.setRespId(H0104)
|
||||
.setRs(j8104)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定终端参数
|
||||
*
|
||||
* @param devId 设备号
|
||||
*/
|
||||
public Object getDeviceSpecifyConfig(String devId, J8106 j8106, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8106)
|
||||
.setRespId(H0104)
|
||||
.setRs(j8106)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置终端参数
|
||||
*
|
||||
* @param devId 设备号
|
||||
*/
|
||||
public Object setDeviceSpecifyConfig(String devId, J8103 j8103, Integer timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8103)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8103)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
private Long randomInt() {
|
||||
return (long) random.nextInt(1000) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备控制
|
||||
*/
|
||||
public Object deviceControl(String devId, J8105 j8105, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8105)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8105)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询终端属性
|
||||
*/
|
||||
public Object deviceAttribute(String devId, J8107 j8107, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8107)
|
||||
.setRespId(H0107)
|
||||
.setRs(j8107)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 位置信息查询
|
||||
*/
|
||||
public Object queryPositionInfo(String devId, J8201 j8201, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8201)
|
||||
.setRespId(H0201)
|
||||
.setRs(j8201)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object tempPositionTrackingControl(String devId, J8202 j8202, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8202)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8202)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object confirmationAlarmMessage(String devId, J8203 j8203, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8203)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8203)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object linkDetection(String devId, J8204 j8204, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8204)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8204)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object textMessage(String devId, J8300 j8300, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8300)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8300)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object telephoneCallback(String devId, J8400 j8400, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8400)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8400)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object setPhoneBook(String devId, J8401 j8401, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8401)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8401)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object vehicleControl(String devId, J8500 j8500, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8500)
|
||||
.setRespId(H0500)
|
||||
.setRs(j8500)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object setAreaForCircle(String devId, J8600 j8600, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8600)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8600)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object deleteAreaForCircle(String devId, J8601 j8601, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8601)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8601)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object setAreaForRectangle(String devId, J8602 j8602, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8602)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8602)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object deleteAreaForRectangle(String devId, J8603 j8603, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8603)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8603)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object setAreaForPolygon(String devId, J8604 j8604, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8604)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8604)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object deleteAreaForPolygon(String devId, J8605 j8605, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8605)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8605)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object setRoute(String devId, J8606 j8606, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8606)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8606)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object deleteRoute(String devId, J8607 j8607, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8607)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8607)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object queryAreaOrRoute(String devId, J8608 j8608, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8608)
|
||||
.setRespId(H0608)
|
||||
.setRs(j8608)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object queryDriverInformation(String devId, J8702 j8702, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8702)
|
||||
.setRespId(H0702)
|
||||
.setRs(j8702)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object shooting(String devId, J8801 j8801, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8801)
|
||||
.setRespId(H0805)
|
||||
.setRs(j8801)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object queryMediaData(String devId, J8802 j8802, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8802)
|
||||
.setRespId(H0802)
|
||||
.setRs(j8802)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object uploadMediaData(String devId, J8803 j8803, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8803)
|
||||
.setRespId(H0801)
|
||||
.setRs(j8803)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object record(String devId, J8804 j8804, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8804)
|
||||
.setRespId(H0001)
|
||||
.setRs(j8804)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object uploadMediaDataForSingle(String devId, J8805 j8805, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H8805)
|
||||
.setRespId(H0801)
|
||||
.setRs(j8805)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
|
||||
public Object queryMediaAttribute(String devId, J9003 j9003, int timeOut) {
|
||||
checkTerminalStatus(devId);
|
||||
Cmd cmd = new Cmd.Builder()
|
||||
.setPhoneNumber(devId)
|
||||
.setPackageNo(randomInt())
|
||||
.setMsgId(H9003)
|
||||
.setRespId(H1003)
|
||||
.setRs(j9003)
|
||||
.build();
|
||||
return SessionManager.INSTANCE.request(cmd, timeOut);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.jt1078.proc.Header;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.factory.CodecFactory;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.request.Re;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.response.Rs;
|
||||
import com.genersoft.iot.vmp.jt1078.service.Ijt1078Service;
|
||||
import com.genersoft.iot.vmp.jt1078.session.Session;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
@ -11,10 +12,17 @@ import io.netty.buffer.CompositeByteBuf;
|
||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author QingtaiJiang
|
||||
@ -24,40 +32,64 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class Jt808Decoder extends ByteToMessageDecoder {
|
||||
|
||||
private ApplicationEventPublisher applicationEventPublisher = null;
|
||||
private Ijt1078Service service = null;
|
||||
|
||||
public Jt808Decoder(ApplicationEventPublisher applicationEventPublisher, Ijt1078Service service ) {
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||
Session session = ctx.channel().attr(Session.KEY).get();
|
||||
log.info("> {} hex:{}", session, ByteBufUtil.hexDump(in));
|
||||
|
||||
log.info("> {} hex: 7e{}7e", session, ByteBufUtil.hexDump(in));
|
||||
try {
|
||||
// 按照部标定义执行校验和转义
|
||||
ByteBuf buf = unEscapeAndCheck(in);
|
||||
|
||||
buf.retain();
|
||||
Header header = new Header();
|
||||
header.setMsgId(ByteBufUtil.hexDump(buf.readSlice(2)));
|
||||
header.setMsgPro(buf.readUnsignedShort());
|
||||
// 从消息属性中读取是否存在分包
|
||||
boolean isSubpackage = (header.getMsgPro() >>> 13 & 1) == 1;
|
||||
if (header.is2019Version()) {
|
||||
header.setVersion(buf.readUnsignedByte());
|
||||
String devId = ByteBufUtil.hexDump(buf.readSlice(10));
|
||||
header.setDevId(devId.replaceFirst("^0*", ""));
|
||||
header.setPhoneNumber(devId.replaceFirst("^0*", ""));
|
||||
} else {
|
||||
header.setDevId(ByteBufUtil.hexDump(buf.readSlice(6)).replaceFirst("^0*", ""));
|
||||
header.setPhoneNumber(ByteBufUtil.hexDump(buf.readSlice(6)).replaceFirst("^0*", ""));
|
||||
}
|
||||
header.setSn(buf.readUnsignedShort());
|
||||
|
||||
if (isSubpackage) {
|
||||
int packageCount = buf.readUnsignedShort();
|
||||
int packageNumber = buf.readUnsignedShort();
|
||||
log.debug("[分包消息] header: {}, 序号: {}, 总数: {}", header, packageNumber, packageCount);
|
||||
// 缓存带合并的分包消息
|
||||
ByteBuf intactBuf = MultiPacketManager.INSTANCE.add(header, packageCount, buf);
|
||||
if (intactBuf == null) {
|
||||
return;
|
||||
}
|
||||
buf = intactBuf;
|
||||
}
|
||||
Re handler = CodecFactory.getHandler(header.getMsgId());
|
||||
if (handler == null) {
|
||||
log.error("get msgId is null {}", header.getMsgId());
|
||||
buf.release();
|
||||
return;
|
||||
}
|
||||
Rs decode = handler.decode(buf, header, session);
|
||||
|
||||
Rs decode = handler.decode(buf, header, session, service);
|
||||
ApplicationEvent applicationEvent = handler.getEvent();
|
||||
if (applicationEvent != null) {
|
||||
applicationEventPublisher.publishEvent(applicationEvent);
|
||||
}
|
||||
if (decode != null) {
|
||||
out.add(decode);
|
||||
}
|
||||
} finally {
|
||||
in.skipBytes(in.readableBytes());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -121,7 +153,7 @@ public class Jt808Decoder extends ByteToMessageDecoder {
|
||||
}
|
||||
|
||||
if (calculationCheckSum == checkSum) {
|
||||
if (bufList.size() == 0) {
|
||||
if (bufList.isEmpty()) {
|
||||
return byteBuf.slice(low, high);
|
||||
} else {
|
||||
bufList.add(byteBuf.slice(low, high - low));
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package com.genersoft.iot.vmp.jt1078.codec.decode;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.proc.Header;
|
||||
import io.netty.buffer.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Slf4j
|
||||
public enum MultiPacketManager {
|
||||
INSTANCE;
|
||||
// 用与消息的缓存
|
||||
private final Map<String, CompositeByteBuf> packetMap = new ConcurrentHashMap<>();
|
||||
private final Map<String, Long> packetTimeMap = new ConcurrentHashMap<>();
|
||||
|
||||
MultiPacketManager() {
|
||||
startLister();
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加待合并的分包,如果分包接受完毕会返回完整的数据包
|
||||
*/
|
||||
public ByteBuf add(Header header, Integer count, ByteBuf byteBuf) {
|
||||
String key = header.getMsgId() + "/" + header.getPhoneNumber();
|
||||
CompositeByteBuf compositeBuf = packetMap.computeIfAbsent(key, k -> new CompositeByteBuf(UnpooledByteBufAllocator.DEFAULT, false, count));
|
||||
// compositeBuf.addComponent(true, byteBuf.readSlice(byteBuf.readableBytes()));
|
||||
compositeBuf.addComponent(true, byteBuf);
|
||||
packetTimeMap.put(key, System.currentTimeMillis());
|
||||
if (count == compositeBuf.numComponents()) {
|
||||
packetMap.remove(key);
|
||||
packetTimeMap.remove(key);
|
||||
compositeBuf.retain();
|
||||
return compositeBuf;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void startLister(){
|
||||
Timer timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
long expireTime = System.currentTimeMillis() - 20 * 1000;
|
||||
if (!packetTimeMap.isEmpty()) {
|
||||
for (String key : packetTimeMap.keySet()) {
|
||||
if (packetTimeMap.get(key) < expireTime) {
|
||||
log.info("分包消息超时 key: {}", key);
|
||||
packetTimeMap.remove(key);
|
||||
packetMap.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 2000L, 2000L);
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,8 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author QingtaiJiang
|
||||
* @date 2023/4/27 18:10
|
||||
@ -21,12 +23,12 @@ public class Jt808Encoder extends MessageToByteEncoder<Rs> {
|
||||
protected void encode(ChannelHandlerContext ctx, Rs msg, ByteBuf out) throws Exception {
|
||||
Session session = ctx.channel().attr(Session.KEY).get();
|
||||
|
||||
ByteBuf encode = Jt808EncoderCmd.encode(msg, session, session.nextSerialNo());
|
||||
if(encode!=null){
|
||||
log.info("< {} hex:{}", session, ByteBufUtil.hexDump(encode));
|
||||
out.writeBytes(encode);
|
||||
List<ByteBuf> encodeList = Jt808EncoderCmd.encode(msg, session, session.nextSerialNo());
|
||||
if(encodeList!=null && !encodeList.isEmpty()){
|
||||
for (ByteBuf byteBuf : encodeList) {
|
||||
log.debug("< {} hex:{}", session, ByteBufUtil.hexDump(byteBuf));
|
||||
out.writeBytes(byteBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author QingtaiJiang
|
||||
@ -30,51 +31,84 @@ public class Jt808EncoderCmd extends MessageToByteEncoder<Cmd> {
|
||||
protected void encode(ChannelHandlerContext ctx, Cmd cmd, ByteBuf out) throws Exception {
|
||||
Session session = ctx.channel().attr(Session.KEY).get();
|
||||
Rs msg = cmd.getRs();
|
||||
ByteBuf encode = encode(msg, session, cmd.getPackageNo().intValue());
|
||||
if (encode != null) {
|
||||
log.info("< {} hex:{}", session, ByteBufUtil.hexDump(encode));
|
||||
out.writeBytes(encode);
|
||||
List<ByteBuf> encodeList = encode(msg, session, cmd.getPackageNo().intValue());
|
||||
if (encodeList != null && !encodeList.isEmpty()) {
|
||||
for (ByteBuf byteBuf : encodeList) {
|
||||
log.debug("< {} hex:{}", session, ByteBufUtil.hexDump(byteBuf));
|
||||
out.writeBytes(byteBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ByteBuf encode(Rs msg, Session session, Integer packageNo) {
|
||||
public static List<ByteBuf> encode(Rs msg, Session session, Integer packageNo) {
|
||||
String id = msg.getClass().getAnnotation(MsgId.class).id();
|
||||
if (!StringUtils.hasLength(id)) {
|
||||
log.error("Not find msgId");
|
||||
return null;
|
||||
}
|
||||
ByteBuf encode = msg.encode();
|
||||
Header header = msg.getHeader();
|
||||
|
||||
List<ByteBuf> byteBufList = new LinkedList<>();
|
||||
if (encode.readableBytes() > 1000) {
|
||||
int index = 1;
|
||||
int total = encode.readableBytes()%1000 == 0 ? encode.readableBytes()/1000 : (encode.readableBytes()/1000 + 1);
|
||||
while (encode.isReadable()) {
|
||||
ByteBuf byteBuf;
|
||||
if (index == total) {
|
||||
byteBuf = buildMsgByte(header, id, session, packageNo, encode.readRetainedSlice(encode.readableBytes()), index, total);
|
||||
}else {
|
||||
byteBuf = buildMsgByte(header, id, session, packageNo, encode.readRetainedSlice(1000), index, total);
|
||||
}
|
||||
|
||||
byteBufList.add(byteBuf);
|
||||
index ++;
|
||||
}
|
||||
}else {
|
||||
byteBufList.add(buildMsgByte(header, id, session, packageNo, encode, 0, 0));
|
||||
}
|
||||
return byteBufList;
|
||||
}
|
||||
|
||||
// 分包
|
||||
private static ByteBuf buildMsgByte(Header header, String id, Session session, Integer packageNo, ByteBuf encode, Integer packetIndex, Integer packetTotal) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
|
||||
byteBuf.writeBytes(ByteBufUtil.decodeHexDump(id));
|
||||
|
||||
ByteBuf encode = msg.encode();
|
||||
|
||||
Header header = msg.getHeader();
|
||||
if (header == null) {
|
||||
header = session.getHeader();
|
||||
}
|
||||
|
||||
if (header.is2019Version()) {
|
||||
int msgBody = encode.readableBytes() | 1 << 14;
|
||||
if (packetIndex > 0) {
|
||||
msgBody = msgBody | 1 << 13;
|
||||
}
|
||||
// 消息体属性
|
||||
byteBuf.writeShort(encode.readableBytes() | 1 << 14);
|
||||
byteBuf.writeShort(msgBody);
|
||||
|
||||
// 版本号
|
||||
byteBuf.writeByte(header.getVersion());
|
||||
|
||||
// 终端手机号
|
||||
byteBuf.writeBytes(ByteBufUtil.decodeHexDump(Bin.strHexPaddingLeft(header.getDevId(), 20)));
|
||||
byteBuf.writeBytes(ByteBufUtil.decodeHexDump(Bin.strHexPaddingLeft(header.getPhoneNumber(), 20)));
|
||||
} else {
|
||||
// 消息体属性
|
||||
byteBuf.writeShort(encode.readableBytes());
|
||||
|
||||
byteBuf.writeBytes(ByteBufUtil.decodeHexDump(Bin.strHexPaddingLeft(header.getDevId(), 12)));
|
||||
byteBuf.writeBytes(ByteBufUtil.decodeHexDump(Bin.strHexPaddingLeft(header.getPhoneNumber(), 12)));
|
||||
}
|
||||
|
||||
// 消息体流水号
|
||||
byteBuf.writeShort(packageNo);
|
||||
|
||||
if (packetIndex > 0) {
|
||||
byteBuf.writeShort(packetTotal);
|
||||
byteBuf.writeShort(packetIndex);
|
||||
}
|
||||
|
||||
// 写入消息体
|
||||
byteBuf.writeBytes(encode);
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.jt1078.codec.netty;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.event.ConnectChangeEvent;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.response.Rs;
|
||||
import com.genersoft.iot.vmp.jt1078.session.Session;
|
||||
import com.genersoft.iot.vmp.jt1078.session.SessionManager;
|
||||
@ -8,6 +9,10 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.timeout.IdleState;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
@ -18,6 +23,12 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class Jt808Handler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
private ApplicationEventPublisher applicationEventPublisher = null;
|
||||
|
||||
public Jt808Handler(ApplicationEventPublisher applicationEventPublisher) {
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
if (msg instanceof Rs) {
|
||||
@ -25,6 +36,8 @@ public class Jt808Handler extends ChannelInboundHandlerAdapter {
|
||||
} else {
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
// 读取完成后的消息释放
|
||||
ReferenceCountUtil.release(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -33,6 +46,13 @@ public class Jt808Handler extends ChannelInboundHandlerAdapter {
|
||||
Session session = SessionManager.INSTANCE.newSession(channel);
|
||||
channel.attr(Session.KEY).set(session);
|
||||
log.info("> Tcp connect {}", session);
|
||||
if (session.getPhoneNumber() == null) {
|
||||
return;
|
||||
}
|
||||
ConnectChangeEvent event = new ConnectChangeEvent(this);
|
||||
event.setConnected(true);
|
||||
event.setPhoneNumber(session.getPhoneNumber());
|
||||
applicationEventPublisher.publishEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -40,6 +60,14 @@ public class Jt808Handler extends ChannelInboundHandlerAdapter {
|
||||
Session session = ctx.channel().attr(Session.KEY).get();
|
||||
log.info("< Tcp disconnect {}", session);
|
||||
ctx.close();
|
||||
if (session.getPhoneNumber() == null) {
|
||||
return;
|
||||
}
|
||||
ConnectChangeEvent event = new ConnectChangeEvent(this);
|
||||
event.setConnected(false);
|
||||
event.setPhoneNumber(session.getPhoneNumber());
|
||||
applicationEventPublisher.publishEvent(event);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.jt1078.codec.decode.Jt808Decoder;
|
||||
import com.genersoft.iot.vmp.jt1078.codec.encode.Jt808Encoder;
|
||||
import com.genersoft.iot.vmp.jt1078.codec.encode.Jt808EncoderCmd;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.factory.CodecFactory;
|
||||
import com.genersoft.iot.vmp.jt1078.service.Ijt1078Service;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@ -17,6 +18,13 @@ import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -34,11 +42,15 @@ public class TcpServer {
|
||||
private boolean isRunning = false;
|
||||
private EventLoopGroup bossGroup = null;
|
||||
private EventLoopGroup workerGroup = null;
|
||||
private ApplicationEventPublisher applicationEventPublisher = null;
|
||||
private Ijt1078Service service = null;
|
||||
|
||||
private final ByteBuf DECODER_JT808 = Unpooled.wrappedBuffer(new byte[]{0x7e});
|
||||
|
||||
public TcpServer(Integer port) {
|
||||
public TcpServer(Integer port, ApplicationEventPublisher applicationEventPublisher, Ijt1078Service service) {
|
||||
this.port = port;
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
private void startTcpServer() {
|
||||
@ -59,10 +71,10 @@ public class TcpServer {
|
||||
channel.pipeline()
|
||||
.addLast(new IdleStateHandler(10, 0, 0, TimeUnit.MINUTES))
|
||||
.addLast(new DelimiterBasedFrameDecoder(1024 * 2, DECODER_JT808))
|
||||
.addLast(new Jt808Decoder())
|
||||
.addLast(new Jt808Decoder(applicationEventPublisher, service))
|
||||
.addLast(new Jt808Encoder())
|
||||
.addLast(new Jt808EncoderCmd())
|
||||
.addLast(new Jt808Handler());
|
||||
.addLast(new Jt808Handler(applicationEventPublisher));
|
||||
}
|
||||
});
|
||||
ChannelFuture channelFuture = bootstrap.bind(port).sync();
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package com.genersoft.iot.vmp.jt1078.config;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.cmd.JT1078Template;
|
||||
import com.genersoft.iot.vmp.jt1078.codec.netty.TcpServer;
|
||||
import com.genersoft.iot.vmp.jt1078.service.Ijt1078Service;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
@ -18,13 +20,14 @@ import org.springframework.core.annotation.Order;
|
||||
@ConditionalOnProperty(value = "jt1078.enable", havingValue = "true")
|
||||
public class JT1078AutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Autowired
|
||||
private Ijt1078Service service;
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
public TcpServer jt1078Server(@Value("${jt1078.port}") Integer port) {
|
||||
return new TcpServer(port);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JT1078Template jt1078Template() {
|
||||
return new JT1078Template();
|
||||
return new TcpServer(port, applicationEventPublisher, service);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.genersoft.iot.vmp.jt1078.config;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.common.ConfigAttribute;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "jt1078", ignoreInvalidFields = true)
|
||||
@Order(3)
|
||||
public class JT1078Config {
|
||||
|
||||
private Integer port;
|
||||
|
||||
private String password;
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
package com.genersoft.iot.vmp.jt1078.config;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.cmd.JT1078Template;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.response.*;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* curl http://localhost:18080/api/jt1078/start/live/18864197066/1
|
||||
*
|
||||
* @author QingtaiJiang
|
||||
* @date 2023/4/27 18:12
|
||||
* @email qingtaij@163.com
|
||||
*/
|
||||
@ConditionalOnProperty(value = "jt1078.enable", havingValue = "true")
|
||||
@RestController
|
||||
@RequestMapping("/api/jt1078")
|
||||
public class JT1078Controller {
|
||||
|
||||
@Resource
|
||||
JT1078Template jt1078Template;
|
||||
|
||||
/**
|
||||
* jt1078Template 调用示例
|
||||
*/
|
||||
@GetMapping("/start/live/{deviceId}/{channelId}")
|
||||
public WVPResult<?> startLive(@PathVariable String deviceId, @PathVariable String channelId) {
|
||||
J9101 j9101 = new J9101();
|
||||
j9101.setChannel(Integer.valueOf(channelId));
|
||||
j9101.setIp("192.168.1.1");
|
||||
j9101.setRate(1);
|
||||
j9101.setTcpPort(7618);
|
||||
j9101.setUdpPort(7618);
|
||||
j9101.setType(0);
|
||||
// TODO 分配ZLM,获取IP、端口
|
||||
String s = jt1078Template.startLive(deviceId, j9101, 6);
|
||||
// TODO 设备响应成功后,封装拉流结果集
|
||||
WVPResult<String> wvpResult = new WVPResult<>();
|
||||
wvpResult.setCode(200);
|
||||
wvpResult.setData(String.format("http://192.168.1.1/rtp/%s_%s.live.mp4", deviceId, channelId));
|
||||
return wvpResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,119 @@
|
||||
package com.genersoft.iot.vmp.jt1078.controller;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.jt1078.bean.*;
|
||||
import com.genersoft.iot.vmp.jt1078.service.Ijt1078Service;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@ConditionalOnProperty(value = "jt1078.enable", havingValue = "true")
|
||||
@RestController
|
||||
@Tag(name = "部标终端以及通道管理")
|
||||
@RequestMapping("/api/jt1078/terminal")
|
||||
public class JT1078TerminalController {
|
||||
|
||||
@Resource
|
||||
Ijt1078Service service;
|
||||
|
||||
@Operation(summary = "JT-分页查询部标设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||
@Parameter(name = "query", description = "查询内容")
|
||||
@Parameter(name = "online", description = "是否在线")
|
||||
@GetMapping("/list")
|
||||
public PageInfo<JTDevice> getDevices(int page, int count,
|
||||
@RequestParam(required = false) String query,
|
||||
@RequestParam(required = false) Boolean online) {
|
||||
return service.getDeviceList(page, count, query, online);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "device", description = "设备", required = true)
|
||||
@PostMapping("/update")
|
||||
public void updateDevice(JTDevice device){
|
||||
assert device.getId() > 0;
|
||||
assert device.getPhoneNumber() != null;
|
||||
service.updateDevice(device);
|
||||
}
|
||||
|
||||
@Operation(summary = "JT-新增设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "device", description = "设备", required = true)
|
||||
@PostMapping("/add")
|
||||
public void addDevice(JTDevice device){
|
||||
assert device.getPhoneNumber() != null;
|
||||
String phoneNumber = device.getPhoneNumber().replaceFirst("^0*", "");
|
||||
device.setPhoneNumber(phoneNumber);
|
||||
service.addDevice(device);
|
||||
}
|
||||
@Operation(summary = "删除设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "phoneNumber", description = "设备手机号", required = true)
|
||||
@DeleteMapping("/delete")
|
||||
public void addDevice(String phoneNumber){
|
||||
assert phoneNumber != null;
|
||||
service.deleteDeviceByPhoneNumber(phoneNumber);
|
||||
}
|
||||
@Operation(summary = "查询设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "phoneNumber", description = "设备手机号", required = true)
|
||||
@GetMapping("/query")
|
||||
public JTDevice getDevice(Integer deviceId){
|
||||
return service.getDeviceById(deviceId);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "JT-查询部标通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||
@Parameter(name = "deviceId", description = "设备ID", required = true)
|
||||
@Parameter(name = "query", description = "查询内容")
|
||||
@GetMapping("/channel/list")
|
||||
public PageInfo<JTChannel> getChannels(int page, int count,
|
||||
@RequestParam(required = true) Integer deviceId,
|
||||
@RequestParam(required = false) String query) {
|
||||
assert deviceId != null;
|
||||
return service.getChannelList(page, count, deviceId, query);
|
||||
}
|
||||
|
||||
@Operation(summary = "JT-查询单个部标通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "id", description = "通道数据库ID", required = true)
|
||||
@GetMapping("/channel/one")
|
||||
public JTChannel getChannel(Integer id) {
|
||||
assert id != null;
|
||||
return service.getChannelByDbId(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "JT-更新通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "channel", description = "通道", required = true)
|
||||
@PostMapping("/channel/update")
|
||||
public void updateChannel(@RequestBody JTChannel channel){
|
||||
assert channel.getId() > 0;
|
||||
assert channel.getChannelId() != null;
|
||||
service.updateChannel(channel);
|
||||
}
|
||||
|
||||
@Operation(summary = "JT-新增通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "channel", description = "通道", required = true)
|
||||
@PostMapping("/channel/add")
|
||||
public JTChannel addChannel(@RequestBody JTChannel channel){
|
||||
assert channel.getChannelId() != null;
|
||||
assert channel.getTerminalDbId() != 0;
|
||||
service.addChannel(channel);
|
||||
return channel;
|
||||
}
|
||||
@Operation(summary = "JT-删除通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "id", description = "通道的数据库ID", required = true)
|
||||
@DeleteMapping("/channel/delete")
|
||||
public void deleteChannel(Integer id){
|
||||
service.deleteChannelById(id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.genersoft.iot.vmp.jt1078.controller.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.JTConfirmationAlarmMessageType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 人工确认报警消息参数
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "人工确认报警消息参数")
|
||||
public class ConfirmationAlarmMessageParam {
|
||||
|
||||
@Schema(description = "终端手机号")
|
||||
private String phoneNumber;
|
||||
@Schema(description = "报警消息流水号")
|
||||
private int alarmPackageNo;
|
||||
@Schema(description = "人工确认报警类型")
|
||||
private JTConfirmationAlarmMessageType alarmMessageType;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConfirmationAlarmMessageParam{" +
|
||||
"PhoneNumber='" + phoneNumber + '\'' +
|
||||
", alarmPackageNo=" + alarmPackageNo +
|
||||
", alarmMessageType=" + alarmMessageType +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.genersoft.iot.vmp.jt1078.controller.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.JTDeviceConnectionControl;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class ConnectionControlParam {
|
||||
|
||||
@Schema(description = "终端手机号")
|
||||
private String phoneNumber;
|
||||
private JTDeviceConnectionControl control;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConnectionControlParam{" +
|
||||
"deviceId='" + phoneNumber + '\'' +
|
||||
", control=" + control +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.genersoft.iot.vmp.jt1078.controller.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.JTQueryMediaDataCommand;
|
||||
import com.genersoft.iot.vmp.jt1078.bean.JTShootingCommand;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "存储多媒体数据参数")
|
||||
public class QueryMediaDataParam {
|
||||
|
||||
@Schema(description = "终端手机号")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "多媒体 ID, 单条存储多媒体数据检索上传时有效")
|
||||
private Long mediaId;
|
||||
|
||||
@Schema(description = "删除标志, 单条存储多媒体数据检索上传时有效")
|
||||
private int delete;
|
||||
|
||||
@Schema(description = "存储多媒体数据参数")
|
||||
private JTQueryMediaDataCommand queryMediaDataCommand;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueryMediaDataParam{" +
|
||||
"设备手机号='" + phoneNumber + '\'' +
|
||||
", mediaId=" + mediaId +
|
||||
", queryMediaDataCommand=" + queryMediaDataCommand +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.genersoft.iot.vmp.jt1078.controller.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.bean.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Schema(description = "设置区域参数")
|
||||
public class SetAreaParam {
|
||||
|
||||
@Schema(description = "终端手机号")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "圆形区域项")
|
||||
private List<JTCircleArea> circleAreaList;
|
||||
|
||||
@Schema(description = "矩形区域项")
|
||||
private List<JTRectangleArea> rectangleAreas;
|
||||
|
||||
@Schema(description = "多边形区域")
|
||||
private JTPolygonArea polygonArea;
|
||||
|
||||
@Schema(description = "路线")
|
||||
private JTRoute route;
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SetAreaParam{" +
|
||||
"设备手机号='" + phoneNumber + '\'' +
|
||||
", circleAreaList=" + circleAreaList +
|
||||
", rectangleAreas=" + rectangleAreas +
|
||||
", polygonArea=" + polygonArea +
|
||||
", route=" + route +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user