之前模拟了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);
    }

