acme-camera: boundaries, device-cloud, fleet management with bulk config, AI usage

caf8326 · Gabriel Morell · 2026-10-13 19:37

3 files +144 -1

Files changed

modified content/presentations/acme-camera.md
+144 −1
@@ -18,7 +18,7 @@ reveal_transition = "slide"
18 18
19 19 1. Architecture: hardware and software
20 20 2. Performance metrics and targets
21 −3. Instrumentation and fleet data
21 +3. Instrumentation and fleet management
22 22 4. Risks, plan and questions
23 23
24 24 Note:
@@ -222,6 +222,22 @@ Each unit runs as its own user with ProtectSystem=strict and DeviceAllow for onl
222 222 The broker checks the connecting uid (SO_PEERCRED) against per-topic ACLs, so portalctl can request config but never write it
223 223 A crashed daemon is restarted by systemd and counted in telemetry
224 224
225 +--
226 +
227 +## Boundaries
228 +
229 +| Boundary | Transport |
230 +|---|---|
231 +| process ↔ process | MQTT on a Unix socket |
232 +| SOC ↔ MCU | UART + wake GPIO |
233 +| device ↔ cloud | MQTT 5 over mutual TLS |
234 +| clips → cloud | HTTPS to object storage |
235 +
236 +Note:
237 +The MCU raises a GPIO to wake the SOC, then they talk COBS-framed messages over UART from one shared schema, so both sides agree on MotionDetectionMode and friends
238 +mcuctl is the only process that touches the UART, everything else goes through the broker
239 +Video never goes over MQTT, cameractl gets a pre-signed URL and uploads clips directly
240 +
225 241 ---
226 242
227 243 # Boot Plan
@@ -263,6 +279,49 @@ Factory reset wipes /data and revokes the device cert server side
263 279
264 280 ---
265 281
282 +# Device ↔ Cloud
283 +
284 +One connection, held only while awake
285 +
286 +Note:
287 +The device is asleep most of the time, so the cloud is designed around a device that is usually unreachable
288 +
289 +--
290 +
291 +## Connection
292 +
293 +| Concern | Approach |
294 +|---|---|
295 +| Identity | per-device cert from the claim |
296 +| Transport | MQTT 5 over mutual TLS |
297 +| Reconnects | TLS session resumption |
298 +| Commands | queued until the next wake |
299 +| Config | device shadow, desired vs reported |
300 +| Offline | buffer locally, send on reconnect |
301 +
302 +Note:
303 +Session resumption skips most of the TLS handshake on every wake, which is time and energy on the event path
304 +A persistent MQTT session holds commands for a sleeping device, it picks them up on its next wake or heartbeat
305 +Live view needs the device reachable while asleep, which means Wi-Fi power-save on the SOC module or the keep-alive radio from the trade-offs, both cost standby current
306 +
307 +--
308 +
309 +## Cloud Topics
310 +
311 +| Topic | Direction | Carries |
312 +|---|---|---|
313 +| `d/<id>/event` | up | motion, detections |
314 +| `d/<id>/telemetry` | up | batched metrics |
315 +| `d/<id>/shadow` | both | desired / reported config |
316 +| `d/<id>/cmd` | down | live view, reboot, logs |
317 +| `d/<id>/ota` | down | update offers |
318 +
319 +Note:
320 +The device can only publish and subscribe under its own id, enforced by the cert
321 +The shadow is the bridge to configctl: the cloud writes desired, configctl applies it and reports back what it actually runs
322 +
323 +---
324 +
266 325 # Components
267 326
268 327 | Component | Role |
@@ -440,6 +499,62 @@ A crash spike in a new firmware cohort pauses the rollout automatically
440 499
441 500 ---
442 501
502 +# Fleet Management
503 +
504 +Identity, config and updates for every device
505 +
506 +Note:
507 +Two audiences use the same tools: Acme operating the whole fleet, and owners managing their own cameras
508 +
509 +--
510 +
511 +## Lifecycle
512 +
513 +| Stage | What happens |
514 +|---|---|
515 +| Factory | keys in the secure element, cert registered |
516 +| Claim | owner's app links the device to an account |
517 +| Operate | shadow config, telemetry, alerts |
518 +| Update | staged OTA by cohort |
519 +| Retire | reset wipes `/data`, cert revoked |
520 +
521 +Note:
522 +The claim token is the QR code on the device, it's useless without the device cert behind it
523 +A resold camera goes through Retire then Claim, so the new owner never sees the old owner's data
524 +
525 +--
526 +
527 +## Bulk Configuration
528 +
529 +- Owners group cameras by site or area
530 +- Profiles: motion, light, power, processing
531 +- Apply a profile to a group, override per camera
532 +- Each camera reports when it has applied
533 +
534 +Note:
535 +A profile write sets the desired shadow on every camera in the group, each one picks it up on its next wake or heartbeat
536 +configctl validates it like any other change, so a profile can't push a camera into a state it doesn't support
537 +The app shows pending / applied / rejected per camera, because sleeping devices apply changes over minutes, not instantly
538 +Same mechanism Acme uses at fleet scale, e.g. changing a default for a firmware cohort
539 +
540 +--
541 +
542 +## OTA Rollout
543 +
544 +| Stage | Devices | Gate |
545 +|---|---|---|
546 +| Internal | ~50 dogfood | a clean week |
547 +| Canary | 1% | crashes, drain vs control |
548 +| Staged | 10% → 50% | same, per cohort |
549 +| Full | 100% | |
550 +
551 +Note:
552 +Any cohort regressing on crash rate or battery drain pauses the rollout automatically
553 +Devices only download above a battery threshold or while charging, and delta updates keep the bytes down
554 +A/B slots mean a bad update rolls back on its own, the rollout gates are about not needing that
555 +
556 +---
557 +
443 558 # Risks
444 559
445 560 | Risk | Mitigation |
@@ -921,3 +1036,31 @@ struct Detection {
921 1036
922 1037 Note:
923 1038 A detection above the threshold upgrades a motion event into a person / vehicle / package alert
1039 +
1040 +---
1041 +
1042 +# How I Used AI
1043 +
1044 +| Where | How |
1045 +|---|---|
1046 +| Slides | drafted text, tables and notes |
1047 +| Types | sketched the Rust types per component |
1048 +| Review | checked the deck against the brief |
1049 +| Tooling | built and deployed the deck site |
1050 +
1051 +Note:
1052 +Draft, edit to match what you actually did
1053 +Tooling included the Diogramos embed frame mode and theme sync, the Forgejo CI and the Argo deploy
1054 +
1055 +--
1056 +
1057 +## Practices
1058 +
1059 +- AI drafts, I decide the architecture
1060 +- Numbers checked by hand: power math, part specs
1061 +- Small steps, reviewed and committed as I go
1062 +- Every slide rendered and checked
1063 +
1064 +Note:
1065 +Draft, edit to match how you actually work
1066 +

Parents: 3b61cfd