Partition¶
Overview¶
Logical alarm group containing detectors with independent arming state. Called Area, Partition, Section, or Group by different intrusion vendors.
- Added in: PQ Framework 2.1
- Namespace:
Pq.Adapters.Framework - Construction:
extended_construction: true(adapter provides constructor)
When to Use¶
- Intrusion alarm panels with zones/areas
- Security partitions in commercial systems
- Logical grouping of detectors for independent arming
- Any system supporting partial arming (stay/night modes)
States¶
Arming States¶
| State | Description | Status String |
|---|---|---|
Disarmed |
Monitoring disabled | pq.state.intrusion.disarmed |
Armed |
Fully armed - all zones active | pq.state.intrusion.armed |
ArmedInstant |
Armed with no entry delay | pq.state.intrusion.armed.instant |
ArmedDelay |
Armed with entry delay | pq.state.intrusion.armed.delay |
ArmedPartial |
Partial arming (stay/night mode) | pq.state.intrusion.armed.partial |
Transitional States¶
| State | Description | Status String |
|---|---|---|
Exit |
Exit delay period after arming | pq.state.intrusion.exit |
Entry |
Entry delay period before alarm | pq.state.intrusion.entry |
Alarm States¶
| State | Description | Status String |
|---|---|---|
Prealarm |
Entry delay zone triggered | pq.state.intrusion.prealarm |
Alarm |
Intrusion alarm active | pq.state.intrusion.alarm |
Operational States¶
| State | Description | Status String |
|---|---|---|
Walktest |
Walk test diagnostic mode | pq.state.supervision.test.walktest |
Actions¶
Arming¶
Armed(timestamp, personId, armMode?) (custom)
- Description: Partition armed (full protection)
- Target State:
Armed - Events:
pq.event.intrusion.armed(Info) - Parameters:
personId(Guid) - Person who armedarmMode(string?) - Optional mode description (defaults to "full")- Usage: User armed partition in full mode
ArmedInstant(timestamp, personId, armMode?) (custom)
- Description: Partition armed with no entry delay
- Target State:
ArmedInstant - Events:
pq.event.intrusion.armed(Info) - Parameters:
personId(Guid) - Person who armedarmMode(string?) - Optional mode description (defaults to "instant")- Usage: User armed partition in instant mode
ArmedPartial(timestamp, personId, armMode?) (custom)
- Description: Partition armed in stay/night mode
- Target State:
ArmedPartial - Events:
pq.event.intrusion.armed(Info) - Parameters:
personId(Guid) - Person who armedarmMode(string?) - Optional mode description (defaults to "partial")- Usage: User armed partition in stay/night mode
ArmedSchedule(timestamp)
- Description: Partition armed by schedule
- Target State:
Armed - Events:
pq.event.intrusion.armed.schedule(Info)
ArmedRemote(timestamp)
- Description: Partition armed remotely
- Target State:
Armed - Events:
pq.event.intrusion.armed.remote(Info)
ArmedForced(timestamp)
- Description: Partition force armed (zones bypassed)
- Target State:
Armed - Events:
pq.event.intrusion.armed.forced(Warn)
ArmingFailed(timestamp)
- Description: Arming attempt failed (zones not ready)
- Events:
pq.event.intrusion.arming.failed(Warn)
ArmingDenied(timestamp)
- Description: Arming attempt denied (no permission)
- Events:
pq.event.intrusion.arming.denied(Warn)
Disarming¶
Disarmed(timestamp)
- Description: Partition disarmed
- Target State:
Disarmed - Events:
pq.event.intrusion.disarmed(Info)
DisarmedSchedule(timestamp)
- Description: Partition disarmed by schedule
- Target State:
Disarmed - Events:
pq.event.intrusion.disarmed.schedule(Info)
DisarmedRemote(timestamp)
- Description: Partition disarmed remotely
- Target State:
Disarmed - Events:
pq.event.intrusion.disarmed.remote(Info)
DisarmedAlarm(timestamp)
- Description: Partition disarmed during active alarm
- Target State:
Disarmed - Events:
pq.event.intrusion.disarmed.alarm(Info)
DisarmingFailed(timestamp)
- Description: Disarming attempt failed
- Events:
pq.event.intrusion.disarming.failed(Warn)
DisarmingDenied(timestamp)
- Description: Disarming attempt denied (no permission)
- Events:
pq.event.intrusion.disarming.denied(Warn)
Delay Periods¶
ExitDelayStarted(timestamp)
- Description: Exit delay period started after arming
- Target State:
Exit
ExitDelayExpired(timestamp) (custom)
- Description: Exit delay completed, partition now armed
- Custom Logic: Transitions to the pending armed state (Armed/ArmedInstant/ArmedPartial)
- Usage: Exit delay timer expired
EntryDelayStarted(timestamp)
- Description: Entry delay triggered, countdown before alarm
- Target State:
Entry
EntryDelayExpired(timestamp)
- Description: Entry delay expired, triggering alarm
- Target State:
Alarm - Events:
pq.event.intrusion.alarm(Critical)
Alarm¶
PrealarmTriggered(timestamp)
- Description: Entry zone activated during armed state
- Target State:
Prealarm - Events:
pq.event.intrusion.prealarm(Warn)
AlarmTriggered(timestamp)
- Description: Intrusion alarm triggered
- Target State:
Alarm - Events:
pq.event.intrusion.alarm(Critical)
AlarmCleared(timestamp)
- Description: Alarm condition cleared
- Target State:
Disarmed - Events:
pq.event.intrusion.cleared(Info)
Diagnostic¶
WalkTestStarted(timestamp)
- Description: Walk test diagnostic mode activated
- Target State:
Walktest - Events:
pq.event.intrusion.testing.started(Info)
WalkTestEnded(timestamp)
- Description: Walk test mode deactivated
- Target State:
Disarmed - Events:
pq.event.intrusion.testing.completed(Info)
Special¶
DuressDetected(timestamp, personId?) (custom)
- Description: Duress code entered during disarm
- Custom Logic: Disarms partition normally but publishes silent alarm
- Target State:
Disarmed - Events:
pq.event.intrusion.duress(Critical) - Parameters:
personId(Guid?) - Optional person identifier- Usage: User entered duress PIN
RearmRequired(timestamp)
- Description: Elevated authorization required to rearm
- Target State:
Armed
Properties¶
None. All configuration is adapter-specific. Timing properties (entry/exit delay, auto-rearm) are typically device-configured, not framework-managed. Define in adapter-registration.yaml if needed.
YAML Example¶
device_types:
- type_id: IntrusionPanel
name: "Intrusion Alarm Panel"
functions:
Partition:
properties:
entry_delay_seconds:
type: "int"
default: 30
range: [0, 300]
description: "Entry delay (device-side configuration)"
exit_delay_seconds:
type: "int"
default: 60
range: [0, 300]
supports_partial_arming:
type: "bool"
default: true
- type_id: PartitionController
name: "Alarm Partition"
functions:
Partition:
ConnectionBase:
Power:
Code Usage¶
Basic Arming¶
public class PartitionThing : Thing
{
public PartitionFunction Partition { get; }
public PartitionThing(Thing parent) : base(parent)
{
Partition = new PartitionFunction(this);
}
protected override async Task HandleDeviceEvent(PartitionEvent evt, CancellationToken ct)
{
switch (evt.Type)
{
case PartitionEventType.Armed:
await Partition.Armed(evt.Timestamp, evt.PersonId, evt.ArmMode);
break;
case PartitionEventType.Disarmed:
await Partition.Disarmed(evt.Timestamp);
break;
case PartitionEventType.AlarmTriggered:
await Partition.AlarmTriggered(evt.Timestamp);
break;
}
}
}
Command Handling¶
public async Task HandleArmCommand(Intrusion.Arm cmd, CancellationToken ct)
{
// send command to device
await Protocol.SendArmCommand(cmd.OperatorIdentity, ct);
// start exit delay
await Partition.ExitDelayStarted(DeviceTimestamp.UtcNow);
// framework tracks exit delay expiration
_ = Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(ExitDelaySeconds), ct);
await Partition.ExitDelayExpired(DeviceTimestamp.UtcNow);
}, ct);
}
public async Task HandleDisarmCommand(Intrusion.Disarm cmd, CancellationToken ct)
{
await Protocol.SendDisarmCommand(cmd.OperatorIdentity, ct);
await Partition.Disarmed(DeviceTimestamp.UtcNow);
}
Duress Handling¶
protected override async Task HandleDeviceEvent(PartitionEvent evt, CancellationToken ct)
{
if (evt.Type == PartitionEventType.DuressCode)
{
// silently disarm but raise critical alarm
await Partition.DuressDetected(evt.Timestamp, evt.PersonId);
}
}
Notes¶
- Extended Construction: Partition requires manual constructor because the generated class omits it (
extended_construction: true) - Exit Delay Logic:
ExitDelayExpired()uses internal_pendingArmStatefield to restore the correct armed state (Armed/ArmedInstant/ArmedPartial) - Bypass Not Here: Detector bypass is on
IntrusionDetector, not Partition. Partition can reflect aggregate bypass state if needed viapq.state.intrusion.bypassedstatus. - No Timers: Unlike
Doorfunction, Partition does not manage entry/exit delay timers -- adapter handles timing based on device capabilities.
Constructor Pattern¶
Since extended_construction: true, you must provide constructor:
public partial class PartitionFunction
{
// Framework requires this constructor
public PartitionFunction(Thing owner) : base(owner) { }
}
See Also¶
- Functions: IntrusionDetector - Intrusion sensors
- Functions: Power - Power monitoring for panels