{{ currentPageTitle }}
Gestión de Personas
| ID | Identificación | Nombre | 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
| ID | Persona | Roles asignados | Acciones | |
|---|---|---|---|---|
| Sin coincidencias. | ||||
| {{ person.id }} | {{ person.name }} | {{ person.email }} | {{ r }} | |
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. | |||||||
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. | ||||||||
Auditoría de Comandos
| Fecha | Device | Acción | Actor | Estado | Flags | ms | |
|---|---|---|---|---|---|---|---|
| {{ formatDate(entry.created_at) }} |
{{ entry.device_name || '—' }}
{{ entry.device_serial || '#' + entry.device_id }}
|
{{ entry.action_code || '—' }}
{{ entry.action_label }}
|
{{ entry.actor_email || (entry.actor_user_id ? '#' + entry.actor_user_id : '—') }} | {{ entry.status }} | OVR FORCE | {{ entry.duration_ms ?? '—' }} | |
|
mqtt_payload
{{ JSON.stringify(entry.mqtt_payload, null, 2) }}
response
{{ entry.response ? JSON.stringify(entry.response, null, 2) : '(sin respuesta)' }}
reason:
{{ entry.reason }}
id:
{{ entry.id }} · completed_at: {{ formatDate(entry.completed_at) || '—' }}
|
|||||||
| No hay entradas en el log para los filtros aplicados. | |||||||
{{ selectedInstaller.name }}
- Identificación
- {{ selectedInstaller.identify }}
- Nombre completo
- {{ selectedInstaller.name }}
- {{ selectedInstaller.email }}
- Teléfono
- {{ selectedInstaller.tel || '—' }}
- País
- {{ countryName(selectedInstaller.country_id) }}
- Dirección
- {{ selectedInstaller.address || '—' }}
- Creado
- {{ formatDate(selectedInstaller.created_at) }}
| Tipo | Nombre | Fecha | Descripción | Acciones |
|---|---|---|---|---|
| Sin capacitaciones registradas para este instalador. | ||||
| {{ t.type }} | {{ t.name }} | {{ formatDate(t.training_date) }} | {{ t.description || '—' }} | |
| ID | Pago | Vencimiento | Tipo | Acciones |
|---|---|---|---|---|
| Sin membresías registradas para este instalador. | ||||
| {{ m.id }} | {{ formatDate(m.payment_date) }} | {{ formatDate(m.expiration_date) }} | {{ m.type ?? '—' }} | |
| ID | Validado por | Fecha | Notas | Acciones |
|---|---|---|---|---|
| Sin validaciones recibidas. | ||||
| {{ v.id }} | {{ personName(v.validator_person_id) }} | {{ formatDate(v.validation_date) }} | {{ v.notes || '—' }} | |
| ID | Validado | Fecha | Notas | Acciones |
|---|---|---|---|---|
| Sin validaciones realizadas. | ||||
| {{ v.id }} | {{ personName(v.validated_person_id) }} | {{ formatDate(v.validation_date) }} | {{ v.notes || '—' }} | |
| 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 || '—' }} |
| 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
| ID | Identificación | Nombre | País | Estado | Acciones | |
|---|---|---|---|---|---|---|
| {{ installer.id }} | {{ installer.identify }} | {{ installer.name }} | {{ installer.email }} | {{ countryName(installer.country_id) }} | Sin cuenta Activo Inactivo |
{{ selectedClient.name }}
- Identificación
- {{ selectedClient.identify }}
- Nombre completo
- {{ selectedClient.name }}
- {{ selectedClient.email }}
- Teléfono
- {{ selectedClient.tel || '—' }}
- País
- {{ countryName(selectedClient.country_id) }}
- Dirección
- {{ selectedClient.address || '—' }}
| ID | Serial | Nombre | Tipo | Ubicación | Estado |
|---|---|---|---|---|---|
| Este cliente no tiene dispositivos asignados. | |||||
| {{ d.id }} | {{ d.serial_number }} | {{ d.name }} | {{ deviceTypeName(d.device_type) }} | {{ d.location || '—' }} |
{{ d.is_online ? 'Online' : 'Offline' }}
{{ d.is_test_device ? '🧪 TEST' : '⚠️ PROD' }}
|
| 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 || '—' }} |
| 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' }} |
Gestión de Clientes
| ID | Identificación | Nombre | 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
| 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
Spec MQTT (PROTOCOL.md){"AC":"command","value":N}
(N = 0 OPEN, 1 CLOSE, 2 STOP, 3 OCS, 4 PEDESTRIAN, 5 RELE, 6 LOCK,
7 KEEP_OPEN, 8 LAMP). El backend inyecta idInstaller en
runtime. Otros comandos (GE, SE, sesión, etc.)
usan su AC literal. Ver PROTOCOL.md §2–§11.
| Orden | Código | Etiqueta | Payload (firmware) | Rol | Sesión inst. | Estado | Acciones |
|---|---|---|---|---|---|---|---|
| Sin acciones definidas para este motor. | |||||||
| {{ action.sort_order }} | {{ action.code }} spec ✓ ? | {{ action.label }} | {{ JSON.stringify(action.mqtt_payload) }} |
{{ action.role_required }} | {{ action.requires_installer_session ? 'Sí' : 'No' }} | {{ 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) }} |
{{ selectedDeviceForDetail.name }}
- 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) }}
| Fecha | Acción | Actor | Estado | Flags | ms | |
|---|---|---|---|---|---|---|
| {{ formatDate(entry.created_at) }} |
{{ entry.action_code || '—' }}
{{ entry.action_label }}
|
{{ entry.actor_email || (entry.actor_user_id ? '#' + entry.actor_user_id : '—') }} | {{ entry.status }} | OVR FORCE | {{ entry.duration_ms ?? '—' }} | |
|
mqtt_payload
{{ JSON.stringify(entry.mqtt_payload, null, 2) }}
response
{{ entry.response ? JSON.stringify(entry.response, null, 2) : '(sin respuesta)' }}
reason:
{{ entry.reason }}
id:
{{ entry.id }} · completed_at: {{ formatDate(entry.completed_at) || '—' }}
|
||||||
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.
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.
{{ JSON.stringify(deviceDetailData.testResult, null, 2) }}
Gestión de Dispositivos
| ID | Serial | Nombre | Tipo | Ubicación | Estado | Acciones |
|---|---|---|---|---|---|---|
| {{ device.id }} | {{ device.serial_number }} | {{ device.name }} | {{ 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).
Detalle del Dispositivo
Parametros
{{ JSON.stringify(selectedDevice._full.parameters, null, 2) }}