Files
homeclaw/.claude/plans/arduino-sensors-plan.md
T
kimandClaude Opus 5 e85ebe6608 v4.3.20: 미커밋 자산 일괄 정리 + 유저 워크스페이스/세션토큰 gitignore
그동안 쌓여 있던 미커밋 파일들을 정리. 소스·자산만 올리고, 개인 데이터와
런타임 상태는 gitignore로 차단.

추가된 자산:
- web-ui/audiomass, web-ui/wavacity — 자체 호스팅 오디오 에디터
- web-ui/drums — 드럼 샘플
- wol-gate — WOL 프록시 컨테이너(Dockerfile + server.js)
- glm-1m-fix — GLM 1M 컨텍스트 설치 스크립트(linux/windows)
- RENODE_FIXES_SUMMARY*.md, CCTV정보_서울특별시.csv, .claude/plans

수정:
- edge_tts_synth.py: rate 인자 추가(말하기 속도 조절)
- .smallclaw/config.json: google(gemini) provider 등록 — 키는 vault 참조
- assets/SmallClaw*.png 삭제분 반영

gitignore (중요):
- .smallclaw/users/*/workspace/ 전체 차단. 기존 패턴이 memory/uploads와 일부
  확장자만 막아서 detective/(고소장·통화녹취·의사소견서·가족관계증명서),
  generated-media/, music/, pptx/ 등 앱 생성 개인 데이터 403MB가 노출돼 있었음
- .smallclaw/active-sessions.json 차단 — 살아있는 bearer 토큰과 admin 역할이
  평문으로 들어있어 커밋 시 게이트웨이 관리자 자격증명이 그대로 공개됨
- google-usage.json, config.json.bak-*, workspace/memory·weather-maps·
  task_result_*, voice/ 등 런타임 상태도 함께 차단

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 14:55:37 +09:00

6.8 KiB

Arduino 에뮬레이터 센서/액추에이터 추가 계획

목표

web-ui/arduino-emulator.html과 src/gateway/server-v2.ts에 다음 5가지 부품의 시뮬레이션을 순서대로 추가한다.

  1. MPU-6050 (I2C 6축 IMU)
  2. BME280 (I2C 온도/습도/기압)
  3. DS18B20 (1-Wire 온도)
  4. 릴레이 모듈 (GPIO 스위칭)
  5. L298N 모터 드라이버 (GPIO DC 모터)

적용 대상 에뮬레이터

  • ESP32 QEMU (src/gateway/server-v2.ts QEMU 경로)
  • ESP8266 native (src/gateway/server-v2.ts g++ native 경로)
  • **AVR8js (UNO/Nano)**는 시뮬레이션 회로도(SCH)에서 DHT 연결 감지 패턴을 확장하여 일부 지원.

1단계: 공통 인프라 확장

1.1 백엔드 프로토콜 추가 (_parsePtyGpio)

\x02 프리픽스 명령어를 추가하여 SSE로 브로드캐스트.

명령어 의미 SSE 페이로드
IMU:<sda>:<scl>:<addr> MPU-6050 초기화 {imu:{sda,scl,addr}}
IMV:<addr>:<ax>:<ay>:<az>:<gx>:<gy>:<gz>:<temp> IMU 값 변경 {imu_values:{addr,ax,ay,az,gx,gy,gz,temp}}
BMU:<sda>:<scl>:<addr> BME280 초기화 {bme:{sda,scl,addr}}
BMV:<addr>:<t>:<h>:<p> BME 값 변경 {bme_values:{addr,t,h,p}}
OWI:<pin> OneWire/DS18B20 초기화 {onewire:{pin}}
OWV:<pin>:<t> DS18B20 온도 {ds18b20:{pin,t}}
RLY:<pin>:<state> 릴레이 상태 {relay:{pin,state}}
MOT:<enA>:<in1>:<in2>:<in3>:<in4>:<enB> L298N 핀 설정 {motor:{enA,in1,in2,in3,in4,enB}}
MST:<enA>:<in1>:<in2>:<in3>:<in4>:<enB> L298N 상태 갱신 {motor_state:{...}}

1.2 값 주입 엔드포인트 추가

/api/arduino/qemu/:id/imu, /esp8266/:id/imu 등 POST 엔드포인트를 추가하여 stdin/serial로 \x02ISET:<addr>:..., \x02BSET:..., \x02OSET:... 주입.

2단계: MPU-6050 (I2C)

2.1 백엔드

  • Wire.h 모의 라이브러리를 강화: beginTransmission(addr), requestFrom(addr, qty)가 감지되면 \x02IMU:<sda>:<scl>:<addr>\n 출력.
  • MPU6050.h 모의 라이브러리 추가 (또는 MPU6050 클래스가 Wire로 레지스터 읽는 일반 라이브러리 대응).
  • Wire.read()가 호출될 때 내부 버퍼에서 가속도/자이로/온도 레지스터 값 반환.
  • _emb::_imu_poll()에서 ISET:<addr>:ax:ay:az:gx:gy:gz:temp 파싱 후 버퍼 갱신.

2.2 프론트엔드

  • #imu-section 패널 추가: ax/ay/az, gx/gy/gz, temp 슬라이더.
  • SSE msg.imu → 패널 표시 및 핀 정보 저장.
  • SSE msg.imu_values → UI 갱신.
  • 슬라이더 변경 시 POST /api/arduino/{qemu,esp8266}/:id/imu.

3단계: BME280 (I2C)

3.1 백엔드

  • Wire 모의 라이브러리에서 주소 0x76/0x77 감지 시 \x02BMU:<sda>:<scl>:<addr>\n 출력.
  • BME280.h 또는 Adafruit_BME280.h 모의: 보정 계수/측정 레지스터 읽기 시 온도/습도/기압 값 반환.
  • _emb::_bme_poll()에서 BSET:<addr>:t:h:p 파싱.

3.2 프론트엔드

  • #bme-section 패널 추가: 온도/습도/기압 슬라이더.
  • SSE msg.bme / msg.bme_values 처리.
  • POST /api/arduino/{qemu,esp8266}/:id/bme.

4단계: DS18B20 (1-Wire)

4.1 백엔드

  • OneWire.h 모의 라이브러리 추가: search() / reset() 호출 시 \x02OWI:<pin>\n 출력.
  • DallasTemperature.h 모의: getTempCByIndex() 호출 시 버퍼의 온도 반환.
  • _emb::_ow_poll()에서 OSET:<pin>:temp 파싱.

4.2 프론트엔드

  • #ds18b20-section 패널 추가: 온도 슬라이더.
  • SSE msg.onewire / msg.ds18b20 처리.
  • POST /api/arduino/{qemu,esp8266}/:id/ds18b20.

5단계: 릴레이 (GPIO)

5.1 백엔드

  • 릴레이는 스케치에서 pinMode(pin, OUTPUT) + digitalWrite(pin, HIGH/LOW)만 사용.
  • 게이트웨이가 G<pin>:<val> 출력을 감시할 필요 없이, 릴레이 모듈 모의 라이브러리를 제공해 \x02RLY:<pin>:<state>\n 명시적으로 출력.
  • Relay.h 모의: begin(pin) → RLY:<pin>:0, on() → RLY:<pin>:1, off() → RLY:<pin>:0.

5.2 프론트엔드

  • #relay-section 패널에 핀별 ON/OFF 토글 버튼 표시.
  • SSE msg.relay → 토글 상태 갱신.
  • 사용자가 토글 클릭 시 \x03BTN 프로토콜(기존) 또는 별도 POST로 스케치에 HIGH/LOW 반영.
    • 단순히 표시용이면 토글만; 양방향이려면 POST /input에 BTN:<pin>:<level> 전송.

6단계: L298N 모터 드라이버

6.1 백엔드

  • L298N.h 모의 라이브러리 추가: begin(), setSpeedA(s), forwardA(), backwardA(), stopA() 등.
  • 상태 변경 시 \x02MST:<enA>:<in1>:<in2>:<in3>:<in4>:<enB>\n 출력.
  • 초기화 시 \x02MOT:...\n 출력.

6.2 프론트엔드

  • #motor-section 패널: 채널 A/B 속도 슬라이더, 방향 버튼(정/역/정지), 상태 텍스트.
  • SSE msg.motor / msg.motor_state 처리.
  • POST /api/arduino/{qemu,esp8266}/:id/motor로 속도/방향 주입.

7단계: AVR8js 회로도 연동

  • detectDHTConnections() 함수를 일반화하여 detectI2CConnections() / detectOneWireConnections() 추가.
  • MPU-6050/BME280/DS18B20/릴레이/L298N 부품의 터미널 위치와 보드 핀 매핑을 통해 AVR8js의 portD/B/C 및 I2C TWI 인터페이스에 연동.
  • 단, AVR8js의 I2C는 이미 LCD/OLED TWI 에뮬레이션이 있으므로 MPU-6050/BME280를 TWI 슬레이브로 등록하는 방식으로 확장.

8단계: 빌드 및 검증

  1. npm run build (TypeScript).
  2. systemctl --user restart homeclaw.
  3. 테스트 스케치:
    • MPU-6050: #include <MPU6050.h> → Wire.begin(), mpu.initialize() → 가속도/자이로 출력.
    • BME280: #include <Adafruit_BME280.h> → bme.begin() → 온습기압 출력.
    • DS18B20: #include <OneWire.h>, <DallasTemperature.h> → sensors.getTempCByIndex(0).
    • 릴레이: #include <Relay.h> → relay.on().
    • L298N: #include <L298N.h> → 모터 회전.

우선순위 및 단계별 커밋

각 부품별로 독립 커밋:

  1. feat(emu): MPU-6050 I2C simulation
  2. feat(emu): BME280 I2C simulation
  3. feat(emu): DS18B20 1-Wire simulation
  4. feat(emu): Relay module simulation
  5. feat(emu): L298N motor driver simulation

위험 및 완화

  • 위험: I2C 모의가 Wire 라이브러리 표준과 다르면 다양한 서드파티 라이브러리와 호환되지 않을 수 있음.
    • 완화: Adafruit/SparkFun 라이브러리에서 가장 흔히 사용하는 beginTransmission, requestFrom, read 흐름만 지원하고, 복잡한 write-then-read 시퀀스는 단순화.
  • 위험: QEMU stdin 쓰기 시 부팅 중 충돌 (DHT에서 이미 확인).
    • 완화: 센서 초기화 이벤트 수신 후 지연 시간을 두고 값을 전송, 부팅 직후 write는 피함.
  • 위험: 한 번에 너무 많은 파일 수정으로 회귀 버그 발생.
    • 완화: 단계별로 구현/빌드/재시작/테스트 후 다음 단계 진행.