Traccar GPS Tracking Binding [5.0.0;6.0.0)

Key Value
uid traccar
type binding
author Nanna Agesen
version range [5.0.0;6.0.0)
download org.openhab.binding.traccar-5.2.0-SNAPSHOT.jar

Traccar GPS Tracking Binding

The Traccar binding integrates Traccar GPS tracking server with openHAB, enabling real-time vehicle/device tracking, geofencing automation, and comprehensive location monitoring.

Traccar is an open-source GPS tracking system that supports over 200 GPS protocols and 2000+ GPS tracking devices.

Features

  • Real-Time Position Tracking — GPS coordinates, altitude, speed, course, accuracy, GPS fix validity, street address with optional Nominatim reverse geocoding
  • BLE Beacon Tracking — Track up to 4 Bluetooth Low Energy beacons per device (RSSI, distance, battery, temperature, humidity) with MAC address routing for consistent slot assignment
  • Geofencing Automation — Instant geofence entry/exit events via webhooks — perfect for garage doors, lights, security
  • Dual Update Mechanism — Polling (configurable interval, min 10s) + Webhooks (real-time position every 1-2s during movement)
  • Distance Tracking — Odometer, totalDistance, and trip distance with automatic protocol-aware handling (Teltonika, OSMand, H02, GT06)
  • Advanced Reverse Geocoding — Nominatim integration with worldwide transliteration, multi-language support, intelligent caching, and rate limiting
  • GPS Noise Filtering — Configurable speed threshold (default 2 km/h) eliminates GPS drift from stationary devices
  • Device Information — Battery level, motion detection, activity recognition, ignition status, engine hours, GPS satellites, GSM signal strength
  • Auto-Discovery — Devices configured in Traccar appear automatically in the openHAB Inbox

Supported Things

Thing Type Description
server (Bridge) Connection to a Traccar server instance (cloud or self-hosted)
device Individual GPS tracked device/vehicle

Channels

Position & Navigation

Channel Type Description
position Location GPS coordinates (lat, lon, altitude)
altitude Number:Length Altitude above sea level
speed Number:Speed Current speed (converted to configured unit)
course Number:Angle Direction/heading (0-359°)
accuracy Number:Length GPS accuracy in meters
valid Switch GPS fix validity
address String Street address from reverse geocoding

Distance Tracking

Channel Type Description
odometer Number:Length Device odometer (OSMand)
totalDistance Number:Length Cumulative distance (Teltonika/all protocols)
distance Number:Length Trip distance since last update

Device Status

Channel Type Description
status String online/offline/unknown
lastUpdate DateTime Timestamp of last update
batteryLevel Number:Dimensionless Battery level (0-100%)
motion Switch Movement detection
activity String Activity recognition (OSMand only)
protocol String Device protocol type

Vehicle & Connectivity

Channel Type Description
ignition Switch Ignition status
hours Number:Time Engine running hours
event Number Device-specific event code
gpsSatellites Number GPS satellite count
gsmSignal Number:Dimensionless Cellular signal strength

Geofencing

Channel Type Description
geofenceEvent String geofenceEnter / geofenceExit
geofenceId Number Numeric ID of triggered geofence
geofenceName String Name of triggered geofence

BLE Beacons (×4 slots)

Channel Type Description
beacon1-mac String Beacon MAC address
beacon1-name String Beacon name
beacon1-rssi Number Signal strength (dBm)
beacon1-distance Number:Length Calculated distance (meters)
beacon1-battery Number:ElectricPotential Battery voltage
beacon1-lowBattery Switch Low battery warning
beacon1-temperature Number:Temperature Ambient temperature
beacon1-humidity Number:Dimensionless Relative humidity

(Repeat for beacon2, beacon3, beacon4)

Quick Start

traccar.things

Bridge traccar:server:myserver "Traccar Server" [
    url="https://demo.traccar.org",
    username="user@example.com",
    password="password",
    refreshInterval=30,
    webhookPort=8090,
    speedUnit="kmh",
    speedThreshold=2.0,
    useNominatim=true,
    nominatimLanguage="en"
] {
    Thing device car1 "Family Car" [ deviceId=1 ]
    Thing device motorcycle "Motorcycle" [
        deviceId=10,
        beacon1Mac="7cd9f413830b",
        beacon2Mac="7cd9f414d0d7",
        beacon3Mac="7cd9f4128704"
    ]
}

traccar.items

Group gFamilyCar "Family Car" <car>

Location FamilyCar_Position "Position" (gFamilyCar)
    {channel="traccar:device:myserver:car1:position"}
Number:Speed FamilyCar_Speed "Speed [%.1f %unit%]" (gFamilyCar)
    {channel="traccar:device:myserver:car1:speed"}
String FamilyCar_Address "Address [%s]" (gFamilyCar)
    {channel="traccar:device:myserver:car1:address"}
Number:Length FamilyCar_TotalDistance "Odometer [%.1f km]" (gFamilyCar)
    {channel="traccar:device:myserver:car1:totalDistance", unit="km"}
String FamilyCar_GeofenceName "Geofence [%s]" (gFamilyCar)
    {channel="traccar:device:myserver:car1:geofenceName"}
Switch FamilyCar_Motion "Motion" (gFamilyCar)
    {channel="traccar:device:myserver:car1:motion"}

Geofencing Rule Example

rule "Open Garage on Arrival"
when
    Item FamilyCar_GeofenceEvent changed to "geofenceEnter"
then
    val geofenceId = (FamilyCar_GeofenceId.state as Number).intValue()
    if (geofenceId == 1) {
        logInfo("Garage", "Car arriving, opening garage door")
        GarageDoor.sendCommand(ON)
    }
end

Protocol Support

Protocol Speed Odometer Ignition Hours Beacons Activity
Teltonika :white_check_mark: totalDistance :white_check_mark: :white_check_mark: :white_check_mark: (4 slots) :cross_mark:
OSMand :white_check_mark: odometer :cross_mark: :cross_mark: :cross_mark: :white_check_mark:
H02/GT06 :white_check_mark: odometer :cross_mark: :cross_mark: :cross_mark: :cross_mark:
Traccar Client :white_check_mark: odometer :cross_mark: :cross_mark: :cross_mark: :white_check_mark:

Resources

6 Likes

Nanna, thank you for implementing this!
I just tried giving it a whirl, but I am already struggling with setting up the bridge.

I setup the server thing using the UI.

url="http://hxxxxxx.stratoserver.net",
username="myusermailadress",
password="mypassword",
refreshInterval=30,
webhookPort=8082,
speedUnit="kmh",
speedThreshold=2.0,
useNominatim=true,
nominatimLanguage="en"

If I type http://hxxxxxx.stratoserver.net:8082 in my browser, traccar server shows me a login screen and with the username and password I am able to log in.

With the settings above, server thing is offline.
The log suggests authetication failure.

2026-03-23 14:14:30.234 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'traccar:server:stratoserver' changed from OFFLINE (COMMUNICATION_ERROR): Authentication failed to UNKNOWN

2026-03-23 14:14:30.285 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'traccar:server:stratoserver' changed from UNKNOWN to OFFLINE (COMMUNICATION_ERROR): Authentication failed

I must be missing something obvious. Any ideas?

Your welcome…

Have you configured Traccar webhook?

Webhook Configuration

Webhooks enable real-time position updates and instant geofence notifications. The binding supports two types of webhook data:

1. Position Updates (Real-Time Tracking)

Receive position updates every 1-2 seconds during movement without polling.

2. Event Notifications (Geofencing)

Instant notifications for geofence entry/exit, device online/offline events.

Traccar Server Configuration

Modern Configuration (Traccar 5.0+)

Edit /opt/traccar/conf/traccar.xml (or equivalent):

<!-- Enable position forwarding -->
<entry key='forward.enable'>true</entry>
<entry key='forward.url'>http://YOUR_OPENHAB_IP:8090/webhook</entry>
<entry key='forward.type'>json</entry>
<entry key='forward.retry'>true</entry>

<!-- Enable event forwarding -->
<entry key="event.forward.enable">true</entry>
<entry key='event.forward.url'>http://YOUR_OPENHAB_IP:8090/webhook</entry>

Replace YOUR_OPENHAB_IP with your openHAB server’s IP address (e.g., 192.168.1.50).

Restart Traccar:

sudo systemctl restart traccar

Thank you for your detailed reply.

I did exactly as you suggested, but no dice.

2026-03-23 17:53:46.061 [WARN ] [ng.traccar.internal.TraccarApiClient] - Failed to authenticate: java.net.ConnectException: Connection refused

On traccar server ufw status says inactive.

edit:
I changed webhook port to 8082, that did not work either.

<entry key='event.forward.url'>http://YOUR_OPENHAB_IP:8082/webhook</entry>
<entry key='forward.url'>http://YOUR_OPENHAB_IP:8082/webhook</entry>

Have you read the read me?

Are your traccar local hosted? We need to be sure that openhab can reach your traccar instance :

Things show OFFLINE

Symptoms: Bridge or device things show OFFLINE status

Solutions:

  1. Verify Traccar URL is accessible from openHAB server:

    curl -u "user:pass" "https://your-traccar-server/api/devices"
    
  2. Check username/password are correct

  3. Verify firewall allows outbound HTTPS connections

  4. Enable debug logging to see connection errors:

    openhab> log:set DEBUG org.openhab.binding.traccar
    
    

obviously I have no idea what i’m doing. :wink:

With your suggestions I have made progress.
To spare others some time, here are my findings …

The webhook port has to be different from the port on the traccar server on which it is listening,
and the ids for the devices that are reporting to the traccar server have to be looked up on the traccar gui.
to reach the gui of my traccar server I use this url:

http://hxxxxxx.stratoserver.net:8082 

This is the working thing config

Bridge traccar:server:myserver "Traccar Server" [    url="http://hxxxxx.stratoserver.net:8082",    
username="myuser",    
password="mypw",    
refreshInterval=30,    
webhookPort=8090,    
speedUnit="kmh",    
speedThreshold=2.0,    
useNominatim=true,    
nominatimLanguage="en"] 
{    
Thing device car_1 "Name Car1" [ deviceId=TRACCAR_DEVICE_ID_CAR1 ]    
Thing device car_2 "Name Car2" [ deviceId=TRACCAR_DEVICE_ID_CAR2 ]    
Thing device human_1 "Name human1" [ deviceId=TRACCAR_DEVICE_ID_HUMAN1 ]    
Thing device human_2 "Name human2" [ deviceId=TRACCAR_DEVICE_ID_HUMAN2 ]
}

With these settings I can see the devices attributes ans status in openhab.
I have to do a lot more digging.
Next stop: geofences!

@Nanna_Agesen Thank you for your help and this binding!

1 Like

I have all my devices now reporting in OH, but I am still struggling with my geofence.
While every leaving and entering is reported in traccar app, the channels regarding geofence In OH are all NULL. The rule below has never fired, as geofenceEvent_P is not changing when entering or leaving.
Am I missing a setting that has to be done on the traccar side?

Number          geofenceId_P     "Geofence ID P [%d]"       <none>                      {channel="traccar:device:myserver:human_2:geofenceId"}
String          geofenceName_P   "Geofence Name P [%s]"     <none>                      {channel="traccar:device:myserver:human_2:geofenceName"}
String          geofenceEvent_P  "Geofence Event P [%s]"    <none>  (gGeofenceEvent)    {channel="traccar:device:myserver:human_2:geofenceEvent"}

val java.util.Map<Integer, String> geofenceMapping = newHashMap(
    1 -> "PresenceHomeGps"   // Home-Geofence
    // 2 -> "PresenceWorkGps" // work-Geofence 
)

rule "set_geofence_switches"
when
    Member of gGeofenceEvent changed
then
    val suffix = triggeringItemName.split("_").last

    if (suffix != "P" && suffix != "S" && suffix != "Q" && suffix != "V") {
        logWarn("presence.rules", "set_geofence_switches: Unbekanntes Suffix '"+suffix+"' in "+triggeringItemName)
        return;
    }

    val geofenceIdItem = ScriptServiceUtil.getItemRegistry.getItem("geofenceId_"+suffix)
    val geofenceId = if (geofenceIdItem.state instanceof Number)
                         (geofenceIdItem.state as Number).intValue
                     else -1

    logInfo("presence.rules", "set_geofence_switches: Person="+suffix+
        ", Event="+triggeringItem.state+
        ", GeofenceId="+geofenceId)

    val switchPrefix = geofenceMapping.get(geofenceId)

    if (switchPrefix === null) {
        logInfo("presence.rules", "set_geofence_switches: Kein Mapping für GeofenceId "+geofenceId)
        return;
    }

    val presenceSwitch = ScriptServiceUtil.getItemRegistry.getItem(switchPrefix+"_"+suffix)

    if (presenceSwitch === null) {
        logWarn("presence.rules", "set_geofence_switches: Switch '"+switchPrefix+"_"+suffix+"' nicht gefunden")
        return;
    }

    if (triggeringItem.state == "geofenceEnter") {
        presenceSwitch.sendCommand(ON)
    } else if (triggeringItem.state == "geofenceExit") {
        presenceSwitch.sendCommand(OFF)
    }
end

How are notification settings in traccar?

Are you using correct: geofence I’d

Web Interface Configuration (Alternative)

  1. Go to Traccar web interfaceSettingsNotifications

  2. Add notification for events you want:

    • geofenceEnter - Device enters geofence

    • geofenceExit - Device exits geofence

    • deviceOnline - Device comes online

    • deviceOffline - Device goes offline

  3. Select Web Request (POST)

  4. Set URL: http://YOUR_OPENHAB_IP:8090/webhook

  5. Content Type: application/json

I have made significant progress.
My traccar server is hosted by Strato, my openhab server is local.
Obviously the traccar server can’t see local IP addresses.
After setting up an ssh tunnel which will automatically reestablished if it might fail everything is working as expected.
i am now trying to fine tune the settings in the traccar client app to track my presence.
The possibilities utilizing your binding are incredible.
Thank you for your time!

1 Like

Glad you made it work :blush::blush: