Output¶
Overview¶
Generic output control point for relays, actuators, and other binary control devices not covered by specialized functions like Door. Provides simple on/off control for auxiliary outputs and general-purpose relays.
- Added in: PQ Framework 2.1
- Namespace:
Pq.Adapters.Framework
When to Use¶
- Auxiliary relays (sirens, bells, strobes)
- General-purpose output relays
- Actuators (valves, motors, locks)
- LED/indicator control
- Any binary output not specifically covered by specialized functions
Do NOT use for:
- Door strikes/deadbolts (use
Doorfunction) - Reader feedback LEDs (use
Readerfunction) - Outputs requiring state feedback (extend function with custom actions)
States¶
Control States¶
| State | Status String | Description |
|---|---|---|
On |
pq.state.control.on |
Output activated (energized) |
Off |
pq.state.control.off |
Output deactivated (de-energized) |
Actions¶
State Transitions¶
Activated(timestamp)
- Description: Output activated (energize relay)
- Target State:
On - Events:
pq.event.control.activated - Usage: Turn on siren, open valve, energize lock
ActivatedRemote(timestamp)
- Description: Output activated by operator
- Target State:
On - Events:
pq.event.control.activated.remote - Usage: Operator-initiated activation from the management system
Deactivated(timestamp)
- Description: Output deactivated (de-energize relay)
- Target State:
Off - Events:
pq.event.control.deactivated - Usage: Turn off siren, close valve, de-energize lock
DeactivatedRemote(timestamp)
- Description: Output deactivated by operator
- Target State:
Off - Events:
pq.event.control.deactivated.remote - Usage: Operator-initiated deactivation from the management system
Properties¶
None. All configuration is adapter-specific. Define properties in adapter-registration.yaml if needed (e.g., pulse_duration_ms, normally_open).
YAML Example¶
device_types:
- type_id: AuxiliaryRelay
name: "Auxiliary Relay Output"
functions:
Output:
properties:
normally_open:
type: "bool"
default: true
description: "Relay type: true=NO, false=NC"
- type_id: SirenOutput
name: "Siren Output"
functions:
Output:
properties:
pulse_duration_ms:
type: "int"
default: 0
description: "Pulse duration (0=continuous, >0=pulse)"
max_activation_minutes:
type: "int"
default: 5
description: "Maximum siren activation time"
Code Usage¶
public class SirenOutputThing : Thing
{
public OutputFunction Relay { get; }
public async Task HandleAlarmEvent(AlarmEvent evt, CancellationToken ct)
{
if (evt.IsAlarmCondition)
{
await Relay.Activated(DeviceTimestamp.UtcNow);
// schedule auto-deactivation
_ = Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromMinutes(5), ct);
await Relay.Deactivated(DeviceTimestamp.UtcNow);
}, ct);
}
else
{
await Relay.Deactivated(DeviceTimestamp.UtcNow);
}
}
}
Command Handling¶
Outputs typically respond to commands from the PQ server or local automation:
public class RelayOutputThing : Thing
{
public OutputFunction Relay { get; }
protected override async Task HandleCommand(Output.Activate cmd, CancellationToken ct)
{
// send activation command to device
await Device.ActivateRelay(cmd.OutputId, ct);
// reflect state change
await Relay.Activated(DeviceTimestamp.UtcNow);
}
protected override async Task HandleCommand(Output.Deactivate cmd, CancellationToken ct)
{
await Device.DeactivateRelay(cmd.OutputId, ct);
await Relay.Deactivated(DeviceTimestamp.UtcNow);
}
}
Notes¶
- Simple Control: Output function provides minimal state machine for binary control
- No Feedback: Output assumes command success. For feedback monitoring, add custom properties/states
- Pulse Mode: Adapter implements pulse/timed activation logic based on device capabilities
- Command Names: Framework commands
Output.ActivateandOutput.Deactivatemap to theActivated/Deactivatedfunction actions - Remote Variants:
ActivatedRemote/DeactivatedRemotedistinguish operator-initiated changes from device-local activation - Interlocking: Adapter responsible for mutual exclusion logic if outputs share resources