Data produced by the SonoMarc module
Entity
One entity per seat, named PlatformName/SeatName, id a stable hash of that same string. Every discovered seat is published every capture tick, whether or not anything on it changed.
Each seat entity carries a LinkedEntityComponent
pointing at a parent_entity_id computed from the platform’s name - but this module never
publishes an EntityState for that platform id itself. A consumer following that link to find
the platform entity will not find one published by this module; the platform’s own position
(when available) is instead attached directly to the seat entity’s own
WorldPositionComponent.
Position
Only populated when SonoMarc reports the platform’s position with source: "geographic"
(latitude/longitude/altitude). A platform whose position is reported as "geocentric" publishes
no WorldPositionComponent at all in this version - that source shape is recognised but not yet
converted. heading is always published as 0; this module does not read a heading value from
SonoMarc at all, regardless of what the platform reports.
Radio and intercom assets
One RadioComponent per radio, intercom or relay
asset on the seat, with asset_name, asset_type, frequency_tx, frequency_rx,
frequency_dual, radio_band, secure_enabled, volume and squelch_level read from
SonoMarc’s own current state each tick.
selected is always published false. The parsing code sets it to false with a comment
promising it will be “updated via SSE events” - but nothing in this module ever actually updates
it after that. There is no way to tell which radio a seat has selected from this module’s output
in this version.
Activity events
Transmit, receive and push-to-talk activity arrive over SonoMarc’s event stream, not on a fixed
poll, so they reflect real timing rather than being bounded by Interval. Each fires both a
TrackingEvent and, for transmit/receive/PTT
specifically, a CommsEvent carrying comms_type: COMMS_TYPE_VOICE,
frequency (the asset’s frequency_tx), target (seat key and asset name joined by a slash), secure and
radio_band from that asset’s current state.
The tracking-event mapping has three real gaps, not only naming quirks:
| SonoMarc signal | Tracking event | Note |
|---|---|---|
| Transmit on / off | VOICE_TRANSMISSION_STARTED / _ENDED | Symmetric - both directions fire |
| Receive on | RECEIVED | Receive ending fires no event at all - there is no “reception ended” signal |
| Push-to-talk: normal, priority, or emergency | VOICE_TRANSMISSION_STARTED (push-to-talk off: _ENDED) | The normal/priority/emergency distinction is lost - all three map to the same started event, and the distinguishing value is not carried into the published CommsEvent either |
| Asset selected, or squelch toggled | INTERCOM_STATE_CHANGED | Both map to the identical event type - you cannot tell from the event stream alone which of the two happened |
| Secure toggled on, or off | TRANSMITTER_STATE_CHANGED | Both directions map to the identical event type - the event tells you secure mode changed, not which way |
Malfunctions
A microphone or speaker fault beginning or clearing publishes a
FaultEvent (fault_type: "microphone" or "speaker",
state: FAULTS_STATE_ACTIVATED or FAULTS_STATE_RESOLVED). Like the radio/intercom state above,
this is detected by comparing this tick’s polled value against the last one - see
Configure for why a fault that both starts and clears inside one
Interval window can be missed.
Virtual-person voice commands
A recognised voice command from a virtual platform publishes two separate events at once: a
CommsEvent (comms_type: COMMS_TYPE_TTS, target the virtual person’s name, content the raw
command JSON) and a JsonEventData named
sonomarc_voice_command carrying the same JSON as structured data. Both carry the identical
payload in different shapes; a consumer only needs one of the two, not both.