ADR-0055: Fridges and freezers — levels decided by Home Assistant against food-safety norms, a « Froid » popup, central-card alerts and a blinking icon on the clock, pushed by tab5_maj_froid¶
Status: Accepted (2026-10-10, asked for by the author; not tried on a tablet when written). Date: 2026-10-10
Context¶
The author wants to watch his fridge and freezer from the tablet: declare them in the settings, check their temperature against the norms, catch a rise (a door left ajar), see the last 24 hours, get the usual alerts of the central card, and — for a serious problem only — an icon that blinks in the clock's top-right corner. A full-screen popup gathers the curves and the incidents.
Constraints: push-only and events-only (ADR-0001, ADR-0025); no entity ID in the firmware or in the public HA files (ADR-0024); colours from the palette (ADR-0029); lv_chart is not compiled; instant transitions, no fade (author's taste).
Decision¶
- Declared in Home Assistant, never guessed. Two multiple-choice lists built like « Tab5 · capteurs suivis » (ADR-0054): « Tab5 · réfrigérateurs · fridges » (
select.tab5_refrigerateurs) and « Tab5 · congélateurs · freezers » (select.tab5_congelateurs), memoriesinput_text.tab5_choix_frigos/tab5_choix_congelateurs. Only temperature sensors with statistics are offered (device_class: temperature,state_class: measurement); a sensor chosen in one list is not offered in the other; four appliances at most in all (the popup's four cards). Empty lists work: the popup says where to declare them. - Home Assistant decides, the tablet shows.
packages/tab5_froid.yamlcomputes, for each appliance, a level (0 within norm, 1 attention, 2 serious), a cause (ok,chaud,froid,porte,indispo) and since when, from the current value andrecorder.get_statistics(5-minute statistics for the last 30 minutes, hourly ones for the curve and the 24-hour extremes). The thresholds are in one place, theseuilsvariable ofscript.tab5_froid_calculer, commented: - fridge: norm 0 to 5 °C; attention when the 15-minute mean is above 5 or below 0; serious above 8 for 30 minutes, or at 10 or more;
- freezer: norm -18 °C at most; attention when the 15-minute mean is above -15; serious above -12 for 30 minutes, or at -10 or more;
- door: a rise of 2 °C (fridge) / 4 °C (freezer) between the lowest of the last 30 minutes and now is « porte ouverte ? » (attention); still there after 20 minutes and not going down (no more than 0.5 °C under the episode's highest) it is « porte mal fermée » (serious). The « not going down » guard is ours: a door closed after a long opening cools down slowly and must not end as « mal fermée »;
- no reading for 30 minutes: « capteur muet » (attention); shorter gaps keep the previous state.
A Fahrenheit sensor is converted. The rules are applied in that order (first true wins) and mirrored by an independent Python calculation in
tests/test_froid.py. - State kept in Home Assistant, not in the tablet. A trigger-based template sensor
sensor.tab5_froid(state = the most serious level, attributeappareils, restored at restart) is updated only by thetab5_froid_bilanevent that the script fires; the script reads its previous attributes (when a cause started, the running incident, the last finished one). An incident runs from the first non-zero level to the return to 0; the last finished one (most serious cause, start, duration, extreme) stays with the appliance. - When. A mirror (« Tab5 · signature du froid ») changes when a sensor changes: an automation in mode
singlecomputes at once, waits one minute (changes meanwhile are dropped) and computes again if the signature moved. A second automation computes every five minutes (durations move on without a change), when a list changes, when the tablet connects, on « MAJ Écran » and at HA start (tab5_origineguard). The state is kept even when the tablet is away; the push needstab5_connectee. - One new action, one compact payload.
tab5_maj_froid(payload): one record per appliance, fifteen|fields —name|type|value|level|cause|since|min|max|low|high|points|icause|istart|iduration|imax— temperatures in °C with one decimal (empty: unknown; empty low: no lower limit), the norm pushed by HA (the tablet hard-codes none), 24 hourly means then the current value. Read in pure C++ byfroid_lire()(Tab5/socle/tab5_parse.*, section 12; cases intools/test_parse.cpp, called by the libFuzzer harness and fuzzed with the other services): four appliances, 32 points, temperatures bounded to ±80 °C, an unknown type skips the record, a level above 2 is 2. - Alerts of the central card. A source « froid » in
custom_templates/tab5_alertes.jinja: one stable id per appliance (froid:<entity_id>), revision key = cause and level (a value that changes only updates the text), Orange at level 1, Red at level 2, coded text@froid:<cause>:<level>:<value>:<name>composed by the tablet in its language (ha_alerte_texte(): « Frigo cuisine : porte mal fermée, 9.1 °C »). Subscription: « Tab5 · alertes : réfrigérateurs et congélateurs » (Oui / Non). Doubt (sensor.tab5_froidunavailable) is never an end. - The blinking icon.
fridge-alert(F11B1,mdi_font_26, roleERROR) in the clock tile's top-right corner (btn_froid_alerte, the 27 px left of the minutes' frame), shown only while an appliance is at level 2. It blinks without fade: onelv_timerof 500 ms created once, paused while the icon is hidden; it stays lit while the Froid popup is open. No acknowledgement: it stays as long as the serious level lasts. A tap opens the popup throughtab5_ecran_ouvrir. It follows the theme (role style). - The « Froid » popup. Full-screen modal with the shared chrome (ADR-0009), one
ModalRegistry::addline (ADR-0013, 26 of 32),Ecran::FROID(option « Froid » at the end of « Aller à l'écran », gesture codefroidat the end ofkCodesGestes, index 27, offered by the blueprint), and in the navigation wheel (ADR-0042) at the end of Agenda — Devices (8 of 8) and the first ring (6 of 6) are full; offered unless Home Assistant said no appliance is declared. Its title is « Frigos et congélateurs » and its wheel word « Frigos »: the key « Froid » already translates as « Cool » (a climate mode, a lamp's white). One card per appliance (froid_carte.yaml, four instances), one row for one or two, two rows of two above: icon (fridge or snowflake), name, temperature coloured by level (SUCCESS/WARNING/ERROR), status (« Conforme », « Trop chaud depuis 14 h 32 », « Porte mal fermée »…), 24-hour extremes and the norm, the 24-hour curve (ui_courbe_lisse()) between the dashed lines of the norm, and the last incident.
Consequences¶
- Contract stays 1.2.0: one action added since the last release (v3.8.0-rc.4, contract 1.1.0), already a minor step. Update order: firmware first, then
packages/tab5_reglages.yaml,packages/tab5_froid.yaml,packages/tab5_alerts.yaml,custom_templates/tab5_alertes.jinjaand the blueprint. New HA files with an older firmware: the push fails without stopping anything else (continue_on_error), and the alert text shows raw (@froid:…) until the firmware is updated; new firmware with older HA files: the popup says « En attente de Home Assistant ». - The 5-minute statistics are compiled after their period ends: the current value always joins the 15-minute mean and the 30-minute minimum, so a rise is seen at once.
- A door opened for shopping can raise « porte ouverte ? » (attention, Orange) for a few minutes: that is the requested threshold. It becomes serious only if the rise lasts 20 minutes without cooling down.
- 37 new screen texts in six languages; MDI glyphs
fridge(F0290: 26, 32, 36, 45, 70) andfridge-alert(F11B1: 26). - Render: three captures (
froid-vide,froid, andaccueil-froid, not compared: the icon blinks).