ConnectionBase¶
Overview¶
Provides basic handling of communication with the device. Every Thing automatically gets a Connection property from this function to manage connection lifecycle, health monitoring, and reconnection logic.
- Added in: PQ Framework 2.0
- Namespace:
Pq.Adapters.Framework
When to Use¶
- All device types automatically include this function
- Manages device connectivity lifecycle
- Monitors communication health and reliability
- Handles automatic reconnection
- Reports connection state to the framework
Note: This is a special function with extended_construction: true, meaning the framework provides extended initialization logic and automatic reconnection handling.
States¶
Connection Lifecycle¶
| State | Description | Status String |
|---|---|---|
Online |
Device connected and communicating | pq.state.connection.online |
Offline |
Device disconnected or unreachable | pq.state.connection.offline |
Degraded |
Connection unstable or experiencing issues | pq.state.connection.degraded |
Actions¶
None. ConnectionBase does not expose custom actions. State transitions are managed internally by the framework through:
Thing.ConnectedAsync()- Called by adapter when connection establishedThing.DisconnectedAsync()- Called by adapter when connection lost- Framework automatic reconnection logic
- Health monitoring and degradation detection
Properties¶
None. All connection configuration is framework-managed or adapter-specific. Define connection properties in adapter-registration.yaml if needed (e.g., connection_timeout_seconds, keepalive_interval_seconds).
Events¶
ConnectionBase does not declare events of its own. The framework may publish connection-lifecycle notifications (connected, disconnected, quality degraded) as part of its internal state management; adapters do not raise these directly.
YAML Example¶
device_types:
- type_id: AccessController
name: "Access Control Panel"
functions:
ConnectionBase: # automatically included
Door:
properties:
# connection-specific properties (adapter-defined)
connection_timeout_seconds:
type: "int"
default: 30
description: "Connection timeout in seconds"
keepalive_interval_seconds:
type: "int"
default: 60
description: "Keepalive interval in seconds"
- type_id: NetworkReader
name: "Network-Connected Reader"
functions:
ConnectionBase: # automatically included
Reader:
properties:
ip_address:
type: "string"
required: true
description: "Device IP address"
Code Usage¶
Basic Connection Management¶
public class AccessControllerThing : Thing
{
private readonly TcpClient _client = new();
public override async Task InitializeAsync(CancellationToken ct)
{
// Start connection attempt
await ConnectAsync(ct);
}
private async Task ConnectAsync(CancellationToken ct)
{
try
{
await _client.ConnectAsync(IpAddress, Port, ct);
// Notify framework of successful connection
await ConnectedAsync(ct);
// Start event processing loop
_ = ProcessEventsAsync(ct);
}
catch (Exception ex)
{
Logger.LogError(ex, "Connection failed");
// Framework will retry automatically
}
}
private async Task ProcessEventsAsync(CancellationToken ct)
{
try
{
while (!ct.IsCancellationRequested)
{
var message = await _client.ReadMessageAsync(ct);
await HandleDeviceMessage(message, ct);
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Connection lost");
// Notify framework of disconnection
await DisconnectedAsync(ct);
// Framework will handle reconnection
}
}
}
Health Monitoring with Degradation Detection¶
public class NetworkControllerThing : Thing
{
private int _consecutiveTimeouts = 0;
private const int DegradationThreshold = 3;
private async Task<bool> SendCommandAsync(byte[] command, CancellationToken ct)
{
try
{
await _client.SendAsync(command, ct);
var response = await _client.ReceiveAsync(TimeSpan.FromSeconds(5), ct);
// Reset timeout counter on success
_consecutiveTimeouts = 0;
return true;
}
catch (TimeoutException)
{
_consecutiveTimeouts++;
// Report degraded state after threshold
if (_consecutiveTimeouts >= DegradationThreshold)
{
Logger.LogWarning("Connection degraded: {Count} consecutive timeouts",
_consecutiveTimeouts);
// Framework detects degradation via health checks
}
return false;
}
}
}
Manual Disconnection Control¶
public class SerialDeviceThing : Thing
{
private SerialPort? _serialPort;
public override async Task InitializeAsync(CancellationToken ct)
{
_serialPort = new SerialPort(PortName, BaudRate);
_serialPort.Open();
await ConnectedAsync(ct);
}
protected override async Task OnShutdownAsync(CancellationToken ct)
{
// Clean disconnection before shutdown
await DisconnectedAsync(ct);
_serialPort?.Close();
_serialPort?.Dispose();
}
}
Notes¶
- Automatic Inclusion: Every
Thingautomatically getsConnectionBase- you don't need to explicitly add it to YAML unless defining connection properties - Extended Construction: The framework provides automatic reconnection logic, connection pooling, and health monitoring
- No Direct Action Methods: Unlike other functions, you don't call
Connection.SomeAction(). Instead, useThing.ConnectedAsync()andThing.DisconnectedAsync() - Framework Responsibility: Connection state management is primarily handled by the framework. Adapters notify state changes, framework handles the rest.
- Reconnection Logic: Framework automatically retries failed connections with exponential backoff
- Health Checks: Framework periodically checks connection health and transitions to
Degradedstate if issues detected
See Also¶
- Concepts: Functions - Function architecture and patterns
- Reference: Generated Code API - Using generated function classes
- Patterns: Connection Management - Implementing device connections
- Functions: Power - Power monitoring (often paired with connection monitoring)