Tu Nombre commited on
Commit
d1dbb0b
·
1 Parent(s): fe91d69

Actualización: Cambio a modelo Llama 3.1 8B

Browse files
Files changed (2) hide show
  1. familiar.html +0 -147
  2. index.html +0 -130
familiar.html DELETED
@@ -1,147 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="es">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Visor Familiar</title>
6
- <script src="https://unpkg.com/peerjs@1.5.2/dist/peerjs.min.js"></script>
7
- <style>
8
- body { background: #000; color: #0ff; font-family: sans-serif; text-align: center; }
9
- #videoRemoto { width: 100%; max-width: 500px; border: 2px solid #0ff; border-radius: 10px; }
10
- #alerta-box { display:none; position:fixed; top:0; left:0; width:100%; padding:20px;
11
- font-size:1.5em; font-weight:bold; z-index:999; animation: parpadeo 0.5s infinite; }
12
- .CRITICO { background: #f00; color: #fff; }
13
- .MODERADO { background: #ff0; color: #000; }
14
- @keyframes parpadeo { 0%,100%{opacity:1} 50%{opacity:0.3} }
15
- #historial { text-align:left; max-width:500px; margin:10px auto;
16
- background:#111; border-radius:8px; padding:10px; max-height:200px; overflow-y:auto; }
17
- #vitales-familiar { display:flex; justify-content:center; gap:20px; margin:10px auto; max-width:500px; }
18
- .vital-f { background:#1a1a1a; border-radius:8px; padding:8px 16px; font-size:0.9em; color:#fff; }
19
- .vital-f span { font-size:1.3em; font-weight:bold; display:block; }
20
- .v-normal { color: #0f0; }
21
- .v-bajo { color: #ff0; }
22
- .v-critico { color: #f00; }
23
- </style>
24
- </head>
25
- <body>
26
- <div id="alerta-box"></div>
27
- <h1>👁️ Visor Familiar</h1>
28
- <input type="text" id="familiarNombre" placeholder="Tu nombre (ej: maria)..." style="padding:10px;width:80%;">
29
- <button onclick="registrar()" style="padding:15px;width:80%;margin-top:10px;">📡 CONECTAR Y VIGILAR</button>
30
- <div id="status">Esperando...</div>
31
- <video id="videoRemoto" autoplay playsinline></video>
32
-
33
- <!-- Vitales en tiempo real -->
34
- <div id="vitales-familiar">
35
- <div class="vital-f">
36
- 💧 Oxígeno
37
- <span id="f-oxigeno" class="v-normal">--</span>
38
- </div>
39
- <div class="vital-f">
40
- ❤️ Corazón
41
- <span id="f-corazon" class="v-normal">--</span>
42
- </div>
43
- </div>
44
-
45
- <div id="historial"><b>📋 Historial Groq:</b><br></div>
46
-
47
- <script>
48
- let peer = null;
49
- let ws = null;
50
- let audioCtx = null;
51
-
52
- function registrar() {
53
- const nombre = document.getElementById('familiarNombre').value.trim().toLowerCase();
54
-
55
- const wsUrl = (location.protocol === 'https:' ? 'wss' : 'ws') + '://' + location.host + '/ws/familiar';
56
- ws = new WebSocket(wsUrl);
57
- ws.onmessage = (e) => {
58
- const data = JSON.parse(e.data);
59
- manejarAlerta(data);
60
- };
61
-
62
- if (peer) peer.destroy();
63
- peer = new Peer("fam-" + nombre, {
64
- host: '0.peerjs.com', port: 443, path: '/', secure: true,
65
- config: { iceServers: [
66
- { urls: 'stun:stun.l.google.com:19302' },
67
- { urls: 'stun:stun1.l.google.com:19302' }
68
- ]}
69
- });
70
- peer.on('open', (id) => {
71
- document.getElementById('status').textContent = "🟡 Registrado: " + id + " — Esperando paciente...";
72
- });
73
- peer.on('call', (call) => {
74
- call.answer();
75
- call.on('stream', (remoteStream) => {
76
- const video = document.getElementById('videoRemoto');
77
- video.srcObject = remoteStream;
78
- video.play().catch(() => video.addEventListener('click', () => video.play(), { once: true }));
79
- document.getElementById('status').textContent = "🟢 VÍDEO EN VIVO + GROQ VIGILANDO";
80
- });
81
- call.on('close', () => {
82
- document.getElementById('status').textContent = "🔴 Paciente desconectado";
83
- document.getElementById('videoRemoto').srcObject = null;
84
- });
85
- });
86
- peer.on('error', (err) => {
87
- document.getElementById('status').textContent = "❌ " + err.message;
88
- });
89
- }
90
-
91
- function manejarAlerta(data) {
92
- const nivel = data.nivel || 'NORMAL';
93
- const mensaje = data.mensaje || '';
94
- const hora = new Date().toLocaleTimeString();
95
- const iconos = { CRITICO: '🔴', MODERADO: '🟡', NORMAL: '🟢' };
96
- const mapClase = { NORMAL: 'v-normal', BAJO: 'v-bajo', ALTERADO: 'v-bajo', CRITICO: 'v-critico' };
97
- const iconO2 = { NORMAL: '🟢', BAJO: '🟡', CRITICO: '🔴' };
98
- const iconFC = { NORMAL: '🟢', ALTERADO: '🟡', CRITICO: '🔴' };
99
-
100
- // Actualizar vitales en familiar
101
- if (data.oxigeno_visual) {
102
- const el = document.getElementById('f-oxigeno');
103
- el.textContent = (iconO2[data.oxigeno_visual] || '⚪') + ' ' + data.oxigeno_visual;
104
- el.className = mapClase[data.oxigeno_visual] || 'v-normal';
105
- }
106
- if (data.corazon_visual) {
107
- const el = document.getElementById('f-corazon');
108
- el.textContent = (iconFC[data.corazon_visual] || '⚪') + ' ' + data.corazon_visual;
109
- el.className = mapClase[data.corazon_visual] || 'v-normal';
110
- }
111
-
112
- // Historial
113
- const historial = document.getElementById('historial');
114
- const entrada = document.createElement('div');
115
- entrada.textContent = hora + ' — ' + (iconos[nivel] || '⚪') + ' ' + mensaje;
116
- entrada.style.color = nivel === 'CRITICO' ? '#f88' : nivel === 'MODERADO' ? '#ff0' : '#0f0';
117
- historial.appendChild(entrada);
118
- historial.scrollTop = historial.scrollHeight;
119
-
120
- // Alerta visual + sonido
121
- const box = document.getElementById('alerta-box');
122
- if (nivel === 'CRITICO' || nivel === 'MODERADO') {
123
- box.textContent = (iconos[nivel]) + ' ' + nivel + ': ' + mensaje;
124
- box.className = 'alerta-box ' + nivel;
125
- box.style.display = 'block';
126
- sonarAlarma(nivel);
127
- setTimeout(() => box.style.display = 'none', 8000);
128
- }
129
- }
130
-
131
- function sonarAlarma(nivel) {
132
- try {
133
- if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
134
- const osc = audioCtx.createOscillator();
135
- const gain = audioCtx.createGain();
136
- osc.connect(gain);
137
- gain.connect(audioCtx.destination);
138
- osc.frequency.value = nivel === 'CRITICO' ? 880 : 440;
139
- osc.type = 'square';
140
- gain.gain.value = 0.3;
141
- osc.start();
142
- osc.stop(audioCtx.currentTime + (nivel === 'CRITICO' ? 2 : 1));
143
- } catch(e) {}
144
- }
145
- </script>
146
- </body>
147
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
index.html DELETED
@@ -1,130 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="es">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Paciente</title>
6
- <script src="https://unpkg.com/peerjs@1.5.2/dist/peerjs.min.js"></script>
7
- <style>
8
- body { background: #000; color: #fff; font-family: sans-serif; text-align: center; }
9
- #video { width: 100%; max-width: 500px; border: 2px solid #0f0; border-radius: 10px; }
10
- #analisis { margin-top: 10px; padding: 10px; border-radius: 8px; background: #111; max-width: 500px; margin: 10px auto; }
11
- .CRITICO { color: #f00; font-weight: bold; font-size: 1.2em; }
12
- .MODERADO { color: #ff0; }
13
- .NORMAL { color: #0f0; }
14
- #vitales { display: flex; justify-content: center; gap: 20px; margin-top: 8px; }
15
- .vital { background: #1a1a1a; border-radius: 8px; padding: 8px 16px; font-size: 0.9em; }
16
- .vital span { font-size: 1.3em; font-weight: bold; display: block; }
17
- .v-normal { color: #0f0; }
18
- .v-bajo { color: #ff0; }
19
- .v-critico { color: #f00; }
20
- </style>
21
- </head>
22
- <body>
23
- <h1>🏥 Monitor Paciente</h1>
24
- <input type="text" id="nombreInput" placeholder="Tu nombre (ej: cristobal)..." style="padding:10px;width:80%;">
25
- <input type="text" id="familiarInput" placeholder="Nombre del familiar (ej: maria)..." style="padding:10px;width:80%;">
26
- <button onclick="iniciar()" style="padding:15px;width:80%;margin-top:10px;">▶ INICIAR MONITORIZACIÓN</button>
27
- <h2 id="status">INACTIVO</h2>
28
- <video id="video" autoplay muted playsinline></video>
29
- <canvas id="canvas" style="display:none;"></canvas>
30
-
31
- <div id="analisis">
32
- <div id="nivelGroq" class="NORMAL">🟢 Sistema listo</div>
33
- <div id="mensajeGroq"></div>
34
- <div id="vitales">
35
- <div class="vital">
36
- 💧 Oxígeno
37
- <span id="oxigeno-val" class="v-normal">--</span>
38
- </div>
39
- <div class="vital">
40
- ❤️ Corazón
41
- <span id="corazon-val" class="v-normal">--</span>
42
- </div>
43
- </div>
44
- </div>
45
-
46
- <script>
47
- let localStream, peer, ws;
48
- let intervaloAnalisis = null;
49
-
50
- async function iniciar() {
51
- const nombre = document.getElementById('nombreInput').value.trim().toLowerCase();
52
- const familiar = document.getElementById('familiarInput').value.trim().toLowerCase();
53
-
54
- try {
55
- localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
56
- document.getElementById('video').srcObject = localStream;
57
- } catch (e) {
58
- document.getElementById('status').textContent = "❌ Cámara: " + e.message;
59
- return;
60
- }
61
-
62
- const wsUrl = (location.protocol === 'https:' ? 'wss' : 'ws') + '://' + location.host + '/ws/paciente';
63
- ws = new WebSocket(wsUrl);
64
- ws.onopen = () => {
65
- document.getElementById('status').textContent = "🔗 Groq conectado — iniciando análisis...";
66
- iniciarAnalisis();
67
- };
68
- ws.onmessage = (e) => {
69
- const data = JSON.parse(e.data);
70
- if (data.analisis) mostrarAnalisis(data.analisis);
71
- };
72
- ws.onerror = () => document.getElementById('status').textContent = "❌ Error WebSocket";
73
-
74
- if (peer) peer.destroy();
75
- peer = new Peer("pac-" + nombre, {
76
- host: '0.peerjs.com', port: 443, path: '/', secure: true,
77
- config: { iceServers: [
78
- { urls: 'stun:stun.l.google.com:19302' },
79
- { urls: 'stun:stun1.l.google.com:19302' }
80
- ]}
81
- });
82
- peer.on('open', () => {
83
- document.getElementById('status').textContent = "📞 Llamando a familiar...";
84
- const call = peer.call("fam-" + familiar, localStream);
85
- call.on('stream', () => document.getElementById('status').textContent = "🟢 FAMILIAR CONECTADO + GROQ ACTIVO");
86
- call.on('error', (err) => document.getElementById('status').textContent = "❌ " + err.message);
87
- });
88
- peer.on('error', (err) => document.getElementById('status').textContent = "❌ PeerJS: " + err.message);
89
- }
90
-
91
- function iniciarAnalisis() {
92
- const video = document.getElementById('video');
93
- const canvas = document.getElementById('canvas');
94
- const ctx = canvas.getContext('2d');
95
- if (intervaloAnalisis) clearInterval(intervaloAnalisis);
96
- intervaloAnalisis = setInterval(() => {
97
- if (video.readyState < 2) return;
98
- canvas.width = 640;
99
- canvas.height = 480;
100
- ctx.drawImage(video, 0, 0, 640, 480);
101
- const frame = canvas.toDataURL('image/jpeg', 0.7).split(',')[1];
102
- if (ws && ws.readyState === WebSocket.OPEN) {
103
- ws.send(JSON.stringify({ frame }));
104
- }
105
- }, 5000);
106
- }
107
-
108
- function mostrarAnalisis(a) {
109
- const iconos = { CRITICO: '🔴', MODERADO: '🟡', NORMAL: '🟢' };
110
- const elNivel = document.getElementById('nivelGroq');
111
- elNivel.className = a.nivel;
112
- elNivel.textContent = (iconos[a.nivel] || '⚪') + ' ' + a.nivel;
113
- document.getElementById('mensajeGroq').textContent = a.mensaje;
114
-
115
- // Vitales visuales
116
- const mapClase = { NORMAL: 'v-normal', BAJO: 'v-bajo', ALTERADO: 'v-bajo', CRITICO: 'v-critico' };
117
- const iconO2 = { NORMAL: '🟢', BAJO: '🟡', CRITICO: '🔴' };
118
- const iconFC = { NORMAL: '🟢', ALTERADO: '🟡', CRITICO: '🔴' };
119
-
120
- const oxEl = document.getElementById('oxigeno-val');
121
- oxEl.textContent = (iconO2[a.oxigeno_visual] || '⚪') + ' ' + (a.oxigeno_visual || '--');
122
- oxEl.className = mapClase[a.oxigeno_visual] || 'v-normal';
123
-
124
- const fcEl = document.getElementById('corazon-val');
125
- fcEl.textContent = (iconFC[a.corazon_visual] || '⚪') + ' ' + (a.corazon_visual || '--');
126
- fcEl.className = mapClase[a.corazon_visual] || 'v-normal';
127
- }
128
- </script>
129
- </body>
130
- </html>