fix(ha): cushion check - eliminate hallucinations + add quiet hours
Prompt fixes after Gemini was flagging empty terraces as having cushions (count=4 on bare metal rattan chairs): - Correct scene description: camera on left wall of house, terrace visible on right side (was incorrectly described as bird's-eye view) - Explicit anti-hallucination guidance: don't assume textiles are there by default, empty terraces are common - Add "DEFINITIVELY NOT TEXTILES" list (built-in rattan seats/backs, metal frames, shadows) - prior prompt only mentioned them indirectly - Lead examples with "empty terrace" case so AI uses it as anchor - Tiebreaker rule: when uncertain, default to has_loose_cushions=false Quiet hours: no notify between 22:00-07:00 to avoid waking up. Snapshot and AI evaluation still run and log, just no push/telegram during the window. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6328a7c275
commit
eb58e9c736
|
|
@ -43,37 +43,42 @@ COOLDOWN_HOURS = 3
|
|||
FORECAST_PRECIP_THRESHOLD_MM = 0.5
|
||||
RAIN_NOW_THRESHOLD_MM = 0.1
|
||||
|
||||
INSTRUCTIONS = """Analizujesz obraz z kamery zewnetrznej (widok z lotu ptaka na taras o kamiennej posadzce).
|
||||
# Quiet hours - nie wysylaj powiadomien miedzy [START, END) godzina lokalna
|
||||
# (22:00 - 07:00 = noc). Snapshot/AI nadal sie wykonuje (loguje), ale BEZ alertu.
|
||||
QUIET_HOURS_START = 22 # 22:00
|
||||
QUIET_HOURS_END = 7 # 07:00
|
||||
|
||||
KONTEKST SCENY:
|
||||
Po PRAWEJ stronie kadru znajduje sie taras z meblami ogrodowymi. Glowny mebel do obserwacji to SOFA OGRODOWA z metalowym/wiklinowym stelazem, ktora ma KOMPLET TEKSTYLIOW: dwa MATERACE SIEDZISKOWE (dolne, plaskie, ciemne) plus trzy PODUSZKI OPARCIOWE (gorne, kwadratowe, ciemne). W tej scenie tekstylia sa CIEMNOSZARE / CZARNE.
|
||||
INSTRUCTIONS = """Analizujesz obraz z kamery zewnetrznej zamontowanej na LEWEJ scianie domu, skierowanej w prawo i delikatnie w dol. W kadrze widac fragment domu, dach garazu, ogrod i taras o kamiennej posadzce. Glowny obszar zainteresowania - taras z meblami - znajduje sie PO PRAWEJ stronie kadru i nieco z gory (perspektywa z boku).
|
||||
|
||||
ZADANIE: Sprawdz czy te tekstylia (materace + poduszki) sa OBECNIE na sofie. Wszystkie sa luzne i moga sie zniszczyc od deszczu wiec trzeba je zabrac.
|
||||
ZADANIE OBIEKTYWNE: Wykryj czy na meblach tarasowych po prawej stronie kadru leza LUZNE TEKSTYLIA (poduszki, materace, koce) ktore moga sie zniszczyc od deszczu.
|
||||
|
||||
CO LICZYC jako tekstylia (rosnij count o 1 za kazdy widoczny element):
|
||||
- Materac siedziskowy luzno polozony na ramie sofy
|
||||
- Poduszka oparciowa lub dekoracyjna na sofie/oparciu
|
||||
- Dodatkowo: luzne koce, narzuty, mniejsze poduszki dorzucone
|
||||
WAZNE: NIE zakladaj z gory ze tekstylia tam sa. Bywaja dni gdy taras ma TYLKO same metalowe/wiklinowe meble bez zadnych tekstyliow - to normalna, czesta sytuacja. W takim wypadku has_loose_cushions=false.
|
||||
|
||||
CZEGO NIE LICZYC (False positives - traktuj jako NIE):
|
||||
- Same metalowe / wiklinowe / drewniane elementy konstrukcji mebli BEZ tekstyliow
|
||||
- Plandeka zakrywajaca mebel (jesli widac plandeke - tekstylia juz zabezpieczone)
|
||||
- Doniczki, donice, kamienie, posadzka, dywany podlogowe
|
||||
- Cienie, plamy swiatla
|
||||
- Krzesla po przeciwnej (lewej) stronie tarasu
|
||||
OBIEKTYWNE KRYTERIA WYKRYCIA TEKSTYLIOW:
|
||||
Tekstylia (poduszka, materac, koc) to MIEKKI, plaski, prostokatny lub kwadratowy element o WYRAZNYM ksztalcie wyrastajacym ponad rame mebla. Powinien byc widoczny jako oddzielna, dorzucona warstwa o miekkich krawedziach.
|
||||
|
||||
ZASADA: Jesli na ramie sofy po prawej WIDAC ciemne/kolorowe miekkie elementy - to sa tekstylia, has_loose_cushions=true. Jesli widac sama goly metalowy/wiklinowy stelaz bez tekstyliow - has_loose_cushions=false.
|
||||
DEFINITYWNIE NIE SA TEKSTYLIAMI (traktuj jako has_loose_cushions=false):
|
||||
- Czarne/ciemne plastikowe lub gumowe siedziska wlasciwe metalowych krzesel ogrodowych (sa CZESCIA konstrukcji, nie luzne)
|
||||
- Czarne tkane oparcia w stylu rattan/wiklina - to konstrukcja krzesla
|
||||
- Same metalowe ramy / siedziska siatkowe / drewniane deski
|
||||
- Ciemne cienie pod meblami
|
||||
- Doniczki, kamienie, posadzka
|
||||
|
||||
UWAGA NA HALUCYNACJE: Jesli obraz pokazuje TYLKO dwa metalowe krzesla z prostym czarnym oparciem i siedzeniem przy stoliku - to NIE SA poduszki, to konstrukcja krzesla. Has_loose_cushions=false.
|
||||
|
||||
ZASADA ROZSTRZYGAJACA: Jesli watpisz czy widzisz luzny tekstylny dodatek czy tylko czesc konstrukcji krzesla - ustaw has_loose_cushions=false. Lepiej raz przegapic alert (mozna zauwazyc samemu przed deszczem) niz codziennie spamowac falszywymi powiadomieniami.
|
||||
|
||||
Odpowiedz w formacie strukturalnym (JSON), pola:
|
||||
- has_loose_cushions (bool): true gdy na sofie po prawej sa widoczne JAKIEKOLWIEK tekstylia (materace, poduszki, koce)
|
||||
- count (int): laczna liczba widocznych tekstyliow (materace + poduszki + dodatkowe). Sofa w komplecie = 5 (2 materace + 3 poduszki)
|
||||
- has_loose_cushions (bool): true TYLKO gdy widzisz wyraznie odrebne, miekkie elementy lezace na ramach mebli (nie sama konstrukcje)
|
||||
- count (int): liczba widocznych LUZNYCH tekstyliow (0 jesli has_loose_cushions=false)
|
||||
- confidence (int 0-100): pewnosc oceny
|
||||
- description (string, po polsku, max 150 znakow): co konkretnie widzisz na sofie po prawej
|
||||
- description (string, po polsku, max 150 znakow): konkretny opis tego co widzisz - mebli, materialow, ich stanu
|
||||
|
||||
PRZYKLAD KOMPLET: has_loose_cushions=true, count=5, confidence=90, description="Sofa po prawej w komplecie - widoczne 2 materace siedziskowe i 3 poduszki oparciowe"
|
||||
PRZYKLAD CZESCIOWY: has_loose_cushions=true, count=2, confidence=85, description="Na sofie po prawej widoczne tylko 2 materace, brak poduszek oparciowych"
|
||||
PRZYKLAD PUSTY: has_loose_cushions=false, count=0, confidence=90, description="Sofa po prawej pusta - widac sam metalowy stelaz, tekstylia zabrane"
|
||||
PRZYKLAD ZASLONIETY: has_loose_cushions=false, count=0, confidence=80, description="Sofa zakryta plandeka - tekstylia juz zabezpieczone"
|
||||
PRZYKLAD PUSTY TARAS (typowy): has_loose_cushions=false, count=0, confidence=90, description="Dwa metalowe krzesla ogrodowe z czarnymi wbudowanymi oparciami i stolik. Brak luznych tekstyliow."
|
||||
PRZYKLAD PUSTA SOFA: has_loose_cushions=false, count=0, confidence=85, description="Stelaz sofy widoczny bez tekstyliow - same metalowe rame i drewniane elementy."
|
||||
PRZYKLAD Z PODUSZKAMI: has_loose_cushions=true, count=3, confidence=85, description="Na sofie trzy luzne kwadratowe poduszki dekoracyjne w jasnym kolorze, wyraznie odstajace od ciemnej ramy."
|
||||
PRZYKLAD KOMPLET: has_loose_cushions=true, count=5, confidence=90, description="Sofa wyposazona - widoczne 2 plaskie materace siedziskowe plus 3 mniejsze poduszki oparciowe."
|
||||
PRZYKLAD ZASLONIETY: has_loose_cushions=false, count=0, confidence=80, description="Sofa zakryta plandeka ochronna - tekstylia juz zabezpieczone."
|
||||
"""
|
||||
|
||||
AI_STRUCTURE = {
|
||||
|
|
@ -132,6 +137,16 @@ def _on_cooldown():
|
|||
return False
|
||||
|
||||
|
||||
def _in_quiet_hours():
|
||||
"""True jesli teraz jest cisza nocna (alert idzie tylko do logu, bez notify/telegram)."""
|
||||
h = datetime.now().hour
|
||||
if QUIET_HOURS_START < QUIET_HOURS_END:
|
||||
# zakres w obrebie tego samego dnia, np. 0-7
|
||||
return QUIET_HOURS_START <= h < QUIET_HOURS_END
|
||||
# zakres przez polnoc, np. 22-7 (typowy nocny)
|
||||
return h >= QUIET_HOURS_START or h < QUIET_HOURS_END
|
||||
|
||||
|
||||
def _rain_now():
|
||||
try:
|
||||
return float(state.get(RAIN_NOW_SENSOR) or 0) >= RAIN_NOW_THRESHOLD_MM
|
||||
|
|
@ -298,7 +313,13 @@ def _run_check(reason):
|
|||
)
|
||||
|
||||
if has_cushions and count > 0 and confidence >= MIN_CONFIDENCE_FOR_ALERT:
|
||||
_notify(count, confidence, desc, reason)
|
||||
if _in_quiet_hours():
|
||||
log.info(
|
||||
f"cushion_check: ALERT POMINIETY (quiet hours {QUIET_HOURS_START}:00-{QUIET_HOURS_END}:00) - "
|
||||
f"count={count} conf={confidence}% desc={desc[:120]}"
|
||||
)
|
||||
else:
|
||||
_notify(count, confidence, desc, reason)
|
||||
else:
|
||||
log.info(
|
||||
f"cushion_check: brak alertu (has_cushions={has_cushions}, "
|
||||
|
|
|
|||
Loading…
Reference in New Issue