SlideShare a Scribd company logo
1 of 50
Download to read offline
One (language) for All (platforms)
development note
ผศ.ดร.ศภชย วรพจนพศทธ
ภาควชาวศวกรรมไฟฟ้าและคอมพวเตอร
มหาวทยาลยธรรมศาสตร
บนทึก
●
13 ม%ค. 58
การตดต้ง Python และเครื่องมือ
การตดต่อเว็บบรการ Google Maps
การตดต้ง Raspberry Pi
●
19 ม%ค. 58
การตดต้ง OpenCV สำาหรบ Windows + Raspberry Pi
การเข%ยนโค ้ด computer vision
●
26 ม%ค. 58
การตดต้ง Python SDK สำาหรบ Google App Engine
การพฒนา web app และ web service
เตร%ยม Python และ IDE
●
ดาวนโหลดและตดต้ง Python 2.7.8
http://www.python.org
●
ดาวนโหลดและตดต้ง PyCharm IDE
https://www.jetbrains.com/pycharm/
ทดสอบ Python environment
●
เปด PyCharm แล ้วเลือกสร ้าง Pure Python project
ตรวจสอบว่า Interpreter ตรงกบร่นท%่ตดต้ง
●
คลกท%่ Python console แล ้วพมพ print('hello')
เพื่อยืนยนการทำางาน
ทดสอบ Python IDE
●
คลกขวาท%่ชื่อ project แล ้วเลือก New → Python file
● พมพโค ้ดเพื่อทดสอบ
if __name__ == '__main__':
print('hello, world')
●
เลือกเมนู Run เพื่อส่งทำางาน เช็คผลจากหน้าต่าง Run
อ่านเข%ยนไฟล
●
เตร%ยมไฟล test.txt ท%่เป็นข ้อความสำาหรบใช ้ทดสอบ
●
พมพโค ้ดสำาหรบนบคำาจากไฟล แล ้วส่ง Run
if __name__ == '__main__':
f = open('test.txt', 'r')
counts = {}
content = f.read()
for word in content.split():
if word not in counts:
counts[word] = 1
else:
counts[word] += 1
for k,v in counts.items():
print k,v
เข ้าถึงเนื้อหาบนอนเตอรเน็ต
●
ข ้อมูลอสงหารมทรพยท%่ Sacramento เป็น CSV
http://samplecsvs.s3.amazonaws.com/Sacramentoreal
estatetransactions.csv
●
พมพโค ้ดสำาหรบการอ่านไฟลจากเว็บ แล ้วส่ง Run
import urllib
if __name__ == '__main__':
url = 'http://…csv'
conn = urllib.urlopen(url)
content = conn.read()
conn.close()
lines = content.split('r')
table = []
for line in lines:
fields = line.split(',')
if not table:
for field in fields:
table.append({'name':field, 'column':[]})
else:
idx = 0
for field in fields:
table[idx]['column'].append(field)
idx += 1
for item in table:
print(item['name'])
ดึงไฟลจากเว็บไซต
แยกเนื้อหาตามบรรทด
แยกข ้อมูลด ้วย ,
ประกอบข ้อมูลใหม่
ทดสอบใช ้ด%บ๊กเกอร
●
คลกต้ง breakpoint ท%่ด ้านหน้าโค ้ด
lines = content.split('r')
●
เลือกเมนู Run → Debug
●
ตรวจสอบตวแปรในหน้าต่างย่อย Variables
●
ใช ้ป่ มบน toolbar เพื่อส่งทำางาน
ใช ้งานบรการ Google Maps
●
API สำาหรบเข ้าใช ้เว็บบรการของ Google Maps
https://developers.google.com/maps/documentation/
webservices/
●
ทดสอบบรการ Geocoding ด ้วยเบราเซอร
https://maps.googleapis.com/maps/api/geocode/json
?address=Bangkok+Thailand
●
พมพคำาส่งลงใน Python console เพื่อทดลองการแยกข ้อมูล
ในรูปแบบ json
import urllib
import json
url = 'https://maps.googleapis.com/maps/api/geocode/json?'
args = {'address':'Bangkok,Thailand','language':'th'}
url += urllib.urlencode(args)
conn = urllib.urlopen(url)
resp = json.load(conn)
●
ทดลองดึงค่าออกจากผลลพธของเว็บบรการ
resp.keys()
print resp['status']
type(resp['results'])
ทดสอบการแยกข ้อมูล
ได ้ผลลพธ [u'status', u'results']
ลำาดบการดึงข ้อมูลพกด
●
ลำาดบในการแยกข ้อมูลพกด lat/lng ของสถานท%่
type(resp['results'][0])
<type 'dict'>
resp['results'][0].keys()
[u'geometry', u'address_components', u'place_id', …
type(resp['results'][0]['geometry'])
<type 'dict'>
resp['results'][0]['geometry'].keys()
[u'location', u'bounds', u'viewport', …
type(resp['results'][0]['geometry']['location'])
<type 'dict'>
resp['results'][0]['geometry']['location'].keys()
[u'lat', u'lng']
resp['results'][0]['geometry']['location']
{u'lat': 13.7563309, u'lng': 100.5017651}
ข ้อมูลแบบ list
ผลลพธ
ดึงข ้อมูลพกดจากสถานท%่
●
พมพโค ้ดดึงข ้อมูล แล ้วส่ง Run
import urllib
import json
if __name__ == '__main__':
url = 'https://.../maps/api/geocode/json?'
args = {'address':'Bangkok,Thailand','language':'th'}
url += urllib.urlencode(args)
conn = urllib.urlopen(url)
resp = json.load(conn)
latlng = resp['results'][0]['geometry']['location']
print latlng['lat'],latlng['lng']
for place in resp['results']:
print place['formatted_address']
เตร%ยม Raspberry Pi
ดาวนโหลดและตดต้ง Raspbian ลงใน SD card โดยใช ้
โปรแกรม Win32 Disk Imager
●
http://downloads.raspberrypi.org/raspbian_latest
●
http://sourceforge.net/projects/win32diskimager/
เตร%ยมคอมพวเตอร (Windows 7)
●
ต้งค่า Network and Connection Sharing โดยเลือก
รายการ change adapter settings
●
เลือกแชร WiFi → LAN (Ethernet)
เชื่อมต่อ PC ↔ Raspberry Pi
●
เส%ยบ SD card เข ้า Raspberry Pi
●
เส%ยบสาย LAN และ USB เข ้าคอมพวเตอร
เช็คสถานะบูต/เครือข่ายจาก LED ส%เข%ยว
●
พมพคำาส่ง cmd ใน Start menu ของ Windows
●
พมพคำาส่ง arp -a เพื่อดู IP address ของบอรด
ล็อกอนผ่าน Ethernet
●
ดาวนโหลดโปรแกรม PuTTY
http://www.chiark.greenend.org.uk/~sgtatham/putty/
download.html
●
ล็อกอนผ่าน ssh โดยป้อน IP address ของบอรด
●
รหสผู้ใช ้pi และรหสผ่าน raspberry
ส่งไฟลจาก PC
●
ดาวนโหลดและตดต้งโปรแกรม WinSCP (secure copy)
http://sourceforge.net/projects/winscp/
●
โอนย ้ายไฟล ???.py ไป แล ้วทดสอบเร%ยกใช ้เช่น
python test.py
ต้งค่าเร่มต ้นให ้บอรด
● พมพคำาส่ง sudo raspi-config
●
เลือกรายการ Expand Filesystem เพื่อขยายระบบไฟล
ให ้ใช ้เต็มพื้นท%่ SD card
●
กดป่ มลูกศรหรือ Tab เพื่อเลือก <Finish>
ตดต้งซอฟตแวรพื้นฐาน
● พมพคำาส่งเพื่อตดต้งแพคเกจ
sudo apt-get install tightvncserver
●
เปดใช ้งาน vncserver แล ้วป้อนรหสผ่าน
vncserver :0 -geometry 800x600 -depth 16
●
ไปท%่เว็บ chrome เพื่อตดต้งแอพ VNC viewer
https://chrome.google.com/webstore/category/apps
ตดต้ง VNC client บน PC
●
เชื่อมต่อบรการ VNC โดยป้อน IP address:0
●
เลือก LXTerminal เพื่อเปด console รบคำาส่ง
ตดต้งเครื่องมือท%่จำาเป็น
●
การต้ง vncserver ให ้ทำางานช่วงบูตระบบ
http://www.raspberrypi.org/documentation/remote-
access/vnc/
●
แก ้ไขการทำางานของสครปต vncboot ให ้เป็นผู้ใช ้pi
sudo -u pi vncserver :0 -geometry 800x600
-depth 16 -pixelformat 565
ตดต้งเครื่องมือสำาหรบ Python
●
พมพคำาส่งเพื่อตดต้ง wxPython
sudo apt-get install python-wxgtk2.8 wx2.8-
i18n python-wxtools
●
เลือกแอพ PyCrust
จากเมนู
ป่ ม Ctrl + ] หรือ [ เพื่อ
ขยาย/ลดขนาด font
●
พมพคำาส่ง pyalamode
หรือ pyalacarte เพื่อเปด
ใช ้editor
ตดต้ง OpenCV ใน PC
●
ดาวนโหลดและตดต้ง numpy สำาหรบ Python 2.7
http://sourceforge.net/projects/numpy/files/NumPy/
●
ดาวนโหลดและขยายไฟล OpenCV
http://sourceforge.net/projects/opencvlibrary/files/
opencv-win/
●
สำาเนาไฟล cv2.pyd จากโฟลเดอร opencvbuild
python2.7x86 ไปท%่ C:Python27Lib
●
ทดสอบการตดต้งจาก Python Console
import cv2
สร ้างโครงของ computer vision
● พมพโค ้ดเพื่ออ่านภาพจากเว็บแคม กลบด ้าน และแสดง
ผลทางหน้าต่าง
import cv2
if __name__ == '__main__':
cap = cv2.VideoCapture(0)
cv2.namedWindow('mirror')
while True:
res,frame = cap.read()
cv2.flip(frame, 1, frame)
cv2.imshow('mirror', frame)
if cv2.waitKey(100) == 27:
break
cap.release()
cv2.destroyAllWindows()
รอ 100 msec
ป่ ม Esc เพื่อหยด
อ่านภาพ
ประมวลผล
นำาไปใช ้
ตดต้ง OpenCV ใน RPi
●
พมพคำาส่งเพื่อตดต้ง OpenCV
sudo apt-get install python-opencv
●
เร%ยกใช ้pyalamode เพื่อพมพโค ้ด mirror.py
● พมพคำาส่งเพื่อเร%ยกใช ้
python mirror.py
การจบภาพจากเว็บแคมด ้วย OpenCV
ใน Raspberry Pi จะหน่วง และม%
ความซำ้าของภาพ
ใช ้filter เพื่อแปลงรูป
●
เข%ยนโค ้ดแทรกใน mirror.py
● สร ้างฟงกชนก่อน if __name__ == '__main__':
def onChange(pos):
print 'Current position is ' + str(pos)
●
สร ้าง trackbar หลงบรรทด cv2.namedWindow()
cv2.createTrackbar('filter', 'mirror', 0, 2, onChange)
● เข%ยนโค ้ดเพื่อทำาเงื่อนไขประมวลผลภาพ
0 ไม่ประมวลผล
1 แปลงเป็นภาพเฉดเทา
2 แปลงเป็นเส ้นขอบ (อลกอรธึม Canny)
ใช ้filter เพื่อแปลงรูป
● เข%ยนโค ้ดแทรกหลงบรรทด cv2.flip()
if cv2.getTrackbarPos('filter', 'mirror') == 1:
frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2GRAY)
if cv2.getTrackbarPos('filter', 'mirror') == 2:
frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2GRAY)
frame = cv2.Canny(frame, 50, 200)
สร ้าง time lapse camera
●
เข%ยนโค ้ดเพื่อสร ้างตวบนทึก video โดยกำาหนด format
กบ frame rate
w = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))
format = cv2.cv.CV_FOURCC('M','J','P','G')
out = cv2.VideoWriter('test.avi', format, 10, (w,h))
● บนทึกเฟรมลงในคลป
out.write(frame)
●
ควบคม frame rate โดยการหน่วงเวลา
if cv2.waitKey(100) == 27:
import cv2
if __name__ == '__main__':
cap = cv2.VideoCapture(0)
w = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))
format = cv2.cv.CV_FOURCC('M','J','P','G')
out = cv2.VideoWriter('test.avi', format, 10, (w,h))
cv2.namedWindow('preview')
while True:
res,frame = cap.read()
frame = cv2.flip(frame, 1)
cv2.imshow('preview', frame)
out.write(frame)
if cv2.waitKey(100) == 27:
break
cap.release()
cv2.destroyAllWindows()
ใน Raspberry Pi ให ้ตดต้ง VLC player เพื่อดูไฟลท%่บนทึก
sudo apt-get install vlc
ต้งสื่อ
บนทึก
หาตำาแหน่งแล ้วแปลงพกด
● ประยกตใช ้ในแอพประเภทสแกนเอกสาร
http://www.pyimagesearch.com/2014/09/01/build-
kick-ass-mobile-document-scanner-just-5-minutes/
●
cv2.cvtColor()
●
cv2.Canny()
●
cv2.findContours()
●
cv2.warpPerspective()
แปลงภาพ
เป็นเฉดเทา
หาขอบด ้วย
Canny
Bounding
rectangle
Perspective
warping
แปลงภาพเป็น binary
ret,frame = cap.read()
(h,w,_) = frame.shape; w = w/2; h = h/2
img = cv2.resize(frame, (w,h))
img = cv2.flip(img, 1)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_img = cv2.GaussianBlur(gray_img, (5, 5), 0)
edge_img = cv2.Canny(gray_img, 50, 100)
kernel = numpy.ones((5,5), numpy.uint8)
edge_img = cv2.morphologyEx(edge_img, cv2.MORPH_CLOSE,
kernel)
อ่านและย่อภาพ
หาขอบ
หา 4 จดล ้อมภาพ
(cnts, _) = cv2.findContours(edge_img, cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts,key=cv2.contourArea,reverse=True)[:5]
rect = numpy.zeros((4, 2), dtype=numpy.float32)
for c in cnts:
peri = cv2.arcLength(c, True)
pts = cv2.approxPolyDP(c, 0.01 * peri, True)
if len(pts) == 4 and cv2.contourArea(c) > 0.15*w*h:
cv2.drawContours(img, [pts], -1, (0, 255, 0), 2)
sums = [pt[0].sum() for pt in pts]
diffs = [numpy.diff(pt[0]) for pt in pts]
rect[0] = pts[numpy.argmin(sums)][0]
rect[1] = pts[numpy.argmin(diffs)][0]
rect[2] = pts[numpy.argmax(diffs)][0]
rect[3] = pts[numpy.argmax(sums)][0]
ล ้อมเส ้น
หาจดท%่ 4 มม
สร ้างกรอบ
แปลงพกดของภาพ
(tl,tr,bl,br) = rect
top = cv2.norm(tr,tl)
bottom = cv2.norm(br,bl)
width = max(int(top), int(bottom))
left = cv2.norm(tl,bl)
right = cv2.norm(tr,br)
height = max(int(left), int(right))
dst = numpy.array([[0, 0],[width - 1, 0],
[0, height - 1],[width - 1, height – 1]],
dtype=numpy.float32)
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(img, M, (width, height))
warped = cv2.flip(warped,1)
คำานวณขนาด
แปลง
พกด
แนวคด Internet of Things
Cloud computing
gateway
sensor
ค่าเซ็นเซอร
server
HTTP - REST
เตร%ยม Google App Engine
●
เงื่อนไข: ม% google account + ฟร% = จำากดการใช ้
●
ดาวนโหลดและตดต้ง App Engine SDK for Python
https://cloud.google.com/appengine/downloads
ข้นตอนสร ้างบรการบน cloud
●
กำาหนดช่องทาง (URL) ในการเข ้าถึงบรการ = web API
http://AAA.appspot.com/xxx/yyy/zzz?arg1=?&arg2=?
ตวอย่างเช่น บรการ Geocoding ของ Google Maps
https://maps.googleapis.com/maps/api/geocode/
json?address=Bangkok+Thailand
●
ออกแบบโมเดลของการแลกเปล%่ยนข ้อมูล
●
เข%ยนโค ้ดประมวลผล HTTP requests: GET,POST,...
จำาแนกข ้อมูล > จดการฐานข ้อมูล > สร ้างผลลพธ
●
ตอบสนอง = return code + HTML (web apps) หรือ
XML/JSON (web services)
กรณ%ตวอย่าง sensor acquisition
●
มมมองอปกรณ = data entity
ค่า + คณสมบต (what,which,where,how,...)
●
มมมองเซรฟเวอร = database entity
เวลา + อ ้างอง + ค่า + คณสมบต (what,how,...)
●
มมมองผู้ใช ้= information
เทรนดของค่า / ตวแทนของค่าข ้อมูล / ...
application: rpi-box
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon.ico
static_files: favicon.ico
upload: favicon.ico
- url: /ws
script: service.app
- url: /ui
script: ui.app
- url: .*
script: main.app
libraries:
- name: webapp2
version: latest
- name: jinja2
version: latest
ไลบราร%ท%่ขอใช ้
การเชื่อม URL กบโค ้ด
ชื่อของแอพพลเคชน
ไฟล app.yaml
การใช ้งาน Google App Engine
●
กดป่ ม Run เพื่อใช ้PC เป็นเซรฟเวอร
● ใช ้เบราเซอรดูการทำางานจากพอรต
http://localhost:port
●
กดป่ ม Logs เพื่อตรวจสอบสถานะทำางาน
●
ตรวจสอบฐานข ้อมูล
http://localhost:admin_port
●
หลงยืนยนการทำางาน กดป่ ม Deploy เพื่ออพโหลด
● ใช ้เบราเซอรไปท%่เซรฟเวอร
http://appname.appspot.com
โครงของเว็บบรการ (service.py)
●
HTTP request > ประมวลผล > JSON
#!/usr/bin/env python
import webapp2
import json
class TestHandler(webapp2.RequestHandler):
def get(self):
resp = {'status':'OK'}
self.response.write(json.dumps(resp))
app = webapp2.WSGIApplication([
('/ws/test', TestHandler)
], debug=True)
ใช ้เบราเซอรดูท%่ http://localhost:xxxx/ws/test
เตร%ยมต ้นแบบข ้อมูล (model.py)
● นยามข ้อมูล
when = เวลา which = แหล่งข ้อมูล
what = ข ้อมูล how = วธ%การ
where = ตำาแหน่ง ...
from google.appengine.ext import ndb
class MyData(ndb.Model):
timestamp = ndb.DateTimeProperty(auto_now_add=True)
serial = ndb.IntegerProperty(required=True)
value = ndb.FloatProperty(required=True)
เพ่มบรการ (service.py)
class UpdateHandler(webapp2.RequestHandler):
def get(self):
sn = self.request.get('sn')
val = self.request.get('value')
if sn != '' and val != '':
resp = {'status':'OK'}
data = MyData(serial=int(sn),value=float(val))
data.put()
else:
resp = {'status':'ERR'}
self.response.write(json.dumps(resp))
app = webapp2.WSGIApplication([
('/ws/test', TestHandler),
('/ws/update', UpdateHandler)
], debug=True)
แยกข ้อมูลจาก arg
จดเก็บข ้อมูล
http://appname.appspot.com/ws/update?sn=11&val=1.0
เตร%ยมเชื่อมต่อ Arduino
●
Raspberry Pi สามารถเชื่อมต่อ Arduino ผ่านพอรต
USB ท้งรูปแบบข ้อมูลและโค ้ด
sudo apt-get install arduino arduino-mk
python-serial
●
เส%ยบ Arduino เข ้ากบ Raspberry Pi
●
พมพคำาส่ง dmesg ดูรายงานการเชื่อมต่อ
●
ตรวจสอบพอรตอนกรมท%่เป็น Arduino: ttyACMx หรือ
ttyUSBx
> ls /dev/tty*
สร ้างแหล่งข ้อมูล
●
เข%ยนโค ้ดบน Arduino เพื่อส่มวดและรายงานผล
void setup() {
Serial.begin(9600);
}
void loop() {
int val = analogRead(0);
Serial.println(val);
delay(1000);
}
หากม%หลายข ้อมูล แนะนำาให ้ใช ้csv หรือ json
Serial.print(val1); Serial.print(',');
Serial.print(val2); Serial.print(',');
Serial.println(val3);
ส่งผ่านข ้อมูล
●
สร ้างไฟล data_feed.py สำาหรบ Raspberry Pi
import json
import serial
import urllib
if __name__ == '__main__':
ser = serial.Serial('/dev/ttyACM0',9600,timeout=10)
ser.flush()
while True:
line = ser.readline()
data = line.strip()
args = {'sn':11, 'value':data}
url = 'http://rpi-box.appspot.com/ws/update?'
conn = urllib.urlopen(url + urllib.urlencode(args))
resp = json.load(conn)
print resp['status']
เชื่อมต่อพอรตอนกรม
รบและจำาแนกข ้อมูล
โครงของเว็บแอพ (ui.py)
●
HTTP request > สืบค ้นและจดรูปข ้อมูล > HTML
import webapp2
import os
import jinja2
JINJA_ENV = jinja2.Environment(loader=
jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],autoescape=True)
class ViewHandler(webapp2.RequestHandler):
def get(self):
...
self.response.write(template.render(resp))
app = webapp2.WSGIApplication([
('/ui/view', ViewHandler)
], debug=True)
สืบค ้นข ้อมูลจาก datastore
●
ข ้อมูลถูกจดเก็บในรูป object อ ้างองได ้ด ้วย key
●
ใช ้เทคนค templating เพื่ออ่านไฟล HTML ต ้นแบบ
from model import *
sn = self.request.get('sn')
if sn != '':
resp = {'status':'OK'}
query = MyData.query(MyData.serial==int(sn))
data = query.fetch(10)
resp['values'] = [entity.value for entity in data]
else:
resp = {'status':'ERR'}
template = JINJA_ENV.get_template('index.html')
กำาหนดเงื่อนไข/สืบค ้น
ไฟล HTML ต ้นแบบ
●
ใช ้การทดแทน HTML tag ในระหว่าง rendering
ทดแทนตวแปร
<div data-role="footer">
<h2>{{status}}</h2>
</div>
แบบรายการ list, tuple
<ui>
{% for value in values %}
<li>Value is {{value}}</li>
{% endfor %}
</ui>
ดึงค่าตวแปรมาแสดง
วนสร ้างรายการจาก list
ตดต้งเครื่องมือสำาหรบ Python
●
พมพคำาส่งเพื่อตดต้งตวตดต้งแพคเกจเฉพาะ Python
sudo apt-get install python-pip
●
ตดต้ง idlex โดยพมพคำาส่ง
sudo pip install idlex
●

More Related Content

Similar to สไลด์ประกอบกิจกรรม One (language) for All (platforms)

Basic Creating Virtual Reality with HDR Panoramic Photography Technique - Day...
Basic Creating Virtual Reality with HDR Panoramic Photography Technique - Day...Basic Creating Virtual Reality with HDR Panoramic Photography Technique - Day...
Basic Creating Virtual Reality with HDR Panoramic Photography Technique - Day...Rachabodin Suwannakanthi
 
เริ่มต้นการเขียนโปรแกรมหุ่นยนต์
เริ่มต้นการเขียนโปรแกรมหุ่นยนต์เริ่มต้นการเขียนโปรแกรมหุ่นยนต์
เริ่มต้นการเขียนโปรแกรมหุ่นยนต์Wittayakorn Yasingthong
 
แบบทดสอบก่อนเรียน
แบบทดสอบก่อนเรียนแบบทดสอบก่อนเรียน
แบบทดสอบก่อนเรียนNimanong Nim
 
โปรแกรมย่อยและฟังก์ชันมาตรฐาน
โปรแกรมย่อยและฟังก์ชันมาตรฐานโปรแกรมย่อยและฟังก์ชันมาตรฐาน
โปรแกรมย่อยและฟังก์ชันมาตรฐานchanamanee Tiya
 
โปรแกรมย่อยและฟังก์ชันมาตรฐาน
โปรแกรมย่อยและฟังก์ชันมาตรฐานโปรแกรมย่อยและฟังก์ชันมาตรฐาน
โปรแกรมย่อยและฟังก์ชันมาตรฐานchanamanee Tiya
 
การสร้างสระบบนำชมด้วยเทคโนโลยีเสมือนจริง 3D Vista
การสร้างสระบบนำชมด้วยเทคโนโลยีเสมือนจริง 3D Vistaการสร้างสระบบนำชมด้วยเทคโนโลยีเสมือนจริง 3D Vista
การสร้างสระบบนำชมด้วยเทคโนโลยีเสมือนจริง 3D VistaDr.Kridsanapong Lertbumroongchai
 
นางสาว จรัญญา-กฤตย์ณัชช์-59170236-กลุ่ม-1
นางสาว จรัญญา-กฤตย์ณัชช์-59170236-กลุ่ม-1นางสาว จรัญญา-กฤตย์ณัชช์-59170236-กลุ่ม-1
นางสาว จรัญญา-กฤตย์ณัชช์-59170236-กลุ่ม-1หน่อย หน่อย
 
ความรู้เบื้องต้นภาษาจาวา
ความรู้เบื้องต้นภาษาจาวาความรู้เบื้องต้นภาษาจาวา
ความรู้เบื้องต้นภาษาจาวาThanachart Numnonda
 
Red5 streaming
Red5 streamingRed5 streaming
Red5 streamingvorravan
 

Similar to สไลด์ประกอบกิจกรรม One (language) for All (platforms) (20)

Basic Creating Virtual Reality with HDR Panoramic Photography Technique - Day...
Basic Creating Virtual Reality with HDR Panoramic Photography Technique - Day...Basic Creating Virtual Reality with HDR Panoramic Photography Technique - Day...
Basic Creating Virtual Reality with HDR Panoramic Photography Technique - Day...
 
Python Programming for Lecturer_RUS_Nonthaburi 17may2019
Python Programming for Lecturer_RUS_Nonthaburi 17may2019Python Programming for Lecturer_RUS_Nonthaburi 17may2019
Python Programming for Lecturer_RUS_Nonthaburi 17may2019
 
เริ่มต้นการเขียนโปรแกรมหุ่นยนต์
เริ่มต้นการเขียนโปรแกรมหุ่นยนต์เริ่มต้นการเขียนโปรแกรมหุ่นยนต์
เริ่มต้นการเขียนโปรแกรมหุ่นยนต์
 
Pop bot-xt v 2013-11-11
Pop bot-xt v 2013-11-11Pop bot-xt v 2013-11-11
Pop bot-xt v 2013-11-11
 
Land use(lab)
Land use(lab)Land use(lab)
Land use(lab)
 
650 1
650 1650 1
650 1
 
แบบทดสอบก่อนเรียน
แบบทดสอบก่อนเรียนแบบทดสอบก่อนเรียน
แบบทดสอบก่อนเรียน
 
Red5 workshop
Red5 workshopRed5 workshop
Red5 workshop
 
โปรแกรมย่อยและฟังก์ชันมาตรฐาน
โปรแกรมย่อยและฟังก์ชันมาตรฐานโปรแกรมย่อยและฟังก์ชันมาตรฐาน
โปรแกรมย่อยและฟังก์ชันมาตรฐาน
 
โปรแกรมย่อยและฟังก์ชันมาตรฐาน
โปรแกรมย่อยและฟังก์ชันมาตรฐานโปรแกรมย่อยและฟังก์ชันมาตรฐาน
โปรแกรมย่อยและฟังก์ชันมาตรฐาน
 
การสร้างสระบบนำชมด้วยเทคโนโลยีเสมือนจริง 3D Vista
การสร้างสระบบนำชมด้วยเทคโนโลยีเสมือนจริง 3D Vistaการสร้างสระบบนำชมด้วยเทคโนโลยีเสมือนจริง 3D Vista
การสร้างสระบบนำชมด้วยเทคโนโลยีเสมือนจริง 3D Vista
 
POP-X2 Education Kit Presentation
POP-X2 Education Kit PresentationPOP-X2 Education Kit Presentation
POP-X2 Education Kit Presentation
 
นางสาว จรัญญา-กฤตย์ณัชช์-59170236-กลุ่ม-1
นางสาว จรัญญา-กฤตย์ณัชช์-59170236-กลุ่ม-1นางสาว จรัญญา-กฤตย์ณัชช์-59170236-กลุ่ม-1
นางสาว จรัญญา-กฤตย์ณัชช์-59170236-กลุ่ม-1
 
Java AWT
Java AWTJava AWT
Java AWT
 
ความรู้เบื้องต้นภาษาจาวา
ความรู้เบื้องต้นภาษาจาวาความรู้เบื้องต้นภาษาจาวา
ความรู้เบื้องต้นภาษาจาวา
 
Advanced Predictive Modeling with R and RapidMiner Studio 7
Advanced Predictive Modeling with R and RapidMiner Studio 7Advanced Predictive Modeling with R and RapidMiner Studio 7
Advanced Predictive Modeling with R and RapidMiner Studio 7
 
03 using psp0
03 using psp003 using psp0
03 using psp0
 
Web dav android (1)
Web dav android (1)Web dav android (1)
Web dav android (1)
 
Web dav android
Web dav androidWeb dav android
Web dav android
 
Red5 streaming
Red5 streamingRed5 streaming
Red5 streaming
 

สไลด์ประกอบกิจกรรม One (language) for All (platforms)

  • 1. One (language) for All (platforms) development note ผศ.ดร.ศภชย วรพจนพศทธ ภาควชาวศวกรรมไฟฟ้าและคอมพวเตอร มหาวทยาลยธรรมศาสตร
  • 2. บนทึก ● 13 ม%ค. 58 การตดต้ง Python และเครื่องมือ การตดต่อเว็บบรการ Google Maps การตดต้ง Raspberry Pi ● 19 ม%ค. 58 การตดต้ง OpenCV สำาหรบ Windows + Raspberry Pi การเข%ยนโค ้ด computer vision ● 26 ม%ค. 58 การตดต้ง Python SDK สำาหรบ Google App Engine การพฒนา web app และ web service
  • 3. เตร%ยม Python และ IDE ● ดาวนโหลดและตดต้ง Python 2.7.8 http://www.python.org ● ดาวนโหลดและตดต้ง PyCharm IDE https://www.jetbrains.com/pycharm/
  • 4. ทดสอบ Python environment ● เปด PyCharm แล ้วเลือกสร ้าง Pure Python project ตรวจสอบว่า Interpreter ตรงกบร่นท%่ตดต้ง ● คลกท%่ Python console แล ้วพมพ print('hello') เพื่อยืนยนการทำางาน
  • 5. ทดสอบ Python IDE ● คลกขวาท%่ชื่อ project แล ้วเลือก New → Python file ● พมพโค ้ดเพื่อทดสอบ if __name__ == '__main__': print('hello, world') ● เลือกเมนู Run เพื่อส่งทำางาน เช็คผลจากหน้าต่าง Run
  • 6. อ่านเข%ยนไฟล ● เตร%ยมไฟล test.txt ท%่เป็นข ้อความสำาหรบใช ้ทดสอบ ● พมพโค ้ดสำาหรบนบคำาจากไฟล แล ้วส่ง Run if __name__ == '__main__': f = open('test.txt', 'r') counts = {} content = f.read() for word in content.split(): if word not in counts: counts[word] = 1 else: counts[word] += 1 for k,v in counts.items(): print k,v
  • 7. เข ้าถึงเนื้อหาบนอนเตอรเน็ต ● ข ้อมูลอสงหารมทรพยท%่ Sacramento เป็น CSV http://samplecsvs.s3.amazonaws.com/Sacramentoreal estatetransactions.csv ● พมพโค ้ดสำาหรบการอ่านไฟลจากเว็บ แล ้วส่ง Run
  • 8. import urllib if __name__ == '__main__': url = 'http://…csv' conn = urllib.urlopen(url) content = conn.read() conn.close() lines = content.split('r') table = [] for line in lines: fields = line.split(',') if not table: for field in fields: table.append({'name':field, 'column':[]}) else: idx = 0 for field in fields: table[idx]['column'].append(field) idx += 1 for item in table: print(item['name']) ดึงไฟลจากเว็บไซต แยกเนื้อหาตามบรรทด แยกข ้อมูลด ้วย , ประกอบข ้อมูลใหม่
  • 9. ทดสอบใช ้ด%บ๊กเกอร ● คลกต้ง breakpoint ท%่ด ้านหน้าโค ้ด lines = content.split('r') ● เลือกเมนู Run → Debug ● ตรวจสอบตวแปรในหน้าต่างย่อย Variables ● ใช ้ป่ มบน toolbar เพื่อส่งทำางาน
  • 10. ใช ้งานบรการ Google Maps ● API สำาหรบเข ้าใช ้เว็บบรการของ Google Maps https://developers.google.com/maps/documentation/ webservices/ ● ทดสอบบรการ Geocoding ด ้วยเบราเซอร https://maps.googleapis.com/maps/api/geocode/json ?address=Bangkok+Thailand
  • 11. ● พมพคำาส่งลงใน Python console เพื่อทดลองการแยกข ้อมูล ในรูปแบบ json import urllib import json url = 'https://maps.googleapis.com/maps/api/geocode/json?' args = {'address':'Bangkok,Thailand','language':'th'} url += urllib.urlencode(args) conn = urllib.urlopen(url) resp = json.load(conn) ● ทดลองดึงค่าออกจากผลลพธของเว็บบรการ resp.keys() print resp['status'] type(resp['results']) ทดสอบการแยกข ้อมูล ได ้ผลลพธ [u'status', u'results']
  • 12. ลำาดบการดึงข ้อมูลพกด ● ลำาดบในการแยกข ้อมูลพกด lat/lng ของสถานท%่ type(resp['results'][0]) <type 'dict'> resp['results'][0].keys() [u'geometry', u'address_components', u'place_id', … type(resp['results'][0]['geometry']) <type 'dict'> resp['results'][0]['geometry'].keys() [u'location', u'bounds', u'viewport', … type(resp['results'][0]['geometry']['location']) <type 'dict'> resp['results'][0]['geometry']['location'].keys() [u'lat', u'lng'] resp['results'][0]['geometry']['location'] {u'lat': 13.7563309, u'lng': 100.5017651} ข ้อมูลแบบ list ผลลพธ
  • 13. ดึงข ้อมูลพกดจากสถานท%่ ● พมพโค ้ดดึงข ้อมูล แล ้วส่ง Run import urllib import json if __name__ == '__main__': url = 'https://.../maps/api/geocode/json?' args = {'address':'Bangkok,Thailand','language':'th'} url += urllib.urlencode(args) conn = urllib.urlopen(url) resp = json.load(conn) latlng = resp['results'][0]['geometry']['location'] print latlng['lat'],latlng['lng'] for place in resp['results']: print place['formatted_address']
  • 14. เตร%ยม Raspberry Pi ดาวนโหลดและตดต้ง Raspbian ลงใน SD card โดยใช ้ โปรแกรม Win32 Disk Imager ● http://downloads.raspberrypi.org/raspbian_latest ● http://sourceforge.net/projects/win32diskimager/
  • 15. เตร%ยมคอมพวเตอร (Windows 7) ● ต้งค่า Network and Connection Sharing โดยเลือก รายการ change adapter settings ● เลือกแชร WiFi → LAN (Ethernet)
  • 16. เชื่อมต่อ PC ↔ Raspberry Pi ● เส%ยบ SD card เข ้า Raspberry Pi ● เส%ยบสาย LAN และ USB เข ้าคอมพวเตอร เช็คสถานะบูต/เครือข่ายจาก LED ส%เข%ยว ● พมพคำาส่ง cmd ใน Start menu ของ Windows ● พมพคำาส่ง arp -a เพื่อดู IP address ของบอรด
  • 17. ล็อกอนผ่าน Ethernet ● ดาวนโหลดโปรแกรม PuTTY http://www.chiark.greenend.org.uk/~sgtatham/putty/ download.html ● ล็อกอนผ่าน ssh โดยป้อน IP address ของบอรด ● รหสผู้ใช ้pi และรหสผ่าน raspberry
  • 18. ส่งไฟลจาก PC ● ดาวนโหลดและตดต้งโปรแกรม WinSCP (secure copy) http://sourceforge.net/projects/winscp/ ● โอนย ้ายไฟล ???.py ไป แล ้วทดสอบเร%ยกใช ้เช่น python test.py
  • 19. ต้งค่าเร่มต ้นให ้บอรด ● พมพคำาส่ง sudo raspi-config ● เลือกรายการ Expand Filesystem เพื่อขยายระบบไฟล ให ้ใช ้เต็มพื้นท%่ SD card ● กดป่ มลูกศรหรือ Tab เพื่อเลือก <Finish>
  • 20. ตดต้งซอฟตแวรพื้นฐาน ● พมพคำาส่งเพื่อตดต้งแพคเกจ sudo apt-get install tightvncserver ● เปดใช ้งาน vncserver แล ้วป้อนรหสผ่าน vncserver :0 -geometry 800x600 -depth 16 ● ไปท%่เว็บ chrome เพื่อตดต้งแอพ VNC viewer https://chrome.google.com/webstore/category/apps
  • 21. ตดต้ง VNC client บน PC ● เชื่อมต่อบรการ VNC โดยป้อน IP address:0 ● เลือก LXTerminal เพื่อเปด console รบคำาส่ง
  • 22. ตดต้งเครื่องมือท%่จำาเป็น ● การต้ง vncserver ให ้ทำางานช่วงบูตระบบ http://www.raspberrypi.org/documentation/remote- access/vnc/ ● แก ้ไขการทำางานของสครปต vncboot ให ้เป็นผู้ใช ้pi sudo -u pi vncserver :0 -geometry 800x600 -depth 16 -pixelformat 565
  • 23. ตดต้งเครื่องมือสำาหรบ Python ● พมพคำาส่งเพื่อตดต้ง wxPython sudo apt-get install python-wxgtk2.8 wx2.8- i18n python-wxtools ● เลือกแอพ PyCrust จากเมนู ป่ ม Ctrl + ] หรือ [ เพื่อ ขยาย/ลดขนาด font ● พมพคำาส่ง pyalamode หรือ pyalacarte เพื่อเปด ใช ้editor
  • 24. ตดต้ง OpenCV ใน PC ● ดาวนโหลดและตดต้ง numpy สำาหรบ Python 2.7 http://sourceforge.net/projects/numpy/files/NumPy/ ● ดาวนโหลดและขยายไฟล OpenCV http://sourceforge.net/projects/opencvlibrary/files/ opencv-win/ ● สำาเนาไฟล cv2.pyd จากโฟลเดอร opencvbuild python2.7x86 ไปท%่ C:Python27Lib ● ทดสอบการตดต้งจาก Python Console import cv2
  • 25. สร ้างโครงของ computer vision ● พมพโค ้ดเพื่ออ่านภาพจากเว็บแคม กลบด ้าน และแสดง ผลทางหน้าต่าง import cv2 if __name__ == '__main__': cap = cv2.VideoCapture(0) cv2.namedWindow('mirror') while True: res,frame = cap.read() cv2.flip(frame, 1, frame) cv2.imshow('mirror', frame) if cv2.waitKey(100) == 27: break cap.release() cv2.destroyAllWindows() รอ 100 msec ป่ ม Esc เพื่อหยด อ่านภาพ ประมวลผล นำาไปใช ้
  • 26. ตดต้ง OpenCV ใน RPi ● พมพคำาส่งเพื่อตดต้ง OpenCV sudo apt-get install python-opencv ● เร%ยกใช ้pyalamode เพื่อพมพโค ้ด mirror.py ● พมพคำาส่งเพื่อเร%ยกใช ้ python mirror.py การจบภาพจากเว็บแคมด ้วย OpenCV ใน Raspberry Pi จะหน่วง และม% ความซำ้าของภาพ
  • 27. ใช ้filter เพื่อแปลงรูป ● เข%ยนโค ้ดแทรกใน mirror.py ● สร ้างฟงกชนก่อน if __name__ == '__main__': def onChange(pos): print 'Current position is ' + str(pos) ● สร ้าง trackbar หลงบรรทด cv2.namedWindow() cv2.createTrackbar('filter', 'mirror', 0, 2, onChange) ● เข%ยนโค ้ดเพื่อทำาเงื่อนไขประมวลผลภาพ 0 ไม่ประมวลผล 1 แปลงเป็นภาพเฉดเทา 2 แปลงเป็นเส ้นขอบ (อลกอรธึม Canny)
  • 28. ใช ้filter เพื่อแปลงรูป ● เข%ยนโค ้ดแทรกหลงบรรทด cv2.flip() if cv2.getTrackbarPos('filter', 'mirror') == 1: frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2GRAY) if cv2.getTrackbarPos('filter', 'mirror') == 2: frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2GRAY) frame = cv2.Canny(frame, 50, 200)
  • 29. สร ้าง time lapse camera ● เข%ยนโค ้ดเพื่อสร ้างตวบนทึก video โดยกำาหนด format กบ frame rate w = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)) h = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)) format = cv2.cv.CV_FOURCC('M','J','P','G') out = cv2.VideoWriter('test.avi', format, 10, (w,h)) ● บนทึกเฟรมลงในคลป out.write(frame) ● ควบคม frame rate โดยการหน่วงเวลา if cv2.waitKey(100) == 27:
  • 30. import cv2 if __name__ == '__main__': cap = cv2.VideoCapture(0) w = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)) h = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)) format = cv2.cv.CV_FOURCC('M','J','P','G') out = cv2.VideoWriter('test.avi', format, 10, (w,h)) cv2.namedWindow('preview') while True: res,frame = cap.read() frame = cv2.flip(frame, 1) cv2.imshow('preview', frame) out.write(frame) if cv2.waitKey(100) == 27: break cap.release() cv2.destroyAllWindows() ใน Raspberry Pi ให ้ตดต้ง VLC player เพื่อดูไฟลท%่บนทึก sudo apt-get install vlc ต้งสื่อ บนทึก
  • 31. หาตำาแหน่งแล ้วแปลงพกด ● ประยกตใช ้ในแอพประเภทสแกนเอกสาร http://www.pyimagesearch.com/2014/09/01/build- kick-ass-mobile-document-scanner-just-5-minutes/ ● cv2.cvtColor() ● cv2.Canny() ● cv2.findContours() ● cv2.warpPerspective() แปลงภาพ เป็นเฉดเทา หาขอบด ้วย Canny Bounding rectangle Perspective warping
  • 32. แปลงภาพเป็น binary ret,frame = cap.read() (h,w,_) = frame.shape; w = w/2; h = h/2 img = cv2.resize(frame, (w,h)) img = cv2.flip(img, 1) gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray_img = cv2.GaussianBlur(gray_img, (5, 5), 0) edge_img = cv2.Canny(gray_img, 50, 100) kernel = numpy.ones((5,5), numpy.uint8) edge_img = cv2.morphologyEx(edge_img, cv2.MORPH_CLOSE, kernel) อ่านและย่อภาพ หาขอบ
  • 33. หา 4 จดล ้อมภาพ (cnts, _) = cv2.findContours(edge_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnts = sorted(cnts,key=cv2.contourArea,reverse=True)[:5] rect = numpy.zeros((4, 2), dtype=numpy.float32) for c in cnts: peri = cv2.arcLength(c, True) pts = cv2.approxPolyDP(c, 0.01 * peri, True) if len(pts) == 4 and cv2.contourArea(c) > 0.15*w*h: cv2.drawContours(img, [pts], -1, (0, 255, 0), 2) sums = [pt[0].sum() for pt in pts] diffs = [numpy.diff(pt[0]) for pt in pts] rect[0] = pts[numpy.argmin(sums)][0] rect[1] = pts[numpy.argmin(diffs)][0] rect[2] = pts[numpy.argmax(diffs)][0] rect[3] = pts[numpy.argmax(sums)][0] ล ้อมเส ้น หาจดท%่ 4 มม สร ้างกรอบ
  • 34. แปลงพกดของภาพ (tl,tr,bl,br) = rect top = cv2.norm(tr,tl) bottom = cv2.norm(br,bl) width = max(int(top), int(bottom)) left = cv2.norm(tl,bl) right = cv2.norm(tr,br) height = max(int(left), int(right)) dst = numpy.array([[0, 0],[width - 1, 0], [0, height - 1],[width - 1, height – 1]], dtype=numpy.float32) M = cv2.getPerspectiveTransform(rect, dst) warped = cv2.warpPerspective(img, M, (width, height)) warped = cv2.flip(warped,1) คำานวณขนาด แปลง พกด
  • 35. แนวคด Internet of Things Cloud computing gateway sensor ค่าเซ็นเซอร server HTTP - REST
  • 36. เตร%ยม Google App Engine ● เงื่อนไข: ม% google account + ฟร% = จำากดการใช ้ ● ดาวนโหลดและตดต้ง App Engine SDK for Python https://cloud.google.com/appengine/downloads
  • 37. ข้นตอนสร ้างบรการบน cloud ● กำาหนดช่องทาง (URL) ในการเข ้าถึงบรการ = web API http://AAA.appspot.com/xxx/yyy/zzz?arg1=?&arg2=? ตวอย่างเช่น บรการ Geocoding ของ Google Maps https://maps.googleapis.com/maps/api/geocode/ json?address=Bangkok+Thailand ● ออกแบบโมเดลของการแลกเปล%่ยนข ้อมูล ● เข%ยนโค ้ดประมวลผล HTTP requests: GET,POST,... จำาแนกข ้อมูล > จดการฐานข ้อมูล > สร ้างผลลพธ ● ตอบสนอง = return code + HTML (web apps) หรือ XML/JSON (web services)
  • 38. กรณ%ตวอย่าง sensor acquisition ● มมมองอปกรณ = data entity ค่า + คณสมบต (what,which,where,how,...) ● มมมองเซรฟเวอร = database entity เวลา + อ ้างอง + ค่า + คณสมบต (what,how,...) ● มมมองผู้ใช ้= information เทรนดของค่า / ตวแทนของค่าข ้อมูล / ...
  • 39. application: rpi-box version: 1 runtime: python27 api_version: 1 threadsafe: yes handlers: - url: /favicon.ico static_files: favicon.ico upload: favicon.ico - url: /ws script: service.app - url: /ui script: ui.app - url: .* script: main.app libraries: - name: webapp2 version: latest - name: jinja2 version: latest ไลบราร%ท%่ขอใช ้ การเชื่อม URL กบโค ้ด ชื่อของแอพพลเคชน ไฟล app.yaml
  • 40. การใช ้งาน Google App Engine ● กดป่ ม Run เพื่อใช ้PC เป็นเซรฟเวอร ● ใช ้เบราเซอรดูการทำางานจากพอรต http://localhost:port ● กดป่ ม Logs เพื่อตรวจสอบสถานะทำางาน ● ตรวจสอบฐานข ้อมูล http://localhost:admin_port ● หลงยืนยนการทำางาน กดป่ ม Deploy เพื่ออพโหลด ● ใช ้เบราเซอรไปท%่เซรฟเวอร http://appname.appspot.com
  • 41. โครงของเว็บบรการ (service.py) ● HTTP request > ประมวลผล > JSON #!/usr/bin/env python import webapp2 import json class TestHandler(webapp2.RequestHandler): def get(self): resp = {'status':'OK'} self.response.write(json.dumps(resp)) app = webapp2.WSGIApplication([ ('/ws/test', TestHandler) ], debug=True) ใช ้เบราเซอรดูท%่ http://localhost:xxxx/ws/test
  • 42. เตร%ยมต ้นแบบข ้อมูล (model.py) ● นยามข ้อมูล when = เวลา which = แหล่งข ้อมูล what = ข ้อมูล how = วธ%การ where = ตำาแหน่ง ... from google.appengine.ext import ndb class MyData(ndb.Model): timestamp = ndb.DateTimeProperty(auto_now_add=True) serial = ndb.IntegerProperty(required=True) value = ndb.FloatProperty(required=True)
  • 43. เพ่มบรการ (service.py) class UpdateHandler(webapp2.RequestHandler): def get(self): sn = self.request.get('sn') val = self.request.get('value') if sn != '' and val != '': resp = {'status':'OK'} data = MyData(serial=int(sn),value=float(val)) data.put() else: resp = {'status':'ERR'} self.response.write(json.dumps(resp)) app = webapp2.WSGIApplication([ ('/ws/test', TestHandler), ('/ws/update', UpdateHandler) ], debug=True) แยกข ้อมูลจาก arg จดเก็บข ้อมูล http://appname.appspot.com/ws/update?sn=11&val=1.0
  • 44. เตร%ยมเชื่อมต่อ Arduino ● Raspberry Pi สามารถเชื่อมต่อ Arduino ผ่านพอรต USB ท้งรูปแบบข ้อมูลและโค ้ด sudo apt-get install arduino arduino-mk python-serial ● เส%ยบ Arduino เข ้ากบ Raspberry Pi ● พมพคำาส่ง dmesg ดูรายงานการเชื่อมต่อ ● ตรวจสอบพอรตอนกรมท%่เป็น Arduino: ttyACMx หรือ ttyUSBx > ls /dev/tty*
  • 45. สร ้างแหล่งข ้อมูล ● เข%ยนโค ้ดบน Arduino เพื่อส่มวดและรายงานผล void setup() { Serial.begin(9600); } void loop() { int val = analogRead(0); Serial.println(val); delay(1000); } หากม%หลายข ้อมูล แนะนำาให ้ใช ้csv หรือ json Serial.print(val1); Serial.print(','); Serial.print(val2); Serial.print(','); Serial.println(val3);
  • 46. ส่งผ่านข ้อมูล ● สร ้างไฟล data_feed.py สำาหรบ Raspberry Pi import json import serial import urllib if __name__ == '__main__': ser = serial.Serial('/dev/ttyACM0',9600,timeout=10) ser.flush() while True: line = ser.readline() data = line.strip() args = {'sn':11, 'value':data} url = 'http://rpi-box.appspot.com/ws/update?' conn = urllib.urlopen(url + urllib.urlencode(args)) resp = json.load(conn) print resp['status'] เชื่อมต่อพอรตอนกรม รบและจำาแนกข ้อมูล
  • 47. โครงของเว็บแอพ (ui.py) ● HTTP request > สืบค ้นและจดรูปข ้อมูล > HTML import webapp2 import os import jinja2 JINJA_ENV = jinja2.Environment(loader= jinja2.FileSystemLoader(os.path.dirname(__file__)), extensions=['jinja2.ext.autoescape'],autoescape=True) class ViewHandler(webapp2.RequestHandler): def get(self): ... self.response.write(template.render(resp)) app = webapp2.WSGIApplication([ ('/ui/view', ViewHandler) ], debug=True)
  • 48. สืบค ้นข ้อมูลจาก datastore ● ข ้อมูลถูกจดเก็บในรูป object อ ้างองได ้ด ้วย key ● ใช ้เทคนค templating เพื่ออ่านไฟล HTML ต ้นแบบ from model import * sn = self.request.get('sn') if sn != '': resp = {'status':'OK'} query = MyData.query(MyData.serial==int(sn)) data = query.fetch(10) resp['values'] = [entity.value for entity in data] else: resp = {'status':'ERR'} template = JINJA_ENV.get_template('index.html') กำาหนดเงื่อนไข/สืบค ้น
  • 49. ไฟล HTML ต ้นแบบ ● ใช ้การทดแทน HTML tag ในระหว่าง rendering ทดแทนตวแปร <div data-role="footer"> <h2>{{status}}</h2> </div> แบบรายการ list, tuple <ui> {% for value in values %} <li>Value is {{value}}</li> {% endfor %} </ui> ดึงค่าตวแปรมาแสดง วนสร ้างรายการจาก list