Files
ha_explore/backend/app/services/entity_actions.py
2026-02-21 16:55:10 +01:00

135 lines
4.2 KiB
Python

import json
from datetime import datetime
from sqlmodel import Session
from app.database import get_engine
from app.ha_client import ha_client
from app.models import EntityCache, EntityFlag, AuditLog
def _get_current_state(session: Session, entity_id: str) -> str | None:
"""Récupère l'état actuel d'une entité depuis le cache."""
entity = session.get(EntityCache, entity_id)
return entity.state if entity else None
def _save_original_state(session: Session, entity_id: str):
"""Sauvegarde l'état original avant désactivation."""
flag = session.get(EntityFlag, entity_id)
if not flag:
flag = EntityFlag(entity_id=entity_id)
# Ne sauvegarder que si pas déjà désactivé (garder le vrai état original)
if not flag.original_state:
flag.original_state = _get_current_state(session, entity_id)
flag.disabled_at = datetime.utcnow()
session.add(flag)
return flag
def _clear_original_state(session: Session, entity_id: str):
"""Efface l'état original lors de la réactivation."""
flag = session.get(EntityFlag, entity_id)
if flag:
flag.original_state = None
flag.disabled_at = None
session.add(flag)
async def disable_entity(entity_id: str) -> dict:
mode = "local_flag"
error = ""
# Sauvegarder l'état original
with Session(get_engine()) as session:
_save_original_state(session, entity_id)
session.commit()
# Tenter désactivation via HA registry
try:
await ha_client.update_entity_registry(entity_id, disabled_by="user")
mode = "ha_registry"
except Exception as e:
error = str(e)
# Fallback : flag local
with Session(get_engine()) as session:
flag = session.get(EntityFlag, entity_id)
if not flag:
flag = EntityFlag(entity_id=entity_id)
flag.ignored_local = True
session.add(flag)
session.commit()
_log_action("disable", [entity_id], mode, error)
return {"entity_id": entity_id, "mode": mode, "error": error}
async def enable_entity(entity_id: str) -> dict:
mode = "local_flag"
error = ""
try:
await ha_client.update_entity_registry(entity_id, disabled_by=None)
mode = "ha_registry"
except Exception as e:
error = str(e)
with Session(get_engine()) as session:
flag = session.get(EntityFlag, entity_id)
if flag:
flag.ignored_local = False
session.add(flag)
session.commit()
# Effacer l'état original
with Session(get_engine()) as session:
_clear_original_state(session, entity_id)
session.commit()
_log_action("enable", [entity_id], mode, error)
return {"entity_id": entity_id, "mode": mode, "error": error}
def set_flag(entity_ids: list[str], action: str) -> list[dict]:
results = []
with Session(get_engine()) as session:
for eid in entity_ids:
flag = session.get(EntityFlag, eid)
if not flag:
flag = EntityFlag(entity_id=eid)
if action == "favorite":
flag.favorite = True
elif action == "unfavorite":
flag.favorite = False
elif action == "ignore":
# Sauvegarder l'état original avant ignore
if not flag.original_state:
flag.original_state = _get_current_state(session, eid)
flag.disabled_at = datetime.utcnow()
flag.ignored_local = True
elif action == "unignore":
flag.ignored_local = False
flag.original_state = None
flag.disabled_at = None
session.add(flag)
results.append({"entity_id": eid, "action": action, "ok": True})
session.commit()
_log_action(action, entity_ids, "ok", "")
return results
def _log_action(action: str, entity_ids: list[str], result: str, error: str):
with Session(get_engine()) as session:
log = AuditLog(
ts=datetime.utcnow(),
action=action,
entity_ids_json=json.dumps(entity_ids),
result=result,
error=error,
)
session.add(log)
session.commit()