스마트 홈 기기 이름이 많아지면 "알렉사, 거실 조명 켜줘" 같은 명령어를 기억하기 어렵고, 잘못된 기기가 켜지거나 알렉사가 못 알아듣는 경우가 빈번합니다. "알렉사, 이 조명 켜줘"라고 말하고, 알렉사가 사용자 위치를 파악해 의도한 조명을 제어하면 훨씬 직관적일 것입니다.
해결책: Walabot 3D 센서
Walabot은 프로그래머블 3D 이미징 센서로, 무선 주파수(RF)를 사용해 주변 물체와 움직임을 감지합니다. 카메라와 달리 사생활 침해 없이 위치 추적이 가능합니다.
LattePanda: 윈도우 10 탑재 x86 SBC
인텔 아톰 x8300 쿼드코어, 2/4GB RAM, 윈도우 10 구동. 내장 ATmega32u4(아두이노 레오나르도 호환) 코프로세서로 GPIO 제어 가능. Walabot(USB)과 아두이노(내장)를 한 보드에서 연결해 에지 컴퓨팅에 최적화.
Node-RED: 비주얼 IoT 로직 빌더
브라우저 기반 플로우 에디터로 알렉사 명령 수신, Walabot 데이터 처리, 아두이노 GPIO 제어를 노드 연결로 구현. 주요 노드:
node-red-contrib-alexa-local: 알렉사 로컬 스마트 홈 에뮬레이션 (필립스 휴 브리지 스푸핑)
node-red-node-arduino: 펌라타(Firmata) 프로토콜로 아두이노 통신
시스템 동작 흐름
3단계 파이프라인:
Walabot 서비스 처리: 파이썬 스크립트가 Walabot에서 객체 위치(x,y,z) 읽어 TCP 포트 1890으로 JSON 스트리밍
위치 데이터 저장: Node-RED가 포트 1890 수신 → JSON 파싱 → 전역 변수(X, Y, Z)에 최신 위치 저장
알렉사 명령 처리: 알렉사 명령 수신 → 저장된 위치 기반으로 어느 램프 제어할지 결정 → 아두이노 릴레이 핀 제어
git clone https://github.com/rondagdag/smart3DSensorForAlexa
cd smart3DSensorForAlexa
npm install
npm start
7단계: 알렉사 연동
동일 와이파이 네트워크 확인
알렉사 앱에서 "스마트 홈 스킬" 활성화
"알렉사, 기기 찾아줘" → "Lamp" 발견
Node-RED 플로우 수정: https://localhost:1880/red/
Node-RED 플로우 상세
1. Walabot 서비스 (파이썬)
from __future__ import print_function
from sys import platform
from os import system
from imp import load_source
import socket, sys
WalabotAPI = load_source('WalabotAPI', 'C:\\Program Files\\Walabot\\WalabotSDK\\python\\WalabotAPI.py')
if __name__ == '__main__':
WalabotAPI.Init()
WalabotAPI.SetSettingsFolder()
WalabotAPI.ConnectAny()
WalabotAPI.SetProfile(WalabotAPI.PROF_SENSOR)
WalabotAPI.SetThreshold(35)
WalabotAPI.SetArenaR(50, 400, 4)
WalabotAPI.SetArenaPhi(-45, 45, 2)
WalabotAPI.SetArenaTheta(-20, 20, 10)
WalabotAPI.SetDynamicImageFilter(WalabotAPI.FILTER_TYPE_MTI)
WalabotAPI.Start()
system('cls' if platform == 'win32' else 'clear')
numOfTargetsToDisplay = 1
if len(sys.argv) == 2:
TCP_IP = '127.0.0.1'
TCP_PORT = int(sys.argv[1])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
while True:
WalabotAPI.Trigger()
targets = WalabotAPI.GetSensorTargets()
finds = '{"targets": ['
index = 0
for i, t in enumerate(targets):
if i < numOfTargetsToDisplay:
index += 1
print('Target {}\nx = {}\ny = {}\nz = {}'.format(i+1, t.xPosCm, t.yPosCm, t.zPosCm))
finds += '{"x": "%s", "y": "%s", "z": "%s"}' % (t.xPosCm, t.yPosCm, t.zPosCm)
finds += ']}'
conn.sendall(str.encode(finds))
conn.close()
WalabotAPI.Stop()
WalabotAPI.Disconnect()
2. 위치 데이터 파싱 및 저장 (Node-RED 함수 노드)
raw = msg.payload.toString('UTF-8');
j = JSON.parse(raw);
var msg1 = { payload: raw };
var msg2 = { payload: j };
if (raw.length > 20) {
X = msg2.payload.targets[0].x;
Y = msg2.payload.targets[0].y;
Z = msg2.payload.targets[0].z;
global.set("X", X);
global.set("Y", Y);
global.set("Z", Z);
var msg3 = { payload: X };
var msg4 = { payload: Y };
var msg5 = { payload: Z };
}
return [msg1, msg2, msg3, msg4, msg5];
3. 알렉사 명령 처리 (Node-RED)
node-red-contrib-alexa-local 노드로 알렉사 명령 수신 → 전역 변수(X,Y,Z) 기반으로 위치 판단 → 해당 릴레이 핀 제어 명령 아두이노로 전송