oguzhantogay / philips-hue-client
A modern, fully-featured PHP client for Philips Hue smart lights
Fund package maintenance!
OguzhanT
Buy Me A Coffee
Thanks Dev
Requires
- php: ^8.0
- ext-json: *
- clue/buzz-react: ^2.0
- doctrine/instantiator: ^1.5.0
- guzzlehttp/guzzle: ^7.0
- nesbot/carbon: ~2.66.0
- psr/log: ^1.1|^2.0|^3.0
- react/event-loop: ^1.0
- slim/psr7: ^1.0
- slim/slim: ^4.0
- symfony/console: ^5.0,<5.4.40
- symfony/finder: ^5.4,<6.0
Requires (Dev)
- mockery/mockery: ^1.5
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^3.7
- zircote/swagger-php: ^3.0
README
A modern, fully-featured PHP client for Philips Hue smart lights. Control lights, rooms, scenes, and schedules with an elegant API. Framework-agnostic with built-in support for Laravel, Symfony, and standalone PHP applications.
โจ Features
- ๐จ Complete Hue API v2 Support - Lights, groups, scenes, schedules, sensors
- ๐ Auto Bridge Discovery - Automatic bridge detection using mDNS/N-UPnP
- ๐ก Intuitive API - Fluent interface for natural command chaining
- ๐ฌ Scene Management - Create, modify, and activate scenes
- ๐ญ Built-in Effects - Color loops, breathing, alerts, and custom animations
- โก Event Streaming - Real-time updates via Server-Sent Events (SSE)
- ๐ ๏ธ CLI Tool - Command-line interface for quick control
- ๐ REST API Server - Full REST API with Swagger documentation
- ๐ฆ Framework Integration - Ready-made adapters for popular frameworks
- ๐งช Fully Tested - Comprehensive test coverage with mocked responses
- ๐ Resource Monitoring - Track energy usage and light statistics
- ๐ Secure - Supports Hue's enhanced security mode
- ๐ Performance - Connection pooling, caching, and retry mechanisms
- ๐ณ Docker Ready - Container support for easy deployment
- ๐ Rate Limiting - Prevents API abuse and protects bridge
- ๐พ Smart Caching - Automatic caching with configurable TTL
๐ Requirements
- PHP 8.0 or higher
- Philips Hue Bridge (v2 or newer)
- Network access to Hue Bridge
- ext-json
- ext-curl (optional, for better performance)
๐ Installation
Install via Composer:
composer require oguzhantogay/philips-hue-client
๐ง Quick Start
Bridge Discovery & Authentication
use OguzhanTogay\HueClient\HueClient; use OguzhanTogay\HueClient\Discovery\BridgeDiscovery; // Auto-discover bridges on your network $discovery = new BridgeDiscovery(); $bridges = $discovery->discover(); if (empty($bridges)) { die("No Hue bridges found on network"); } $bridge = $bridges[0]; // Use first bridge echo "Found bridge: {$bridge->getId()} at {$bridge->getIp()}\n"; // Create client and authenticate $client = new HueClient($bridge->getIp()); // First time setup - press bridge button then run: $username = $client->register('my-app-name', 'my-device-name'); echo "Save this username: {$username}\n"; // For subsequent connections: $client = new HueClient($bridgeIp, $username);
Basic Light Control
// Get all lights $lights = $client->lights()->getAll(); foreach ($lights as $light) { echo "{$light->getName()}: {$light->getState()->getStatus()}\n"; } // Control specific light $light = $client->lights()->get(1); // Simple commands $light->on(); $light->off(); $light->toggle(); // Set properties $light->setBrightness(75); // 0-100% $light->setColor('#FF5733'); // Hex color $light->setColorTemperature(2700); // Kelvin (2000-6500) // Chain commands $light->on() ->setBrightness(100) ->setColor('#00FF00') ->transition(1000); // 1 second transition
Room/Group Control
// Get all rooms $rooms = $client->groups()->getRooms(); // Control entire room $livingRoom = $client->groups()->getByName('Living Room'); $livingRoom->on(); $livingRoom->setBrightness(60); $livingRoom->setScene('Relax'); // Create custom group $group = $client->groups()->create('Movie Lights', [1, 3, 5]); $group->setColor('#0000FF')->dim(20); // Control all lights $client->groups()->all()->off();
Scenes
// List available scenes $scenes = $client->scenes()->getAll(); foreach ($scenes as $scene) { echo "{$scene->getName()} - Room: {$scene->getGroup()}\n"; } // Activate scene $client->scenes()->activate('Sunset'); // Create custom scene $scene = $client->scenes()->create( name: 'Movie Time', lights: [ 1 => ['on' => true, 'brightness' => 30, 'color' => '#0000FF'], 2 => ['on' => false], 3 => ['on' => true, 'brightness' => 20, 'color' => '#FF0000'] ] );
Advanced Effects
use OguzhanTogay\HueClient\Effects\ColorLoop; use OguzhanTogay\HueClient\Effects\Breathing; use OguzhanTogay\HueClient\Effects\Alert; // Color loop effect $effect = new ColorLoop($client); $effect->start($light, duration: 30); // 30 seconds // Breathing effect $breathing = new Breathing($client); $breathing->start($light, '#FF0000', speed: 'slow'); // Alert flash $alert = new Alert($client); $alert->flash($light, times: 3); // Custom animation $light->animate([ ['color' => '#FF0000', 'duration' => 1000], ['color' => '#00FF00', 'duration' => 1000], ['color' => '#0000FF', 'duration' => 1000], ], repeat: 5);
Schedules
// Create schedule $schedule = $client->schedules()->create( name: 'Morning Wake Up', command: $client->groups()->getByName('Bedroom')->sunrise(duration: 900), time: '07:00:00', repeat: ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'] ); // One-time schedule $client->schedules()->once( name: 'Party Lights', command: $client->groups()->all()->party(), dateTime: '2024-12-31 23:00:00' ); // Sunset/sunrise schedules $client->schedules()->atSunset( command: $client->groups()->getByName('Garden')->on() );
Real-time Events (SSE)
// Listen for light state changes $client->events()->listen(function($event) { if ($event->getType() === 'light.state_changed') { echo "Light {$event->getLightId()} changed\n"; echo "New state: " . json_encode($event->getData()) . "\n"; } }); // Subscribe to specific events $client->events()->subscribe('motion.detected', function($event) { $client->groups()->getByName('Hallway')->on(); });
๐ ๏ธ CLI Usage
The package includes a powerful CLI tool:
# Install globally composer global require oguzhantogay/philips-hue-client # Discover bridges hue discover # Setup/authenticate hue setup # Light control hue lights # List all lights hue on "Living Room" # Turn on light hue off --all # Turn off all lights hue brightness 75 "Kitchen" # Set brightness hue color "#FF5733" --all # Set color for all # Scenes hue scenes # List scenes hue scene activate "Relax" # Activate scene # Effects hue effect party --duration=30 hue effect sunrise --room="Bedroom" --duration=600 # Interactive mode hue interactive # Enter interactive shell hue server # Start REST API server
๐ REST API Server
The package includes a full REST API server with Swagger documentation:
Quick Start
# Start the API server ./bin/hue-server --discover # Or with specific bridge ./bin/hue-server -h 192.168.1.100 -u your-username # Or using Composer composer serve # Or using Docker docker-compose up
The API will be available at:
- API Base URL:
http://localhost:8080/api
- Swagger Documentation:
http://localhost:8080/docs
- Health Check:
http://localhost:8080/api/health
API Endpoints
Bridge Management
GET /api/health
- Bridge connectivity statusGET /api/bridge/info
- Bridge informationGET /api/bridge/config
- Bridge configuration
Lights
GET /api/lights
- List all lightsGET /api/lights/{id}
- Get specific lightPUT /api/lights/{id}/state
- Set light statePATCH /api/lights/{id}/state
- Update light state partiallyPUT /api/lights/{id}/name
- Rename light
Groups & Rooms
GET /api/groups
- List all groupsGET /api/rooms
- List all roomsGET /api/zones
- List all zonesGET /api/groups/{id}
- Get specific groupPOST /api/groups
- Create new groupPUT /api/groups/{id}/action
- Control groupDELETE /api/groups/{id}
- Delete group
Scenes
GET /api/scenes
- List all scenesGET /api/scenes/{id}
- Get specific scenePOST /api/scenes
- Create new scenePUT /api/scenes/{id}/activate
- Activate sceneDELETE /api/scenes/{id}
- Delete scene
Schedules
GET /api/schedules
- List all schedulesGET /api/schedules/{id}
- Get specific schedulePOST /api/schedules
- Create new schedulePUT /api/schedules/{id}
- Update scheduleDELETE /api/schedules/{id}
- Delete schedule
Sensors
GET /api/sensors
- List all sensorsGET /api/sensors/{id}
- Get specific sensorPUT /api/sensors/{id}/state
- Update sensor state
Example API Usage
# Get all lights curl http://localhost:8080/api/lights # Turn on a light curl -X PUT http://localhost:8080/api/lights/1/state \ -H "Content-Type: application/json" \ -d '{"on": true, "brightness": 75}' # Set light color curl -X PATCH http://localhost:8080/api/lights/1/state \ -H "Content-Type: application/json" \ -d '{"color": "#FF5733"}' # Control a room curl -X PUT http://localhost:8080/api/groups/1/action \ -H "Content-Type: application/json" \ -d '{"on": true, "brightness": 80, "color": "#00FF00"}' # Activate a scene curl -X PUT http://localhost:8080/api/scenes/abc123/activate # Health check curl http://localhost:8080/api/health
Environment Configuration
Create a .env
file (copy from .env.example
):
HUE_BRIDGE_IP=192.168.1.100 HUE_USERNAME=your-hue-username HUE_PORT=8080 CACHE_TTL=300
๐ Framework Integration
๐ Laravel Integration
Installation & Setup
# Install the package composer require oguzhantogay/philips-hue-client # Publish configuration php artisan vendor:publish --tag=hue-config # Discover bridges php artisan hue:discover # Setup bridge authentication php artisan hue:setup --discover
Configuration
// config/hue.php (auto-published) return [ 'default' => 'main', 'bridges' => [ 'main' => [ 'ip' => env('HUE_BRIDGE_IP'), 'username' => env('HUE_USERNAME'), 'options' => [ 'timeout' => env('HUE_TIMEOUT', 5), 'cache_enabled' => env('HUE_CACHE_ENABLED', true), 'retry_attempts' => env('HUE_RETRY_ATTEMPTS', 3), ] ], // Multiple bridges supported 'office' => [ 'ip' => env('HUE_BRIDGE_IP_2'), 'username' => env('HUE_USERNAME_2'), ] ], 'auto_discovery' => env('HUE_AUTO_DISCOVERY', true), ];
Environment Variables
# .env HUE_BRIDGE_IP=192.168.1.100 HUE_USERNAME=your-bridge-username HUE_CACHE_ENABLED=true HUE_CACHE_TYPE=redis HUE_RETRY_ATTEMPTS=3 HUE_TIMEOUT=5
Service Provider Registration
// config/app.php 'providers' => [ // ... OguzhanTogay\HueClient\Laravel\HueServiceProvider::class, ], 'aliases' => [ // ... 'Hue' => OguzhanTogay\HueClient\Laravel\Facades\Hue::class, ],
Usage Examples
use OguzhanTogay\HueClient\Laravel\Facades\Hue; use OguzhanTogay\HueClient\HueClient; use OguzhanTogay\HueClient\ConnectionPool; // Using Facade Hue::lights()->getAll(); Hue::groups()->getByName('Living Room')->on(); Hue::scenes()->activate('Movie Time'); // Using Service Container $hue = app(HueClient::class); $hue->lights()->get(1)->setColor('#FF5733'); // Multiple Bridges $pool = app(ConnectionPool::class); $results = $pool->broadcastToAll(function($client) { return $client->groups()->all()->off(); }); // In Controllers class LightController extends Controller { public function __construct(private HueClient $hue) {} public function toggleLight(int $lightId) { $light = $this->hue->lights()->get($lightId); $light->toggle(); return response()->json([ 'success' => true, 'light' => $light->getName(), 'status' => $light->getState()->isOn() ? 'on' : 'off' ]); } } // Background Jobs class MorningRoutineJob implements ShouldQueue { public function handle(HueClient $hue): void { $bedroom = $hue->groups()->getByName('Bedroom'); $bedroom->sunrise(600); // 10 minute sunrise } } // Event Listeners class MotionDetectedListener { public function handle(MotionDetected $event, HueClient $hue): void { $hue->groups()->getByName($event->room)->on(); } }
Artisan Commands
# Discover bridges php artisan hue:discover # Setup bridge authentication php artisan hue:setup --discover # Start REST API server php artisan hue:serve --port=8080 # Clear Hue cache php artisan cache:clear --tags=hue
๐ก Symfony Integration
Installation & Setup
# Install the package composer require oguzhantogay/philips-hue-client # Discover bridges bin/console hue:discover # Setup bridge authentication bin/console hue:setup --discover
Bundle Registration
// config/bundles.php return [ // ... OguzhanTogay\HueClient\Symfony\HueBundle::class => ['all' => true], ];
Configuration
# config/packages/hue.yaml hue: default_bridge: main auto_discovery: true bridges: main: ip: '%env(HUE_BRIDGE_IP)%' username: '%env(HUE_USERNAME)%' options: timeout: '%env(int:HUE_TIMEOUT)%' cache_enabled: '%env(bool:HUE_CACHE_ENABLED)%' retry_attempts: '%env(int:HUE_RETRY_ATTEMPTS)%' office: ip: '%env(HUE_BRIDGE_IP_2)%' username: '%env(HUE_USERNAME_2)%' cache: adapter: redis ttl: lights: 10 groups: 30 scenes: 60 api: enabled: true port: 8080 rate_limit: 100
Environment Variables
# .env HUE_BRIDGE_IP=192.168.1.100 HUE_USERNAME=your-bridge-username HUE_CACHE_ENABLED=true HUE_CACHE_TYPE=redis HUE_RETRY_ATTEMPTS=3 HUE_TIMEOUT=5
Service Usage
// In Controllers use OguzhanTogay\HueClient\HueClient; use OguzhanTogay\HueClient\ConnectionPool; class LightController extends AbstractController { public function __construct( private HueClient $hueClient, private ConnectionPool $connectionPool ) {} #[Route('/lights', methods: ['GET'])] public function lights(): JsonResponse { $lights = $this->hueClient->lights()->getAll(); return $this->json(array_map(function($light) { return [ 'id' => $light->getId(), 'name' => $light->getName(), 'state' => $light->getState()->toArray() ]; }, $lights)); } #[Route('/lights/{id}/toggle', methods: ['POST'])] public function toggleLight(int $id): JsonResponse { $light = $this->hueClient->lights()->get($id); $light->toggle(); return $this->json([ 'success' => true, 'status' => $light->getState()->isOn() ? 'on' : 'off' ]); } } // In Services #[AsAlias('app.hue_service')] class HueService { public function __construct(private HueClient $hueClient) {} public function createMoodLighting(string $room, string $mood): void { $group = $this->hueClient->groups()->getByName($room); match($mood) { 'relax' => $group->setColor('#FF8C00')->setBrightness(30), 'focus' => $group->setColor('#FFFFFF')->setBrightness(90), 'party' => $group->setColor('#FF00FF')->setBrightness(100), default => $group->on() }; } } // Event Subscribers class HueEventSubscriber implements EventSubscriberInterface { public function __construct(private HueClient $hueClient) {} public static function getSubscribedEvents(): array { return [ 'app.user_arrived_home' => 'onUserArrivedHome', 'app.bedtime' => 'onBedtime', ]; } public function onUserArrivedHome(): void { $this->hueClient->scenes()->activate('Welcome Home'); } public function onBedtime(): void { $this->hueClient->groups()->all()->sunset(300); } }
Console Commands
# Discover bridges bin/console hue:discover # Setup bridge authentication bin/console hue:setup --discover # Start REST API server bin/console hue:serve --port=8080 # Clear cache bin/console cache:clear
Standalone/Vanilla PHP
require 'vendor/autoload.php'; $config = [ 'bridge_ip' => '192.168.1.100', 'username' => 'your-username' ]; $hue = new \OguzhanTogay\HueClient\HueClient( $config['bridge_ip'], $config['username'] );
๐ณ Docker Development
Quick Start with Docker
# Clone the repository git clone https://github.com/oguzhanT/philips-hue-client.git cd philips-hue-client # Copy environment file cp .env.example .env # Edit .env with your bridge IP and username nano .env # Start with Docker Compose docker-compose up -d # View logs docker-compose logs -f hue-api
Development Environment
# Development environment with hot reload docker-compose -f docker-compose.dev.yml up # Run tests in container docker-compose exec dev composer test # Access shell docker-compose exec dev sh
One-Click Development
๐งช Testing
# Run tests composer test # Run tests with coverage composer test-coverage # Run static analysis composer analyse # Run API tests composer test -- tests/Api/ # Test with Docker docker-compose exec dev composer test
๐ Performance Features
Connection Pooling
use OguzhanTogay\HueClient\ConnectionPool; $pool = new ConnectionPool(); $pool->addBridge('192.168.1.100', 'username1'); $pool->addBridge('192.168.1.101', 'username2'); // Health check all bridges $health = $pool->healthCheck(); // Broadcast action to all bridges $results = $pool->broadcastToAll(function($client) { return $client->groups()->all()->on(); });
Caching & Retry
$client = new HueClient($bridgeIp, $username, [ 'cache_enabled' => true, 'cache_type' => 'redis', // or 'filesystem' 'retry_attempts' => 5, 'timeout' => 10 ]); // Automatic caching and retry on failures $lights = $client->lights()->getAll(); // Cached for 10 seconds
Rate Limiting
The REST API automatically rate limits requests to protect your bridge:
- Limit: 100 requests per minute per IP
- Headers:
X-RateLimit-Limit
,X-RateLimit-Remaining
- Error: HTTP 429 when exceeded
๐ Examples
Check the /examples
directory for complete examples:
Basic Examples
basic-control.php
- Simple light controlparty-mode.php
- Multi-room party effectsrest-api-client.php
- REST API usage examplesworking-example.php
- Complete working exampleinteractive-test.php
- Interactive testing
Framework Integration Examples
laravel-controller.php
- Laravel controller integrationsymfony-controller.php
- Symfony controller integration
Creative & Advanced Examples
music-sync-party.php
- ๐ต Music-synchronized party lighting with beat detectionsecurity-system.php
- ๐ Home security integration with motion alertsgaming-mood-lighting.php
- ๐ฎ Gaming lighting with health bars and achievementsweather-based-lighting.php
- ๐ค๏ธ Weather-responsive ambient lightingbiometric-health-integration.php
- ๐ Health monitoring with biometric datasmart-home-automation.php
- ๐ Complete smart home automation hub
๐ Community Showcase
Built something awesome? Share it with us!
Project | Description | Author |
---|---|---|
Hue DJ Controller | Sync lights with DJ mixer | @username |
Smart Office Bot | Slack bot for office lighting | @username |
Gaming Immersion | React to game events | @username |
๐ฌ Join the Discussion
- ๐ Report bugs
- ๐ก Request features
- ๐ฌ General discussion
- ๐ Get help
๐ค Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
๐ License
The MIT License (MIT). Please see License File for more information.
๐ Links
๐ Support
If you find this package useful, please consider:
- โญ Starring the repository
- ๐ Reporting bugs
- ๐ก Suggesting new features
- ๐บ Buying me a coffee
Made with โค๏ธ by Oguzhan Togay