This is a web application designed to control KEF LS50 Wireless II, LSX II and LS60 speakers. It provides a user-friendly interface for managing multiple speakers, controlling their core functionalities (power, volume, source, mute), and offers a REST API for external integration.
- Backend: PHP
- Handles speaker configuration (stored in
speakers.json
). - Provides a REST API for speaker control and status retrieval.
- Utilizes the
KefConnector
class for communication with KEF speakers via their HTTP API.
- Handles speaker configuration (stored in
- Frontend: HTML, JavaScript, CSS
- Single-page application (SPA) structure.
- Material Design Lite (MDL): For a responsive and modern user interface.
- SortableJS: For drag-and-drop functionality in speaker reordering.
- Speaker Management (CRUD): Add, edit, delete, and reorder speakers.
- Dashboard: Displays configured speakers with real-time status updates, including speaker ID and model name.
- Core Controls: Power on/off, volume adjustment, source selection, mute/unmute.
- Playback Controls: Play/pause, next track, previous track.
- Group Controls: Turn all speakers off or mute/unmute all simultaneously.
- REST API: Allows external applications to control speakers via GET and POST requests.
- Application Settings: Configure application's base URL and base path. Control debug mode (enables/disables debug logging and UI button visibility).
- Debug Mode: Toggles display of raw API responses for troubleshooting.
- API Info Overlay: Provides a quick reference for GET API endpoints for each configured speaker.
- Manual Refresh: Button to manually refresh speaker status.
- Auto-Refresh Toggle: Button to pause/resume automatic status updates.
The web interface provides a user-friendly way to control your KEF speakers.
- Prerequisites: Ensure you have PHP installed.
- Navigate to Project Root: Open your terminal and navigate to the project's root directory (
/Users/marcus/Projects/kef
). - Start PHP Development Server: Run the following command:
(You can change
php -S localhost:8000
localhost:8000
to your desired host and port.) - Access in Browser: Open your web browser and go to
http://localhost:8000
(or your configured host and port).
- Prerequisites: Ensure you have Docker and Docker Compose (V1) installed.
- Navigate to Project Root: Open your terminal and navigate to the project's root directory (
/Users/marcus/Projects/kef
). - Build and Run with Docker Compose: Execute the following command:
This command builds the Docker image and starts the container in the background. The
docker-compose up --build -d
config.json
,debug.log
, andspeakers.json
files will be stored locally in the./data/
directory of your project, thanks to Docker volumes. - Access in Browser: Open your web browser and go to
http://localhost:8000
. - Stop the Application: To stop the Docker containers, run:
docker-compose down
- Prerequisites: Ensure you have Docker and Docker Compose (V2) plugin installed.
- Navigate to Project Root: Open your terminal and navigate to the project's root directory (
/Users/marcus/Projects/kef
). - Build and Run with Docker Compose: Execute the following command:
This command builds the Docker image and starts the container in the background. The
docker compose up --build -d
config.json
,debug.log
, andspeakers.json
files will be stored locally in the./data/
directory of your project, thanks to Docker volumes. - Access in Browser: Open your web browser and go to
http://localhost:8000
. - Stop the Application: To stop the Docker containers, run:
docker compose down
The application exposes a REST API for speaker control. All API endpoints are relative to the application's base URL and base path (e.g., http://localhost:8000/api/...
).
-
Speaker Management:
GET /api/speakers
: Get all configured speakers.POST /api/speakers
: Add a new speaker.curl -X POST -H "Content-Type: application/json" -d '{"name":"Living Room Speaker","ip":"192.168.1.100"}' http://localhost:8000/api/speakers
PUT /api/speakers/{id}
: Update an existing speaker.curl -X PUT -H "Content-Type: application/json" -d '{"name":"Updated Living Room Speaker"}' http://localhost:8000/api/speakers/YOUR_SPEAKER_ID
DELETE /api/speakers/{id}
: Delete a speaker.curl -X DELETE http://localhost:8000/api/speakers/YOUR_SPEAKER_ID
POST /api/speakers/reorder
: Reorder speakers.curl -X POST -H "Content-Type: application/json" -d '["ID1", "ID3", "ID2"]' http://localhost:8000/api/speakers/reorder
-
Speaker Control (GET & POST):
GET /api/speaker/{id}/power/{state}
: Set power state or source.- Power On:
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/power/on
- Power Off:
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/power/off
- Set Source (e.g., Optical):
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/power/optical
(Note: Setting a source will also power on the speaker if it's off.) (Note: Setting a source will also power on the speaker if it's off.)
- Power On:
POST /api/speaker/{id}/power
: Set power state via JSON body.curl -X POST -H "Content-Type: application/json" -d '{"state": "on"}' http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/power
GET /api/speaker/{id}/control/{action}/{value}
: Control speaker actions.- Set Volume to 50:
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/control/setVolume/50
- Mute:
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/control/mute
- Unmute:
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/control/unmute
- Toggle Play/Pause:
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/control/togglePlayPause
- Next Track:
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/control/nextTrack
- Previous Track:
http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/control/prevTrack
- Set Volume to 50:
POST /api/speaker/{id}/control
: Control speaker actions via JSON body.curl -X POST -H "Content-Type: application/json" -d '{"action": "setVolume", "value": 50}' http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/control
GET /api/speaker/{id}/status
: Get current speaker status.curl http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/status
GET /api/speaker/{id}/modelName
: Get speaker model name.curl http://localhost:8000/api/speaker/YOUR_SPEAKER_ID/modelName
-
Application Configuration:
GET /api/config
: Get application settings.POST /api/config
: Save application settings.curl -X POST -H "Content-Type: application/json" -d '{"app_base_url":"http://my-domain.com","debug_enabled":true}' http://localhost:8000/api/config
index.html
: Main application entry point (frontend).css/style.css
: Custom CSS styles.js/api.js
: JavaScript functions for interacting with the backend API.js/app.js
: Main frontend application logic.api/
: Backend PHP files.index.php
: Main API router.speakers.php
: Handles speaker CRUD operations.config.php
: Handles application configuration operations.KefConnector.php
: PHP class for communicating with KEF speakers via their HTTP API.speakers.json
: Stores speaker configurations.config.json
: Stores application settings.debug.log
: Log file for PHP errors and debug messages.
The KefConnector.php
class is responsible for communicating with the KEF speakers. It uses HTTP GET/POST requests to the speaker's internal API. The power status is inferred from the speaker's source (e.g., 'standby' means off).
This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0).
- BY (Attribution): You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
- NC (NonCommercial): You may not use the material for commercial purposes.
- SA (ShareAlike): If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/.
Third-party libraries and fonts used in this project retain their original open-source licenses, as detailed in the LICENSE
file.