이 페이지는 간단한 HTTP server(Flask를 이용)와 Web 상에서 실시간으로 양 방향 통신을 가능하게 하는 WebSocket을 이용한 원격제어에 대한 이해를 위한 페이지 이다.
- Python를 이용한 Webserver 환경 만들기
- Python를 이용한 Raspberry Pi Webserver
- Web checkbox을 이용한 LED 제어
- Raspberry Pi 시작 시 자동으로 프로그램 시작 하도록 하기
- Flask 설치 하기
- 다음 명령으로 Python3에 설치된 Python package를 확인 할 수 있다.
- web file(Python file, html file, css file)을 저장하기 위한 폴더 만들기
- Python web file(html)를 저장할 Directory(webapp)를 만든다.
- webapp 폴더에 web file(html)를 저장할 Directory(templates)를 만든다.
- webapp 폴더에 css file 등를 저장할 Directory(static)를 만든다.
Flask는 Python으로 작성된 웹 응용 프로그램 프레임 워크이다.
Raspberry Pi에는 Python과 Python을 위한 Flask Library가 이미 설치되어 있기 때문에 별도로 설치 할 필요가 없다.
pip3 list
mkdir webapp
mkdir templates
mkdir static
- 첫번째 Web server 만들기
- Windows PC에서 Notepad++ 편집기를 사용하여 web server(first.py) File을 아래와 같이 작성 한다.
#!/user/bin/env python
# coding=utf8
# Importing flask module
from flask import Flask
# Flask 생성자는 현재 모듈 이름 (__name__)을 인수로 사용한다.
app = Flask(__name__)
# Flask 클래스의 route() 함수는 Decorator(데코레이터)로,
# 연결된 함수를 호출하는 URL(이 예에서는 '/')을 알려준다.
# 이 예에서 '/' URL은 first_web() 함수와 바인딩 된다.
@app.route('/')
def fist_web():
return 'First web server'
# Flask 클래스의 run() 메소드는 애플리케이션을 실행한다.
# run() method의 모든 parameter는 모두 Optional 이기 때문에 생략 할 수 있다.
# host parameter는 Defaults 값이 127.0.0.1
# (이 경우 localhost 에서 만 접속 할 수 있음) 이다.
# host='0.0.0.0' 인 경우 Web server를 외부에서 접속 할 수 있도록 한다.
# port parameter는 Defaults 값이 5000 이다.
# 이 예에서는 2880 번을 사용하였다. 포트 번호는 각자 적당한 값으로 별경 할 수 있다.
# 외부에서 Web server에 접속하기 위하여는 공유기에서 포트포워드 설정을 하여야 한다.
# debug parameter는 Defaults 값이 False 이다.
# 개발 단계에서 Debug information 이 필요한 경우 True로 설정 한다.
if __name__ == '__main__':
app.run(host='0.0.0.0', port=2880, debug=True)
python3 first.py
http://[RaspberryPi_IP]:2880/
위에서 [RaspberryPi_IP]는 Raspberry Pi의 IP Adress
- Windows PC에서 Notepad++ 편집기를 사용하여 web server(hello.py) File을 아래와 같이 작성 한다.
원하는 Web page를 직접 Acces 하기 위하여 Routing 기술을 사용 한다.
#!/user/bin/env python
# coding=utf8
# Importing flask module
from flask import Flask
# Flask 생성자는 현재 모듈 이름 (__name__)을 인수로 사용한다.
app = Flask(__name__)
# Flask 클래스의 route() 함수는 Decorator(데코레이터)로,
# 연결된 함수를 호출하는 URL(이 예에서는 '/'hello)을 알려준다.
# 이 예에서 '/hello' URL은 hello_world() 함수와 바인딩 된다.
@app.route('/hello')
def hello_world():
return 'Hello world'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=2880, debug=True)
python3 hello.py
http://[RaspberryPi_IP]:2880/hello
위에서 [RaspberryPi_IP]는 Raspberry Pi의 IP Adress
- Windows PC에서 Notepad++ 편집기를 사용하여 web server(first-html.py) File을 아래와 같이 작성 한다.
render_template() 함수를 사용하여 Web browser에서 HTML 파일(Web page)을 전송 받는다.
#!/user/bin/env python
# coding=utf8
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('first-html.htm')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=2880, debug=True)
Flask는 HTML file을 templates folder에 있는 것으로 간주하기 때문에 이 예를 위한 폴더 구성과 파일 위치는 아래와 같이 구성 하여야 한다.
- wepapp <- Folder: 이 예에서 Application 폴더 이름을 wepapp로 하였다.
- first-html.py <- Python file
- templates <- Folder
- first-html.htm <- html file
python3 first-html.py
http://[RaspberryPi_IP]:2880/
위에서 [RaspberryPi_IP]는 Raspberry Pi의 IP Adress
- 실험을 위한 준비
- Raspberry Pi Pin11(GPIO 17)에 1번 LED를 연결 한다.
- Raspberry Pi Pin13(GPIO 27)에 2번 LED를 연결 한다.
- GPIO Pin과 LED 연결하기
- Raspberry Pi의 GPIO Pin과 330옴 저항의 한 단자를 연결 한다.
- LED의 + 단자와 330옴 저항의 다른 단자를 연결 한다.
- LED의 - 단자을 Breadboard의 GND 에 연결 한다.
- Raspberry Pi의 GND(Pin9)과 Breadboard GND를 연결 한다.
- Editor를 사용하여 webapp Directory에 py-checkbox-led.py File을 만들고 아래와 같이 편집 한다.
Raspberry Pi LED 제어하기를 참고하기 바람.
#!/user/bin/env python
# coding=utf8
from flask import Flask, render_template, request
from gpiozero import LED
app = Flask(__name__)
import json
led = [LED(17),LED(27)]
@app.route('/')
def checkBoxLED():
return render_template('py-checkbox-led.htm')
@app.route('/checkBoxLEDControl', methods=['POST'])
def LEDControl():
# Checkbox의 Check list(Check 상태로 HTML File에서 Value로 정의 됨)를 갖어 온다.
checkbox = request.form.getlist('check')
#print('checkbox: ',checkbox)
# checkbox에는 Check된 Checkbox의 상태만 포함되어 있기 때문에
# Check 되지 않은 Checkbox의 상태도 포함하기 위하여 checkList[ ]를 정의한다.
checkList = [0, 0]
checkListLen = len(checkList)
# 모든 LED를 Turn off 한다.
for i in range(0, checkListLen):
led[i].off()
# Checkbox가 Check된 LED를 Turn on 한다.
for checkboxNo in checkbox:
i = int(checkboxNo)
led[i].on()
# 현재 모든 LED의 상태(On, Off)를 checkList에 저장한다.
for i in range(0, checkListLen):
if led[i].is_active == True:
checkList[i] = 1
else:
checkList[i] = 0
#print('checkList: ',checkList)
# 현재 LED의 상태(On, Off)를 표시하는 checkList를 Web page에 Return 한다.
return json.dumps({'status':'OK','checkbox':checkList});
@app.route('/checkBoxLEDGet', methods=['GET'])
def LEDGet():
# Checkbox의 Check list(Check 상태로 HTML File에서 Value로 정의 됨)를 갖어 온다.
getMsg = request.args.get('getLED')
#print('getMsg: ',getMsg)
# checkbox에는 Check된 Checkbox의 상태만 포함되어 있기 때문에
# Check 되지 않은 Checkbox의 상태도 포함하기 위하여 checkList[ ]를 정의한다.
checkList = [0, 0]
checkListLen = len(checkList)
# 현재 모든 LED의 상태(On, Off)를 checkList에 저장한다.
for i in range(0, checkListLen):
if led[i].is_active == True:
checkList[i] = 1
else:
checkList[i] = 0
#print('checkList: ',checkList)
# 현재 LED의 상태(On, Off)를 표시하는 checkList를 Web page에 Return 한다.
return json.dumps({'status':'OK','checkbox':checkList});
if __name__ == '__main__':
app.run(host='0.0.0.0', port=2880, debug=True)
py-checkbox-led.htm을 실행한 Web page 예
python3 py-checkbox-led.py
http://[RaspberryPi_IP]:2880/
위에서 [RaspberryPi_IP]는 Raspberry Pi의 IP Adress
- Turn on 하려고 하는 LED 번호에 해당되는 Chekbox를 Check 하고 "LED Control" 버튼을 누르면 Check 된 번호의 LED가 Turn on 된다.
- "Get LED Status" 버튼을 누르면 현재 Turn on 된 LED에 대응하는 Checkbox 가 Check 된다. 동작 확인을 위하여 Checkbox를 Clear 한 다음 이 명령을 실행 한다.
- Python Script를 Background에서 실행 하기
- Python Script의 윗 부분에 아래 Code를 삽입 한다.
- 아래 명령으로 Python Script File의 Permissions을 실행 가능한 속성으로 변경 한다.
- 아래 명령으로 Python Script File을 실행 한다.
- Python Script File의 실행중 발생하는 Output(log)는 nohup.out에 저장 된다.
- Raspberry Pi 시작 시 자동으로 프로그램이 시작 하도록 하기 위한 설정
- /etc/rc.local File에 Editor를 사용하여 다음 명령을 삽입 한다.
- sudo nohup python3 (path)/(run flie name) &
- 예: sudo nohup python3 /home/pi/python/webapp/py-checkbox-led.py &
- & 문자는 프로그램이 Background에서 실행 되도록 함. 소유자: root
- Background에서 실행 중인 Process를 확인 하고 정지 하기
- 다음 명령으로 Background 에서 실행 중인 python3 Process PID를 확인 한다. 윗 예에서 실행 프로그램 이름은 py-checkbox-led.py 이지만 실행 Process 이름은 python3 임.
- 다음 명령으로 실행 중인 python3 Process를 정지 한다.
#!/usr/bin/env python3
chmod +x file-name.py
nohup python3 file-name.py &
ps -A | grep (Process name)
예: ps -A | grep python3
sudo kill pid (pid는 ps 명령으로 확인한 python3 process의 pid 번호 임.)