Contributing¶
How to engage¶
- Email — joe@xengineering.net for bug reports, feature requests, or questions.
- GitHub — issues and pull requests on the public repo, github.com/XEngineeringLLC/XREG-010.
Report unclear behavior even if it may not be a bug — confusing behavior is a documentation defect at minimum.
Before you change code¶
The following disciplines exist because each one has been violated before, with real consequences.
The telemetry three-way sync¶
Live data reaches the dashboard over five server-sent-event data channels — CSVData, CSVData4, CSVData2, CSVData3 and TimestampData (see the telemetry pipeline) — plus a separate text console stream. Each data channel's packet is a comma-separated list of numbers, matched by position to a field-name array in the browser. That means any field you add or remove must be changed in three places at once:
- the firmware index list (the channel's enum in
3_functions.ino, e.g.Csv1Index, whose closing sentinel such asCSV1_FIELD_COUNTbecomes the declared field count), - the packet-building format string (the
snprintfcall for that channel in3_functions.ino— one conversion specifier per field), and - the matching JavaScript field array (
CSV1_FIELDS,CSV2_FIELDS,CSV4_FIELDS, orTS_FIELDSinweb_src/script.js).
If these three drift out of sync, the failure is silent: the format string drops trailing fields, the browser detects a count mismatch, and the entire channel is rejected — not just your new field. Always verify all three together before considering a telemetry change complete.
The settings echo (CSVData3) is the exception. It is declared once, as the CSV3_LIST X-macro in 3_functions.ino, which expands into its enum, format string, and argument list; CSV3_FIELDS in script.js is generated from the same list at build time. Add one line to the list and bump CSV3_EXPECTED_FIELDS, and never hand-edit CSV3_FIELDS.
Pick the right pattern for a new variable¶
There are three established patterns for adding a new variable to the firmware and the dashboard, depending on what it is:
- a fast-changing live value the dashboard should plot in real time — see adding telemetry,
- a user-configurable setting that persists across reboots and echoes back to its form field — see adding a setting,
- a button or control on the dashboard that triggers a firmware action — see adding a dashboard control.
Classify first, then follow the matching recipe. The most common mistake is sending a setting over a telemetry channel meant for diagnostics, which sends redundant traffic and breaks the echo-on-change behavior.
Update comments with the code¶
When you edit code, edit the comments around it in the same change. A stale comment is worse than none — both humans and AI assistants treat comments as accurate here. Don't delete existing comments unless the code they describe is gone.
Plain English first in UI copy¶
Any text a user sees — labels, tooltips, console messages, documentation — leads with plain English and puts the technical term in parentheses after, e.g. "current-limited phase (CC phase)". Raw firmware identifiers (cv_I, VoltageKp, etc.) never appear in user-facing copy; use the dashboard label names instead. No emojis, anywhere.
Expectations for a contribution¶
- No formal test suite exists. The requirement instead: your change must compile cleanly in the Arduino IDE (board: ESP32-S3 — see Building the Firmware), and you should test it on a real device or at least exercise the affected dashboard behavior in a browser. Say in the PR what you tested and how.
- Small, focused pull requests are strongly preferred. One concern per PR. A 50-line change that does one thing reviewably is easier to review than a 500-line change that does three.
- Match the house style. Flat layout, descriptive global names, minimal abstraction. Don't introduce class hierarchies, clever indirection, or new dependencies to "clean things up" — the monolithic style is a deliberate choice (see Start Here).
- Safety-relevant code gets extra scrutiny. Anything touching the field control loop, the protections, or shutdown paths (charging control, safeties and protections) will be reviewed conservatively and may need bench-test evidence. This device drives real charging hardware on real boats.
License¶
The project is licensed under the GNU General Public License v3 (GPLv3). By submitting a contribution you agree it is provided under the same license. Don't submit code you don't have the right to license this way.