modbus协议分为基于tcp/ip的modbus tcp和和基于RS485接口的modbus rtu两种通信方式。
modbus方式虚拟设备部署测试
如下:参阅:https://docs.edgexfoundry.org/1.2/examples/Ch-ExamplesAddingModbusDevice/
1. 首先登录控制台edgex-ui-go页面,导入device profile文件,和mqtt导入相同。文件名为modbus.device.profile.yml。内容如下:
name: "Network Power Meter" manufacturer: "Dent Instruments" model: "PS3037" description: "Power Scout Meter" labels: - "modbus" - "powerscout" deviceResources: - name: "Current" description: "Average current of all phases" attributes: { primaryTable: "HOLDING_REGISTERS", startingAddress: "9" } properties: value: { type: "UINT16", scale: "1"} units: { type: "String", readWrite: "R", defaultValue: "min"} - name: "Energy" description: "System Total True Energy" attributes: { primaryTable: "HOLDING_REGISTERS", startingAddress: "4001" } properties: value: { type: "FLOAT32", scale: "1"} units: { type: "String", readWrite: "R", defaultValue: "min"} - name: "Power" description: "System Total True Power " attributes: { primaryTable: "HOLDING_REGISTERS", startingAddress: "4003" } properties: value: { type: "UINT16", scale: "1"} units: { type: "String", readWrite: "R", defaultValue: "min"} - name: "Voltage" description: "Voltage Line to line (Volts) Average" attributes: { primaryTable: "HOLDING_REGISTERS", startingAddress: "4017" } properties: value: { type: "UINT16", scale: "1"} units: { type: "String", readWrite: "R", defaultValue: "min"} - name: "DemandWindowSize" description: "Demand window size in minutes; default is 15 min" attributes: { primaryTable: "HOLDING_REGISTERS", startingAddress: "4603" } properties: value: { type: "UINT16", readWrite: "R", scale: "1"} units: { type: "String", readWrite: "R", defaultValue: "min"} - name: "LineFrequency" description: "Line frequency setting for metering: 50=50 Hz, 60=60Hz" attributes: { primaryTable: "HOLDING_REGISTERS", startingAddress: "4609" } properties: value: { type: "UINT16", readWrite: "R", scale: "1"} units: { type: "String", readWrite: "R", defaultValue: "Hz"} deviceCommands: - name: "Current" get: - { index: "1", operation: "get", deviceResource: "Current" } - name: "Values" get: - { index: "1", operation: "get", deviceResource: "Energy" } - { index: "2", operation: "get", deviceResource: "Power" } - { index: "3", operation: "get", deviceResource: "Voltage" } - name: "Configuration" set: - { index: "1", operation: "set", deviceResource: "DemandWindowSize" } - { index: "2", operation: "set", deviceResource: "LineFrequency" } get: - { index: "1", operation: "get", deviceResource: "DemandWindowSize" } - { index: "2", operation: "get", deviceResource: "LineFrequency" } coreCommands: - name: "Current" get: path: "/api/v1/device/{deviceId}/Current" responses: - code: "200" description: "Get the Current" expectedValues: ["Current"] - code: "500" description: "internal server error" expectedValues: [] - name: "Values" get: path: "/api/v1/device/{deviceId}/Values" responses: - code: "200" description: "Get the Values" expectedValues: ["Energy","Power","Voltage"] - code: "500" description: "internal server error" expectedValues: [] - name: "Configuration" get: path: "/api/v1/device/{deviceId}/Configuration" responses: - code: "200" description: "Get the Configuration" expectedValues: ["DemandWindowSize","LineFrequency"] - code: "500" description: "internal server error" expectedValues: [] put: path: "/api/v1/device/{deviceId}/Configuration" parameterNames: ["DemandWindowSize","LineFrequency"] responses: - code: "204" description: "Set the Configuration" expectedValues: [] - code: "500" description: "internal server error" expectedValues: []
对要读取的modbus地址和存储的数据类型需要在profile中进行编辑。
2 修改modbus服务端的容器编排文件docker-compose.yml,将以下代码解注释:
然后重新启动:docker-compose up -d。
# device-modbus: # image: edgexfoundry/docker-device-modbus-go:1.2.1 # ports: # - "127.0.0.1:49991:49991" # container_name: edgex-device-modbus # hostname: edgex-device-modbus # networks: # - edgex-network # environment: # <<: *common-variables # Service_Host: edgex-device-modbus # depends_on: # - data # - command
3.和MQTT方式相同,在服务下添加设备,配置地址和端口,获得最终的控制台界面:
4.配置虚拟modebus设备。下载软件中的jar包,打开,点击Add,为方便测试,默认全选即可,其他不需要配置。然后点击Run。
http://modbuspal.sourceforge.net/
5.在控制台点击Send,获取结果,观察结果。另外,其中的Float32的Base64编码结果测试结果如下:
原始结果先解码,然后将byte数组所有表示为16进制,变成4个字节。其中高位两个字节表示为读取单位的值(INT),最大到0x7F7F,低位两个字节表示为读取位置的下一个位置的值。
当值超出范围或者仿真设置不正确时,Send返回结果会报错。
附上Python解码Base64并全体16进制显示的脚本:
import base64 bytes = base64.b64decode("f38AAA==") l = [hex(int(i)) for i in bytes] print(" ".join(l))