之前模拟了Modbus设备的数据采集,这次来模拟下Modbus下的RPC请求。
1.模拟一个空调设备,采用ModbusTCP
使用ModbusSlave模拟设备,设备地址1,分配4个寄存器:
- 寄存器1:模式
- 寄存器2:开关状态
- 寄存器3,4:温度(这里用2个寄存器存浮点型数据)
网关配置文件:
{
"server": {
"type": "tcp",
"host": "10.49.0.66",
"port": 502,
"timeout": 35,
"method": "socket",
"byteOrder": "BIG",
"devices": [
{
"unitId": 1,
"deviceName": "CountSensor",
"attributesPollPeriod": 5000,
"timeseriesPollPeriod": 5000,
"sendDataOnlyOnChange": true,
"timeseries": [
{
"byteOrder": "BIG",
"tag": "count",
"type": "16int",
"functionCode": 3,
"objectsCount": 1,
"address": 0
},
{
"byteOrder": "BIG",
"tag": "status",
"type": "16int",
"functionCode": 3,
"objectsCount": 1,
"address": 1
},
{
"byteOrder": "BIG",
"tag": "temperature",
"type": "32float",
"functionCode": 3,
"objectsCount": 2,
"address": 2
}
],
"rpc": [
{
"tag": "setValue",
"type": "16int",
"functionCode": 6,
"objectsCount": 1,
"address": 1
},
{
"tag": "getValue",
"type": "16int",
"functionCode": 3,
"objectsCount": 1,
"address": 1
},
{
"tag": "setTemperature",
"type": "32float",
"functionCode": 6,
"objectsCount": 2,
"address": 2
},
{
"tag": "getTemperature",
"type": "32float",
"functionCode": 3,
"objectsCount": 2,
"address": 2
}
]
}
]
}
}
2.打开ModbusSlave的Connection,启动网关
可以看到设备数据已经上来:
3.创建仪表盘
先新建一个实体设备,指向CountSensor。添加开关控件及数值控件。
注意控件中的高级设置,Rpc get value method,Rpc set value method的值要与网关中rpc配置方法名一致。
整个仪表盘如下图:
4.控制模拟
点击开关控制Round Switch,可看到仪表盘状态值的改变
控制温度,发现没有效果,查看网关日志,发现如下错误:
""2020-06-19 10:15:09" - ERROR - [modbus_connector.py] - modbus_connector - 290 - required argument is not a float" Traceback (most recent call last): File "D:\ProgramFilesData\Motrix\thingsboard-gateway-2.3.1.1\thingsboard_gateway\connectors\modbus\modbus_connector.py", line 278, in server_side_rpc_handler self.__process_rpc_request(content, rpc_command_config) File "D:\ProgramFilesData\Motrix\thingsboard-gateway-2.3.1.1\thingsboard_gateway\connectors\modbus\modbus_connector.py", line 298, in __process_rpc_request rpc_command_config["payload"] = self.__devices[content["device"]]["downlink_converter"].convert( File "D:\ProgramFilesData\Motrix\thingsboard-gateway-2.3.1.1\thingsboard_gateway\connectors\modbus\bytes_modbus_downlink_converter.py", line 75, in convert builder_functions[lower_type](value) File "D:\ProgramFiles\Python\Python38\lib\site-packages\pymodbus\payload.py", line 251, in add_32bit_float p_string = self._pack_words(fstring, value) File "D:\ProgramFiles\Python\Python38\lib\site-packages\pymodbus\payload.py", line 79, in _pack_words value = pack("!{}".format(fstring), value) struct.error: required argument is not a float
报错说传入的参数不是一个float值,于是我重新控制,在网关中断点看到了传入的参数是一个str:
应该是上层的问题,于是查看下控制请求的参数,发现传参时就是个str:
找到问题那就好改了,在knob.directive.js中将控件值转成float:
function turn(ratio) {
var value = (vm.minValue + (vm.maxValue - vm.minValue)*ratio).toFixed(vm.ctx.decimals);
if (canvasBar.value != value) {
canvasBar.value = value;
}
updateColor(canvasBar.getValueColor());
value = parseFloat(value);
onValue(value);
}