occupancy classification does not change across gross occupancy change (single deployment, needs second-site confirmation)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 94.4k
- Forks
- 12.5k
- Avg merge
- 21h 27m
- Merged PRs (30d)
- 43
Description
Summary
On one hardware deployment, the top-level occupancy classification never changed value. Across
90 samples spanning deliberately extreme stimulus — including the operator leaving the room
entirely — presence had exactly one distinct value (true), estimated_persons was always
1, and confidence was always 0.4.
Stated limitation up front: this is one room, one server build, one node topology. It has
not been reproduced on a second installation. Filing so it can be checked elsewhere; if other
installs do not show it, something specific to this one is responsible and the issue should be
closed.
Measurements
Three ESP32-S3 nodes on v0.8.4, ~127 frames/s aggregate, with a completed empty-room baseline
active (fresh, bound, 85,731 frames, receipt issued).
Perturbation sequence, 90 samples at 1 Hz:
| phase | n | presence | persons | confidence | variance (median) |
|---|---|---|---|---|---|
| sit still | 18 | 18/18 true | 1 | 0.4 | 427.8 |
| walk through node↔AP line of sight | 18 | 18/18 true | 1 | 0.4 | 468.3 |
| wave both arms ~50 cm from a node | 18 | 18/18 true | 1 | 0.4 | 452.7 |
| operator out of the room | 18 | 18/18 true | 1 | 0.4 | 408.0 |
| return and sit | 18 | 18/18 true | 1 | 0.4 | 443.9 |
across all 90 samples: distinct presence values = {true}
distinct confidence values = [0.4]
Separate empty-vs-occupied A/B (10 samples each) — classification bit-identical. Per-feature
discrimination (AUC; 0.5 = chance):
breathing_band_power 0.38 spectral_power 0.40
dominant_freq_hz 0.53 change_points 0.53
mean_rssi 0.60 motion_band_power 0.60
variance 0.69
The DSP underneath is alive — features vary sample to sample. variance carries weak signal
(AUC 0.69). It does not reach the classification.
breathing_band_power at AUC 0.38 is below chance: it read slightly lower with a person in
the room.
Notes on interpretation
The three constant fields are not three independent results, and should not be read as
three confirmations:
confidenceis0.4 + signal_quality * 0.3 + motion_score * 0.3(main.rs:2670), so 0.4 is
its floor.estimated_personsis gated behindif classification.presence(main.rs:8090).
So this is one stuck classification echoed through dependent fields.
One inconsistency worth a look independently: the emitted confidence is 0.3999999999999996
while the live signal_quality_score was 0.4928733422189253. By the expression above that
should be at least 0.4 + 0.4929*0.3 = 0.5479, so the emitted value does not appear to come
from that expression.
Environment caveats (disclosed, not dismissed)
- The three nodes sit within roughly 1 m of one another — poor multistatic geometry.
- Masonry/stone room with a structural pillar and metal radiators — heavy multipath.
Both would weaken spatial discrimination. Neither explains a constant: node spacing cannot
make presence unable to differ between an occupied and an empty room, and the arms-at-50 cm
phase is about the largest perturbation available in the space.
Done when
Either the classification responds to gross occupancy change on this class of deployment, or
it is established that this configuration is out of scope and the system says so rather than
emitting a confident constant.
Work items
- Confirm or refute on a second installation — the blocking question.
- Trace why
classification.presencenever leavestruewhen frames continue and the
environment changes drastically. - Check the
confidenceexpression againstsignal_quality_score(above). - Consider whether an undiscriminating classifier should report low confidence rather than
a constant 0.4.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in main.rs around lines 2670 and 8090, tracing how classification.presence, estimated_persons, and confidence are produced. Check the confidence expression against signal_quality_score, then reproduce the occupancy sequence on a second installation if available. Done means the behavior responds to gross occupancy changes or the configuration is identified as out of scope and reports low confidence rather than a constant.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100