

MorayGlow
WiFi-connected RGB LED strip controller — XIAO ESP32-S3 firmware, custom PCB, MQTT/REST/WebSocket, Home Assistant auto-discovery
- Size
- 50.6 × 39.6 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 27
- Nets
- 31
- Pads
- 86
- Tracks, vias
- 116, 6
- Routed
- Yes
- KiCad
- KiCad 10.0 (file 20260206)
- Created
- 10 Apr 2026
- Updated
- 28 Apr 2026
Overview
MorayGlow is an open-source printed circuit board by GarethCooke, from the GarethCooke/MorayGlow repository on GitHub. It is a 2-layer board of 50.6 × 39.6 mm with 27 parts on 31 nets, routed with 116 tracks and 6 vias.
It is built around the IRLML6344TRPBF and 1N5819HW-7-F-01. Its parts include 7 resistors, 4 capacitors, 3 transistors, 2 diodes and 2 connectors. It belongs with the home automation and IoT and lEDs and displays boards and the ESP32 boards of this library.
Main components
2README
README.mdMorayGlow
IoT LED strip controller — ESP32 firmware + web UI with Home Assistant integration.
Project Summary
MorayGlow controls an RGB LED strip via an ESP32. The device hosts a web UI and exposes a REST + WebSocket API. A browser-based client lets you toggle the strip on/off and pick a colour. The device also integrates with Home Assistant via MQTT auto-discovery, so it appears automatically as a light entity.
Project Structure
MorayGlow/
├── MorayServer/ # ESP32 firmware (C++, PlatformIO)
│ ├── platformio.ini
│ ├── src/main.cpp # WiFi, LittleFS, REST API, WebSocket
│ ├── include/
│ │ ├── config.h # WiFi credentials, MQTT config — edit before flashing
│ │ ├── state.h # Pure logic: stateToJson, rgbToHex, parseMqttCommand
│ │ └── mqtt.h # MQTT client + Home Assistant discovery
│ └── test/
│ └── test_state.cpp # Unity tests (run on host, not device)
└── MorayClient/ # Web UI (plain HTML/CSS/JS — no framework)
├── index.html
├── css/style.css
├── js/
│ ├── moray.js # UMD utility module (buildWsUrl, isValidHexColor)
│ └── app.js # Main UI logic
├── test/
│ └── moray.test.js # Jest tests for moray.js
└── test-server/ # Node.js mock server for UI development
├── server.js
├── logic.js # Pure functions (testable without starting server)
├── db.json # Persisted state between restarts
└── test/
└── server.test.js # Jest tests for logic.jsAPI
| Method | Endpoint | Body | Description |
|---|---|---|---|
| GET | /api/state | — | Returns {"on": bool, "color": "#rrggbb"} |
| POST | /api/power | {"on": bool} | Turn strip on or off |
| POST | /api/color | {"color": "#rrggbb"} | Set strip colour |
| WS | /ws | — | Server pushes state on every change |
Design Decisions
| Decision | Choice | Reason |
|---|---|---|
| MCU | ESP32 Dev Board | Dual-core, Wi-Fi + Bluetooth built in |
| Build system | PlatformIO | Dependency management, board config, native test env |
| Web server | esphome/ESPAsyncWebServer-esphome | Supports ESP32; async |
| Filesystem | LittleFS | Serves client files from device flash |
| JSON | ArduinoJson v7 (JsonDocument) | No capacity arg needed; widely supported |
| MQTT | knolleary/PubSubClient + setBufferSize(512) | Lightweight, well-maintained |
| HA integration | MQTT auto-discovery | Device appears automatically in Home Assistant |
| Client | Plain HTML/CSS/JS (no framework) | Keeps LittleFS footprint small |
| Client module | UMD pattern (moray.js) | Works as browser global and Node.js/Jest module |
| Testability | Pure functions in state.h / logic.js | Compiled and tested on host without hardware |
| C++ tests | Unity (via PlatformIO native env) | Bundled with PlatformIO; runs on host |
| JS tests | Jest | Standard, zero-config for CommonJS modules |
Before Flashing
Edit MorayServer/include/config.h and set your WiFi SSID/password and MQTT broker IP before building and flashing.
Running Tests
MorayServer — C++ firmware (Unity via PlatformIO)
Requires gcc/g++ on your PATH (install MinGW-w64 if not present).
cd MorayServer
pio test -e nativeMorayClient — browser JS logic (Jest)
cd MorayClient
npm install # first time only
npm testTest server — Node.js logic (Jest)
cd MorayClient\test-server
npm install # first time only
npm testStarting the Test Server
The test server lets you develop and test the web UI without the physical device.
cd MorayClient\test-server
npm install # first time only
npm startThen open http://localhost:3000 in a browser.
State is persisted to MorayClient\test-server\db.json between restarts.
Parts
27| Qty | Value | Footprint | References |
|---|---|---|---|
| 4 | Hole_Pad | MountingHole:MountingHole_3.2mm_M3_ISO7380_Pad | H1, H2, H3, H4 |
| 3 | 100 | Resistor_SMD:R_0603_1608Metric | R1, R2, R3 |
| 3 | 100k | Resistor_SMD:R_0603_1608Metric | R4, R5, R6 |
| 3 | IRLML6344TRPBF | IRLML6344TRPBF:TRANS_IRLML6344TRPBF | Q1, Q2, Q3 |
| 2 | 0.1uF | Capacitor_SMD:C_0603_1608Metric | C1, C3 |
| 2 | LOGO | LOGO | G***, G*** |
| 1 | 100uF | Capacitor_Tantalum_SMD:CP_EIA-3216-18_Kemet-A | C4 |
| 1 | 10uF | Capacitor_SMD:C_0603_1608Metric | C2 |
| 1 | 1N5819HW-7-F | Diode_SMD:D_SOD-123 | D1 |
| 1 | 330 | Resistor_SMD:R_0603_1608Metric | R7 |
| 1 | Barrel Jack | Connector_BarrelJack:BarrelJack_Kycon_KLDX-0202-xC_Horizontal | J1 |
| 1 | LED | LED_SMD:LED_0603_1608Metric | LED1 |
| 1 | MP1584 5V buck module | MP1584EN:SRT_MPT1584EN_Module | PS1 |
| 1 | RGB LED | Connector_JST:JST_XH_S4B-XH-A_1x04_P2.50mm_Horizontal | J2 |
| 1 | SW_DIP_x01 | Button_Switch_SMD:SW_Push_1P1T_NO_CK_KMR2 | SW1 |
| 1 | XIAO-ESP32-S3-Plus-SMD | XIAO_Series_Footprints:XIAO-ESP32-S3-DIP | U1 |
Similar boards
- 2 layers149.6 × 127.1 mm

- 2 layers100 × 50 mm

- 2 layers65.3 × 18.3 mm

Klipper nano expander
orobardet/klipper_nano_expander
Klipper Nano Expander, an Arduino Nano Shield to be used as an auxiliary Klipper MCU
39 parts35MIT - 2 layers79.7 × 62.6 mm

OpenReflow
CarlosGS/OpenReflow
Simple reflow oven controller that is configurable from a phone
39 parts25GPL-3.0 - 2 layers35 × 50 mm

Imu rc hand unit
DimitriOnLSD/imu-rc
Gesture-based RC car controller using ESP32-S3, BLE, LSM6DSO IMU, OLED display, and LiPo battery with USB-C charging.
76 parts7MIT - 4 layers36 × 36 mm

Vapeagochi
lucia3e8/vapeagochi
Eventually I want to target the bc5000 because it's cuter but I'd have to redesign the PCB
50 parts5 - 2 layers65 × 65 mm

LMR14050SDDA reference
luxas/special-computing-machine
Let's make a Raspberry Pi cluster similar to real data centers!
49 parts5Apache-2.0 - 2 layers467.5 × 140 mm

Questions
How big is the MorayGlow PCB?
It measures 50.6 × 39.6 mm and has 2 copper layers, 1.6 mm thick.
What parts does the MorayGlow use?
27 parts, built around the IRLML6344TRPBF and 1N5819HW-7-F-01. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
Where can I download the MorayGlow KiCad files?
From the GarethCooke/MorayGlow repository on GitHub, at the commit this page was made from: the board is docs/KiCad/MorayGlow.kicad_pcb and its schematic docs/KiCad/MorayGlow.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the MorayGlow design in my own project?
Its repository states no licence, so its author keeps all rights: ask GarethCooke before reusing the design.