gimm3fuel / easylap-server
EasyLap PHP-server: read an EasyLAP USB lap counter and send timing data over UDP
Requires
- php: >=7.4
Requires (Dev)
- phpunit/phpunit: ^9.6
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
PHP server that reads an EasyLAP USB lap counter and sends timing data over the local network.
It advertises _easylap._udp.local. via mDNS/Bonjour, accepts HELLO / BYE registrations over UDP, forwards lap JSON to those clients, and handles LIGHTS ON / LIGHTS OFF / LIGHTS <value> for the start-light GPIO expander.
Requirements
- PHP 7.4 or newer (CLI), with the sockets extension
- PHP FFI extension for real USB access (Linux hidraw or Windows HID)
- On Raspberry Pi, for real hardware:
- EasyLAP USB device (CP2110, VID
0x10C4, PID0x86B9) - FFI for hidraw, or the kernel
hid-cp2110driver exposing/dev/ttyUSB* - i2c-tools (
i2cset) for the Adafruit MCP23017 GPIO bonnet - Avahi (
avahi-publish) is used for mDNS when present; otherwise a built-in mDNS announcer is used
- EasyLAP USB device (CP2110, VID
- On Windows, for real hardware: EasyLAP USB device plus FFI (
hid.dll/kernel32.dll). mDNS uses the built-in announcer. The MCP23017 start-light expander is Linux-only; on Windows lights commands are accepted but the expander is faked.
Without a USB counter, pass -f / --fake or set EASYLAP_FAKE=1 to use a fake device (same test frames as the Python fake.cp2110 module). Fake mode is not selected automatically on Windows.
Run
From this directory:
php bin/easylapd
php bin/easylapd -v
php bin/easylapd -f
php bin/easylapd -d
| Flag | Meaning |
|---|---|
-d / --daemon |
Log to syslog, not stdout |
-v / --verbose |
Debug logging |
-f / --fake |
Use the fake CP2110 (no USB hardware) |
If the counter is not plugged in, pass -f or set EASYLAP_FAKE=1. Otherwise the server looks for a real CP2110 (Windows HID, Linux hidraw, then /dev/ttyUSB* / /dev/ttyACM*).
Optional environment variables:
| Variable | Purpose |
|---|---|
EASYLAP_DEVICE |
Device path: Linux hidraw/serial (/dev/hidraw0, /dev/ttyUSB0) or a Windows HID path containing hid |
EASYLAP_I2C_BUS |
I2C bus number for the MCP23017 (default 1; Linux only) |
EASYLAP_FAKE |
1 to force the fake CP2110 |
A small UDP client (discovers the service, pings HELLO, sends LIGHTS commands):
php bin/easylap-client
Windows
Install PHP for Windows (CLI). Enable sockets and ffi in php.ini (extension=sockets, extension=ffi, and ffi.enable=true). bin/easylapd will re-invoke PHP with FFI enabled if the extension is present but not loaded.
Plug in the EasyLAP USB counter, then from this directory:
php bin/easylapd
php bin/easylapd -v
The server finds the HID interface (VID 10C4, PID 86B9) and prints Using EasyLAP HID: ... to stderr. If no device is found, it keeps running and retries; use -f to inject fake lap frames instead.
To confirm the USB path and UART reports independently of the full server:
php bin/probe-hid.php
-d / --daemon still only switches logging to syslog; Windows has no syslog by default, so prefer stdout (-v as needed). Start-light GPIO is not wired on Windows.
Raspberry Pi
Install PHP CLI (and FFI if you use hidraw):
sudo apt install php-cli php-ffi i2c-tools avahi-daemon avahi-utils
Copy this php directory to the Pi, then:
php bin/easylapd
Composer is optional. src/autoload.php is enough. If you use Composer:
composer install
php bin/easylapd
To start at boot, call php /path/to/easylapd from /etc/rc.local or a systemd unit, same idea as the Python easylapd service.
Protocol
Unchanged from the Python server so the existing iOS app keeps working:
- UDP port 5005, IPv4 unicast
- Client → server:
HELLO(every ~10s),BYE,LIGHTS ON/OFF/ integer bitmask - Server → clients: JSON
{"time": <timer>, "uid": <transponder or 0>} - Clients not seen for 15 seconds are dropped
- mDNS type
_easylap._udp.local., instanceEasyLap Service
Tests
php tests/run.php
Or, with Composer:
composer install
./vendor/bin/phpunit