Zones¶
A zone is a geofence — polygon, circle, or rectangle — used by the RTLS to fire entry/exit events when tags move in or out. Zones come in two flavors: static (a fixed shape on the floorplan) and dynamic (the shape follows a tag's position).
Quick reference¶
| Method | What it does |
|---|---|
client.zones.list() |
All zones in scope. |
client.zones.get(uid) |
Fetch one zone by uid. |
client.zones.create(name, *, dynamic=False, tag_uid=None, **fields) |
Create a zone; for dynamic zones, bind a tag in the same call. Geometry (shape, points, radius_m) is passed through **fields. |
client.zones.update(uid, *, tag_uid=None, **fields) |
Update; reconciles the dynamic-zone binding if it changed. |
client.zones.delete(uid) |
Delete; clears any dynamic-zone reference on the bound tag. |
client.zones.history(start, end) |
Time series of geometry changes in the window. |
client.zones.list_custom_prototypes() |
Server-defined zone-type prototypes available in this deployment. |
client.zones.create_raw / update_raw / delete_raw |
Single-call REST escape hatches. |
client.zones.download_request(tag_uids, *, action="UPDATE") |
Trigger (or verify) the SZM→tag zone-download wire push for one or more tags. |
client.zones.download_status(tag_uid=None) |
Per-tag zone-download sync status — all tags, or one. |
Static vs dynamic zones¶
A static zone has a fixed shape (polygon points, circle radius). A dynamic zone is bound to a tag — the shape follows that tag's last known position. Useful for "exclusion bubble around the forklift" or "follow-the-operator" workflows.
# Static polygon
static = client.zones.create(
name="Loading dock",
shape="polygon",
points=[(0, 0), (100, 0), (100, 50), (0, 50)],
)
# Dynamic: 5 m bubble that follows tag t-1
dynamic = client.zones.create(
name="Forklift bubble",
shape="circle",
radius_m=5.0,
dynamic=True,
tag_uid="t-1",
)
For a dynamic zone, create performs the zone-create + tags.update
(setting self_zone_uid) in one compound call. Rollback on partial
failure raises PartialFailureError.
Update — dynamic-zone re-binding¶
If tag_uid changes on a dynamic zone, update clears the old
binding and sets the new one — also a compound, also with rollback.
The partial-failure case "old binding cleared but new binding failed"
leaves completed_steps=["clear_old_binding"] so a retry knows where
to resume.
Delete¶
For dynamic zones, delete also clears the tag's self_zone_uid
reference. The *_raw variant deletes only the zone row — leaves a
stale reference on the tag.
Zone download (SZM → tag LZM sync)¶
Zones only take effect on a tag once they're pushed down and the tag's
Local Zone Manager (LZM) confirms it. download_request triggers the
push (same action as SiteWise's "start zone download" button);
download_status polls the per-tag sync outcome. The request call
does not block on the push completing — poll status separately.
client.zones.download_request(["t-1"])
# ... poll until synced ...
statuses = client.zones.download_status("t-1")
assert statuses[0].download_status == "UPDATED"
Pass action="VERIFY" to ask the tag to report its current state
without re-pushing. download_request accepts multiple tags in one
call:
download_status() with no argument returns every tag's status, not
just one:
for status in client.zones.download_status():
if status.download_status != "UPDATED":
print(f"{status.tag_uid}: {status.download_status}")
download_statusrows are keyed bytag_uid, not the zone's ownuid. The two are unrelated identifiers — a status row tells you whether this tag's current zone set has synced, not which zone is out of date. To find which zones are stale for a tag, cross-referencetags.get(uid).self_zone_uidandzones.list()separately.
Model — Zone¶
| Field | Type | Notes |
|---|---|---|
uid |
str |
Server-assigned. |
name |
str |
Required. |
shape |
str \| None |
"polygon", "circle", etc. |
dynamic |
bool |
True if the zone follows a tag. |
tag_uid |
str \| None |
The bound tag's uid (dynamic only). |
Geometry inputs (points, radius_m) are accepted on create via
**fields but are not surfaced as typed fields on the returned Zone.
Model — ZoneDownloadStatus¶
| Field | Type | Notes |
|---|---|---|
tag_uid |
str |
The tag this sync-status row is for. SDK-canonical name for the server's trackable_uid. |
download_status |
str |
One of "OUTDATED", "IN_PROCESS", "UPDATED", "OOSYNC" — the server's own vocabulary, kept verbatim. |
ts |
datetime \| None |
When this status was last updated, if the server reports one. |
reason |
str \| None |
Present on some rows (e.g. why a sync is OOSYNC), absent on others. |
sync_requested |
bool \| None |
Present on some rows, absent on others. |
Related entities¶
- Tags: a dynamic zone's
tag_uidpoints at a Tag.tags.create(attached_zone=...)is the inverse helper.download_request/download_statusare also keyed by tag — see Tags for the entity itself. - Areas: zones live inside an Area, set via the
area_uidcreate input. - Events: zone entry/exit fire as
ZoneEvents — see Events.
See also¶
- Error handling —
PartialFailureError.failed_stepstrings:create_zone,set_tag_binding,load_zone,clear_old_binding,set_new_binding,update_zone. - Compound workflows — the dynamic-zone binding saga.