Skip to content

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 Status id Description
Disarmed intrusion.disarmed Monitoring disabled
Armed intrusion.armed Fully armed - all zones active
ArmedInstant intrusion.armed.instant Armed with no entry delay
ArmedDelay intrusion.armed.delay Armed with entry delay
ArmedPartial intrusion.armed.partial Partial arming (stay/night mode)

Transitional States

State Status id Description
Exit intrusion.exit Exit delay period after arming
Entry intrusion.entry Entry delay period before alarm

Alarm States

State Status id Description
Prealarm intrusion.prealarm Entry delay zone triggered
Alarm intrusion.alarm Intrusion alarm active

Operational States

State Status id Description
TestWalktest supervision.test.walktest Walk test diagnostic mode

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 armed
  • armMode (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 armed
  • armMode (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 armed
  • armMode (string?) - Optional mode description (defaults to "partial")
  • Usage: User armed partition in stay/night mode

ArmedPartialRemote(timestamp)

  • Description: Partition partially armed remotely
  • Target State: ArmedPartial
  • Events: pq.event.intrusion.armed.partial.remote (Info)

ArmedPartialStay(timestamp)

  • Description: Partition armed in stay mode
  • Target State: ArmedPartial
  • Events: pq.event.intrusion.armed.partial.stay (Info)

ArmedPartialStayRemote(timestamp)

  • Description: Partition armed remotely in stay mode
  • Target State: ArmedPartial
  • Events: pq.event.intrusion.armed.partial.stay.remote (Info)

ArmedPartialSleep(timestamp)

  • Description: Partition armed in sleep mode
  • Target State: ArmedPartial
  • Events: pq.event.intrusion.armed.partial.sleep (Info)

ArmedPartialSleepRemote(timestamp)

  • Description: Partition armed remotely in sleep mode
  • Target State: ArmedPartial
  • Events: pq.event.intrusion.armed.partial.sleep.remote (Info)

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)

ArmedExitDelayRemote(timestamp)

  • Description: Partition arming exit delay started remotely
  • Target State: Exit
  • Events: pq.event.intrusion.armed.exit_delay.remote (Info)

ArmedForced(timestamp)

  • Description: Partition force armed
  • Target State: Armed
  • Events: pq.event.intrusion.armed.forced (Warn)

ArmedForcedBypass(timestamp)

  • Description: Partition armed with bypassed zones
  • Target State: Armed
  • Events: pq.event.intrusion.armed.forced.bypass (Warn)

ArmedForcedRemote(timestamp)

  • Description: Partition force armed remotely
  • Target State: Armed
  • Events: pq.event.intrusion.armed.forced.remote (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)

DisarmedAlarmRemote(timestamp)

  • Description: Partition disarmed remotely during active alarm
  • Target State: Disarmed
  • Events: pq.event.intrusion.disarmed.alarm.remote (Warn)

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)

AlarmAcknowledged(timestamp)

  • Description: Alarm acknowledged by operator
  • Events: pq.event.intrusion.alarm.acknowledged (Info)

AlarmAcknowledgedRemote(timestamp)

  • Description: Alarm acknowledged remotely by operator
  • Events: pq.event.intrusion.alarm.acknowledged.remote (Info)

Diagnostic

WalkTestStarted(timestamp)

  • Description: Walk test diagnostic mode activated
  • Target State: TestWalktest
  • 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

Life-Safety (panic / medical / fire buttons)

Partition-level distress calls raised at the panel or keypad with no owning zone Thing, parallel to the IntrusionDetector life-safety actions. They set the single partition alarm state, so AlarmCleared clears them like any other partition alarm.

Panic(timestamp)

  • Description: Panic / hold-up alarm raised on the partition
  • Target State: Alarm
  • Events: pq.event.safety.panic (Critical)

PanicFire(timestamp)

  • Description: Fire panic button raised on the partition
  • Target State: Alarm
  • Events: pq.event.safety.panic.fire (Critical)

PanicMedical(timestamp)

  • Description: Medical panic button raised on the partition
  • Target State: Alarm
  • Events: pq.event.safety.panic.medical (Critical)

PanicCleared(timestamp)

  • Description: Panic / medical / fire condition cleared on the partition
  • Target State: Disarmed
  • Events: pq.event.safety.panic.cleared (Info)

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 _pendingArmState field 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 via the intrusion.bypassed status id.
  • No Timers: Unlike Door function, 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