# 樂活 Firmware 開發規格說明 與 電路板 相關要求 #### Release Ver. 1.1.1 ###### Release note : * 補充Curl * 補充 Mqtt get cmd . * 補充 Mqtt ~~update cmd 目前不需要實作, 但需記錄~~ ## Doucument Version 說明 Version number : {A.B.C} A: 重大改變 B: 雙方共識 C: 小幅改變 ## Document History | Date | Release note. | Version | | ---------- | --------------------------- | ------- | | 2020/02/04 | Init Release | 0.01 | | 2020/02/06 | 增加Release History | 0.0.2 | | | 增加 Mqtt 完整 說明 | | | | 增加 主板 考量條件 | | | 2/12 | 增加流程圖 | 1.0.0 | | | 增加資料時間限制 | | | | 增加Device I/O 需求list | | | 2/13 | 修正文件中掉圖 | 1.1.0 | | | 增加主板選擇最低要求 | | | | 經過全部會議共識 | | | | 增加 Doucument Version 說明 | | | | | | | | | | | | | | ## 開發主板考量條件: #### 主板必要規格: * Wifi 2.4G/802.11n . * Bluetooth 4.1 * RAM 大於 256M . TBD * Storage : 大於 ( Embedded linux system + 程式 + 256M bytes) TBD * 必須是 Embedded linux , 可以 ssh 連線 console. TBD * 主板的選擇 有考慮到量產生產 相關考量 (交貨時間,價格). #### 建議方向: 1. 考慮Raspberry pi zero w . 但價格與交期要確定. 2. 希望可以 相容 Raspberry pi 系統 ### 開發與主板最低要求 1. 滿足必要的通訊定義 (Bluetooth/MQTTs) 2. 滿足必要的功能定義 (control/info responsd) 3. 滿足必要的反應時間限定 4. Storage: 32K ## Connection 有3部分 , * cloud server--> Device : sever 下指令action 給 device . 使用 Mqtts * device --> cloud server : 回報 sensor 資訊 到 Server . 使用 Mqtts * Device <--> mobile App : 做裝置與手機配對用. 使用Bluetooth 4.1 ## Device I/O 需求list - 按鈕x1:有支援長壓短壓辨識,作為電源開關與進入配對模式用 - LEDx1 : RGB 256色 - 需取得資訊: - - 溫濕度 - PM2.5 : 單位體積內空氣中不同粒徑的懸浮顆粒物個數 - 濾網的門定位:確認濾網的門確定是否關閉定位.(ex:微動開關),當門打開時馬達需停止作動 - PIR 紅外線 : 確認前方有無人 - VOC 感測器 - 風壓偵測x2:判斷出風速度推斷濾材使用率 ,兩邊濾網進風所以兩個 - 機器過熱感測:預防過熱,馬達或板子有可能過熱的一切. - 馬達轉速:回報馬達轉速 ## 資料與規範 * 手機與裝置藍芽資料 ``` { SSID:"String" Password:"String" PSK:"String" } ``` * device 回報 Sensor 資料 ``` Event example: { "ambiance":{ "infrared":"1", "temp":16.0, "hum":60.0, "pm":"0.5", "hepa":"1", "voc":"0.5" }, "status":{ "productId":"2S45N5X8J1", "deviceName":"000001", "motor":{ RPM:"string" tempture:"String" } "filter":{ "left":"left", "right":"right" }, "createdAt":"0001-01-01T00:00:00Z" } } ``` * Server To device data ``` "desired": { "airflow": 76, "auto": false, "light": true, "on": true, "safetyLock": true, "speaker": false } ``` ## 資料取得時間限制 * Device 計算 Mqtts username password , sha256 時間不得超過 1秒 * 當雲端控制馬達指令送達device 後 開始計時到馬達相對運作, 時間不得超過1秒 * Device 在取得WIFI SSID/密碼後 建立連線WIFI 時間 不超過 10 秒 * Device 成功連線 wifi 後, 確認 Internet 是否存在,不超過 5秒. ## 生產時相關資訊 ### 需要燒錄的資料 * ProductID : Batch ID 一批一批會不同. * Device Name : Device ID 裝置識別碼.目前是 000000 六個數字 . 生產時 依序遞增 * ProductID + DeviceID 是unique 唯一值. ###其他:開發時需考慮到生產工具. ## 整體流程圖 ![Roehl air filter engineer flow chat](Roehl_air_filter_engineer_flow_chat.jpg) ## 雲端溝通 與 Protocol ### 溝通架構 Term : * Cloud Server : 雲端 Server 目前是 騰訊Server * Device : 樂活空氣清淨機 * Mobile App : 樂活App Cloud server <---------MQTT------>Device Device <------------Bluetooth-------> Mobile App Mobile <-----------Https--------------> Cloud Server ```mermaid graph LR S[Cloud Server] ==> P[MQTT] ==> D[Device] D ==> P ==> S ``` ```mermaid graph LR D[Device] ==> B[Bluetooth] ==> A[MobileApp] A ==> B ==> D ``` ```mermaid graph LR A[MobileApp]==>H[HTTPS]==>S[CloudServer] ``` data type: JSON string #### 一組MQTT可用資訊: 一組資訊如下 並在後面說明 各個資訊如何取得: ``` 設備密鑰PSK KSqRcN72G+kDSKlQUewn6g== client id X5TVRIJ59A000002 mqtt username X5TVRIJ59A000002;12010126;X23IM;1614971831 mqtt password a33500700acb52097dcc52287bf070c00f7f05b4f99ba93e2d6cc73328696721;hmacsha256 ``` #### MQTT 資訊說明 | 名詞 | 說明 | 取得方式 | | ------------- | ---------------------------------------------------------- | ------------------------------- | | 設備密鑰PSK | 用於計算Mqtt password用 | 與手機配對時.透過bluetooth 取得 | | client id | \${productid}${deviceName} | 製造時已儲存在Device 中 | | mqtt username | \${productid}${devicename};${sdkappid};${connid};${expiry} | 利用規則產出 | | MQTT password | ${token};hmac簽名方法 | 利用psk 計算取得 | ##### 設備密鑰PSK 在手機與Device 配對的時候取得. 透過Bluetooth ##### Client ID ``` ${productid}${deviceName} ``` 在生產製造時已存放在主板上. 是唯一值.Unique ID * productid : 為公司產品類別的區分, ``` 例如: 第一代產品 productID : "第一代" 第二代產品: productID : "第二代" ``` * devicename: 為裝置本身流水號, ClientID 生產工廠製造時 放入.因此外包商在設計時 要包含 到 與制具銜接的方法. ##### MQTT Username /Password 說明 ``` client id : ${productid}${deviceName} username字段的格式為:  ${productid}${devicename};${sdkappid};${connid};${expiry} 注意:${}表示變量,並非特定的拼接符號。 其中各字段含義如下: productid:產品 ID。 devicename: 設備名稱。 sdkappid:固定填12010126。 connid :一個隨機字符串。 過期時間 :表示簽名的有效期, 從1970年1月1日00:00:00 UTC 時間至今秒數的 UTF8 字符串。 ``` 用 base64 對設備私鑰進行解碼得到原始密鑰 raw_key。 用第3步生成的 raw_key,通過 HMAC-SHA1 或者 HMAC-SHA256 算法對 username 生成一串摘要,簡稱 token。 password 字段格式為: ```  ${token};hmac簽名方法 可選的值有 hmacsha256 和 hmacsha1。 ``` 下面提供 程式碼 python 範例 ,如何計算出 username./password . ```python import base64 import hashlib import hmac import random import string import time import sys # 生成指定長度的隨機字符串 def RandomConnid(length):      return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length)) # 生成接入物聯雲需要的各參數 def IotHmac(productID, devicename, devicePsk):      # 1. 生成connid為一個隨機字符串,方便後台定位問題      connid = RandomConnid(5)      # 2. 生成過期時間,表示簽名的過期時間,從紀元1970年1月1日 00:00:00 UTC 時間至今秒數的 UTF8 字符串      expiry = int(time.time()) + 60 * 60      # 3. 生成MQTT的clientid部分, 格式為${productid}${devicename}      clientid = "{}{}".format(productID, devicename)      # 4. 生成mqtt的username部分, 格式為${clientid};${sdkappid};${connid};${expiry}      username = "{};12010126;{};{}".format(clientid, connid, expiry)      # 5. 對username進行簽名,生成token      token = hmac.new(devicePsk.decode("base64"), username, digestmod=hashlib.sha256).hexdigest()           password = "{};{}".format(token, "hmacsha256")      return {          "clientid" : clientid,          "username" : username,          "password" : password      } if __name__ == '__main__':  print IotHmac(sys.argv[1], sys.argv[2], sys.argv[3]) ``` ```shell python Hmac.py "YOUR_PRODUCTID" "YOUR_DEVICENAME" "YOUR_PSK" ``` ![截圖 2020-02-06 上午9.47.00](9.47.00.png) ### 資料格式 資料格式 在裝置接收與傳送 都是以 JSON type 傳送, 請實際操作所提供的 postman profile.操作. 後面會列出兩個範例 . 一個 是 對風量做調整, 一個是 sensor 值回報. 傳送Sensor 值的Json格式 如下 ``` { "ambiance":{ "infrared":"1", "temp":18.0, "hum":20.0, "pm":"0.5", "hepa":"1", "voc":"0.5" }, "status":{ "productId":"2S45N5X8J1", "deviceName":"000001", "motor":{ "tempture": 30.0, "rpm": 3000 }, "filter":{ "left":"left", "right":"right" } } } ``` ### 範例 展示兩個範例,分別是 控制風量 與 回報Sensor資訊 , 裝置端 使用 MQTT client 替代. 所以有列出mqtt client 的設定內容. 也提供 postman 檔案, 供Import 測試 , postman 環境變數 需額外手動新增, 資訊請參考附圖. #### Example :APP 對空氣機調整風量 Topic: \$shadow/operation/${productId}/${deviceName} ``` $shadow/operation/result/X5TVRIJ59A/000002 ``` ![截圖 2020-02-04 下午12.03.00](12.03.00.png) ![截圖 2020-02-04 下午12.18.55](12.18.55.png) #### Example Sensor 回報: topic name : {productId}/{deviceName}/event/m001 X5TVRIJ59A/000002/event/m001 Publish : ```json { "ambiance":{ "infrared":"1", "temp":18.0, "hum":20.0, "pm":"0.5", "hepa":"1", "voc":"0.5" }, "status":{ "productId":"2S45N5X8J1", "deviceName":"000001", "motor":{ }, "filter":{ "left":"left", "right":"right" } } } ``` ![截圖 2020-02-04 下午12.30.55](12.30.55.png) ### 驗證回報結果 ![12.33.08](12.33.08.png) ##other : ### postman 說明: ​ import postman profile , json file, posman 環境變數必須另外手動增加. 請參考 host 是 Roehl.com.cn . postman Env : https:![截圖 2020-02-04 下午12.34.59](12.34.59.png)