相信各位看官對於目前 IDS server 裡散落各處的 hard-coding 一定看不過眼吧 ...
因此!今天本喵就試著把這些東西整理一番吧!
目前在 IDS server 中,有以下幾項可能會因應需求而異的 hard-coding 設定值:
名稱或變數名 | 值 | 意義 |
---|---|---|
_adv_interval_us | 250000 | 廣播間距 |
_passkey | 123456 | BLE PIN |
local_name | IDS 🍭 | 廣播攜帶的 complete local name |
IDD Features | b'\x01\x02\x03' | 回應 BLE read 要求的值 |
除了這些設定值散落在不同程式碼的問題外,即使將它們集中在某個檔案內,有些值理應是每台機器都不同的,比如 PIN 和 Complete Local Name。所以為了更好管理,咱們會建立一個可以讓使用者自行修改的設定檔,當伺服器啟動後會依據其設定來做相應的設定。
咱們先將設定值全歸在一個類別裡:
class Config:
def __init__(self):
self.local_name = "IDS 🍭"
self.adv_interval_us = 250_000
self.passkey = "123456"
self.idd_features = b"\x01\x02\x03"
為了讓使用者可以自行修改,設定檔的格式必須讓他人容易了解,因此咱們使用 JSON 來撰寫設定檔。為了將類別實體以 JSON 來儲存,需要將待儲存的資料轉成字典型式:
def to_dict(self):
return {
"local_name": self.local_name,
"adv_interval_us": self.adv_interval_us,
"passkey": self.passkey,
"idd_features": tuple(self.idd_features),
}
然後將 Config 實體傳入 json.dump():
def _build_config():
c = config.Config()
with open(config.CONFIG_PATH, "w", encoding="utf-8") as fp:
# MicroPython 不支援這些命名參數
json.dump(c.to_dict(), fp, ensure_ascii=False, indent=4)
可以得到如下內容的檔案:
{
"local_name": "IDS 🍭",
"adv_interval_us": 250000,
"passkey": "123456",
"idd_features": [
1,
2,
3
]
}
要特別注意的是,_build_config() 是使用 Python 來執行,因為 MicroPython 的 json.dump() 不支援如 ensure_ascii 和 indent 等命名參數。若使用 MicroPython 來執行,會得到如下結果:
{"local_name": "IDS 🍭", "passkey": "123456", "idd_features": [1, 2, 3], "adv_interval_us": 250000}
所有都內容歸於一行,若以後設定愈來愈多,將不易於查看,所以才以 Python 製作良好風格的 JSON 檔。
首先讓系統讀入保存設定的 JSON 檔:
def get_config():
# MicroPython 沒有 os.path.exists()
if CONFIG_PATH in os.listdir():
with open(CONFIG_PATH, encoding="utf-8") as fp:
data = json.load(fp)
return Config.from_dict(data)
else:
print("No configuration file")
return Config()
然後由 Config 類別將其還原為實體:
@classmethod
def from_dict(cls, d):
obj = cls()
obj.local_name = d["local_name"]
obj.adv_interval_us = d["adv_interval_us"]
obj.passkey = d["passkey"]
obj.idd_features = bytes(d["idd_features"])
return obj
先宣告一個全域變數:
_config = config.get_config()
然後只是簡單地將先前在 main.py 裡的 hard-coding 替換為 _config 的成員變數。如由原本的:
# 發送廣播
adv_data = build_advertising_payload()
local_name = "IDS 🍭"
resp_data = build_scan_response_payload(local_name)
ble.gap_advertise(_adv_interval_us, adv_data, resp_data=resp_data)
變為:
# 發送廣播
adv_data = build_advertising_payload()
resp_data = build_scan_response_payload(_config.local_name)
ble.gap_advertise(_config.adv_interval_us, adv_data, resp_data=resp_data)
完整程式請參考 https://github.com/ArcticCatSD/ESP32_MicroPython_IDS/tree/main/05