simulacion de estados y flujo de notificacion, modificacion de estilos en todas las vistas
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import os
|
||||
import firebase_admin
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from firebase_admin import credentials, messaging
|
||||
|
||||
_firebase_initialized = False
|
||||
@@ -27,9 +29,13 @@ def send_to_topic(topic: str, payload: dict):
|
||||
"""Envía una notificación push a todos los dispositivos suscritos a un topic (ej. RUTA-01)."""
|
||||
title = payload.get("title", "")
|
||||
body = payload.get("body", "")
|
||||
# `data` viaja como Dict[str, str] en FCM; permite que el cliente
|
||||
# clasifique el evento (event, routeId) en notifications_screen.dart.
|
||||
raw_data = payload.get("data") or {}
|
||||
data: dict[str, str] = {str(k): str(v) for k, v in raw_data.items() if v is not None}
|
||||
|
||||
if not _firebase_initialized:
|
||||
print(f"[MOCK PUSH] -> Topic: {topic} | Título: '{title}' | Mensaje: '{body}'")
|
||||
print(f"[MOCK PUSH] -> Topic: {topic} | Título: '{title}' | Mensaje: '{body}' | Data: {data}")
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -38,9 +44,29 @@ def send_to_topic(topic: str, payload: dict):
|
||||
title=title,
|
||||
body=body,
|
||||
),
|
||||
data=data or None,
|
||||
topic=topic,
|
||||
)
|
||||
response = messaging.send(message)
|
||||
print(f"Push enviado al topic '{topic}' exitosamente. MessageID: {response}")
|
||||
except Exception as e:
|
||||
print(f"Error al enviar push al topic '{topic}': {e}")
|
||||
print(f"Error al enviar push al topic '{topic}': {e}")
|
||||
|
||||
def send_whatsapp_alert(phone: str, message: str):
|
||||
"""
|
||||
Envía un WhatsApp usando la API gratuita de CallMeBot.
|
||||
"""
|
||||
print("\n" + "="*50)
|
||||
print(f"🟢 [WHATSAPP TRIGGER] Preparando mensaje para {phone}")
|
||||
print(f"💬 Mensaje: {message}")
|
||||
print("="*50 + "\n")
|
||||
|
||||
# REEMPLAZA ESTO POR EL CÓDIGO QUE TE DIO EL BOT EN WHATSAPP:
|
||||
apikey = "6756808" # <--- BORRA "TU_API_KEY_AQUI" Y PON TU CÓDIGO REAL AQUÍ
|
||||
safe_msg = urllib.parse.quote(message)
|
||||
url = f"https://api.callmebot.com/whatsapp.php?phone={phone}&text={safe_msg}&apikey={apikey}"
|
||||
|
||||
try:
|
||||
urllib.request.urlopen(url, timeout=5)
|
||||
except Exception as e:
|
||||
print(f"Error enviando WhatsApp real: {e}")
|
||||
@@ -1,5 +1,6 @@
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
from typing import Dict, List, Optional
|
||||
from app.services import notifications
|
||||
|
||||
@@ -58,34 +59,65 @@ def _find_notif(event_name: str) -> Optional[Dict]:
|
||||
|
||||
|
||||
def tick() -> List[Dict]:
|
||||
"""Avanza todas las rutas en memoria (pos 1..8) y devuelve eventos disparados."""
|
||||
global ESTADO, LAST_EVENTS
|
||||
"""Avanza todas las rutas en memoria (pos 1→8) y devuelve eventos disparados.
|
||||
Al llegar a pos 8, reinicia la ruta para que la demo sea un ciclo continuo."""
|
||||
global ESTADO, STATUS, LAST_EVENTS
|
||||
events = []
|
||||
for route_id, pos in list(ESTADO.items()):
|
||||
if pos < 8:
|
||||
antes = pos
|
||||
ahora = pos + 1
|
||||
ESTADO[route_id] = ahora
|
||||
evt = None
|
||||
if antes == 1 and ahora == 2:
|
||||
evt = "ROUTE_START"
|
||||
elif ahora == 4:
|
||||
evt = "TRUCK_PROXIMITY"
|
||||
elif ahora == 8:
|
||||
evt = "ROUTE_COMPLETED"
|
||||
# Ciclo: cuando la ruta completó, reiniciar en el siguiente tick
|
||||
if pos >= 8:
|
||||
ESTADO[route_id] = 1
|
||||
STATUS[route_id] = "PENDIENTE"
|
||||
print(f"[SIM RESET] {route_id} reiniciado para nuevo ciclo.")
|
||||
continue
|
||||
|
||||
if evt:
|
||||
notif = _find_notif(evt)
|
||||
payload = notif.get("pushPayload") if notif else {"title": evt, "body": ""}
|
||||
simulated = {"routeId": route_id, "event": evt, "payload": payload}
|
||||
events.append(simulated)
|
||||
LAST_EVENTS.append(simulated)
|
||||
# Enviar push vía servicio de notificaciones (FCM) o mock
|
||||
topic = f"topic_{route_id}"
|
||||
try:
|
||||
notifications.send_to_topic(topic, payload)
|
||||
except Exception:
|
||||
print(f"[SIM PUSH FAIL] {route_id} -> {evt}: {payload.get('title')} - {payload.get('body')}")
|
||||
antes = pos
|
||||
ahora = pos + 1
|
||||
ESTADO[route_id] = ahora
|
||||
|
||||
# Actualizar STATUS según la nueva posición
|
||||
if ahora == 2:
|
||||
STATUS[route_id] = "en_ruta"
|
||||
elif ahora == 8:
|
||||
STATUS[route_id] = "completada"
|
||||
|
||||
evt = None
|
||||
if antes == 1 and ahora == 2:
|
||||
evt = "ROUTE_START"
|
||||
elif ahora == 4:
|
||||
evt = "TRUCK_PROXIMITY"
|
||||
elif ahora == 8:
|
||||
evt = "ROUTE_COMPLETED"
|
||||
|
||||
if evt:
|
||||
notif = _find_notif(evt)
|
||||
payload = notif.get("pushPayload") if notif else {"title": evt, "body": ""}
|
||||
# Adjuntar event + routeId en `data` para que el cliente Flutter
|
||||
# los clasifique (notifications_screen.dart usa msg.data['event']).
|
||||
payload = {
|
||||
**payload,
|
||||
"data": {
|
||||
**(payload.get("data") or {}),
|
||||
"event": evt,
|
||||
"routeId": route_id,
|
||||
},
|
||||
}
|
||||
simulated = {"routeId": route_id, "event": evt, "payload": payload}
|
||||
events.append(simulated)
|
||||
LAST_EVENTS.append(simulated)
|
||||
topic = f"topic_{route_id}"
|
||||
try:
|
||||
notifications.send_to_topic(topic, payload)
|
||||
|
||||
# ── WHATSAPP: Se dispara cuando el camión está cerca (posición 4) ──
|
||||
if evt == "TRUCK_PROXIMITY":
|
||||
# Para evitar saturar el bot y bloquear el servidor,
|
||||
# enviamos el WhatsApp de demostración solo para la primera ruta.
|
||||
if route_id == "RUTA-01":
|
||||
msg = f"¡Hola! Soy Eco 🍃. El camión recolector de tu ruta ({route_id}) está a menos de 15 minutos. ¡Saca la basura! ♻️"
|
||||
notifications.send_whatsapp_alert("5214131060699", msg)
|
||||
except Exception:
|
||||
print(f"[SIM PUSH FAIL] {route_id} -> {evt}: {payload.get('title')} - {payload.get('body')}")
|
||||
|
||||
return events
|
||||
|
||||
|
||||
Reference in New Issue
Block a user