Custom Event Sources
Every input to the SEI daemon (nvpss_daemon) arrives through one client library,
libnvpssd_interface. The shipped clients use it: mdx_client reports safety events, SAIM
(safety_monitor) reports sensor verdicts, PCM (nv_perception_monitor) reports AI-pipeline
verdicts, and the NvPSD Gateway heartbeats the daemon. A custom event source or monitor uses the
same library and is held to the same rules.
This page covers the client contract. How the daemon fuses and routes what it receives is on
Safety Event Integrator. Every nvpss.conf key named
here is described on SEI Configuration.
Library and link
The development package at this release installs pss_protocol.h but not pss_daemon.h, which
the sample below includes. The declarations it provides are listed in API and
Client types.
A minimal event source registers as a numbered MDX client, heartbeats, and reports one event per heartbeat:
Build it against both libraries:
API
Every call returns NVPSSD_SUCCESS (0) or NVPSSD_FAIL. The reason for a refusal is logged by
the daemon, not returned. There is no initialisation call and no automatic reconnect: after the
daemon restarts, a client must register again.
Client types
There is no generic type; any other value is refused. That gives two cases:
- An event source registers as
CLIENT_MDX. Give it a numbered instance so that the daemon supervises it by name (see Required sources and presence). Both launchers already runmdx_clientas instance 1, so pick another number. - A sensor or AI-pipeline monitor must register as
CLIENT_SAFETY_MONITORorCLIENT_PERCEPTION_MONITOR. Each is a single slot, so it replaces SAIM or PCM rather than running beside it. The launchers start SAIM and PCM according to--saim-modeand--pcm-mode; see Launchers.
Register
What the daemon does with a registration:
If the client already holding a single slot is in heartbeat fault, the daemon evicts it and
accepts the newcomer, and logs REGISTER_CLIENT: evicted fault-latched stale singleton.
Capacity and timing:
- The daemon holds 8 client connections. A ninth is closed and logged as
admission dropped: no free client slot. The reference stack uses 4: SAIM, PCM, the gateway andmdx_client. - A connection that has not registered when the heartbeat timeout (6500 ms) has passed is closed
on the next 5-second check:
Closing unregistered connection: registration timeout. - The returned
clientIdencodes the daemon’s slot in its low 8 bits. Copy(uint8_t)clientIdintofusionMetadata.clientIDof every event you report.
Heartbeat
Send NvPSSSendHeartbeat(clientId, clientType) every 5000 ms (HB_INTERVAL_MS), with the same
clientType you registered with. A heartbeat with a different type disconnects the client.
The daemon checks every client once per 5-second tick. A client whose last heartbeat is older than
6500 ms (HB_TIMEOUT_MS) gets one miss on that tick. With M = max_hb_failures from
nvpss.conf (1 to 255; the shipped file sets 50):
With the shipped value of 50, a client that stops heartbeating is declared failed between about
4 minutes 12 seconds and 4 minutes 17 seconds later, depending on where the 5-second tick falls. A trust report (SENSOR_*, AI_PIPELINE_*) is also refused if the
reporter’s last heartbeat is older than 6500 ms.
What every SDM is told when a client is lost:
Every SDM latches on these. A loss of SAIM, PCM or a numbered instance clears only when that same
source registers and heartbeats again. The SAIM heartbeat also sets the daemon’s mode: DEGRADED
above the warn tier, ERROR at M.
The library does not retry or reconnect for you. mdx_client, for example, exits after 10
consecutive failed heartbeats, 5 seconds apart, and logs
PSS heartbeat ACK failure limit reached — PSS presumed dead, exiting.
Report events
Fill a SafetyEvent from pss_protocol.h:
There is no severity field. The daemon assigns OPERATIONAL or CRITICAL itself.
The daemon checks each report in this order and answers with the first failure:
The client sees only NVPSSD_FAIL and logs
safety event reporting by client <id> rejected with the status number.
A report that passes is accepted, and the call returns success, before its sensor identity is
checked. An identity that does not match the configuration is dropped later and logged by the
daemon (for example Rejecting event: sensorIdentifier '<name>' does not match sensor_config entry '<expected>' for pipelineID <n>).
The client is not told, and this drop does not count towards the rejection streak below.
Trust reports
Rules that follow from the daemon’s behaviour:
- A verdict is a level, not an event. The daemon keeps the last verdict until the monitor sends the opposite one. Losing the monitor does not clear it; restarting the daemon does.
- Send on change, and repeat. SAIM and PCM send each verdict when it changes and repeat it:
SAIM every 30 seconds, PCM every 5 seconds. The daemon itself re-sends every standing
INVALIDverdict to the SDMs once per status interval, so an SDM that restarts relearns it (see the safe-state model). - Cause. Put the reason in
cause. OnSENSOR_INVALID,CAUSE_SAIM_INIT(1) marks a start-up seed that SDMs do not count as a failed sensor; every other value counts. The values are on Causes and Records. - 3D. In a 3D deployment the BEV group’s health is derived from its member cameras. A
SENSOR_*report that names the group is refused:Trust report rejected: pipelineID names a sensor group, whose health is derived from its members and cannot be reported directly.
Identity rules
The daemon reads sensor_config.conf and, in 3D, the group file. It does not read
sensor_pipelines_config.conf; that file is read by mdx_client, to turn Kafka sensor names into
pipeline ids in 3D, and by the SDMs. File formats are on
Sensor files.
Required sources and presence
nvpss.conf names the sources a deployment must run. All three keys are mandatory, and the daemon
refuses to start if one is missing, repeated or out of range.
How the daemon tracks sources:
- Present. A source is present once it has registered and sent at least one heartbeat, and while it is not in heartbeat fault.
- Tracked. SAIM, PCM and every numbered
CLIENT_MDXinstance are tracked whether or not they are required. If one is lost, every SDM latches until that source is back. - Never registered. A required source that has not registered when the heartbeat budget has
run out since the daemon started is reported lost once, with reason
never_registered. The budget is 6500 ms plusmax_hb_failures - 1times 5000 ms, checked on the 5-second tick: about 4 minutes 12 seconds with the shipped value of 50. From then on every SDM expects it, including an SDM that starts later. - Presence report. Every status no-op (every
status_noop_interval_ms, 5000 ms in the shipped file) carries causeCAUSE_SOURCE_PRESENCE(16) with two sets: the sources present now, and the sources expected. An SDM raises a loss for a source it knows of that is missing from the present set, and clears it only when the report names that source again.
Anonymous CLIENT_MDX clients are not tracked by name. Use a numbered instance for any source the
deployment depends on, and count it in required_mdx_instances. The key covers instances 1 to N,
so requiring instance 2 also requires instance 1.
Rejection streak
A source that keeps sending reports the daemon rejects is live but unusable. The daemon counts consecutive rejected reports per client; any accepted report resets the count.
Checklist
- Run with the same primary group as the SEI daemon. See Shared process group.
- Register with the right type and, for an event source, a numbered instance that is not 1.
- Heartbeat every 5 s with the registered type. Register again if the daemon restarts.
- Fill
fusionMetadata.clientIDwith(uint8_t)clientId, a uniqueid, a monotonictimestamp, and a confidence of at least 0.6. - Use the pipeline id and name from the identity file for the deployment mode.
- Add the source to
required_*innvpss.confif the deployment depends on it. - Call
NvPSSTerminatePSSClient()on shutdown. For a tracked source this is reported to the SDMs as a loss, which is the intended fail-safe behaviour.