PHPackages                             sunfoxcz/apc-pdu - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. sunfoxcz/apc-pdu

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

sunfoxcz/apc-pdu
================

PHP library for reading data from APC PDU AP8XXX series via SNMP (v1 and v3) with Network Port Sharing support

v0.3.0(3mo ago)082MITPHPPHP &gt;=8.2

Since Jan 29Pushed 3mo agoCompare

[ Source](https://github.com/sunfoxcz/apc-pdu)[ Packagist](https://packagist.org/packages/sunfoxcz/apc-pdu)[ RSS](/packages/sunfoxcz-apc-pdu/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (4)Versions (5)Used By (0)

APC PDU Library
===============

[](#apc-pdu-library)

PHP library for reading data from APC PDU AP8XXX series via SNMP (v1 and v3) or SSH with Network Port Sharing support.

Requirements
------------

[](#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
------------

[](#installation)

```
composer require sunfoxcz/apc-pdu
```

Usage
-----

[](#usage)

### SNMPv1 Connection

[](#snmpv1-connection)

```
use Sunfox\ApcPdu\ApcPduFactory;
use Sunfox\ApcPdu\DeviceMetric;
use Sunfox\ApcPdu\OutletMetric;

$pdu = ApcPduFactory::snmpV1('192.168.1.100', 'public');
```

### SNMPv3 Connection

[](#snmpv3-connection)

```
$pdu = ApcPduFactory::snmpV3(
    '192.168.1.100',
    'monitor',
    'AuthPassphrase',
    'PrivPassphrase'
);
```

### Client Implementations

[](#client-implementations)

The library provides multiple SNMP client implementations with automatic discovery:

MethodDescriptionDependencies`snmpV1()` / `snmpV3()`**Auto-detects** best available clientAny 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

[](#automatic-client-discovery)

The `snmpV1()` and `snmpV3()` methods automatically detect and use the best available SNMP client in priority order:

1. **Binary** - Most efficient batch operations (`net-snmp` package)
2. **FreeDSx** - Efficient batch operations, pure PHP (`freedsx/snmp`)
3. **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

[](#performance-comparison)

Benchmark results (SNMPv3, AP8653 PDU):

OperationNativeBinaryFreeDSxSSHSingle device metric128 ms69 ms73 ms905 msDevice metrics (batch)1.26 s200 ms215 msN/A\*Single outlet metric62 ms65 ms233 ms904 msOutlet metrics (batch)1.09 s213 ms229 msN/A\*All 24 outlets25.82 s7.07 s7.45 sN/A\*Full PDU status54.74 s16.64 s13.72 sN/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-snmp` system 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

[](#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

[](#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)

[](#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

[](#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

[](#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)

[](#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

[](#testing-connection)

```
if ($pdu->testConnection()) {
    echo "PDU is reachable";
}
```

Available Metrics
-----------------

[](#available-metrics)

### Device Metrics (DeviceMetric)

[](#device-metrics-devicemetric)

MetricUnitDescriptionModuleIndex-Module indexPduIndex-PDU indexNamestringDevice nameLoadStatusLoadStatusLoad status (Normal, LowLoad, NearOverload, Overload)PowerWCurrent power consumptionPeakPowerWPeak power since last resetPeakPowerTimestampdatetimeWhen peak power occurredPeakPowerStartTimedatetimeWhen peak power tracking started (last reset)EnergykWhTotal energy since last resetEnergyStartTimedatetimeWhen energy tracking started (last reset)ApparentPowerVAApparent powerPowerFactorratioPower factor (0.0-1.0)OutletCount-Number of outletsPhaseCount-Number of phasesLowLoadThreshold%Low load warning thresholdNearOverloadThreshold%Near overload warning thresholdOverloadRestriction-Overload restriction setting### Outlet Metrics (OutletMetric)

[](#outlet-metrics-outletmetric)

MetricUnitDescriptionModuleIndex-Module indexPduIndex-PDU indexNamestringOutlet name/labelIndexintOutlet indexStatePowerStatePower state (Off, On)CurrentACurrent drawPowerWPower consumptionPeakPowerWPeak powerPeakPowerTimestampdatetimeWhen peak power occurredPeakPowerStartTimedatetimeWhen peak power tracking started (last reset)EnergykWhTotal energyEnergyStartTimedatetimeWhen energy tracking started (last reset)\*OutletTypestringOutlet type (e.g., "IEC C13")ExternalLinkstringExternal 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

[](#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
--------------

[](#tested-devices)

- APC AP8653 (Metered by Outlet with Switching)
- Rack PDU FW: 7.1.4
- APC OS: 7.1.2

Development
-----------

[](#development)

### Running Tests with Docker

[](#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

[](#without-docker)

```
composer install
composer test
```

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

###  Health Score

37

—

LowBetter than 82% of packages

Maintenance86

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

3

Last Release

97d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/404311acad630d4698613e2ceae18f8b9b268aa1ed5eb73feb2a4f1679a29bf2?d=identicon)[sunfoxcz](/maintainers/sunfoxcz)

---

Top Contributors

[![foxycode](https://avatars.githubusercontent.com/u/1284781?v=4)](https://github.com/foxycode "foxycode (21 commits)")

---

Tags

monitoringapcsnmppowerpduap8653network-port-sharing

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/sunfoxcz-apc-pdu/health.svg)

```
[![Health](https://phpackages.com/badges/sunfoxcz-apc-pdu/health.svg)](https://phpackages.com/packages/sunfoxcz-apc-pdu)
```

###  Alternatives

[rollbar/rollbar

Monitors errors and exceptions and reports them to Rollbar

33723.7M81](/packages/rollbar-rollbar)[liip/monitor-bundle

Liip Monitor Bundle

4728.7M16](/packages/liip-monitor-bundle)[datadog/php-datadogstatsd

An extremely simple PHP datadogstatsd client

19124.6M15](/packages/datadog-php-datadogstatsd)[ekino/newrelic-bundle

Integrate New Relic into Symfony2

28111.2M8](/packages/ekino-newrelic-bundle)[rollbar/rollbar-laravel

Rollbar error monitoring integration for Laravel projects

14110.4M7](/packages/rollbar-rollbar-laravel)[analog/analog

Fast, flexible, easy PSR-3-compatible PHP logging package with dozens of handlers.

3451.5M24](/packages/analog-analog)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
