Drivers NEEO con meta
meta (jac459/meta) es un motor Node.js que lee archivos JSON de dispositivos de su carpeta active/ y convierte cada uno en un driver del SDK de NEEO registrado con el cerebro NEEO local. Describes el dispositivo en JSON; no escribes JavaScript (excepto pequeñas expresiones DYNAMIK).
Idioma: escribe al usuario en su idioma. Las claves JSON, palabras clave del motor, nombres de botones y cadenas de registro se mantienen exactamente como están documentadas aquí (inglés).
Alcance: solo importan el SDK de NEEO previo a la adquisición, el cerebro local y meta. Ignora el material de Control4 y la nube de NEEO (cerrada).
Reglas básicas (nunca omitir)
- Nunca inventes una clave JSON o tipo de comando. Si una característica no está en las referencias, indícalo y ofrece una alternativa: un servicio acompañante (Node-RED + MQTT, o un pequeño puente REST local, ver
references/companion-services.md), un comandocli, o una cadena de botones ocultos. - JSON puro: sin comentarios, sin comas finales, comillas dobles. Valida con
python3 -m json.tool archivo.jsonypython3 scripts/check_driver.py archivo.json. - Los tipos de comando distinguen mayúsculas y minúsculas:
http-get,http-rest,http-post,http-get-soap,static,cli,repl,webSocket,socketIO,jsontcp,mqtt,wol,mDNS,android. - Incrementa
versioncada vez que se añada un componente visible. El cerebro solo añade componentes; renombrar o eliminar uno requiere borrar y volver a añadir el dispositivo en la app NEEO (las recetas y accesos directos deben rehacerse). Incluso un incremento a veces no es suficiente en un dispositivo instalado: consulta el cerebro (references/debugging.md). - Nombres (claves) de etiquetas, interruptores, deslizadores, imágenes y sensores: solo letras y dígitos. Un espacio o símbolo rompe el enlace del sensor (
"sensor": nullen el cerebro) y el mando se bloquea al sincronizar en cuanto el componente se usa como acceso directo. El textolabelmostrado es libre. Los nombres de botones pueden contener espacios, pero evita+y acentos (DISNEY PLUS, etiquetaDisney+). - Nunca escribas
""en una variable vinculada a una etiqueta: en meta v1.2.0, una etiqueta que pasa de un texto a""detiene meta. Escribe" "(o un texto legible de respaldo). Inicializa también las variables de etiqueta con" ", como hábito. - Desinfecta todo texto externo antes de que llegue a una etiqueta:
"->',\->/, caracteres de control -> espacio,$->$(ancho completo). Hazlo tanto en el driver como en la fuente. - Los listeners se inician una vez por sesión, mediante el guardia
ListenerOn+ el botón oculto__LISTENconectado a cada control visible. Nunca confíes solo enPOWER ON, y nunca llames a__CLEANUPen un listenermqtt(references/listeners-and-state.md). - Eventos sobre sondeo (
webSocket,socketIO,mqtt). Si se sondea,pooltime>=3000. $Resultsiempre es una cadena,"undefined"en caso de fallo: protege todoJSON.parse. Un botón obtiene un escalar (ok); un alimentador de acción de directorio obtiene["ok"].- Nombres de variables: nunca uses un nombre que sea prefijo de otro;
$Varpegado a letras se lee como una variable diferente. - Seguridad:
DYNAMIKycliejecutan código en el anfitrión de meta. No hay secretos codificados en un driver destinado a compartirse; meta no debe ejecutarse como root/admin. - Los cambios irreversibles necesitan consentimiento: añadir componentes visibles (p. ej.
DIGIT 0-9) no se puede deshacer sin reinstalar el dispositivo. Pregunta primero. - Entregables separados: un driver de meta es un objeto JSON (empieza con
{, nunca-flowen su nombre, va enactive/); un flujo Node-RED es una lista JSON (empieza con[, siempre nombrado*-flow.json, importado en Node-RED). - En
template,dynamicnameydynamicidson obligatorios;dynamiciddebe ser estable (dirección MAC o ID de hardware en lugar de una IP DHCP).
Flujo de trabajo
- Recopila lo que necesitas (haz como máximo 3 preguntas específicas a la vez): modelo exacto del dispositivo; su protocolo de control o API (HTTP/REST, WebSocket, TCP sin procesar, MQTT, solo IR, Android TV...); IP fija o no y un ID estable (MAC); qué debe controlarse y qué estado debe mostrarse; versión de meta y dónde se ejecuta meta (Pi con pm2, Docker...); si hay disponible un broker MQTT y Node-RED. Busca la documentación oficial de la API del dispositivo cuando exista.
- Elige el tipo NEEO (
references/driver-anatomy.md, sección tipos y botones reconocidos) y el patrón de descubrimiento (references/discovery.md): dispositivo único estático, IP introducida por el usuario, mDNS o hub. - Empieza desde un esqueleto en
assets/:skeleton-static.json(un dispositivo, dirección fija) oskeleton-register-ip.json(el usuario escribe la IP). Reutiliza patrones probados dereferences/patterns.md. - Decide dónde reside la lógica. Dispositivo HTTP o WebSocket simple: todo en el driver. Protocolo binario o con estado (TCP sin procesar, sesiones persistentes, emparejamiento, estado rápido): coloca un servicio acompañante entre medias, con comandos HTTP rápidos y estado enviado como un mensaje MQTT retenido (
references/companion-services.md). - Verifica antes de entregar:
python3 -m json.tool driver.jsonluegopython3 scripts/check_driver.py driver.json(nombres, valores de etiqueta vacíos, tipos, versión, guardia, sondeo...);node scripts/simulate_guard.js driver.jsoncuando el driver tenga listeners (cuenta__INITIALISE/__CLEANUPentre sesiones);- evalúa expresiones
DYNAMIKcomplicadas en Node con las reglas de sustitución reales (references/logic-and-commands.md); - vuelve a leer
references/pitfalls.md.
- Entrega en este orden: resumen (dispositivo, protocolo, tipo NEEO, patrón de descubrimiento, cubierto / no cubierto); el archivo JSON completo y validado con un nombre de archivo explícito; pasos de implementación (copiar a
active/, reiniciar meta, añadir el dispositivo en la app NEEO, visibilidad de recetas y accesos directos a crear); plan de pruebas (botones a probar, resultado esperado, líneas de registro a buscar); suposiciones no verificadas en el dispositivo real; siguiente iteración. Para proyectos de múltiples archivos (driver + flujo + servicio): orden de operaciones, un marcador de versión en cada entregable y cómo comprobar qué versión está instalada. Siempre di qué no se probó en el dispositivo real.
Mapa de referencias (lee solo lo que necesite la tarea)
| Archivo | Leer cuando |
|---|---|
references/meta-engine.md | Arquitectura, instalación, carpetas, reinicio, niveles de registro, temas MQTT expuestos por meta, alojamiento Docker/NAS, errores conocidos de meta v1.2.0 |
references/driver-anatomy.md | Claves de nivel superior, tipos de dispositivo NEEO y nombres de botones reconocidos, variables, sustitución $, DYNAMIK, componentes de interfaz de usuario |
references/logic-and-commands.md | evalwrite, evaldo, evalnext, botones especiales, cada tipo de comando, queryresult / JSONPath |
references/listeners-and-state.md | Listeners, el guardia ListenerOn, comportamiento del listener MQTT, fuentes de estado rápidas, reconstrucciones de instancia |
references/discovery.md | discover, register, template, initcommandset, mDNS, entrada de IP, hubs, emparejamiento |
references/directories.md | Listas, alimentadores, campos item*, acciones, navegación multinivel |
references/patterns.md | Recetas probadas: volumen, encendido, barra de estado, persistencia, cadenas, bucles, ruta de respaldo, lanzador de apps, imagen de carátula |
references/pitfalls.md | Relectura obligatoria antes de entregar |
references/debugging.md | Lectura de datos de meta, Mosquitto y el cerebro, firmas de registro, aislamiento de un enlace, pruebas en espacio aislado |
references/companion-services.md | Puentes Node-RED y MQTT, puentes REST locales, lecciones de Apple TV / pyatv |
references/community-drivers.md | Drivers de referencia para imitar, mapeo SDK <-> meta, fuentes |
Etiquetas de evidencia utilizadas en las referencias
[código v1.2.0] leído en el código fuente de meta (rama Release); [observado] visto en drivers reales o instalaciones reales; [por verificar] deducción aún no probada. Cuando un comportamiento sea relevante y no esté etiquetado, comprueba el código de meta (git clone --depth 1 --branch Release https://github.com/jac459/meta) en lugar de adivinar, y di cuál has hecho.