IntrusionDetector¶
Overview¶
Generic intrusion detection sensor covering all types: PIR motion, magnetic contact, glass break, shock, vibration, curtain, dual-tech. The adapter selects appropriate actions based on the physical sensor type.
- Added in: PQ Framework 2.1
- Namespace:
Pq.Adapters.Framework
When to Use¶
- PIR motion detectors
- Magnetic contact sensors (door/window)
- Glass break detectors
- Shock/vibration sensors
- Curtain/beam sensors
- Dual-technology sensors
- Any intrusion detection sensor
States¶
Detection Lifecycle¶
| State | Description | Status String |
|---|---|---|
Normal |
No detection condition present | pq.state.detection.clear |
PreAlarm |
Threshold exceeded, approaching alarm | pq.state.intrusion.prealarm |
Alarm |
Full alarm condition triggered | pq.state.intrusion.alarm |
Fault |
Sensor malfunction detected | pq.state.supervision.fault |
Trouble |
Detector malfunction or fault | pq.state.supervision.trouble |
Masked |
Sensor masked or obstructed | pq.state.intrusion.masked |
Calibrating |
Sensor calibration in progress | pq.state.supervision.test.calibrating |
Testmode |
Walk test or diagnostic mode active | pq.state.supervision.test |
Motion-Specific States¶
| State | Description | Status String |
|---|---|---|
Motiondetected |
Active motion sensed | pq.state.detection.motion.active |
Motioncleared |
Motion stopped, settling period | pq.state.detection.motion.idle |
Contact-Specific States¶
| State | Description | Status String |
|---|---|---|
Opened |
Door/barrier is in open position | pq.state.position.open |
Closed |
Door/barrier is in closed position | pq.state.position.closed |
Intrusion Overrides¶
| State | Description | Status String |
|---|---|---|
Bypassed |
Excluded from security monitoring | pq.state.intrusion.bypassed |
Tampered |
Device enclosure opened or tampered | pq.state.intrusion.tamper |
Actions¶
Alarm Events¶
Alarm(timestamp)
- Description: Intrusion alarm triggered
- Target State:
Alarm - Events:
pq.event.intrusion.alarm(Critical) - Usage: Sensor detected intrusion condition
PreAlarm(timestamp)
- Description: Pre-alarm condition (threshold warning)
- Target State:
PreAlarm - Events:
pq.event.intrusion.prealarm(Warn) - Usage: Entry delay zone triggered
Cleared(timestamp)
- Description: Alarm condition cleared, return to normal
- Target State:
Normal - Events:
pq.event.intrusion.cleared(Info)
Tamper Events¶
Tamper(timestamp)
- Description: Tamper detected (enclosure opened)
- Target State:
Tampered - Events:
pq.event.intrusion.tamper(Critical)
TamperRestored(timestamp)
- Description: Tamper condition restored
- Target State:
Normal - Events:
pq.event.intrusion.tamper.cleared(Info)
Fault Events¶
Fault(timestamp)
- Description: Sensor fault detected
- Target State:
Fault - Events:
pq.event.supervision.fault(Warn)
FaultRestored(timestamp)
- Description: Sensor fault restored
- Target State:
Normal - Events:
pq.event.technical.fault.cleared(Info)
Masked/Blocked Events¶
Masked(timestamp)
- Description: Sensor masked or obstructed
- Target State:
Masked
MaskedRestored(timestamp)
- Description: Masking condition cleared
- Target State:
Normal
Bypass Events¶
Bypassed(timestamp, personId, zoneName, reason?) (custom)
- Description: Detector bypassed by operator
- Target State:
Bypassed - Events:
pq.event.intrusion.bypassed(Info) - Parameters:
personId(Guid) - Person who performed bypasszoneName(string) - Name of zone being bypassedreason(string?) - Optional reason for bypass- Usage: Operator manually excluded detector from monitoring
BypassCancelled(timestamp)
- Description: Bypass cancelled, return to normal monitoring
- Target State:
Normal - Events:
pq.event.intrusion.bypassed.cleared(Info)
Motion Detection (PIR, Dual-Tech)¶
MotionDetected(timestamp)
- Description: Motion detected by sensor
- Target State:
Motiondetected - Events:
pq.event.intrusion.motion.detected(Info)
MotionCleared(timestamp)
- Description: Motion cleared
- Target State:
Motioncleared - Events:
pq.event.intrusion.motion.cleared(Info)
Contact (Magnetic Contacts)¶
ContactOpen(timestamp)
- Description: Contact opened (door/window opened)
- Target State:
Opened - Events:
pq.event.intrusion.contact.open(Warn)
ContactClosed(timestamp)
- Description: Contact closed (door/window closed)
- Target State:
Closed - Events:
pq.event.intrusion.contact.closed(Info)
Special Events¶
ForcedEntry(timestamp, personId?, zoneId?) (custom)
- Description: Forced entry detected
- Events:
pq.event.intrusion.entry.forced(Critical) - Parameters:
personId(Guid?) - Optional person identifierzoneId(Guid?) - Optional zone identifier- Usage: Contact opened while partition armed
TestModeActivated(timestamp)
- Description: Walk test mode activated
- Target State:
Testmode - Events:
pq.event.intrusion.testing.started(Info)
TestModeDeactivated(timestamp)
- Description: Walk test mode deactivated
- Target State:
Normal - Events:
pq.event.intrusion.testing.completed(Info)
Life-Safety Events (panic / medical / hold-up)¶
Intrusion and life-safety share the security domain, so panic, medical, and hold-up calls are
actions on this function. They publish the pq.event.safety.panic.* family (distinct from
burglary intrusion.*, because they trigger a different operational response — ambulance/police
dispatch). Fire is the exception: it has its own FireDetector function.
Panic(timestamp)
- Description: Panic / hold-up alarm raised
- Target State:
Alarm - Events:
pq.event.safety.panic(Critical)
Medical(timestamp)
- Description: Medical-call alarm raised
- Target State:
Alarm - Events:
pq.event.safety.panic.medical(Critical)
Police(timestamp)
- Description: Police / duress hold-up alarm raised
- Target State:
Alarm - Events:
pq.event.safety.panic.police(Critical)
PanicCleared(timestamp)
- Description: Panic / medical condition cleared
- Target State:
Normal - Events:
pq.event.safety.panic.cleared(Info)
Properties¶
None. All configuration is adapter-specific. Define properties in adapter-registration.yaml if needed (e.g., sensitivity, supervision_type).
YAML Example¶
device_types:
- type_id: PIRMotionDetector
name: "PIR Motion Detector"
functions:
IntrusionDetector:
properties:
sensitivity:
type: "int"
default: 50
range: [0, 100]
description: "Sensor sensitivity (0=min, 100=max)"
supervision_type:
type: "string"
default: "eol"
description: "Supervision: none, eol, deol, digital"
- type_id: DoorContact
name: "Magnetic Door Contact"
functions:
IntrusionDetector:
properties:
supervision_type:
type: "string"
default: "eol"
Code Usage¶
public class PIRDetectorThing : Thing
{
public IntrusionDetectorFunction Detector { get; }
protected override async Task HandleDeviceEvent(DetectorEvent evt, CancellationToken ct)
{
switch (evt.Type)
{
case DetectorEventType.MotionDetected:
await Detector.MotionDetected(evt.Timestamp);
break;
case DetectorEventType.MotionCleared:
await Detector.MotionCleared(evt.Timestamp);
break;
case DetectorEventType.Tamper:
await Detector.Tamper(evt.Timestamp);
break;
case DetectorEventType.Fault:
await Detector.Fault(evt.Timestamp);
break;
}
}
public async Task HandleBypass(Intrusion.Bypass cmd, CancellationToken ct)
{
await Detector.Bypassed(
DeviceTimestamp.UtcNow,
cmd.OperatorIdentity,
zoneName: this.Name,
reason: "Manual bypass"
);
}
}
Notes¶
- Generic Design: IntrusionDetector is intentionally generic to support all sensor types in one function
- Adapter Chooses Actions: PIR sensors call
MotionDetected(), contacts callContactOpen(), glass break callsAlarm() - Bypass Ownership: Bypass is on the detector, not the partition. Partition reflects aggregate bypass state if needed.
- Fire Detection: Fire is a separate FireDetector function with fire-specific events (
pq.event.fire.*); panic/medical/hold-up, however, live here as life-safety actions.