sunfoxcz/apc-pdu
最新稳定版本:v0.3.0
Composer 安装命令:
composer require sunfoxcz/apc-pdu
包简介
PHP library for reading data from APC PDU AP8XXX series via SNMP (v1 and v3) with Network Port Sharing support
README 文档
README
PHP library for reading data from APC PDU AP8XXX series via SNMP (v1 and v3) or SSH with Network Port Sharing support.
Requirements
- PHP 8.2+
- One of the following backends:
ext-snmp- PHP SNMP extension (for Native client)net-snmp- System package (for Binary client)freedsx/snmp- Composer package (for FreeDSx client)ext-ssh2- PHP SSH2 extension (for SSH client)
Installation
composer require sunfoxcz/apc-pdu
Usage
SNMPv1 Connection
use Sunfox\ApcPdu\ApcPduFactory; use Sunfox\ApcPdu\DeviceMetric; use Sunfox\ApcPdu\OutletMetric; $pdu = ApcPduFactory::snmpV1('192.168.1.100', 'public');
SNMPv3 Connection
$pdu = ApcPduFactory::snmpV3( '192.168.1.100', 'monitor', 'AuthPassphrase', 'PrivPassphrase' );
Client Implementations
The library provides multiple SNMP client implementations with automatic discovery:
| Method | Description | Dependencies |
|---|---|---|
snmpV1() / snmpV3() |
Auto-detects best available client | Any of the below |
snmpV1Binary() / snmpV3Binary() |
Uses the snmpget binary via shell |
net-snmp package |
snmpV1FreeDsx() / snmpV3FreeDsx() |
Uses the FreeDSx SNMP library | freedsx/snmp composer package |
snmpV1Native() / snmpV3Native() |
Uses PHP's native SNMP functions | ext-snmp |
ssh() |
Uses SSH/CLI interface | ext-ssh2 |
Automatic Client Discovery
The snmpV1() and snmpV3() methods automatically detect and use the best
available SNMP client in priority order:
- Binary - Most efficient batch operations (
net-snmppackage) - FreeDSx - Efficient batch operations, pure PHP (
freedsx/snmp) - Native - Fallback, slower batch operations (
ext-snmp)
If no client is available, a NoSnmpClientAvailableException is thrown.
// Auto-detect best available client (recommended) $pdu = ApcPduFactory::snmpV3($host, $user, $authPass, $privPass); // Or explicitly choose a specific client: // Binary - requires net-snmp package (apt install snmp) $pdu = ApcPduFactory::snmpV3Binary($host, $user, $authPass, $privPass); // FreeDSx - pure PHP, no extensions required (composer require freedsx/snmp) $pdu = ApcPduFactory::snmpV3FreeDsx($host, $user, $authPass, $privPass); // Native - requires ext-snmp PHP extension $pdu = ApcPduFactory::snmpV3Native($host, $user, $authPass, $privPass); // SSH - uses CLI commands over SSH (requires ext-ssh2) $pdu = ApcPduFactory::ssh($host, $sshUser, $sshPass);
Performance Comparison
Benchmark results (SNMPv3, AP8653 PDU):
| Operation | Native | Binary | FreeDSx | SSH |
|---|---|---|---|---|
| Single device metric | 128 ms | 69 ms | 73 ms | 905 ms |
| Device metrics (batch) | 1.26 s | 200 ms | 215 ms | N/A* |
| Single outlet metric | 62 ms | 65 ms | 233 ms | 904 ms |
| Outlet metrics (batch) | 1.09 s | 213 ms | 229 ms | N/A* |
| All 24 outlets | 25.82 s | 7.07 s | 7.45 s | N/A* |
| Full PDU status | 54.74 s | 16.64 s | 13.72 s | N/A* |
*SSH uses an interactive shell which adds latency. It supports only a limited set of metrics (Power, Energy, ApparentPower, PowerFactor, Current, Name) and cannot retrieve full device/outlet status.
Recommendations:
- Native: Good for simple single-metric queries, requires
ext-snmp - Binary: Best batch performance, requires
net-snmpsystem package - FreeDSx: Best for full status dumps, pure PHP with no extension dependencies
- SSH: Alternative when SNMP is unavailable, limited metrics support
Run bin/benchmark to compare performance on your system. Use --ssh flag to
include SSH in the comparison.
Device-Level Metrics
// Get individual metrics (PDU 1 is default) $power = $pdu->getDevice(DeviceMetric::Power); // Returns watts $peak = $pdu->getDevice(DeviceMetric::PeakPower); // Returns watts $energy = $pdu->getDevice(DeviceMetric::Energy); // Returns kWh $name = $pdu->getDevice(DeviceMetric::Name); // Returns string $loadStatus = $pdu->getDevice(DeviceMetric::LoadStatus); // Returns int (1=Normal, 2=LowLoad, 3=NearOverload, 4=Overload) $apparentPower = $pdu->getDevice(DeviceMetric::ApparentPower); // Returns VA $powerFactor = $pdu->getDevice(DeviceMetric::PowerFactor); // Returns ratio (0.0-1.0) // Get all device metrics at once as DTO $device = $pdu->getDeviceStatus(); echo $device->powerW; // Current power in watts echo $device->peakPowerW; // Peak power in watts echo $device->energyKwh; // Total energy in kWh echo $device->name; // Device name echo $device->loadStatus->name; // LoadStatus enum (Normal, LowLoad, NearOverload, Overload) echo $device->apparentPowerVa; // Apparent power in VA echo $device->powerFactor; // Power factor (0.0-1.0) echo $device->outletCount; // Number of outlets echo $device->phaseCount; // Number of phases
Outlet-Level Metrics
// Get individual outlet metrics $name = $pdu->getOutlet(1, 5, OutletMetric::Name); $power = $pdu->getOutlet(1, 5, OutletMetric::Power); $current = $pdu->getOutlet(1, 5, OutletMetric::Current); $energy = $pdu->getOutlet(1, 5, OutletMetric::Energy); $state = $pdu->getOutlet(1, 5, OutletMetric::State); // 1=Off, 2=On // Get all metrics for one outlet as DTO $outlet = $pdu->getOutletStatus(1, 5); echo $outlet->name; // Outlet name echo $outlet->index; // Outlet index echo $outlet->state->name; // PowerState enum (Off, On) echo $outlet->currentA; // Current in amps echo $outlet->powerW; // Power in watts echo $outlet->peakPowerW; // Peak power in watts echo $outlet->energyKwh; // Energy in kWh echo $outlet->outletType; // Outlet type (e.g., "IEC C13") // Get all outlets for a PDU $outlets = $pdu->getAllOutlets(1);
Outlet Control (Write Operations)
use Sunfox\ApcPdu\OutletCommand; // Get an outlet object for control operations $outlet = $pdu->getOutlet(1, 5); // PDU 1, Outlet 5 // Power control $outlet->setState(OutletCommand::On); // Turn on $outlet->setState(OutletCommand::Off); // Turn off $outlet->setState(OutletCommand::Reboot); // Reboot (off then on) // Configuration $outlet->setName('Web Server'); $outlet->setExternalLink('https://example.com/server1'); // Power thresholds (in Watts) $outlet->setLowLoadThreshold(10); $outlet->setNearOverloadThreshold(400); $outlet->setOverloadThreshold(500);
Device Reset Operations
// Reset device-level counters $pdu->resetDevicePeakPower(1); // Reset peak power to current load $pdu->resetDeviceEnergy(1); // Reset energy meter to zero // Reset all outlet counters $pdu->resetOutletsPeakPower(1); // Reset all outlets peak power $pdu->resetOutletsEnergy(1); // Reset all outlets energy meters
Complete Status
// Get complete status for one PDU $pduInfo = $pdu->getPduInfo(1); echo $pduInfo->pduIndex; echo $pduInfo->device->powerW; foreach ($pduInfo->outlets as $outlet) { echo $outlet->name . ': ' . $outlet->powerW . 'W'; } // Get complete dump of all PDUs (stops when PDU not found) $status = $pdu->getFullStatus();
Network Port Sharing (NPS)
When multiple PDUs are daisy-chained (up to 4 PDUs supported), specify the PDU index as the second parameter:
use Sunfox\ApcPdu\DeviceMetric; // PDU 1 (Host) - default when no index specified $hostPower = $pdu->getDevice(DeviceMetric::Power); $hostPower = $pdu->getDevice(DeviceMetric::Power, 1); // Explicit // PDU 2 (Guest) $guest1Power = $pdu->getDevice(DeviceMetric::Power, 2); // PDU 3 and 4 (additional guests) $guest2Power = $pdu->getDevice(DeviceMetric::Power, 3); $guest3Power = $pdu->getDevice(DeviceMetric::Power, 4); // Get all metrics for specific PDU $device = $pdu->getDeviceStatus(2); // All metrics for PDU 2
Testing Connection
if ($pdu->testConnection()) { echo "PDU is reachable"; }
Available Metrics
Device Metrics (DeviceMetric)
| Metric | Unit | Description |
|---|---|---|
| ModuleIndex | - | Module index |
| PduIndex | - | PDU index |
| Name | string | Device name |
| LoadStatus | LoadStatus | Load status (Normal, LowLoad, NearOverload, Overload) |
| Power | W | Current power consumption |
| PeakPower | W | Peak power since last reset |
| PeakPowerTimestamp | datetime | When peak power occurred |
| PeakPowerStartTime | datetime | When peak power tracking started (last reset) |
| Energy | kWh | Total energy since last reset |
| EnergyStartTime | datetime | When energy tracking started (last reset) |
| ApparentPower | VA | Apparent power |
| PowerFactor | ratio | Power factor (0.0-1.0) |
| OutletCount | - | Number of outlets |
| PhaseCount | - | Number of phases |
| LowLoadThreshold | % | Low load warning threshold |
| NearOverloadThreshold | % | Near overload warning threshold |
| OverloadRestriction | - | Overload restriction setting |
Outlet Metrics (OutletMetric)
| Metric | Unit | Description |
|---|---|---|
| ModuleIndex | - | Module index |
| PduIndex | - | PDU index |
| Name | string | Outlet name/label |
| Index | int | Outlet index |
| State | PowerState | Power state (Off, On) |
| Current | A | Current draw |
| Power | W | Power consumption |
| PeakPower | W | Peak power |
| PeakPowerTimestamp | datetime | When peak power occurred |
| PeakPowerStartTime | datetime | When peak power tracking started (last reset) |
| Energy | kWh | Total energy |
| EnergyStartTime | datetime | When energy tracking started (last reset)* |
| OutletType | string | Outlet type (e.g., "IEC C13") |
| ExternalLink | string | External link URL |
*Note: EnergyStartTime for outlets is shared across all outlets on a PDU (comes from
device-level rPDU2DeviceStatusOutletsEnergyStartTime OID). When you reset an outlet's
energy, all outlets share the same start time.
Enums
use Sunfox\ApcPdu\LoadStatus; use Sunfox\ApcPdu\PowerState; use Sunfox\ApcPdu\OutletCommand; // LoadStatus values LoadStatus::Normal; // 1 LoadStatus::LowLoad; // 2 LoadStatus::NearOverload; // 3 LoadStatus::Overload; // 4 // PowerState values PowerState::Off; // 1 PowerState::On; // 2 // OutletCommand values (for write operations) OutletCommand::On; // 1 OutletCommand::Off; // 2 OutletCommand::Reboot; // 3
Tested Devices
- APC AP8653 (Metered by Outlet with Switching)
- Rack PDU FW: 7.1.4
- APC OS: 7.1.2
Development
Running Tests with Docker
# Create .env file with your PDU credentials cp .env.example .env # Edit .env with your settings # Run unit tests (default) docker compose run --rm php # Run integration tests (requires real PDU) docker compose run --rm integration # Run PHPStan analysis docker compose run --rm phpstan # Run PSR-12 coding style check docker compose run --rm phpcs # Auto-fix PSR-12 violations docker compose run --rm phpcbf # Run benchmark (requires real PDU) docker compose run --rm php bin/benchmark --help
Without Docker
composer install
composer test
License
MIT License. See LICENSE for details.
统计信息
- 总下载量: 82
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 5
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-29