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 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 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

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 _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 pq.state.intrusion.bypassed status.
  • 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