0.7.0: assenza con date, conto alla rovescia del boost, catalogo rifatto
- AwayDialog.qml: popup con inizio e fine (Dialog, ValueButton, DatePickerDialog: componenti e proprieta' verificati nella guida Silica dell'SDK). Il tasto Assenza apre il popup invece di mandare il comando; - conto alla rovescia 30:00 -> 00:00 in Home e in copertina, con i secondi dell'impianto (AiraJson::countdown + timer che si riallinea a ogni lettura); - commandPayload accetta campi extra (start/end); - catalogo: lupdate leggeva solo i C++ e marcava 151 voci QML come obsolete. Ora src e qml espliciti: 197 stringhe, 0 non tradotte; - versione 0.7.0 (spec, main.cpp), PROTOCOL, README/PIANO, post per il forum.
This commit is contained in:
@@ -149,8 +149,8 @@ check("senza termostato: nessun errore",
|
||||
from pyairahome.commands import CommandBase # noqa: E402
|
||||
|
||||
boost = b.build_command("hot_water_boost_on")
|
||||
check("boost: un'ora di default",
|
||||
boost._message.hot_water_boost_duration.seconds == 3600,
|
||||
check("boost: mezz'ora di default (richiesta dell'utente)",
|
||||
boost._message.hot_water_boost_duration.seconds == 1800,
|
||||
f"{boost._message.hot_water_boost_duration.seconds}s")
|
||||
check("boost: durata scelta in minuti (90 -> 5400s)",
|
||||
b.build_command("hot_water_boost_on", 90)
|
||||
@@ -199,6 +199,47 @@ for cid in b.COMMANDS:
|
||||
check(f"whitelist: {cid} si costruisce e si incarta", False,
|
||||
f"{type(exc).__name__}: {exc}")
|
||||
|
||||
# --- 6) assenza con date, e conto alla rovescia del boost ----------------- #
|
||||
from datetime import datetime, timedelta, timezone # noqa: E402
|
||||
from zoneinfo import ZoneInfo # noqa: E402
|
||||
|
||||
ROMA = ZoneInfo("Europe/Rome")
|
||||
|
||||
|
||||
def a_roma(t):
|
||||
return t.ToDatetime(tzinfo=timezone.utc).astimezone(ROMA).strftime("%Y-%m-%d %H:%M")
|
||||
|
||||
|
||||
date_di = b.build_command("away_mode_on", None, 1, ctx,
|
||||
{"start": "2026-11-01", "end": "2026-11-08"})
|
||||
m3 = date_di._message
|
||||
check("assenza con date: inizio = 1 novembre a mezzanotte",
|
||||
a_roma(m3.current_time) == "2026-11-01 00:00", a_roma(m3.current_time))
|
||||
check("assenza con date: fine = mezzanotte dell'8 (da li' riparte)",
|
||||
a_roma(m3.end_time) == "2026-11-08 00:00", a_roma(m3.end_time))
|
||||
check("assenza con date: casa a 15 °C", abs(m3.target_room_temperature - 15.0) < 1e-6)
|
||||
rifiuta("assenza: fine prima dell'inizio", "away_mode_on", None, 1, ctx,
|
||||
{"start": "2026-11-08", "end": "2026-11-01"})
|
||||
rifiuta("assenza: data illeggibile", "away_mode_on", None, 1, ctx,
|
||||
{"start": "domani", "end": "2026-11-08"})
|
||||
rifiuta("assenza: oltre 180 giorni", "away_mode_on", None, 1, ctx,
|
||||
{"start": "2026-11-01", "end": "2028-11-08"})
|
||||
|
||||
fra = (datetime.now(timezone.utc) + timedelta(minutes=20)).isoformat().replace("+00:00", "Z")
|
||||
check("boost in corso: restano ~1200 secondi",
|
||||
abs(b.boost_restanti({"hot_water_boost": {"end_time": fra}}) - 1200) <= 3)
|
||||
check("boost finito: zero secondi",
|
||||
b.boost_restanti({"hot_water_boost": {"end_time": "2026-01-01T00:00:00Z"}}) == 0)
|
||||
check("boost mai avviato: zero secondi", b.boost_restanti({}) == 0)
|
||||
riassunto = b.summarize({"hot_water_boost": {"end_time": fra}})
|
||||
check("riassunto: dice che il boost e' in corso", riassunto.get("boost_active") is True)
|
||||
check("riassunto: porta i secondi del boost",
|
||||
abs(riassunto.get("boost_remaining_seconds", 0) - 1200) <= 3,
|
||||
str(riassunto.get("boost_remaining_seconds")))
|
||||
check("riassunto senza boost: spento e zero",
|
||||
b.summarize({}).get("boost_active") is False
|
||||
and b.summarize({}).get("boost_remaining_seconds") == 0)
|
||||
|
||||
# --- esito ---------------------------------------------------------------- #
|
||||
falliti = [n for n, ok, _ in esiti if not ok]
|
||||
print(f"\n{len(esiti) - len(falliti)}/{len(esiti)} controlli superati")
|
||||
|
||||
Reference in New Issue
Block a user