The previous doc described only the proprietary 0x81 UART protocol, but
all current AirCarto firmwares (NebuleAir Pro 4G, ModuleAir light) talk
to the NextPM in Modbus RTU. Document the actual register mapping
(PM at 0x38/0x44 for 10s/60s averages, T/HR at 0x6B/0x6A, status at
0x13, 5 granulometric channels at 0x80-0x88), the LSW-MSW word order,
and both reading strategies (per-register and bulk read). Move the
proprietary 0x81 protocol to an annex; drop Python/C examples (to be
published in separate docs).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deployed firmwares hardcode command=0x01 (legacy from when the byte was
named `version`); treating 0x01 as ping would have flagged every existing
frame as a diagnostic. Keep 0x00/0x01 as normal-data and use 0x02 as the
explicit ping trigger.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Le champ `version` (offset 9 du payload NebuleAir Pro 4G) était hardcodé
`0x01` côté firmware et n'a jamais porté un vrai versioning protocole.
Renommé en `command` et réaffecté à un type de trame :
- 0x00 = données mesure
- 0x01 = ping test (firmware → Miotiq → backend, pas d'archivage)
Versioning protocole reste sur `version_major/minor/patch`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Will be moved to its own file later. Kept only the descriptor format
spec and per-sensor binary layout in this doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parsers and formats are tightly linked (a parser produces a format) and
the split made cross-links heavy for a single parser file. Also removed
the confusing "Enveloppe JSON" block in udp-miotiq.md that mixed the
raw webhook wrapper with what the backend actually consumes — the
decoded payload schema lives in json-payload.md and is now referenced
directly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Breakdown per-transmission size (UDP+IP overhead + payload), daily/monthly/
yearly/10y consumption tables for both fixed (NebuleAir Pro 4G, 83B) and
mobile (MobileAir, 17B) modes at various transmission intervals, and a
with-signaling majorant (x1.5) for LTE-M worst case.
Recommended intervals: 5 min fixed (~12% budget) and 30s-in-motion mobile
(~16%), both leaving ample margin for descriptor growth and retries.
Flags scenarios that would exceed budget (fixed 30s continuous, mobile 10s
24/7) and lists TODOs around validating counting policy via Miotiq reports.
Today these 3 fields appear in the JSON final but are absent from the 83B
descriptor. The 11-byte 'reserved' block has room for all three (4+4+1=9).
TODO section now proposes concrete encoding lines:
8|latitude|hex2dec|degrees|x/1000000|
8|longitude|hex2dec|degrees|x/1000000|
2|misc|hex2dec|||
...with an open question on whether Miotiq hex2dec supports signed ints,
and a note to keep 2 bytes reserved for future growth.
formats/json-payload.md: full rewrite around the actual server-side template
(endpoint api.aircarto.com/receive_data?device_type=<model>, flat schema,
_unit suffix companions, -1 and 255 sentinel semantics, full bitfield
tables for error_flags/npm_status/device_status, misc context codes).
formats/iso-pollutant-codes.md: fill in the LCSQA mapping. Fixes my earlier
inversion — ISO_39=PM2.5 and ISO_24=PM10 (not the other way). Add gases:
ISO_03=NO2, ISO_04=CO, ISO_05=H2S, ISO_08=O3, ISO_21=NH3.
parsers/udp-miotiq.md:
- string base function outputs hex (not ASCII) — update description and
generic Python parser accordingly.
- Fix ISO_39/ISO_24 labels in NebuleAir Pro 4G byte layout.
- Name the 5 gases by offset, cross-link bitfield docs and JSON canonical.
- New TODO: origin of latitude/longitude/misc in final JSON (not in 83B
descriptor).
README.md: reflect the new file layout and data flow summary.
- 6th column is 'export to JSON' (Y/W/N), not a writable flag.
- Add base functions hex2bin (bitfield string) and userdef (pass-through).
- Rename 'scale' to 'equation' (expression in x, e.g. (x-32)*5/9 possible).
- Update generic Python parser to handle all base functions and emit Y-style unit rows.
- Remove resolved TODO on flag W semantics.
- Refactor parsers/udp-miotiq.md around the pipe-separated descriptor format used on Miotiq side.
- Document the full 83-byte NebuleAir Pro 4G descriptor (PM, gases, noise, weather, power, status).
- Keep legacy MobileAir 17B binary format for reference.
- Add formats/iso-pollutant-codes.md placeholder for AirCarto ISO 7168 code mapping.
- Open TODOs: flag W semantics, endianness, signed battery_current, MobileAir migration.