All Collections
Connect your Devices
Connect Teltonika TRB140 Modbus IoT Gateway to Ubidots using MQTT
Connect Teltonika TRB140 Modbus IoT Gateway to Ubidots using MQTT

Send Modbus TCP data to Ubidots using Teltonika gateways.

Sergio M avatar
Written by Sergio M
Updated over a week ago
Teltonika TRB140 LTE Router | Getic

The TRB140 is an ultra-small, lightweight, and energy-efficient IoT device with mission-critical LTE Cat 4 and Gigabit Ethernet connectivity options. Its Linux environment offers a high degree of customization.

This gateway is perfect for projects and applications where a single device must be upgraded with reliable and secure internet connectivity.

In this guide, the TRB polls humidity and temperature data from a Modbus server and then sends the data to Ubidots via MQTT.

This guide should also work for other Teltonika routers and gateways that support the Mobdus protocol, such as:

  • RUT1, RUT2 & RUT3 series

  • RUT9 series

  • RUTX series

  • RUTM50

  • TRB1 & TRB2 series

  • TRB500

Requirements

1. Set up the hardware

If you are looking to use a SIM card to provide mobile connectivity, start by removing the device's front panel and inserting the SIM as shown below. If you are using Ethernet for connectivity, you can move to the next step.

After that, proceed to power the TRB140 using the included power chord and then connect it to your router using the included Ethernet cable.

2. Accessing the TRB140 web configuration interface

From your PC, launch a terminal and run the following command to get the PC's assigned IP address on your LAN:

ifconfig

Your PC's IP address will be displayed as shown below:

Component 4.png

Using this IP address, scan your whole LAN to get the IP address of the TRB140 by running the following command:

sudo nmap -sn <ip-address>/24 | grep 'TRB140'

Make sure to replace the <ip-address> with the IP address you obtained before. For example, if your PC's IP address is 192.168.22.34, the command that you should run is:

sudo nmap -sn 192.168.22.34/24 | grep 'TRB140'

The output of this command will display the TRB's IP address as:

Now, open a web browser and type the TRB140's IP address. Once there, you'll be prompted for credentials:

You can find the device's credentials on its back plate. Use them to log in:

3. Configuring Modbus

This section configures the Modbus service within the TRB140 to enable it to poll data from the Modbus server. As implied in the beginning of the article, before moving forward, you'll need to have a data source or simulate it. Python's Pymodbus is a good option for the latter.


Once logged into the device's web configuration interface, go to Services Modbus Modbus TCP Client:

Once there, enable the Modbus Client checkbox and then click on the ADD button:

In the configuration window that will pop-up, under the SERVER DEVICE CONFIGURATION section, make sure to:

  • Check the Enable option.

  • Set the Name field with a name you find appropriate. In this guide, we went for Modbus_server_hq.

  • Fill the Server ID option with the Modbus server ID.

  • Fill the Address field with your Modbus server address. For this article, a Modbus server was set up in the address 192.168.22.191.

  • Fill the Port field with the port in which your Modbus server is running. For this article, the Modbus server was configured to run in port 5020.

  • As for the rest of parameters in this section, such as Timeout, Always reconnect, Frequency, etc., set them accordingly to your requirements.

Scroll down to the ADD NEW REQUEST section. A request in this context is the required configuration to read one or several coils/registers from the Modbus server. In this example, a request will be created for each variable, namely humidity and temperature.

Write the name of the variable in the NEW CONFIGURATION NAME field and then click the ADD button:

You'll note that after clicking the ADD button, a new REQUEST CONFIGURATION will appear with some pre-selected configurations. You must change this pre-selected configurations according to your Modbus server settings.

As the screenshot above shows, both toggleable buttons must be enabled.

  • The one within the yellow box is to ensure that the retrieved data contains no additional characters ([<data>]).

  • The one within the red box is the most important since it enables the configuration.

According to the approach taken for this article, a REQUEST CONFIGURATION will be created for each variable. For the case of humidity and temperature, it will look like this:

Name

Data type

Function

First register number

Register count/values

Brackets

temperature

16bit INT, high byte first

Read holding register (3)

40202

1

ON, ON

3.1. Modbus settings explanation

  • DATA TYPE: 16bit INT, high byte first. This is the most common configuration for analogue sensors and you should make sure to select the endianness according to yours. For this article the XY-MD02 temperature and humidity sensor is being used.

  • FUNCTION: Since this article uses an analogue sensor, such data is read by using the Read holding registers (3) function. However, if you are not measuring analogue data, you might want to use the "read coils (1)" function.

  • FIRST REGISTER NUMBER: This is the first Modbus address from which to start reading the registers. Select this according to your data's address.

  • REGISTER COUNT VALUES: This is the amount of registers to read starting from FIRST REGISTER NUMBER. Adjust this according to your requirements. To read only one variable, as in the approach taken for this example, this value should be

4. Testing the Modbus configuration

Scroll down until you find the REQUEST CONFIGURATION TESTING section, select the recently created REQUEST CONFIGURATION from the drop-down menu and click the TEST button. If everything is correctly set up, the reading from the Modbus server will be displayed:

Now that the configuration is tested, you can save it by clicking the SAVE & APPLY button:

Now, the pop-up window will collapse and the Modbus TCP Client configuration screen will be displayed again. The resulting configuration of section 2 of the guide would be this:

Click on the SAVE & APPLY button to save this configuration.

5. Set up the Data to Server service

The next step is to configure sending the data retrieved from the Modbus server to Ubidots.

Go to UbidotsDevicesFunctions and create a new UbiFunction.

  • Give it any Name that you find appropriate.

  • Set the Method to POST.

  • Set the Runtime to Python 3.11 Lite.

  • Set the Ubidots Token.

In the code section, paste the following:

import requests
import time
import json

# Base url to perform request to Ubidots API
BASE_URL = "https://industrial.api.ubidots.com"

REQUESTS_FUNCTIONS = {"get": requests.get, "post": requests.post}

# If you changed the data configuration name to other
# than the one used in the article, set this variable to that name
DATA_CONFIGURATION_NAME: str = 'ModbusServerData'

def main(args):
# Print args for debug
print(args)
# Get the payload containing the data of our interest
data: dict = args['payload'][DATA_CONFIGURATION_NAME]
# Build the device label using the server name and its ip address
device_label: str = data['server_name'].replace('_', '-') + '-' + data['ip'].replace('.', '-')
# Get the variable's name
variable_label: str = data['name']
# Divide the value by 10 according to the device's datasheet. Adjust this accordingly
value: int = int(data['data']) / 10
# Get the Ubidots token
token: str = args.get('_auth_token', None)

if token is None:
print("[ERROR] Please configure you Ubidots token for this Ubifunction or define it within it.")
return {"status": "error"}

if not data:
print("No data")
return {"error" : "No data present in the payload"}

payload: dict = {variable_label : value}
req = update_device(device_label, payload, token)

print("[INFO] Request result:")
print(req.text)

return {"status": "Ok", "result": req.json()}



def update_device(device, payload, token):
"""
updates a variable with a single dot
"""

url = "{}/api/v1.6/devices/{}".format(BASE_URL, device)
headers = {"X-Auth-Token": token, "Content-Type": "application/json"}

req = create_request(url, headers, payload, attempts=5, request_type="post")

return req

def create_request(url, headers, data, attempts, request_type):
"""
Function to create a request to the server
"""

request_func = REQUESTS_FUNCTIONS.get(request_type)

kwargs = {"url": url, "headers": headers}

if request_type == "post":
kwargs["json"] = data

try:
req = request_func(**kwargs)
print("[INFO] Request result: {}".format(req.text))
status_code = req.status_code
time.sleep(1)

while status_code >= 400 and attempts < 5:
req = request_func(**kwargs)
print("[INFO] Request result: {}".format(req.text))
status_code = req.status_code
attempts += 1
time.sleep(1)

return req
except Exception as e:
print("[ERROR] There was an error with the request, details:")
print(e)
return None

Click on the Make it live button to save the UbiFunction. After this, make sure to copy the function's HTTPS endpoint URL:

Go back to the TRB140's web configuration interface and then Services Data to Server and, under the ADD NEW INSTANCE section, write a NEW COLLECTION NAME, and then click on the ADD button:

Collections are just entities that allow you to set up a data source to be sent to the cloud. Our collection name was set to sendDataToUbidots.

Once you do that, the DATA CONFIGURATION screen will pop-up with an empty configuration. Edit it to set the following configuration:

  • Fill the Name field with any name that helps you identify this configuration. One thing to take into account is that the payload that you'll receive on Ubidots is under the payload/<data-configuration-name> key. For example, if you name this configuration ModbusServerData, then the data arriving on Ubidots will be in under Payload modbusserverdata.

  • In the Type field, choose Modbus. This will select the data source to be the Modbus server data.

  • In Format type, select JSON. This is so that the received data on Ubidots is a JSON and not a JSON-formatted string.

  • Make sure to enable the Send as object option.

  • Leave the other settings unchanged.

Scroll down until you find the button to keep going with the configuration and click on it:

In the next configuration page, make sure to turn on the Enable button next to GENERAL SETTINGS and leave the Format type set to JSON.

You can set the data publishing period by going to the ADVANCED SETTINGS tab. Here, the Period option allows you to select the data sending interval in seconds. Once done, click on the Next button.

Once the SERVER CONFIGURATION is displayed, set the following configuration:

  • Select the Type to MQTT.

  • In the Server address field, set functions.ubidots.com

  • Set the Port to 1883 if you are using plain MQTT or 8883 for MQTT over TLS.

  • Generate a random 15 length string to set the Client ID field.

  • Set the Topic field using your Ubifunction's HTTPS Endpoint URL in the following way: /prv/<username>/<function-label>. In other words, delete everything up until you reach "/prv".

  • Make sure to check the Use Credentials checkbox.

  • Set the Username to your Ubidots username.

  • Set the Password to your Ubidots token.

  • Fill the other fields according to your requirements.

  • Leave the other settings unchanged and click on the SAVE & APPLY button:

After saving this configuration, the pop-window will collapse and show your created collection. Make sure it's enabled:

6. Checking the received data on Ubidots

Go to your Ubidots account → Devices Devices and, if you followed all naming conventions in the guide, you'll be able to see a device whose label is something like "modbuser-server-hq-<server-ip-address>" containing the humidity and temperature variables:

Did this answer your question?