b8ef430ed4a72daa05bf052d087cfb11a0e9a7b8
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
96d06369bc |
review: floor the sensing interval at one minute
Dropping native_min to 0 fixed the read range and quietly opened a write:
native_min governs what the user can enter, not just what renders, so 0
became enterable and would have gone out as periodicSensingInterval "0".
Nothing establishes what that does to this board -- both fixtures report 600,
the app's smallest choice is 10 min, and 60 s is the lowest value confirmed
accepted. The two precedents leaned on differ in exactly the way that matters:
oven.cook_time and operational.delay_start_hours sit at a zero floor under a
value where 0 is a real setting ("no timer", "no delay").
One minute is also the resolution this board reports results at.
lastSensingTime lands on an exact minute on every sample from the AVT-WW-TP1
and A-VTWW-TP2 boards -- both fixtures, plus eleven consecutive live readings
-- where the TP1X/AC/hood boards report arbitrary seconds. A sub-minute
interval is unobservable here whether or not the board honours it.
So native_min goes to 1 rather than 0, and the read rounds up instead of to
nearest so a sub-minute reading renders as 1 rather than falling below the
entity's own floor. The write still refuses anything under a minute -- a None
return, the silent no-op range_hood._lamp_level_write uses for a level the
device didn't advertise -- since native_min only guards the UI path, not a
service call.
|
||
|
|
a5484f746a |
review: unfold AI Purify into one entity per field
Review feedback on #268. The largest change is that the sensing-mode select no longer folds two device fields into one control. periodicSensingActivationState and autoExeState are independent knobs, and the appliance presents them that way -- its own UI has an on/off for AI Purify separately from the three mode choices. Folding them lost two things: a configured action was invisible while the feature was off, and no select option could toggle the feature without also overwriting the action. The switch was not the duplicate it looked like. So the switch now owns periodicSensingActivationState alone, and the select owns autoExeState alone. That resolves the hardcoded-options finding at the source rather than working around it: the select reads supportedAutoExeState via options_field -- the same shape SOUND_MODE already uses for supportedModes -- instead of carrying a typed-in tuple, so a board advertising a fourth action is accepted on both the options list and the write path. _sensing_mode, _sensing_mode_write and _SENSING_MODE_BODIES are all gone with the fold. Option slugs are now the advertised values lowercased (off / airpurify / alarm) rather than invented names. The catalog carries the labels, so the two 'off's stay distinguishable in the UI: the switch's means the unit isn't sampling, the select's means it samples and doesn't act on the reading -- what the app calls "sensing only". Also from the review: * _interval_minutes checks `is None` so a reported 0 stays 0, and native_min drops to 0 since sub-30s values round there. oven.cook_time and operational's delay hours are the precedent -- both convert a device time value and floor at zero. The Number-rather-than-Select choice is now stated in the write helper: the app offers three fixed intervals, but this resource advertises no supported-values or range field (supportedAutoExeState sits right beside it, so the board does advertise constraints where it has them) and it accepted 60 s, six times finer than the app's smallest choice. * _skip_time_write no longer splices a malformed half back onto the wire. The read side already refuses one it can't parse; the write side now zeroes it to match. * air_sensing_state and last_air_sensing_level lose enabled_default=False, matching range_hood.AIR_LEVEL_CHECK. Hiding two of three read-only keys while claiming key parity with that capability -- and leaving the third visible -- had no justification behind it. * The catalog-parity test drops periodic_air_sensing from its key set: that key is a SwitchDesc here and a BinarySensorDesc on the hood, so the two live in different platform catalogs and are worded differently. The claim now covers only the three read-only sensor keys, where it holds. * Tests route through the descriptors (_desc(key).write_fn / .value_fn) rather than module-private helpers, matching test_air_monitor_capabilities. startSensingOnce stays unbound, now explicitly rather than by omission -- the module comment records it as deferred. It looks like a one-shot "sense now" button, but this board acknowledges writes it discards, and nothing has confirmed the side effect yet. Goldens are untouched: the key set is unchanged, only sensing_mode's value moves from the folded slug to the raw autoExeState. |
||
|
|
412fff9b99 |
feat(air_purifier): expose the AI Purify sensing engine on /airlevelcheck/vs/0
/airlevelcheck/vs/0 has been covered as "periodic air-quality sensing scheduler plumbing" since the registry gained a coverage stub for it. Two AVT-WW-TP1-23-AXX500 dumps (issues #84 and #190) show it is not plumbing: it drives the feature the SmartThings app calls AI Purify, where the unit wakes on a timer, samples the air, and optionally acts on the result. Every field is named, none are opaque, and two of them are already user-set on the reported units. The select's three on-states are the app's own options rather than an invented grouping -- it offers exactly "Sensing only" (sample, take no action), "Auto clean" (purify while the air reads bad, stop once it improves) and "Get notified" (raise a SmartThings notification). Labels were transcribed from the Korean app and rendered in English; the auto-stop half of "Auto clean" is the app's own description and is not otherwise visible in the dump, which reports only the selected autoExeState. The remaining entity names follow their raw fields rather than inventing a concept -- the skip window is "sensing skip", after periodicSensingSkipStatus/Time. Three of this registry's four board families report the resource with the same field names -- TP1X_DA-AC-AIR (#130), A-VTWW-TP2 (#151) and AVT-WW-TP1 (#84, #190). Only ARTIK051_TVTL (#56) has no such href, and its golden is unchanged. Bound unconditionally rather than behind a match_fn; the one field that genuinely varies (periodicSensingInterval, absent on the #130 board) is gated per-entity, so that board gets eight entities instead of nine rather than a broken one. range_hood.AIR_LEVEL_CHECK already models this same href, and its read-only keys are reused verbatim here so both families share one catalog entry. It is deliberately not imported: the hood exposes periodic_air_sensing as a read-only BinarySensorDesc and this board needs a writable SwitchDesc on that key, so reusing the hood's capability would migrate every hood user's entity to a different platform. Every write was exercised on AVT-WW-TP1-23-AXX500 hardware. This board hands out 2.04 for writes it silently discards (see HEPA_FILTER's filter-reset note), so an echo proves nothing -- each was judged by whether the value survived a reconnect, which forces a new DTLS session, fresh discovery and a fresh observe of the href, leaving no cached state to read back: * sensing_mode's combined two-field PUT lands both fields, both ways: sensing_only -> auto_purify raises autoExeState with activation still On, and back again lowers it. * The sensing-skip switch holds Off -> On and back. * The half-preserving time writes hold: from 13:00-23:00, writing start=07:30 then end=22:00 left the device on '07302200' -- each write kept the half it wasn't given. * periodic_air_sensing and sensing_interval: writing 60 s drove an observed ~60 s sensing cycle. * The read side of the skip window is separately cross-confirmed on two units: #84's sits at the inert '00000000', #190's carries a real '03002300' (03:00-23:00), which is what pins the HHMMHHMM split. * The other two families get the writes on field-shape grounds -- the same basis on which they already share MODE, HEPA_FILTER and the air-quality sensors. range_hood._timestamp moves to common.epoch_to_utc so both callers share it, matching how filter_usage_percent was shared. No behaviour change. Every existing entity is untouched: the three golden updates are purely additive, no renames, no unit or device_class changes. |