diff --git a/CLAUDE.md b/CLAUDE.md index ed22ec5..21c2adb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -28,6 +28,7 @@ Adriana, Michelle, Jesús and the field technicians work from it; Claude closes | **Juntas** (standup + quick wins, 22-oct) | `docs/tableros/juntas.md` (process, agenda, cadence, register) | Claude or Leo | Leo records with Gemini → Claude turns the transcript into a lote → Leo applies; add a row to «Registro» each time; tags `crisis`, `quick-win`; track `gestion` | | **Enfoque de la semana** (home) | server `/api/hoy` (`enfoque.json`) | Leo and Adriana only | Claude proposes the text in the hand-off; `enfoque_inicial` in `proyecto.json` shows only while nobody has written one | | **Ruta a producción**, version cards, fase, pedido, próximas fechas, map pins | `docs/datos/proyecto.json` | Claude or Leo | edit by hand (keep the one-array-per-line format); step states `hecho · ahora · bloqueado · falta`, card tone `hecho · ahora · aviso · bloqueado`; bump `actualizado` | +| **Instalaciones** (per-site installation board, 22-oct) | `docs/tableros/instalaciones.md` + `.js`/`.css`; data: field actas via `GET /api/instalaciones` (`backend/instalaciones.py`, hooked at the end of `app.py`) | automatic | stages envío → recepción → instalación → **prueba en sitio** (acta `prueba-sitio`; only a passed test counts for the 1–2 per-site goal) → en operación (7 days after the test, no failure) + «con falla»; colour, nota and meta per site from `proyecto.json`; forms accept `?serie=&sitio=&=` prefill (`acta.js`) | | **Últimas decisiones** (Ingeniería) | `docs/tableros/ingenieria.md` | Claude or Leo | new `
  • DD-mmm (hora) — …
  • ` at the top, with the decision number (D-xx-n) and links | | **Bitácora → Documentos por fecha** | `docs/bitacora.md` | Claude or Leo | newest first under the month: `**DD oct**` + `: [Title](path.md#anchor): what it decides or changes` | | **Documentos recientes** (home) | automatic from `date:` front matter (`hooks/documentos.py`) | — | give every new page a `date:`; pages under «Historia» are left out | diff --git a/DESPLIEGUE.md b/DESPLIEGUE.md index 8e64e08..53b546d 100644 --- a/DESPLIEGUE.md +++ b/DESPLIEGUE.md @@ -353,6 +353,36 @@ curl -s -u leo:PASS 'https://drogheda.helgen.online/api/tareas?sitio=eit' | head | `Sitio inválido: …` al guardar | sitio que no existe | icave, timsa, eit, lzc o qro (también acepta Veracruz, Manzanillo, Ensenada, LCT, Querétaro) | | `revisar` dice «el backend todavía no conoce «sitios»» | no se reinició el servicio | el `restart` de arriba | +## A7 · 22-oct: tablero de Instalaciones por sitio y prueba en sitio + +Qué cambia: página nueva **Instalaciones** (`/tableros/instalaciones/`, pestañas ICAVE · TIMSA · EIT · LCT): una tarjeta por +unidad con su vehículo, sus actas y su etapa (enviada → recibida → instalada → probada en sitio → en operación, más «con +falla») contra la meta de cada sitio. Acta nueva **Prueba en sitio** (`formularios/prueba-sitio.html`, tipo `prueba-sitio`). +El acta de instalación pide además 12/24 V, los tipos Reach Stacker y Empty Handler y el nombre en el monitor (H00xx). Los +formularios aceptan `?serie=…&sitio=…` para abrir la siguiente acta ya llena (`acta.js`). + +Backend: `backend/instalaciones.py` (nuevo; lo engancha el final de `app.py`) da `GET /api/instalaciones[?sitio=eit]` y vuelve +repetible `prueba-sitio` **sin tocar** `ACTAS_REPETIBLES` del servicio. `deploy.sh` ya copia el archivo nuevo. + +**Cambió `backend/app.py`: reinicia el servicio.** Sin reiniciar, la página dice «falta reiniciar el servicio actas-hbox» y +la segunda prueba en sitio de una misma unidad daría «Ya existe un acta». + +```bash +cd ~/Documents/Claude/Projects/Drogheda/hbox-docs +mkdocs build --strict +git add -A && git commit -m "Tablero de Instalaciones por sitio y acta de prueba en sitio" && git push +cd .. && git add hbox-docs && git commit -m "hbox-docs: tablero de Instalaciones" && git push && cd hbox-docs # sube el submódulo +./scripts/deploy.sh # sitio + backend (rsync, ya con instalaciones.py) +ssh leo@git.helgen.online 'sudo systemctl restart actas-hbox' +curl -s -u leo:PASS 'https://drogheda.helgen.online/api/instalaciones?sitio=icave' | head -c 300 # «"ok": true» +``` + +| Síntoma | Causa | Arreglo | +|---|---|---| +| «No se pudo leer el tablero de instalaciones (HTTP 404)» | servicio sin reiniciar, o falta `backend/instalaciones.py` en el servidor | `deploy.sh` y el `restart`; si falta el archivo, `journalctl -u actas-hbox` dice «instalaciones.py no se cargó» | +| Una unidad instalada no aparece | no tiene acta, o su acta no trae el sitio ni el nombre del puerto | llenar el acta de instalación con el sitio y la **fecha real** | +| La unidad sale en otro sitio | cuenta en el sitio de su acta más reciente | revisar el sitio de esa acta en el expediente | + --- ## B · Verificación después de desplegar diff --git a/backend/app.py b/backend/app.py index fa996e0..de9f774 100644 --- a/backend/app.py +++ b/backend/app.py @@ -2086,5 +2086,17 @@ def actividad(): return jsonify(ok=True, desde=desde, total=len(eventos), eventos=eventos[:limite], equipo=equipo) +# ------------------------------------------------------------------ tablero de Instalaciones (22-oct) +# backend/instalaciones.py: GET /api/instalaciones y el acta repetible «prueba-sitio». Si el archivo +# falta o falla, el resto del servicio arranca igual (el tablero avisa que no hay datos). +try: + import importlib.util as _ilu + _spec = _ilu.spec_from_file_location("instalaciones", os.path.join(os.path.dirname(os.path.abspath(__file__)), "instalaciones.py")) + _inst = _ilu.module_from_spec(_spec) + _spec.loader.exec_module(_inst) + _inst.registrar(app, globals()) +except Exception as _e: # noqa: BLE001 + app.logger.error("instalaciones.py no se cargó: %s", _e) + if __name__ == "__main__": app.run(host="127.0.0.1", port=int(os.environ.get("PORT", "8081"))) diff --git a/backend/instalaciones.py b/backend/instalaciones.py new file mode 100644 index 0000000..55eaee9 --- /dev/null +++ b/backend/instalaciones.py @@ -0,0 +1,263 @@ +"""Tablero de Instalaciones por sitio (22-oct-2026). + +Lo engancha app.py al final con registrar(app, globals()); vive aparte para no crecer app.py. + + GET /api/instalaciones[?sitio=eit] (solo lee) + Una ficha por unidad en cada sitio, armada con las actas de campo: envío → recepción → + instalación → prueba en sitio → en operación, más «con falla». Trae el vehículo (tipo, + número económico, voltaje), el nombre en el monitor (H00xx), fechas, técnico y sus actas. + Las series PRUEBA no cuentan. ?sitio= acepta el id (icave, timsa, eit, lzc) o un alias (lct). + + Acta nueva «prueba-sitio» (formularios/prueba-sitio.html): la prueba después de instalar. + registrar() la vuelve repetible (como las demás de campo) y la suma a los tipos que lista + la página de cada sitio, sin tocar ACTAS_REPETIBLES en actas-hbox.service. + +Reglas de las etapas (la última acta manda; se ordenan por la fecha que anotó el técnico): + - Enviada: acta de envío «Enviada» a ese sitio. Un envío nuevo empieza otro ciclo. + - Recibida en sitio: recepción «Lista para entrar» o «Entra con observaciones». + - Instalada: acta de instalación que no dice «No se pudo instalar». Una instalación nueva pide + otra prueba. + - Probada en sitio: SOLO con el acta «Prueba en sitio» aprobada (resultado OK). + - En operación: probada hace DIAS_OPERACION días o más, sin falla registrada después. + - Con falla (aparte de la columna): instalación sin reportar o FALLA, prueba no aprobada, + diagnóstico con falla, unidad desmontada o reemplazada, recepción rechazada, o marca de daño. + Cada serie se cuenta en un solo sitio: el de su acta más reciente. +""" +import datetime +import os + +from flask import jsonify, request + +TIPO_PRUEBA = "prueba-sitio" +TIPOS = ("envio", "recepcion", "instalacion-campo", TIPO_PRUEBA, "diagnostico-campo", "dano") +DIAS_OPERACION = 7 +ORDEN = ("icave", "timsa", "eit", "lzc") # el orden de las pestañas (lo pidió Leo) +ETAPAS = ("enviada", "recibida", "instalada", "probada", "operacion") + + +def _resp(d, clave): + """Respuesta de un campo del acta (d['respuestas'][clave]['val']) como texto.""" + r = d.get("respuestas") + v = r.get(clave) if isinstance(r, dict) else None + v = v.get("val") if isinstance(v, dict) else None + return str(v).strip() if isinstance(v, str) else "" + + +def _dia(d): + f = str(d.get("fecha") or "") + if len(f) == 10 and f[4] == "-" and f[7] == "-": + return f + return str(d.get("_recibido") or "")[:10] + + +def _evento(tipo, fn, d, sitio, modo): + ev = {"tipo": tipo, "archivo": fn, "serie": d.get("serie"), "sitio": sitio, "coincidencia": modo, + "fecha": _dia(d), "recibido": str(d.get("_recibido") or ""), "tecnico": str(d.get("tecnico") or "")[:80], + "resultado": str(d.get("resultado") or ""), "accion": str(d.get("accion") or "")[:160], + "motivo": str(d.get("motivo") or "")[:160], "clasificacion": str(d.get("clasificacion") or "")[:120], + "maquina": str(d.get("maquina_id") or d.get("maquina") or "").strip()[:60], + "id_monitor": str(d.get("id_monitor") or _resp(d, "id_monitor")).strip().upper()[:20], + "fotos": len(d.get("fotos") or [])} + if tipo in ("instalacion-campo", TIPO_PRUEBA): + ev["tipo_vehiculo"] = (str(d.get("clasificacion") or "") or _resp(d, "tipo_vehiculo"))[:60] + ev["voltaje"] = (str(d.get("sistema_v") or "") or _resp(d, "sistema_v"))[:20] + ev["placas"] = _resp(d, "placas")[:40] + if tipo == "diagnostico-campo": + ev["repuesto"] = _resp(d, "unidad_repuesto")[:40] + if tipo == TIPO_PRUEBA: + ev["gga"] = _resp(d, "gga")[:40] + return ev + + +def _falla(ev, motivo): + return {"motivo": motivo, "tipo": ev["tipo"], "fecha": ev["fecha"], "archivo": ev["archivo"]} + + +def _ficha(serie, eventos, marca, hoy): + """Estado de una serie en su sitio a partir de sus actas ahí (viejas → nuevas).""" + etapa, falla, instalada, retirada, sin_inst = None, None, False, False, False + fechas = {} + prueba = None + destino = "" + inicio = 0 # un envío nuevo empieza otro ciclo + for i, ev in enumerate(eventos): + t, acc, res = ev["tipo"], ev["accion"], ev["resultado"] + if t == "envio": + if acc.startswith("Lista pero detenida"): + continue + etapa, falla, instalada, retirada, sin_inst, prueba = "enviada", None, False, False, False, None + fechas, inicio = {"enviada": ev["fecha"]}, i + destino = ev["maquina"] + elif t == "recepcion": + destino = ev["maquina"] or destino + mala = acc.startswith(("No entra", "Rechazada")) or res == "FALLA" + if etapa in (None, "enviada", "recibida"): + etapa = "recibida" + fechas["recibida"] = ev["fecha"] + falla = _falla(ev, acc or "La recepción no pasó la inspección") if mala else None + elif mala: # ya estaba instalada: una recepción mala solo marca la falla + falla = _falla(ev, acc or "La recepción no pasó la inspección") + elif t == "instalacion-campo": + if acc.startswith("No se pudo instalar"): + falla = _falla(ev, "No se pudo instalar") + continue + etapa, instalada, retirada, sin_inst, prueba = "instalada", True, False, False, None + fechas["instalada"] = ev["fecha"] + fechas.pop("probada", None) + if acc.startswith("Instalada, sin reportar"): + falla = _falla(ev, "Instalada, sin reportar todavía") + elif res == "FALLA": + falla = _falla(ev, "Instalación con falla") + else: + falla = None + elif t == TIPO_PRUEBA: + if etapa not in ("instalada", "probada"): + sin_inst, instalada, retirada = True, True, False + fechas.setdefault("instalada", "") + if res == "OK" and not acc.startswith("No aprobada"): + etapa, falla, prueba = "probada", None, ev + fechas["probada"] = ev["fecha"] + else: + etapa = etapa if etapa == "probada" else "instalada" + falla = _falla(ev, "Prueba en sitio no aprobada") + elif t == "diagnostico-campo": + if acc.startswith("Desmontada"): + falla, instalada, retirada = _falla(ev, acc), False, True + elif acc.startswith("Reemplazada"): + falla = _falla(ev, "Reemplazada por otra unidad" + (f" ({ev.get('repuesto')})" if ev.get("repuesto") else "")) + instalada, retirada = False, True + elif res == "FALLA" or acc.startswith("Instalada, pero sin resolver"): + falla = _falla(ev, ev["motivo"] or acc or "Diagnóstico con falla") + if etapa is None: + etapa, instalada, sin_inst = "instalada", True, True + elif res == "OK": + falla = None + if etapa is None: + etapa, instalada, sin_inst = "instalada", True, True + fechas.setdefault("instalada", "") + if marca and marca.get("marca"): + a = marca.get("acta") or {} + m = "Dada de baja" if marca["marca"] == "BAJA" else "Marcada como dañada" + if a.get("clasificacion"): + m += ": " + str(a["clasificacion"])[:80] + falla = {"motivo": m, "tipo": "dano", "fecha": a.get("fecha") or "", "archivo": a.get("archivo") or ""} + if etapa is None and not falla: + return None + operacion_desde = None + if prueba and prueba.get("fecha"): + try: + operacion_desde = (datetime.date.fromisoformat(prueba["fecha"]) + + datetime.timedelta(days=DIAS_OPERACION)).isoformat() + except ValueError: + operacion_desde = None + if etapa == "probada" and not falla and operacion_desde and operacion_desde <= hoy: + etapa = "operacion" + # vehículo: el último que anotó una instalación, una prueba o un diagnóstico (de este ciclo) + veh = {"numero": "", "tipo": "", "voltaje": "", "placas": "", "acta": ""} + monitor = "" + for ev in eventos[inicio:]: + if ev["id_monitor"]: + monitor = ev["id_monitor"] + if ev["tipo"] in ("instalacion-campo", TIPO_PRUEBA, "diagnostico-campo") and ev["maquina"]: + veh["numero"], veh["acta"] = ev["maquina"], ev["tipo"] + for k in ("tipo_vehiculo", "voltaje", "placas"): + if ev.get(k): + veh["tipo" if k == "tipo_vehiculo" else k] = ev[k] + ultima = eventos[-1] if eventos else None + return { + "serie": serie, + "etapa": etapa, + "columna": "falla" if falla else etapa, + "falla": falla, + "instalada": bool(instalada and not retirada), + "retirada": retirada, + "sin_acta_instalacion": sin_inst, + "probada": etapa in ("probada", "operacion") and not falla, + "vehiculo": veh if (veh["numero"] or veh["tipo"]) else None, + "vehiculo_destino": destino or None, + "id_monitor": monitor or None, + "fechas": fechas, + "operacion_desde": operacion_desde, + "marca": (marca or {}).get("marca"), + "tecnico": ultima["tecnico"] if ultima else "", + "ultima": {k: ultima[k] for k in ("tipo", "fecha", "accion", "resultado")} if ultima else None, + "actas": [{k: ev[k] for k in ("tipo", "archivo", "fecha", "tecnico", "resultado", "accion")} + for ev in reversed(eventos)], + } + + +def registrar(app, g): + """g = globals() de app.py: se usan sus funciones (lectura de actas y sitios) sin copiarlas.""" + g["TIPOS_REPETIBLES"].add(TIPO_PRUEBA) + if TIPO_PRUEBA not in g["TIPOS_SITIO"]: + g["TIPOS_SITIO"] = tuple(g["TIPOS_SITIO"]) + (TIPO_PRUEBA,) + + def _orden(s): + sid = s.get("id", "") + return (ORDEN.index(sid) if sid in ORDEN else len(ORDEN), s.get("orden", 50), s.get("nombre", "")) + + @app.get("/api/instalaciones") + def instalaciones(): + slug, leer = g["slug"], g["_leer_json"] + sitios = [s for s in g["_listar_json"](g["SITIOS_DIR"]) if s.get("activo", True) and s.get("id")] + sitios.sort(key=_orden) + ids = [s["id"] for s in sitios] + pedido = slug(request.args.get("sitio"), 30).lower() + pedido = g.get("ALIAS_SITIO", {}).get(pedido, pedido) + if pedido and pedido not in ids: + return jsonify(ok=False, error=f"No existe el sitio {pedido}."), 404 + + en_sitio = g["_acta_en_sitio"] + por_serie = {} + for tipo in TIPOS: + carpeta = os.path.join(g["BASE"], tipo) + if not os.path.isdir(carpeta): + continue + for fn in sorted(os.listdir(carpeta)): + if not fn.endswith(".json"): + continue + d = leer(os.path.join(carpeta, fn)) + if not isinstance(d, dict) or d.get("_prueba"): + continue + serie = str(d.get("serie") or "") + if not serie or "PRUEBA" in serie.upper(): + continue + donde, modo = None, None + for s in sitios: # primero el sitio elegido en el acta; luego por nombre + m = en_sitio(d, s) + if m == "sitio": + donde, modo = s["id"], m + break + if m and not donde: + donde, modo = s["id"], m + if donde: + por_serie.setdefault(serie, []).append(_evento(tipo, fn, d, donde, modo)) + + hoy = datetime.date.today().isoformat() + unidades = [] + for serie, evs in por_serie.items(): + evs.sort(key=lambda e: (e["fecha"], e["recibido"], e["archivo"])) # el archivo lleva microsegundos + sitio = evs[-1]["sitio"] # cuenta en el sitio de su acta más reciente + u = _ficha(serie, [e for e in evs if e["sitio"] == sitio], g["estado_serie"](serie), hoy) + if u: + u["sitio"] = sitio + u["coincidencia"] = "sitio" if any(e["coincidencia"] == "sitio" for e in evs if e["sitio"] == sitio) else "texto" + unidades.append(u) + + resumen = {} + for sid in ids: + us = [u for u in unidades if u["sitio"] == sid] + r = {c: sum(1 for u in us if u["columna"] == c) for c in ETAPAS + ("falla",)} + r.update(unidades=len(us), instaladas=sum(1 for u in us if u["instalada"]), + probadas=sum(1 for u in us if u["probada"]), + sin_vehiculo=sum(1 for u in us if u["instalada"] and not (u["vehiculo"] or {}).get("numero")), + sin_prueba=sum(1 for u in us if u["instalada"] and u["etapa"] == "instalada" and not u["falla"])) + resumen[sid] = r + + orden_col = {c: i for i, c in enumerate(("falla",) + ETAPAS)} + unidades.sort(key=lambda u: (ids.index(u["sitio"]), orden_col.get(u["columna"], 9), u["id_monitor"] or u["serie"])) + if pedido: + unidades = [u for u in unidades if u["sitio"] == pedido] + return jsonify(ok=True, generado=g["ahora"](), hoy=hoy, sitio=pedido or None, dias_operacion=DIAS_OPERACION, + sitios=[{k: s.get(k) for k in ("id", "nombre", "cliente", "ubicacion", "alias")} for s in sitios], + resumen=resumen, unidades=unidades, total=len(unidades)) diff --git a/backend/lotes/2026-10-22_instalaciones.json b/backend/lotes/2026-10-22_instalaciones.json new file mode 100644 index 0000000..70dc999 --- /dev/null +++ b/backend/lotes/2026-10-22_instalaciones.json @@ -0,0 +1,83 @@ +{ + "lote": "2026-10-22_instalaciones", + "autor": "claude", + "fecha": "2026-10-22", + "motivo": "Tablero de Instalaciones por sitio y acta «Prueba en sitio» (22-oct): cada unidad con su vehículo, su estado y su prueba; para la meta de 1–2 unidades por sitio solo cuentan las probadas", + "fuente": "/tableros/instalaciones/", + "cambios": [ + { + "id": "t-prueba-en-sitio", + "poner": { + "descripcion": "22-oct: había metas de instalación pero no había prueba. Cada unidad instalada pasa la prueba en sitio y se registra con el acta «Prueba en sitio»: unidad y vehículo, fix RTK visto en el monitor, reporte en el monitor y en Wialon, posición coherente en el mapa, respaldo en batería si aplica, y fotos. Solo una prueba aprobada cuenta para la meta de 1–2 unidades por sitio; si pasan 7 días sin fallas, la unidad queda «En operación». Todo se ve en el tablero de Instalaciones.", + "enlaces": [ + { "titulo": "Acta de prueba en sitio", "url": "/formularios/prueba-sitio.html" }, + { "titulo": "Instalaciones por sitio", "url": "/tableros/instalaciones/" } + ] + }, + "nota": "Ya está el acta «Prueba en sitio» (Formularios → Campo): se llena en la máquina con alguien viendo el monitor. El tablero de Instalaciones la cuenta para la meta del sitio." + }, + { + "id": "t-timsa-instalar", + "poner": { + "titulo": "TIMSA (Manzanillo): instalar y probar 1–2 unidades", + "descripcion": "Meta inmediata: 1 o 2 unidades instaladas y probadas por sitio. Bloqueado por el trámite del vehículo. Al instalar: checklist de puesta en marcha, acta de instalación con el vehículo y acta de prueba en sitio (t-prueba-en-sitio); sin la prueba aprobada no cuenta para la meta. Responsable de campo: t-asignar-campo.", + "enlaces": [ + { "titulo": "Checklist de puesta en marcha", "url": "/procedimientos/v5-checklist-puesta-en-marcha/" }, + { "titulo": "Acta de instalación", "url": "/formularios/instalacion.html?sitio=timsa" }, + { "titulo": "Acta de prueba en sitio", "url": "/formularios/prueba-sitio.html?sitio=timsa" }, + { "titulo": "Instalaciones de TIMSA", "url": "/tableros/instalaciones/?sitio=timsa" } + ] + }, + "nota": "La meta es instalada y probada. Ligas a las dos actas, ya con TIMSA elegido, y a las instalaciones del sitio." + }, + { + "id": "t-eit-instalar", + "poner": { + "titulo": "EIT (Ensenada): instalar y probar 1–2 unidades", + "descripcion": "Meta inmediata: 1 o 2 unidades instaladas y probadas por sitio. Espera el material que viene de Manzanillo. Al instalar: checklist de puesta en marcha, acta de instalación con el vehículo y acta de prueba en sitio (t-prueba-en-sitio); sin la prueba aprobada no cuenta para la meta. Responsable de campo: t-asignar-campo.", + "enlaces": [ + { "titulo": "Checklist de puesta en marcha", "url": "/procedimientos/v5-checklist-puesta-en-marcha/" }, + { "titulo": "Acta de instalación", "url": "/formularios/instalacion.html?sitio=eit" }, + { "titulo": "Acta de prueba en sitio", "url": "/formularios/prueba-sitio.html?sitio=eit" }, + { "titulo": "Instalaciones de EIT", "url": "/tableros/instalaciones/?sitio=eit" } + ] + }, + "nota": "La meta es instalada y probada. Ligas a las dos actas, ya con EIT elegido, y a las instalaciones del sitio." + }, + { + "id": "t-icave-unidades", + "poner": { + "titulo": "ICAVE (Veracruz): confirmar 1–2 unidades instaladas y probadas", + "descripcion": "Meta inmediata: 1 o 2 unidades instaladas y probadas por sitio. En ICAVE ya hay unidades: registrar el acta de instalación de cada una con su vehículo (t-registrar-instaladas) y hacerles la prueba en sitio; las que no reporten bien en el monitor o en Wialon van a la lista de t-icave-campo.", + "enlaces": [ + { "titulo": "Acta de instalación", "url": "/formularios/instalacion.html?sitio=icave" }, + { "titulo": "Acta de prueba en sitio", "url": "/formularios/prueba-sitio.html?sitio=icave" }, + { "titulo": "Instalaciones de ICAVE", "url": "/tableros/instalaciones/?sitio=icave" } + ] + }, + "nota": "«Reportando bien» ahora se demuestra con la prueba en sitio. Ligas a las dos actas, ya con ICAVE elegido, y a las instalaciones del sitio." + }, + { + "id": "t-lct-instalar", + "poner": { + "titulo": "LCT (Lázaro Cárdenas): instalar y probar 1–2 unidades — estado por confirmar en la junta", + "descripcion": "Meta inmediata: 1 o 2 unidades instaladas y probadas por sitio. El estado de LCT no se revisó el 22-oct: confirmar en la junta qué hay en sitio y qué falta. Cada unidad lleva su acta de instalación con el vehículo y su acta de prueba en sitio (t-prueba-en-sitio).", + "enlaces": [ + { "titulo": "Checklist de puesta en marcha", "url": "/procedimientos/v5-checklist-puesta-en-marcha/" }, + { "titulo": "Acta de instalación", "url": "/formularios/instalacion.html?sitio=lzc" }, + { "titulo": "Acta de prueba en sitio", "url": "/formularios/prueba-sitio.html?sitio=lzc" }, + { "titulo": "Instalaciones de LCT", "url": "/tableros/instalaciones/?sitio=lzc" } + ] + }, + "nota": "La meta es instalada y probada. Ligas a las dos actas, ya con LCT elegido, y a las instalaciones del sitio." + }, + { + "id": "t-acta-instalacion", + "nota": "22-oct: el acta ya pide el número económico, el tipo de vehículo (con Reach Stacker y Empty Handler), si es de 12 o 24 V y el nombre en el monitor, y lleva a la prueba en sitio. Falta probarla en una instalación real." + }, + { + "id": "t-registrar-instaladas", + "nota": "Las que ya estaban instaladas se registran con la fecha real de instalación; después, cada una lleva su prueba en sitio. En el tablero de Instalaciones salen como «sin vehículo» o «sin prueba» mientras falte algo." + } + ] +} diff --git a/backend/lotes/2026-10-22_t40-v6.json b/backend/lotes/2026-10-22_t40-v6.json new file mode 100644 index 0000000..e4f6546 --- /dev/null +++ b/backend/lotes/2026-10-22_t40-v6.json @@ -0,0 +1,80 @@ +{ + "lote": "2026-10-22_t40-v6", + "autor": "claude", + "motivo": "T40 aplicado en la v6: MH4 libre (D23/D24 fuera del barreno, /SIM_CLK por In1, /SIM_RST arriba de D25, /NTC alrededor del barreno, vías de GND de las TVS y de U19.92/94) y D-22-4 para Leo", + "fuente": "/hardware/v6-estado-21oct/#7-t40-22-oct-tarde-mh4-libre", + "cambios": [ + { + "id": "t-v6-barrenos", + "poner": { + "estado": "hecho", + "titulo": "v6: liberar MH4 (MH6 con T38, MH8 con T39 y MH4 con T40)" + }, + "nota": "22-oct, tarde: T40 (Claude) liberó MH4. D23 bajo U19.31, D24 junto a R129/R133, /SIM_CLK por In1, /SIM_RST arriba de D25 y /NTC a 0.95 mm de la orilla. DRC: 11 errores (los de margen), 0 sin conectar. Las TVS junto a J14 pasan a D-22-4." + }, + { + "id": "t-v6-t39-push", + "poner": { + "estado": "hecho" + }, + "nota": "Leo hizo el commit de T39 (d5f5002) y el push el 22-oct. T40 tiene su propio pendiente de push (t-v6-t40-push)." + }, + { + "id": "t-v6-cierre-pedido", + "nota": "22-oct, tarde: T40 liberó MH4. DRC de la v6: 11 errores, los encimes de courtyard de margen; 0 sin conectar, paridad igual. Quedan 4 de los 8 bloqueantes del 16-oct y D-22-4 (las TVS de la SIM junto a J14)." + }, + { + "crear": { + "id": "t-v6-t40-push", + "titulo": "v6: commit y push de T40 (MH4); Michelle no abre la v6 hasta el push", + "pista": "ingenieria", + "estado": "por-hacer", + "responsable": "leo", + "version_tarjeta": "v6", + "fecha_limite": "2026-10-23", + "descripcion": "T40 cambió hbox-watchdog-v6.kicad_pcb (ya rellenado con kicad-cli y el proyecto; idéntico a la copia probada, a273d44c) y agregó kicad/tools/t40_v6_mh4.py. Primero el commit del submódulo kicad y su push; después el del repo principal (docs, figura, CLAUDE.md) con el submódulo al día. Los comandos están en la respuesta de Claude del 22-oct. Después, Michelle hace git pull --ff-only antes de abrir la v6.", + "enlaces": [ + { + "titulo": "Estado de la v6, §7 (T40)", + "url": "/hardware/v6-estado-21oct/#7-t40-22-oct-tarde-mh4-libre" + } + ], + "etiquetas": [ + "git" + ] + }, + "si_no_hay": [ + "push de T40" + ] + }, + { + "crear": { + "id": "d-22-4-v6-tvs-sim", + "titulo": "D-22-4: TVS de la SIM de la v6 — (a) se quedan del lado del módem o (b) junto a J14, en /SIMB_* — decide Leo", + "pista": "ingenieria", + "estado": "por-hacer", + "responsable": "leo", + "version_tarjeta": "v6", + "fecha_limite": "2026-10-24", + "descripcion": "T40 sacó D23–D25 de MH4, pero del lado del módem de las resistencias de 22 Ω: una descarga en el zócalo recorre 27–41 mm de pista y la resistencia antes de llegar a la TVS. El plan (L-38, por B-09) las pedía junto a J14, y el 28-sep se dejó fuera el arreglo de ESD de /SIM_VDD contando con eso. (a) Se quedan así: no cuesta nada y el módem queda protegido. (b) Recomendada por Claude: D23–D25 pasan a /SIMB_DATA, /SIMB_CLK y /SIMB_RST en el esquemático, pegadas a los pines de J14 y cada una con su vía de GND. Son las mismas piezas; lo hace Claude como T41 (esquemático y tarjeta por script) o Michelle el sábado 24.", + "enlaces": [ + { + "titulo": "Estado de la v6, §7.2 (D-22-4)", + "url": "/hardware/v6-estado-21oct/#72-las-tvs-de-la-sim-se-quedan-del-lado-del-modem-d-22-4" + }, + { + "titulo": "Plan de fines de semana, §3.4", + "url": "/hardware/v6-plan-fines-de-semana/#34-barrenos-mh4-y-mh6-1-h" + } + ], + "etiquetas": [ + "decisión", + "esd" + ] + }, + "si_no_hay": [ + "D-22-4" + ] + } + ] +} diff --git a/docs/actas/index.md b/docs/actas/index.md index b3e8282..0bdb0c5 100644 --- a/docs/actas/index.md +++ b/docs/actas/index.md @@ -42,6 +42,7 @@ El acta de ensamble no deja elegir un módulo sin aprobar, sin integración o ya | Acta | Qué registra | Procedimiento | |---|---|---| | [Instalación en campo](../formularios/instalacion.html) | Una por unidad y vehículo: sitio, equipo, alimentación 24 V, antenas, RTK FIX, señal 4G, fotos | [Checklist de puesta en marcha](../procedimientos/v5-checklist-puesta-en-marcha.md) · [Sitios](../sitios/index.md) | +| [Prueba en sitio](../formularios/prueba-sitio.html) | Después de instalar, una por unidad: fix RTK en el monitor, reporte en el monitor y en Wialon, posición, respaldo en batería, fotos. Solo con ella la unidad cuenta para la meta del sitio | [Instalaciones](../tableros/instalaciones.md) | | [Diagnóstico en campo](../formularios/diagnostico.html) | Una por visita; muestra las visitas anteriores y admite fotos desde el teléfono | [Diagnóstico en campo](../diagnostico/procedimiento-diagnostico-campo.md) · [Tablero de campo](../tableros/campo.md) | | [Envío](../formularios/envio.html) · [Recepción](../formularios/recepcion.html) | El tramo entre el banco y el puerto | [Ciclo de vida](../procedimientos/ciclo-de-vida.md) | | [Daño o incidente](../formularios/dano.html) | Cualquier serie; la marca en todos los formularios. «Reparada» la levanta, «Baja» la hace permanente | [Ciclo de vida](../procedimientos/ciclo-de-vida.md#dano-o-incidente) | diff --git a/docs/bitacora.md b/docs/bitacora.md index 0acf71f..851271e 100644 --- a/docs/bitacora.md +++ b/docs/bitacora.md @@ -23,6 +23,9 @@ Arriba, lo que pasó en el tablero de pendientes y en las actas en los últimos ### Octubre de 2026 **22 oct** +: [Instalaciones por sitio](tableros/instalaciones.md): tablero nuevo, una tarjeta por unidad con **en qué vehículo está** (número económico, tipo, 12/24 V), sus actas y su etapa: enviada → recibida → instalada → **probada en sitio** → en operación, más «con falla». Acta nueva [Prueba en sitio](formularios/prueba-sitio.html): solo con ella aprobada una unidad cuenta para la meta de 1–2 por sitio. +: [Estado de la v6, rev. 1.3: T40, MH4 libre](hardware/v6-estado-21oct.md#7-t40-22-oct-tarde-mh4-libre): D23 y D24 fuera del barreno, `/SIM_CLK` por In1, `/SIM_RST` por arriba de D25 y `/NTC` alrededor del barreno; las tres TVS de la SIM y los pines 92/94 de U19 con vía de GND propia. DRC: **11 errores** (los encimes de margen), 0 sin conectar. Leo decide D-22-4: las TVS siguen del lado del módem y Claude recomienda pasarlas junto a J14. Falta el push de T40; lote `2026-10-22_t40-v6`. +: [Plan de fines de semana de la v6, rev. 1.5](hardware/v6-plan-fines-de-semana.md#34-barrenos-mh4-y-mh6-1-h): MH4 ya quedó; de los barrenos solo queda D-22-4. : [Juntas: standup y quick wins](tableros/juntas.md): **modo crisis, semáforo en rojo** (sin pago este mes y compras detenidas; TIMSA bloqueado por el trámite del vehículo; EIT espera material de Manzanillo; ICAVE con mal clima). El tablero ahora tiene **sitio** por pendiente (ICAVE, TIMSA, EIT, LCT, Querétaro) con filtro y vista *Por sitio*, y la pista **Gestión**. Las juntas se graban con Gemini y Claude pasa los acuerdos al tablero con un lote. : [Re-verificación de las 13:30](hardware/auditoria-final-22oct.md#2-que-se-reviso-metodo-ag): Leo rellenó las zonas, guardó y regeneró los paquetes a las 13:00 → **P-1 cerrado** (relleno guardado = fresco, 0.000 mm²; mismo cobre, mismo paquete, BOM/CPL iguales; DRC igual). El veredicto no cambia; falta el commit. Presentación e informe reemitidos con la re-verificación; `verify_mac.sh` + `gcmp_b.py` para repetirla en 5 min después de cualquier cambio. : [Estado de la v6, rev. 1.2: T39, el bloque A por script](hardware/v6-estado-21oct.md#6-t39-22-oct-el-bloque-a-por-script): D34 entre U25 y L22, con el cátodo a 3.52 mm del pin SW y un lazo de 56.5 mm² con C149. In1 e In2 sin pistas bajo la fuente y MH8 libre. DRC: 44 errores (≈ 33 de MH4 y 11 encimes de margen), 0 sin conectar. Falta el push de T39; lote `2026-10-22_t39-v6`. diff --git a/docs/campo/index.md b/docs/campo/index.md index 51fc11d..caf9df0 100644 --- a/docs/campo/index.md +++ b/docs/campo/index.md @@ -22,6 +22,7 @@ Cada sitio muestra sus unidades instaladas y sus actas de instalación y diagnó | Situación | Procedimiento | Acta | |---|---|---| | **Instalar en el puerto** (gabinete montado, 24 V, antenas, RTK FIX) | [Checklist de puesta en marcha](../procedimientos/v5-checklist-puesta-en-marcha.md) — imprimir, una hoja por unidad | [Instalación en campo](../formularios/instalacion.html) — sitio, unidad, vehículo, antena, alimentación, RTK FIX, fotos | +| **Probar la unidad recién instalada** (monitor, Wialon, posición, batería) | En el acta; el avance por sitio está en [Instalaciones](../tableros/instalaciones.md) | [Prueba en sitio](../formularios/prueba-sitio.html) — solo con ella cuenta para la meta del sitio | | **Falla en la máquina** | [Diagnóstico en campo](../diagnostico/procedimiento-diagnostico-campo.md) | [Diagnóstico en campo](../formularios/diagnostico.html) — una por visita, con fotos desde el teléfono | | Sale una unidad del banco | [Ciclo de vida §6](../procedimientos/ciclo-de-vida.md#6-envio) | [Envío](../formularios/envio.html) | | Llega una unidad al puerto o al taller | [Ciclo de vida §7](../procedimientos/ciclo-de-vida.md#7-recepcion-e-inspeccion) | [Recepción e inspección](../formularios/recepcion.html) | diff --git a/docs/datos/proyecto.json b/docs/datos/proyecto.json index 30966ba..41a0602 100644 --- a/docs/datos/proyecto.json +++ b/docs/datos/proyecto.json @@ -267,8 +267,8 @@ ], [ "bloqueado", - "5 bloqueantes", - "T39: bloque A y MH8 listos; faltan MH4 y los bloques B a H" + "4 bloqueantes", + "T39 y T40: bloque A y los 5 barrenos listos; faltan los bloques B a H" ], [ "falta", @@ -296,16 +296,16 @@ "después de G2" ] ], - "detalle": "No lista (22-oct): T25, T28 y T38 ya están en HBox_PCB (b74b96f). T39 (Claude, 22-oct) hizo el bloque A con la propuesta α: D34 entre U25 y L22 (cátodo a 3.52 mm del pin SW, lazo de 56.5 mm² con C149, antes ≈ 115), In1 e In2 sin pistas bajo la fuente y MH8 libre. DRC: 44 errores (≈ 33 de MH4 y 11 encimes de margen), 0 sin conectar. Quedan 5 de los 8 bloqueantes (MH4, 5 V por capas internas, cargador U6, RF por In1, vías de tierra).", - "siguiente": "Leo: commit y push de T39; Michelle hace git pull --ff-only antes de abrir la v6. Claude evalúa MH4 (T40). Sáb 24: Michelle revisa el bloque A, hace Rig1 y el /24V sin montar, MH4 si T40 no lo resolvió, y sigue con el bloque B. Dom 25: bloques C, D y E (módem, GNSS y U12); en la noche, re-auditoría de Claude. Sáb 31: bloques F, G y H1 (pares, puertos serie e In1). Dom 1-nov: H2 y DRC final; en la tarde, re-auditoría final y Gerber (G1). Lun 2-nov: pedido del piloto de 20. Firmware los fines de semana del 7–8 y del 14–15 nov; banco del piloto el 21–22 nov (G2). No habrá v6.1.", + "detalle": "No lista (22-oct): T25, T28, T38 y T39 ya están en HBox_PCB (d5f5002). T39 (Claude) hizo el bloque A con la propuesta α: D34 entre U25 y L22 (cátodo a 3.52 mm del pin SW, lazo de 56.5 mm² con C149, antes ≈ 115), In1 e In2 sin pistas bajo la fuente y MH8 libre. T40 (Claude, 22-oct, tarde) dejó libre MH4: D23 y D24 fuera del barreno, /SIM_CLK por In1, /SIM_RST por arriba de D25, /NTC alrededor del barreno y vías de GND para las tres TVS de la SIM. DRC: 11 errores (los encimes de margen), 0 sin conectar. Quedan 4 de los 8 bloqueantes (5 V por capas internas, cargador U6, RF por In1, vías de tierra) y D-22-4 (las TVS de la SIM junto a J14).", + "siguiente": "Leo: commit y push de T40, y D-22-4 (Claude recomienda pasar las TVS de la SIM a /SIMB_*, junto a J14); Michelle hace git pull --ff-only antes de abrir la v6. Sáb 24: Michelle revisa el bloque A y MH4, hace Rig1 y el /24V sin montar, las TVS junto a J14 si Leo elige (b), y sigue con el bloque B. Dom 25: bloques C, D y E (módem, GNSS y U12); en la noche, re-auditoría de Claude. Sáb 31: bloques F, G y H1 (pares, puertos serie e In1). Dom 1-nov: H2 y DRC final; en la tarde, re-auditoría final y Gerber (G1). Lun 2-nov: pedido del piloto de 20. Firmware los fines de semana del 7–8 y del 14–15 nov; banco del piloto el 21–22 nov (G2). No habrá v6.1.", "quien": "Michelle (layout) · Leo (scripts y pedido) · Claude (re-auditoría y Gerber) · Aldair (pedido) · Jesús (banco)", "docs": [ [ - "Estado de la v6 (22-oct, T39)", + "Estado de la v6 (22-oct, T39 y T40)", "/hardware/v6-estado-21oct/" ], [ - "Plan de fines de semana (rev. 1.4)", + "Plan de fines de semana (rev. 1.5)", "/hardware/v6-plan-fines-de-semana/" ], [ @@ -432,7 +432,7 @@ "etiqueta": "der", "nota": "mal clima: ventanas cortas en campo y fallas por investigar · se compara con el CalAmp", "estado": "amarillo", - "meta": "1–2 unidades instaladas" + "meta": "1–2 unidades instaladas y probadas" }, { "id": "lzc", @@ -443,7 +443,7 @@ "etiqueta": "der", "estado": "amarillo", "nota": "estado por confirmar en la junta del 22-oct", - "meta": "1–2 unidades instaladas" + "meta": "1–2 unidades instaladas y probadas" }, { "id": "eit", @@ -454,7 +454,7 @@ "etiqueta": "der", "estado": "rojo", "nota": "esperando el material que se envió desde Manzanillo", - "meta": "1–2 unidades instaladas" + "meta": "1–2 unidades instaladas y probadas" }, { "id": "timsa", @@ -465,7 +465,7 @@ "etiqueta": "izq", "estado": "rojo", "nota": "bloqueado por un trámite administrativo del vehículo", - "meta": "1–2 unidades instaladas" + "meta": "1–2 unidades instaladas y probadas" } ], "oficina": { diff --git a/docs/formularios/acta.js b/docs/formularios/acta.js index 99771a9..64b4cc3 100644 --- a/docs/formularios/acta.js +++ b/docs/formularios/acta.js @@ -20,6 +20,8 @@ item.tipo = 'sitio' → lista de sitios (puertos/terminales) desde /api/sitios; con guardaEn:'sitio' el slug queda en la raíz del acta y la página del sitio la encuentra (sitios/sitio.html?id=) + Precarga (22-oct): formulario.html?serie=…&sitio=…&=… elige la unidad y llena los campos + vacíos (lo usa el tablero de Instalaciones para abrir la siguiente acta). Modos de serie: (a) simple: cfg.prefijo + cfg.series (cantidad) [+ cfg.desde, cfg.pad] → "RTK-005" @@ -94,6 +96,7 @@ const tecnico = $('input', { type: 'text', id: 'f_tecnico', placeholder: 'Nombre y apellido' }); const flota = Array.isArray(cfg.unidades) && cfg.unidades.length > 0; + let ensambladas = null; // promesa: unidades HBOX completas (para la precarga) const serieOtra = $('input', { type: 'text', id: 'f_serie_otra', placeholder: 'Escribe la etiqueta de la unidad tal como viene en la caja' }); const fichaUnidad = $('div', { class: 'ficha-unidad' }); const armar = $('div', { class: 'armar-hbox' }); const armarSel = {}; @@ -107,7 +110,7 @@ grupos[g].forEach(u => og.append($('option', { value: u.serie, text: u.etiqueta || (u.serie + (u.maquina ? ' · ' + u.maquina : '')) }))); serieSel.append(og); }); - if (!cfg.sinEnsambladas) cargarEnsambladas(); + if (!cfg.sinEnsambladas) ensambladas = cargarEnsambladas(); if (!cfg.sinEnsambladas) serieSel.insertBefore($('option', { value: '__HBOX__', text: 'Unidad HBOX completa: elegir sus 3 piezas' }), serieSel.children[1] || null); serieSel.append($('option', { value: '__OTRA__', text: 'Otra unidad (no está en la lista)' })); serieSel.append($('option', { value: 'CAMPO-PRUEBA', text: 'PRUEBA (no cuenta)' })); @@ -607,7 +610,7 @@ try { const r = await fetch(`/api/historial?tipo=${encodeURIComponent(cfg.tipo)}&serie=${encodeURIComponent(s)}`, { cache: 'no-store' }); const j = await r.json(); - if (!j.total) { hist.innerHTML = '🆕 Primera visita registrada para esta unidad.'; return; } + if (!j.total) { hist.innerHTML = 'Primera visita registrada para esta unidad.'; return; } hist.innerHTML = ''; hist.append($('div', { class: 'hist-t', html: '' + j.total + ' visita(s) anterior(es) a esta unidad — léelas antes de empezar:' })); j.visitas.slice(0, 6).forEach(v => { @@ -716,7 +719,7 @@ } // ---------------- cargar una serie ---------------- - async function loadSerie() { + async function cargarSerie() { msg.className = 'msg'; locked = false; if (flota) { serieOtra.style.display = serieSel.value === '__OTRA__' ? '' : 'none'; @@ -749,6 +752,53 @@ } } } + // ---------------- precarga desde la dirección (22-oct) ---------------- + // El tablero de Instalaciones abre la siguiente acta ya con la unidad, el sitio y el vehículo: + // ?serie=HBOX5-…&sitio=eit&maquina_id=TP-114 (cualquier campo por su clave). Solo llena lo vacío: + // no pisa lo escrito ni el borrador guardado, y nunca marca casillas, fotos ni el resultado. + const pre = new URLSearchParams(location.search); + const preSerie = String(pre.get('serie') || '').trim().toUpperCase().replace(/[^A-Z0-9_-]/g, '-').slice(0, 24); + async function precargarSerie() { + if (!preSerie || !flota) return; + const hay = () => Array.from(serieSel.options).some(o => o.value === preSerie); + if (!hay() && ensambladas) { try { await ensambladas; } catch (e) {} } + if (hay()) serieSel.value = preSerie; + else { serieSel.value = '__OTRA__'; serieOtra.value = preSerie; } + } + function precargarCampos() { + if (locked || (preSerie && serieActual() !== preSerie)) return; + let n = preSerie && flota ? 1 : 0; + pre.forEach((v, k) => { + if (k === 'serie' || !/^[a-z][a-z0-9_]{0,39}$/.test(k)) return; + v = String(v || '').trim().slice(0, 200); + const els = Array.from(fields()).filter(e => e.dataset.id === k); + if (!v || !els.length) return; + if (els[0].type === 'radio') { + if (els.some(e => e.checked)) return; + const r = els.find(e => e.value === v); + if (r) { r.checked = true; n++; } + return; + } + const el = els[0]; + if (el.disabled || ['checkbox', 'hidden', 'file'].includes(el.type)) return; + if (el.tagName === 'SELECT') { + if (el.value) return; + if (Array.from(el.options).some(o => o.value === v)) el.value = v; else el.dataset.pend = v; + } else { + if (el.value && el.value !== el.dataset.def) return; + el.value = v; + } + n++; + }); + if (!n) return; + aplicarCondiciones(); + if (banner.className === 'msg') { + banner.className = 'msg ok'; + banner.textContent = 'Datos precargados desde el tablero de Instalaciones. Revisa que la unidad, el sitio y el vehículo sean los correctos antes de firmar.'; + } + } + async function loadSerie() { await cargarSerie(); precargarCampos(); } + wrap.addEventListener('input', () => { aplicarCondiciones(); guardarLocal(); }); wrap.addEventListener('change', aplicarCondiciones); serieSel.addEventListener('change', loadSerie); @@ -833,6 +883,7 @@ if (!tecnico.value) tecnico.value = nombreUsuario; } } catch (e) {} + await precargarSerie(); loadSerie(); })(); } diff --git a/docs/formularios/instalacion.html b/docs/formularios/instalacion.html index 827d698..370659b 100644 --- a/docs/formularios/instalacion.html +++ b/docs/formularios/instalacion.html @@ -36,12 +36,14 @@ Acta.render({ textoOK: 'INSTALADA Y REPORTANDO', intro: '
    Cómo se llena
      ' + '
    1. Elige el sitio y la unidad (la etiqueta de la caja, HBOX5-Exx-Axxx-Rxxxx). Si la unidad trae aviso de daño, no la instales.
    2. ' - + '
    3. Anota el vehículo como lo nombra el puerto (FL-JUN-060, RT-ZPMC-20): así lo buscan después.
    4. ' + + '
    5. Anota el vehículo: su número económico como lo nombra el puerto (FL-JUN-060, RT-ZPMC-20), su tipo y si es de 12 V o 24 V. Así lo buscan después y así sale en el tablero de Instalaciones.
    6. ' + '
    7. Marca cada punto del checklist después de hacerlo, no antes. Mide el voltaje con la máquina encendida.
    8. ' + '
    9. Espera el RTK FIX con la antena ya fija en su lugar definitivo y anota cuánto tardó.
    10. ' + '
    11. Confirma con alguien que vea el monitor que la posición aparece. Sin confirmación, el resultado es FALLA.
    12. ' + '
    13. Fotos: gabinete montado, antena, interior con cables sujetos. Si no subieron por señal, reintenta antes de irte.
    14. ' + '
    15. Resultado: INSTALADA Y REPORTANDO solo si todo quedó. Si no, FALLA y explica qué faltó; se vuelve con otra acta.
    16. ' + + '
    17. Después va la prueba en sitio: sin ella la unidad no cuenta para la meta del sitio.
    18. ' + + '
    19. ¿La unidad ya estaba instalada y no tiene acta? Llénala ahora con la fecha real de la instalación; lo que no sepas, anótalo en observaciones.
    20. ' + '
    ', secciones: [ @@ -50,10 +52,14 @@ Acta.render({ { tipo:'fecha', clave:'fecha', req:true, guardaEn:'fecha', txt:'Fecha de la instalación' }, { tipo:'sitio', clave:'sitio', req:true, guardaEn:'sitio', txt:'Sitio (puerto o terminal)', ayuda:'Si el sitio no está en la lista, elige «Otro» y escríbelo en observaciones; Leo lo da de alta.' }, - { tipo:'texto', clave:'maquina_id', req:true, guardaEn:'maquina_id', rows:'1', txt:'Vehículo o equipo (ID como lo nombra el puerto)', ph:'FL-JUN-060 · RT-ZPMC-20 · HS-WES-62' }, + { tipo:'texto', clave:'maquina_id', req:true, guardaEn:'maquina_id', rows:'1', txt:'Número económico del vehículo o equipo (como lo nombra el puerto)', ph:'FL-JUN-060 · RT-ZPMC-20 · HS-WES-62' }, { tipo:'radio', clave:'tipo_vehiculo', req:true, guardaEn:'clasificacion', txt:'Tipo de vehículo o equipo', - opciones:['RTG','Montacargas','Tractoplana','Grúa','Camión / pick-up','Equipo fijo','Otro'] }, - { tipo:'texto', clave:'placas', rows:'1', txt:'Placas o número económico (si aplica)' }, + opciones:['RTG','Reach Stacker','Empty Handler','Tractoplana','Montacargas','Grúa','Camión / pick-up','Equipo fijo','Otro'] }, + { tipo:'radio', clave:'sistema_v', req:true, guardaEn:'sistema_v', txt:'Sistema eléctrico del vehículo', + opciones:['24 V','12 V','No se sabe'] }, + { tipo:'nota', txt:'En ICAVE, RTG, Reach Stacker y Empty Handler son de 24 V; Tractoplana y Montacargas, de 12 V. La unidad toma 24 V de la fuente del gabinete en los dos casos; la ignición llega directo del vehículo.' }, + { tipo:'texto', clave:'placas', rows:'1', txt:'Placas (si aplica)' }, + { tipo:'texto', clave:'id_monitor', rows:'1', guardaEn:'id_monitor', txt:'Nombre de la unidad en el monitor (H00xx), si ya lo sabes', ph:'H0013' }, { tipo:'texto', clave:'acompanante', rows:'1', txt:'Quién autorizó o acompañó (operador, supervisor)', ph:'Abraham (ICAVE), 10:30' }, ] }, @@ -113,7 +119,7 @@ Acta.render({ items: [ { tipo:'radio', clave:'accion', req:true, guardaEn:'accion', txt:'Cómo quedó', opciones:['Instalada y reportando','Instalada, sin reportar todavía (explica)','No se pudo instalar (explica)'], - aviso:'Solo «Instalada y reportando» cuenta como instalación terminada en el tablero y en la página del sitio.' }, + aviso:'Solo «Instalada y reportando» cuenta como instalación terminada en el tablero de Instalaciones y en la página del sitio. Para contar en la meta del sitio falta la prueba en sitio.' }, { tipo:'check', clave:'operador_informado', txt:'Operador o supervisor informado: no desconectar ni abrir el gabinete; a quién llamar.' }, { tipo:'check', clave:'registro_sitio', txt:'Vehículo y unidad anotados en la hoja de contacto que se queda en el sitio.' }, { tipo:'texto', clave:'observaciones', rows:'3', txt:'Observaciones (qué faltó, qué cambió respecto al plan)' }, diff --git a/docs/formularios/prueba-sitio.html b/docs/formularios/prueba-sitio.html new file mode 100644 index 0000000..d024b5a --- /dev/null +++ b/docs/formularios/prueba-sitio.html @@ -0,0 +1,122 @@ + + + + + +Prueba en sitio — HBOX + + + + + +
    + + + + + + diff --git a/docs/hardware/img/2026-10-22_Drogheda_v6-T40-MH4_v1.0.png b/docs/hardware/img/2026-10-22_Drogheda_v6-T40-MH4_v1.0.png new file mode 100644 index 0000000..aa9d9af Binary files /dev/null and b/docs/hardware/img/2026-10-22_Drogheda_v6-T40-MH4_v1.0.png differ diff --git a/docs/hardware/index.md b/docs/hardware/index.md index f410b61..9c86d3d 100644 --- a/docs/hardware/index.md +++ b/docs/hardware/index.md @@ -11,16 +11,16 @@ Estado de cada versión de la EinarBoard al **22-oct-2026**, con sus documentos - **Condiciones del pedido (no tocan el cobre):** (1) vías *Epoxy Filled & Capped* + rayos X en U6 (3 vías dentro de la pasta del QFN); (2) rotación y polaridad en el visor de JLC (U6, U7, U25, U26, L22, Q7, U16, D34, D10, electrolíticos: huellas easyeda2kicad nunca fabricadas); (3) BOM: D10 SMBJ33A → SMBJ33CA. - **NO-GO para las 108 / 322** hasta que el piloto pase el banco con el firmware 0.7.0: hoy ningún firmware enciende el módem de estas tarjetas. `board_v56.h` ya existe; 0.7.0-pre (módem, NTC, LFP, ignición por ADC) es 1 día y va antes de que lleguen las tarjetas. - **P-1 cerrado a las 13:00:** Leo rellenó, guardó y regeneró los paquetes; re-verificado a las 13:30 (relleno guardado = fresco, 0.000 mm²; mismo cobre y mismo paquete que en la mañana; BOM/CPL iguales). Falta el commit de `kicad/` y `production/`. Regla D-22-3: todo script T que toque cobre termina con rellenado en el GUI ([re-verificación](auditoria-final-22oct.md#2-que-se-reviso-metodo-ag)). - - **v6:** T39 (22-oct, Claude) hizo el bloque A con la propuesta α. D34 quedó entre U25 y L22, In1/In2 sin pistas bajo la fuente y MH8 libre. DRC: 44 errores (≈ 33 de MH4 y 11 encimes de margen), 0 sin conectar. Falta el push de T39 y MH4 (T40) → [estado de la v6, §6](v6-estado-21oct.md#6-t39-22-oct-el-bloque-a-por-script). + - **v6:** T39 (22-oct, Claude) hizo el bloque A con la propuesta α, y T40 (22-oct, tarde) dejó libre MH4: D23 y D24 fuera del barreno, `/SIM_CLK` por In1, `/SIM_RST` por arriba de D25 y `/NTC` alrededor del barreno. DRC: **11 errores** (los encimes de margen), 0 sin conectar. Falta el push de T40 y que Leo decida D-22-4 (las TVS de la SIM junto a J14) → [estado de la v6, §7](v6-estado-21oct.md#7-t40-22-oct-tarde-mh4-libre). - [**▶ Auditoría final (veredicto, hallazgos, riesgos)**](auditoria-final-22oct.md) · [PDF completo, 33 pp.](2026-10-22_Drogheda_Auditoria-Final-Produccion_V5.6-V5.7_ES_v1.0.pdf) · [presentación, 19 láminas](2026-10-22_Drogheda_Auditoria-Final-Produccion_V5.6-V5.7_Presentacion_ES_v1.0.pdf) · [protocolo](auditoria-final-protocolo.md). Antes: [auditoría del 21-oct (pasadas 4 a 6)](v56-v57-auditoria-21oct.md) · [re-auditoría del 19-oct](re-auditoria-19oct.md) · [qué es crítico en la V5.6](v56-clasificacion-19oct.md) · [plan v6 (rev. 1.4)](v6-plan-fines-de-semana.md). + [**▶ Auditoría final (veredicto, hallazgos, riesgos)**](auditoria-final-22oct.md) · [PDF completo, 33 pp.](2026-10-22_Drogheda_Auditoria-Final-Produccion_V5.6-V5.7_ES_v1.0.pdf) · [presentación, 19 láminas](2026-10-22_Drogheda_Auditoria-Final-Produccion_V5.6-V5.7_Presentacion_ES_v1.0.pdf) · [protocolo](auditoria-final-protocolo.md). Antes: [auditoría del 21-oct (pasadas 4 a 6)](v56-v57-auditoria-21oct.md) · [re-auditoría del 19-oct](re-auditoria-19oct.md) · [qué es crítico en la V5.6](v56-clasificacion-19oct.md) · [plan v6 (rev. 1.5)](v6-plan-fines-de-semana.md). | Tarjeta | Estado | Pedido | Proyecto KiCad | Firmware | |---|---|---|---|---| | V5.5 | En campo (15 pzas, 22-ago). No se fabrica más. | — | `hbox-watchdog-v5` (tag `v5.5-as-fabbed`) | `hbox-v5-bringup_0.6.0` CAMPO · 0.6.3 banco | | V5.6 | **Auditoría final del 22-oct: GO al piloto** con tres condiciones de pedido (vías tapadas + rayos X en U6, visor de JLC, D10 → SMBJ33CA). Paquete `HBOX_v5_Rev6_PROD` verificado = cobre con relleno fresco; DRC y paridad limpios. P-1 cerrado a las 13:00 (relleno fresco en el repo, re-verificado; falta el commit) ([auditoría final](auditoria-final-22oct.md)). | 113 (piloto de 5 primero, se pide hoy) | `hbox-watchdog-v5` | 0.7.0: `board_v56.h` listo; 0.7.0-pre por escribir (1 día) | | V5.7 | **Auditoría final del 22-oct: GO a los 5 prototipos** con las mismas condiciones. Fuente U25 a 5.32 V / 600 kHz: 9–32 V sin la SD-15B; C149/C150 se quedan (D-21-2) y el timbre se mide en banco; D10 → SMBJ33CA es obligatorio aquí (con el arnés al revés abre F2, que es SMD) ([auditoría final](auditoria-final-22oct.md)). | 327 (5 prototipos primero, se piden hoy) | `hbox-watchdog-v57` (convive con v5) | el mismo 0.7.0 (mismos pines de MCU) | -| v6 | Revisada el 22-oct (`b74b96f` + T39): **NO LISTA**. T28 cerró 2 de los 8 bloqueantes de la [auditoría v6](v6-auditoria-produccion-16oct.md), T25 regresó los barrenos, T38 corrigió courtyards, MH6 y el `/3V3` bajo los barrenos, y **T39 hizo el bloque A** (D34 entre U25 y L22, MH8 libre). Faltan MH4 y los bloques B a H ([estado, §6](v6-estado-21oct.md#6-t39-22-oct-el-bloque-a-por-script)). Plan: [fines de semana 24-oct → 22-nov](v6-plan-fines-de-semana.md). | 130 + reemplazos (piloto de 20, pedido previsto el 2-nov) | `hbox-watchdog-v6` | 0.7.x (`board_v6.h` + NTRIP), no existe | +| v6 | Revisada el 22-oct (`d5f5002` + T40): **NO LISTA**. T28 cerró 2 de los 8 bloqueantes de la [auditoría v6](v6-auditoria-produccion-16oct.md), T25 regresó los barrenos, T38 corrigió courtyards, MH6 y el `/3V3` bajo los barrenos, **T39 hizo el bloque A** (D34 entre U25 y L22, MH8 libre) y **T40 liberó MH4**. Faltan los bloques B a H y D-22-4 ([estado, §7](v6-estado-21oct.md#7-t40-22-oct-tarde-mh4-libre)). Plan: [fines de semana 24-oct → 22-nov](v6-plan-fines-de-semana.md). | 130 + reemplazos (piloto de 20, pedido previsto el 2-nov) | `hbox-watchdog-v6` | 0.7.x (`board_v6.h` + NTRIP), no existe | | V4 | En prueba y campo. Sin producción nueva. | — | `hbox-watchdog-v4` | `hbox-tarjetaV4_0.6.0` CAMPO | | V3 | 3 unidades en campo. Registro congelado. | — | `hbox-watchdog-v3-PROD` (no editar) | `hbox-tarjetaV3_4.0.0` | @@ -132,23 +132,32 @@ DRC: 52 errores, todos conocidos (MH4 28 · MH8 10 · courtyards 14), 0 sin cone - In1 e In2 sin pistas bajo la fuente: I²C y la toma de 5 V de R121 pasan a B.Cu. - MH8 libre. -DRC: **44 errores** (≈ 33 de MH4 y 11 encimes de courtyard de margen, que ya estaban), 0 sin conectar, paridad igual. Del bloque A quedan Rig1 y el `/24V` sin montar. Detalle: [**▶ estado de la v6, rev. 1.2 (§6)**](v6-estado-21oct.md#6-t39-22-oct-el-bloque-a-por-script). +DRC: **44 errores** (≈ 33 de MH4 y 11 encimes de courtyard de margen, que ya estaban), 0 sin conectar, paridad igual. Del bloque A quedan Rig1 y el `/24V` sin montar. Detalle: [**▶ estado de la v6, rev. 1.3 (§6)**](v6-estado-21oct.md#6-t39-22-oct-el-bloque-a-por-script). + +**22-oct, tarde (T40, Claude): MH4 libre.** + +- D23 (TVS de `/SIM_DATA`) debajo de U19.31 y D24 (TVS de `/SIM_CLK`) junto a R129/R133; D25 no se mueve. Las tres tienen vía de GND propia. +- `/SIM_CLK` baja a In1; `/SIM_RST` pasa por F.Cu arriba de D25, a 4.2 mm del centro, hasta una vía nueva. +- `/NTC` (In2) ya no cruza el barreno: pasa a 0.95 mm de su orilla. +- Los pines 92 y 94 de U19 quedaban sin tierra: pista de GND y vía nueva. + +DRC: **11 errores**, los encimes de margen; ya no hay errores de barreno, de máscara ni de courtyard con barreno. 0 sin conectar, paridad igual. **D-22-4 (Leo):** las TVS siguen del lado del módem; Claude recomienda pasarlas a `/SIMB_*`, pegadas a J14 (L-38). Detalle: [**▶ estado de la v6, rev. 1.3 (§7)**](v6-estado-21oct.md#7-t40-22-oct-tarde-mh4-libre). El firmware que sustituye al 4G NTRIP Master no existe. Decisión vigente: **no habrá v6.1**. | | Documentos | |---|---| -| Vigentes | [**▶ Estado al 22-oct (T25, T28, T38 y T39)**](v6-estado-21oct.md) · [**▶ Auditoría de producción v6 (16-oct)**](v6-auditoria-produccion-16oct.md) · [**▶ Plan de fines de semana (rev. 1.4: 24-oct → 22-nov)**](v6-plan-fines-de-semana.md) · [Re-auditoría 19-oct, §8](re-auditoria-19oct.md#8-v6) · [Plan de corrección y lista de liberación (28-sep, el porqué de cada punto)](v6-plan-correccion.md) · [Esquemático final — resumen de 3 pasadas](v6-cambios-resumen.md) · [Mapa de pines MCU para `board_v6.h`](v6-pinmap.md) · [Plan de cobre y colocación EMC](EinarBoard-v6_Plan-de-Cobre_ES.html) ([inglés](EinarBoard-v6_Copper-Plan_EN.html)) · [Manual v6 (marcador)](../manuales/manual-tarjeta-v6.md) | +| Vigentes | [**▶ Estado al 22-oct (T25, T28, T38, T39 y T40)**](v6-estado-21oct.md) · [**▶ Auditoría de producción v6 (16-oct)**](v6-auditoria-produccion-16oct.md) · [**▶ Plan de fines de semana (rev. 1.5: 24-oct → 22-nov)**](v6-plan-fines-de-semana.md) · [Re-auditoría 19-oct, §8](re-auditoria-19oct.md#8-v6) · [Plan de corrección y lista de liberación (28-sep, el porqué de cada punto)](v6-plan-correccion.md) · [Esquemático final — resumen de 3 pasadas](v6-cambios-resumen.md) · [Mapa de pines MCU para `board_v6.h`](v6-pinmap.md) · [Plan de cobre y colocación EMC](EinarBoard-v6_Plan-de-Cobre_ES.html) ([inglés](EinarBoard-v6_Copper-Plan_EN.html)) · [Manual v6 (marcador)](../manuales/manual-tarjeta-v6.md) | | Detalle (28-sep) | [Auditoría completa](v6-auditoria-completa.md) ([inglés](v6-full-audit.md)) · [Pasada 1 — cambios al esquemático](v6-cambios-esquematico.md) · [Pasada 2 — puertos (inglés)](v6-puertos-sin-nueva-version.md) · [Pasada 3 — revisión final (inglés)](v6-revision-final.md) | | Históricos | [Próximos pasos para ordenar (29-sep)](v6-proximos-pasos.md) — superado por el plan de fines de semana · [Auditoría V5.6 · V5.7 · v6 del 16-oct (mañana), §8](auditoria-produccion-16oct.md#8-v6-que-falta) · [Revisión contra lecciones V5.5](v6-revision-lecciones-v55.md) — superada por la auditoría completa · [Auditoría pre-fab 25-sep](v6-auditoria-prefab.md) ([inglés](v6-prefab-audit.md)) — superada por la del 28-sep | | Cantidad | La auditoría de septiembre hablaba de **5 prototipos**; el plan del 13-oct son **130 unidades y todos los reemplazos futuros**. Recomendado: piloto de 20 que pase el banco con el firmware 0.7.x antes de las 130. | -**Siguiente paso** ([plan de fines de semana, rev. 1.4](v6-plan-fines-de-semana.md); recorrido una semana el 19-oct): +**Siguiente paso** ([plan de fines de semana, rev. 1.5](v6-plan-fines-de-semana.md); recorrido una semana el 19-oct): - **Lun 19 o mar 20:** pre-órdenes en JLC (THVD1410DR, TPS7A2033PDBVR, J14). No se recorren. - **21-oct:** T25, T28 y T38 aplicados; Leo subió T38 el 22-oct (`b74b96f`). -- **22-oct:** T39 (Claude): bloque A con la propuesta α y MH8 libre; falta el push. Claude evalúa MH4 (T40). -- **Sáb 24:** Michelle revisa el bloque A que dejó T39, hace Rig1 y el `/24V`, MH4 si T40 no lo resolvió, y sigue con el bloque B ([estado, §3](v6-estado-21oct.md#3-lo-que-tiene-que-corregir-michelle-antes-de-seguir)). +- **22-oct:** T39 (Claude): bloque A con la propuesta α y MH8 libre (`d5f5002`). En la tarde, T40: MH4 libre; falta el push. Leo decide D-22-4 (TVS de la SIM junto a J14). +- **Sáb 24:** Michelle revisa el bloque A y MH4 que dejaron T39 y T40, hace Rig1 y el `/24V`, las TVS junto a J14 si Leo elige (b) en D-22-4, y sigue con el bloque B ([estado, §3](v6-estado-21oct.md#3-lo-que-tiene-que-corregir-michelle-antes-de-seguir)). - **Dom 25:** RF del módem, U20, GNSS y U12. - **Sáb 31 y dom 1-nov:** pares, puertos, In1, vías de tierra (T29), serigrafía y DRC final. P7/P8 se quitan del esquemático (decisión del 9-oct). - **Lun 2-nov:** pedido del piloto de 20. diff --git a/docs/hardware/v6-estado-21oct.md b/docs/hardware/v6-estado-21oct.md index f0ca2e1..13535c2 100644 --- a/docs/hardware/v6-estado-21oct.md +++ b/docs/hardware/v6-estado-21oct.md @@ -1,19 +1,25 @@ --- -title: "Estado de la v6 al 22-oct: T25, T28, T38 y T39 (bloque A) aplicados" -tags: [project-drogheda, hardware, hbox, einarboard, v6, auditoria, t25, t28, t38, t39, courtyards, barrenos, u25, bloque-a, layout, michelle] +title: "Estado de la v6 al 22-oct: T25, T28, T38, T39 (bloque A) y T40 (MH4) aplicados" +tags: [project-drogheda, hardware, hbox, einarboard, v6, auditoria, t25, t28, t38, t39, t40, courtyards, barrenos, mh4, sim, esd, u25, bloque-a, layout, michelle] project: Project Drogheda author: Helgen Technologies (revisión: Claude; pedido: Leo) date: 2026-10-22 -version: 1.2 -status: ACTIVO — HBox_PCB b74b96f (T25, T28 y T38; Leo, 22-oct 09:42) + T39 (Claude, 22-oct) · falta commit y push de T39 +version: 1.3 +status: ACTIVO — HBox_PCB d5f5002 (T39; Leo, 22-oct) + T40 (Claude, 22-oct, tarde) · falta commit y push de T40 audience: Leo, Michelle (layout) --- -# Estado de la v6 al 22-oct · T25, T28, T38 y T39 aplicados +# Estado de la v6 al 22-oct · T25, T28, T38, T39 y T40 aplicados **Pregunta (Leo, 21-oct):** ¿T28 ya quedó o hay que correrlo? ¿Cómo va la v6? Y en la noche: trabaja en la v6 real. **22-oct, 09:40:** «Haz tú los cambios de la v6; es la prioridad». +!!! note "Rev. 1.3 (22-oct, tarde): T40 dejó libre MH4" + - **T40 sacó de MH4 todo lo que no era GND**, por script. D23 quedó debajo del pin 31 de U19 y D24 junto a R129/R133. `/SIM_CLK` va por In1, `/SIM_RST` por arriba de D25 y `/NTC` ya no cruza el barreno. Las tres TVS de la SIM tienen vía de GND propia, y los pines 92 y 94 de U19 también. Detalle en el [§7](#7-t40-22-oct-tarde-mh4-libre). + - **DRC de KiCad 10:** quedan **11 errores**, los encimes de courtyard que son solo de margen. Hay 0 sin conectar y la misma paridad (19 PWR_FLAG). Salieron 37 violaciones y no entró ninguna. + - **Lo que no hace T40:** las TVS se quedan del lado del módem, no junto a J14 como pide L-38 (B-09). Leo decide si se cambian al lado del zócalo (D-22-4, [§7.2](#72-las-tvs-de-la-sim-se-quedan-del-lado-del-modem-d-22-4)). + - **Falta el commit y el push de T40.** Hasta entonces, Michelle no abre la v6. + !!! note "Rev. 1.2 (22-oct): T39, el bloque A, ya está en la v6" - **T39 aplicó la propuesta α del bloque A por script.** Leo lo pidió el 22-oct como prioridad. D34 quedó entre U25 y L22, L22 al este y R53/R54 junto a U6. El nodo SW y `/VEH5V` van por F.Cu. In1 e In2 ya no llevan pistas bajo la fuente, y MH8 quedó libre. Detalle en el [§6](#6-t39-22-oct-el-bloque-a-por-script). - **DRC de KiCad 10, con relleno y paridad:** @@ -28,7 +34,8 @@ audience: Leo, Michelle (layout) **Respuesta corta (22-oct):** -- **T25, T28 y T38** ya están en HBox_PCB: `b74b96f`, que Leo subió el 22-oct a las 09:42. +- **T25, T28 y T38** ya están en HBox_PCB: `b74b96f`, que Leo subió el 22-oct a las 09:42. **T39** también: `d5f5002`. +- **T40 (22-oct, tarde) dejó libre MH4** ([§7](#7-t40-22-oct-tarde-mh4-libre)). Con eso los 5 barrenos quedan libres y el DRC ya no tiene errores de barreno, de máscara ni de courtyard con barreno. - **T39 (22-oct) hizo el bloque A** con la propuesta α ([§6](#6-t39-22-oct-el-bloque-a-por-script)): - el cátodo de D34 quedó a 3.52 mm del pin SW (antes 13.0) y L22.1 a 8.79 mm; - el nodo SW tiene 9.8 mm² de cobre fuera de los pads; @@ -36,11 +43,13 @@ audience: Leo, Michelle (layout) - MH8 quedó libre y ya no están los 3 encimes reales: C153 y C154 bajo L22, y R53 sobre U25; - In1 e In2 ya no llevan pistas de señal bajo el nodo SW, L22 ni la entrada de U25. - **Del bloque A queda poco:** Rig1 a ≤ 3 mm de P1.3 (está a 4.79 mm) y decidir el `/24V` sin montar (pasos 5 y 6 del plan). -- **La v6 todavía no se puede pedir.** Falta MH4, que Claude evalúa como T40, y siguen los bloques B a H del plan. -- **DRC de hoy, con T39:** - - 44 errores: ≈ 33 de MH4 y 11 encimes de courtyard que son solo de margen; esos se excluyen al final; +- **La v6 todavía no se puede pedir.** Siguen los bloques B a H del plan, y D-22-4 (las TVS de la SIM junto a J14). +- **DRC de hoy, con T39 y T40:** + - 11 errores, los encimes de courtyard que son solo de margen; esos se excluyen al final; - 0 sin conectar y la paridad solo con los 19 PWR_FLAG; - - 254 avisos, 8 menos que antes. + - 249 avisos, 5 menos que con T39. + +![v6 con T40: el barreno MH4 libre](img/2026-10-22_Drogheda_v6-T40-MH4_v1.0.png) ![v6 con T39: el bloque A, la fuente U25, por script](img/2026-10-22_Drogheda_v6-T39-Bloque-A_v1.0.png) @@ -48,7 +57,7 @@ audience: Leo, Michelle (layout) ![v6 al 21-oct: la fuente U25 y los barrenos](img/2026-10-21_Drogheda_v6-Estado-U25-Barrenos_v1.0.png) -## 1. T25, T28 y T38: qué cambiaron hoy +## 1. T25, T28, T38, T39 y T40: qué cambiaron | Script | Qué cambió en `hbox-watchdog-v6` | |---|---| @@ -56,6 +65,7 @@ audience: Leo, Michelle (layout) | **T28** | U25 sin el código del AP64350: queda solo LCSC C524806 (TPS54360B) · pasta del EP de U6 al 50 % (6 ventanas de 0.95 × 0.85 mm) · conexión sólida a la zona en 114 pads de tierra de potencia y RF · stackup JLC04161H-7628 con ENIG y control de impedancia · cajetín «EinarBoard v6 (HBOX 6.0)», rev 6.0, y textos de serigrafía · clase RF a 0.35 mm en el `.kicad_pro`. | | **T38** (21-oct, noche) | Courtyard correcto en U19, U20, U23, U24, U25, U26, D22, D27, J12, J13 y L22, en la tarjeta y en `Drogheda-v6.pretty` · `/3V3` de MH6 por B.Cu, a 4.06 mm del centro · regla nueva en el `.kicad_dru`: en F.Cu y B.Cu, solo GND a menos de 4 mm del centro de un barreno. No toca el `.kicad_pro`. | | **T39** (22-oct) | Bloque A con la propuesta α: mueve D34, L22, R53 y R54 · nodo SW y `/VEH5V` con pistas anchas de F.Cu · `/I2C_SDA`, `/I2C_SCL` y la toma de 5 V de R121 pasan de In1/In2 a B.Cu · borra 28 tramos y 5 vías (2 de ellas dentro de MH8) y agrega 9 vías y 19 tramos. Solo cambia el `.kicad_pcb`; ver [§6](#6-t39-22-oct-el-bloque-a-por-script). | +| **T40** (22-oct, tarde) | MH4 libre: mueve D23 y D24 · `/SIM_CLK` por In1 · `/SIM_RST` por F.Cu arriba de D25, con vía nueva · `/NTC` (In2) rodea el barreno · vías de GND para D23, D24, D25 y los pines 92/94 de U19 · borra 17 tramos y 2 vías, acorta 2 tramos y agrega 7 vías y 17 tramos. Solo cambia el `.kicad_pcb`; ver [§7](#7-t40-22-oct-tarde-mh4-libre). | **Cómo se probó.** @@ -64,24 +74,25 @@ audience: Leo, Michelle (layout) - con los scripts: 22 errores, todos en MH4 y MH8; 0 sin conectar; la paridad igual (19 PWR_FLAG). - T38: igual, sobre una copia de la v6 ya con T25 y T28. Después se aplicó a la v6 de HBox_PCB y el resultado es idéntico, byte por byte, a la copia probada. - T39: igual, sobre una copia de `b74b96f`. Después se aplicó a la v6 de HBox_PCB y se rellenó con `kicad-cli` y el proyecto cargado; el archivo es idéntico, byte por byte, a la copia probada (`97ea7e45`). +- T40: igual, sobre una copia de la v6 ya con T39 (`97ea7e45`, la de `d5f5002`). Aplicado y rellenado en HBox_PCB: idéntico a la copia probada (`a273d44c`). - Correr T28 o T38 otra vez no cambia nada, y T25 se niega si los barrenos ya están. !!! warning "Antes de que Michelle vuelva a abrir la v6" - T39 (22-oct) cambia `hbox-watchdog-v6.kicad_pcb`, igual que antes T38 cambió el `.kicad_pcb`, el `.kicad_dru` y 8 archivos de `Drogheda-v6.pretty`. Git ya no mezcla archivos de KiCad (`merge=binary`): si Michelle guarda la v6 sobre su copia anterior y la sube, se pierde uno de los dos trabajos. El orden es: **Leo sube → Michelle hace `git pull --ff-only` → abre la v6.** + T40 (22-oct, tarde) cambia `hbox-watchdog-v6.kicad_pcb`, igual que T39 y que antes T38, que cambió el `.kicad_pcb`, el `.kicad_dru` y 8 archivos de `Drogheda-v6.pretty`. Git ya no mezcla archivos de KiCad (`merge=binary`): si Michelle guarda la v6 sobre su copia anterior y la sube, se pierde uno de los dos trabajos. El orden es: **Leo sube → Michelle hace `git pull --ff-only` → abre la v6.** ## 2. Los 8 bloqueantes del 16-oct, hoy -Medido en el cobre con las zonas rellenadas. «19-oct» = `00a9af4`; «hoy» = `b74b96f` (T25, T28 y T38) con T39. +Medido en el cobre con las zonas rellenadas. «19-oct» = `00a9af4`; «hoy» = `d5f5002` (T25, T28, T38 y T39) con T40. | # | Bloqueante del 16-oct | 19-oct | Hoy | Estado | |---|---|---|---|---| | 1 | U25 con el código del AP64350 | igual | solo C524806 | ✅ T28 | -| 2 | Sin barrenos | sin barrenos | 5 barrenos · MH5, MH6, MH7 y MH8 libres (MH6 con T38, MH8 con T39) · **MH4 con piezas y cobre dentro** (≈ 33 errores) | 🟠 liberar MH4 | +| 2 | Sin barrenos | sin barrenos | **5 barrenos libres**: MH6 con T38, MH8 con T39 y MH4 con T40. En las caras, dentro de 4 mm del centro solo queda GND | ✅ T25 + T38–T40 | | 3 | 5 V por capas internas | `/VEH5V` 12 mm por In1 a 0.5 mm; `/VIN_SW` 22 mm por In2 | `/VEH5V` de L22.2 a R51.1 **de 2 mm por F.Cu** (T39); de R51.1 a RS1 sigue de 1.0 mm, sin vías (meta ≥ 2 mm). La toma de 5 V de R121 ya no va por In1. `/VIN_SW` de RS1 a Q7 **igual**: 22 mm por In2 a 0.5–0.8 mm, con 2 vías; Q7 sigue a 10.6 mm de RS1 | 🟠 mitad | | 4 | Cargador U6 | `/SW_BAT` y `/BAT_PLUS` de 0.5 mm; 1 vía en el EP | `/SW_BAT` de 0.7–0.75 mm (meta: polígono ≥ 2 mm); `/BAT_PLUS` igual; 1 vía en el EP (meta 9) | ❌ | | 5 | Fuente U25 | L22 a 13 mm; EP sin vías | **D34 a 3.52 mm del pin SW** ✅ · L22.1 a 8.79 mm ✅ · nodo SW 9.8 mm² fuera de los pads ✅ · lazo por centros 56.5 mm² con C149 (60.8 con C150) ✅ · 6 vías en el EP y 4 en el ánodo de D34 ✅ · C149 a 0.75 mm de VIN ✅ · C153 y C154 fuera de L22 ✅ · faltan Rig1 (4.79 mm de P1.3) y el `/24V` sin montar | ✅ T39 (con las metas del 21-oct) | | 6 | RF LTE por In1 | 21.9 mm por In1 | igual | ❌ | -| 7 | Vías de GND | 96 (meta ≥ 400) | 116 (T39: 7 nuevas y 2 menos en MH8): 1 bajo U19 y 0 bajo U18; In1 con 1 587 mm de pistas (69 menos) | ❌ | +| 7 | Vías de GND | 96 (meta ≥ 400) | 119 (T39: 7 nuevas y 2 menos en MH8; T40: 4 nuevas y 1 menos): 1 bajo U19 y 0 bajo U18; In1 con 1 595 mm de pistas (T40 le sumó 8 mm de `/SIM_CLK`) | ❌ | | 8 | Stackup genérico | igual | JLC04161H-7628, ENIG, control de impedancia | ✅ T28 | **Lo demás** (bloques C a H: módem, GNSS, U12, pares diferenciales, puertos, In1, serigrafía) no cambió desde el 19-oct. @@ -105,7 +116,7 @@ Después del `git pull`. Primero esto y luego el resto de los bloques A y B del 2. **R53/R54 quedaron abajo de JP2.** Están a 3.4 mm de U6.10 y a 6–7 mm de U6.18, no a ≤ 3 mm: más cerca de U6.18 no hay lugar sin mover piezas del bloque B. 3. **El nodo SW y `/VEH5V` son pistas anchas, no zona** ([§6.3](#63-por-que-pistas-y-no-zona)). - **Para Michelle queda:** MH4 (si T40 no lo resuelve), Rig1 y el `/24V` del bloque A, y luego el bloque B del plan. + **Para Michelle queda:** Rig1 y el `/24V` del bloque A, y luego el bloque B del plan. MH4 ya quedó con T40 ([§7](#7-t40-22-oct-tarde-mh4-libre)); si Leo elige la opción (b) de D-22-4, también las TVS de la SIM junto a J14. ![v6 con T38: courtyards reales, la fuente U25 y los barrenos](img/2026-10-21_Drogheda_v6-T38-Courtyards-U25-Barrenos_v1.0.png) @@ -151,10 +162,10 @@ Después del `git pull`. Primero esto y luego el resto de los bloques A y B del ### 3.2 Barrenos 1. **MH8 (195.2, 135.3):** ✅ ya quedó con T39 (22-oct). D34 salió de ahí y se borraron las 2 vías de GND de (194.6, 133.7) y (196.2, 133.7): 0 errores en MH8. -2. **MH4 (185.2, 90.3):** igual que el 16-oct ([plan, §3.4](v6-plan-fines-de-semana.md#34-barrenos-mh4-y-mh6-1-h)). Claude lo evalúa como T40 (22-oct). La regla nueva hace que el DRC ya muestre todo lo que estorba: ≈ 33 errores con KiCad 10. El número cambia un poco de una corrida a otra; ver el [§6.4](#64-drc-con-t39). - - D23, D24 y D25 junto a J14 y sus resistencias de 22 Ω; - - `/NTC` (In2) a ≥ 2.5 mm del centro; - - `/SIM_RST`, `/SIM_CLK`, `/SIM_DATA` y la pista GND fuera del círculo de 4 mm. +2. **MH4 (185.2, 90.3):** ✅ ya quedó con T40 (22-oct, tarde; [§7](#7-t40-22-oct-tarde-mh4-libre)). Lo que pedía el plan: + - `/NTC` (In2) a ≥ 2.5 mm del centro: ✅ pasa a 2.55 mm del centro, 0.95 mm de la orilla del barreno; + - `/SIM_RST`, `/SIM_CLK`, `/SIM_DATA` y la pista GND fuera del círculo de 4 mm: ✅ en F.Cu y B.Cu solo queda GND; + - D23, D24 y D25 junto a J14 y sus resistencias de 22 Ω: **no**. Salieron del barreno, pero se quedan del lado del módem. Lo decide Leo (D-22-4, [§7.2](#72-las-tvs-de-la-sim-se-quedan-del-lado-del-modem-d-22-4)). 3. **MH6 (65.2, 135.3):** ✅ ya quedó con T38. 4. **No mover los barrenos:** MH4–MH6 son los de la placa base de la V5.5, y MH7 y MH8 son las esquinas de la v6. @@ -168,9 +179,9 @@ Commit y push con el bloque en el mensaje. ## 4. Calendario -El paso del sábado 24 a las 8:00 (Leo corre T25 y T28) ya está hecho, y también MH6, MH8 y la colocación del bloque A (T39). Lo demás del [plan de fines de semana](v6-plan-fines-de-semana.md) sigue igual: +El paso del sábado 24 a las 8:00 (Leo corre T25 y T28) ya está hecho, y también MH6, MH8, la colocación del bloque A (T39) y MH4 (T40). Lo demás del [plan de fines de semana](v6-plan-fines-de-semana.md) sigue igual: -- sábado 24: lo que queda del bloque A (Rig1 y `/24V`) y el bloque B; +- sábado 24: lo que queda del bloque A (Rig1 y `/24V`), el bloque B y, si Leo elige la opción (b) de D-22-4, las TVS de la SIM junto a J14; - domingo 25: bloques C, D y E; - entre semana: T29; - lunes 2-nov: pedido del piloto. @@ -362,17 +373,105 @@ KiCad 10.0.4, `pcb drc --schematic-parity --refill-zones --severity-all --all-tr 3. **Rig1 y el `/24V` sin montar** (pasos 5 y 6 del bloque A) siguen como estaban. 4. **Michelle:** al abrir la v6, revisar el bloque A y ajustar lo que no le guste. En ese bloque el DRC ya está limpio. +## 7. T40 (22-oct, tarde): MH4 libre + +Script: `kicad/tools/t40_v6_mh4.py`. + +- Requiere T39. +- Antes de escribir revisa que ninguna de las piezas y pistas que toca se haya movido. +- Si ya se aplicó, no hace nada. +- Guarda un respaldo `.T40bak`. + +![v6 con T40: el barreno MH4 libre](img/2026-10-22_Drogheda_v6-T40-MH4_v1.0.png) + +### 7.1 Qué cambió + +| Qué | Antes (T39) | Con T40 | +|---|---|---| +| D23 (TVS de `/SIM_DATA`) | (182.7, 90.5): su pad de GND quedaba dentro del barreno y el de `/SIM_DATA` a 3.6 mm del centro | **(179.25, 87.0)**, girado 90°, debajo de U19.31: `/SIM_DATA` llega directo del pin (1.95 mm; antes 7.5 mm de pista) | +| D24 (TVS de `/SIM_CLK`) | (182.7, 88.5), con el barreno dentro de su courtyard | **(188.15, 87.6)**, girado 90°, entre la vía de `/SIM_CLK` y R129/R133 | +| D25 (TVS de `/SIM_RST`) | (182.7, 86.5) | **no se mueve** | +| `/SIM_CLK` | por F.Cu en y = 87.75, a 2.55 mm del centro y dentro de la máscara abierta | baja a **In1** junto a U19.32 y corre en y = 86.7 hasta una vía entre D24 y R129 | +| `/SIM_RST` | por F.Cu en y = 87.25 hasta una vía a 3.94 mm del centro (regla 4.0) | sale de D25 por **F.Cu en y = 85.95**, por arriba de D25 (a 4.2 mm del centro), hasta una vía nueva en (187.05, 85.95); la diagonal de In1 se acorta 0.42 mm | +| `/NTC` (In2) | en y = 89.7: **cruzaba por dentro del barreno** | dobla antes, en (179.8, 87.5), y pasa en y = 87.5: a 0.95 mm de la orilla del barreno | +| Pines 92 y 94 de U19 (GND) | al relleno de F.Cu y a la vía de (183.0, 85.5) | pista de GND de 0.25 mm en y = 85.35, bajo U19.93, y **vía nueva en (186.6, 84.6)** | +| Vías de GND de las TVS | ninguna propia | D23 a 0.8 mm · D24 a 1.1 mm · D25 a 2.3 mm, con pista directa | +| Referencias en serigrafía | D23 y D24 dentro de la máscara de MH4 | D23 a la izquierda de D23, D24 arriba de D24; la de R129 (DNP) pasa a la derecha de R129 para no caer sobre D24 | + +**Por qué los pines 92 y 94 necesitan su pista.** `/SIM_RST` tiene que pasar entre la fila de pines de U19 y D25: más abajo entra en los 4 mm de MH4. El canal que queda (0.8 mm) es muy angosto para el relleno de GND, que pide 0.5 mm de alivio, 0.3 mm de holgura y 0.25 mm de cobre. Sin la pista nueva, los pines 92 y 94 se quedan sin tierra. Por eso también se borró la vía de GND de (183.0, 85.5), que estorbaba a `/SIM_RST`. + +**Holguras más justas de lo nuevo** (regla 0.15 mm): + +- `/SIM_RST` a D25.2: 0.20 mm; +- la pista de GND a U19.93 (BT_ANT, sin conectar): 0.225 mm; +- la vía de GND de D23 a `/CHRG_FAULT` (In1): 0.23 mm; +- `/NTC` a las vías de `/SIM_CLK` y de D25: 0.25 mm. + +### 7.2 Las TVS de la SIM se quedan del lado del módem (D-22-4) + +El plan (L-38, por B-09 del 28-sep) pide **D23–D25 junto a J14**. T40 no lo hace: las saca del barreno, pero las deja junto a U19 (D23 y D25) y junto a R129/R133 (D24). + +- **Por qué no.** En el esquemático, D23–D25 están en `/SIM_DATA`, `/SIM_CLK` y `/SIM_RST`, del lado del módem de las resistencias de 22 Ω. R133 y R134 (las de `/SIM_CLK` y `/SIM_DATA`) están junto a U22, a 13–24 mm de pista de J14, así que esas dos redes no llegan al zócalo. Ponerlas ahí pide una de dos: + - mover también R133 y R134 junto a J14, y volver a rutear las redes; + - o cambiar las TVS a `/SIMB_*` en el esquemático. +- **Qué protege hoy.** Una descarga en el zócalo recorre **27–41 mm de pista**, y pasa por la resistencia de 22 Ω, antes de llegar a la TVS: 28.6 mm en DATA, 27.1 en CLK y 40.6 en RST (antes de T40: 34.1, 32.2 y 41.2). El módem queda protegido, pero el pico entra a la tarjeta y la resistencia lo aguanta completo. +- **Por qué importa.** El 28-sep se dijo que no hacía falta un arreglo de ESD para `/SIM_VDD` porque la SIM se pone una vez, dentro del gabinete, **y** porque D23–D25 iban a quedar junto a J14. La segunda razón ya no se cumple. + +**D-22-4 (decide Leo):** + +- **(a) Se quedan así.** No cuesta nada más y el módem queda protegido. +- **(b) Recomendada: TVS del lado del zócalo.** D23–D25 pasan a `/SIMB_DATA`, `/SIMB_CLK` y `/SIMB_RST`, pegadas a los pines de J14 y cada una con su vía de GND. Son las mismas piezas: el BOM no cambia. Es un cambio chico de esquemático, más la colocación. Claude lo puede hacer como T41 (esquemático y tarjeta por script), o Michelle el sábado. + +Recomiendo (b): la SIM se pone a mano, en el taller o en el sitio, casi siempre sin pulsera antiestática, y un módem dañado es una vuelta al sitio. La TVS tiene que quedar donde entra la descarga. + +### 7.3 DRC con T40 + +| | Con T39 (misma corrida) | Con T40 | +|---|---|---| +| Errores | 43: 13 de holgura de barreno · 17 de máscara · 2 de barreno en courtyard · 11 encimes de margen | **11**: los encimes de margen | +| Sin conectar | 0 | 0 | +| Paridad | 19 PWR_FLAG | 19 PWR_FLAG | +| Avisos | 254 | 249 (5 menos de serigrafía sobre la máscara de MH4) | + +KiCad 10.0.4, `pcb drc --schematic-parity --refill-zones --severity-all --all-track-errors`. En esta corrida, la v6 con T39 dio 13 errores de holgura de barreno en MH4. En la del §6.4 dio 14: el número cambia de una corrida a otra. + +- **Se van 37 violaciones y no entra ninguna.** Son todas las de MH4: holgura de barreno y regla T38, máscara, barreno en el courtyard de D23 y D24, y la serigrafía de D23 y D24. +- **El relleno solo cambia junto a MH4.** Fuera de una ventana de 29 × 24 mm alrededor del barreno, los rellenos de las 4 capas son idénticos a los de T39. +- **Conectividad.** `/SIM_CLK`, `/SIM_RST`, `/SIM_DATA`, `/SIM_VDD` y `/NTC` siguen en un solo grupo cada una. Los pines 29, 92 y 94 de U19 y los pads de GND de las tres TVS quedan unidos a GND: 0 sin conectar y ningún alivio térmico incompleto. + +### 7.4 Cómo se probó y lo que queda a la vista + +**Prueba.** + +- Copia de la v6 con T39 (`97ea7e45`) en la Mac, con su `.kicad_pro`, `.kicad_dru`, esquemático y bibliotecas. T40 en la copia, y DRC de la copia contra la v6 sin T40. +- Antes de escribir, el script revisa: + - la holgura de todo lo nuevo, movido o acortado contra el cobre de las otras redes; + - en todas las capas, 0.25 mm de la orilla del barreno, y la regla de 4 mm en las caras; + - que dentro de 4 mm de MH4, en las caras, ya no quede nada que no sea GND; + - que los courtyards de D23 y D24 no se encimen con nadie ni encierren un barreno; + - que no se pierdan UUIDs. +- **Aplicación.** Se aplicó a la v6 de HBox_PCB y se rellenó con `kicad-cli`, con el proyecto al lado (regla D-22-3). El archivo es idéntico, byte por byte, a la copia probada (`a273d44c`). + +**Lo que queda a la vista:** + +1. **D-22-4:** las TVS junto a J14 ([§7.2](#72-las-tvs-de-la-sim-se-quedan-del-lado-del-modem-d-22-4)). +2. **D25 quedó con su vía de GND a 2.3 mm** (antes había una a 1.25 mm, por el relleno). Ahora llega por una pista directa de 0.4 mm. Más cerca no cabe: arriba pasa `/SIM_RST` y abajo, en In1/In2, `/SIM_CLK` y `/NTC`. +3. **`/SIM_CLK` suma 8.7 mm por In1**, que es plano de tierra. Corre entre el GND de F.Cu y el de In2, y encima, en F.Cu, solo hay pistas de la SIM y de GND. +4. **La pista de GND bajo U19.93** (BT_ANT, sin usar) queda a 0.225 mm de su pad, bajo máscara. + ## Cómo se hizo - **Archivos:** - HBox_PCB `9255b84` (Michelle, 21-oct 18:14) contra `00a9af4` (19-oct). - Para T39: `b74b96f` (22-oct 09:42). + - Para T40: la v6 con T39 (`97ea7e45`, commit `d5f5002`). - El esquemático de la v6 no cambió desde el 28-sep (`d58a89ba…`). -- **Scripts:** primero en una copia y luego en los archivos de HBox_PCB. Los respaldos `.T25bak`, `.T28bak`, `.T38bak` y `.T39bak` no se suben. +- **Scripts:** primero en una copia y luego en los archivos de HBox_PCB. Los respaldos `.T25bak`, `.T28bak`, `.T38bak`, `.T39bak` y `.T40bak` no se suben. - `kicad/tools/t25_mounting_holes_v55.py --set v6`; - `kicad/tools/t28_v6_mecanicos.py`; - `kicad/tools/t38_v6_courtyards_mh.py`; - - `kicad/tools/t39_v6_bloque_a.py`. + - `kicad/tools/t39_v6_bloque_a.py`; + - `kicad/tools/t40_v6_mh4.py`. - **DRC:** KiCad 10.0.4, `pcb drc --schematic-parity --refill-zones --severity-all`, con el `.kicad_dru` del proyecto. - **Medidas:** - El script de la auditoría del 16-oct sobre el cobre rellenado: distancias, series de cobre, vías por red y por EP, y lazo por centros de pad. diff --git a/docs/hardware/v6-plan-fines-de-semana.md b/docs/hardware/v6-plan-fines-de-semana.md index 76ad2c6..dbad304 100644 --- a/docs/hardware/v6-plan-fines-de-semana.md +++ b/docs/hardware/v6-plan-fines-de-semana.md @@ -4,8 +4,8 @@ tags: [project-drogheda, hardware, hbox, einarboard, v6, plan, layout, firmware, project: Project Drogheda author: Helgen Technologies (plan: Claude; revisión: Leo) date: 2026-10-16 -version: 1.4 -status: ACTIVO — rev. 1.1 (19-oct): recorrido una semana; empieza el sábado 24-oct a las 8:00 · 21-oct: T25 y T28 ya aplicados · 21-oct noche: T38 aplicado y metas del bloque A corregidas (§3.1) · 22-oct: T39 hizo la colocación del bloque A y liberó MH8 +version: 1.5 +status: ACTIVO — rev. 1.1 (19-oct): recorrido una semana; empieza el sábado 24-oct a las 8:00 · 21-oct: T25 y T28 ya aplicados · 21-oct noche: T38 aplicado y metas del bloque A corregidas (§3.1) · 22-oct: T39 hizo la colocación del bloque A y liberó MH8 · 22-oct, tarde: T40 liberó MH4 audience: Leo, Michelle (layout), Jesús (banco), Aldair (fabricación), Adriana (PM) --- @@ -35,6 +35,14 @@ audience: Leo, Michelle (layout), Jesús (banco), Aldair (fabricación), Adriana Del §3.1 solo quedan Rig1 (paso 5) y el `/24V` sin montar (paso 6). Del §3.2, el paso 6 quedó a medias: R53/R54 ya están junto a U6, pero a 6–7 mm de U6.18. El sábado 24 empieza con eso y con el bloque B. +!!! success "Rev. 1.5 (22-oct, tarde): T40 liberó MH4" + **T40 sacó de MH4 todo lo que no era GND** ([estado de la v6, §7](v6-estado-21oct.md#7-t40-22-oct-tarde-mh4-libre)). Con eso, los 5 barrenos están libres y el DRC de la v6 solo tiene los 11 encimes de courtyard que son de margen. + + - D23 quedó debajo de U19.31 y D24 junto a R129/R133. D25 no se movió, y las tres tienen vía de GND propia. + - `/SIM_CLK` va por In1, `/SIM_RST` por arriba de D25 y `/NTC` rodea el barreno. + + **Lo que no hace:** llevar D23–D25 junto a J14 (§3.4, por B-09/L-38). Leo decide (D-22-4): (a) se quedan del lado del módem, o (b) se pasan a `/SIMB_*`, pegadas al zócalo. Claude recomienda (b). + **Dos metas:** | Meta | Qué significa | Fecha objetivo | @@ -59,7 +67,7 @@ audience: Leo, Michelle (layout), Jesús (banco), Aldair (fabricación), Adriana | Día | Quién | Qué | Listo cuando | |---|---|---|---| | **Sáb 24-oct, 8:00** | Leo | Correr T25 `--set v6` + T28 y subir (§2). **Ya se corrieron el 21-oct: falta el push** | push hecho; Michelle avisada | -| **Sáb 24-oct** | Michelle | **Bloques A + B:** el camino de la energía (U25, RS1, Q7, U6, L6) + liberar MH4 y MH6 (§3) | criterios del §3.5 | +| **Sáb 24-oct** | Michelle | **Bloques A + B:** el camino de la energía (U25, RS1, Q7, U6, L6). MH4, MH6 y MH8 ya quedaron (T38–T40); las TVS de la SIM junto a J14 si Leo elige (b) en D-22-4 (§3) | criterios del §3.5 | | **Dom 25-oct** | Michelle | **Bloque C:** módem (RF LTE, U20, VBAT). **Bloque D:** GNSS. **Bloque E:** U12 (§4) | criterios del §4.4 | | **Dom 25-oct, noche** | Claude | Re-auditoría del commit del domingo; lista corta para el lunes | lista enviada | | **Lun 26 – vie 30** | Leo / Adriana | Decisiones D-v6-1…6 y cotización (§5). Las **pre-órdenes en JLC** no esperan: lun 19 o mar 20-oct | pre-órdenes pagadas | @@ -165,10 +173,10 @@ Qué cambia T28: U25 sin el código del AP64350 · pasta del EP de U6 al 50 % · ![Barrenos: qué hay que mover en MH4 y MH6](img/2026-10-16_Drogheda_v6-Barrenos_v1.0.png) -1. **MH4 (185.2, 90.3):** - - Llevar **D23, D24 y D25** (ESD de la SIM) junto a J14 y sus resistencias de 22 Ω (R131–R134): ahí deben ir de todos modos (B-09) y así salen del barreno. - - Desviar `/NTC` (In2) a **≥ 2.5 mm del centro**. - - Sacar `/SIM_CLK`, `/SIM_RST` y la pista GND del **círculo de 4 mm**. +1. **MH4 (185.2, 90.3):** ✅ con T40 (22-oct, tarde; [estado, §7](v6-estado-21oct.md#7-t40-22-oct-tarde-mh4-libre)). + - Desviar `/NTC` (In2) a **≥ 2.5 mm del centro**: ✅ a 2.55 mm, 0.95 mm de la orilla del barreno. + - Sacar `/SIM_CLK`, `/SIM_RST` y la pista GND del **círculo de 4 mm**: ✅ en las caras solo queda GND. + - Llevar **D23, D24 y D25** (ESD de la SIM) junto a J14 y sus resistencias de 22 Ω (B-09): **queda abierto.** T40 las sacó del barreno, pero del lado del módem. Leo decide D-22-4 ([estado, §7.2](v6-estado-21oct.md#72-las-tvs-de-la-sim-se-quedan-del-lado-del-modem-d-22-4)): (a) se quedan así, o (b) se pasan a `/SIMB_*`, pegadas a J14, con su vía de GND (recomendada; T41 o Michelle el sábado). 2. **MH6 (65.2, 135.3):** ✅ ya quedó con T38 (21-oct, noche): `/3V3` por B.Cu, a 4.06 mm del centro. Si la rondana no cabe, correr H4 1 mm al este. 3. **MH8 (195.2, 135.3):** ✅ con T39 (22-oct): D34 salió de ahí y se borraron las 2 vías de GND de (194.6, 133.7) y (196.2, 133.7). 4. **Regla nueva (T38):** el DRC ya marca cualquier cobre que no sea GND a menos de 4 mm del centro de un barreno, en F.Cu y B.Cu. En MH4 marca también `/SIM_DATA`. @@ -176,7 +184,7 @@ Qué cambia T28: U25 sin el código del AP64350 · pasta del EP de U6 al 50 % · ### 3.5 Cierre del sábado -- [ ] DRC: **0 errores** y 0 sin conectar. Los de MH8 y el encime de C153 con L22 ya se fueron con T39; faltan los ≈ 33 de MH4. Solo quedan los encimes de courtyard que son de margen: se excluyen al final ([estado, §3.3](v6-estado-21oct.md#33-cierre)). +- [ ] DRC: **0 errores** y 0 sin conectar. Los de MH8 y el encime de C153 con L22 ya se fueron con T39, y los de MH4 con T40. Solo quedan los encimes de courtyard que son de margen: se excluyen al final ([estado, §3.3](v6-estado-21oct.md#33-cierre)). - [ ] Ningún aviso de ancho de pista en `/VEH5V`, `/VIN_SW`, `/MAIN5V`, `/SW_BAT`, `/BAT_PLUS`, `/VIN_PROT`. - [ ] Nada de potencia en In1/In2 entre L22, RS1, Q7, U6, L6 y P3. - [ ] Vías: EP de U6 = 9, EP de U25 = 6, D34 ≥ 4. diff --git a/docs/inicio/inicio.js b/docs/inicio/inicio.js index 90c7788..9dd3dee 100644 --- a/docs/inicio/inicio.js +++ b/docs/inicio/inicio.js @@ -266,17 +266,32 @@ if (COLOR[s.estado]) a.append(el('span', { class: 'vh', text: ' (' + COLOR[s.estado].toLowerCase() + ')' })); const estado = el('span', { class: 'in-gris', text: s.nota || '' }); li.append(a, estado); - if (s.meta) li.append(el('span', { class: 'in-sit-meta', text: 'Meta: ' + s.meta })); + if (s.meta) li.append(el('a', { class: 'in-sit-meta', href: '/tableros/instalaciones/?sitio=' + encodeURIComponent(s.id), title: 'Instalaciones de ' + s.nombre, text: 'Meta: ' + s.meta + ' · ver instalaciones' })); ul.append(li); return estado; }; + // Conteos por sitio: los mismos del tablero de Instalaciones (solo las probadas cuentan para la meta). + // Si el servicio todavía no tiene /api/instalaciones (falta reiniciar actas-hbox), se usa el conteo anterior. + const porSitio = json('/api/instalaciones').then(j => j.resumen || {}).catch(() => null); + const conteoAnterior = (s, estado) => json('/api/sitio/unidades?id=' + encodeURIComponent(s.id)).then(j => { + const n = j.total_unidades || 0, inst = (j.unidades || []).filter(u => u.instalada).length; + const partes = []; + if (s.nota) partes.push(s.nota); + partes.push(n ? plural(n, 'unidad con actas', 'unidades con actas') + ', ' + (inst ? plural(inst, 'instalada', 'instaladas') : 'ninguna instalada') : 'sin unidades registradas'); + estado.textContent = partes.join(' · '); + }); (P.sitios || []).forEach(s => { const estado = fila(s); - json('/api/sitio/unidades?id=' + encodeURIComponent(s.id)).then(j => { - const n = j.total_unidades || 0, inst = (j.unidades || []).filter(u => u.instalada).length; + porSitio.then(R => { + if (!R) return conteoAnterior(s, estado); + const r = R[s.id] || {}; const partes = []; if (s.nota) partes.push(s.nota); - partes.push(n ? plural(n, 'unidad con actas', 'unidades con actas') + ', ' + (inst ? plural(inst, 'instalada', 'instaladas') : 'ninguna instalada') : 'sin unidades registradas'); + if (r.unidades) { + let t = plural(r.instaladas || 0, 'instalada', 'instaladas') + ', ' + plural(r.probadas || 0, 'probada', 'probadas'); + if (r.falla) t += ', ' + plural(r.falla, 'con falla', 'con falla'); + partes.push(t); + } else partes.push('sin unidades registradas'); estado.textContent = partes.join(' · '); }).catch(() => { estado.textContent = s.nota || ''; }); }); diff --git a/docs/tableros/actividad.js b/docs/tableros/actividad.js index 103256a..8d06947 100644 --- a/docs/tableros/actividad.js +++ b/docs/tableros/actividad.js @@ -10,7 +10,7 @@ 'prueba-v5': 'tarjeta V5', 'prueba-v4': 'tarjeta V4', 'modulo-ard': 'ArduSimple', 'modulo-4g': 'módem 4G', 'integracion': 'integración', 'ensamble': 'ensamble', 'reflasheo': 'reflasheo', 'prueba-ethernet-serie': 'Ethernet y serie', 'envio': 'envío', 'recepcion': 'recepción', 'instalacion-campo': 'instalación', 'diagnostico-campo': 'diagnóstico en campo', - 'diagnostico-banco': 'diagnóstico en banco', 'dano': 'daño', 'prueba-bateria-modem': 'prueba de batería del módem' + 'diagnostico-banco': 'diagnóstico en banco', 'dano': 'daño', 'prueba-bateria-modem': 'prueba de batería del módem', 'prueba-sitio': 'prueba en sitio' }; const CAMPOS = { titulo: 'el título', descripcion: 'la descripción', pista: 'la pista', responsable: 'el responsable', fecha_limite: 'la fecha', version_tarjeta: 'la tarjeta', enlaces: 'las ligas', etiquetas: 'las etiquetas', diff --git a/docs/tableros/index.md b/docs/tableros/index.md index 4216e97..fb2c8e7 100644 --- a/docs/tableros/index.md +++ b/docs/tableros/index.md @@ -15,6 +15,7 @@ Las páginas que abres para saber **dónde está el proyecto hoy**: qué pendien | **Cuántas unidades** llevamos y cuántas faltan | [Producción](produccion.md) | Plan 113 V5.6 · 327 V5.7 · 130 v6 contra las unidades reales por etapa; embudo por paso; bloqueos; alertas de inventario | | Qué **tarjeta, módulo o unidad** pasó cada acta | [Actas](actas.md) | Series V5-NN, ARD-NNN, RTK-NNNN y V4-NN; parejas integradas; unidades ensambladas. Pendiente = liga al acta | | Qué **material** hay y qué falta | [Inventario](inventario.md) | Existencias, mínimos y cada movimiento con quién y por qué | +| En qué **vehículo** está cada unidad y si ya pasó la **prueba en sitio** | [Instalaciones](instalaciones.md) | Una tarjeta por unidad en cada sitio: enviada, recibida, instalada, probada en sitio y en operación, más «con falla»; vehículo (número económico, tipo, 12/24 V), sus actas y el botón de la siguiente acta. Solo las probadas cuentan para la meta de 1–2 por sitio | | Qué hay **en cada puerto** | [Sitios](sitio.md) | Unidades instaladas, envíos, diagnósticos, daños y contactos de ICAVE, LCT, EIT y TIMSA | | Qué se acordó en las **juntas** (standup y quick wins) | [Juntas](juntas.md) | La agenda fija, la cadencia y el registro de cada junta con su lote | | **Quién es quién** | [Equipo](equipo.md) | Miembros, área, acceso al sitio y pendientes abiertos y vencidos de cada quien. El administrador crea aquí los accesos | diff --git a/docs/tableros/ingenieria.md b/docs/tableros/ingenieria.md index 56afa19..eda42b0 100644 --- a/docs/tableros/ingenieria.md +++ b/docs/tableros/ingenieria.md @@ -37,6 +37,9 @@ hide:

    Últimas decisiones

    Lo decidido manda hasta que otra decisión con fecha posterior lo cambie. Fuente: notas del proyecto; detalle en la sección de hardware.