# Table of Content 1. [What's this project?](#user-content-whats-this-project) 2. [Web UI](#user-content-web-ui) 3. [BusyLight Buddy companion app](#user-content-busylight-buddy-companion-app) 4. [Stream Deck plug-in](#user-content-stream-deck-plug-in) 5. [BusyLight API](#user-content-busylight-api) 6. [MuteDeck integration](#user-content-mutedeck-integration) 7. [Electronic parts](#user-content-electronic-parts) 8. [Firmware installation](#user-content-firmware-installation) 9. [3D files - Enclosure](#user-content-3d-files---enclosure) 10. [Wiring / Soldering](#user-content-wiring--soldering) 11. [Tools & libs](#user-content-tools--libs) # What's this project? **Let people know if they can bother you with light signals!** A cheap, simple to build, nice looking and portable DIY **Busy Light**. It comes with a with a simplistic but neat **Web UI** and a simple (but hopefully convenient) **Rest API**. | Controlled by Stream Deck with REST API | Light roll | | --- | --- | | ![busylight and stream deck](img/busylight.jpg) | ![busylight roll](img/busylight.gif) | # Web UI A very simplistic but neat UI is available on port `80` (thanks @nicolaeser). Default hostname is `igox-busylight`. You can try to reach the web UI @ . | What an neat UI ! 😄 | | --- | | ![Web UI](img/web-ui.png) | # BusyLight Buddy companion app [BusyLight Buddy](https://code.igox.org/iGoX/busylight-buddy) is a free, open-source multiplatform companion app to control your BusyLight from your phone or computer — no browser needed. Available for **iOS**, **iPadOS**, **Android**, **macOS**, and **Windows**. It features quick status presets, a custom color picker with saveable presets, a brightness slider, and background polling to keep the UI in sync with the device. # Stream Deck plug-in You can download a Stream Deck plugin to control your BusyLight: Or directly from [here](streamdeck-plugin/README.md). # BusyLight API ## End points | Path | Method | Parameter | Description | | --- | --- | --- | --- | | /api/color | POST | `color` JSON object | Set the BusyLight color according to the `color` object passed in the request body. Return a `status` object. | | /api/color | GET | n/a | Retreive the color currently displayed by the BusyLight. Return a `color` object. | | /api/brightness | POST | `brightness` JSON object | Set the BusyLight brightness according to the `brightness` object passed in the request body. Return a `status` object. | | /api/brightness | GET | n/a | Retreive the BusyLight brightness. Return a `brightness` object. | | /api/status/on | POST / GET | n/a | Light up the BusyLight. White color. Return a `status` object. | | /api/status/available | POST / GET | n/a | Set the BusyLight in `available` mode. Green color. Return a `status` object. | | /api/status/away | POST / GET | n/a | Set the BusyLight in `away` mode. Yellow color. Return a `status` object. | | /api/status/busy | POST / GET | n/a | Set the BusyLight in `busy` mode. Red color. Return a `status` object. | | /api/status/off | POST / GET | n/a | Shutdown the BusyLight. Return a `status` object. | | /api/status | GET | n/a | Retreive the current BusyLight status. Return a `status` object. | | /api/blink | POST | `blink` JSON object | Make the BusyLight blink. Preserves current color, status and brightness. Return a `status` object. | | /api/blink | GET | n/a | Retrieve the current BusyLight blink status. Return a `blink` object. | | /api/blink/stop | POST | n/a | Stop the BusyLight blinking and restore previous state. Return a `status` object. | | /api/debug | GET | n/a | Retreive the full BusyLight status. | ## JSON objects ### `color` object ```json { "r": 255, "g": 0, "b": 127, "brightness": 0.5 } ``` `r`: RED color | integer | [0 .. 255] `g`: GREEN color | integer | [0 .. 255] `b`: BLUE color | integer | [0 .. 255] `brightness`: LED brightness (optional) | float | [0.0 .. 1.0] ### `brightness` object ```json { "brightness": 0.5 } ``` `brightness`: LED brightness | float | [0.0 .. 1.0] ### `blink` object ```json { "isblinking": true, "frequency": 2, "duration": 5.0, "remains": 3.2 } ``` `isblinking`: whether the BusyLight is currently blinking | boolean `frequency`: blink frequency | integer | Hz `duration`: total blink duration | float | seconds | 0 = endless `remains`: remaining blink time | float | seconds | 0 if endless ### `status` object ```json { "status": "" } ``` `` : `on` | `off` | `available` | `away` | `busy` | `colored` | `blinking` # MuteDeck integration The `POST api/mutedeck-webhook` endpoint aims to collect [MuteDeck](https://mutedeck.com/help/docs/notifications.html#enabling-the-webhook-integration) webhook callbacks. It will automatically switch to the BusyLight in: * busy mode (Red color) when entering a meeting with Mic `ON` **and** camera `ON`. * away mode (Yellow color) when entering a meeting with Mic `OFF` **and** camera `ON`. * away mode (Yellow color) if the mic is muted during a meeting. * available mode (Green color) when exiting/closing a meeting. | MuteDeck Configuration | | --- | | ![MuteDeck config](img/mutedeck-webhook-conf.png) | # Electronic parts | Parts | Links (Amazon - not affiliated) | | --- | --- | | Micro-controler | [D1 ESP32 Mini NodeMCU](https://www.amazon.fr/dp/B0CDXB48DZ) - USB C version | | Led rings (x2) | [AZDelivery 5 x LED Ring 5V RGB compatible avec WS2812B 12-Bit 38mm](https://www.amazon.fr/dp/B07V1GGKHV) | | Battery | [Anker PowerCore 5000mAh](https://www.amazon.fr/dp/B01CU1EC6Y) | | USB A to USB C adapter | [USB A to USB C adapter](https://www.amazon.fr/dp/B0BYK917NM) | # Firmware installation **(1)** Flash your ESP32 with [Micropython](https://micropython.org/download/ESP32_GENERIC/) **v1.24.1**. **(2)** Install [microdot](https://microdot.readthedocs.io/en/latest/index.html) **v2.0.6** library on the ESP32. This can easily be done using [Thonny](https://thonny.org): | Tools > Manage plug-ins | lib selection | | --- | --- | | ![lib-menu](img/lib-menu.png) | ![lib-install](img/lib-install.png) | > ⚠️ **Compatibility note:** MicroPython v1.27 is **not compatible** with Microdot due to breaking changes in the underlying ESP-IDF v5.5. Use MicroPython **v1.24.1** with Microdot **v2.0.6**. **(3)** Edit the `WIFI Configuration` section in the [boot.py](ESP32/boot.py) file. **(4)** Copy the content of [ESP32](ESP32) folder with the modified `boot.py` file to the root of your ESP32 file system. Again, can easily be done using [Thonny](https://thonny.org): ![file-copy](img/file-copy.png) **Done!** # 3D files - Enclosure All the required 3D files (STLs and f3d project) to 3D print the enclosure are available in the [3D-files-to-print](3D-files-to-print) folder. ![3D files](3D-files-to-print/img/busylight-3d.jpg) # Wiring / Soldering ![wiring-soldering](img/wiring-soldering.png) You can see a final assembly image [here](3D-files-to-print/README.md). # Tools & libs ## Thonny ## Micropython ## Microdot ## JSColor