6.3 實作悟空類別

在這一章節中,我們會搭配4.2節的資料流編程範例來介紹如何實作悟空類別,實作出來的悟空類別可以同時用於Edison, Galileo和Raspberry Pi,使用的方式如同5.2節所述。

悟空裝置的Python樣版

以下爲悟空裝置的樣版,從樣版中可看到,悟空裝置會加入悟空類別(addClass),並產生悟空物件(addObject)。目前所有的悟空裝置程式都存放在https://github.com/wukong-m2m/wukong-darjeeling/tree/release0.4/wukong/gateway/udpwkpf

  from twisted.internet import reactor
  from udpwkpf import WuClass, Device
  import sys

  if __name__ == "__main__":
      class XXX(WuClass):
          def __init__(self):
              WuClass.__init__(self)
              self.loadClass('XXX')

          def update(self,obj,pID=None,val=None):
              pass

      class MyDevice(Device):
          def __init__(self,addr,localaddr):
              Device.__init__(self,addr,localaddr)

          def init(self):
              cls = XXX()
              self.addClass(cls,0)
              self.addObject(cls.ID)

      d = MyDevice(sys.argv[1],sys.argv[2])
      reactor.run()

悟空裝置範例程式:按鈕和燈光

此範例程式是根據以上的樣版所寫成,在此裝置樣版中實作了兩個悟空類別,一個是第10行的按鈕(Button),另一個是第25行的燈光(Light_Actuator),有了這兩個悟空類別的實作,我們就可以照者4.2節的步驟來部署應用程式,因此,在往下看程式之前,建議可以先照者4.2節所述的步驟操作一遍,將有助於對此程式的理解。接者,每個悟空類別都有初始函式(init)與更新函式(update),初始函式是用來設定各變數,狀態與硬體參數的起始值,而更新函式則是用來被屬性架構重覆地呼叫執行。最後,當悟空裝置範例程式被執行後,這兩個悟空類別將會被加入(addClass)悟空裝置中,並用來產生(addObject)悟空物件。

爲了透過GPIO控制按鈕和燈光,我們需要在悟空裝置最前面匯入(import)物聯網開發板的GPIO函式庫,而且,爲了盡可能讓同一個悟空裝置程式能執行在不同的物聯網開發板,我們新增了這個介面(udpdevice_io_interface.py)來決定如何使用三個不同的GPIO函式庫,下一個章節會繼續說明這個GPIO介面。

這個函式的輸入參數必須是悟空類別的名稱,並且,此名稱要與WuKongStandardLibrary.xml所定義的名稱相同,當這個函式取得悟空類別名稱後,就會分析WuKongStandardLibrary.xml所定義的內容,截取這個悟空類別的每個參數。

使用第1點所提的GPIO介面來設定哪個GPIO腳位會被用到,並設定該腳位是數位(digital)還是類比(analog),以及設定是輸入(input)或輸出(output)。

由於在6.2節中,按鈕感測器有定義刷新速度(refresh rate)屬性,所以更新函式(update)會定期被執行並透過GPIO讀取其感測到的值。

setProperty函式是用來將某屬性的值寫入屬性架構的屬性儲存區,當屬性架構監測到此屬性的值改變後,就會按照資料流表單來傳遞值。setProperty函式的第一個參數是屬性辨別號(property ID, pID),在第20行中,pID等於零表示按鈕的第1個屬性的值將被寫入屬性儲存區,若我們對照WuKongStandardLibrary.xml,可知道按鈕的第1個屬性是current_value,也就是說,按鈕的感測數值會被寫入屬性儲存區。

由於燈光悟空類別沒有定義刷新速度(refresh rate),所以燈光的更新函式只會在其屬性的值改變時被呼叫。以4.2節的範例來說,當按鈕被按下去時,屬性架構會知道按鈕的第1個屬性的值已改變,於是就照着資料流清單把值傳遞給燈光屬性儲存區,並且呼叫燈光的更新函式,當函式被執行時,就會照者讀取到的值來開關燈光。在屬性架構呼叫更新函式時,同時也會傳遞改變的obj(悟空物件),pID(屬性識別號)和value(值)給更新函式做運用。

這個函式爲用來加入悟空類別到悟空裝置,在這個範例程式中,按鈕和燈光均加入到同一個悟空裝置程式,所以會共同使用一個屬性架構。關於此函式的第2個輸入參數,是用來表示這個悟空類別可否自行產生悟空物件,零代表此悟空類別不能自行產生悟空物件,因此需要用下一行的函式(addObject)來產生悟空物件。在7.3節時,我們將會使用到能自行產生悟空物件的悟空類別,屆時就不需要用addObject來產生悟空物件。

由於屬性架構的實作是用Python的Twisted函式庫,所以最後記得要加這行程式,否則按鈕的值不會被定期更新。

要點

這一章節的最後,我們歸納出實作悟空類別的幾個要點:

  • 首先是新增並仿照悟空裝置樣版到<path_of_source_code>/wukong/gateway/udpwkpf/udpdevice_XXX.py
  • 若是要新增感測器(sensor),請參考按鈕的悟空類別寫法;若是要新增控制器(acutator),請參考燈光的悟空類別寫法。
  • 最後加入悟空類別到裝置上(addClass),並在裝置上產生悟空物件(addObject)。