meta로 NEEO 드라이버 만들기
meta(jac459/meta)는 active/ 폴더 안의 JSON 디바이스 파일을 읽어 각 파일을 NEEO SDK 드라이버로 바꾸고 로컬 NEEO Brain에 등록하는 Node.js 엔진입니다. 디바이스를 JSON으로 기술하면 됩니다. JavaScript는 작성하지 않습니다(작은 DYNAMIK 표현식 제외).
언어: 사용자에게는 사용자의 언어로 작성하세요. JSON 키, 엔진 키워드, 버튼 이름, 로그 문자열은 여기에 문서화된 그대로(영어) 유지합니다.
범위: 인수 이전 NEEO SDK, 로컬 Brain, meta만 중요합니다. Control4 자료와 NEEO 클라우드(종료)는 무시합니다.
기본 규칙(절대 생략 금지)
- JSON 키나 명령 유형을 절대 임의로 만들지 마세요. 레퍼런스에 기능이 없으면 그렇게 말하고 대안을 제시하세요: 컴패니언 서비스(Node-RED + MQTT 또는 작은 로컬 REST 브리지,
references/companion-services.md참조),cli명령, 또는 숨겨진 버튼 체인. - 순수 JSON: 주석 없음, 후행 쉼표 없음, 큰따옴표 사용.
python3 -m json.tool file.json과python3 scripts/check_driver.py file.json으로 검증하세요. - 명령 유형은 대소문자 구분:
http-get,http-rest,http-post,http-get-soap,static,cli,repl,webSocket,socketIO,jsontcp,mqtt,wol,mDNS,android. version을 올리세요 화면에 보이는 구성 요소가 추가될 때마다. Brain은 구성 요소를 추가만 합니다. 이름을 바꾸거나 삭제하려면 NEEO 앱에서 디바이스를 삭제하고 다시 추가해야 합니다(레시피와 바로 가기도 다시 만들어야 함). 설치된 디바이스에서는 버전을 올려도 충분하지 않을 때가 있습니다. Brain을 확인하세요(references/debugging.md).- 라벨, 스위치, 슬라이더, 이미지, 센서의 이름(키): 글자와 숫자만 사용. 공백이나 기호는 센서 링크를 깨뜨립니다(Brain에서
"sensor": null). 바로 가기로 사용되는 구성 요소는 리모컨이 동기화 시 충돌합니다. 표시되는label텍스트는 자유롭게. 버튼 이름에는 공백이 허용되지만+와 악센트는 피하세요(DISNEY PLUS, 레이블Disney+). - 라벨에 바인딩된 변수에
""를 절대 쓰지 마세요: meta v1.2.0에서 라벨이 텍스트에서""로 돌아가면 meta가 멈춥니다." "(또는 읽을 수 있는 대체 텍스트)를 쓰세요. 라벨 변수도" "로 초기화하는 습관을 들이세요. - 외부 텍스트가 라벨에 도달하기 전에 반드시 정화하세요:
"->',\->/, 제어 문자 -> 공백,$->$(전각). 드라이버와 소스 모두에서 하세요. - 리스너는 세션당 한 번
ListenerOn가드 + 모든 보이는 컨트롤에 연결된 숨겨진__LISTEN버튼을 통해 시작됩니다.POWER ON만으로는 절대 충분하지 않으며,mqtt리스너에서__CLEANUP을 절대 호출하지 마세요(references/listeners-and-state.md). - 폴링보다 이벤트(
webSocket,socketIO,mqtt). 폴링해야 한다면pooltime>=3000. $Result는 항상 문자열, 실패 시"undefined": 모든JSON.parse를 보호하세요. 버튼은 스칼라(ok)를 받고, 디렉터리 액션 피더는["ok"]를 받습니다.- 변수 이름: 다른 변수 이름의 접두사가 되는 이름을 절대 사용하지 마세요.
$Var가 문자에 붙으면 다른 변수로 읽힙니다. - 보안:
DYNAMIK와cli는 meta 호스트에서 코드를 실행합니다. 공유할 드라이버에 비밀을 하드코딩하지 마세요. meta는 root/관리자 권한으로 실행되어서는 안 됩니다. - 되돌릴 수 없는 변경은 동의 필요: 보이는 구성 요소(예:
DIGIT 0-9)를 추가하는 것은 디바이스를 재설치하지 않고는 되돌릴 수 없습니다. 먼저 물어보세요. - 결과물 구분: meta 드라이버는 JSON 객체(
{로 시작, 이름에-flow없음,active/에 넣음)입니다. Node-RED 플로우는 JSON 리스트([로 시작, 항상*-flow.json이름, Node-RED에 임포트). template에서dynamicname과dynamicid는 필수입니다.dynamicid는 안정적이어야 합니다(DHCP IP 대신 MAC 주소나 하드웨어 ID).
워크플로우
- 필요한 정보 수집(한 번에 최대 3개의 집중 질문): 정확한 디바이스 모델; 제어 프로토콜 또는 API(HTTP/REST, WebSocket, raw TCP, MQTT, IR 전용, Android TV...); 고정 IP 여부와 안정적인 ID(MAC); 제어해야 할 것과 표시해야 할 상태; meta 버전과 실행 위치(Pi + pm2, Docker...); MQTT 브로커와 Node-RED 사용 가능 여부. 가능하면 디바이스 공식 API 문서를 찾으세요.
- NEEO 타입 선택(
references/driver-anatomy.md, 섹션 types and recognized buttons)과 디스커버리 패턴(references/discovery.md): 고정 단일 디바이스, 사용자 입력 IP, mDNS, 또는 허브. assets/의 스켈레톤에서 시작:skeleton-static.json(고정 주소 단일 디바이스) 또는skeleton-register-ip.json(사용자가 IP 입력).references/patterns.md의 검증된 패턴을 재사용하세요.- 로직 위치 결정. 간단한 HTTP 또는 WebSocket 디바이스: 드라이버 내에 모든 것. 바이너리 또는 상태 저장 프로토콜(raw TCP, 영구 세션, 페어링, 버스트 상태): 중간에 컴패니언 서비스를 두고 빠른 HTTP 명령과 보존 MQTT 메시지로 상태 전송(
references/companion-services.md). - 전달 전 확인:
python3 -m json.tool driver.json다음python3 scripts/check_driver.py driver.json(이름, 빈 라벨 값, 타입, 버전, 가드, 폴링...);- 리스너가 있는 드라이버는
node scripts/simulate_guard.js driver.json(세션 간__INITIALISE/__CLEANUP카운트); - 까다로운
DYNAMIK표현식은 실제 치환 규칙으로 Node에서 평가(references/logic-and-commands.md); references/pitfalls.md를 다시 읽으세요.
- 다음 순서로 전달: 요약(디바이스, 프로토콜, NEEO 타입, 디스커버리 패턴, 포함/미포함); 명시적 파일명과 함께 완전한 검증된 JSON 파일; 배포 단계(
active/에 복사, meta 재시작, NEEO 앱에서 디바이스 추가, 레시피 표시 및 바로 가기 생성); 테스트 계획(시도할 버튼, 예상 결과, 확인할 로그 라인); 실제 디바이스에서 확인하지 않은 가정; 다음 반복. 여러 파일 프로젝트(드라이버 + 플로우 + 서비스)의 경우: 작업 순서, 각 결과물의 버전 표시, 설치된 버전 확인 방법. 실제 디바이스에서 테스트하지 않은 내용을 항상 말하세요.
레퍼런스 맵(작업에 필요한 것만 읽기)
| 파일 | 읽어야 할 때 |
|---|---|
references/meta-engine.md | 아키텍처, 설치, 폴더, 재시작, 로그 레벨, meta가 노출하는 MQTT 토픽, Docker/NAS 호스팅, 알려진 meta v1.2.0 버그 |
references/driver-anatomy.md | 최상위 키, NEEO 디바이스 타입과 인식되는 버튼 이름, 변수, $ 치환, DYNAMIK, UI 구성 요소 |
references/logic-and-commands.md | evalwrite, evaldo, evalnext, 특수 버튼, 모든 명령 유형, queryresult / JSONPath |
references/listeners-and-state.md | 리스너, ListenerOn 가드, MQTT 리스너 동작, 버스트 상태 소스, 인스턴스 재구축 |
references/discovery.md | discover, register, template, initcommandset, mDNS, IP 입력, 허브, 페어링 |
references/directories.md | 목록, 피더, item* 필드, 액션, 다중 레벨 탐색 |
references/patterns.md | 검증된 레시피: 볼륨, 전원, 상태 표시줄, 지속성, 체인, 루프, 대체 경로, 앱 런처, 아트워크 이미지 |
references/pitfalls.md | 전달 전 반드시 다시 읽어야 함 |
references/debugging.md | meta, Mosquitto, Brain 데이터 읽기, 로그 시그니처, 링크 분리, 샌드박스 테스트 |
references/companion-services.md | Node-RED 및 MQTT 브리지, 로컬 REST 브리지, Apple TV / pyatv 교훈 |
references/community-drivers.md | 모방할 레퍼런스 드라이버, SDK <-> meta 매핑, 소스 |
레퍼런스에 사용된 증거 태그
[code v1.2.0] meta 소스 코드(브랜치 Release)에서 읽음; [observed] 실제 드라이버나 실제 설치에서 확인; [to verify] 아직 테스트되지 않은 추론. 태그가 없고 동작이 중요한 경우, 추측보다 meta 코드를 확인(git clone --depth 1 --branch Release https://github.com/jac459/meta)하고 어떤 방법을 사용했는지 말하세요.