从零开始使用 Netty 接入领浩智能柜 实现设备通信

连接设备






- 首先如图1所示进入设备的后台 设置你的服务器地址 这里我用的是内网穿透的地址
- 然后创建一个项目引入 netty的依赖 如图2所示
- 然后创建一个 server包 里面创建一个 NettyServer 代码如下
运行这个代码如图4所示我们和设备就连接上了
命令码




命令码
设备连接服务器以后,服务器首先下发获取设备编号命令,如果是内部设备,则会根据规则进行应答,服务器接收到设备编号进行匹配,确认是否建立网络通道
0x01:获取设备编号
0x02:打卡指定箱门
0x03:查询指定箱门状态
0x04:查询指定箱门卡号
0x05:打开指定箱门的消毒灯
0x06:关闭指定箱门的消毒灯
0x07:设置二维码
0x09:设置广告
0x0A:设置背景图片
0xFF:心跳回环
命令格式参考
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 01 | 保留 | FF |
应答格式参考
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 01 | 0000 | FF |
根据这个我们创建一个命令码 的常量类
协议的常量类
报文格式化处理




根据上面信息得知 我们发送的格式和下位机应答的格式都是固定的 所以我们写一个编码器和解码器对设备进行一个统一的处理
首先创建一个指令类 代码如下
- 创建一个 handler包 在这个包下创建 LockerDecoder 类 和LockerEncoder 类
- LockerDecoder 解码器代码如下 其实原理很简单就是挨个位置进行解析 再存放到实体类中
- LockerEncoder 编码器代码如下 这个就是把数据 转换并存放到 ByteBuf中
- 然后创建一个LockerServerHandler 类 这个里面存放我们与设备连接和命令操作的相关代码
- 修改server 把刚刚写好的解码器 编码器和命令实现 添加到 ChannelPipeline中
重新运行效果如图2所示
心跳互连





如图所示 我们设备上写的是连接中 我们需要与设备进行心跳交互才能变成已连接
设备连接到服务器以后需要主动发送一次报文
下位机接收到报文后15秒发送一次心跳,服务器接收到设备心跳,相同的心跳命令再 推送回来,设备收到以后会刷新发送间隔,15秒后再次发送心跳。
如果超过35秒未收到服务器下发心跳,则认为服务器宕机,执行断线重连。
上位机发送:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | FF | 00 | FF |
下位机应答:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | FF | 00 | FF |
修改处理代码如下
其实就是设备连接时候发送一个心跳 这时候设备延迟15s 会再给你发送 然后你再发送一个 这样设备每15s都会给你发送一个 如图3 设备已经变成了已连接
获取设备编号

设备连接到服务器以后,服务器首先下发获取设备编号命令,如果是内部设备,则会根据规则进行应答如下:
(下位机应答长度不准确 疑似去掉了帧头帧尾)
上位机发送:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 01 | 00 | FF |
下位机应答:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 14 | 01 | 33 31 30 32 35 31 31 32 34 30 30 33 | FF |
设备编号为纯数字组合,例如:310251124003,ASCII码编译后为33 31 30 32 35 31 31 32 34 30 30 33。
我在设备连接时候发起了一个发送设备编号的请求 代码如下 效果如图
打开指定箱门


上位机发送:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 02 | 01 | FF |
数据位说明:16进制,01至FF最多255个箱门
下位机应答:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 02 | 00(开门成功) 02(无此箱门) 20(通讯失败) | FF |
说明:
02:如果硬件端总共10个箱门,发送开11号箱门命令,则认为无此箱门号。
20:如果485通讯异常(级联线接触不良,锁板故障等)都会返回20
我依旧在连接时候发请求进行测试 效果看视频
这个代码有一个前提就是需要一个响应的常量类 代码如下
代码如下
查询指定箱门状态

上位机发送:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 03 | 01 | FF |
数据位说明:16进制,01至FF最多255个箱门
下位机应答:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 03 | 00(打开) 11(关闭) 02(无此箱门) 20(通讯失败) | FF |
数据位说明:
00/11:根据锁的类型(开门通/闭门通)刚好相反。
开门通:00打开,11关闭
闭门通:11打开,00关闭
02:如果硬件端总共10个箱门,发送开11号箱门命令,则认为无此箱门号。
20:如果485通讯异常(级联线接触不良,锁板故障等)都会返回20
代码如下 效果如图
设置信息

设置设备二维码【服务器->设备】
设备连接到服务器以后,服务器发送【获取设备编号】命令后,下发【设置二维码命令】,设备接收到命令后,立即更新显示的二维码内容。
(数据内容为二维码的访问地址,并非二维码的图片地址)
例1:
上位机发送:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 2B | 07 | 68 74 74 70 73 3A 2F 2F 77 77 77 2E 62 61 69 64 75 2E 63 6F 6D 2F 6F 70 65 6E 2F 33 31 30 32 35 31 31 32 34 30 30 33 | FF |
数据位说明:如:
https://www.baidu.com/open/310251124003
ASCII码编译后为:
68 74 74 70 73 3A 2F 2F 77 77 77 2E 62 61 69 64 75 2E 63 6F 6D 2F 6F 70 65 6E 2F 33 31 30 32 35 31 31 32 34 30 30 33
下位机应答:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 07 | 00(设置成功) 01(设置失败) | FF |
设置广告【服务器->设备】
服务器根据业务逻辑,需要更新广告的时候下发指令,设备主动下载视频文件,并保存至本地。
例1:
上位机发送:
帧头 | 长度 | 命令码 | 息屏时间 | 数据 | 帧尾 |
EF | 23 | 09 | 0A | 68 74 74 70 73 3A 2F 2F 78 69 6E 6C 69 61 6E 73 6D 61 72 74 2E 63 6F 6D 2F 72 65 6E 74 61 6C 31 2E 6D 70 34 | FF |
( 可以理解为数据位的第0位为熄屏时间 byte[0] )
息屏时间说明:单位秒:78即120秒屏幕无触摸,则自动播放广告;
熄屏时间设置为0 即为永不熄屏(视频地址需要传输正常的)
例如 EF 06 09 00 68 74 74 70 73 3A 2F 2F 78 69 6E 6C 69 61 6E 73 6D 61 72 74 2E 63 6F 6D 2F 72 65 6E 74 61 6C 31 2E 6D 70 34 FF
数据位说明:如:
https://xinliansmart.com/rental1.mp4
ASCII码编译后为:
68 74 74 70 73 3A 2F 2F 78 69 6E 6C 69 61 6E 73 6D 61 72 74 2E 63 6F 6D 2F 72 65 6E 74 61 6C 31 2E 6D 70 34
下位机应答:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 09 | 00(设置成功) 01(设置失败) | FF |
设置背景图片【服务器->设备】
服务器根据业务逻辑,需要更换背景的时候下发指令,设备主动下载图片文件,并保存至本地。
例1:
上位机发送:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 23 | 0A | 68 74 74 70 73 3A 2F 2F 78 69 6E 6C 69 61 6E 73 6D 61 72 74 2E 63 6F 6D 2F 62 67 32 2E 70 6E 67 | FF |
数据位说明:如:
https://xinliansmart.com/bg2.png
ASCII码编译后为:
68 74 74 70 73 3A 2F 2F 78 69 6E 6C 69 61 6E 73 6D 61 72 74 2E 63 6F 6D 2F 62 67 32 2E 70 6E 67
下位机应答:
帧头 | 长度 | 命令码 | 数据 | 帧尾 |
EF | 05 | 0A | 00(设置成功) 01(设置失败) | FF |
完整代码如下
0
0
0
qq空间
微博
复制链接
分享
0