135 lines
4.2 KiB
Python
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()
|