Time Synchronization

Every data frame a device outputs carries a timestamp. After the SDK connects to a device, it synchronizes time automatically so device timestamps align with the host's UTC clock. This page explains what the timestamp means, how synchronization works, and how to trigger a sync manually.

Data frame timestamps

All data frames share the same FrameHeader, in which timestamp_us is a 64-bit microsecond timestamp. Its meaning depends on whether time synchronization has completed:

  • After sync: timestamp_us is a UTC timestamp in microseconds (a Unix timestamp), directly aligned with the host clock
  • Before sync: timestamp_us is device uptime, the number of microseconds since power-on

The device has no real-time clock (RTC) and counts from 0 at power-on. Time synchronization aligns this uptime counter to real UTC time.

How synchronization works

The SDK uses client-side time setting: the device does not fetch time on its own. Instead, the SDK pushes the host clock to the device.

The sync flow follows the NTP four-timestamp model — the SDK and device exchange a request/response pair and record four moments (request sent, device received, device replied, response received). From these, the SDK computes offset_us, the device clock's offset relative to host UTC, and pushes it to the device. The device then derives:

device_time = uptime_us + offset_us

This is a PTP-like lightweight synchronization that does not rely on standard PTP hardware. Sync accuracy depends on the network round-trip time between the SDK and the device.

Periodic auto-sync requires recent firmware. Earlier firmware applies the offset only on the first sync after connecting. Subsequent periodic syncs do not refresh the device clock. Upgrade to the latest firmware for full time synchronization.

Automatic synchronization

After the SDK connects to a device, it maintains time synchronization automatically, and applications usually do not need to intervene:

  • First sync: a full sync runs immediately when connect() completes
  • Periodic sync: after connecting, a background sync runs every 30 seconds by default to counter device crystal drift

The background sync interval is configured through ConnectOptions.auto_time_sync_interval_ms:

from wuji_sdk import ConnectOptions

# default 30 seconds
options = ConnectOptions()

# custom 10 seconds
options = ConnectOptions(auto_time_sync_interval_ms=10_000)

# disable background auto-sync
options = ConnectOptions(auto_time_sync_interval_ms=None)
ValueBehavior
Not setDefault 30000 (30 seconds)
NoneDisables background auto-sync
Integer (milliseconds)Custom interval, must be ≥ 100

When a session closes, the sync state clears automatically and re-syncs on the next connection.

Manual synchronization

To force a sync at a moment of your choice (for example, before a long recording or a time-sensitive operation), call the device's sync_time():

result = glove.sync_time()
print(f"Offset: {result.offset_us} us")
print(f"Round trip: {result.round_trip_us} us")
print(f"Synced at: {result.synced_at_us} us")

sync_time() is a blocking call. It triggers a full sync, pushes the offset to the device, and returns a TimeSyncResult:

FieldTypeDescription
offset_usintDevice clock offset. device_time = uptime_us + offset_us
round_trip_usintNetwork round-trip time of this sync (microseconds), measured with a monotonic clock. Smaller is more accurate
synced_at_usintHost UTC timestamp (microseconds) when this sync completed

The SDK already runs a built-in 30-second background auto-sync, so most use cases do not need to call sync_time() manually. Manual calls are useful in two cases: forcing an immediate sync before a time-sensitive operation, or inspecting the quality of the latest sync through the returned round_trip_us.

Timestamp monotonicity

timestamp_us is strictly monotonically increasing across all sync scenarios. Even when the host clock steps backward or a periodic sync computes a reverse offset, the device smooths the correction so the timestamp never jumps backward. Each frame's timestamp_us is greater than the previous one, so the field can be used directly for ordering frames and computing sample intervals.

Sync accuracy

Sync accuracy is determined mainly by the network round-trip time between the SDK and the device. TimeSyncResult.round_trip_us reflects this metric. The smaller the round-trip time, the more accurate the offset estimate. Over a direct wired Ethernet connection, round-trip time is typically on the order of a few hundred microseconds.

The periodic background sync continuously corrects device crystal drift, keeping the device clock aligned with host UTC even over long runs.