thingsboard / thingsboard-gateway

Open-source IoT Gateway - integrates devices connected to legacy and third-party systems with ThingsBoard IoT Platform using Modbus, CAN bus, BACnet, BLE, OPC-UA, MQTT, ODBC and REST protocols
https://thingsboard.io/docs/iot-gateway/what-is-iot-gateway/
Apache License 2.0
1.75k stars 845 forks source link

[HELP] Different sensor data separation methods in mqtt.json #813

Closed peterandthejetsons closed 2 years ago

peterandthejetsons commented 2 years ago

Hello!

I have latest TB Gateway installed and connected to external MQTT Broker. TB Gateway get the following messages from Broker:

Message from Sensor 1:

{"Key":{"Sensor1":{"Device":"Sensor1","Name":"DoorSensor","0500<00":"000000010000","ZoneStatusChange":0,"ZoneStatusChangeZone":1,"Contact":0,"Endpoint":1,"LinkQuality":39}}}

Message from Sensor 2:

{"Key":{"Sensor2":{"Device":"Sensor2","Name":"TempSensor","0400<00":"000000010000","ZoneStatusChange":0,"ZoneStatusChangeZone":1,"Temp":24.5,"Humidity":45,"Endpoint":1,"LinkQuality":39}}}

Connector name (If you need help with some connector/converter): MQTT Connector

mqtt.json configuration part:

...
  "mapping": [
    {
      "topicFilter": "topic/+/SENSOR",
      "converter": {
        "type": "json",
        "filterExpression": "${[?(@.Name == 'DoorSensor')]}",
        "deviceNameJsonExpression": "${*.*.Device}",
        "deviceTypeJsonExpression": "default",
        "timeout": 60000,
        "timeseries": [
          {
            "type": "string",
            "key": "Contact",
            "value": "${*.*.Contact}"
          },
          {
            "type": "string",
            "key": "LinkQuality",
            "value": "${*.*.LinkQuality}"
          }
        ]
      }
    },
    {
      "topicFilter": "topic/+/SENSOR",
      "converter": {
        "type": "json",
        "filterExpression": "${[?(@.Name == 'TempSensor')]}",
        "deviceNameJsonExpression": "${*.*.Device}",
        "deviceTypeJsonExpression": "default",
        "timeout": 60000,
        "timeseries": [
          {
            "type": "string",
            "key": "Humidity",
            "value": "${*.*.Humidity}"
          }
        ]
      }
    }
  ]
...

So I have two different types of sensors which are sending different data. Sensor 1 send two keys, Sensor 2 send one key. How can I separate incoming data with filterExpression or any other solution by name key to avoid empty keys in Thingsboard?

Versions:

samson0v commented 2 years ago

Hi @peterandthejetsons, it was fixed, so update your Gateway to the newest version via the master branch. Thanks for your interest in ThingsBoard IoT Gateway!

peterandthejetsons commented 2 years ago

Hi @samson0v! Thank you for your answer! I've downloaded the project and built a new image from it with the following command:

root@docker01:/docker/thingsboard-gateway# docker build -t thingsboard/tb-gateway -f docker/Dockerfile .

I used the following docker-compose file to run TB, TB Gateway and a mosquitto server:

version: "3"

services:
  mosquitto:
    image: eclipse-mosquitto
    volumes:
      - ./:/mosquitto/:rw
    ports:
      - 1883:1883
      - 9001:9001
  tb:
    restart: always
    image: "thingsboard/tb-postgres"
    ports:
      - "8080:9090"
      - "1884:1883"
      - "7070:7070"
      - "5683-5688:5683-5688/udp"
    environment:
      TB_QUEUE_TYPE: in-memory
    volumes:
      - tb-data:/data
      - tb-logs:/var/log/thingsboard
  tb-gateway:
    restart: always
    image: "digi/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

volumes:
  tb-data:
  tb-logs:

And I used the following mqtt.json configuration file:

{
  "broker": {
    "name": "MQTT Broker",
    "host": "192.168.123.160",
    "port": 1883,
    "clientId": "ThingsBoard_gateway",
    "maxMessageNumberPerWorker": 10,
    "maxNumberOfWorkers": 100,
    "security": {
      "type": "basic",
      "username": "admin",
      "password": "password"
    }
  },
  "mapping": [
    {
      "topicFilter": "topic/+/SENSOR",
      "converter": {
        "type": "json",
        "filterExpression": "${[?(@.Name == 'asdasDoorSensor')]}",
        "deviceNameJsonExpression": "${*.*.Device}",
        "deviceTypeJsonExpression": "default",
        "timeout": 60000,
        "timeseries": [
          {
            "type": "string",
            "key": "Contact",
            "value": "${*.*.Contact}"
          },
          {
            "type": "string",
            "key": "LinkQuality",
            "value": "${*.*.LinkQuality}"
          }
        ]
      }
    }
  ]
}

But everytime I try I always get empty key pairs. It seems like filterExpression is not working. I using the following input JSON message:

{"Key":{"Sensor1":{"Device":"Sensor1","Name":"DoorSensor","0500<00":"000000010000","ZoneStatusChange":0,"ZoneStatusChangeZone":1,"Contact":0,"Endpoint":1,"LinkQuality":39}}}

Could the problem be that the Name key is not the top key? I tried to find out right JSON path with https://jsonpath.com/ page, but what expression this page uses not the same what TB Gateway waiting for. Can I find specification for filterExpression or any other solution to solve this issue?

peterandthejetsons commented 2 years ago

Hi @samson0v! I've added more JSON keys and removed filterExpression and it worked without that, i mean it works with different sensor data with new version out-of-box. Thank you for your help!