Bluetooth tag-tracking using MQTT and ThingsBoard
Bluetooth tag-tracking using MQTT and ThingsBoard
Section titled “Bluetooth tag-tracking using MQTT and ThingsBoard”Implement Bluetooth tag-tracking solutions using MQTT protocol and ThingsBoard IoT platform with MikroTik KNOT devices. This guide covers topology planning, ThingsBoard configuration, RouterOS scripting, and data visualization.
Overview
Section titled “Overview”Bluetooth interface implementation in RouterOS allows devices to capture Bluetooth advertising packets broadcasted over channels 37, 38, and 39. MikroTik Bluetooth tags like TG-BT5-IN and TG-BT5-OUT broadcast advertising payloads over these channels, enabling asset tracking when used with KNOT devices.
Supported Hardware
Section titled “Supported Hardware”| Device | Description |
|---|---|
| KNOT | IoT gateway with Bluetooth scanning capabilities |
| TG-BT5-IN | Indoor Bluetooth asset tracking tag |
| TG-BT5-OUT | Outdoor Bluetooth asset tracking tag with extended range |
Key Capabilities
Section titled “Key Capabilities”- Track assets equipped with Bluetooth tags across multiple KNOT devices
- Monitor tag proximity and movement between zones
- Capture RSSI signal strength for distance estimation
- Integrate with ThingsBoard via MQTT for visualization
- Configure filters for MAC addresses, payload data, and signal strength
Sub-menu
Section titled “Sub-menu”/iot bluetooth scanners
Prerequisites
Section titled “Prerequisites”Before implementing Bluetooth tag tracking, ensure you have:
Hardware Requirements
Section titled “Hardware Requirements”| Requirement | Specification |
|---|---|
| KNOT device | With Bluetooth interface |
| Bluetooth tags | TG-BT5-IN or TG-BT5-OUT |
| Network connectivity | Ethernet, Wi-Fi, or cellular |
| ThingsBoard server | Cloud or local installation |
Software Requirements
Section titled “Software Requirements”- RouterOS 7.x with IoT package installed
- ThingsBoard instance (cloud or container-based)
- MQTT broker configuration on KNOT
Tag Configuration
Section titled “Tag Configuration”Tags can be configured using the MikroTik Beacon Manager app to broadcast payloads:
- Automatically at fixed intervals
- When movement is detected
- When tilt is detected
- When free-fall is detected
Topology Planning
Section titled “Topology Planning”Basic Two-Zone Topology
Section titled “Basic Two-Zone Topology”Deploy two KNOT devices (KNOT-A and KNOT-B) to create separate tracking zones. When a tag moves between zones, the server indicates which KNOT detected the tag.
Multi-Zone Deployment
Section titled “Multi-Zone Deployment”For larger areas, deploy multiple KNOT devices with overlapping and non-overlapping Bluetooth ranges:
# Example: KNOT-A covers Zone A, KNOT-B covers Zone B# Distance between KNOTs: 140m for non-overlapping ranges# Each KNOT range: ~70m (environment-dependent)Bluetooth Range Considerations
Section titled “Bluetooth Range Considerations”| Environment | Typical Range |
|---|---|
| Line of sight, no interference | Up to 180m |
| Office environment | 30-100m |
| Industrial setting | Variable based on interference |
RSSI Filtering
Section titled “RSSI Filtering”Use RSSI threshold filtering to control detection range:
| RSSI Value | Interpretation |
|---|---|
| -40 dBm | Very close proximity |
| -60 dBm | Moderate distance |
| -80 dBm | Edge of detection range |
Configure RSSI filtering in scripts to ignore weak signals from distant tags.
ThingsBoard Configuration
Section titled “ThingsBoard Configuration”MQTT and ThingsBoard Setup
Section titled “MQTT and ThingsBoard Setup”Before configuring RouterOS, set up ThingsBoard for MQTT communication. This guide uses the access-token authentication method for simplicity.
Creating Gateway Devices
Section titled “Creating Gateway Devices”Create each KNOT as a gateway device in ThingsBoard:
- Navigate to Devices section
- Click + and select Add new device
- Configure device settings:
- Name: Descriptive identifier (e.g., “KNOT-A-Warehouse”)
- Check Is gateway option
- Repeat for each KNOT device
Access Token Configuration
Section titled “Access Token Configuration”Set up unique access tokens for each KNOT:
- Select the device in ThingsBoard
- Navigate to Manage credentials
- Generate or assign access token
- Record credentials for RouterOS configuration
Gateway MQTT Topic
Section titled “Gateway MQTT Topic”KNOT devices publish telemetry to the gateway topic:
topic = "v1/gateway/telemetry"RouterOS Configuration
Section titled “RouterOS Configuration”MQTT Broker Setup
Section titled “MQTT Broker Setup”Configure MQTT broker connection on each KNOT:
/iot/mqtt/brokers/add name=tb address=x.x.x.x port=1883 username=KNOT-A_ACCESS_TOKEN| Parameter | Description |
|---|---|
| name | Broker identifier (used in scripts) |
| address | ThingsBoard server IP or hostname |
| port | MQTT port (1883 for non-SSL, 8883 for SSL) |
| username | Device access token from ThingsBoard |
Bluetooth Verification
Section titled “Bluetooth Verification”Verify tag detection before implementing tracking scripts:
/iot bluetooth scanners advertisements print # DEVICE PDU-TYPE TIME ADDRESS-TYPE ADDRESS RSSI LENGTH DATA 0 bt1 adv-noconn-ind mar/07/2023 12:11:57 public DC:2C:6E:0F:C0:3D -51dBm 22 15ff4f09010079100000ffff0000cf188a6b2b000064 1 bt1 adv-noconn-ind mar/07/2023 12:11:58 public 2C:C8:1B:4B:BB:0A -49dBm 22 15ff4f090100168dfefffffffeffa51ae1362200005eFilter for specific tag:
/iot bluetooth scanners advertisements print where address=DC:2C:6E:0F:C0:3DTracking Script
Section titled “Tracking Script”Create a script to process advertisements and publish MQTT messages:
/system script add dont-require-permissions=no name=tracking owner=admin policy=\ ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="# Required packages: iot\r\ \n\r\ \n################################ Configuration ##############################\r\ \n# Name of an existing MQTT broker that should be used for publishing\r\ \n:local broker "tb"\r\ \n\r\ \n# MQTT topic where the message should be published\r\ \n:local topic "v1/gateway/telemetry"\r\ \n\r\ \n# POSIX regex for filtering advertisement Bluetooth addresses\r\ \n# To disable this filter, set it to ""\r\ \n:local addressRegex ""\r\ \n\r\ \n# POSIX regex for filtering Bluetooth advertisements based on their data\r\ \n# To disable this filter, set it to ""\r\ \n:local advertisingDataRegex ""\r\ \n\r\ \n# Signal strength filter (e.g. -40 ignores signals weaker than -40dBm)\r\ \n# To disable this filter, set it to ""\r\ \n:local rssiThreshold ""\r\ \n\r\ \n# KNOT identifier for MQTT message\r\ \n:local gwName "KNOT_A"\r\ \n\r\ \n################################## Bluetooth ###############################\r\ \n:put ("[*] Gathering Bluetooth info...")\r\ \n\r\ \n:global makeRecord do={\r\ \n :local jsonStr "{\"ts\":\$ts,\"values\":{\"reporter\":\"\$gwName\",\"rssi\":\$rssi}}"\r\ \n :return \$jsonStr\r\ \n}\r\ \n\r\ \n# array of record strings collected for each advertising MAC address\r\ \n:global macRecords [:toarray ""]\r\ \n\r\ \n# process advertisements and update macRecords\r\ \n:local advertisements [/iot bluetooth scanners advertisements print detail as-value where\r\ \naddress ~ \$addressRegex and\r\ \ndata ~ \$advertisingDataRegex and\r\ \nrssi > \$rssiThreshold]\r\ \n\r\ \n/iot/bluetooth/scanners/advertisements clear\r\ \n\r\ \n:foreach adv in \$advertisements do={\r\ \n :local address (\$adv->"address")\r\ \n :local rssi (\$adv->"rssi")\r\ \n :local epoch (\$adv->"epoch")\r\ \n \r\ \n :local recordStr [\$makeRecord ts=\$epoch gwName=\$gwName rssi=\$rssi]\r\ \n \r\ \n :if ([:len (\$macRecords->\$address)] > 0) do={\r\ \n :local str (\$macRecords->\$address)\r\ \n :local newStr "\$str,\$recordStr"\r\ \n :set (\$macRecords->\$address) \$newStr\r\ \n } else={:set (\$macRecords->\$address) \$recordStr}\r\ \n}\r\ \n\r\ \n:local sendData true\r\ \n\r\ \n:if (\$sendData) do={\r\ \n :local jsonStr "{"\r\ \n \r\ \n :foreach addr,advRec in \$macRecords do={\r\ \n :set jsonStr "\$jsonStr\"\$addr\":[\$advRec],"}\r\ \n \r\ \n :local payloadlength\r\ \n :set payloadlength [:len (\$jsonStr)]\r\ \n :local remcom\r\ \n :set remcom [:pick \$jsonStr 0 (\$payloadlength-1)]\r\ \n :set jsonStr "\$remcom}"\r\ \n :local message\r\ \n :set message "\$jsonStr"\r\ \n :log info "\$message";\r\ \n :put ("[*] Message structured: \$message")\r\ \n :put ("[*] Total message size: \$[:len \$message] bytes")\r\ \n :put ("[*] Sending message to MQTT broker...")\r\ \n /iot mqtt publish broker="\$broker" topic="\$topic" message=\$message\r\ \n}"Script Configuration Parameters
Section titled “Script Configuration Parameters”| Parameter | Description | Example |
|---|---|---|
| broker | MQTT broker name | "tb" |
| topic | MQTT topic path | "v1/gateway/telemetry" |
| addressRegex | MAC address filter (POSIX regex) | "^DC:2C:6E" or "" to disable |
| advertisingDataRegex | Payload data filter | "15ff4f09" for MikroTik tags |
| rssiThreshold | Minimum RSSI value | "-40" or "" to disable |
| gwName | KNOT identifier | "KNOT_A" |
JSON Message Structure
Section titled “JSON Message Structure”The script generates JSON messages formatted for ThingsBoard Gateway API:
{ "2C:C8:1B:4B:BB:0A": [ { "ts": 1678967250600, "values": { "reporter": "KNOT_A", "rssi": -47 } } ], "DC:2C:6E:0F:C0:3D": [ { "ts": 1678967247850, "values": { "reporter": "KNOT_A", "rssi": -59 } } ]}| Field | Description |
|---|---|
| MAC address | Tag identifier |
| ts | Unix timestamp in milliseconds |
| reporter | KNOT device that detected the tag |
| rssi | Signal strength in dBm |
Scheduler Configuration
Section titled “Scheduler Configuration”Automate script execution with scheduler:
/system/scheduler/add name=bluetoothscheduler interval=30s on-event="/system/script/run tracking"Recommended Interval Settings
Section titled “Recommended Interval Settings”| Use Case | Interval | Notes |
|---|---|---|
| Real-time tracking | 10-15s | Higher data freshness |
| Standard monitoring | 30s-1m | Balanced approach |
| Low-frequency updates | 15m+ | Reduced message volume |
Temperature Monitoring Script
Section titled “Temperature Monitoring Script”For TG-BT5-OUT tags with temperature sensing, use this enhanced script:
/system script add dont-require-permissions=no name=tracking+temp owner=admin policy=\ ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="# Required packages: iot\r\ \n\r\ \n################################ Configuration ##############################\r\ \n:local broker "tb"\r\ \n:local topic "v1/gateway/telemetry"\r\ \n:local addressRegex ""\r\ \n:local advertisingDataRegex ""\r\ \n:local rssiThreshold ""\r\ \n:local gwName "1"\r\ \n\r\ \n################################## Bluetooth ###############################\r\ \n:global invertU16 do={\r\ \n :local inverted 0\r\ \n :for idx from=0 to=15 step=1 do={\r\ \n :local mask (1 << \$idx)\r\ \n :if (\$1 & \$mask = 0) do={\r\ \n :set \$inverted (\$inverted | \$mask)\r\ \n }\r\ \n }\r\ \n return \$inverted\r\ \n}\r\ \n\r\ \n:global le16ToHost do={\r\ \n :local lsb [:pick \$1 0 2]\r\ \n :local msb [:pick \$1 2 4]\r\ \n :return [:tonum "0x\$msb\$lsb"]\r\ \n}\r\ \n\r\ \n:global from88 do={\r\ \n :global invertU16\r\ \n :global le16ToHost\r\ \n :local num [\$le16ToHost \$1]\r\ \n :if (\$num & 0x8000) do={\r\ \n :set \$num (-1 * ([\$invertU16 \$num] + 1))\r\ \n }\r\ \n :return ((\$num * 125) / 32)\r\ \n}\r\ \n\r\ \n:put ("[*] Gathering Bluetooth info...")\r\ \n\r\ \n:global makeRecord do={\r\ \n :local jsonStr "{\"ts\":\$ts,\"values\":{\"KNOT_\$gwName\":\"\$gwName\",\"temp\":\$temp}}"\r\ \n :return \$jsonStr\r\ \n}\r\ \n\r\ \n:global macRecords [:toarray ""]\r\ \n\r\ \n:local advertisements [/iot bluetooth scanners advertisements print detail as-value where\r\ \naddress ~ \$addressRegex and\r\ \ndata ~ \$advertisingDataRegex and\r\ \nrssi > \$rssiThreshold]\r\ \n\r\ \n/iot/bluetooth/scanners/advertisements clear\r\ \n\r\ \n:foreach adv in \$advertisements do={\r\ \n :local address (\$adv->"address")\r\ \n :local ad (\$adv->"data")\r\ \n :local rssi (\$adv->"rssi")\r\ \n :local epoch (\$adv->"epoch")\r\ \n :local temp [\$from88 [:pick \$ad 28 32]]\r\ \n \r\ \n :local recordStr [\$makeRecord ts=\$epoch gwName=\$gwName temp=\$temp]\r\ \n \r\ \n :if ([:len (\$macRecords->\$address)] > 0) do={\r\ \n :local str (\$macRecords->\$address)\r\ \n :local newStr "\$str,\$recordStr"\r\ \n :set (\$macRecords->\$address) \$newStr\r\ \n } else={:set (\$macRecords->\$address) \$recordStr}\r\ \n}\r\ \n\r\ \n:local sendData true\r\ \n\r\ \n:if (\$sendData) do={\r\ \n :local jsonStr "{"\r\ \n :foreach addr,advRec in \$macRecords do={\r\ \n :set jsonStr "\$jsonStr\"\$addr\":[\$advRec],"}\r\ \n :local payloadlength\r\ \n :set payloadlength [:len (\$jsonStr)]\r\ \n :local remcom\r\ \n :set remcom [:pick \$jsonStr 0 (\$payloadlength-1)]\r\ \n :set jsonStr "\$remcom}"\r\ \n :local message\r\ \n :set message "\$jsonStr"\r\ \n :log info "\$message";\r\ \n :put ("[*] Message structured: \$message")\r\ \n /iot mqtt publish broker="\$broker" topic="\$topic" message=\$message\r\ \n}"The temperature value is decoded from the 8.8 fixed-point format in the tag payload at bytes 28-32.
Data Visualization
Section titled “Data Visualization”Device Creation
Section titled “Device Creation”When the script runs, ThingsBoard automatically creates devices for new MAC addresses:
- Navigate to Devices section
- New tags appear as devices
- Each tag shows latest telemetry data
Creating Dashboards
Section titled “Creating Dashboards”- Select a tag device
- Go to Latest telemetry
- Select reporter or temp parameter
- Click Show on widget
- Choose widget type (e.g., Timeseries table)
- Add to new or existing dashboard
Dashboard Configuration
Section titled “Dashboard Configuration”Configure time windows for data display:
# Recommended: Realtime-current day for ongoing trackingMulti-Tag Dashboard
Section titled “Multi-Tag Dashboard”Create a consolidated dashboard showing all tracked assets:
- Add widget for each unique tag
- Configure time window
- Enable auto-refresh
- Add alert thresholds if needed
Use Cases
Section titled “Use Cases”Warehouse Asset Tracking
Section titled “Warehouse Asset Tracking”Track pallets and inventory across warehouse zones:
- Install KNOT at zone entry/exit points
- Attach TG-BT5-IN tag to each asset
- Monitor asset movement between zones
- Generate dwell time reports
Vehicle Tracking
Section titled “Vehicle Tracking”Track assets during transport:
- Install KNOT in delivery vehicles
- Attach TG-BT5-OUT tag to cargo
- Monitor cargo location during transit
- Receive alerts when cargo enters/exits vehicles
Cold Chain Monitoring
Section titled “Cold Chain Monitoring”Monitor temperature-sensitive shipments:
- Use TG-BT5-OUT tags with temperature sensing
- Configure temperature alerts in ThingsBoard
- Track temperature history during transit
- Generate compliance reports
Zone-Based Access Control
Section titled “Zone-Based Access Control”Implement location-based triggering:
- Configure RSSI thresholds for zone boundaries
- Trigger actions when tags enter/exit zones
- Integrate with other automation systems
- Log access events for audit trails
Troubleshooting
Section titled “Troubleshooting”Tags Not Appearing
Section titled “Tags Not Appearing”- Verify Bluetooth interface is enabled
- Check tag is within KNOT range
- Confirm tag is broadcasting (Beacon Manager app)
- Review KNOT logs for Bluetooth errors
/log print where message~"bluetooth"MQTT Connection Failures
Section titled “MQTT Connection Failures”- Verify broker address and port
- Check access token validity
- Confirm network connectivity
- Review firewall rules
/iot/mqtt/brokers/print/iot/mqtt/publish printMissing Telemetry Data
Section titled “Missing Telemetry Data”- Verify script is running via scheduler
- Check script execution logs
- Confirm topic format matches ThingsBoard API
- Validate JSON message structure
/system/script/run tracking:put ([/log info])Intermittent Detection
Section titled “Intermittent Detection”- Adjust RSSI threshold for environment
- Reduce tag broadcast interval
- Check for 2.4GHz interference
- Verify KNOT placement for optimal coverage
Performance Issues
Section titled “Performance Issues”| Issue | Solution |
|---|---|
| High CPU usage | Increase scheduler interval |
| Missing detections | Reduce number of tracked tags |
| Slow updates | Decrease scheduler interval |
| Memory issues | Restart KNOT device |
Related Commands
Section titled “Related Commands”/iot bluetooth scanners advertisements print- View detected advertisements/iot bluetooth scanners advertisements clear- Clear advertisement cache/iot mqtt publish- Publish MQTT messages/system script run- Execute tracking script/system scheduler- Configure automated script execution