謝作如



寒假期間,忙里偷閑設計了一個名叫“sfarm”的開源智慧農場方案。sfarm采用了應用最廣泛的MQTT協議,多節點設備匯集到一個服務器上,不僅能自動灌溉,還實現了遠程控制,定時采集各種數據。方案中涉及的開源硬件、傳感器、電磁閥和其他灌溉設備,在淘寶上都能買到,因而得到了很多朋友的關注。其中福州連江五中的盧老師就在學校的大花壇上部署了一套,運行效果很好。
雖然系統運行正常,但很快就產生了新的需求:當有嘉賓或者學生來參觀智慧農場系統的時候,如何快速展示這一系統的“物聯”功能?畢竟打開SIoT(MQTT服務器)的Web管理頁面,再進行演示總不夠便捷,也難以體現個性化。這就需要寫一個物聯網應用程序,對接入的各個節點設備進行直觀的管理。當然,我們期望這個物聯網應用程序的開發難度不能太高,最好學生也能夠開發。這樣,智慧農場就和學生的物聯網學習、編程學習密切結合起來了。
● 用Web方式開發物聯網應用程序的優勢分析
物聯網應用程序的開發有很多種方式可以選擇,比較常見的是用VB、C#之類的語言來編寫,但是開發的應用程序要運行在電腦上,無論是演示還是平時管理都不夠靈活。用App inventor編寫一個手機App也是不錯的選擇,技術門檻也低,中學生大都能參與編寫。但美中不足的是,這個App要事先安裝,而且只能運行在安卓手機上,不夠靈活且不具備普適性。
用類Scratch的軟件來編寫應用程序,也是可行的一種選擇,如Mind+(一款圖形化編程軟件)內置了MQTT模塊,可以編寫物聯網應用程序。Mind+的門檻很低,小學生也能夠編寫出一個非常個性化的物聯網應用。但遺憾的是,Mind+的代碼不能脫離Mind+環境運行,也不能編譯為一款獨立的軟件。
毫無疑問,最靈活的方式肯定是采用B/S架構,編寫一個單獨的管理網頁,即WebApp。在服務器上運行該程序,任何手機的瀏覽器都能打開這個特定的網頁,看到各種采集的數據,還可以通過網頁按鈕來控制“澆水”。這樣的應用場景顯然很“智能”很“貼心”,但遺憾的是,編寫WebApp一般需要掌握一定的網頁前端開發技術,而目前學生普遍缺少這方面的編程基礎。
● 用Python開發WebApp
能不能用Python來編寫WebApp?現在的中學信息技術教材幾乎都采用Python語言了,如果能夠用Python來編寫網頁,學生就不需要學習HTML、JS和CSS等網頁開發技術。當然,答案是肯定的,一個名叫“Remi”的Python庫,就是用來開發WebApp的。
1.Remi庫簡介
Remi是一個用于Python應用程序的GUI庫,它將應用程序的界面轉換為HTML,以便在Web瀏覽器中呈現。嚴格地說,我們不能用Remi庫來編寫傳統的網站,而只將他當成Web形式的Tkinter庫(Python最經典的圖形界面庫)來使用。如果要做網站,還是要老老實實學點前端知識,然后結合Python的Flask框架來開發。
2.Remi庫的安裝
Remi可以采用pip命令安裝,具體如下:
pip install remi
3.Remi庫的代碼示例(如圖1)
運行這段代碼后,瀏覽器會自動打開一個本地的網址,出現如圖2所示的界面。將“127.0.0.1”換成IP地址,就能通過其他電腦、手機的瀏覽器來訪問了。
點擊“請點擊這里”按鈕,界面會發生變化,如圖3所示。不用寫復雜的JS代碼,在Remi的支持下,網頁交互就變得這么簡單。
如果需要了解更多關于Remi庫的資源,可以訪問github或者官方文檔。
github地址:https://github.com/dddomodossola/remi
文檔地址:https://remi.readthedocs.io/en/latest/
● 基于Remi編寫基于Web的物聯網應用程序
既然是編寫物聯網應用程序,那么肯定還需要安裝siot庫。這也是“虛谷物聯”團隊開發的Python庫,因為MQTT的官方Python庫(paho-mqtt)編寫出來的代碼冗長,不好理解,于是委托上海蘑菇云團隊在paho-mqtt的基礎上進行了新的封裝。siot庫可以通過pip命令來安裝,命令如下:
pip install siot
1.物聯網應用的工作流程
因為“sfarm”每一個節點都有采集土壤、光線信息的功能,都具備單獨的電磁閥,用物聯網消息來控制。那么,這個應用程序既需要顯示消息,又要能夠發送消息(控制指令),工作流程如圖4所示。其實,絕大多數的物聯網應用程序,都需要同時具備訂閱和發送消息功能。
2.核心代碼1:物聯網消息的訂閱
因為要同時訂閱多個主題的消息,代碼中采用了“定點存放定時處理”的方式,即先將接收到的消息放在一個字典(topic_msg_map)中,然后定時在字典中查找是否有新消息,讀取新消息后就刪除這一消息,避免重復讀取。參考代碼如下頁圖5所示。
3.核心代碼2:物聯網消息的顯示
顯示消息需要不斷刷新網頁組件中的文字,這需要啟動一個新的進程來處理,然后在這個進程中不斷循環讀取字典(topic_msg_map)中的消息。參考代碼如圖6所示。
4.核心代碼3:物聯網消息的發送
消息發送通過“澆水”按鈕來實現。參考代碼如圖7所示。
5.核心代碼4:物聯網設備的切換
sfarm是一個多節點工作的物聯網系統,因而需要加上設備切換功能,比較簡單的做法是用一個列表(project_list)記錄需要呈現的設備名稱,然后在切換時修改全局變量(id)。參考代碼如下頁圖8所示。
● 運行效果和反饋
Python的神奇,就在于其擁有無窮無盡的“庫”,能夠用來快速解決問題。從找到Remi庫到寫出代碼,我僅僅花了一個晚上的時間,這種編程的感覺特別好。最終的代碼運行效果如下頁圖9所示。
福州連江五中的盧老師將代碼運行在sfarm系統的物聯網服務器上,然后將訪問地址做成二維碼,用手機掃碼(手機要能夠訪問服務器)的方式來打開這個網頁,效果很不錯,如下頁圖10所示。從難度上看,只要有Python編程基礎,就能編出類似的程序。他正在將這方面的內容開發成一個物聯網課程,讓學生真正參與到sfarm的開發和維護中。
完成了這個物聯網應用后,最大的收獲并不是解決了sfarm系統的演示問題,而在于找到了一種設計Python程序界面的新方法。例如,可以用Remi庫寫一個基于Web的校園氣象站、攝像頭遠程控制程序等。相對來說,用Remi庫開發WebApp,比Flask(一個Python開發的Web框架)要簡單得多,后者需要了解大量的HTML、JS和CSS之類的知識,對中學生來說門檻略高了一些。