讓 Telegram bot 告訴你樹莓派的 IP 吧!(Rust version)

本文為本人先前製作的另外一個小工具的 Rust 版本,先前是使用 Python 寫成的,有興趣了解的人可以參考本人之前在 Medium 的教學文:https://hms5232.medium.com/讓-telegram-bot-告訴你樹莓派的-ip-吧-dac22f5ad0d6

本文撰寫的時間剛好是大年初三,因此開頭先祝大家新年快樂!本專案其實在過年前就已經初步開發完成了,但因為隨後就是過年,所以一些相關的心得記錄就拖到現在──其實 README 也才剛 commit 上去不久就是。

先前情提要一下(關於樹梅派拿 IP 這件事情有接觸過的人應該會知道,就不贅述),先前已經做了一個 Python 版本的了,為什麼還要再開發一個用 Rust 重寫的版本呢?為什麼是 Rust?有什麼優勢?

首先,其實先前製作的 Python 版本,在我的樹梅派重新安裝成 64 位元(相關心得請見〈前進!Raspberry Pi OS 64 位元〉)+改用 Poetry 後,會出現異常情況:剛開機就立刻執行會無法正確地取得 IP。至於為什麼我到現在也還沒找到,觀察下來有在猜是否因為剛開機還沒連線所以抓不到?但即便如此,也應該要有 local 及 docker 網路介面卡資訊才對。在幾番測試下,最後找到了解法:延遲。

開機後先 sleep 7 秒(這是我反覆重新啟動後認為最保險不會出問題的秒數)再開始拿 IP 和送訊息。這招雖然解決了前面提到的問題,可是造成了其他問題:每次開機後(即便開機速度飛快)我也至少要等待 7 秒鐘,機器人把訊息送出我接收到了才能真的確認樹梅派開機完成且連上網路。空等在現在這個硬體速度飛快的年代是難以接受的一件事,不過當時手邊可運用的資源沒更好的解法,只能先這樣,當成十年前沒有 SSD 的老電腦開機。

去年我開始學習 Rust,過年前某個周末,想說來練習一下 leetcode 好了,用 Rust 一寫、提交,我靠,這什麼數字!

Leetcode 提交且被接受後的執行時間統計數字
Leetcode 提交且被接受後的記憶體使用量統計數字

0 ms!令人震驚的數字!然後過幾天我突然想到,既然 Rust 跨平台、高效能,那運用在效能有限的樹梅派上,不是很剛好嗎?因此就開始動手實作用 Rust 重寫的工作。

準備

先提一下我的樹梅派環境:

  • Raspberry Pi 4 8GB with Raspberry Pi OS 64 bit

基本上這應該是不影響本專案使用,不過以防萬一就還是提出來做為參考。

然後要自備的其他東西:

  • Telegram:如果你沒有 Telegram,趕快一起加入吧!
  • Telegram bot:如同我之前教學文中說的,如果不會開機器人,可參考這位大大寫的教學文,即使放到今日也是相當詳細的好文章
  • (選,想直接使用二進位執行檔者不需要)Rust:請至官網依指示安裝,直接裝最新版就對了

使用

設定

設定方式有兩種:環境變數或是 .env

使用環境變數的人,請在執行程式碼之前設定好環境變數,請直接跳到執行段落。

使用 .env 的話,請先複製出專案的範例設定檔:

1
2
cp .env.example .env
# 或直接到 https://raw.githubusercontent.com/hms5232/get-LAN-IP-telegram-bot-rs/main/.env.example 複製

然後編輯 .env 的內容。

這個 .env 必須要放在和二進位執行檔相同或上層的資料夾。

Binary

目前我沒有把編譯好的執行檔放在 GitHub,這部分還在思考該怎麼進行(例如:是否使用 GitHub Release 搭配 action,還是直接保留最新執行 job 產出的 artifact 就好等等)。

如果想直接使用二進位執行檔,需要有其他人或裝置先完成編譯,再放到樹梅派中。

現在已經有在 GitHub Release 放上打包好的二進位執行檔囉,歡迎需要的人下載使用!

https://github.com/hms5232/get-LAN-IP-telegram-bot-rs/releases

Source

請直接 Clone 或下載 repo,進入專案後直接

1
cargo build --release

雖然我曾擔心過這個編譯的動作(尤其為 release 的編譯)會不會讓樹梅派無法負荷,不過事實證明我想太多了。我自己的樹梅派是裸著沒有散熱片和風扇等東西的,在冬天的時候(沒有寒流)編譯可以順利完成;反而是在安裝或更新 Rust 的時候常常 ssh 直接斷掉或重開。因此我也有在想是否要使用 CI 的方式編譯出執行檔,樹梅派直接下載回來用即可。不過這部分目前還在衡量,因此比較簡單快速的方式仍是直接從原始碼編譯。

執行

Add the following line into /etc/rc.local:

1
(cd /path/to/binary && ./get-LAN-IP-telegram-bot-rs; cd -)&

1
(TOKEN='bot token' NOTIFY_USER_ID='chat id' /path/to/get-LAN-IP-telegram-bot-rs/binary)&

for example:

1
(cd /home/pi/Documents/get-LAN-IP-telegram-bot-rs && ./target/release/get-LAN-IP-telegram-bot-rs; cd -)&

結語

IP 來了

這次也是一個小小的 Rust 專案,雖然我曾經想過要不要直接用 http 請求來做這個需求(畢竟 Telegram API 還算單純)但後來想想日後或許會再添增一些功能上去,故還是安裝了他人寫好了 Telegram bot client 來用。雖然執行檔體積和編譯時間都會增加,不過換取日後新增功能方便,應該是還可以接受的犧牲。

就我自己實測結果來看,我前面推測的沒錯,開機執行到樹梅派設定的開機手稿時,IP 資訊早就有了,Python 版本在那個階段執行確實出了點問題。我懷疑是取得 IP 的套件有問題,不過現在有 Rust 版本後,那邊的問題我也懶得去測試了,後面順利的話可能就會直接封存 Python 版本了吧。

這次撰寫本文分享,希望能夠幫助到有相同需求的人。如果覺得專案有幫上忙,也希望可以幫忙在 GitHub 上點個星星,讓我知道這個小東西也有在其他地方默默地發揮它的功能。本次文章就到這邊,最後再次祝大家新年快樂。