WebIOPi 0.7 Released
To use WebIOPi interface that uses javascript to control our GPIO from a web page that can be accessed anywhere in the world.
1) 基本安裝作文件:
- 修改web登入帳號及密碼,執行webiopi-passwd再重新啓動服務
$ webiopi-passwd
設定檔/etc/webiopi/config
#一次啓動2個python script
[SCRIPTS]
myscript = /home/pi/iot/python/script.py
myscript1=/home/pi/iot/examples/scripts/blink/script.py
[HTTP]
# HTTP Server configuration
enabled = true
port = 80
# File containing sha256(base64("user:password"))
# Use webiopi-passwd command to generate it
passwd-file = /etc/webiopi/passwd
# Change login prompt message
prompt = "WebIOPi"
# Use doc-root to change default HTML and resource files location
doc-root = /home/pi/iot/html
# Use welcome-file to change the default "Welcome" file
#welcome-file = index.html
myscript = /home/pi/iot/python/script.py
myscript1=/home/pi/iot/examples/scripts/blink/script.py
[HTTP]
# HTTP Server configuration
enabled = true
port = 80
# File containing sha256(base64("user:password"))
# Use webiopi-passwd command to generate it
passwd-file = /etc/webiopi/passwd
# Change login prompt message
prompt = "WebIOPi"
# Use doc-root to change default HTML and resource files location
doc-root = /home/pi/iot/html
# Use welcome-file to change the default "Welcome" file
#welcome-file = index.html
啓動Webiopi
sudo webiopi -d -c /etc/webiopi/config
------------Ittraining IoT Platform-----------------
it:WebIOPi command-line usage
webiopi [-h] [-c config] [-l log] [-s script] [-d] [port]
Options:
-h, --help Display this help
-c, --config file Load config from file
-l, --log file Log to file
-s, --script file Load script from file
-d, --debug Enable DEBUG
Arguments:
port Port to bind the HTTP Server
cat /usr/bin/webiopi
#!/bin/sh python3 -m webiopi $*
-m mod : run library module as a script
主程式為 __main__.py
INSTALL=/usr/local/lib/python3.2/dist-packages/WebIOPi-0.7.0-py3.2-linux-armv6l.egg/webiopi
不要密碼的話, 直接刪除 rm /etc/webiopi/passwd
2) 同學必看
https://code.google.com/p/webiopi/wiki/Tutorial_Devices
3)youtube 影片
https://www.youtube.com/watch?v=6RaBz01pi4E
4) References:
http://ruten-proteus.blogspot.tw/2012/11/webiopi-gpio.html
The customization process has 3 steps :
- Write a simple Python script to initialize the GPIO and handle auto on/off
- Write a simple HTML/Javascript page
- Configure WebIOPi Server
- You can build your HTML / Web UI from scratch, using the WebIOPi JS library or not.
- You can extend the WebIOPi behavior by loading custom Python script using an Arduino like syntax with setup/loop functions
HTML (javascript)與python 的關係 home- pi - myproject - html --> .html
- python --> Python script .py
1) html 為前端使用者界面 .html檔案,html 主要是利用 htdocs\webiopi.js的java script WEB I/O函式庫
<script type="text/javascript" src="/webiopi.js"></script>
2) python 放的是.py程式, 負責Web後端處理 , 用來get/set 系統狀態。python 亦有python I/O 函式庫可使用。python I/O 函式庫有底層GPIO, I2C, SPI 抽象Bus界面類別。函式庫亦有針對一些感測器, 溫度、溼度、壓力感測器模組,提供裝置驅動程式,以OO物件思維,提供類別相對應的Method。 (如何自己新增一個Device? 往下看!)
# python script code
@webiopi.macro
def setLightHours(on, off):
global HOUR_ON, HOUR_OFF
HOUR_ON = int(on)
HOUR_OFF = int(off)
return getLightHours()
def setLightHours(on, off):
global HOUR_ON, HOUR_OFF
HOUR_ON = int(on)
HOUR_OFF = int(off)
return getLightHours()
3) 從HTML(javascript)呼叫後端python 程式方法
javascript 利用 callMacro()的方式,來呼叫python 的函式
如:
webiopi().callMacro("setLightHours", hours, updateLightHours);
"setLightHours": 為python 函式 (即macro)
hours: python 函式的代入參數值
updateLightHours: 為javascript Call Back函式, 當macro返回後,要呼叫那個函式來處理。通常此函式用來更新HTML UI的值。
// Following function will process data received from set/getLightHours macro.
var updateLightHours = function(macro, args, response) {
var hours = response.split(";");
// Following lines use jQuery functions
$("#inputOn").val(hours[0]);
$("#inputOff").val(hours[1]);
}
var hours = response.split(";");
// Following lines use jQuery functions
$("#inputOn").val(hours[0]);
$("#inputOff").val(hours[1]);
}
HTTP遠端呼叫 (WebIOPi REST API )
WebIOPi provides a REST API. Here’s the API reference: https://code.google.com/p/webiopi/wiki/RESTAPI
curl -v -X POST http://192.168.1.116/GPIO/22/function/out
set "in" or "out"
curl -v -X POST http://192.168.1.116/GPIO/22/value/1
set value "1" or "0"
有密碼時或非80 port時
curl -v -X POST -u pi:raspberry http://192.168.1.116:8000/GPIO/22/function/out
為URL 路徑設立新的別名
In /etc/webiopi/config
[ROUTES]
# Custom REST API route syntax :
# source = destination
# source : URL to route
# destination : Resulting URL
# Adding routes allows to simplify access with Human comprehensive URLs
# source = destination
# source : URL to route
# destination : Resulting URL
# Adding routes allows to simplify access with Human comprehensive URLs
# In the next example with have the bedroom light connected to GPIO 25
# and a temperature sensor named temp2, defined in [DEVICES] section
# - GET /bedroom/light => GET /GPIO/25/value, returns the light state
# - POST /bedroom/light/0 => POST /GPIO/25/value/0, turn off the light
# - POST /bedroom/light/1 => POST /GPIO/25/value/1, turn on the light
# - GET /bedroom/temperature => GET /devices/temp2/temperature/c, returns the temperature in celsius
/bedroom/light = /GPIO/22/value
#/bedroom/temperature = /devices/temp2/temperature/c
# - GET /bedroom/light => GET /GPIO/25/value, returns the light state
# - POST /bedroom/light/0 => POST /GPIO/25/value/0, turn off the light
# - POST /bedroom/light/1 => POST /GPIO/25/value/1, turn on the light
# - GET /bedroom/temperature => GET /devices/temp2/temperature/c, returns the temperature in celsius
/bedroom/light = /GPIO/22/value
#/bedroom/temperature = /devices/temp2/temperature/c
curl -v -X POST http://192.168.1.116/GPIO/22/value/1
curl -v -X POST http://192.168.1.116/bedroom/light/1
curl -v -X POST http://192.168.1.116/device/sensor/temperature/c
* Closing connection #0
1root@raspberrypi:/etc/webiopi# curl -v -X POST http://192.168.1.116/bedroom/light/0
* About to connect() to 192.168.1.116 port 80 (#0)
* Trying 192.168.1.116...
* connected
* Connected to 192.168.1.116 (192.168.1.116) port 80 (#0)
> POST /bedroom/light/0 HTTP/1.1
> User-Agent: curl/7.26.0
> Host: 192.168.1.116
> Accept: */*
>
* additional stuff not fine transfer.c:1037: 0 0
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: WebIOPi/0.7.0/Python3.2
< Date: Thu, 02 Oct 2014 07:23:14 GMT
< Cache-Control: no-cache
< Content-Type: text/plain
< Content-Length: 1
<
* Closing connection #0
1root@raspberrypi:/etc/webiopi# curl -v -X POST http://192.168.1.116/bedroom/light/0
* About to connect() to 192.168.1.116 port 80 (#0)
* Trying 192.168.1.116...
* connected
* Connected to 192.168.1.116 (192.168.1.116) port 80 (#0)
> POST /bedroom/light/0 HTTP/1.1
> User-Agent: curl/7.26.0
> Host: 192.168.1.116
> Accept: */*
>
* additional stuff not fine transfer.c:1037: 0 0
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: WebIOPi/0.7.0/Python3.2
< Date: Thu, 02 Oct 2014 07:23:14 GMT
< Cache-Control: no-cache
< Content-Type: text/plain
< Content-Length: 1
<
* Closing connection #0
如何加入REST API
1) python script在def函式定義先一行標示 @webiopi.macro 即可使該函數, 成為HTTP遠端呼叫的對象 # destroy function is called at WebIOPi shutdown def destroy(): GPIO.digitalWrite(LIGHT, GPIO.LOW) @webiopi.macro def getLightHours(): return "%d;%d" % (HOUR_ON, HOUR_OFF) @webiopi.macro def setLightHours(on, off): global HOUR_ON, HOUR_OFF HOUR_ON = int(on) HOUR_OFF = int(off) return getLightHours() 2) HTTP 遠端呼叫使用方式: 執行: curl -v -X POST http://192.168.1.116/macros/getLightHours 輸出顯示: * About to connect() to 192.168.1.116 port 80 (#0) * Trying 192.168.1.116... * connected * Connected to 192.168.1.116 (192.168.1.116) port 80 (#0) > POST /macros/getLightHours HTTP/1.1 > User-Agent: curl/7.26.0 > Host: 192.168.1.116 > Accept: */* > * additional stuff not fine transfer.c:1037: 0 0 * HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Server: WebIOPi/0.7.0/Python3.2 < Date: Tue, 07 Oct 2014 07:19:09 GMT < Cache-Control: no-cache < Content-Type: text/plain < Content-Length: 5 < * Closing connection #0 20;18
如何產生特定裝置的類別 未來只要修改 /etc/webiopi/config 就可以使用特定Sensor/Device,而非通用GPIO類別,而是產生特定裝置類別, 並且後續使用HTTP GET/POST來完成存取, 例如 # GPIO Expander(MCP302)裝置, 設定PIN 3值為HIGH HTTP POST /devices/mcp/digital/3/value/1#溫度感測裝置, 取得溫度並且以攝氏溫度傳回
HTTP GET /devices/tmp/temperature/c
程式架構:
1) 底層裝置HAL程式目錄結構, .py 為對應的device Interface python language
進入安裝路徑 /usr/local/lib/python3.2/dist-packages/WebIOPi-0.7.0-py3.2-linux-armv6l.egg/webiopi/devices
./webiopi/devices
├── analog --> 類比裝置class
├── bus.py
├── digital/gpio.py --> 數位裝置class,gpio上層python,call _webiopi/GPIO.py
├── i2c.py ├── __init__.py --> Common INIT 函式 ├── instance.py ├── manager.py ├── onewire.py ├── __pycache__ ├── sensor --> 感測裝置class ├── serial.py ├── shield └── spi.py bus.py I/O 函式for spi.py, i2c.py,serial.py (low level I/O Python Library)
./digital
├── ds2408.py ├── gpio.py ├── __init__.py ├── mcp23XXX.py ├── pcf8574.py
2) 在Sensor 目錄下新增一個的Virtual Sensor
2-1 新增Device class :在webiopi\devices\sensor
新增 itvirtual.py 檔案 class TMPSi7020(I2C, Temperature):
def __init__(self,slave=0x50,b=0): self.aa=b I2C.__init__(self, toint(slave)) def __str__(self): return "TMP110(slave=0x%02X)" % self.slave def __getKelvin__(self): return 10 def __getCelsius__(self): self.aa+=1 return self.aa def __getFahrenheit__(self): return 30 2-2 新增裝置名稱 : 修改 webiopi\devices\sensor\__init__.py DRIVERS = {} DRIVERS["bmp085"] = ["BMP085", "BMP180"] DRIVERS["tmpXXX"] = ["TMP75", "TMP102", "TMP275"] DRIVERS["tslXXXX"] = ["TSL2561", "TSL2561CS", "TSL2561T", "TSL4531"] DRIVERS["itvirtual"] = ["TMPSi7020"] 2-3 編輯/etc/webiopi/config # USB serial adapters #usb0 = Serial device:ttyUSB0 baudrate:9600 #usb1 = Serial device:ttyACM0 baudrate:9600 Si7020 = TMPSi7020 #temp1 = TMP102 slave:0x49 #temp2 = DS18B20 2-4 建構前端網頁 device.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content = "width = 420, user-scalable = no" /> <title>WebIOPi | Devices Monitor</title> <script type="text/javascript" src="/webiopi.js"></script> <script type="text/javascript"> webiopi().ready(function() { var content = $("#content"); var device = webiopi().newDevice("Temperature","Si7020"); device.element = $("<div>"); content.append(device.element); device.refreshUI(); }); </script> <style type="text/css"> button, .FunctionBasic { width: 50px; } </style> </head> <body> <h1>Si7020 Temperature</h1> <div id="content"> </div> </body> </html> 2-5 重新啓動 webiopi ,連入 http://192.168.1.116/device.html
curl -v -X POST http://192.168.1.116/bedroom/temperature
最底層的Driver驅動使用C
C code , 使用 open("/dev/mem")方式做上層User Space Driver 處理
GPIO.py python script will load GPIO library (.so)
./_webiopi ├── GPIO.cpython-32mu.so (C Driver library) ├── GPIO.py (load C library) ├── __init__.py └── __pycache__ ├── GPIO.cpython-32.pyc └── __init__.cpython-32.pyc
沒有留言 :
張貼留言