그동안 쌓여 있던 미커밋 파일들을 정리. 소스·자산만 올리고, 개인 데이터와 런타임 상태는 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>
6.8 KiB
6.8 KiB
Arduino 에뮬레이터 센서/액추에이터 추가 계획
목표
web-ui/arduino-emulator.html과 src/gateway/server-v2.ts에 다음 5가지 부품의 시뮬레이션을 순서대로 추가한다.
- MPU-6050 (I2C 6축 IMU)
- BME280 (I2C 온도/습도/기압)
- DS18B20 (1-Wire 온도)
- 릴레이 모듈 (GPIO 스위칭)
- L298N 모터 드라이버 (GPIO DC 모터)
적용 대상 에뮬레이터
- ESP32 QEMU (
src/gateway/server-v2.tsQEMU 경로) - ESP8266 native (
src/gateway/server-v2.tsg++ 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단계: 빌드 및 검증
npm run build(TypeScript).systemctl --user restart homeclaw.- 테스트 스케치:
- 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>→ 모터 회전.
- MPU-6050:
우선순위 및 단계별 커밋
각 부품별로 독립 커밋:
feat(emu): MPU-6050 I2C simulationfeat(emu): BME280 I2C simulationfeat(emu): DS18B20 1-Wire simulationfeat(emu): Relay module simulationfeat(emu): L298N motor driver simulation
위험 및 완화
- 위험: I2C 모의가
Wire라이브러리 표준과 다르면 다양한 서드파티 라이브러리와 호환되지 않을 수 있음.- 완화: Adafruit/SparkFun 라이브러리에서 가장 흔히 사용하는
beginTransmission,requestFrom,read흐름만 지원하고, 복잡한 write-then-read 시퀀스는 단순화.
- 완화: Adafruit/SparkFun 라이브러리에서 가장 흔히 사용하는
- 위험: QEMU stdin 쓰기 시 부팅 중 충돌 (DHT에서 이미 확인).
- 완화: 센서 초기화 이벤트 수신 후 지연 시간을 두고 값을 전송, 부팅 직후 write는 피함.
- 위험: 한 번에 너무 많은 파일 수정으로 회귀 버그 발생.
- 완화: 단계별로 구현/빌드/재시작/테스트 후 다음 단계 진행.