dept-of-scrapyard-robotics / pwm-rgb-fan
A PHP package for controlling RGB LEDs and Fan Speed on a PWM-controlled fan.
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/dept-of-scrapyard-robotics/pwm-rgb-fan
Requires
- php: ^8.3
- ext-phpixel: *
- ext-pwm: *
- ext-sockets: *
- dept-of-scrapyard-robotics/pwm-fan-control: ^0.2.0
- phpdafruit/neopixel-php: ^0.1
Requires (Dev)
- mockery/mockery: ^1.6
- pestphp/pest: ^4.1
README
A modern PHP 8.3+ library for controlling PWM-driven fans with integrated RGB LEDs on embedded Linux devices. This package extends pwm-fan-control by adding synchronized RGB LED control, combining fan motor and lighting into one elegant API.
Features
- Combined Control: Synchronize fan speed and RGB colors with single method calls
- Temperature Visualization: Automatic color gradients based on temperature (blue → cyan → green → yellow → red)
- Advanced Effects: Breathing, rainbow, spinning rainbow, and party mode
- Speed Indicator: RGB colors automatically reflect fan speed
- Full Inheritance: All PWMFan methods available (ramping, pulsing, temperature control)
- Flexible RGB: Direct access to underlying RGB channel for custom effects
- Type-Safe: Full PHP 8.3+ type hints and return type declarations
- Chainable Methods: Fluent API for readable, expressive code
Requirements
- PHP 8.3 or higher
- php-pwm extension installed
- phpixel extension installed
- phpdafruit/neopixel-php package
- dept-of-scrapyard-robotics/pwm-fan-control package
- Embedded Linux device with PWM and SPI support (Jetson Orin Nano, Raspberry Pi, etc.)
- PWM device nodes exported (e.g.,
/sys/class/pwm/pwmchip3/pwm0
) - SPI device nodes accessible (e.g.,
/dev/spidev1.0
)
Installation
Install via Composer
composer require dept-of-scrapyard-robotics/pwm-rgb-fan
This will automatically install the required dependencies:
dept-of-scrapyard-robotics/pwm-fan-control
phpdafruit/neopixel-php
Install Required Extensions
Before using this library, ensure both extensions are installed:
Core Concepts
RGBPWMFan
An RGBPWMFan
extends PWMFan
and adds synchronized RGB LED control. It automatically selects the appropriate RGB controller (DoubleDots
for 2-LED fans, PixelChannel
for others) and provides methods that control both fan and LEDs together.
Basic Usage
use DeptOfScrapyardRobotics\PWM\Fans\RGB\RGBPWMFan; use PhpdaFruit\NeoPixels\Enums\NeoPixelType; // Create RGB fan controller $fan = new RGBPWMFan( '/sys/class/pwm/pwmchip3/pwm0', // PWM device '/dev/spidev1.0', // SPI device for RGB NeoPixelType::GRB, // LED color order 2 // Number of LEDs ); // Set speed and color together $fan->setSpeedWithColor(50.0, 0x00FF00); // 50% speed, green // Color indicates speed automatically $fan->setSpeed(75.0); $fan->speedIndicator(); // Red-ish color for high speed // Turn off both fan and RGB $fan->shutdown();
API Reference
Construction
public function __construct( string $pwm_path, string $spi_device_path, NeoPixelType $pixel_type = NeoPixelType::RGB, int $no_lights = 2, int $frequency = 1000 )
Creates a new RGBPWMFan instance.
- Parameters:
$pwm_path
- Path to PWM device (e.g.,/sys/class/pwm/pwmchip3/pwm0
)$spi_device_path
- Path to SPI device (e.g.,/dev/spidev1.0
)$pixel_type
- LED color order (default:NeoPixelType::RGB
)$no_lights
- Number of RGB LEDs (default: 2)$frequency
- PWM frequency in Hz (default: 1000)
Example:
$fan = new RGBPWMFan( '/sys/class/pwm/pwmchip3/pwm0', '/dev/spidev1.0', NeoPixelType::GRB, 2, 1000 );
Combined Control Methods
setSpeedWithColor()
public function setSpeedWithColor(float $speed, int $color): static
Set fan speed and RGB color simultaneously.
$fan->setSpeedWithColor(60.0, 0xFF00FF); // 60% speed, purple
speedIndicator()
public function speedIndicator(): static
Automatically set RGB color based on current fan speed. Blue (0%) → Red (100%).
$fan->setSpeed(75.0); $fan->speedIndicator(); // RGB shows red-ish color
temperatureVisual()
public function temperatureVisual(float $temp, float $minTemp = 40.0, float $maxTemp = 80.0): static
Adjust both fan speed AND RGB color based on temperature. Creates gradient: Blue (cool) → Cyan → Green → Yellow → Red (hot).
$temp = $fan->getCPUTemp(); $fan->temperatureVisual($temp, 40.0, 80.0); // Fan + RGB respond to temp
RGB Effects
breathe()
public function breathe(int $color = 0x00FFFF, int $cycles = 3, int $duration_ms = 2000, float $minSpeed = 30.0, float $maxSpeed = 80.0): static
Synchronized breathing effect - fan speed and RGB brightness fade together.
$fan->breathe(0x00FFFF, 3, 2000, 30.0, 80.0); // Cyan breathing
rainbow()
public function rainbow(float $speed = 50.0, int $duration_ms = 2000, int $cycles = 3): static
Rainbow color cycle at specified fan speed.
$fan->rainbow(75.0, 2000, 3); // Rainbow at 75% speed
spinningRainbow()
public function spinningRainbow(float $speed = 75.0, int $rotations = 5, int $speed_ms = 500): static
Spinning rainbow effect (best for 2-LED fans). Creates illusion of rotating colors.
$fan->spinningRainbow(75.0, 5, 500);
party()
public function party(int $duration_ms = 10000): static
Random colors and fan speeds for party effect.
$fan->party(10000); // 10 seconds of party mode
shutdown()
public function shutdown(int $duration_ms = 2000): static
Gracefully fade out both fan and RGB simultaneously.
$fan->shutdown(3000); // 3-second fade to off
Direct RGB Access
getRGBChannel()
public function getRGBChannel(): PixelChannel|DoubleDots
Get the underlying RGB channel for direct manipulation using neopixel-php methods.
// Access DoubleDots methods $fan->getRGBChannel()->split(0xFF0000, 0x0000FF)->show(); // Red/Blue $fan->getRGBChannel()->alternate(0x00FF00, 5); // Green flashing $fan->getRGBChannel()->crossfade(0xFF00FF, 0x00FFFF); // Color morph // Access PixelChannel methods $fan->getRGBChannel()->fill(0xFFFFFF)->show(); // White $fan->getRGBChannel()->rotate(1)->show(); // Rotate pixels
Inherited Methods
All methods from PWMFan
are available:
Basic Control:
on()
- Turn on at last speedoff()
- Turn off fansetSpeed(float $percent)
- Set speed 0-100%getSpeed()
- Get current speedisRunning()
- Check if runninggetStatus()
- Detailed status
Effects:
rampUp(float $target, int $duration_ms, int $steps)
- Smooth ramp uprampDown(float $target, int $duration_ms, int $steps)
- Smooth ramp downpulse(float $low, float $high, int $cycles, int $duration_ms)
- Pulsing effect
Temperature:
autoControl(float $temp, float $min, float $max, float $minSpeed)
- Auto fan controlgetCPUTemp(int $zone)
- Read CPU temperature
Presets:
setPreset(string $preset)
- Use preset: 'off', 'low', 'medium', 'high', 'full'
Usage Examples
Example 1: Basic Combined Control
use DeptOfScrapyardRobotics\PWM\Fans\RGB\RGBPWMFan; use PhpdaFruit\NeoPixels\Enums\NeoPixelType; $fan = new RGBPWMFan( '/sys/class/pwm/pwmchip3/pwm0', '/dev/spidev1.0', NeoPixelType::GRB, 2 ); // Set speed with color $fan->setSpeedWithColor(50.0, 0x0000FF); // 50%, blue sleep(2); // Use speed indicator $fan->setSpeed(75.0); $fan->speedIndicator(); // Automatic color sleep(2); // Graceful shutdown $fan->shutdown();
Example 2: Temperature-Based Control
use DeptOfScrapyardRobotics\PWM\Fans\RGB\RGBPWMFan; use PhpdaFruit\NeoPixels\Enums\NeoPixelType; $fan = new RGBPWMFan( '/sys/class/pwm/pwmchip3/pwm0', '/dev/spidev1.0', NeoPixelType::GRB, 2 ); // Monitor temperature with visual feedback while (true) { $temp = $fan->getCPUTemp(); $fan->temperatureVisual($temp, 40.0, 80.0); echo "Temp: {$temp}°C, Fan: {$fan->getSpeed()}%\n"; sleep(2); }
Example 3: RGB Effects
use DeptOfScrapyardRobotics\PWM\Fans\RGB\RGBPWMFan; use PhpdaFruit\NeoPixels\Enums\NeoPixelType; $fan = new RGBPWMFan( '/sys/class/pwm/pwmchip3/pwm0', '/dev/spidev1.0', NeoPixelType::GRB, 2 ); // Breathing effect $fan->breathe(0x00FFFF, 3, 2000); // Cyan, 3 cycles // Rainbow $fan->rainbow(60.0, 2000, 2); // 60% speed, 2 cycles // Spinning rainbow $fan->spinningRainbow(75.0, 5, 500); // 5 rotations // Party mode $fan->party(5000); // 5 seconds // Shutdown $fan->shutdown(3000);
Example 4: Direct RGB Control
$fan = new RGBPWMFan( '/sys/class/pwm/pwmchip3/pwm0', '/dev/spidev1.0', NeoPixelType::GRB, 2 ); // Set fan speed separately $fan->setSpeed(60.0); // Use DoubleDots methods directly $rgb = $fan->getRGBChannel(); $rgb->split(0xFF0000, 0x0000FF)->show(); // Red left, blue right sleep(2); $rgb->alternate(0x00FF00, 5); // Green alternating sleep(2); $rgb->crossfade(0xFF00FF, 0x00FFFF, 2, 2000); // Purple to cyan
Testing
The library includes a comprehensive Pest v4 test suite.
Running Tests
# Run all tests composer test # Run tests quietly composer test:quiet # Run with coverage report composer test:coverage
Included Examples
The package includes three comprehensive examples:
# Example 1: Basic combined control sudo php examples/01_basic_combined.php # Example 2: Temperature-based RGB control sudo php examples/02_temperature_rgb.php # Example 3: Advanced RGB effects sudo php examples/03_fan_effects.php
Troubleshooting
Extensions Not Found
Solution: Install both php-pwm and phpixel extensions.
PWM or SPI Device Not Found
Solution:
- Export PWM:
echo 0 | sudo tee /sys/class/pwm/pwmchip3/export
- Check SPI:
ls /dev/spidev*
- Verify permissions (add user to
gpio
andspi
groups)
Wrong RGB Colors
Solution: Try different NeoPixelType
values:
$fan = new RGBPWMFan($pwm, $spi, NeoPixelType::GRB, 2); // Try GRB $fan = new RGBPWMFan($pwm, $spi, NeoPixelType::RGB, 2); // Or RGB
License
MIT License. See LICENSE file for details.
Credits
This library combines:
- dept-of-scrapyard-robotics/pwm-fan-control - Base fan control
- phpdafruit/neopixel-php - RGB LED control
Contributing
Contributions are welcome! When contributing:
- Follow PSR-12 coding standards
- Add tests for new features
- Update documentation as needed
- Ensure all tests pass before submitting pull requests
Support
For issues related to:
- This library: Open an issue in this repository
- pwm-fan-control: See the pwm-fan-control repository
- neopixel-php: See the neopixel-php repository
- Hardware setup: Consult your device's documentation