The standardized motion attribute was introduced to have a universal way of handling device motion for all protocols. Some devices report this attribute directly. For other devices it is automatically calculated based on the speed value and the speedThreshold parameter. It is also possible to override it using computed attributes.
The system analyzes positions and switches motion state according to the configuration. Traccar switches state from stopped to moving if a device is reporting motion as true for more than minimalTripDuration seconds or if trip distance is more than minimalTripDistance meters. Traccar switches state from moving to stopped if a device is reporting motion as false for more than minimalParkingDuration seconds or if useIgnition is enabled and the ignition is off. Only continuous periods can switch the state; any fluctuations reset the detection.
The following parameters can be used to configure the detection logic:
If report.trip.newLogic is enabled, Traccar uses an alternative motion model based on spatial clustering instead of relying only on speed transitions. Motion starts after the device moves sufficiently far from the last motion reference point, and motion stops after the device remains within a limited area for a minimum time. This approach reduces false stop/start transitions during short pauses. Long gaps in incoming data can also split movement intervals to keep trip timelines more realistic.
Traccar provides two advanced report types called Trips and Stops. It uses the same motion detection algorithm to determine trips and stops for those reports. The stops report can detect gaps between reported positions and treat them as a stop.
Trips, stops and summary reports have two implementations. The system picks between them automatically based on the requested period: if it is longer than report.fastThreshold seconds (one day by default), the fast version is used, otherwise the slow one.
The slow version reprocesses all positions in the period and recomputes trips and stops from scratch using the current configuration. The fast version instead reuses the deviceMoving and deviceStopped events that were recorded in real time, which is much faster but less accurate. Some details are missing (for example, maximum speed is reported as zero), and the main drawback is that if positions arrive out of order, the real-time events end up misplaced and fast reports reflect those inaccuracies, while the slow version would sort positions correctly.
Following are two examples to illustrate how the logic works.
The first example illustrates the most common case of reporting. This can be a device that has an internal battery or connected to an uninterrupted external power supply. It keeps reporting even when the vehicle stops, but it can go into a sleep mode after some period (rows 19 - 21) if there is no movement.
Trip 1 is detected because period started from zero speed (initialized as stopped), distance longer than default 500 meters or duration longer than 5 minutes, and it is followed by stop longer than minimalParkingDuration.
Stop 1 is detected because it has a duration longer than minimalParkingDuration and the speed is close to zero.
Trip 2 is detected from row 27; rows 24 - 25 are ignored as fluctuation. Parameters are more than minimal, and it is preceded and followed by positions with zero speed.
The second example illustrates a case when a device does not have an internal battery and is powered only when ignition is on. Such devices always cold-start and have a delay in GPS fix. For such devices it is common to start reporting with a speed higher than zero. It is impossible to use the same algorithm as in the first example, so additional logic was introduced. Gaps between reporting intervals are detected as stops.
The report.trip.minimalNoDataDuration parameter is set to 600 (10 minutes). You can see that the speed is never less than the speedThreshold, but the gap (rows 15 - 28) is more than 10 minutes. It is interpreted as a stop. Preceding trip is detected correctly. Following movement period is not detected as a trip because the algorithm cannot determine when it ends. Only full stops or trips are recorded.