樹莓派因為可以連接感測器取得所需要的環境資訊,且又具備Linux作業系統可以安裝許多軟體及伺服器,因此很適合作為物聯網系統中的邊緣運算裝置(Edge Device)。在實際工廠生產線的應用上,OPC UA是現在非常流行的協定之一,本文的目的即在於示範如何在樹莓派上安裝OPC UA Server,讓它可以被其它裝置以OPC UA的協定讀取它所感測到的資料。
在本文中的樹莓派所連接的感測器延續前面文章中的溫濕度以及聲音和亮度感測器,我們的目的是藉由OPC UA的協定,在不同裝置間傳送這些感測器的資料。也就是說,在其中一台樹莓派上執行OPCUA Server,在另外一台機器上(可以是樹莓派,也可以是PC)執行客戶端程式以取得伺服器上的資料。
首先是伺服器的部份,在樹莓派的作業系統下,要先執行以下的安裝程序:
sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get install libxml2-dev libxmlsec1-dev libffi-dev
上述的指令主要是安裝在OPC UA Server模組中可能會使用到的開發程式庫。接著要安裝Python所需要的套件,一般而言,建議所有執行的專案都為其建立一個Python的虛擬環境,在虛擬環境中安裝個別Python專案所需要的模組及套件會比較單純且不易出錯。
pip install cryptograpy
pip install freeopcua
所有模組順利安裝完畢之後,先來看伺服器端的程式碼(opcua_server.py),我們把目前伺服器的ip放在ip.txt檔案中,其中ip.txt的內容看起來會是像下面這個樣子:
192.168.73.204
ip.txt中的內容,就是目前你的樹莓派本身的IP位置,這個值要確定是能夠被連線的,之後客戶端程式使用同樣的IP才能夠順利連線。接著才是我們的主程式:
from opcua import Server
from random import randint
import datetime
from gpiozero import MCP3008
import time
import Adafruit_DHT
GPIO_PIN = 4
humdity, temperature, light, sound = 0, 0, 0, 0
light_adc = MCP3008(0)
sound_adc = MCP3008(1)
with open("ip.txt", "r") as f:
ip = f.read().strip()
server =Server()
url ="opc.tcp://{}:4840".format(ip)
print("Path:", url)
server.set_endpoint(url)
name ="OPCUA_SIMULATION_SERVER"
addspace =server.register_namespace(name)
node=server.get_objects_node()
Param=node.add_object(addspace,"Parameters")
Temperature = Param.add_variable(addspace,"Temperature",0)
Humidity = Param.add_variable(addspace,"Humidity",0)
Sound =Param.add_variable(addspace,"Sound",0)
Light = Param.add_variable(addspace,"Light",0)
Temperature.set_writable()
Humidity.set_writable()
Sound.set_writable()
Light.set_writable()
server.start()
while(True):
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, GPIO_PIN)
sound = sound_adc.value
light = light_adc.value
#print(temperature, humidity, sound, light)
Temperature.set_value(temperature)
Humidity.set_value(humidity)
Light.set_value(light)
Sound.set_value(sound)
# time.sleep(2)
在上面的程式中,我們利用前面教學文章中介紹的內容取得了溫濕度感測器、聲音感測器、以及亮度感測器的內容,分別放在temperature, humidity, sound, light這幾個變數中,而在一開始定義OPC UA伺服器可以被存取的資料中,分別是Temperature、Humidity、Sound、Light等4個物件,把它們設定成OPC UA伺服器中可以提供客戶端讀取的參數,再利用迴圈不斷地寫入新的資料即可。
以下則是OPC UA客戶端的程式碼(opcua_client.py):
from opcua import Client
import time
with open("ip.txt", "r") as f:
ip = f.read().strip()
url="opc.tcp://{}:4840".format(ip)
print("Client URL:", url)
client=Client(url)
client.connect()
print("Client Connected")
while (True):
Temperature=client.get_node("ns=2;i=2")
temperature=Temperature.get_value()
Humidity=client.get_node("ns=2;i=3")
humidity=Humidity.get_value()
print(temperature, humidity)
Sound=client.get_node("ns=2;i=4")
sound=Sound.get_value()
Light=client.get_node("ns=2;i=5")
light=Light.get_value()
print(sound, light)
time.sleep(1)
在客戶端中我們讀取同一個內容的ip.txt,利用該檔案的內容作為伺服器的IP位址進行連線。連線完成之後,再利用一個無窮迴圈取出OPC UA所提供的資料。
上述的程式都建立完成之後,先執行opcua_server.py,過一段時間等出現等待訊息之後,如果是同一台機器進行測試,則可再開另外一個終端機執行opcua_client.py即可。