thingsboard-gateway icon indicating copy to clipboard operation
thingsboard-gateway copied to clipboard

[HELP] Not writing float attributes properly through Modbus TCP

Open mcavalcante opened this issue 3 years ago • 3 comments

Describe the issue I´ve configured a ThingsBoard gateway as instructed in the link https://thingsboard.io/docs/iot-gateway/getting-started/ (Ubuntu), where I connected a PLC (model PLC-300 / WEG) programmed to receive some parameters through Modbus TCP. I can successfuly read and write integer values to this PLC, but for float it is simply not working for writing (ISSUE A), and for reading (ISSUE B) I´m not sure if the behaviour is Ok.

The problem is that the numbers I write through attributes/TB keys are been written wrongly at the PLC.

The configuration for the Modbus connector is as following (/etc/thingsboard-gateway/config/modbus.json): For reading (seems to be working)

        "attributes": [
         {
            "tag": "var_a",
            "type": "32float",
            "wordOrder": "LITTLE",
            "functionCode": 3,
            "objectsCount": 2,
            "address": 8016
         },

For writing (not working Ok)

        "attributeUpdates":[
...
         {
            "tag": "svar_a",
            "type": "32float",
            "functionCode": 16,
            "objectsCount": 2,
            "address": 8016
         },

Note: For the key "svar_a" I also tried the functionCode 6, but the behaviour is the same.

TO REPRODUCE THE ISSUES: ISSUE A (WRITE)

  1. In ThingsBoard UI, I click on "Devices" on the vertical menu;
  2. Find and click on device "PLC-300", and in the new windows opened, click on "Attributes";
  3. Select "Shared Attributes" and create one for the key "svar_a', type '123 double', value "6.1" and click "Add";
  4. On the PLC, modbus address 8016, now I see the value "1.8367E-41" (it should be displaying the value 6,1).

ISSUE B (READ)

  1. In the PLC side, throught its HMI, I set a variable called VAR_A (the same one used in ISSUE A) to "6.1";
  2. In ThingsBoard, I navigate throught Devices, "PLC-300", Attributes, Client Attributes;
  3. I see that the "var_a" attribute, the same one set on the step 1, is with the value "6.099999904632568"; Q: For the issue B, should I consider it a problem, or is it expected, once 6.1 is "equal" to 6.099999904?

Configuration (Attach your configuration file) Notate: Remove Access token from file if you want to attach a tb_gateway.yaml tb_gateway.yaml

thingsboard:
  host: xxxxxxxxxxxxxx
  port: 1883
  remoteShell: false
  remoteConfiguration: false
  statsSendPeriodInSeconds: 3600
  minPackSendDelayMS: 0
  checkConnectorsConfigurationInSeconds: 60
  security:
    accessToken: XXXXXXXXXXXXXXXXXXX
  qos: 1
storage:
  type: memory
  read_records_count: 100
  max_records_count: 100000

  grpc:
  enabled: false
  serverPort: 9595
  keepaliveTimeMs: 10000
  keepaliveTimeoutMs: 5000
  keepalivePermitWithoutCalls: true
  maxPingsWithoutData: 0
  minTimeBetweenPingsMs: 10000
  minPingIntervalWithoutDataMs: 5000
connectors:
  -
    name: Modbus Connector
    type: modbus
    configuration: modbus.json

modbus.json

{
  "master": {
    "slaves": [
      {
        "host": "192.168.16.11",
        "port": 502,
        "type": "tcp",
        "method": "socket",
        "timeout": 35,
        "byteOrder": "BIG",
        "wordOrder": "BIG",
        "retries": true,
        "retryOnEmpty": true,
        "retryOnInvalid": true,
        "pollPeriod": 5000,
        "unitId": 1,
        "deviceName": "PLC-300",
        "deviceType": "PLC",
        "sendDataOnlyOnChange": false,
        "connectAttemptTimeMs": 5000,
        "connectAttemptCount": 5,
        "waitAfterFailedAttemptsMs": 30000,
        "attributes": [
         {
            "tag": "var_a",
            "type": "32float",
            "wordOrder": "LITTLE",
            "functionCode": 3,
            "objectsCount": 2,
            "address": 8016
         },
         {
            "tag": "var_b",
            "type": "32float",
            "wordOrder": "LITTLE",
            "functionCode": 3,
            "objectsCount": 2,
            "address": 8024
         },
         {
            "tag": "var_c",
            "type": "32float",
            "wordOrder": "LITTLE",
            "functionCode": 3,
            "objectsCount": 2,
            "address": 8032
         }
        ],
        "timeseries": [
          {
            "tag": "TesteTimer",
            "type": "16int",
            "functionCode": 3,
            "objectsCount": 1,
            "address": 8000
          }
        ],
        "attributeUpdates":[
         {
           "tag": "maxTimer",
           "type": "32int",
           "byteOrder": "BIG",
           "wordOrder": "LITTLE",
           "functionCode": 6,
           "objectsCount": 2,
           "address": 8008
         },
         {
            "tag": "svar_a",
            "type": "32float",
            "functionCode": 16,
            "objectsCount": 2,
            "address": 8016
         },
         {
            "tag": "svar_b",
            "type": "32float",
            "functionCode": 16,
            "objectsCount": 2,
            "address": 8024
         },
         {
            "tag": "svar_c",
            "type": "32float",
            "functionCode": 6,
            "objectsCount": 2,
            "address": 8032
         }
        ],
        "rpc": [
         {
           "tag": "resetTimer",
           "type": "bits",
           "functionCode": 5,
           "bitCount": 1,
           "address": 40000,
           "value": 1
         },
         {
           "tag": "setMaxTimer",
           "type": "32int",
           "byteOrder": "BIG",
           "functionCode": 6,
           "objectsCount": 2,
           "address": 8008
         },
         {
           "tag": "getMaxTimer",
           "type": "16int",
           "functionCode": 3,
           "objectsCount": 1,
           "address": 8008
         }
        ]
      }
    ]
  }
}

Connector name (If you need help with some connector/converter): Modbus Connector (modbus.json)

Versions (please complete the following information):

  • OS: Ubuntu Desktop 20.04.3 and Ubunto Server 20.04.4 for the ThingBoard Gateway
  • Thingsboard IoT Gateway version 3.0.1
  • Python version 3.8.10

** Import information **

  • PLC-300 Manual: https://static.weg.net/medias/downloadcenter/h08/h0e/WEG-plc300-manual-do-usuario-10000703041-manual-portugues-br.pdf
  • The variable VAR_A is a variable type REAL (Float Point Standard IEEE 559)

Scenario Diagram descricao_cenario

Setting Value 6.1 on TB TB_Devices

Value Shown In PLC when setting 6.1 through TB PLC_var_a_value

The wrong value seen through a Modbus client (Notice that it is NOT setting a value for address 8007) modbus_client_radzio_wrong_value

An example of value Ok through a Modbus client (Notice that IT IS setting a value for address 8007) modbus_client_radzio_ok_value(example)

mcavalcante avatar Mar 14 '22 20:03 mcavalcante

Hi @mcavalcante, thanks for your interest in ThingsBoard IoT Gateway! We will investigate this problem.

samson0v avatar Mar 15 '22 08:03 samson0v

Hi @mcavalcante, thanks for your interest in ThingsBoard IoT Gateway! We will investigate this problem.

After doing some researches, I found a way to put it working, but I´m not sure it is the correct way. Firstly, I´ve set the object "svar_a" like this:

         {
            "tag": "svar_a",
            "type": "32float",
            "byteOrder": "BIG",
            "wordOrder": "LITTLE",
            "functionCode": 16,
            "objectsCount": 2,
            "address": 8016
         },

... and, in the file /usr/lib/python3/dist-packages/thingsboard_gateway/connectors/modbus/modbus_connector.py, I´ve changed some lines of the method __process_rpc_request in the following way:

                try:
                    i = 0
                    for cd in converted_data:
                        if (cd > 0):
                            i += 1

                    if (i >= 2):
                        rpc_command_config[PAYLOAD_PARAMETER] = converted_data
                    else:
                        rpc_command_config[PAYLOAD_PARAMETER] = converted_data[0]
                except IndexError:
                    rpc_command_config[PAYLOAD_PARAMETER] = converted_data
            try:
                response = self.__function_to_device(device, rpc_command_config)

For some reason, when the variable PAYLOAD_PARAMETER has some value ("payload" in my personal scenario), it was only building the modbus frame with only one object (address 8016). Now it is writing both ones, the 8016 and 8017.

Would it be a bug or some misconfiguration that I did?

mcavalcante avatar Mar 16 '22 23:03 mcavalcante

Hi @mcavalcante, please, update your Gateway to the newest version via the master branch and let us know if it helps.

samson0v avatar Jul 18 '22 11:07 samson0v

Hello @samson0v,

Sorry, we´ve retaken this part of the project few weeks ago and I haddn´t see your message. I´ve tried with the version below and I guess we had an step back. Now, even with the work around suggested here in march 16º 2022, I can´t write float variables from TB toward the the PLC (ISSUE A mentioned above). However, for reading the float vars, it´s Ok.

""2023-03-17 10:35:13" - |INFO| - [tb_gateway_service.py] - tb_gateway_service - __init__ - 153 - ThingsBoard IoT gateway version: 3.2"

Work around:

                try:
                    i = 0
                    for cd in converted_data:
                        if (cd > 0):
                            i += 1

                    if (i >= 2):
                        rpc_command_config[PAYLOAD_PARAMETER] = converted_data
                    else:
                        rpc_command_config[PAYLOAD_PARAMETER] = converted_data[0]
                except IndexError:
                    rpc_command_config[PAYLOAD_PARAMETER] = converted_data
            try:
                response = self.__function_to_device(device, rpc_command_config)

memind-rad avatar Mar 17 '23 13:03 memind-rad