6.1 悟空屬性架構
在介紹如何實作悟空類別(WuClass)之前,將先解釋悟空裝置(Node)是如何透過悟空類別元件(Component)傳遞資料,這項說明有助於掌握接下來的實作章節。
悟空裝置中的軟體架構可以用以下這張圖清楚地描述:
圖中最核心的區塊爲屬性架構(Profile Framework, WKPF), 這個架構是用來管理悟空類別與悟空物件(WuObject)如何在裝置上運作。
接著,圖中最上方的區塊爲資料流表單(Link table),這張表單是由主控臺(Master)在部署程式時所產生, 表單內容記錄了每一筆資料流的來源屬性與目的屬性,因此當資料在傳遞(Property propagation)前, 都會先確認這張表單。最後,圖中右下角的區塊爲悟空物件,每個裝置可以包含多個悟空物件, 而每個物件中都有一個更新函式(Update()),更新函式的執行將視何時被屬性架構呼叫, 若該物件的類別有定義刷新速度(refresh rate)這項屬性的話(於下一節詳述),這個函式會被定期呼叫;
另外,當屬性架構被任一個更新函式通知這個物件的屬性有新資料時,這個函式也會被呼叫, 這個函式爲悟空類別實作的一部分,將於6.3節說明。

屬性架構(Profile Framework, WKPF)
悟空屬性架構運行於悟空裝置上,使得裝置具有服務架構。當主控臺部署一個資料流應用時,屬性架構會監控網路中的每一個悟空裝置,並管理彼此的通訊。
這個架構負責四項主要的功能:
- 載入悟空類別並產生悟空物件到悟空裝置。
- 使得主控臺能尋找每個裝置中的類別與物件清單(Get available profiles and endpoints)。
- 呼叫物件內的更新函式(定期或是被觸發)。
- 依照資料流表單上的來源與目的,在各個物件屬性間傳遞新的資料。
屬性(Property)
屬性是屬性架構裏最小的資料單位,屬性也是最主要控制悟空物件的方式。正如我們將於下一小節提到的,每一個屬性有四個元素的定義,包含名稱(Name),存取(Access),資料形態(Datatype)以及初始值(Default)。
悟空類別與悟空物件(WuClass and WuObject)
如同名稱所示,悟空類別與物件導向程式中的類別具有相似的定義,各個變數與函式均定義於悟空類別內,並用以產生悟空物件;悟空物件是用以處理應用服務的資料的最小單位,悟空物件均被執行在每個裝置中。
悟空物件屬性儲存區(WuObject Property Store)
每個悟空物件上屬性的資料,均由屬性架構用一個共有的儲存區來管理,屬性架構並提供訪問儲存區的函式(Property access),讓每個悟空物件在更新函式被呼叫的時候,可以用儲存區的函式存取其資料。這個設計讓屬性架構能監控每個物件屬性的改變,並適時將改變的值傳遞到該資料流的目的地。
更新函式(Update Method)
更新函式實作了悟空類別的行爲,這個函式會在該物件屬性的值改變時被執行,或是依照所定義的刷新速度被規律地執行。一旦更新函式被呼叫執行後,悟空物件會透過儲存區的函式讀出被改變的值,並在更新函式中使用。因此,撰寫悟空類別相當於撰寫更新函式。
另外,悟空物件之所以要透過儲存區函式來讀寫值的原因是,悟空物件並不儲存本身屬性的值,這個值會被儲存於屬性架構中,以便於管理資料傳遞與監控,因此,悟空物件需要在更新函式中訪問屬性架構,以讀取更新其屬性的值。
更新函式的執行過程可分爲以下三個階段:
- 向屬性架構的屬性儲存區讀取某一屬性的值
- 根據更新函式內的程式做資料運算
- 寫入數值到屬性架構的屬性儲存區以更改某一屬性的值
以一個簡易的按鈕感測器(Button)爲例,它的更新函式包含了第2和3階段,但跳過了第1階段,原因是它身爲感測器,無需向屬性架構讀取值,而是定期將感測到的值寫入屬性架構。另一個例子是燈光致動器(Light actuator or LED),由於它沒有輸出的屬性,所以它的更新函式包含了第1和2階段,但跳過了第3階段,一旦當它的更新函式被呼叫時,它會向屬性架構讀取值,來決定是否開燈或關燈。
資料流表單(Link Table)
這個表單記錄了每一筆資料流的來源屬性與目的屬性,並由主控臺在部署應用服務時傳給悟空裝置。
訪問儲存區的函式(Property Access)
def setProperty(self,pID,val):
self.cls.setProperty(self.port,pID,val)
def getProperty(self,pID):
return self.cls.getProperty(self.port,pID)
setProperty可以讓悟空物件將某屬性的值寫入到儲存區getPropert可以讓悟空物件從儲存區讀取某屬性的值
此函式實作在https://github.com/wukong-m2m/wukong-darjeeling/blob/release0.4/wukong/gateway/udpwkpf/udpwkpf.py。
在接下來的章節中,我們會時常使用這兩個函式訪問儲存區。
範例:用按鈕控制燈光開關

經過以上的說明,我們將比較4.2節的執行步驟與這張圖的關聯,透過這個比較,能進一步了解悟空如何讓按鈕控制燈光開關。
新增裝置(Add Node)
當裝置被新增之後,裝置會先進行初始化,在初始化的過程中,會依序載入悟空類別與產生悟空物件。尋找裝置(Discovery)
當我們按下"尋找裝置"的按鈕時,主控臺會收集每個裝置中的類別與物件清單(Get available profiles and endpoints)。配對(Map)
主控臺會依照所取得的類別與物件清單,從中配對資料流編程(FBP)所需要的悟空物件。以此圖爲例,資料流編程所需要的悟空物件爲1個按鈕(Button)和1個燈光(Light Actuator),由於裝置1(Node 1)有1個按鈕物件,裝置2(Node 2)有1個燈光物件,因此,資料流編程的按鈕將會被配對至裝置1,資料流編程的燈光將會被配對至裝置2。部署程式(Deploy)
當我們按下"部署程式"按鈕時,每個裝置會得到從主控臺來的資料流表單,用以傳遞需要被更新的屬性的值,同時也會得到資料流編程所需要的悟空物件清單。測試(Testing)
當我們按下按鈕後,由於按鈕的悟空類別有定義刷新速度屬性,所以裝置1上的按鈕悟空物件的更新函式會被定期執行,並且定期將感測到的資料寫入屬性儲存區,此時,當悟空屬性架構在儲存區發現按鈕的第1個屬性(current value)改變時,就會按照資料流清單上的來源與目的,將這個改變的值傳遞給裝置2。接著,裝置2的屬性架構會發現其儲存區有屬性改變,便呼叫具有該屬性的燈光悟空物件的更新函式,在函式執行的過程中,燈光悟空物件會拿到被更新的屬性的值,也就是燈光悟空物件的第1個屬性(on off),最後,按照這個屬性的值來開關燈光。