Documentation
Events
Events travel from a PD to a Control Panel. In Python each event is a frozen dataclass in the osdp.events module. A PD reports one with PeripheralDevice.submit_event; a CP receives it from ControlPanel.get_event or a registered event handler.
Because each event is its own type, a match statement gives you exactly the right fields with no dictionary lookups:
match cp.get_event(101):
case events.CardRead(data=data, format=fmt):
print(f"card {data.hex()} ({fmt.name})")
case events.KeyPress(data=keys):
print(f"keys {keys!r}")
case events.Status(report=report):
print(f"status {report!r}")
Card and keypad
CardRead
A card was presented to a reader. For the raw formats, bits is the exact bit count and data is the packed payload; for ASCII, data is the character bytes. format is a CardFormat:
A card was presented to a reader.
For the raw formats the card is a bit string whose length is not necessarily a multiple of eight, so `bits` carries the real length and `data` is that many bits padded out to whole bytes. For the ASCII format the card is bytes and `bits` does not apply.
Example:
A 26-bit Wiegand card needs four bytes to hold its 26 bits:
>>> event = CardRead(format=CardFormat.Wiegand,
... data=bytes([0x01, 0x02, 0x03, 0x40]), bits=26)
>>> event.bits
26
Leave `bits` out and it is taken to be all of the data:
>>> event = CardRead(format=CardFormat.Wiegand, data=b"\\x01\\x02")
>>> event.bits
16intCardFormatbytesNoneEncoding of the data in a `CardRead` event.
UnspecifiedWiegandASCIIKeyPress
Keys were entered on a reader's keypad.
Keys were pressed on a reader's keypad.
Example:
>>> event = KeyPress(data=b"1234")
>>> event.data
b'1234'intbytesBiometrics
BioRead
A PD's answer to a commands.BioRead — the captured template and its quality. status is a BioStatus:
A PD's answer to a `commands.BioRead`.
The template and quality are only meaningful when `status` is Success. Note there is no format field: the reply does not restate the encoding that was asked for.
Example:
>>> event = BioRead(status=BioStatus.Success,
... type=BioType.RightThumbPrint, quality=200,
... data=b"template")
>>> event.status.name
'Success'
A failed scan carries no template:
>>> BioRead(status=BioStatus.Timeout).data
b''intBioStatusBioTypebytesA template larger than one packet is delivered only when both roles enable the opt-in multi-part flag; see Multi-part Messages.
Outcome of a biometric read or match.
The values are sparse; UnknownError is 0xFF.
SuccessTimeoutUnknownErrorBioMatch
A PD's answer to a commands.BioMatch — whether the scan matched and the score.
A PD's answer to a `commands.BioMatch`.
The score is only meaningful when `status` is Success.
Example:
>>> event = BioMatch(status=BioStatus.Success, score=250)
>>> event.score
250intBioStatusSmartcard
A PD's answers to the smartcard commands, carrying the payload reassembled from the multi-part reply. On the PD side, submit these to answer the corresponding command — from inside the command handler for an inline reply, or later for delivery on a subsequent poll.
A PD's answer to a `commands.PivData`: the PIV object contents.
On the CP, the event carries the payload reassembled from the multi-part reply. On the PD, submit this event (from within the command callback for an inline reply, or later for delivery on a subsequent poll) and libosdp fragments it on the wire.
bytesA PD's answer to a `commands.GenAuth`: the authenticate response.
Delivery semantics match `PivData`.
bytesA PD's answer to a `commands.CrAuth`: the challenge response.
Delivery semantics match `PivData`.
bytesStatus and manufacturer
Status
A status report from the PD (inputs, outputs, tamper, power). type is a StatusReportType.
A PD's status report.
Example:
>>> event = Status(type=StatusReportType.Input, report=bytes([0, 1, 0]))
>>> list(event.report)
[0, 1, 0]StatusReportTypebytesManufacturer
Vendor-specific replies and status/error notifications.
A vendor-specific reply from the PD.
Example:
>>> event = ManufacturerReply(vendor_code=0x00030201, data=b"\\x01")
>>> event.vendor_code
197121intbytesA vendor-specific status reply from the PD.
Unlike `ManufacturerReply` this carries no vendor code; interpret it using the vendor code from the PD's id.
Example:
>>> event = ManufacturerStatus(data=b"\\x01\\x02")
>>> ManufacturerStatus().data
b''bytesA vendor-specific error reply from the PD.
Carries the same payload as `ManufacturerStatus` but is a distinct event, so a handler can tell an error apart from a status without inspecting the bytes.
Example:
>>> event = ManufacturerError(data=b"\\xff")
>>> event.ID.name
'ManufacturerError'bytesNotification
A library-generated notification, delivered as an event when notifications are enabled. Beyond the raw type/arg0/arg1 fields, Notification exposes computed properties (succeeded, sc_active, pd_online, file_id, file_tx_outcome) that decode the arguments for the notification kind. type is a NotificationType.
A library notification delivered to a CP app.
Produced by the library, not by a peer, when `LibFlag.EnableNotification` is set. Apps never submit this.
Each `type` carries its own typed fields; only those relevant to the type are meaningful. The properties below name the common readings.
Example:
>>> note = Notification(type=NotificationType.Command,
... command=int(CommandId.LED), success=True)
>>> note.command_id.name
'LED'
>>> note.succeeded
TrueNotificationTypeintboolcommand_id(self) -> CommandIdWhich command completed. Only for NotificationType.Command.
succeeded(self) -> boolWhether that command succeeded. Only for NotificationType.Command.
sc_active(self) -> boolWhether the secure channel is up.
Only for NotificationType.SecureChannelStatus.
pd_online(self) -> boolWhether the PD is reachable.
Only for NotificationType.PeripheralDeviceStatus.
file_id(self) -> intWhich file was transferred.
Only for NotificationType.Multipart* (reads object_id).
pd_id(self) -> PdIdThe collected PD identity. Only for NotificationType.PdId.
mp_outcome(self) -> MpOutcomeHow the transfer ended.
Only for NotificationType.MultipartDone (reads outcome).
See also
- Peripheral Device — how events are submitted and completed.
- Commands — the payloads a CP sends.
- API Reference — the remaining enums and supporting types.