Repository navigation
Detail Helpers
Raw XML access is nice for fidelity, tedious for daily work. The helper layer gives you typed access for the blocks that matter — without giving up the lossless detail tree underneath.
Three layers:
-
Setters — upsert a known block into
detail - Factories — create a complete event for a common use case in one call
- Predicates — quick "what am I looking at" checks
All setters return the event, so they chain. They upsert: an existing block gets its mentioned attributes replaced, unmentioned ones kept, and any unknown sibling blocks are never touched.
| Setter | Writes |
|---|---|
set_contact(callsign, endpoint=None, phone=None) |
<contact> |
set_group(name, role) |
<__group> team membership |
set_track(speed=..., course=...) |
<track> movement vector |
set_remarks(text) |
<remarks> free text |
set_status(readiness=True, battery=None) |
<status> |
set_precision_location(geopointsrc=None, altsrc=None) |
<precisionlocation> |
set_color(argb) |
<color> signed ARGB (-65536 = red) |
event.set_contact("MYCALL").set_group("Cyan", "Team Member").set_color(-16711936)Important
Team names and roles have a limited set of valid values. set_group()
validates both and raises ValueError listing the valid options. See
takstream.cot.VALID_TEAMS / VALID_ROLES.
marker = CotEvent.marker(
48.208, 16.373,
callsign="PIT",
remarks="landmark", # optional
color_argb=-65536, # optional
)Produces type b-m-p-s-m with contact/remarks/color detail blocks.
sa = CotEvent.sa_report(
48.208, 16.373,
callsign="MYCALL",
team="Cyan",
role="Team Member",
speed=5.0, course=90.0, # optional
battery=88, # optional
)Produces type a-f-G-U-C with contact/group and optional track/status.
chat = CotEvent.chat_message(
"roger that",
sender_callsign="ALPHA",
sender_uid="ANDROID-123",
chatroom="All Chat Rooms", # default
)Produces type b-t-f — the current ATAK 5.8 wire format, where the text
travels in <remarks> and <__chat> carries the routing metadata with a
nested <chatgrp>. Do not copy examples using b-a-o-t with a msg
attribute; that is ancient history.
delivery = CotEvent.chat_receipt(chat, receipt_type="b-t-f-d", responder_callsign="BRAVO")
read = CotEvent.chat_receipt(chat, receipt_type="b-t-f-r", responder_callsign="BRAVO")Mirrors the routing metadata of the original message so the server routes
the receipt back to the sender. Event uid and __chatreceipt/@messageId
reference the original message.
alert = CotEvent.emergency_alert(48.2, 16.3, callsign="MYCALL")
cancel = CotEvent.emergency_cancel(uid=alert.uid, callsign="MYCALL")Alert produces type b-a-o-tif, cancel produces b-a-o-can.
| Predicate | True for |
|---|---|
is_sa() |
Position reports (a-f-, a-u-, a-n-) |
is_marker() |
User-placed markers (b-m-) |
is_chat() |
GeoChat messages and receipts (b-t-f*) |
is_emergency() |
Alerts (b-a-o-tif) and cancellations (b-a-o-can) |
is_stale() |
Events past their stale time |
Every factory output round-trips through the wire format — covered by tests, not by optimism.