You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**lowercase** for component folder and `strcmp` string: `tmp119`
31
26
32
-
Decide on the canonical name early (Step 0) and use it everywhere.
27
+
Decide the canonical name in Step 0 and use it everywhere.
33
28
34
-
> **Proto files are off-limits.** Contributors never touch `.proto` files — only Adafruit staff
35
-
> modify those. The existing `SensorType` enum already covers all common readings.
29
+
> **Proto files are off-limits.** Only Adafruit staff modify `.proto` files.
36
30
37
31
## Reference
38
32
@@ -47,6 +41,39 @@ Wippersnapper_Components repo setup, image requirements, and testing in Adafruit
47
41
48
42
This skill accepts a sensor name as its argument (e.g. `/add_sensor_component_v1 TMP119`).
49
43
44
+
## Environment Check
45
+
46
+
Before starting, determine connectivity level — this affects whether you can use `gh` commands
47
+
or must fall back to plain `git`:
48
+
49
+
```bash
50
+
curl -s -o /dev/null -w "%{http_code}" https://www.bbc.com # general web access
51
+
curl -s -o /dev/null -w "%{http_code}" https://api.github.com # GitHub API (needed for gh)
52
+
git ls-remote https://github.com/adafruit/Wippersnapper_Components HEAD # git clone access
53
+
gh auth status # see if cli/token/login present
54
+
55
+
```
56
+
57
+
| Result | Capability |
58
+
|--------|-----------|
59
+
| All 3 succeed | Full access — use `gh` for forking, PRs, API queries |
60
+
| BBC fails, GitHub API works | Restricted web but `gh` works — skip web fetches for product pages |
61
+
| BBC + API fail, git works | Git-only — use `git clone`/`git push` instead of `gh`, create PRs manually via browser |
62
+
| All fail | Offline — can only write code, user must handle git/PRs |
63
+
64
+
## CI Checks
65
+
66
+
PRs to both repos run CI. Key checks to pass before submitting:
67
+
68
+
**Adafruit_Wippersnapper_Arduino:**
69
+
-**clang-format** — code formatting must match `.clang-format` config. Run `clang-format -i` on all changed files.
70
+
-**Doxygen** — all public/protected methods need Doxygen-style `/*! @brief ... */` comment blocks. CI will fail if these are missing or malformed. Follow the existing driver style exactly.
71
+
-**Build** — firmware must compile for all target boards in `platformio.ini`.
72
+
73
+
**Wippersnapper_Components:**
74
+
-**JSON schema validation** — `definition.json` must conform to `schema.json` in the repo root.
75
+
-**Image validation** — dimensions, file size, and format are checked.
76
+
50
77
---
51
78
52
79
## Step 0 — Research the Sensor
@@ -55,17 +82,17 @@ Before writing any code, gather this information:
55
82
56
83
| What | Where to look |
57
84
|------|---------------|
58
-
| Sensor's Adafruit Arduino library |`gh search repos "Adafruit <SENSOR>" --owner adafruit` or check if it lives inside another library (e.g. TMP119 is in `Adafruit_TMP117`) |
85
+
| Product page | Search the web for "adafruit <SENSOR>" to find the product page. The product page links to the learn guide and Arduino library. This is the fastest route to all other info. |
86
+
| Adafruit Arduino library | The learn guide (linked from product page) shows which library to use. Or: `gh search repos "<SENSOR>" --owner adafruit`. If no dedicated library, check related chips (e.g. TMP119 lives inside `Adafruit_TMP117`). Try partial matches like `TMP11` if exact fails. |
59
87
| Library API | Read the library header on GitHub — find `begin()` signature and sensor read methods (`getEvent`, `readTempC`, etc.) |
|Documentation URL |Prefer: Adafruit learn guide (from product page) > manufacturer datasheet. Non-Adafruit products are accepted — use the manufacturer's product/datasheet URL. Note: third-party domain URLs may initially fail CI URL validation until a maintainer adds the domain to the allowlist.|
64
92
65
93
### Subcomponent type reference
66
94
67
-
These are the valid values for `subcomponents` in `definition.json` and map 1:1 to `getEvent*()`
68
-
methods in the base driver class:
95
+
Valid `subcomponents` values in `definition.json`, mapping 1:1 to base driver `getEvent*()` methods:
69
96
70
97
| Subcomponent | getEvent method |`sensors_event_t` field | SI unit |
71
98
|---|---|---|---|
@@ -95,34 +122,14 @@ When using raw reads (not Unified Sensor `getEvent()`), assign to the correct fi
95
122
96
123
Temperature sensors almost always include both `ambient-temp` and `ambient-temp-fahrenheit`.
97
124
98
-
**Important:** Fahrenheit conversions (`getEventAmbientTempF`, `getEventObjectTempF`) are already
99
-
implemented in the base class — they call the Celsius method and convert. Drivers only need to
100
-
implement the Celsius version (`getEventAmbientTemp`, `getEventObjectTemp`). Never implement
101
-
the Fahrenheit variant in your driver.
125
+
**Fahrenheit:**`getEventAmbientTempF` and `getEventObjectTempF` are in the base class — they
126
+
call the Celsius method and convert. Only implement the Celsius version. Never implement °F.
102
127
103
-
Because the base class Fahrenheit method calls the Celsius method, and the calling order is not
104
-
guaranteed (°F may be called before °C), each `getEvent*()` method should go through a shared
105
-
read-and-cache function with a "recently read" time guard. This way, whichever method is called
106
-
first does the actual I2C read and caches the result; subsequent calls within the window return
107
-
cached data without hitting the bus again.
108
-
109
-
See `WipperSnapper_I2C_Driver_SCD30.h` for the canonical pattern:
**Read-and-cache requirement:** The calling order of `getEvent*()` methods is not guaranteed (°F
129
+
may be called before °C). Every `getEvent*()` must go through a shared `_readSensor()` with a
130
+
millis-based time guard so only the first call per cycle does the I2C read; subsequent calls
131
+
return cached data. See the driver template in Step 1 and `WipperSnapper_I2C_Driver_SCD30.h` and SGP30
132
+
for the canonical patterns.
126
133
127
134
This is especially important for multi-reading sensors but also applies to temperature sensors
128
135
where both °C and °F subcomponents are enabled.
@@ -136,7 +143,7 @@ where both °C and °F subcomponents are enabled.
136
143
### First: Read the library's example sketch
137
144
138
145
Before writing any driver code, find and read the library's `simpletest` or `basic_test` or some example not using interrupts (data ready flags are okay)
139
-
on GitHub. This is your source of truth for how the sensor is meant to be used:
146
+
on GitHub. Check all matches for suitable usage suggestions. This is your source of truth for how the sensor is meant to be used:
140
147
141
148
```bash
142
149
gh api repos/adafruit/<Library_Repo>/contents/examples --jq '.[].name'
@@ -158,7 +165,7 @@ are often not visible in the example sketch but they affect sensor behavior. If
158
165
update changes any of these defaults, it would silently change WipperSnapper's behavior too.
159
166
160
167
When writing the WipperSnapper driver, **explicitly set every configuration parameter that the
161
-
library sets as a default in its `begin()` or `_init()`**. This pins the behavior so that library
168
+
library sets as a default in its `begin()` or `_init()`** chain. This pins the behavior so that library
162
169
updates cannot break WipperSnapper without a deliberate driver change on our side.
163
170
164
171
For example, if the library's `_init()` sets continuous mode with 8x averaging as defaults:
@@ -331,15 +338,13 @@ protected:
331
338
332
339
Two changes, both in **alphabetical order** among existing entries:
333
340
334
-
1. Add the include near the top, with the other driver includes:
-**INA219** (no ambiguity): `["voltage", "current"]`
491
478
492
-
When using `"raw"` as a stand-in, the corresponding driver must implement `getEventRaw()` to
493
-
return that second reading.
479
+
When using `"raw"` as a stand-in, the driver must implement `getEventRaw()` for that reading.
480
+
3.**Non-standard units** — if the sensor reports in a non-SI unit (or doesn't match Adafruit_Sensor type SI unit) then use the appropriate unitless type or raw with a descriptive `displayName` including units.
481
+
4.**Clarity compared to the auto UI labels or between subcomponents** — compare other components using the same types for reference.
494
482
495
483
### 5d. Add product image
496
484
@@ -518,14 +506,15 @@ Fix any compilation errors. Common issues:
518
506
519
507
---
520
508
521
-
## Step 7 — Format with clang-format
509
+
## Step 7 — Format with clang-format, ensure passes doxygen and other CI checks
0 commit comments