lock

BGnius VITA

Panel de Administración

{{ loginError }}

{{ currentPageTitle }}

{{ health.status==='healthy'?'Online':'Degradado' }}
devices
Dispositivos
{{ devices.length }}
group
Clientes
{{ clients.length }}
engineering
Instaladores
{{ installers.length }}
vpn_key
Activaciones
{{ activations.length }}
support_agent {{ openSupportCount }} abiertos
Tickets de soporte
{{ supportRequests.length }}
notifications {{ unreadNotifsCount }} sin leer
Notificaciones
{{ notifications.length }}
fact_check {{ commandsTodayCount }} hoy
Comandos auditados
{{ commandLog.length }}

Gestión de Personas

search {{ filteredPersons.length }} resultado(s)
ID Identificación Nombre Email Tel Roles Acciones
No se encontraron personas
{{ person.id }} {{ person.identify }} {{ person.name }} {{ person.email }} {{ person.tel || 'N/A' }} sin cuenta {{ r }}

Asignación de Roles

Solo aparecen personas con cuenta de usuario asociada. Para crear una cuenta, agregá la persona desde "Personas" o "Instaladores/Clientes" con la opción "create_user".
ID Persona Email Roles asignados Acciones
Sin coincidencias.
{{ person.id }} {{ person.name }} {{ person.email }} {{ r }}

notifications Notificaciones del sistema

ID Fecha Tipo Título Mensaje Usuario Device Leída
{{ n.id }} {{ formatDate(n.created_at) }} {{ n.type }} {{ n.title }} {{ n.body }} {{ n.user_email || ('#' + n.user_id) }} {{ n.device_name || (n.device_id ? '#' + n.device_id : '—') }} leída nueva
No hay notificaciones para los filtros aplicados.

support_agent Tickets de Soporte

ID Fecha Asunto Usuario Device Categoría Prioridad Estado Acciones
{{ req.id }} {{ formatDate(req.created_at) }} {{ req.subject }} {{ req.user_name || req.user_email || ('#' + req.user_id) }} {{ req.device_name || (req.device_id ? '#' + req.device_id : '—') }} {{ req.category }} {{ req.priority }} {{ req.status }}
No hay tickets para los filtros aplicados.

fact_check Auditoría de Comandos

Fecha Device Acción Actor Estado Flags ms
No hay entradas en el log para los filtros aplicados.

gavel Términos y Condiciones

La versión marcada como current se muestra en el modal de Crear Usuario del app cliente VITA. Cuando publicás una nueva versión, queda automáticamente como current y la anterior pasa al historial.

Versión vigente
{{ termsCurrent.version }}
Publicada {{ formatDate(termsCurrent.created_at) }} · por user #{{ termsCurrent.created_by_user_id }}
Ver contenido (markdown)
{{ termsCurrent.body }}
Cargando…
No hay versión vigente. Publicá la primera abajo.

Publicar nueva versión

Usá una versión distinta a las publicadas. El cuerpo es markdown — soporta # encabezados, **negritas**, *itálicas*, listas, links.

Historial de versiones

Sin versiones todavía.
{{ t.version }} VIGENTE
{{ formatDate(t.created_at) }}
Ver contenido
{{ t.body }}

privacy_tip Política de Privacidad

La versión marcada como current se muestra en el modal de Configuración → Política de Privacidad del app cliente VITA. A diferencia de los T&C, la privacy es informativa (no requiere aceptación explícita).

Versión vigente
{{ privacyCurrent.version }}
Publicada {{ formatDate(privacyCurrent.created_at) }} · por user #{{ privacyCurrent.created_by_user_id }}
Ver contenido (markdown)
{{ privacyCurrent.body }}
Cargando…
No hay versión vigente. Publicá la primera abajo.

Publicar nueva versión

Usá una versión distinta a las publicadas. El cuerpo es markdown.

Historial de versiones

Sin versiones todavía.
{{ p.version }} VIGENTE
{{ formatDate(p.created_at) }}
Ver contenido
{{ p.body }}
engineering

{{ selectedInstaller.name }}

{{ selectedInstaller.email }}
ID: {{ selectedInstaller.identify }} · {{ countryName(selectedInstaller.country_id) }} · {{ selectedInstaller.tel }}
Sin cuenta 🟢 Activo Inactivo 🛡️ {{ r }}
Cargando datos del instalador...
Error cargando datos: {{ installerDetailData.error }}
Identificación
{{ selectedInstaller.identify }}
Nombre completo
{{ selectedInstaller.name }}
Email
{{ selectedInstaller.email }}
Teléfono
{{ selectedInstaller.tel || '—' }}
País
{{ countryName(selectedInstaller.country_id) }}
Dirección
{{ selectedInstaller.address || '—' }}
Creado
{{ formatDate(selectedInstaller.created_at) }}
{{ installerTrainings.length }} capacitación(es) registrada(s)
Tipo Nombre Fecha Descripción Acciones
Sin capacitaciones registradas para este instalador.
{{ t.type }} {{ t.name }} {{ formatDate(t.training_date) }} {{ t.description || '—' }}
{{ installerMemberships.length }} membresía(s) registrada(s)
ID Pago Vencimiento Tipo Acciones
Sin membresías registradas para este instalador.
{{ m.id }} {{ formatDate(m.payment_date) }} {{ formatDate(m.expiration_date) }} {{ m.type ?? '—' }}
{{ installerValidationsReceived.length }} validación(es) recibida(s). Otros instaladores que respaldaron a este instalador.
ID Validado por Fecha Notas Acciones
Sin validaciones recibidas.
{{ v.id }} {{ personName(v.validator_person_id) }} {{ formatDate(v.validation_date) }} {{ v.notes || '—' }}
{{ installerValidationsMade.length }} validación(es) realizada(s). Instaladores que este instalador respaldó.
ID Validado Fecha Notas Acciones
Sin validaciones realizadas.
{{ v.id }} {{ personName(v.validated_person_id) }} {{ formatDate(v.validation_date) }} {{ v.notes || '—' }}
{{ installerActivations.length }} instalación(es) realizada(s) por este instalador. Una instalación = motor + dispositivo + cliente final + fecha.
Vita ID Motor Dispositivo Cliente Estado Fecha Notas
Sin activaciones registradas.
{{ a.vita_id }} {{ a.engine_model || '#' + a.engine_id }} {{ a.device_id ? '#' + a.device_id : '—' }} {{ a.client_name || (a.client_person_id ? '#' + a.client_person_id : '—') }} {{ a.status }} {{ formatDate(a.activation_date) }} {{ a.notes || '—' }}
{{ installerInstalledDevices.length }} dispositivo(s) físicamente instalado(s) por este instalador (cross-referenciado desde las activaciones, sin duplicados).
Sin devices instalados todavía. Las activaciones del instalador no apuntan a ningún device físico (device_id null).
ID Serial Nombre Cliente owner Estado activación Online
#{{ d.id }} {{ d.serial_number }} {{ d.name }} {{ d.owner_email || '#' + d.owner_id }} {{ d._activation_status }} {{ d.is_online ? 'Online' : 'Offline' }}

Click en una fila para abrir el detalle del device.

Gestión de Instaladores

search {{ filteredInstallers.length }} resultado(s)
ID Identificación Nombre Email País Estado Acciones
{{ installer.id }} {{ installer.identify }} {{ installer.name }} {{ installer.email }} {{ countryName(installer.country_id) }} Sin cuenta Activo Inactivo
badge

{{ selectedClient.name }}

{{ selectedClient.email }}
ID: {{ selectedClient.identify }} · {{ countryName(selectedClient.country_id) }} · {{ selectedClient.tel }}
Sin cuenta 🟢 Activo Inactivo 🛡️ {{ r }}
Cargando datos del cliente...
Error cargando datos: {{ clientDetailData.error }}
Identificación
{{ selectedClient.identify }}
Nombre completo
{{ selectedClient.name }}
Email
{{ selectedClient.email }}
Teléfono
{{ selectedClient.tel || '—' }}
País
{{ countryName(selectedClient.country_id) }}
Dirección
{{ selectedClient.address || '—' }}
{{ clientDevices.length }} dispositivo(s) propiedad de este cliente. ⚠️ Este cliente no tiene cuenta de usuario, no puede tener devices owned.
ID Serial Nombre Tipo Ubicación Estado
Este cliente no tiene dispositivos asignados.
{{ d.id }} {{ d.serial_number }} {{ d.name }} {{ deviceTypeMatIcon(d.device_type) }} {{ deviceTypeName(d.device_type) }} {{ d.location || '—' }}
{{ d.is_online ? 'Online' : 'Offline' }} {{ d.is_test_device ? '🧪 TEST' : '⚠️ PROD' }}
{{ clientActivationsReceived.length }} activación(es) donde este cliente fue el destinatario final de la instalación. Cada una vincula al instalador que hizo el trabajo.
Vita ID Instalador Motor Dispositivo Estado Fecha Notas
Sin activaciones registradas para este cliente.
{{ a.vita_id }} {{ a.installer_name || '#' + a.installer_person_id }} {{ a.engine_model || '#' + a.engine_id }} {{ a.device_id ? '#' + a.device_id : '—' }} {{ a.status }} {{ formatDate(a.activation_date) }} {{ a.notes || '—' }}
{{ clientSharedDevices.length }} dispositivo(s) compartido(s) con este cliente. Otro cliente lo dueño y le dio acceso con un rol específico (admin, operator, viewer, guest).
Sin devices compartidos. Este cliente solo tiene acceso a sus devices propios.
Device Serial Rol Otorgado Vence
{{ s.device_name || '#' + s.device_id }} {{ s.device_serial || '—' }} {{ s.role }} {{ formatDate(s.created_at) }} {{ s.expires_at ? formatDate(s.expires_at) : 'permanente' }}
{{ clientGroups.length }} grupo(s) creado(s) por este cliente desde su app móvil. Cada grupo agrupa N devices propios para organización ("Casa", "Oficina", etc.).
Sin grupos. El cliente aún no organizó sus devices en categorías.
folder {{ g.name }}
{{ g.description }}
{{ g.device_count != null ? g.device_count : (g.devices ? g.devices.length : 0) }} devices
{{ d.serial_number || ('#' + d.id) }}{{ i < g.devices.length - 1 ? ', ' : '' }}
Creado: {{ formatDate(g.created_at) }}

Gestión de Clientes

search {{ filteredClients.length }} resultado(s)
ID Identificación Nombre Email Teléfono País Estado Acciones
{{ client.id }} {{ client.identify }} {{ client.name }} {{ client.email }} {{ client.tel || '—' }} {{ countryName(client.country_id) }} Sin cuenta Activo Inactivo
No hay clientes registrados todavía. Apretá "Agregar Cliente" para crear uno.

Gestión de Motores

search {{ filteredEngines.length }} resultado(s)
ID Modelo Tipo Marca PCB Acciones
{{ engine.id }} {{ engine.model }} {{ engineTypeName(engine.engine_type_id) }} {{ engine.brand || 'N/A' }} {{ engine.pcb || 'N/A' }}

Tipos de Motor

ID Nombre Creado Acciones
{{ type.id }} {{ type.description }} {{ formatDate(type.created_at) }}

Comandos por modelo de motor

menu_book Spec MQTT (PROTOCOL.md)
Seleccioná un modelo de motor para ver los comandos disponibles.
Orden Código Etiqueta Payload (firmware) Rol Sesión inst. Prim. Tipo UI Estado Acciones
Sin acciones definidas para este motor.
{{ action.sort_order }} {{ action.icon }} {{ action.code }} spec ✓ ? {{ action.label }} {{ JSON.stringify(action.mqtt_payload) }} {{ action.role_required }} {{ action.requires_installer_session ? 'Sí' : 'No' }} {{ action.ui_kind || 'button' }} {{ action.enabled ? 'Activa' : 'Inactiva' }}

Activaciones de Dispositivos

ID Instalador Motor Serial VITA Fecha Acciones
{{ activation.id }} {{ activation.installer_name }} {{ activation.engine_model }} {{ activation.vita_id || 'N/A' }} {{ formatDate(activation.activation_date) }}

Países

ID Nombre Código Regional Acciones
{{ country.id }} {{ country.name }} {{ country.region_code || 'N/A' }}

Membresías

ID Instalador Tipo Pago Vencimiento Acciones
{{ membership.id }} {{ personName(membership.person_id) }} {{ membership.type ?? 'N/A' }} {{ formatDate(membership.payment_date) }} {{ formatDate(membership.expiration_date) }}

Capacitaciones

ID Instalador Tipo Capacitación Fecha Acciones
{{ training.id }} {{ personName(training.person_id) }} {{ training.type || 'N/A' }} {{ training.name || 'N/A' }} {{ formatDate(training.training_date) }}

Validaciones

ID Instalador Validado por Fecha Acciones
{{ validation.id }} {{ personName(validation.validated_person_id) }} {{ personName(validation.validator_person_id) }} {{ formatDate(validation.validation_date) }}
{{ deviceTypeMatIcon(selectedDeviceForDetail.device_type) }}

{{ selectedDeviceForDetail.name }}

{{ selectedDeviceForDetail.serial_number }} · {{ selectedDeviceForDetail.mac_address }}
{{ selectedDeviceForDetail.is_online ? 'Online' : 'Offline' }} {{ selectedDeviceForDetail.is_test_device ? '🧪 TEST' : '⚠️ PROD' }} {{ selectedDeviceForDetail.engine_model || 'sin engine' }}
ID
{{ selectedDeviceForDetail.id }}
Tipo
{{ deviceTypeName(selectedDeviceForDetail.device_type) }}
Serial
{{ selectedDeviceForDetail.serial_number }}
MAC
{{ selectedDeviceForDetail.mac_address }}
Modelo
{{ selectedDeviceForDetail.model || '—' }}
Engine (catálogo)
#{{ selectedDeviceForDetail.engine_id }} {{ selectedDeviceForDetail.engine_model || '' }}
Owner
{{ selectedDeviceForDetail.owner_email || '#' + selectedDeviceForDetail.owner_id }}
Instalador
{{ selectedDeviceForDetail.installer_name || (selectedDeviceForDetail.installer_id ? '#' + selectedDeviceForDetail.installer_id : '—') }}
Ubicación
{{ selectedDeviceForDetail.location || '—' }}
Descripción
{{ selectedDeviceForDetail.description || '—' }}
Última conexión
{{ formatDate(selectedDeviceForDetail.last_seen) }}
Creado
{{ formatDate(selectedDeviceForDetail.created_at) }}
Todos los comandos ejecutados sobre este dispositivo: desde Flutter del cliente, webadmin, o cualquier fuente.
sync Cargando historial...
No hay comandos registrados para este dispositivo.
Fecha Acción Actor Estado Flags ms
Le pregunta al firmware del motor en qué estado está ahora mismo: ciclos, fotoceldas, lámpara, mantenimiento, versión. · Última consulta: {{ formatDate(deviceDetailData.lastStateAt) }}
Error: {{ deviceDetailData.stateError }}
Posibles causas: el motor está apagado o sin internet, el broker MQTT está caído, o el motor no soporta esta consulta.
Tocá "Consultar estado del motor" para ver qué reporta el firmware ahora mismo.
Estado motor
{{ motorStatusLabel(deviceDetailData.lastState.Cur_MotorStatus) }}
Total ciclos
{{ deviceDetailData.lastState.Total_Cycles ?? '—' }}
Lámpara
{{ deviceDetailData.lastState.Lamp_Status === 1 ? 'ON' : 'OFF' }}
Relé
{{ deviceDetailData.lastState.Relay_Status === 1 ? 'ON' : 'OFF' }}
Foto celdas
Apertura
{{ deviceDetailData.lastState.Fc_OpenState === 1 ? '⚠ Interrumpida' : '✓ Sin interrupción' }}
Batería: {{ deviceDetailData.lastState.fc_Open_Battery ?? '—' }}%
Cierre
{{ deviceDetailData.lastState.Fc_CloseState === 1 ? '⚠ Interrumpida' : '✓ Sin interrupción' }}
Batería: {{ deviceDetailData.lastState.fc_Close_Battery ?? '—' }}%
Mantenimiento
Mantenimientos
{{ deviceDetailData.lastState.Maintenance_Count ?? '—' }}
Ciclos desde último
{{ deviceDetailData.lastState.Cycles_SinceMaintenance ?? '—' }}
Límite
{{ deviceDetailData.lastState.Par_MaintenanceLimit ?? '—' }}
Identidad firmware
Version FW
{{ deviceDetailData.lastState.FV || '—' }}
Etiqueta del instalador
{{ deviceDetailData.lastState.labalVIta || '—' }}
SSID actual
{{ deviceDetailData.lastState.ssid || '—' }}
idVita
{{ deviceDetailData.lastState.idVita || '—' }}
Ver respuesta cruda del firmware (debug)
{{ JSON.stringify(deviceDetailData.lastState, null, 2) }}

Esto es lo que devolvió el firmware al comando MQTT GE (Get state). Útil cuando soporte necesita pasarle el detalle al equipo de firmware.

Disparar manualmente cualquier acción del catálogo de este device. Útil para soporte y debugging. Va por el path de override de superadmin (queda en command_log con override=true).
warning
Este device NO está marcado como TEST. El backend va a rechazar comandos a menos que mandes force_production:true + reason (no implementado en este panel). Marcalo como test desde el form de edición si querés probar.

Este engine no tiene acciones definidas en el catálogo.

Resultado: {{ deviceDetailData.testResult.status }} {{ deviceDetailData.testResult._elapsed_ms }}ms
{{ JSON.stringify(deviceDetailData.testResult, null, 2) }}
Error: {{ deviceDetailData.testError }}
🧪 Panel de pruebas del simulador. Estos toggles publican al topic bgnius/vita/<MAC>/sim-control, que solo el fake_vita_device.py escucha. El VITA real ignora este topic, así que no pasa nada si se clickea por error. Sirve para validar los rechazos (fotocelda obstruida, instalador activo, etc.) desde la app cliente.

Fotocelda de apertura

Al encender, un intento de OPEN desde app cliente → `type_Error: "fc_open"`.

Fotocelda de cierre

Al encender, un CLOSE desde app cliente → `type_Error: "fc_close"`.

Sesión de instalador

Simula que el instalador mandó AC:"IS" por BLE. El próximo HB reporta installer:true, la app cliente muestra banner "Instalador trabajando" y cualquier comando devuelve type_Error:"installer".
Error: {{ simDebugState.lastError }}
✓ {{ simDebugState.lastResult.message }}

Gestión de Dispositivos

ID Serial Nombre Tipo Ubicación Estado Acciones
{{ device.id }} {{ device.serial_number }} {{ device.name }} {{ deviceTypeMatIcon(device.device_type) }} {{ deviceTypeName(device.device_type) }} {{ device.location || 'N/A' }}
{{ device.is_online ? 'Online' : 'Offline' }} {{ device.is_test_device ? '🧪 TEST' : '⚠️ PROD' }}
No se encontraron dispositivos

Click en una fila para ver el detalle completo (datos, estado en vivo, probar comandos).

{{ toast.type==='error' ? 'error' : 'check_circle' }} {{ toast.msg }}
warning

Confirmar eliminación

¿Eliminar {{ deleteConfirm.name }}?

vpn_key

Clave temporal

Para {{ tempPasswordModal.name }} ({{ tempPasswordModal.email }})

Pasásela al instalador. Va a tener que cambiarla en el primer login. El email automático todavía no está wireado, así que esta es la única vez que vas a ver esta clave.

{{ tempPasswordModal.password }}