Custom panels from your own device
Every built-in Firefly driver covers the sensors the factory ships with. But Firefly is a development board, so you may already have your own hardware: a custom ESP32 firmware running your own sensor driver, a Raspberry Pi reading a serial device, a Python service polling a USB / GPIO bus, a Node.js box talking to a serial gadget — anything that can run on a LAN and speak UDP or HTTP.
Because Firefly already has a board-to-board panel transport (the same one it uses to mirror sensors from other Firefly boards), you can attach any device as a first-class Firefly panel — dashboard value, automation source/target, OLED display, MQTT publish — without touching firmware. This page documents that contract.
The transport: UDP board-to-board
The publisher (your device) broadcasts a single UDP packet to the Firefly board's data port (default 8422, set via udp_data_port):
FF <MAC> <panel_name> {"": 23.5, "temperature": 23.5, "humidity": 60.0}
Where:
FF— packet type marker.<MAC>— the publishing device's MAC address (uppercase hex, colons). Firefly ignores its own MAC to avoid self-mirroring.<panel_name>— the panel name this value belongs to.{...}— JSON object of numeric values. Key""is the default/primary value; named keys are sub-values (e.g.temperature,humidity).
Set up the receiver
- On the Firefly board, create a new panel: type input, hardware udp_remote.
- Set the MAC field to the publishing device's MAC address and the remote panel field to the panel name you used in the packet.
- Save. The panel appears in the dashboard like any other input — calibratable, automatable, displayable on the OLED, publishable over MQTT.
Example: publish temperature + humidity from a Raspberry Pi
import socket, json
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
payload = b"FF AA:BB:CC:DD:EE:FF sensor1 " + json.dumps(
{"": 23.5, "temperature": 23.5, "humidity": 60.0}
).encode()
sock.sendto(payload, ("192.168.2.100", 8422)) # firefly's data port
Example: publish from an ESP32 firmware
// In your ESP32 firmware, on your chosen cadence:
String json = "{\"\":"; json += String(value, 3); json += ",\"temperature\":" + String(value, 3); json += ",\"humidity\":" + String(humidity, 3) + "}";
udp.beginPacket("255.255.255.255", dataPort);
udp.print("FF " + WiFi.macAddress() + " sensor1 " + json);
udp.endPacket();
Operational notes
- Firefly listens on
udp_port(discovery, default 8421) andudp_data_port(data, default 8422). - A receiver only gets packets whose
MACandpanelmatch what it configured — no self-mirroring, no cross-talk. - Data packets are lossy (UDP). For critical control loops prefer a polled HTTP source; for ambient sensor mirrors UDP broadcast is fine.
- For low-friction custom sensors, HTTP pull is now a first-class option (see the firmware page). Both plugs into the same panel model.
That is the complete custom-panel story on the current build: any network device that speaks UDP in that shape becomes a Firefly panel with zero firmware changes on the Firefly side.