---
# System prepended metadata

title: 2024-04-22 週報
tags: [airaConnect, ' 週報']

---

---
tags: airaConnect, 週報
---

### 上週完成事項
上禮拜都在熟悉 airaConnect，下面是實際推上去的 commits：

#### 共通事項
chore: 移除 repo 裡的 node_modules 以及 src/data
style: 用 prettier 對程式碼作排版
chore: 測試環境以 pm2 形式啟動方便 hot reload
chore: 因應 mongo 改成以 replicaSet 形式運行作調整
Revert "chore: 因應 mongo 改成以 replicaSet 形式運行作調整"
chore: 能用確保 webpack打包並新增停止 pm2 的指令

> 主要是在 .51, .9(.130) 上設 ssh key，去把專案拉下來，啟動。
> 
> yu chin 說，`data` 資料夾其實是三個資料夾共用的，這部分也用 ln -s 將資料夾同步到三個專案去。

#### airaMetaProcessor 的部分
fix: 修正重啟後本日的 eventStat 內容被清空的問題
fix: 修正 eventData 若目前狀態與前一筆狀態一樣的話 end_time 不會更新的問題
fix: pin 腳的 deviceId 應該改為個別裝置的 uuid （而非裝置類型的 uuid）

#### airaConnect 的部分
![image](https://hackmd.io/_uploads/HJpkdN7WA.png)
fix: 所有 group 欄位參數型態改為 array
feat: 編輯區域時同步更新裝置所在的 areaId
feat: 預留告警用的 websocket
feat: 將 operationcase.timestamp 型別改為 number
fix: 補上缺少的 map.enabled 欄位
fix: gateway/compressor 還是要能編輯
feat: 在設備編輯時，將預設群組移除，並改由後端 api 新增

### 卡住的地方
1. 看大家很忙，在專案間切來切去，不確定我有多少時間可以停在同一個專案把它改到好。
> 我想的方式是，如果線上有什麼需求，先幫忙改一些。一方面根據既有的程式碼重構。
2. 在家不好測（可以拿 mock data 假裝它是從 data receiver 推送出來的）。
~~2. 有些代碼有點拗口。譬如說去重複這件事情，程式碼裡是先存一個 array，再用 .find 去找 id 看是否之前設定過⋯⋯這邊可以改用 map 存。很多東西一口氣塞在同一個 module.exports。if else 有點深。~~
3. 看起來我的 Mentor 是 Matt，但 Matt 有自己的事情且對後端比較不熟，好像有些決策面的討論，我是自己做決定就可以嗎？


#### airaDataReceiver
![image](https://hackmd.io/_uploads/H1PROEQZR.png)
feat: 將 DI1, DI2 改為真實資料其餘腳位改為一個1一個0
feat: 有害氣體資料格式調整（Jack 做的；這邊是合併他作的修改）

### 目前被指派的工作以及進度
實作 airaEventHandler。

進度：
- [x] 每次裝置狀態更新時，觸發對規則的解析。
- [x] 當規則修改時，更新與規則相關的裝置清單(IDs)。這是為了避免每次解析規則的時候才查詢（因為解析可能會很頻繁，但裝置清單不一定很頻繁更新）。 
- [ ] 根據 `eventhandle.db` 讀取到的每一條規則，以及前面提到的相關裝置清單，讀取設備狀態進行判斷。
- [ ] 判斷若符合規則，則執行 `eventhandle.db` 裡指定的處置方式。
> 有個 Decision Tree Router 可以用，但它還只在論文裡面，沒在 `npm` 上看到它。

### 可以工作的方向
#### 1. 用 typescript 改寫
我們需要 type hint。

#### 2. 分層、事件驅動、將輔助工具獨立到 CLI 專案
1. 譬如說啟動時如果沒有 .db 或者 mongo collection 就自動產生這件事情，應該獨立到一個輔助工具的專案（如果有問題的話，不要讓它能跑起來！而是去看他少哪個步驟）。
2. 現在資料流的 `mqtt -> udp -> 各專案`。這邊的 `udp -> 各專案` 可以改用 mongo 的 collection watch。
3. 目前的分層有點不太明確。

#### 3. CI/CD
上禮拜 Matt 說公司主要用 github，我以為 `e234xp` 是公司的 organization 帳號。試著串 gitlab CI 發現很難 mirro 過來，後來改架 drone CI，不過跟 drone CI 的腳本不熟，所以先放著。

後來 Matt 說新專案想用 gitlab 存也可以，所以接下來如果有時間，就把 repo 搬到 gitlab 上，跑 gitlab runner。

之後測試機就可以不用上去拉新腳本了，只要把 commit 推上去，跑 CI 腳本就好。

#### 4. 棄用 `.db` 檔都改用 mongo 存
1. 純檔案系統沒有索引可以用，如果資料筆數一多，想要查找就會花很多時間。
2. 越來越多資料存同一個檔案，讀寫變慢。
3. hold 幾條 mongo connection 頻繁「讀寫」 bson，應該比頻繁「開關讀寫」 json 快。
4. mongo 有 transaction，鎖的細粒度應該可以到 record 級，檔案系統的話，我知道開關有一層 lock 可以寫，底下的 lock 就不知道。
5. mongo 可以寫 collection watcher，可以細分出 `insert`、`update`、`replace` blahblah。`fs` 上要自己實作。

#### 5. 關於現在儲存的資料
![image](https://hackmd.io/_uploads/HJ7WbB7b0.png)

#### 5-1. DeviceRowEventStat
這個 Event Stat 如果還會繼續長大的話，讀寫單一筆 bjson 就是很危險的事情。這邊的 `eventData` 感覺應該是 `Device State` 在某個時間區間的 `snapshot`。

前端在讀寫這邊的資料時，看能不能用分頁的方式一次一些的接，不要一口氣從 server side 吐。

如果真的、真的就是要拿到全部的資料的話：
1. 前端可以考慮用 [Event Source](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) 接資料。
2. 後端讀取寫入 `eventData` 欄位時，平常先避開 `eventData` 的讀寫。`eventData` 寫入時改用 `$push`。


##### 5-2. DeviceRow、DeviceRowMeta
合併起來只留一個 `messages` 就好。

##### 5-3. 新增 `deviceStates`
`deviceStates` 存最新的 state。

##### 5-4. 新增 `deviceSnapshots`
可以把 `DeviceRowEventStat` 裡面的 `eventData` 搬到這裡。
在每次 `deviceStates` 更新時，就寫一筆 snapshot 到這裡。

#### 5-5. 新增 `monitoringLists`
每次 `eventhandle.db` 內容有更新，或者有新的裝置加入時，就去更新相對應的清單。