278 files

This commit is contained in:
Home Assistant Version Control
2026-09-13 20:38:58 +00:00
parent d7a0a08372
commit 1b4f5f68c6
278 changed files with 36892 additions and 7150 deletions
+63
View File
@@ -486,6 +486,21 @@ class Chore:
}
def _clean_weekdays(raw: Any) -> list[int]:
"""Coerce stored weekday numbers to a sorted, de-duplicated 0-6 list."""
if not isinstance(raw, (list, tuple, set)):
return []
out: set[int] = set()
for item in raw:
try:
day = int(item)
except (TypeError, ValueError):
continue
if 0 <= day <= 6:
out.add(day)
return sorted(out)
@dataclass
class Reward:
"""Represents a reward."""
@@ -509,6 +524,15 @@ class Reward:
# checked both at save time and again when it fires.
unlock_entity: str = ""
unlock_minutes: int = 0
# Time lock (#857): restrict claiming to certain weekdays and/or a
# time-of-day window. `available_days` holds Python weekday numbers
# (0=Monday .. 6=Sunday); empty means every day. The times are "HH:MM";
# a start later than the end is an overnight window. All of it is inert
# unless `time_lock_enabled` is set.
time_lock_enabled: bool = False
available_days: list[int] = field(default_factory=list)
available_from: str = ""
available_until: str = ""
id: str = field(default_factory=generate_id)
def __post_init__(self) -> None:
@@ -542,6 +566,10 @@ class Reward:
unlock_minutes=int(data.get("unlock_minutes", 0) or 0),
restock_period=data.get("restock_period", "weekly"),
restock_last=data.get("restock_last", ""),
time_lock_enabled=bool(data.get("time_lock_enabled", False)),
available_days=_clean_weekdays(data.get("available_days")),
available_from=str(data.get("available_from", "") or ""),
available_until=str(data.get("available_until", "") or ""),
id=data.get("id") or generate_id(),
)
@@ -563,6 +591,10 @@ class Reward:
"restock_last": self.restock_last,
"unlock_entity": self.unlock_entity,
"unlock_minutes": self.unlock_minutes,
"time_lock_enabled": self.time_lock_enabled,
"available_days": list(self.available_days),
"available_from": self.available_from,
"available_until": self.available_until,
"id": self.id,
}
@@ -1283,3 +1315,34 @@ class CustomNotification:
"recipient_ids": list(self.recipient_ids),
"enabled": self.enabled,
}
@dataclass
class CustomSound:
"""A user-uploaded completion sound (#856).
``file`` is the generated ``<32 hex>.<ext>`` name on disk under
``<config>/taskmate_sounds``; it doubles as the sound's identity, so a
chore references this row as ``custom:<file>``. There is no separate id:
a second id would let the row and the file drift apart, and the filename
is already unique and immutable.
"""
name: str
file: str
created_at: str = field(default_factory=dt_util_now_iso)
@classmethod
def from_dict(cls, data: dict[str, Any]) -> CustomSound:
return cls(
name=data.get("name", ""),
file=data.get("file", ""),
created_at=data.get("created_at", "") or dt_util_now_iso(),
)
def to_dict(self) -> dict[str, Any]:
return {
"name": self.name,
"file": self.file,
"created_at": self.created_at,
}