物聯(lián)網(wǎng)系統(tǒng)如何提供智慧物業(yè)解決方案?">無(wú)線(xiàn)物聯(lián)網(wǎng)系統(tǒng)如何提供智慧物業(yè)解決方案?
763
2025-04-02
相信不少同學(xué)都做過(guò)“基于物聯(lián)網(wǎng)平臺(tái)構(gòu)建智慧路燈應(yīng)用”這個(gè)微認(rèn)證,在這個(gè)微認(rèn)證中,我們構(gòu)建并部署了一個(gè)智慧路燈應(yīng)用,這個(gè)應(yīng)用擁有一個(gè)web界面,可以注冊(cè)路燈設(shè)備,可以獲取路燈設(shè)備的狀態(tài)和上報(bào)的環(huán)境亮度數(shù)據(jù)并顯示到界面上,還可以控制路燈的開(kāi)關(guān)。
在微認(rèn)證中,這個(gè)應(yīng)用的源碼是公開(kāi)的,但不需要修改就可以直接使用,所以很多同學(xué)可能并沒(méi)有仔細(xì)看過(guò)這個(gè)應(yīng)用時(shí)怎么實(shí)現(xiàn)的。所以本文就帶各位同學(xué)一起看下這個(gè)應(yīng)用具體的設(shè)計(jì)與實(shí)現(xiàn),以及探討下如果想要修改這個(gè)應(yīng)用的功能要怎么改,想要開(kāi)發(fā)其他設(shè)備的應(yīng)用要怎么開(kāi)發(fā)。
整體架構(gòu)
智慧路燈的源碼在華為云軟件開(kāi)發(fā)平臺(tái)作為公開(kāi)示例模板公開(kāi),做過(guò)微認(rèn)證的同學(xué)已經(jīng)都已經(jīng)按照模板創(chuàng)建了自己的代碼倉(cāng)庫(kù),接下來(lái)就是把代碼下到本地用本地的IDE打開(kāi),方便查看。
展開(kāi)代碼的目錄后我們可以看出來(lái)這是一個(gè)基于Springboot工程模板創(chuàng)建的web應(yīng)用.
所以,該應(yīng)用的主要功能代碼都位于main文件夾下,其中java文件夾下是后端代碼,resources文件夾下是前端代碼和資源。
接下來(lái)讓我們一邊回憶該應(yīng)用的使用流程,一邊查看對(duì)應(yīng)的代碼是如何實(shí)現(xiàn)的。
Web頁(yè)面
使用智慧路燈應(yīng)用的第一步是通過(guò)IP和端口訪(fǎng)問(wèn)智慧路燈應(yīng)用。我們通過(guò)瀏覽器訪(fǎng)問(wèn)應(yīng)用的時(shí)候?qū)嶋H上就是訪(fǎng)問(wèn)了index.html這個(gè)文件。
打開(kāi)index.html,可以看到就是個(gè)標(biāo)準(zhǔn)的html頁(yè)面,定義了頁(yè)面上顯示的各個(gè)組件。也就是,如果我們想要修改智慧路燈應(yīng)用界面上顯示的內(nèi)容,修改這個(gè)文件就可以了。
而這個(gè)頁(yè)面的行為和交互則是通過(guò).js文件定義,和業(yè)務(wù)相關(guān)的主要代碼都在common.js,也就是想要修改該web頁(yè)面的交互行為,需要修改common.js。
參數(shù)設(shè)置
首次訪(fǎng)問(wèn)智慧路燈應(yīng)用以及點(diǎn)擊“參數(shù)設(shè)置”按鈕時(shí),會(huì)彈出參數(shù)設(shè)置窗口,這個(gè)窗口的行為由openSetParamsDialog()函數(shù)控制。
這個(gè)函數(shù)的功能是從后臺(tái)獲取數(shù)據(jù)作為默認(rèn)值顯示在設(shè)置窗口,以及在用戶(hù)點(diǎn)擊確認(rèn)后將設(shè)置的數(shù)據(jù)保存到后臺(tái)。
獲取后臺(tái)數(shù)據(jù)的函數(shù)是getDeviceParas(),可以看到這里的后臺(tái)其實(shí)就是瀏覽器的本體緩存,以及若后臺(tái)沒(méi)有存儲(chǔ)數(shù)據(jù)時(shí)則返回空值。
將設(shè)置的數(shù)據(jù)保存到后臺(tái)的函數(shù)是onSetParamsDialogConfirm(),先讀取輸入框的值,再寫(xiě)入本地存儲(chǔ),最后調(diào)用postDeviceParas()將數(shù)據(jù)傳到后端供后端使用。
通過(guò)查看TempDatabase類(lèi)可以看到該類(lèi)是個(gè)單純的數(shù)據(jù)存儲(chǔ)類(lèi),paras這是ParameterConfiguration類(lèi)的一個(gè)實(shí)例,再查看ParameterConfiguration類(lèi)可以看到它也是個(gè)單純的數(shù)據(jù)存儲(chǔ)類(lèi),所以該方法就是將用戶(hù)設(shè)計(jì)參數(shù)保存到內(nèi)存中,供本應(yīng)用運(yùn)行時(shí)調(diào)用。
然后讓我們繼續(xù)順藤摸瓜,去看下subscribeDataChange類(lèi)的subscribeDataChange()方法。
這個(gè)方法是個(gè)調(diào)用接口的方法,首先通過(guò)調(diào)用LoginService類(lèi)的login()方法獲取accessToken,然后再調(diào)用設(shè)備接入的的創(chuàng)建訂閱接口。創(chuàng)建訂閱接口用于應(yīng)用向平臺(tái)訂閱設(shè)備數(shù)據(jù),是物聯(lián)網(wǎng)應(yīng)用向物聯(lián)網(wǎng)平臺(tái)獲取數(shù)據(jù)的一種方法,本文不進(jìn)行詳述,感興趣的同學(xué)可以查看我們之前的博文。
(這段代碼相對(duì)較多,截圖就只截關(guān)鍵部分了,后面相同的情況不再說(shuō)明)
通過(guò)對(duì)比訂閱函數(shù)和接口文檔,我們可以看出來(lái)函數(shù)中的accessToken對(duì)應(yīng)接口中的X-Auth-Token,所以login()方法對(duì)應(yīng)IAM服務(wù)的獲取用戶(hù)Token接口。
注冊(cè)設(shè)備
參數(shù)設(shè)置成功后,我們需要輸入設(shè)備標(biāo)識(shí),然后點(diǎn)擊注冊(cè)設(shè)備。
設(shè)備標(biāo)識(shí)是設(shè)備的唯一標(biāo)識(shí)碼,一般用設(shè)備的MAC或IMEI,如果是虛擬設(shè)備可以隨意輸入一串?dāng)?shù)字。
通過(guò)查看index頁(yè)面源碼,我們可以看到用戶(hù)點(diǎn)擊注冊(cè)設(shè)備后應(yīng)用會(huì)調(diào)用common.js中的regDevice( btn )函數(shù),攜帶的參數(shù)就是用戶(hù)輸入的設(shè)備標(biāo)識(shí)。這個(gè)方法會(huì)先檢查你是否設(shè)置了參數(shù),然后再調(diào)用/register-device接口。
/register-device接口對(duì)應(yīng)RegisterDevice類(lèi)的registerDevice(@RequestBody DeviceRegisterVerifyCode deviceRegisterVerifyCode)函數(shù),然后這個(gè)函數(shù)又調(diào)用了registerDirectConnectedDevice類(lèi)的registerDirectDevice(DeviceRegisterVerifyCode deviceInfo)函數(shù),調(diào)用了物聯(lián)網(wǎng)平臺(tái)的創(chuàng)建設(shè)備接口。
然后讓我們看回common.js中的regDevice( btn )函數(shù),可以看到注冊(cè)設(shè)備成功后它先移除了toggle-block的hide屬性,將頁(yè)面上剩下的部分(狀態(tài)查看和路燈控制)顯示了出來(lái),然后調(diào)用了openDialogRegister(states,title,deviceId,secret)函數(shù),并傳入了接口返回的設(shè)備Id和密鑰,實(shí)現(xiàn)了彈窗顯示。最后,這個(gè)函數(shù)調(diào)用了initTickTimer()函數(shù),在initTickTimer()函數(shù)中,我們終于看到了DIS相關(guān)的內(nèi)容。
這個(gè)函數(shù)是一個(gè)定時(shí)任務(wù),循環(huán)檢查用戶(hù)設(shè)置的數(shù)據(jù)獲取方法,并調(diào)用對(duì)應(yīng)函數(shù)。
當(dāng)數(shù)據(jù)獲取方法是DIS時(shí),該函數(shù)調(diào)用getDis()函數(shù)。getDis()函數(shù)調(diào)用/get-dis接口,并根據(jù)返回值設(shè)置界面顯示值。
/get-dis接口對(duì)應(yīng)GetDis類(lèi)的getDIsData()函數(shù),這個(gè)函數(shù)通過(guò)集成DIS的SDK,實(shí)現(xiàn)了從DIS通道或獲取最新數(shù)據(jù)。這部分的實(shí)現(xiàn)可以直接參考DIS的文檔,本文不進(jìn)行詳述。設(shè)備上報(bào)的數(shù)據(jù)從物聯(lián)網(wǎng)平臺(tái)轉(zhuǎn)發(fā)至DIS通道則是基于數(shù)據(jù)轉(zhuǎn)發(fā)規(guī)則,本文也不進(jìn)行詳述。(眼尖的同學(xué)可能會(huì)發(fā)現(xiàn)這個(gè)函數(shù)的最后有一行createDeviceCommand.runSetCommand(slMsg);這行代碼涉及到這個(gè)應(yīng)用的命令下發(fā)機(jī)制,此處暫不講解)
當(dāng)數(shù)據(jù)獲取方法是訂閱推送時(shí),被循環(huán)調(diào)用的是getSub()函數(shù)。getSub()函數(shù)調(diào)用/get-device-data接口,并根據(jù)返回值設(shè)置界面顯示值。
/get-device-data接口對(duì)應(yīng)GetDevData類(lèi)的getDeviceData()函數(shù),這個(gè)函數(shù)直接獲取了TempDatabase中的slMsg(存儲(chǔ)了環(huán)境光強(qiáng)和開(kāi)關(guān)狀態(tài))并返回,那這個(gè)slMsg的值又是哪來(lái)的?
這時(shí)候讓我們回想一下訂閱推送的機(jī)制:應(yīng)用訂閱后,物聯(lián)網(wǎng)平臺(tái)作為客戶(hù)端推送通知給應(yīng)用指定的callbackURL。沒(méi)錯(cuò),這個(gè)數(shù)據(jù)是物聯(lián)網(wǎng)平臺(tái)主動(dòng)推送上來(lái)了,所以在這個(gè)應(yīng)用中應(yīng)該會(huì)有一個(gè)對(duì)應(yīng)callbackURL接口的函數(shù)。
從subscribeDataChange()函數(shù)中我們可以找到callbackURL的后綴“/v1.0.0/messageReceiver”,通過(guò)在代碼中搜索我們找到了PushReceiver類(lèi)中的pushrReceiver(@RequestBody String jsonString)函數(shù)。這個(gè)函數(shù)解析了物聯(lián)網(wǎng)平臺(tái)推送的數(shù)據(jù),并存到了slMsg中。
至此,我們的應(yīng)用已經(jīng)實(shí)現(xiàn)了設(shè)備的注冊(cè)和設(shè)備上報(bào)數(shù)據(jù)的獲取。在下期博客中,我將會(huì)為同學(xué)們介紹智慧路燈應(yīng)用三種路燈控制模式的實(shí)現(xiàn)。
IoT 智慧路燈 物聯(lián)網(wǎng) IoT web應(yīng)用開(kāi)發(fā)
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶(hù)投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶(hù)投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。