Try   HackMD

Getting started with ThingsBoard IoT Gateway

What is Thingsboard IoT Gateway?

  • Devices > - modbus - > converter / connector >

Installation

Docker + Linux

Prerequisites: docker ce + docker-compose

Docker basics

  1. How to Do a Clean Restart of a Docker Instance details
    • Stop the container(s) using the following command: docker-compose down
    • Delete all containers using the following command: docker rm -f $(docker ps -a -q)
    • Delete all volumes using the following command: docker volume rm $(docker volume ls -q) Note: Deleting volumes will wipe out their data. Back up any data that you need before deleting a container.
    • Restart the containers using the following command: docker-compose up -d

docker-compose.yml (template here)

version: '3.0'
services:
  gw:
    restart: always
    image: "thingsboard/tb-gateway"
    # Ports (Required for REST connector)
    ports:
      - "5000:5000"
    volumes:
      - ~/.tb-gateway/config:/thingsboard_gateway/config
      - ~/.tb-gateway/logs:/thingsboard_gateway/logs
      - ~/.tb-gateway/extensions:/thingsboard_gateway/extensions
    devices:
      - "/dev/ttyS0:/dev/ttyS0"
  1. working directory with the file "docker-compose.yml": cd ~/workspace/tb
  2. docker-compose up -d
  3. docker-compose logs --tail 10
  4. star@gateway:~/workspace/tb$ docker exec -it tb-gw-1 bash
root@06154190eb83:/#  pip3 install redis
Collecting redis
  Downloading redis-4.4.2-py3-none-any.whl (237 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 237.8/237.8 kB 1.5 MB/s eta 0:00:00
Collecting async-timeout>=4.0.2
  Downloading async_timeout-4.0.2-py3-none-any.whl (5.8 kB)
Installing collected packages: async-timeout, redis
Successfully installed async-timeout-4.0.2 redis-4.4.2
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

[notice] A new release of pip available: 22.3 -> 23.0
[notice] To update, run: python3 -m pip install --upgrade pip

root@06154190eb83:/#  pip3 install sqlalchemy
Collecting sqlalchemy
  Downloading SQLAlchemy-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.7 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.7/2.7 MB 3.1 MB/s eta 0:00:00
Collecting greenlet!=0.4.17
  Downloading greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (613 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 613.7/613.7 kB 4.0 MB/s eta 0:00:00
Requirement already satisfied: typing-extensions>=4.2.0 in /root/.local/lib/python3.10/site-packages (from sqlalchemy) (4.4.0)
Installing collected packages: greenlet, sqlalchemy
Successfully installed greenlet-2.0.2 sqlalchemy-2.0.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

[notice] A new release of pip available: 22.3 -> 23.0
[notice] To update, run: python3 -m pip install --upgrade pip

console error

tb-gw-1  | ""2023-01-31 04:50:23" - |ERROR| - [modbus_connector.py] - modbus_connector - __process_slaves - 342 - int() argument must be a string, a bytes-like object or a real number, not 'NoneType'"
tb-gw-1  | Traceback (most recent call last):
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 311, in __process_slaves
tb-gw-1  |     self.__connect_to_current_master(device)
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 357, in __connect_to_current_master
tb-gw-1  |     device.config['master'], device.config['available_functions'] = self.__configure_master(device.config)
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 419, in __configure_master
tb-gw-1  |     master = ModbusSerialClient(method=current_config["method"],
tb-gw-1  |   File "/root/.local/lib/python3.10/site-packages/pymodbus/client/serial.py", line 196, in __init__
tb-gw-1  |     super().__init__(framer=framer, **kwargs)
tb-gw-1  |   File "/root/.local/lib/python3.10/site-packages/pymodbus/client/base.py", line 120, in __init__
tb-gw-1  |     self.params.retries = int(retries)
tb-gw-1  | TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
tb-gw-1  | ""2023-01-31 04:50:28" - |ERROR| - [modbus_connector.py] - modbus_connector - __process_slaves - 342 - int() argument must be a string, a bytes-like object or a real number, not 'NoneType'"
tb-gw-1  | Traceback (most recent call last):
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 311, in __process_slaves
tb-gw-1  |     self.__connect_to_current_master(device)
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 357, in __connect_to_current_master
tb-gw-1  |     device.config['master'], device.config['available_functions'] = self.__configure_master(device.config)
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 419, in __configure_master
tb-gw-1  |     master = ModbusSerialClient(method=current_config["method"],
tb-gw-1  |   File "/root/.local/lib/python3.10/site-packages/pymodbus/client/serial.py", line 196, in __init__
tb-gw-1  |     super().__init__(framer=framer, **kwargs)
tb-gw-1  |   File "/root/.local/lib/python3.10/site-packages/pymodbus/client/base.py", line 120, in __init__
tb-gw-1  |     self.params.retries = int(retries)
tb-gw-1  | TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
tb-gw-1  | ""2023-01-31 04:50:33" - |ERROR| - [modbus_connector.py] - modbus_connector - __process_slaves - 342 - int() argument must be a string, a bytes-like object or a real number, not 'NoneType'"
tb-gw-1  | Traceback (most recent call last):
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 311, in __process_slaves
tb-gw-1  |     self.__connect_to_current_master(device)
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 357, in __connect_to_current_master
tb-gw-1  |     device.config['master'], device.config['available_functions'] = self.__configure_master(device.config)
tb-gw-1  |   File "/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 419, in __configure_master
tb-gw-1  |     master = ModbusSerialClient(method=current_config["method"],
tb-gw-1  |   File "/root/.local/lib/python3.10/site-packages/pymodbus/client/serial.py", line 196, in __init__
tb-gw-1  |     super().__init__(framer=framer, **kwargs)
tb-gw-1  |   File "/root/.local/lib/python3.10/site-packages/pymodbus/client/base.py", line 120, in __init__
tb-gw-1  |     self.params.retries = int(retries)
tb-gw-1  | TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
root@06154190eb83:/# pip3 install protobuf --upgrade
Requirement already satisfied: protobuf in /usr/local/lib/python3.10/site-packages (3.20.0)
Collecting protobuf
  Downloading protobuf-4.21.12-cp37-abi3-manylinux2014_x86_64.whl (409 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 409.8/409.8 kB 2.1 MB/s eta 0:00:00
Installing collected packages: protobuf
  Attempting uninstall: protobuf
    Found existing installation: protobuf 3.20.0
    Uninstalling protobuf-3.20.0:
      Successfully uninstalled protobuf-3.20.0
Successfully installed protobuf-4.21.12
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

[notice] A new release of pip available: 22.3 -> 23.0
[notice] To update, run: python3 -m pip install --upgrade pip

try to make freeze and see that versions of libs

root@e65a1a2bd181:/# pip3 freeze

Ubuntu 20 / Debian 11

  • (optional but recommended) sudo apt update

1. Download the deb file (/home/swae/workspace/tb-gw)

wget https://github.com/thingsboard/thingsboard-gateway/releases/latest/download/python3-thingsboard-gateway.deb

2. Install the gateway using apt

sudo apt install ./python3-thingsboard-gateway.deb -y

3. Check gateway status

sudo systemctl status thingsboard-gateway
details
star@debian-vm:~/workspace/tb-gw$ sudo systemctl status thingsboard-gateway.service
● thingsboard-gateway.service - ThingsBoard Gateway
     Loaded: loaded (/etc/systemd/system/thingsboard-gateway.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-01-17 12:02:18 CST; 20min ago
   Main PID: 20949 (python3)
      Tasks: 10 (limit: 2341)
     Memory: 30.7M
        CPU: 5.435s
     CGroup: /system.slice/thingsboard-gateway.service
             └─20949 /usr/bin/python3 -c from thingsboard_gateway.tb_gateway import daemon; daemon()

Jan 17 12:02:19 debian-vm python3[20949]:   File "/var/lib/thingsboard_gateway/.local/lib/python3.9/site-packages/paho/mqtt/re>
Jan 17 12:02:19 debian-vm python3[20949]:     assert identifier in self.names.keys(), identifier
Jan 17 12:02:19 debian-vm python3[20949]: AssertionError: 5
Jan 17 12:02:19 debian-vm python3[20949]: ""2023-01-17 12:02:19" - |ERROR| - [tb_device_mqtt.py] - tb_device_mqtt - _on_connec>
Jan 17 12:02:19 debian-vm python3[20949]: ""2023-01-17 12:02:19" - |INFO| - [tb_updater.py] - tb_updater - check_for_new_versi>
Jan 17 12:02:19 debian-vm python3[20949]: ""2023-01-17 12:02:19" - |INFO| - [tb_updater.py] - tb_updater - check_for_new_versi>
Jan 17 12:02:19 debian-vm python3[20949]: [===UPDATE===]
Jan 17 12:02:19 debian-vm python3[20949]:  New version v3.2 is available!
Jan 17 12:02:19 debian-vm python3[20949]: [===UPDATE===]
Jan 17 12:02:19 debian-vm python3[20949]: "

(optional) 4. Hot Reloader

Enable hot reloader to restart Gateway every time when we edit any project file when using Gateway for development.

python3 ./thingsboard_gateway/tb_gateway.py true - source code
python3 /usr/lib/python3/dist-packages/thingsboard_gateway/tb_gateway.py true

Configuration

Directory structure

    • path: /etc/thingsboard-gateway/config/*
    • tb_gateway.yaml
      • modbus_serial.json

Disable Statistics

  • tb-

    • statistics.json - /usr/lib/python3/dist-packages/thingsboard_gateway/config/statistics.json

Custom

iAeris20 setting

gateway 讀取 iAeris register 的資料經由hex轉換成int時會以4位數呈現小數點後兩位,此呈現方式在顯示上並不符合閱讀邏輯。

暫時解決方案為在 bytes_modbus_uplink_converter.py 檔案中添加下方程式碼強制轉換,後續須考慮新方法以解決不同機型產生的數字所代表的含意。

star@gateway:~/workspace/tb$ docker exec -it tb-gw-1 bash
root@abfd2e6c9960:/# cd /thingsboard_gateway/connectors/modbus/

Edit bytes_modbus_uplink_converter.py (+line 83)

decoded_data=float(decoded_date)/100

p.s. docker在更新過後需重啟docker才能生效

Result:

before:
tb-gw-1 | ""2023-02-21 03:30:37" - |INFO| - [modbus_connector.py] - modbus_connector - run - 651 - {'deviceName': 'iAeris 20', 'deviceType': 'default', 'telemetry': [{'temperature': 2660}, {'humidity': 3590}], 'attributes': []}"

after:
tb-gw-1 | ""2023-02-21 06:41:00" - |INFO| - [modbus_connector.py] - modbus_connector - run - 651 - {'deviceName': 'iAeris 20', 'deviceType': 'default', 'telemetry': [{'temperature': 26.9}, {'humidity': 34.9}], 'attributes': []}"

Troubleshooting

sudo stty -a -F /dev/ttyS0

speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 0; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho
-extproc

connectors:
#  -
#   name: MQTT Broker Connector
#    type: mqtt
#    configuration: mqtt.json
#  -
#    name: Modbus Connector
#    type: modbus
#    configuration: modbus.json
#
   -
     name: Modbus Connector
     type: modbus
     configuration: modbus_serial.json
Jan 17 12:49:25 debian-vm python3[21319]:     from pymodbus.constants import Defaults
Jan 17 12:49:25 debian-vm python3[21319]: ModuleNotFoundError: No module named 'pymodbus'
Jan 17 12:49:25 debian-vm python3[21319]: Modbus library not found - installing...
Jan 17 12:49:25 debian-vm python3[21319]: ""2023-01-17 12:49:25" - |ERROR| - [tb_device_mqtt.py] - tb_device_mqtt - _on_connect - 223 - connection FAIL with>
Jan 17 12:49:25 debian-vm python3[21319]: ""2023-01-17 12:49:25" - |INFO| - [tb_updater.py] - tb_updater - check_for_new_version - 84 - v3.2"
Jan 17 12:49:25 debian-vm python3[21319]: ""2023-01-17 12:49:25" - |INFO| - [tb_updater.py] - tb_updater - check_for_new_version - 86 -

Jan 17 12:49:25 debian-vm python3[21319]: [===UPDATE===]
Jan 17 12:49:25 debian-vm python3[21319]:  New version v3.2 is available!
Jan 17 12:49:25 debian-vm python3[21319]: [===UPDATE===]
Jan 17 12:49:25 debian-vm python3[21319]: "
Jan 17 12:50:27 debian-vm python3[21326]: Collecting pymodbus>=3.0.0
Jan 17 12:50:42 debian-vm python3[21326]:   Downloading pymodbus-3.1.0-py2.py3-none-any.whl (163 kB)
Jan 17 12:50:43 debian-vm python3[21326]: Installing collected packages: pymodbus
Jan 17 12:50:43 debian-vm python3[21326]:   WARNING: The scripts pymodbus.console, pymodbus.server and pymodbus.simulator are installed in '/var/lib/thingsb>
Jan 17 12:50:43 debian-vm python3[21326]:   Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Jan 17 12:50:43 debian-vm python3[21326]: Successfully installed pymodbus-3.1.0

  • error log: tail -f /var/log/thingsboard-gateway/connector.log
Jan 17 13:02:10 debian-vm python3[21319]:     self.__connect_to_current_master(device)
Jan 17 13:02:10 debian-vm python3[21319]:   File "/usr/lib/python3/dist-packages/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 357, in __>
Jan 17 13:02:10 debian-vm python3[21319]:     device.config['master'], device.config['available_functions'] = self.__configure_master(device.config)
Jan 17 13:02:10 debian-vm python3[21319]:   File "/usr/lib/python3/dist-packages/thingsboard_gateway/connectors/modbus/modbus_connector.py", line 419, in __>
Jan 17 13:02:10 debian-vm python3[21319]:     master = ModbusSerialClient(method=current_config["method"],
Jan 17 13:02:10 debian-vm python3[21319]:   File "/var/lib/thingsboard_gateway/.local/lib/python3.9/site-packages/pymodbus/client/serial.py", line 193, in _>
Jan 17 13:02:10 debian-vm python3[21319]:     super().__init__(framer=framer, **kwargs)
Jan 17 13:02:10 debian-vm python3[21319]:   File "/var/lib/thingsboard_gateway/.local/lib/python3.9/site-packages/pymodbus/client/base.py", line 120, in __i>
Jan 17 13:02:10 debian-vm python3[21319]:     self.params.retries = int(retries)
Jan 17 13:02:10 debian-vm python3[21319]: TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

sudo pip3 install pymodbus pyserial twisted --upgrade

Requirement already satisfied: attrs>=19.2.0 in /usr/local/lib/python3.9/dist-packages (from twisted) (22.2.0)
Requirement already satisfied: six in /usr/lib/python3/dist-packages (from Automat>=0.8.0->twisted) (1.16.0)
Requirement already satisfied: idna>=2.5 in /usr/lib/python3/dist-packages (from hyperlink>=17.1.1->twisted) (2.10)
Requirement already satisfied: setuptools in /usr/lib/python3/dist-packages (from zope.interface>=4.4.2->twisted) (52.0.0)
Installing collected packages: zope.interface, typing-extensions, incremental, hyperlink, constantly, Automat, twisted, pyserial, pymodbus
Successfully installed Automat-22.10.0 constantly-15.1.0 hyperlink-21.0.0 incremental-22.10.0 pymodbus-3.1.0 pyserial-3.5 twisted-22.10.0 typing-extensions-4.4.0 zope.interface-5.5.2

root@gateway:~# python /testmode/_1_Python3_Codes/_5_PySerial-Receive_String.py
send:b'\xfe\x03\x00\x1a\x00\x02\xf1\xc3'
get:[b'\xfe\x03\x04\t\x06\x16&\x99\x1b']

- id 0xfe 254 any sensor

modpoll

 ./modpoll -b 19200 -p none -m rtu -a 1 -r 0x1b -c 1 /dev/ttyS0
modpoll 3.10 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2021 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: Modbus RTU, FC3
Slave configuration...: address = 1, start reference = 27, count = 1
Communication.........: /dev/ttyS0, 19200, 8, 1, none, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave... (Ctrl-C to stop)
[27]: 2320
-- Polling slave... (Ctrl-C to stop)
[27]: 2320
-- Polling slave... (Ctrl-C to stop)
[27]: 2320

linux-serial-test (helpless wiht RS-485 mode :<)

star@gateway:/testmode$ ./linux-serial-test -q -s -e -p /dev/ttyS0
Linux serial test app
Error setting RS-485 mode: Inappropriate ioctl for device
/dev/ttyS0: No data received for 2.2s.
/dev/ttyS0: No data received for 3.3s.
/dev/ttyS0: No data received for 4.3s.
/dev/ttyS0: No data received for 5.4s.
/dev/ttyS0: No data received for 6.5s.

Log files

  • /etc/thingsboard-gateway/config/logs.conf
  • /var/log/thingsboard-gateway/*
sudo journalctl --follow -u thingsboard-gateway.service
sudo journalctl -fu thingsboard-gateway.service

References

Star's Lab (手上沒有硬體的做法)

  • Windows Modbus slave simulator
  • Linux Modbus master simulator here