Client Development Environment
This guide covers core information about local testing for development. Production and test builds are built using GitHub Actions.
Dockerfile for ACT
The Dockerfile is maintained in the FireFly-Client repository at .act/dockerfile. Build the image from the repo root (not from .act/) so that libraries.yaml is available in the build context:
Usage for Intel CPU:
docker build --no-cache --platform=linux/amd64 -t act-arduino-ubuntu-24-04:latest -f .act/dockerfile .Usage for Apple Silicon:
docker build --no-cache --platform=linux/arm64 -t act-arduino-ubuntu-24-04:latest -f .act/dockerfile .Configure ACT for Visual Studio Code
To run the ACT docker image through Visual Studio Code, use GitHub Local Actions plug-in for Visual Studio. The following settings must be applied:
| Section | Setting | Value | Notes |
|---|---|---|---|
| Runners | ubuntu-24.04 | act-arduino-ubuntu-24-04 | |
| Options | artifact-server-path | ./artifacts | |
| Options | pull | false | |
| Options | container-architecture | linux/arm64 | For Apple Silicon only |
| Options | container-architecture | linux/amd64 | For Apple Intel chips |
Core Versions
The following ESP8266 Arduino core version is used with this solution. This version is configured in libraries.yaml in the FireFly-Client repository and is automatically updated on each production build.
| Core | Version |
|---|---|
| esp8266:esp8266 | 3.1.2 |
Library Versions
The following library versions are used with this solution. This table is automatically updated on each production build from libraries.yaml in the FireFly-Client repository.
| Library | Version |
|---|---|
| ArduinoJson | v7.4.3 |
| ESPAsyncTCP | v2.0.0 |
| ESPAsyncWebServer | v3.11.0 |
| TBPubSubClient | v2.12.1 |
Compile Flags
The following flags must be passed to the compiler regardless of build method (CI or local):
PRODUCT_HEX The hardware product ID expressed as a hexadecimal. Required — the compiler will error if omitted. Use the 0x-prefixed value from devices.yaml for the target hardware (e.g. -DPRODUCT_HEX=0x06002011).
CORE_DEBUG_LEVEL Controls debug output verbosity:
0= None1= Error2= Warn3= Info4= Debug5= Verbose
DISABLE_ALL_LIBRARY_WARNINGS Suppresses diagnostic messages from dependent libraries.
VERSION The firmware version string, set to the tag name on release builds (e.g. 2026.05.01). Omit for debug builds.
COMMIT_HASH The short (7-character) git SHA of the build commit. Omit for debug builds.
FIREFLY_CLOUD_API_ROOT The FireFly Cloud API root URL (e.g. -DFIREFLY_CLOUD_API_ROOT=https://api.fireflylx.com). Used by the HW-Reg firmware to reach the cloud registration endpoint. In CI this is sourced from the FIREFLY_CLOUD_API_ROOT repository variable — see Repository Variables. Required — the cert fetch step will fail the build if unset.
The repo root must also be added to the include path (e.g. -I/path/to/FireFly-Client) so that headers in common/ can be resolved. Abbreviated paths using ~ will not work.
Partitions
Unlike the Controller, the ESP8266 does not use a generated partitions.csv. The memory layout is baked into the FQBN board options and managed by the ESP8266 Arduino core. Board options are sourced from devices.yaml.
The following partition layout applies to FFI0600-2011:
| Label | Address | Size |
|---|---|---|
| eboot | 0x000000 | 0x001000 |
| app0 | 0x001000 | 0x100000 |
| app1 | 0x101000 | 0x100000 |
| config | 0x200000 | 0x1FB000 |
| rf_cal | 0x3FB000 | 0x001000 |
| phy_init | 0x3FC000 | 0x001000 |
| sdk_config | 0x3FE000 | 0x002000 |
INFO
On ESP8266, LittleFS.begin() locates the filesystem by the address baked into the core at compile time via the eesz board option — not by the partition label. The label is documentary only.
Adding a new hardware version
Hardware configurations are abstracted from the main application to allow compilation with minimal hardware-specific design considerations. Each hardware model's pin mappings and hardware constants are defined in a dedicated header file.
Create a device header in
common/devices/following the pattern ofFFI0600-2011.h. DefineSUPPORTED_HARDWARE, all GPIO pin assignments,LED_CHANNEL_COUNT,LED_PWM_MAX,FACTORY_RESET_PIN,PRODUCT_ID, and theledWrite()inline function.Update
common/hardware.hto add a#if PRODUCT_HEX == 0xXXXXXXXXblock that includes the new header.Add an entry to
devices.yamlat the repository root with theproduct_hex,product_id,status,inputs_count,outputs_count,board_fqbn,board_options,bootloader_addr, andpartition_schemefields. SettingstatustoACTIVEwill include the model in the CI build matrix.
Repository Secrets
Some CI workflows require secrets to be configured across repositories. Each secret is created once and then installed into the repository whose CI workflow uses it.
FIREFLY_DOCS_TOKEN
Installed in: BrentIO/FireFly-Client → Settings → Environments → production → Environment secrets
Purpose: Allows the FireFly-Client production CI workflow to automatically open a pull request on BrentIO/FireFly-Docs when the library list changes.
No new token needed — reuse the existing fine-grained PAT created for FireFly-Controller. The same token covers both repositories because it already has Contents and Pull requests read/write access to BrentIO/FireFly-Docs.
To install the token in BrentIO/FireFly-Client:
- Go to
BrentIO/FireFly-Client→ Settings → Environments → production - Under Environment secrets, click Add secret
- Name:
FIREFLY_DOCS_TOKEN - Value: paste the existing token
AWS_ROLE_ARN
Installed in: BrentIO/FireFly-Client → Settings → Environments → production → Environment secrets
Purpose: IAM role ARN assumed via OIDC to authenticate to AWS during production firmware builds. Required to upload compiled firmware artifacts to S3.
AWS_REGION
Installed in: BrentIO/FireFly-Client → Settings → Environments → production → Environment secrets
Purpose: AWS region where the firmware S3 bucket is located.
S3_FIRMWARE_BUCKET_NAME
Installed in: BrentIO/FireFly-Client → Settings → Environments → production → Environment secrets
Purpose: Name of the S3 bucket where compiled firmware ZIP archives are uploaded during production builds.
Repository Variables
Repository variables are distinct from secrets — their values are visible in logs and workflow run summaries. Set them at Settings → Secrets and variables → Actions → Variables.
FIREFLY_CLOUD_API_ROOT
Installed in: BrentIO/FireFly-Client → Settings → Secrets and variables → Actions → Variables
Purpose: The FireFly Cloud API root URL. Used by both compile-check.yaml (PR builds) and build-firmware.yaml (release/dev builds) to:
- Fetch the live TLS certificate for the cloud endpoint at build time and bake it into the HW-Reg firmware.
- Pass the URL to the firmware as the compile-time flag
-DFIREFLY_CLOUD_API_ROOT=....
Required value: The FireFly Cloud API root URL (e.g. https://api.fireflylx.com).
Effect if unset: The cert fetch step will fail the build with an explicit error message.