How to handle zero value positions in lastLocation() (or in OutdatedHandler)?

Nils Leideck 19 hours ago

Dear Traccar Friends.

I have devices that send zero value location data upon registration and then they continue with hibernation battery reports to let the server know about battery level while the device is stationary.

My problem is that the JT808 decoder handler for these Hypernation Battery Reports (0x0210) in the JT808 decoder uses lastLocation(). If there hasn't been a valid location in the current session yet, all locations are initially set to zero.

I’m now considering whether it would be a valid option for the handler for 0x0102 (registration) to check the database (Storage) to retrieve the last position from the database, so to speak. However, this would require modifying the OutdatedHandler, as far as I could see, which is no longer specific to the JT808 protocol.

I'd appreciate any advice before I open a PR for a change.

$ tail -f -n 100000 /srv/docker/traccar/traccar/logs/tracker-server.log |grep Tff0aa577
2026-10-14 06:26:34  INFO: [Tff0aa577] connected
2026-10-14 06:26:35  INFO: [Tff0aa577: jt808 < 185.57.216.152] 7e0102000c0454100061470383303435343130303036313437e97e
2026-10-14 06:26:35  INFO: [Tff0aa577: jt808 > 185.57.216.152] 7e8001000504541000614700000383010200617e
2026-10-14 06:26:36  INFO: [Tff0aa577: jt808 < 185.57.216.152] 7e010900000454100061470384e97e
2026-10-14 06:26:36  INFO: [Tff0aa577: jt808 > 185.57.216.152] 7e81090008045410006147000007ea0a0e061a2400377e
2026-10-14 06:26:36  INFO: [Tff0aa577: jt808 < 185.57.216.152] 7e10070004045410006147038540000000b37e
2026-10-14 06:26:36  INFO: [Tff0aa577: jt808 > 185.57.216.152] 7e8001000504541000614700000385100700737e
2026-10-14 06:26:37  INFO: [Tff0aa577: jt808 < 185.57.216.152] 7e02000072045410006147038600000000000000000000000000000000000000000000261014142636010400000f2d300116310100e4020064e50100e60100e7080000000600000000e10c0106000200ac8b009cbf0200ec23a8a237d4eaded2c08a60f6e760bea8a237ba36a1af5c4eeefbed5baefa8fca5d4359aaf50101217e
2026-10-14 06:26:37  INFO: [Tff0aa577: jt808 > 185.57.216.152] 7e8001000504541000614700000386020000657e
2026-10-14 06:26:40  INFO: [Tff0aa577] id: 045410006147, time: 2026-10-14 06:26:36, lat: 0.00000, lon: 0.00000, course: 0.0
2026-10-14 06:35:25  INFO: [Tff0aa577: jt808 < 185.57.216.152] 7e02100007045410006147038764261014143524b47e
2026-10-14 06:35:25  INFO: [Tff0aa577: jt808 > 185.57.216.152] 7e8001000504541000614700000387021000747e
2026-10-14 06:35:28  INFO: [Tff0aa577] id: 045410006147, time: 2026-10-14 06:26:36, lat: 0.00000, lon: 0.00000, course: 0.0
2026-10-14 06:36:37  INFO: [Tff0aa577: jt808 < 185.57.216.152] 7e000200000454100061470388ef7e
2026-10-14 06:36:37  INFO: [Tff0aa577: jt808 > 185.57.216.152] 7e80010005045410006147000003880002006b7e
2026-10-14 06:45:26  INFO: [Tff0aa577: jt808 < 185.57.216.152] 7e02100007045410006147038964261014144524ca7e
2026-10-14 06:45:26  INFO: [Tff0aa577: jt808 > 185.57.216.152] 7e80010005045410006147000003890210007a7e
2026-10-14 06:45:29  INFO: [Tff0aa577] id: 045410006147, time: 2026-10-14 06:26:36, lat: 0.00000, lon: 0.00000, course: 0.0
2026-10-14 06:46:36  INFO: [Tff0aa577] disconnected

-- Cheers, Nils

Anton Tananaev 18 hours ago

We already load the last saved position from the database when the device connects, so getLastLocation() is not limited to the current session.

Your log suggests the initial 0x0200 report contains zero coordinates, which then become the last known location. Have you tried enabling filter.zero?

Nils Leideck 18 hours ago

The problem here is that the devices are designed such that, if Wi-Fi networks are detected but there is no previous GPS location data after a reboot, the location is sent as a "zero location" in addition to the Wi-Fi data. However, it is important that the Wi-Fi data be forwarded, so I cannot simply filter out all zero locations.

Would it be possible that, with "zero location" in the incoming data, the system always retrieves the last valid non-zero location instead of just the most recent ones, which could also be zero?

That would effectively mean that no zero locations would ever be saved, except perhaps during the very first connection between the device and the server when there is no record at all in the database. Does that make sense to you?

-- Cheers, Nils

Nils Leideck 17 hours ago

Note:

There is a corresponding test case:

        verifyDecode(decoder, binary(
                "7e0210000704546000231900884f2606180229579c7e"),
                position(Checks.ATTRIBUTES).attribute(Position.KEY_BATTERY_LEVEL, 79));

If this is changed to this one (not limited to Checks.ATTRIBUTES), it fails:

        verifyDecode(decoder, binary(
                "7e0210000704546000231900884f2606180229579c7e"),
                position().attribute(Position.KEY_BATTERY_LEVEL, 79));

-- Cheers, Nils

Anton Tananaev 17 hours ago

You can try using coordinates filter.

Nils Leideck 17 hours ago

Is there something like filter.skipLimit for coordinates.filter ? With coordinates.filter I already run into the problem that a device started with zero locations and never left that position.

Nils Leideck 17 hours ago

If not, would it make sense to submit a pull request for settings like coordinates.filter.skipLimit and/or coordinates.filter.skipAttributes?

Anton Tananaev 17 hours ago

No, it doesn't make sense. What would that parameter do? Something like zero filter would make more sense.

Nils Leideck 16 hours ago

With coordinates.filter.skipLimit I had in mind that coordinates are not replaced by last position if last position is older than XYZ. This would avoid devices to be freezed at some location when using coordinates filter. Do I confuse things maybe?

Anton Tananaev 16 hours ago

Yeah, what you're saying doesn't really make any sense. If you have newer valid position, Traccar will already use it.