---
# System prepended metadata

title: 樂活 Firmware 開發規格說明 與 電路板 相關要求

---

# 樂活 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   | 用於計算Ｍqtt 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)





