立即试用 商务报价
网关
文档 > 配置指南 > CAN

本页目录

CAN Connector Configuration

This guide will help you to get familiar with CAN connector configuration for ThingsBoard IoT Gateway.
Use general configuration to enable this connector.
We will describe connector configuration file below.


Example of CAN Connector config file. Press to expand.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
{
  "interface": "socketcan",
  "channel": "vcan0",
  "backend": {
    "fd": true
  },
  "reconnectPeriod": 5,
  "devices": [
    {
      "name": "Car",
      "sendDataOnlyOnChange": false,
      "enableUnknownRpc": true,
      "strictEval": false,
      "attributes": [
        {
          "key": "isDriverDoorOpened",
          "nodeId": 41,
          "command": "2:2:big:8717",
          "value": "4:1:int",
          "expression": "bool(value & 0b00000100)",
          "polling": {
            "type": "once",
            "dataInHex": "AB CD AB CD"
          }
        }
      ],
      "timeseries": [
        {
          "key": "rpm",
          "nodeId": 1918,
          "isExtendedId": true,
          "command": "2:2:big:48059",
          "value": "4:2:big:int",
          "expression": "value / 4",
          "polling": {
            "type": "always",
            "period": 5,
            "dataInHex": "aaaa bbbb aaaa bbbb"
          }
        },
        {
          "key": "milliage",
          "nodeId": 1918,
          "isExtendedId": true,
          "value": "4:2:little:int",
          "expression": "value * 10",
          "polling": {
            "type": "always",
            "period": 30,
            "dataInHex": "aa bb cc dd ee ff aa bb"
          }
        }
      ],
      "attributeUpdates": [
        {
          "attributeOnThingsBoard": "softwareVersion",
          "nodeId": 64,
          "isExtendedId": true,
          "dataLength": 4,
          "dataExpression": "value + 5",
          "dataByteorder": "little"
        }
      ],
      "serverSideRpc": [
        {
          "method": "sendSameData",
          "nodeId": 4,
          "isExtendedId": true,
          "isFd": true,
          "bitrateSwitch": true,
          "dataInHex": "aa bb cc dd ee ff    aa bb aa bb cc d ee ff"
        },
        {
          "method": "setLightLevel",
          "nodeId": 5,
          "dataLength": 2,
          "dataByteorder": "little",
          "dataBefore": "00AA"
        },
        {
          "method": "setSpeed",
          "nodeId": 16,
          "dataAfter": "0102",
          "dataExpression": "userSpeed if maxAllowedSpeed > userSpeed else maxAllowedSpeed"
        }
      ]
    }
  ]
}

Root section

The root part of the CAN connector configuration provides basic information to connect/reconnect to a CAN bus and the list of device configurations.

参数 Default value 描述
name CAN Connector Name of connector.
interface socketcan Type of CAN interface.
channel vcan0 Channel name of CAN interface.
backend   Interface specific configuration.
reconnect true Whether to reconnect after bus error while sending/receiving CAN messages.
reconnectPeriod 30.0 Period in seconds between reconnect attempts. Floating point means more precise time than seconds.
reconnectCount   Number of reconnect attempts after bus error. If not specified means infinite number of attempts.
devices   List of devices.

The list of supported CAN interfaces one can find in the documentation of the Python CAN library.

Section “backend”

This section is optional and it provides configuration for specific CAN interface. Each option has default value. To get available list of options see the documentation for specific interface type.

For example, the SocketCAN interface supports the following configuration options:

  • receive_own_messages
  • fd
  • can_filters ё
    1
    2
    3
    4
    
    "backend": {
    "receive_own_messages": true,
    "fd": true
    }
    

    This means that transmitted messages should also be received and CAN-FD frames should be supported. By default these options are disabled.

Section “devices”

This section provides array of configurations for devices, which connected through the CAN bus.

参数 Default value 描述
name   Name of device.
type can Type of device.
sendDataOnlyOnChange false Sending only if data changed from last check, if not specified data will send after each received CAN message.
strictEval true Restricted mode of Python eval() API.
enableUnknownRpc false Allow processing RPC commands not listed in serverSideRpc subsection.
overrideRpcConfig false Allow overriding RPC command configuration (all or some of options) by data received from server.
converters   Custom converters.
attributes   List of device attributes.
timeseries   List of time series keys.
attributeUpdates   List of shared attributes to be subscribed for.
serverSideRpc   List of RPC commands.

If enableUnknownRpc is set to true, overrideRpcConfig is forcibly set to true as well.

Note, despite attributes, timeseries, attributeUpdates and serverSideRpc are optional subsections, at least one of them must be set to get in use the device configuration.

Subsection “converters”

CAN connector is provided with built-in uplink/downlink data converters. One can specify custom converter for both uplink and downlink data or for one of them.

参数 Default value 描述
uplink   Python class of uplink converter.
downlink   Python class of downlink converter.

As input data the uplink converter gets CAN payload (array of bytes) and list of configurations from “attributes” and “timeseries” subsection to know which bytes to get and how they need to be interpreted.

As output data the uplink converter returns dictionary with attribute and telemetry lists. Each element of this list is key/value pair, where key is attribute name or time series key and the value is what it is.

1
2
3
4
{
  "attributes": [{"isDriverDoorOpened": "true"}],
  "telemetry": [{"rpm":100},{"milliage": 300000}]
}

As input data the downlink converter gets the value (or values in case of RPC) and configuration (from “attributeUpdates” or “serverSideRpc” subsections) that describes how to convert the value (or values) to CAN payload.

As output data the downlink converter returns CAN payload (array of bytes) for the further sending.

Subsection “attributes” or “timeseries”

This subsection provides the list of configuration each of them describes which bytes to get from CAN payload (array of bytes) and how to convert these bytes to a Thingsboard attribute or a time series key.

参数 Default value 描述
key   Name of attribute or time series key.
nodeId   CAN node (arbitration) id.
value   Value conversion configuration.
expression   Python eval() expression to modify value in some way.
command   Command conversion configuration.
polling   Polling configuration.
isExtendedId false If True means extended CAN node (arbitration) id.
isFd false If True means using CAN FD mode.
bitrateSwitch false Only for CAN FD mode If True means a higher bitrate is used for the data transmission.
“commmand”

The option command is an additional but non-neccessary level of abstraction what lets one to interpret the one part of CAN message differently based on the another part of this CAN message.

For example, the controller of an irrigation system can inform about different parameters of the system. Communication is done via CAN bus.
The first byte of a CAN payload is command. If the value of a command is 2, it means that following bytes is temperature.
If value of command is 4, data is a humidity level.

The option command supports the following formats:

  • As JSON string:
    1
    
    command: "<start>:<length>:[byteorder]:[value]"
    
  • As JSON object:
    1
    2
    3
    4
    5
    6
    
    "command": {
      "start": <start_value>,
      "length": <length_value>,
      "byteorder": <byteorder_value>,
      "value": <value>
    }
    

where:

  • start - the position of the first byte - 0 to 7 for CAN protocol, 0 to 63 for CAN FD protocol
  • length - the number of bytes to get the value of a command
  • byteorder - the order of bytes - big or little (default big)
  • value - the integer value of a command in the decimal format

Example:

  1. Read 2 bytes starting from 0th position as the little byte ordered and trigger processing of the following bytes only if the command value is 12345.
    1
    
    "command": "0:2:little:12345"
    
“value”

The option value describes how many bytes to get from CAN payload and what primitive type to be converted to.

The option value supports the following formats:

  • As JSON string:
    1
    
    "value": "<start>:<length>:[byteorder]:<type>:[encoding|signed]"
    
  • As JSON object:
    1
    2
    3
    4
    5
    6
    7
    8
    
    "value": {
      "start": <start_value>,
      "length": <length_value>,
      "byteorder": <byteorder_value>,
      "type": <type_value>,
      "encoding": <encoding_value>,
      "signed": <signed_value>
    }
    

where

  • start - the position of the first byte - 0-7 for CAN protocol, 0-63 for CAN FD protocol
  • length - the number of bytes to get the value
  • byteorder - the order of bytes - big or little (default big)
  • type - the Python primitive types bool, boolean, int, long, float, double or string. By types bool, int and float it is meant Thingsboard boolean, long and double types respectively. Note, float type value requires 4 bytes and double type value requires 8 bytes.
  • encoding - Only for string type Encoding of string (default ascii).
  • signed - Only for int/long types indicates whether integer is signed value or not - signed or unsigned (default unsigned)

Examples:

  • Read 1 byte starting from 2d position as the big byte ordered and cast to the value of the unsigned int type.
    1
    
    "value": "2:1:int" 
    
  • Read 8 bytes starting from 0th position as the big byte ordered and cast to the value of the double type.
    1
    
    "value": "0:7:double"
    
  • Read 4 bytes starting from 0th position as the little byte ordered and cast to the value of the float type.
    1
    
    "value": "0:4:little:float"
    
  • Read 2 bytes starting from 4th position as the little byte ordered and cast to the value the signed int type. The value is used in Python eval() expression to get the final value.
    1
    2
    
    "value": "4:2:little:int:signed",
    "expression": "value / 4"
    
“expression”

The option expression is evaluated via Python eval() API. There are available the following variables in the eval() context:

  1. value - the result of applying the value configuration to the CAN payload
  2. can_data - the CAN payload (array of bytes)

Note, by default Python eval() API is working in some kind of a restricted mode by denying the explicit access to __builtins__ API, to disable the restricted mode set the option strictEval to False.

“polling”

If a polling configuration is not specified the CAN connector receive only that data what CAN node decides to send on its own.

On demand sending activates after CAN node receives specific data which is specified in the polling configuration. Depending on the type of polling the CAN connector can send that data once or periodically.

参数 Default value 描述
type always Type always means sending CAN message periodically, once means single time sending.
period 1.0 Period of polling in seconds. Floating point means more precise time than seconds.
dataInHex   CAN message payload in the hexadecimal format.

Subsection “attributeUpdates”

This subsection provides the list of configurations to subscribe for changes of Thingsboard shared attributes.

参数 Default value 描述
attribute   Name of shared attribute.
nodeId   CAN node (arbitration) id.
isExtendedId false If True means extended CAN node (arbitration) id.
isFd false If True means using CAN FD mode.
bitrateSwitch false Only for CAN FD mode If True means a higher bitrate is used for the data transmission.
dataLength 1 Only for integer values Number of bytes to pack integer value.
dataByteorder big Only for integer and float values Order of bytes to pack numeric value.
dataSigned false Only for int/long types indicates whether integer is signed value or not.
dataExpression   Python eval() expression to modify attribute value in some way before packing it to array of bytes.
dataEncoding ascii Only for string values Encoding of string packing.
dataBefore   Hexadecimal string of bytes that are preceded value bytes.
dataAfter   Hexadecimal string of bytes that are followed by value bytes.

The steps of processing an attribute update are the following:

  1. If dataExpression is set, the value that received from Thingsboard server is modified via Python eval() API. The variable value is available in dataExpression. This is a value of the attribute that was changed. If dataExpression is not set, the value is left as it is.
  2. The value from the step 1 is packed to the array of bytes based on its type (deduced by Python isinstance() API) and configuration provided for this attribute. Note, float type value requires 4 bytes.
  3. If dataBefore or/and dataAfter are set, they are converted to the arrays of bytes and are added to the value bytes (from the step 2) before and after respectively.
  4. Send the final byte array through a CAN bus.

Subsection “serverSideRpc”

This subsection provides the list of configurations to process RPC commands from a ThingsBoard server to a device.

参数 Default value 描述
method   Name of RPC command.
response false If true, response will be sent to ThingsBoard.
nodeId   CAN node (arbitration) id.
isExtendedId false If True means extended CAN node (arbitration) id.
isFd false If True means using CAN FD mode.
bitrateSwitch false Only for CAN FD mode If True means a higher bitrate is used for the data transmission.
dataLength 1 Only for integer values Number of bytes to pack integer value.
dataByteorder big Only for integer and float values Order of bytes to pack numeric value.
dataSigned false Only for int/long types indicates whether integer is signed value or not.
dataExpression   Python eval() expression to modify attribute value in some way before packing it to array of bytes.
dataEncoding ascii Only for string values Encoding of string packing.
dataBefore   Hexadecimal string of bytes that are preceded value bytes.
dataAfter   Hexadecimal string of bytes that are followed by value bytes.
dataInHex   Only for RPC without parameters Hexadecimal string of bytes that are sent to CAN node.

The CAN connector supports RPC commands without and with parameters (see params JSON object).

The without parameters RPC type requires only dataInHex to be set (another data* options are not used). The value of dataInHex is sent as payload of a CAN message each time when the RPC command is processed.

The with parameters RPC type is based on all data* options except dataInHex. The steps of processing are the same as for attribute updates except:

  • if dataExpression is not set, RPC params must have the JSON property named value. The value of this JSON property is packed to the array of bytes and send to CAN node as payload of a CAN message.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    {
    "device": "Car", 
    "data": {
      "method": "setLightLevel", 
      "params": {
        "value": 70
      }
    }
    }
    
  • if dataExpression is set, no specific JSON property is required and all RPC params are available in dataExpression.


    For example, user want to pick up a car speed to 150 mph, but a car control system has its own limit that is set to 100 mph.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    {
    "device": "Car", 
    "data": {
      "id": 1,
      "method": "setSpeed", 
      "params": {
        "userSpeed": 150,
        "maxAllowedSpeed": 100
      }
    }
    }
    

    The configuration of such RPC command is set in the way whether user exceeds the limit the speed of a car is forcibly set to this limit:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    "serverSideRpc": [
    {
      "method": "setSpeed",
      "nodeId": 16,
      "dataBefore": "09",
      "dataAfter": "aabb",
      "dataExpression": "userSpeed if maxAllowedSpeed > userSpeed else maxAllowedSpeed"
    }
    ]
    

    So after processing the setSpeed RPC command CAN payload is following: [ 0x09, 0x64, 0xAA, 0xBB ], where 0x64 is 100 mph because user exceeds the limit.

Next steps

Explore guides related to main ThingsBoard features: