工具包引入
1 2 3 4 5
| <dependency> <groupId>cn.allbs</groupId> <artifactId>allbs-model</artifactId> <version>0.6.0</version> </dependency>
|
引用站外地址
解析&生成过程中自定义参数说明
应用场景 |
参数值 |
参数说明 |
指令生成 |
GeneratorEnum .ADDRESS .name |
从站地址 |
指令生成 |
GeneratorEnum .FUNCTION .name |
功能码 |
指令生成 |
GeneratorEnum .START_ADDRESS .name |
起始寄存器地址 |
指令生成 |
GeneratorEnum .READ_ADDRESS .name |
读寄存器地址 |
协议解析 |
data |
数据信息 |
协议解析 |
circuit |
回路 |
协议解析 |
point |
点数 |
协议解析 |
gas_type |
点位属性 |
协议解析 |
pre_gas_type |
点位属性原始值 |
协议解析 |
gas_unit |
气体单位 |
协议解析 |
pre_gas_unit |
气体单位原始值 |
协议解析 |
gas_num |
气体监测值 |
协议解析 |
detector_status |
探测器状态 |
协议解析 |
pre_detector_status |
探测器状态原始值 |
协议解析 |
detector_num |
探测器浓度值 |
协议解析 |
extra_power |
外控电源状态 |
协议解析 |
pre_extra_power |
外控电源状态原始值 |
协议解析 |
address |
地址 |
协议解析 |
function |
功能 |
协议解析 |
controller_status |
控制器状态 |
协议解析 |
pre_controller_status |
控制器状态原始值 |
生成示例
代码
1 2 3 4 5 6 7 8 9 10 11
| Map<String, Object> map = new HashMap<>(4);
map.put(ADDRESS.getName(), 1);
map.put(FUNCTION.getName(), 3);
map.put(START_ADDRESS.getName(), 0);
map.put(READ_ADDRESS.getName(), 2); SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); byte[] bytes = sfjk200Mapper.writeDataAsByteArray(map);
|
结果
解析示例
读取 SFJK-200 控制器配置点数( 未配置点数时,返回回路 x 的值为 0x00 )所有请求数据 及响应数据均以 16 进制数据进行交换
1 2 3 4 5 6 7 8 9 10 11 12
| byte[] bytes = new byte[9]; bytes[0] = 0x01; bytes[1] = 0x03; bytes[2] = 0x04; bytes[3] = 0x3F; bytes[4] = 0x00; bytes[5] = 0x00; bytes[6] = 0x00; bytes[7] = (byte) 0xf6; bytes[8] = 0x27; SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); System.out.println(sfjk200Mapper.readValue(bytes, 0x0000, Map.class));
|
读取探测器属性及单位 ( 读取 1 回路 1 号点探测的浓度及属性,根据寄存器地址映射表查 到,1 号探测器对应寄存器地址为 0002H )数据高字节代表单位,低字节代表属性。
1 2 3 4 5 6 7 8 9 10
| byte[] bytes = new byte[9]; bytes[0] = 0x01; bytes[1] = 0x03; bytes[2] = 0x02; bytes[3] = 0x01; bytes[4] = 0x0A; bytes[5] = (byte) 0x39; bytes[6] = (byte) 0xD3; SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); System.out.println(sfjk200Mapper.readValue(bytes, 0x0002, Map.class));
|
连续读取 1 回路 3、4、5、6 号探测器属性及单位。(根据寄存器地址映射表查到 3 号探测 器从 0004H 地址开始 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| byte[] bytes = new byte[13]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03; bytes[2] = (byte) 0x08; bytes[3] = (byte) 0x01; bytes[4] = (byte) 0x0A; bytes[5] = (byte) 0x01; bytes[6] = (byte) 0x0D; bytes[7] = (byte) 0x00; bytes[8] = (byte) 0x81;
bytes[9] = (byte) 0x02; bytes[10] = (byte) 0x82; bytes[11] = (byte) 0x03; bytes[12] = (byte) 0x22; SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x0004, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
读取 1 回路 1 号探测器的低限报警值( 假设 1 号探测器属性为甲烷,单位为%LEL.根据寄存 器地址映射表查到,1 号探测器对应寄存器地址为 03E2H)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| byte[] bytes = new byte[7]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03;
bytes[2] = (byte) 0x02; bytes[3] = (byte) 0x00; bytes[4] = (byte) 0xFA; bytes[5] = (byte) 0x38; bytes[6] = (byte) 0x07; SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x03E2, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
** 注意:当前数据为全部除以10后的数据,因为解析和指令是分开的,所以需要根据指定中指定气体单位判断返回结果需不需要乘以10 **
读取 1 回路 3、4、5、6 号探测器的低限报警值(3 号点属性为天然气,单位为%LEL .4 号 点为甲烷,单位为%LEL .5 号点属性为一氧化碳,单位为 μmol/mol,6 号点为氧气,单位为%V/V) 根据寄存器地址映射表查到,3 号探测器对应寄存器地址为 03E4H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| byte[] bytes = new byte[13]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03; bytes[2] = (byte) 0x08;
bytes[3] = (byte) 0x00; bytes[4] = (byte) 0x64; bytes[5] = (byte) 0x00; bytes[6] = (byte) 0x96; bytes[7] = (byte) 0x00; bytes[8] = (byte) 0x78;
bytes[9] = (byte) 0x00; bytes[10] = (byte) 0xBD; bytes[11] = (byte) 0xB8; bytes[12] = (byte) 0x64; SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x03E4, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
** 注意:当前数据为全部除以10后的数据,因为解析和指令是分开的,所以需要根据指定中指定气体单位判断返回结果需不需要乘以10 **
读取单个探测器状态(状态参考探测器状态定义)根据寄存器地址映射表查到,1 号探测器 对应寄存器地址为 07C2H
示例
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| byte[] bytes = new byte[7]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03; bytes[2] = (byte) 0x02;
bytes[3] = (byte) 0x00; bytes[4] = (byte) 0x01; bytes[5] = (byte) 0x79; bytes[6] = (byte) 0x8E; SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x07C2, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
输出
** 示例CRC存在问题 **
读取 1 回路 3、4、5、6 号探测器的状态(根据寄存器地址映射表查到,3 号探测器对应寄 存器地址为 07C4H)
示例
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| byte[] bytes = new byte[13]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03; bytes[2] = (byte) 0x08;
bytes[3] = (byte) 0x00; bytes[4] = (byte) 0x01; bytes[5] = (byte) 0x00; bytes[6] = (byte) 0x03;
bytes[7] = (byte) 0x00; bytes[8] = (byte) 0x04; bytes[9] = (byte) 0x00; bytes[10] = (byte) 0x08; bytes[11] = (byte) 0x81; bytes[12] = (byte) 0x10; SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x07C4, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
输出
读取 1 回路 1 号点探测器的当前浓度值(根据寄存器地址映射表查到,1 号探测器对应寄存 器地址为 0BA2H )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| byte[] bytes = new byte[7]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03; bytes[2] = (byte) 0x02;
bytes[3] = (byte) 0x01; bytes[4] = (byte) 0x5A; bytes[5] = (byte) 0x39; bytes[6] = (byte) 0xEF;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x0BA2, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
** 注意:当前数据为全部除以10后的数据,因为解析和指令是分开的,所以需要根据指定中指定气体单位判断返回结果需不需要乘以10 **
读取 1 回路 3、4、5、6 号探测器的低限报警值(3 号点属性为天然气,单位为%LEL .4 号 点为甲烷,单位为%LEL .5 号点属性为一氧化碳,单位为 μmol/mol,6 号点为氧气,单位为%V/V) 根据寄存器地址映射表查到,3 号探测器对应寄存器地址为 0BA4H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| byte[] bytes = new byte[13]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03; bytes[2] = (byte) 0x08;
bytes[3] = (byte) 0x00; bytes[4] = (byte) 0x64; bytes[5] = (byte) 0x00; bytes[6] = (byte) 0x96;
bytes[7] = (byte) 0x01; bytes[8] = (byte) 0x40; bytes[9] = (byte) 0x00; bytes[10] = (byte) 0xD1; bytes[11] = (byte) 0x38; bytes[12] = (byte) 0x78;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x03E4, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
读取 SFJK-200 外控电源状态( 外控电源状态请参考外控电压状态定义表 ) 1 回路外控电源 对应寄存器地址为 0f82H )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| byte[] bytes = new byte[9]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03; bytes[2] = (byte) 0x04;
bytes[3] = (byte) 0x30; bytes[4] = (byte) 0x30; bytes[5] = (byte) 0x30; bytes[6] = (byte) 0x30;
bytes[7] = (byte) 0xE1; bytes[8] = (byte) 0x28;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x0F82, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
读取 SFJK-200 控制器状态(SFJK-200 控制器状态参考控制器状态定义表 ) 根据寄存器地 址映射表查到,对应寄存器地址为 0F8AH
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| byte[] bytes = new byte[7]; bytes[0] = (byte) 0x01; bytes[1] = (byte) 0x03; bytes[2] = (byte) 0x02;
bytes[3] = (byte) 0x00; bytes[4] = (byte) 0x01; bytes[5] = (byte) 0x79; bytes[6] = (byte) 0x8E;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper(); Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x0F8A, Map.class); map.forEach((k, v) -> { if (k.equals("data")) { List<Map<String, Object>> list = (List<Map<String, Object>>) v; list.forEach(System.out::println); } else { System.out.println(k + ":" + v); } });
|
** 示例中的CRC校验错误 **
模拟读写
使用工具modbus slave工具
保存至influxdb结果
下载modbus slave测试内容
Mbslave1.mbs
Mbslave2.mbs
Mbslave3.mbs
Mbslave4.mbs
Mbslave5.mbs
Mbslave6.mbs
Mbslave7.mbs
最后是使用的java开发的示例demo
引用站外地址