Oct 042017
 

Docker

  • apt-get install lsb-release
  • curl -sSL https://get.docker.com | sh
  • docker run –rm armv7/armhf-ubuntu_core /bin/echo ‘Hello world’

Docker-compose

  • git clone https://github.com/docker/compose.git
  • cd compose
  • docker build -t docker-compose:armhf -f Dockerfile.armhf .
  • docker run –rm –entrypoint=”script/build/linux-entrypoint” -v $(pwd)/dist:/code/dist -v $(pwd)/.git:/code/.git “docker-compose:armhf”
  • ls -l dist/
  • cp dist/docker-compose-Linux-armv7l /usr/local/bin/docker-compose
  • chown root:root /usr/local/bin/docker-compose
  • chmod 0755 /usr/local/bin/docker-compose
  • docker-compose version

Dockerized HASS(Home ASSistant)

Dcokerized Node-Red

  • cd /root/node-red
  • wget https://github.com/pointbre/nodered-dietpi/blob/master/Dockerfile
  • docker build -t nodered-rpi:0.1 .
  • docker run -dit -p 1880:1880 –name nodered –privileged -v /root/node-red:/data nodered-rpi:0.1
  • 이제 http://rip_ip_address:1880 접속하면 됨
  • 한번 run한 이후로는 docker start nodered 혹은 docker stop nodered만 해주면 된다.
  • 부팅 후 자동 실행을 위해서는 /etc/systemd/system nodered.service 파일을 복사해넣은 후 cd /etc/systemd/system && systemctl enable nodered.service 하면 된다. 재부팅 후 HASS(port 8123, 실행이 시간이 약간 소요됨)와 Node-Red(port 1880)에 접속하면 두 서비스가 모두 살아있음을 확인할 수 있다.
  • 참고로, docker container안에서 백그라운드 서비스만 실행하는 경우, 실행 후 바로 docker container가 종료되는 현상이 있다. 이를 방지하기 위해서 bash 프로세스를 하나 더 실행하는 방식으로 node-red docker container가 계속 실행되도록 하는 트릭이 필요했다. 자세한 내용은 github을 참고하면 된다.
Oct 042017
 

둘째가 벌써 만 8개월이 되었다. 그동안 이것저것 시작했다가 방치해 놓았던 것들이 눈에 들어오기 시작하는 걸 보니 육아의 난이도가 조금은 낮춰진 거 같다. 가구 배치도 바꾸고, 가든 정리도 다시 시작하고, 그에 걸맞게 내 서재방도 깔끔하게 정리했다. 방이 정돈되고 나니, 뭔가를 다시 시작하거나 시작했던 것을 진행해야 할 것 같은 느낌이 들었다. 조그만한 노트를 꺼내고 뭘할까 고민하다가, 와이프에게 필요한 무선 프린터 서버를 해보기로 했다.

DietPi on RPi3

예전에 사두었던 라즈베리파이3를 꺼내들었다. 알리익스프레스에서 깔끔하게 생긴 알루미늄 케이스를 같이 주문했는데, 케이스안에 넣으니 안 그래도 성능 안 좋은 내장 와이파이가, 더욱 더 엉망이 되어서 라즈베리파이3에 잘 붙는 USB 무선랜카드 EDUP EP-N8531을 구매했었다. OS는 DietPi로 하기로 했다. 귀찮은 세팅작업 없이 바로 서버용으로 쓰기에 편하고, 인기있는 어플리케이션들을 한방에 설치할 수도 있기도 하고 괜찮은 녀석이다.

홈페이지에서 라즈베리용 이미지를 다운받은 후 SD카드에 구우면 되는데, OS X에서는 무료 어플리케이션인 Etcher로 하면 된다. 구운 후에는 SD카드에 있는 설치 설정 파일은 dietpi.txt를 수정해서 바로 wifi 접속(Wifi_Enabled=1, Wifi_SSID=???, Wifi_KEY=???)을 하고 무인 설치(AUTO_Install_Enable=1)도 하고 이것 저것 지정할 수 있다. 설정을 입맛에 바꾼 후 저장한 다음에는, SD카드를 넣고 라즈베리파이3를 켜면 알아서 부팅하고 설치하고 할 것이다. 더 자세한 것은 가이드 문서를 보면 된다.

기나 긴 설치와 업데이트가 끝나면 DietPi는 콘솔모드를 부팅이 되었을 것이다. 모니터에 연결되어 있다면 IP주소를 확인할 수 있고, 아니면 공유기에서 라즈베리파이3에 할당된 IP를 찾아서 ssh 접속할 수 있다. 이후 dietpi-config의 Network Options: Adapters 에서 내장 wifi를 비활성화한 후 usb wifi 어댑터를 끼운 다음 재부팅하면 된다.

라즈베리파이3에 Printer driver 설치

  • 사용중인 HP LaserJet P1102 드라이버는 불행히도 기본 포함되어 있지 않기 때문에 다음처럼 드라이버를 별도로 설치해줘야 한다.
  • apt-get install printer-driver-foo2zjs
  • 이제 dietpi-software를 가지고 Google cloud printer를 한방에 설치하면 된다.

CUPS에 프린터 등록 + 테스트

  • 이제 프린터를 라즈베리파이에 연결 후 https://라즈베리파이3의_ip:631 로 가면 CUPS관리자 페이지에서 Add printer를 한 후 설치한 프린터 드라이버(HP LaserJet Pro P1102 Foomatic/foo2zjs-z2 (recommended))를 선택해서 프린터 추가를 하면 된다. 추가시 Sharing을 선택해줘야 한다.
  • 이후 Administration페이지에서 Share printers connected to this system과 Allow printing from the Internet 옵션도 체크해줘야 한다.
  • 추가한 프린터는 Printers메뉴에서 프린터 선택 후 Maintenance 메뉴에서 Print Test Page를 선택해서 테스트할 수 있다.

OS X Sierra 10.12.5

프린터 추가해서 Bonjour 통해서(Google cloud print 설치시 Bonjour지원하는 avahi-daemon이 같이 설치되었슴) 자동으로 잡힌 프린터를 추가해주면 되는데 주의할 점은 자동으로 드라이버가 잡혀서 HP LaserJet Pro P1102 Foomatic/foo2zjs-z2 (recommended)가 선택될 때까지 기다려야 한다. 이 드라이버는 라즈베리파이3에서 실행되고 있는 CUPS를 통해서 다운로드 된 것이다.

윈도우 10

윈도우에서는 조금 복잡하다. 일단 프린터 드라이버를 다운로드 후 프린터 케이블을 꽂아서 드라이버를 설치해야 한다. 아마 CUPS서버에 윈도우용 드라이버가 없어서 일듯 하다. 만약 이미 윈도우용 드라이버가 지원되는 모델이라면그 이후 프린터를 다시 라즈베리파이3에 꽂은 후 프린터 추가를 해야 하는데, 목록에 없슴을 선택하고 이름으로 추가를 고른 후 CUPS의 Printers메뉴에서 프린터 선택하면 가는 url(https://ip:631/printers/HP_LaserJet_Professional_P1102)을 복사해 넣으면 끝이다.

구글 클라우드 프린트

라즈베리파이3에서 cps-auth를 실행하면 url이 출력되는데 해당 url로 가서 구글 계정 로그인 후 등록을 해야 한다. 이후 dietpi-service restart를 실행하고 나서 systemctl status cloudprintd -l을 실행하면 상태를 확인할 수 있다. 잘 등록이 되었다면 이제 폰에서 찾아서 등록 후 사용하면 되는데, 설정에 인쇄라는 메뉴가 안 보이면 google cloud print를 플레이스토어에서 찾아서 설치해야 하는 거 같다.

Oct 042017
 

MacBook 2009 에서의 Docker

최근에 Docker for Mac이 나왔지만 아쉽게도 2010년 모델 이후에 intel MMU virtualization이 지원되는 것들만 사용이 가능하다. 그래서 Home brew를 통해 사용해보려고 했으나 이번에는 osx가 10.9 라서, Xcode가 예전 버전이라서 docker 설치가 되질 않았다. 하는 수 없이 미루고 미뤄뒀던 10.12로의 업그레이드 및 Xcode 새 버전 설치를 진행하기로 했다.

  • 앱스토어에서 Sierra 10.12.5으로 업데이트를 했다. 몇 어플들이 호환 불가로 판정되어서 지워야 했지만, 별다른 이상없이 업데이트된 거 같았다.
  • 역시 앱스토어에서 Xcode 8.3.3(2 ???) 업그레이드/설치 시도했으나 도무지 진행안되었다. 거의 2시간에 걸친 다운로드 완료 후 설치 버튼을 눌러도 도무지 진행이 되질 않았다. 2일을 허비 후 그냥 설치 파일을 받아서 하기로 했다. 현재 8.3.2 버전을 다운받을 수 있었다.

다운로드 페이지에 접근해서 애플 아이디/암호 입력 후 Xcode8.3.2.xip 다운로드 후 설치하면 된다.

Docker

brew를 가지고 다음처럼 docker, docker-machine, docker-compose를 설치하면 된다. docker는 docker사용을 위한 것이고, docker-machine은 os에 구애받지 않고 docker를 사용하기 위해 virtual machine 기반으로 docker를 사용하기 위한 것(원래 docker는 linux os 위에서만 실행가능함)이고, docker-compose는 다수의 docker container 사이의 관계를 파일에 설정해서 쉽게 운영하기 위한 것이다.

  • brew install docker
  • brew install docker-machine
  • brew install docker-compose

Docker machine

생성
  • brew install caskroom/cask/brew-cask
    • virtual box가 설치됨
  • docker-machine create default
    • machine 이름을 default로 하면 docker-machine 명령 실행시 machine 이름을 생략해도 됨
  • eval $(docker-machine env default) 하면 다음과 같은 환경변수들이 설정됨
    • export DOCKER_TLS_VERIFY=”1″
    • export DOCKER_HOST=”tcp://192.168.237.131:2376″
    • export DOCKER_CERT_PATH=”/Users/pointbre/.docker/machine/machines/default”
    • export DOCKER_MACHINE_NAME=”default”
주의할 점

생성 직후에는 machine이 실행된 상태임 PC를 끄고 나서 다시 해보려고 하면 안되는 것이 당연 왜냐하면 machine이 실행안된 상태니까. 반드시 eval $(docker-machine env default) 실행 후 docker command들을 사용할 수 있다.

May 162017
 

RFLink gateway

RFLink RF gateway의 치명적 단점은 Serial 통신만 지원한다는 것이다. Arduino Mega의 USB포트를 이용하면 USB to Serial converter를 통해, 혹은 Arduino Mega의 Serial 포트를 통해 통신해야한다. Wireless를 지향하는 내 관점에서 이것은 치명적이었다. 할 수 없이 뭔가를 해야 했다.

Serial to Websocket

RF 신호가 올 때만 메시지를 보내는 방식 때문에 뭔가 “비동기”적인 방식을 사용해야 했다. MQTT말고 다른 걸 해보고 싶어 웹소켓을 골랐다. ESP8266 보드에 웹소켓 라이브러리를 넣어서, serial 포트에서 데이타가 들어오면 웹소켓으로 broadcast해 주면 될 듯 했다. 문제는 ESP8266을 한번도, 아니 arduino 조차도 한번도 제대로 해본적이 없다는 점이었다. 그래서 초보에게 쉬운 보드를 찾아보았다. Witty Cloud Development board를 알리익스프레스에서 USD 3.45짜리 2개를 구입했다. USB to serial 컨버터 내장에, 5v를 3.3v로 변환도 해주니 ESP8266에 처음 발들여 놓는 나에게 적당해 보였다. 이 때까지만 해도, 1 ~ 2 시간이면 되겠지 하는 자만심에 빠져 있었다.

삽질의 시작 CH340G USB칩

안 그래도 알리익스프레스에서 구한 저렴한 arduino mega 2560 때문에 머리가 아픈 상황이었다. osx 10.9.5 상태에서 아무리 해도 드라이버가 인식되질 않는 것(윈도우에서는 드라이버 설치시 잘 동작해서 RFLink 펌웨어를 올릴 수 있었슴)이었는데, 아차차 Witty Cloud Development board도 같은 칩을 사용한다는 걸 미리 체크하지 못한 것이었다.

현재 시점에서 CH340G의 osx용 드라이버는 V1.4인데, osx 10.9.5 에서는 이걸 깔면 안된다. V1.3을 깔아야 하는데, 이외에도 usb 케이블 길이에 따른 이슈도 있었다. 가지고 있던 스마트폰 충전용 케이블을 사용했더니 부팅 후 자동으로 종료되는 문제가 발생해서 여러번 시도해보았다. 2시간여를 끙끙대다가 혹시나 싶어, 가장 짧은 케이블을 꽂고 했더니 그제서야 인식이 되었다. 일단 드라이버가 제대로 설치된 이후로는 arduino mega 2560도 긴 usb 케이블을 가지고서도 잘 인식이 되었다.

Arduino IDE로 esp8266 개발 환경 설정 및 라이브러리 설치

Board Manager

ESP8266

  • Arduino 재시작
  • Witty cloud 보드의 아래쪽 보드(ESP8266MOD칩이 없는 보드)에 달린 usb를 pc에 연결
  • Tool – Board
    • WeMos D1 R2 & mini를 선택
    • Port에서 /dev/cu.wchusbserial410 선택
    • Upload Speed에서 57600 선택
  • 필요한 추가 라이브러리 – ArduinoWebsockets하고 WifiManager 설치
    • Sketch – Include Library – Manage Libraries.. 클릭
      • websockets 검색 후 나오는 목록 선택 후 2.X.X 선택 후 설치
      • wifimanager 검색 후 나오는 항목 설치

라이브러리 설치

Websocket for RFLink gateway

  • github에서 Serial to Websocket 예제를 찾은 후 ip대신 이름으로 접근하게 해주는 mDNSOTA 펌웨어 업데이트가 가능하도록 간단히 수정했다. 최종 소스는 여기서 다운 받을 수 있다.
  • Verify 혹은 Upload 실행 후 후 보드의 Flash 버튼 눌러서 펌웨어 업로드하면 되는 데 빌드가 끝날 때쯤해서 Flash버튼을 누르고 있다가 업로드가 시작되면 버튼에서 손을 떼도 된다.
    • 아무리 해도 안되는 경우에는 usb 케이블을 뺀 후 Flash 버튼을 누른 채로 usb 케이블을 연결 후 Upload해서 업로드가 시작된 후 버튼에서 손을 떼면 된다.
  • 이제 Witty cloud 보드에서 하단 보드를 빼고 상단보드만 아두이노에 연결하면 된다. esp8266 자체는 3.3V 기반이지만, Witty cloud 보드는 5V를 3.3V로 바꿔서 사용하므로 VCC에 5V를 넣어줘야 한다는 것이다. 혹시 보드상의 esp8266에 직접 연결시에는 3.3V를 넣어줘야 한다.
    • 아두이노 RX –> 상단 보드 TX
    • 아두이노 TX –> 상단 보드 RX
    • 아두이노 5V –> 상단 보드 VCC
    • 아두이노 GND –> 상단 보드 GND

Witty cloud board pinout

  • Chrome extension Simple WebSocket Client 설치해서 입력(소스에 입력한 명칭을 사용) 후 open 버튼 눌러서 RFLink gateway에서 메시지를 받을 수 있는지 확인해 본다.
  • 웹브라우저로 http://rflink.local/update (소스에 입력한 명칭을 사용) 접속해서 펌웨어 업로드도 가능하다.
May 072017
 

Google Assistant SDK preview

최근 기다리던 반가운 소식을 들었다. Google Assistant SDK가 드디어 release 되었다. Preview이긴 하지만 어쨌든 구글이 경쟁자들보다 한 걸음 더 나아가려는 행보임이 분명했다. 새로운 Ecosystem을 만들어서 온 세상에 Google Home을 퍼뜨리려는 것이다.

재미있는 것은 이번 Preview에 Google Assistant를 Raspberry Pi 3에 Python을 가지고 prototyping 해보는 내용이 같이 들어있는 것이다. 이후 MagPi의 부록으로 Google AIY Kit이 포함되었는데 물론 지금은 구하기가 어렵다. 서점이나 일부 인터넷쇼핑몰에서 파는 듯 한데 구하기가 쉽지 않다. 하지만 RPi3용 intruction을 가지고 Mac OS X에서 누군가 성공했기에 직접 따라해봤다.

Home Brew 설치(아직 설치안된 경우에만 다음을 실행해서 Home Brew 설치한다)

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Home Brew 업데이트

brew update

Python 최신 버전 설치

만약 Python이 설치 안된 경우에는 brew install python3 실행해서 신규 설치하고, 기존에 이미 설치된 경우에는 brew upgrade python3해서 설치된 버전을 업그레이드한다(3.4 버전의 경우 인증 실패로 인해 실행이 되지 않았슴).

디렉토리 생성 및 PIP 설치
  • mkdir googlehome (아무 이름이나 상관없슴)
  • cd googlehome
  • python3 -m venv env
  • env/bin/python -m pip install --upgrade pip setuptools
  • source env/bin/activate
Google Assistant SDK sample 다운로드

sudo python3 -m pip install --upgrade google-assistant-sdk[samples]

Google cloud 개발자 계정에서 프로젝트 생성, API 활성화 및 OAuth 2.0 Client ID 생성

Download credential

구글 Home과 연동해서 사용할 사용자 계정(개발자 계정과 달라도 상관없슴)에서 Activity들을 켜줌

https://myaccount.google.com/activitycontrols 에서 다음 항목을 켜 줌

  • Web & App Activity
  • Location History
  • Device Information
  • Voice & Audio Activity
인증

python -m googlesamples.assistant.auth_helpers --client-secrets client_secret_XXXXXXXXXXXXXXXXXXXXXXXX.json (마지막 값은 다운로드한 인증서 파일명이어야 함)

Audio test

python -m googlesamples.assistant.audio_helpers

Google Assistant 테스트

python -m googlesamples.assistant

더 생각해 볼만한 것들…

이제 어떤 기기에서도 Google Assistant를 사용할 수 있게 된다. 이것은 UI 패러다임의 전환이 이제 본격적으로 퍼지게 된다는 것을 의미할 것이다. Conversational Interface는 Input 도구를 사용하기 힘들거나 곤란한거나 불가능하거나 불편한 상황에서 아주 효율적인 UI로 자리매김할 것으로 생각된다.

IoT 측면에서도 정말 유용할 것이다. 비싼 Google Home을 사지 않고도 Google Assistant SDK를 가지고 집안 IoT 제어를 말로 할 수 있게 되었다. 또한 Google Home에서 지원하지 않는 기기도, Philips Hue Emulator를 가지고 제어하거나, Node-RED에서 직접 노드를 구현해서, Google Assistant를 통해 제어 가능하게 될 수 있게 되었다. 누군가의 말처럼, 방마다 Google Home을 둘 수도…

May 052017
 

왜 433Mhz일까?

433Mhz는 라이센스가 필요없다. 이말인 즉슨, 누구나 이 주파수를 사용하는 기기를 아무 제약없이 만들 수 있다는 점이다. 이러한 이유로 인해 433Mhz를 사용하는 수많은 장비들을 찾아볼 수 있다. 온/습도계, 화재경보기, 도어벨, 차고 개폐, 창문/문 개폐 감지 센서, PIR 센서 등 정말 다양한 장치들을 쉽게 구할 수 있다. 그런데, 다양하다는 것은 엉망진창이기도 하다. 단일의 프로토콜이 없어서, 각 기기가 다른 방식으로 통신을 한다. 보안성도 없어서 누구나 신호를 받을 수 있다.

현 시점에서 RF의 경쟁자는 BLE와 Zigbee라고 생각된다. ZWave가 있지만, 국가간 주파수 대역이 달라서 저렴한 제품을 다른 나라에서 구하기가 어렵고 기기 자체의 수나 제조업체의 수가 그다지 많지 않은 거 같다. Wifi의 경우 조금씩 많아지지만, 배터리로 운영되는 게 편한 옵/습도계, 화재 경보기, 개폐 감지 센서, PIR 센서 등 센서류에는 배터리 수명 문제가 있을 것 같다. BLE는 점점 기기수가 많아지는 거 같고, Zigbee 또한 Xiaomi Smart Home suite 덕분에 조금은 저렴하게 구할 수 있게 된 거 같다.

개인적으로 전원선을 연결하기 번거로운 센서류는 RF 장치 사용이 편하고 저렴하게 구할 수 있어서, RFLink gateway 모듈 + 케이스 + 호환 아두이노 메가 2560, 그리고 Acurite 00592TXR 옵/습도계를 구입했다.

RFLink gateway

Image of RFLink gateway in an enclosure

RFLink gateway는 RF 디바이스들을 위한 gateway이다. 주로 433Mhz를 사용하는 기기들을 지원하지만 이외에도 315Mhz, 866Mhz, 915Mhz 및 2.4Ghz 사용하는 몇몇 디바이스들도 지원해준다. RF signal을 송/수신 할 수 있으므로, 433Mhz 기반의 온습도계의 데이타를 읽거나, 433Mhz 기반의 AC switch를 제어하는 데 사용할 수 있다.

상용 제품으로는 RFXCom이라는 잘 만들어진 제품이 있으나 가격이 좀 비싸다. 반면에 RFLink gateway는 Arduino Mega + 호환 RF transmitter/receiver를 가지고 직접 만들수도 있고, nodo-shop.nl에서 판매하는 모듈을 사서 끼워도 되므로 RFXcom에 비해 저렴하게 구현할 수 있다. ESP8266 기반으로 RF 송수신 모듈을 연결해서 구현하는 것보다는 비싸지만, 많은 기기를 지원(지원 장치 목록)하는 SW가 지원된다는 점이 강력한 장점이다. 다른 RF 관련한 오픈소스 프로젝트 RCSwitch(주로 RF Switch류 모니터링/제어용)하고 rtl_433(수신만 가능)하고도 비교해봤지만, 기기 지원면에서 RFLink gateway가 가장 좋은 것으로 판단되었다. 또 하나의 이유로는, nodo-shop.nl에서 모듈과 Arduino Mega 2560을 같이 수납할 수 있는 케이스도 판매하고 있어서 깔끔하게 사용이 가능하다는 것도 강력한 이유였다. 개인적으로 PCB 보드들이 주렁주렁 선으로 연결되어 있는 방식의 DIY를 좋아하지 않기도 했다.

RFLink gateway는 원래 Open source project였으나, 어떤 이유에서인지 Freeware project로 변경이 되었다. 즉, 소스 자체는 공개되어 있지 않지만 사용에는 제약이 없는 형태로 운영이 되어지고 있다. 새로운 기기 지원을 위해서는 Plugin 개발을 해야하는 데 이 경우 운영자에게 직접 문의해서 진행하는 방식인 듯 하다. 다만 Freeware project로 변경되지 이전까지의 소스는 다음의 2 곳에서 찾을 수 있었다.

펌웨어 업로드

펌웨어를 RFLink gateway에 쓰기 위해서는 윈도우환경에서 하는 게 편한데, 업로드 전용툴이 지원되기 때문이다.

  • Arduino mega 2560를 윈도우 pc의 usb 포트에 연결한다.
    • CH340G이 사용된 저렴한 3rd party Arduino mega 2560의 경우 윈도우 7에서 만약 드라이버 설치 실패시 여기에서 다운로드 후 드라이버 업데이트 해야 함
  • 장치 관리자에서 시리얼 포트의 속도를 57600-8-N-1으로 설정
  • 다운로드 페이지에서 최근 파일 다운로드 후 압축을 해제한다.
  • RFLink_loader.exe를 실행해서 포트와 펌웨어를 선택 후 펌웨어 업로드한다.
    • 보드의 led가 빠르게 점멸하다가 멈추면 다운로드가 완료된 것이다. 이 상태에서 만약 RfLinkLoader.exe가 응답없음에 빠지면 그냥 강제 종료하면 된다.
  • 이제 가지고 있는 RF 장치를 켜서 패킷이 송신되게 한 후 어떻게 디코드되는 지 확인하면 된다.

프로토콜

프로토콜 페이지를 보면 자세히 알 수 있지만, 대략 다음과 같은 구조를 가지고 있다.

수신패킷 20;2D;UPM/Esic;ID=0001;TEMP=00cf;HUM=16;BAT=OK;

  • UPM/Esic – 장치/프로토콜 명칭
  • ID=0001 – 장치 아이디
  • TEMP=00cf – 해당 장치가 내보내는 데이타 중 온도, 00cf = 207 –> 20.7도
  • HUM=16 – 해당 장치가 내보내는 데이타 중 습도, 16 –> 16%
  • BAT=OK – 해당 장치가 내보내는 데이타 중 Battery status

송신패킷 10;AB400D;00004d;1;OFF;

  • AB400D – 장치/프로토콜 명칭
  • 00004d – 장치 아이디
  • 1 – 스위치 번호
  • OFF – 제어 명령

Play with Node-red

Raspberry Pi 3의 USB 포트에 RFLink gateway를 연결한 후, Node-red에서 Serial node를 생성하면 RFLink gateway가 보내는 데이타를 쉽게 볼 수 있다. 하지만 해당 메시지들을 손쉽게 가공해주는 전용 node가 없어서 직접 만들었다.

Apr 112017
 

이번에는 Node-RED를 가지고 기본적인 설정 후에 간단히 노드 생성 및 테스트/디버깅해봄으로써 Node-RED를 맛보기로 하겠다.

Node-RED를 라즈베리 파이에서 운영하는 것은 너무도 쉽다. 2015년 11월 이후, 그러니까 Raspbian Jessie 이후의 full image를 설치했다면 이미 Node-RED가 설치되어 있다. 만약 수동으로 설치하려면 링크의 글을 보고 하면 된다. 본격적으로 Node-RED를 사용하려면 부팅시마다 자동으로 실행되도록 해주면 되는데 다음의 명령어를 실행해주면 된다.

sudo systemctl enable nodered.service

Node-RED가 실행중이라면 http://ip:1880을 입력해서 다음과 같은 editor에 접근이 가능하다.

nodered-editor

그런데 뭔가 이상하다. 아무런 인증 과정없이 editor에 접근이 가능했다. 그렇다. 기본적으로 node-red의 editor는 아무런 인증 과정없이도 사용이 가능하다. 링크의 글을 참조해서 기본적인 사용자 인증을 적용하면 되는데, 다음에 기재한 것만 해도 별 무리는 없을 듯 하다.

sudo apt-get update
sudo apt-get install npm
sudo npm install -g node-red-admin
sudo service nodered restart

node-red-admin hash-pw 실행 후 원하는 암호 입력하면 출력되는 hash된 키를 복사해둔다.

vi ~/.node-red/setting.js해서 adminAuth/httpNodeAuth/httpStaticAuth부분의 주석표시를 제거해서 활성화 후 node-red-admin을 통해 생성한 hash된 키를 복사해 넣고 node-red를 재부팅하면 된다.

adminAuth: {
type: “credentials”,
users: [{
username: “admin”,
password: “생성한 hash암호”,
permissions: “*”
}]
},

httpNodeAuth: {user:”admin”,pass:”생성한 hash암호”},
httpStaticAuth: {user:”admin”,pass:”생성한 hash암호”},

이제 다시 http://ip:1880으로 접속해보면 다음처럼 로그인 화면이 나오고 위에서 지정한 암호를 입력해야 editor 접근이 가능해진다.

editor-login

 

이제 Hello world를 해보자. Hello world 용으로 MQTT를 사용해보자. 일단 MQTT 서버와 클라이언트를 라즈베리 파이에 다음처럼 설치하자.

wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-wheezy.list
sudo apt-get update
sudo apt-get install mosquitto mosquitto-clients

아무 설정없는 상태에서 mosquitto에는 아무 인증없이 누구나 subscribe/publish가 가능하다. 그러므로 다음의 사용자 인증/토픽접근 제어 설정을 적용하도록 하자.

sudo vi /etc/mosquitto/mosquitto.users 해서 아이디:암호 형식으로 다음처럼 1줄에 1개씩 기재
admin:password_1

sudo mosquitto_passwd -U /etc/mosquitto/mosquitto.users

sudo vi /etc/mosquitto/mosquitto.conf 해서 다음을 추가
allow_anonymous false
password_file /etc/mosquitto/mosquitto.users

sudo service mosquitto restart

테스트 해보자.
터미널 1: mosquitto_sub -h localhost -t /sensor/livingroom/state -u admin -P password
터미널 2: mosquitto_pub -h localhost -t /sensor/livingroom/state -m “23 -u user -P password

sudo vi /etc/mosquitto/mosquitto.acl 해서 다음을 추가
user admin
topic/sensor/livingroom/state

sudo service mosquitto restart

테스트 해보자.
터미널 1: mosquitto_sub -h localhost -t /sensor/livingroom/state -u admin -P password
터미널 2: mosquitto_pub -h localhost -t/sensor/livingroom/state -m “23” -u admin -P password

다음으로는 dashboard node를 설치해야 한다(참고로 cd ~/.node-red 하지 않고 설치시 설치된 모듈이 지정된 위치에 다운로드되지 않아 인식되지 않는 오류가 발생함으로 현 시점에서는 디렉토리 변경이 필요함).

cd ~/.node-red
npm install node-red-dashboard
sudo service nodered restart

이제 http://ip:1880을 가면 다음과 같은 dashboard node들을 볼 수 있다.

dashboard-nodes

이제 모든 준비가 끝났다.

editor에서 ctrl + i 누른 후 다음을 붙여넣은 후 다음처럼 설정을 해주면 되고 deploy버튼을 눌러서 작성한 내용이 서버에 반영되도록 한 이후 http://ip:1880/ui에 접근하면 랜덤하게 생성된 값들이 MQTT 토픽에 Publish되고 그 값들이 대쉬보드에 실시간 표시됨을 볼 수 있다.

helloworld

[{“id”:”e8a6a48f.8953d8″,”type”:”inject”,”z”:”aa0a983c.7cbef8″,”name”:””,”topic”:””,”payload”:””,”payloadType”:”date”,”repeat”:”5″,”crontab”:””,”once”:false,”x”:115,”y”:54,”wires”:[[“fb45a81f.16e8d8”]]},{“id”:”fb45a81f.16e8d8″,”type”:”random”,”z”:”aa0a983c.7cbef8″,”name”:””,”low”:”10″,”high”:”100″,”inte”:”true”,”x”:266,”y”:53,”wires”:[[“147a741a.fcf04c”]]},{“id”:”147a741a.fcf04c”,”type”:”mqtt out”,”z”:”aa0a983c.7cbef8″,”name”:””,”topic”:”/sensor/livingroom/state”,”qos”:”1″,”retain”:”true”,”broker”:”d96006fc.6471d8″,”x”:463,”y”:51,”wires”:[]},{“id”:”89ac48b1.9612a8″,”type”:”mqtt in”,”z”:”aa0a983c.7cbef8″,”name”:””,”topic”:”/sensor/livingroom/state”,”qos”:”2″,”broker”:”d96006fc.6471d8″,”x”:135,”y”:150,”wires”:[[“1adfa2af.934e3d”]]},{“id”:”1adfa2af.934e3d”,”type”:”ui_gauge”,”z”:”aa0a983c.7cbef8″,”name”:””,”group”:”54359e7.e23766″,”order”:0,”width”:0,”height”:0,”gtype”:”donut”,”title”:”Gauge”,”label”:”units”,”format”:”{{value}}”,”min”:”10″,”max”:”100″,”colors”:[“#00b500″,”#e6e600″,”#ca3838″],”seg1″:””,”seg2″:””,”x”:354,”y”:148,”wires”:[]},{“id”:”d96006fc.6471d8″,”type”:”mqtt-broker”,”z”:””,”broker”:”localhost”,”port”:”1883″,”clientid”:””,”usetls”:false,”compatmode”:true,”keepalive”:”60″,”cleansession”:true,”willTopic”:””,”willQos”:”0″,”willPayload”:””,”birthTopic”:””,”birthQos”:”0″,”birthPayload”:””},{“id”:”54359e7.e23766″,”type”:”ui_group”,”z”:””,”name”:”Default”,”tab”:”841c7e06.6255c”,”disp”:true,”width”:”6″},{“id”:”841c7e06.6255c”,”type”:”ui_tab”,”z”:””,”name”:”Home”,”icon”:”dashboard”}]

helloworld-configuration

만약 어떤 값이 Random 노드에서 생성되는지 알고 싶다면 다음처럼 간단히 debug 노드를 붙여주면 된다. 생성한 디버그 노드의 출력은 끝에 달린 버튼을 클릭해서 on/off 시킬 수 있으므로 삭제하지 말고 필요없을 때에는 그냥 off시켜주면 편리하다.

helloworld-debug

이 예제를 통해 Injetc, debug, random, MQTT read(subscribe)/write(push) 그리고 dashboard 노드 중 Gauge 까지 한번에 다뤄보았다.

Apr 102017
 

최근 IoT와 원격 및 자동 제어에 개인적인 관심이 생겨 취미 삼아 공부중이다. Raspberry Pi등의 Open source H/W SBC류, Arduino/ESP8266등으로 DIY, 기성 RF/WIFI 센서/스위치등의 해킹, 자동화 플랫폼 OpenHAB 등의 학습 등을 진행하면서 실제 적용을 위해 집 IoT 및 원격/자동 제어 시스템을 구축해 나가려고 한다. 누구라도 관심이 있는 사람이라면 따라할 수 있을 정도의 내용 기술을 목표로 하고는 있는데 어찌 될런지, 얼마나 걸릴런지는 모르겠다.

그 첫번째로 Node-RED에 대해 알아보자. 찾아보면 정말 많은 자동화 플랫폼이 있다. 오픈소스 진영만 해도 OpenHAB2, Domoticz 와 Home Assistant 등 쟁쟁한 녀석들이 많다. 그런데 Node-RED가 첫번째 내용이 되어야 하는데에는 나름의 이유가 있다.

Node-RED는 Node.js 기반의 HW, API와 온라인 서비스 등의 “Wiring”해주는 브라우저 기반의 프로그래밍 환경이다. 각각의 기능들은 “Node”로 표현되며, 기본적으로 제공되는 Node들 이외에도 수많은 사람들이 기여한 3rd party Node들을 사용할 수 있다. 그러한 Node들을 브라우저 상에서 “연결”하는 것만으로도 HW, API와 온라인 서비스 등을 쉽게 연동할 수 있게 된다.  예를 들어 기본 제공되는 HTTP input node와 HTTP response node만을 가지고 몇 초 안에 HTTP Restful API를 prototyping할 수 있다. 3rd party node 중 Modbus node와 기본제공되는 MQTT node를 사용하면 Modbus 장치에서 값을 읽어서 MQTT로 push하는 기능을 실제 Modbus 장치 없이도 구현/테스트 가능하다.

http-api-with-mongodb

modbus-to-mqtt

Node-RED는 손쉬운 테스트/디버깅을 가능하게 해준다. 여타 유명한 자동화 플랫폼에서는 해당 플랫폼에서 사용하는 설정 방법이나 특정 파일 형식 등을 사용해서 어떠한 규칙을 기술함으로써 제어, 자동화 혹은 연동이 이뤄진다. 문제는 그러한 방법에 익숙해지지 않고서는 원하고자 하는 것을 구현하기가 그다지 쉽지 않다는 것이다. 또한 테스트도 쉽지 않다. 규칙을 기술하고 나서 장치를 가지고 실제 테스트를 진행해야, 해당 규칙이 잘 동작하는 지 알 수 있다. 하지만 Node-RED는 정말 강력한 테스트/디버깅 기능을 제공한다. Inject node를 통해 수동 혹은 인터벌 trigger를 쉽게 지정할 수 있고, 테스트할 값도 실제 장치없이도 지정할 수 있어서 테스트가 매우 쉽다. 또한 Debugging node를 어느 Node에나 붙일 수 있고, 디버깅 on/off도 쉽게 조절이 가능해야 디버깅 창에서 문제 확인이 바로 바로 가능하다.

inject-and-debugging

Node-RED에서는 자바스크립트 기반의 custom function을 사용할 수 있는데, 자바스크립트 개발 경험이 있는 많은 사람들에게는 정말 반가운 환경이라고 할 수 있다.

custom-function

위에 기술한 3가지 강력한 장점들이 여타의 자동화 플랫폼보다 Node-RED에 좀 더 몰두하도록 만들었지만, 그렇다고 해서 Node-RED가 자동화 플랫폼의 대안이 되기는 아직 시기 상조인듯 하다. 웹기반의 Dash board UI도 있고 사용자 인증도 제공하고, DB 연동도 가능하며, HTTPS 등도 가능하기는 하다. 그래도 그보다는 자동화 플랫폼과 HW/API/온라인 서비스 사이에서 기능별 연동/변환용 시스템으로 사용하는 것이, 현 시점에서는 맞는 활용방법인 거 같다. 자동화 플랫폼들을 보면, 각기 지원되는 기능과 지원되지 않는 기능등이 모두 달라서 그 어느 것 하나 “완벽”하지 않고, 또한 “완벽”할 수도 없다고 생각한다. 그러한 점에서 Node-RED가 그러한 자동화 플랫폼들을 보완해주는 Swiss Army Knife같은 주머니속의 강력한 Middleware system이 될 수 있다고 생각한다.

Mar 172017
 

언제나 그렇듯 클리앙 팁&강좌 게시판과 사용기게시판을 보다가 우연히 acme.sh을 이용한 무료 SSL 자동 갱신에 대한 글을 보았다. 안 그래도 최근 SSL/TLS 적용해야 할 일이 있기도 했기에 바로 착수했다. 우선 목표는 acme.sh(https://github.com/Neilpang/acme.sh)를 이용해서 인증서 자동 갱신 및 갱신 후 아파치 자동 재시작하는 것이다.

acme.sh
Let’s Encrypt 무료 인증서를 자동갱신해주는 쉘스크립트이다. Ubuntu 12.04에서 권한때문에 문제 생기는 게 귀찮아서 acme.sh 실행시 sudo를 사용할 예정인데, crontab에 등록해야 하므로 비밀번호 입력을 생략하기 위해 /etc/sudoer파일을 다음과 같이 수정한다.

vi /etc/sudoer
아이디 ALL=(ALL:ALL) NOPASSWD:ALL

이제 암호를 다시 입력하지 않고도 sudo를 사용할 수 있게 되었다. 만약 권한 문제가 없으리라 생각되면 이 과정은 생략해도 될듯 하다.

acme.sh를 다운받아서 이제 인증서 생성 및 적용하면 되는데, 무슨 이유에서인지 sudo사용시 절대경로를 지정해야만 실행이 되었다.

sudo “/home/아이디/.acme.sh”/acme.sh –issue -d abc.com -w /var/www/wp_abc_com
-d = domain
-w = document root

sudo ~/.acme.sh/acme.sh –issue -d abc.com -w /var/www/wp_abc_com
[Wed Mar 15 13:40:27 EDT 2017] Single domain=’abc.com
[Wed Mar 15 13:40:27 EDT 2017] Getting domain auth token for each domain
[Wed Mar 15 13:40:27 EDT 2017] Getting webroot for domain=’abc.com
[Wed Mar 15 13:40:27 EDT 2017] Getting new-authz for domain=’abc.com
[Wed Mar 15 13:40:28 EDT 2017] The new-authz request is ok.

[Wed Mar 15 13:40:29 EDT 2017] Cert success.
—–BEGIN CERTIFICATE—–

—–END CERTIFICATE—–
[Wed Mar 15 13:40:29 EDT 2017] Your cert is in  /home/아이디/.acme.sh/abc.com/abc.com.cer
[Wed Mar 15 13:40:29 EDT 2017] Your cert key is in  /home/아이디/.acme.sh/abc.com/abc.com.key
[Wed Mar 15 13:40:29 EDT 2017] The intermediate CA cert is in  /home/아이디/.acme.sh/abc.com/ca.cer
[Wed Mar 15 13:40:29 EDT 2017] And the full chain certs is there:  /home/아이디/.acme.sh/abc.com/fullchain.cer

마지막 부분에 인증서가 저장된 위치를 보여주면 인증서 생성이 성공된 것이다. crontab -e 해서 보면 acme.sh에 대한 항목이 이미 생성되어 있는 것을 볼 수 있다. 개인 취향상 자동 지정된 시간을 매일 자정에 맞추었고 sudo지정 및 절대경로로 변경했다.

0 0 * * * sudo “/home/아이디/.acme.sh”/acme.sh –cron –home “/home/아이디/.acme.sh” > /dev/null

아파치에 인증서 갱신 적용하기
이제 아파치에 적용해야 할 시간이다. 그런데 이 부분이 조금 어려웠다. 최초 적용시에는 아무래도 수동으로 직접 인증서를 복사해줘야 하는 것으로 보인다. 복사하지 않고 했더니 자꾸 에러가 났다.

먼저 인증서를 저장한 디렉토리를 생성하자
sudo mkdir /etc/apache2/ssl

이제 생성된 인증서를 복사해넣자.
sudo cp /home/아이디/.acme.sh/abc.com/abc.com.cer /etc/apache2/ssl
sudo cp /home/아이디/.acme.sh/abc.com/abc.com.key /etc/apache2/ssl
sudo cp /home/아이디/.acme.sh/abc.com/fullchain.cer /etc/apache2/ssl

이제는 httpd.conf를 수정해서 https가 사용가능하게 하고, http로 접속시 자동으로 https로 변경되도록 해보자.
sudo vi /etc/apache2/httpd.conf
# Load SSL module
LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so

# 기존 VirtualHost를 수정해서 https로 자동 이동되도록 함
<VirtualHost *:80>
ServerName      abc.com
ServerAlias        www.abc.com
DocumentRoot    /var/www/wp_abc_com
#  외부링크방지
SetEnvIfNoCase Referer abc\.com link_allow
SetEnvIfNoCase Referer www\.abc\.com link_allow
SetEnvIfNoCase Referer clien\.net link_allow
SetEnvIfNoCase Referer m\.clien\.net link_allow
SetEnvIfNoCase Referer ^$ link_allow
<FilesMatch “\.(jpe?g|gif|png|bmp|avi|swf|mpe?g|zip|z[00-99]|rar|mp[1-9]|arj|exe|asf|wm[a-z]*|ra[a-z]*|alz|ZIP|Z[00-99])$”>
Order Deny,Allow
Allow from env=link_allow
Deny from all
ErrorDocument 403 /error_page.php
</FilesMatch>
CustomLog /var/log/apache2/abc.com.access.log combined
LogLevel Error
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://abc.com%{REQUEST_URI} [L,R=301]

</VirtualHost>

# 위의 설정을 카피한 후 아래 부분을 변경처리
<VirtualHost *:443>
ServerName      abc.com:443
DocumentRoot    /var/www/wp_abc_com
#  외부링크방지
SetEnvIfNoCase Referer abc\.com link_allow
SetEnvIfNoCase Referer www\.abc\.com link_allow
SetEnvIfNoCase Referer clien\.net link_allow
SetEnvIfNoCase Referer m\.clien\.net link_allow
SetEnvIfNoCase Referer ^$ link_allow
<FilesMatch “\.(jpe?g|gif|png|bmp|avi|swf|mpe?g|zip|z[00-99]|rar|mp[1-9]|arj|exe|asf|wm[a-z]*|ra[a-z]*|alz|ZIP|Z[00-99])$”>
Order Deny,Allow
Allow from env=link_allow
Deny from all
ErrorDocument 403 /error_page.php
</FilesMatch>
CustomLog /var/log/apache2/abc.com.access.log combined
LogLevel Error
# 인증서 설정
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW

SSLCertificateFile /etc/apache2/ssl/abc.com.cer
SSLCertificateKeyFile /etc/apache2/ssl/abc.com.key
SSLCertificateChainFile /etc/apache2/ssl/abc.com.key
# Disable SSL V2 and V3
SSLProtocol all -SSLv2 -SSLv3
</VirtualHost>

이제는 https 접속을 위해 포트 443이 막혀있다면 방화벽에서 열어줘야 한다.
sudo ufw allow 443

이제 아파치를 재기동(sudo service apache restart)하고 http://abc.com 접속해서 https://abc.com 으로 자동 이동되고 안전한 사이트로 표시되는 지 확인해보자.

다 잘 되었다면 이제 acme.sh가 인증서 갱신 후 아까 생성해둔 디렉토리로 인증서를 복사해넣고 아파치를 재기동하게 해주면 끝이다. 이에 앞서 아까 수동으로 복사해둔 인증서들을 삭제하고 다음 명령을 실행해서 인증서들이 잘 복사되는 지 확인하면 된다.

sudo “/home/아이디/.acme.sh”/acme.sh –install-cert -d abc.com \
–home “/home/아이디/.acme.sh” \
–certpath      /etc/apache2/ssl/abc.com.cer \
–keypath      /etc/apache2/ssl/abc.com.key \
–fullchainpath /etc/apache2/ssl/fullchain.cer \
–reloadcmd    “sudo service apache2 force-reload”

이제 acme.sh가 생성한 설정을 확인해보자. 다음 갱신이 언제인지, 어디로 인증서를 복사해넣을지 등에 대한 설정이 저장되어 있는 것을 볼 수 있을 것이다.

vi /home/아이디/.acme.sh/abc.com/abc.com.conf
Le_Domain=’abc.com
Le_Alt=’no’
Le_Webroot=’/var/www/wp_abc_com’
Le_PreHook=”
Le_PostHook=”
Le_RenewHook=”
Le_API=’https://acme-v01.api.letsencrypt.org’
Le_Keylength=”
Le_LinkCert=’https://acme-v01.api.letsencrypt.org/acme/cert/…’
Le_LinkIssuer=’https://acme-v01.api.letsencrypt.org/acme/issuer-cert’
Le_CertCreateTime=’1489601638′
Le_CertCreateTimeStr=’Wed Mar 15 18:13:58 UTC 2017′
Le_NextRenewTimeStr=’Sun May 14 18:13:58 UTC 2017′
Le_NextRenewTime=’1494699238′
Le_RealCertPath=’/etc/apache2/ssl/abc.com.cer’
Le_RealCACertPath=”
Le_RealKeyPath=’/etc/apache2/ssl/abc.com.key’
Le_ReloadCmd=’sudo service apache2 force-reload’
Le_RealFullChainPath=’/etc/apache2/ssl/fullchain.cer’

이제 Let’s Encrypt 인증서 자동 갱신 적용이 끝났다.

[Updated]
PC 브라우저에서는 문제가 없었는데 안드로이드 크롬에서 보니 insecure로 나와서 다시 확인을 해보았다. certificate chain 파일이 잘못된 듯 했다. acme.sh에서 생성해준 fullchain.cer을 지정해봤으나 타임아웃이 걸릴 정도로 뭔가 문제가 있었고… 구글 검색을 통해 https://whatsmychaincert.com/ 에 가서 사이트명 넣고 chain cert파일을 다운로드 받은 후 http.conf에 적용했다.

SSLCertificateChainFile /etc/apache2/ssl/abc.com.chain.crt

아파치 재부팅 후 테스트해보니 pc와 안드로이드 모두 제대로 나온다.

Mar 042017
 

Rule작성법을 연습하기 위해 PushBullet 연동을 해보았다. Kankun wifi plug의 상태가 변할 때마다 push notification을 받을 수 있도록 OpenHAB2 rule을 작성하면 된다.

*PushBullet api token 준비
Pushbullet에서 Account setting페이지를 가보면 Access token을 생성할 수 있다.

*Rule 작성
sudo -u openhab vi /etc/openhab2/rules/switch.rules 해서 다음을 입력

rule “switchOn”
when
Item mqttsw1 changed from OFF to ON
then
executeCommandLine(“curl@@-k@@-H@@Access-Token: 토큰키@@-XPOST@@https://api.pushbullet.com/v2/pushes@@-H@@Content-Type: application/json@@–data-binary@@{\”type\”: \”note\”, \”title\”: \”스위치1 상태”, \”body\”: \”현재 On입니다.\”}@@”)

end

rule “switchOff”
when
Item mqttsw1 changed from ON to OFF
then
executeCommandLine(“curl@@-k@@-H@@Access-Token: 토큰키@@-XPOST@@https://api.pushbullet.com/v2/pushes@@-H@@Content-Type: application/json@@–data-binary@@{\”type\”: \”note\”, \”title\”: \”스위치1 상태\”, \”body\”: \”현재 Off입니다.”}@@”)
end

스위치를 On/Off하면 이제 푸쉬메시지가 온다.

1 2 3 4 5 6 7 8 9 10 11 12 »