2026年7月8日 星期三

大甲鎮瀾宮一日遊

今天請一天假與水某及菁菁坐自強號去大甲鎮瀾宮拜拜, 雖然坐車單趟 2 小時多, 且炎夏太陽曬得人滿身大汗, 但鎮瀾宮周邊有許多大甲小吃 (炸香芋球, 炸肉丸, 粉腸, ...), 隨興地逛非常輕鬆, 名符其實的身心調適假. 唯一美中不足之處是早上時間抓太緊, 太晚出發去坐捷運, 到了新左營離自強號開車只剩 10 分鐘, 一出捷運閘門趕緊用衝的, 還好在預定上車時間前 3 分鐘到達月台, 結果看板顯示此自強號 3000 列車將晚到 5 分鐘. 









沿著車站前的蔣公路走約 5 分鐘即可達鎮瀾宮, 走進廟門發現它面積其實不算大, 比鄉下老家的獅形頂朝天宮還小一些 :





但走進主殿參拜, 發現其壁畫雕刻相當精巧, 頗有可觀之處 : 





下午吃飽喝足, 參拜完廟宇後去吃芋頭銼冰, 吃完還是覺得暑熱難耐, 只好鑽進路易莎喝咖啡吹冷氣滑手機, 直到傍晚近七點才去搭自強號回高雄, 結束一日大甲快閃之旅. 這是我第一次來到大甲, 第一次到鎮瀾宮拜媽祖, 雖然天氣熱但覺得大甲這地方很不錯, 我喜歡. 

2026年7月7日 星期二

INHON 應宏 Carbonbook 筆電維修 (二)

兩周前在蝦皮買的精密螺絲起子組到貨後, 6/26 高雄豪雨假放假一天, 我把這工具組回鄉下, 用裡面的五角起子拆開 INHON 舊筆電底蓋 : 




SSD 模組位於底部散熱銅管與上方電池模組中間 : 





金手指只有一個凹槽, 正面無接點都是銅箔, 模組上有 PHISON 字樣的大顆 IC 是群聯的 SSD 控制晶片PHISON PS3108-S8 : 




背面缺口凹槽右邊有 6 個接點, 左邊有12 個, 缺口寬度約 1mm, PCB 邊緣到缺口中心約 1cm (右側至中心) 與 1.5cm (左側至中心) :  



 

SSD 插槽 :




這與與目前蝦皮上還可買到的 Toshiba 或 Lite-on M.2 SATA 2280 模組在模組尺寸與金手指接點與凹槽數方面均有差異 : 





"現貨不用等" MSATA SSD 60 120 240GB $550



我把 SSD 拍照上傳 AI 看看能否辨別型號, 結果 AI 無法確認型號, 研判這可能是應宏請合作廠家設計的特規 OEM 客製化板對板 (Mezzanine) SSD SATA 模組. 我也上傳與蝦皮上賣的中古 SSD 圖片請 AI 比對, 發現與 INHON 這塊 SSD 可能無替代性. 在這台 Carbonbook 出廠的 2013~2014 年, 那時正好是 mSATA/M.2 SATA 的 SSD 規格未統一時代, 出現特規模組是很常見的. 所以決定放棄購買這些二手 SSD 模組來重灌. 

我把原廠 SSD 的金手指接點用橡皮擦清潔後插回主機板, 用 Win8 啟動隨身碟開機, 發現畫面與前一篇似乎有點不同 :










雖然修復失敗, 但起碼沒有出現前一篇的 "未連接必要裝置或無法存取必要裝置" 提示 (錯誤碼 0xc0000225), 有讀到 Windows 10 系統, 只是作業系統部分毀損了. 
 

Google Antigravity 學習筆記 : 重構 serverless 函式執行平台 (一)

在利用 agy 完成市圖網站爬蟲改版後, 接下來想要繼續用它來重構 serverless 函式執行平台, 主要目的是要加上 API Key 機制, 其次是美化前端介面. 

本系列全部文章索引參考 :


我去年在鄉下家的 Mapleboard 伺服器上佈署了仿 GCF 基本功能的 serverless 函式執行平台 (後端使用 Flask), 後續透過 ChatGPT 精進功能後, 佈署到 render.com 雲端網站上, 目前主要是用來館裡市圖借書預約爬蟲的擷取結果, 參考 : 


我將 serverless 寄存在 GitHub 以利 render.com 佈署之用 : 



1. 前置處理 : 

我先與 Gemini 討論 GitHub 倉庫是要繼續使用原倉庫 serverless, 還是新建一個 serverless2, 因為基於懷舊, 我想保留原來樸實無華的陽春版本面貌. Gemini 建議繼續在原有的 serverless 倉庫進行改版, 但透過 Git 的分支 (Branch) 或標籤 (Tag) 來管理, 而不需要大費周章開新倉 serverless2. 理由是基於專案連續性與降低維護成本, 開新倉會讓歷史提交紀錄斷代, 未來若發現第一版有個底層 Bug 要修, 得在兩個 repo 各改一次. 

但要如何在原倉完美保留第一版的樸實模樣呢? Gemini 建議兩個方案 :
  • 使用 Git Tag 凍結版本 :
    這是在原倉的狀態上打上一個標籤 (例如 v1.0.0-basic), 然後直接在 main 分支上大刀闊斧地進行重構. 未來如果想重溫第一版, 任何人只需要執行 git checkout v1.0.0-basic 指令, 程式碼就會瞬間回到最純粹的樣子. 
  • 開闢長青分支 (Long-lived Branch) :
    這是用 git checkout 指令為原倉建立一個分支 (例如 v1-basic) 永遠停留在這裡不再異動, 的 main 分支則用來開發具有 API Key 認證機制的新版. 好處是在 GitHub 的網頁畫面上隨時點選下拉選單就能看到第一版專屬分支的程式碼. 
Gemini 強烈建議採用 Git Tag 做法.


(1). 下載專案 : 

首先到 Antigravity CLI 專案根目錄下 (此處為 D:\antigravity_cli\projects) 用 git clone 指令將 repo 複製到本機 : 

git clone https://github.com/tony1966/serverless.git

PS D:\antigravity_cli\projects> git clone https://github.com/tony1966/serverless.git   
Cloning into 'serverless'...
remote: Enumerating objects: 136, done.
remote: Counting objects: 100% (136/136), done.
remote: Compressing objects: 100% (131/131), done.
remote: Total 136 (delta 73), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (136/136), 52.96 KiB | 903.00 KiB/s, done.
Resolving deltas: 100% (73/73), done.

下載完成後會放在專案資料夾 serverless 下, 可用 tree 指令檢視專案結構 :

PS D:\antigravity_cli\projects> tree serverless /f   
列出磁碟區 新增磁碟區 的資料夾 PATH
磁碟區序號為 000001FC 1258:16B8
D:\ANTIGRAVITY_CLI\PROJECTS\SERVERLESS
│  Procfile
│  requirements.txt
│  serverless.py
└─functions
        add.py
        add_function.py
        add_table.py
        clear_stats.py
        delete_function.py
        delete_record.py
        drop_table.py
        edit_function.py
        execute_sql.py
        export_table.py
        hello.py
        linebot_gemini.py
        linebot_gpt.py
        list_functions.py
        list_tables.py
        save_function.py
        send_books_messages.py
        send_ksml_books_messages.py
        show_schema.py
        show_stats.py
        update_function.py
        update_ksml_books.py
        view_table.py
        __init__.py

其中黃底色部分為自訂的應用函式, 不是系統本身的一部份. 

用 git clone 從 GitHub 下載的專案, 其資料夾會自動納入版控, 不需要再下 git init 指令, 因為下載過程會把專案在 GitHub 上的所有 Commit 歷史, 分支, 以及最重要的 Git 核心控制檔 (就是隱藏的 .git 資料夾) 都下載下來, 已經具備完整的 Git 版控功能. 

git clone 下載的專案預設會停在 main (或 master) 分支上, 可用 git status 檢視 :

PS D:\antigravity_cli\projects> cd serverless   
PS D:\antigravity_cli\projects\serverless> git status   
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean


(2). 將原專案打上標籤 : 

接下來用 git tag 指令將下載至本機中的專案打上標籤凍結歷史 : 

git tag -a v1.0.0-basic -m "第一版:樸實無華的基礎 Serverless 平台" 

PS D:\antigravity_cli\projects\serverless> git tag -a v1.0.0-basic -m "第一版:樸實無華的基礎 Serverless 平台"  

然後將此 Tag 推送到 GitHub 上 : 

git push origin v1.0.0-basic 

PS D:\antigravity_cli\projects\serverless> git push origin v1.0.0-basic   
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 230 bytes | 230.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/tony1966/serverless.git
 * [new tag]         v1.0.0-basic -> v1.0.0-basic

如此一來, 無論以後程式碼怎麼改, 只要在任何地方輸入 git checkout v1.0.0-basic, 就能切回去, 隨時重溫第一版的程式碼了. 

注意, git tag 本質上只是在 Git 的歷史紀錄中幫某個特定的 Commit (提交節點) 貼上一張唯讀的標籤紙而已, 這完全沒有更動到任何一行 程式碼, 專案架構或設定檔, 對於依賴原倉來重新佈署 serverless 的 render.com 來說, 整個專案的內容與打 Tag 前是一模一樣的, 不影響縣有兩個 render.com 上專案的佈署, 因為 render.com 的部署機制是認分支而不是認標籤. 上面所坐的動作只是把 main 分支目前的狀態打上標籤並推上去而已. 


(3). 建立新分支 : 

用下列指令從目前的主分枝 main 建立一個新分枝 :

git checkout -b feature/api-token-auth

checkout 是 Git 中用來切換或提取的指令, 作用是移動工作指針 (HEAD), 讓工作目錄切換到不同的分支或歷史節點, 此處用來切換到新分支. -b 是 branch (分支) 的縮寫, 代表建立新分支, 也就是用目前的進度為基底, 原地創造一個全新的分支, 並且在創造完後自動切換到新分支 (如果沒有加 -b 參數, Git 會去尋找一個已經存在的分支並切換過去). 

最後面的參數 feature/api-token-auth 是以軟體工程中標準的斜線命名法來指定分支名稱, 其中 feature/ 表示新功能的前綴, 常見的前綴還有修正 Bug 的 bugfix/ 與重構的 refactor/. 斜線後面的 api-token-auth 是自訂的分支名稱 (可用字元為字母, 底線或連字號), 只要能清楚說明這個分支的目的即可. 

PS D:\antigravity_cli\projects\serverless> git checkout -b feature/api-token-auth
Switched to a new branch 'feature/api-token-auth'

檢視目前狀態在哪個分支 :

PS D:\antigravity_cli\projects\serverless> git status 
On branch feature/api-token-auth
nothing to commit, working tree clean


(4). 在新分支建立隔離資料夾 : 

從上面 tree /f 結果可知, 原倉庫的 functions 資料夾下含有非系統的應用函式 (黃底色檔案), 這些 apps 可能會在 agy 閱讀程式碼時分散它的注意力, 干擾它對專案脈絡的理解. 但也不要直接將它們刪除, 因為當 API Key 認證機制完成後, 我們需要拿幾個函式來測試沒帶 Token 會不會被擋, 這時這些真實的用戶端應用就可派上用場了. 

兩全其美的做法是在 functions 底下建一個臨時資料夾 (例如 apps_backup), 將它們移到一個此資料夾中, 與上層的系統操作函式隔離開來, 因為對 AI 來說, 結構的改變就代表了語意的改變, 當 agy 掃描專案目錄, 分析 serverless.py 的功能後, 又看到 functions 目錄下的 apps_backup 資料夾, 它會立刻理解, functions 底下的函式檔是系統管理功能, 而把 apps_backup 判定為不需同步修改的歷史檔案或備份. 如果不想讓 agy 看到這些自訂應用函式檔, 最徹底的方式是在 ,gitignore 檔中加入 functions/apps_backup/ 這一行. 

PS D:\antigravity_cli\projects\serverless> mkdir functions\apps_backup   

然後用 move 指令將自訂應用函式檔搬到 apps_backup 下 :

PS D:\antigravity_cli\projects\serverless> move functions\add.py functions\apps_backup\
PS D:\antigravity_cli\projects\serverless> move functions\hello.py functions\apps_backup\
PS D:\antigravity_cli\projects\serverless> move functions\linebot_gemini.py functions\apps_backup\
PS D:\antigravity_cli\projects\serverless> move functions\linebot_gpt.py functions\apps_backup\
PS D:\antigravity_cli\projects\serverless> move functions\send_books_messages.py functions\apps_backup\
PS D:\antigravity_cli\projects\serverless> move functions\send_ksml_books_messages.py functions\apps_backup\
PS D:\antigravity_cli\projects\serverless> move functions\update_ksml_books.py functions\apps_backup\

搬移後的檔案結構如下 :

PS D:\antigravity_cli\projects\serverless> tree functions /f  
列出磁碟區 新增磁碟區 的資料夾 PATH
磁碟區序號為 00000244 1258:16B8
D:\ANTIGRAVITY_CLI\PROJECTS\SERVERLESS\FUNCTIONS
│  add_function.py
│  add_table.py
│  clear_stats.py
│  delete_function.py
│  delete_record.py
│  drop_table.py
│  edit_function.py
│  execute_sql.py
│  export_table.py
│  list_functions.py
│  list_tables.py
│  save_function.py
│  show_schema.py
│  show_stats.py
│  update_function.py
│  view_table.py
│  __init__.py
└─apps_backup
        add.py
        hello.py
        linebot_gemini.py
        linebot_gpt.py
        send_books_messages.py
        send_ksml_books_messages.py
        update_ksml_books.py


(5). 提交 Git 紀錄 : 

完成應用 app 檔案搬移後, 就完成重構的前置作業了, 用下列兩個指令進行提交, 把搬移成果正式記錄進 Git 的歷史紀錄裡 : 

PS D:\antigravity_cli\projects\serverless> git add .  
PS D:\antigravity_cli\projects\serverless> git commit -m "chore: 隔離自訂應用至 apps_backup,準備進行 API Token 重構"
[feature/api-token-auth c9afe88] chore: 隔離自訂應用至 apps_backup,準備進行 API Token 重構
 7 files changed, 256 insertions(+), 256 deletions(-)
 rename functions/{ => apps_backup}/add.py (97%)
 rename functions/{ => apps_backup}/hello.py (98%)
 rename functions/{ => apps_backup}/linebot_gemini.py (97%)
 rename functions/{ => apps_backup}/linebot_gpt.py (97%)
 rename functions/{ => apps_backup}/send_books_messages.py (100%)
 rename functions/{ => apps_backup}/send_ksml_books_messages.py (97%)
 rename functions/{ => apps_backup}/update_ksml_books.py (97%)


2026年7月5日 星期日

2026 年第 26 周記事

時序來到七月炎夏, 2026 不知不覺已過去一半了. 二哥因為報名國家半導體中心課程要去成大上課一周 (學習 Synopsys 開發工具), 周日晚上回到高雄, 周五課程上完返回中壢. 由於論文尚未寫完, 老師要他再寫一篇文章發表, 所以要下學期才畢業了. 周五晚上菁菁回家, 一起去巨蛋對面的和牛涮吃火鍋 (我覺得這家很不錯), 吃完載二哥去坐高鐵, 我再回鄉下. 

本周開始改用 Antigravity CLI 開發專案, 用法與舊版的 Gemini CLI 類似, 但功能與配備則強大許多 (除了 Gemini 模型, 還能選擇 Claude 與 GPT 模型), 兩者差異不可同日而語. 接下來我將使用此新工具一步步來把我擱置已久的開發計畫逐一實現. 

今天我用長竿把菜園芒果樹上最後一顆芒果用長竿採下來, 今年的芒果季就算結束了. 往年下個月就是龍眼採收時節, 但可惜今年龍眼沒開花. 

Google Antigravity 學習筆記索引

谷歌在 6/18 進行產品線更新, 推出 Antigravity CLI 平台 (agy) 給個人用戶使用 (免費版與 Google AI Pro 以及 Google AI Ultra 方案訂戶), 原本的 Gemini CLI 則保留給購買 Google Cloud 企業方案, 或是使用付費企業級 API 密鑰的用戶使用. Antigravity CLI 功能比 Gemini CLI 更強大, 可以選擇 Gemini/Claude/GPT 模型來實作專案. 

以下是 agy 的學習筆記索引 :



~ 進行中 ~

2026年7月4日 星期六

在樹莓派 Pi 400 (Trixie) 虛擬環境中佈署市圖爬蟲程式 (v14)

這兩天利用 Antigravity CLI 搞定市圖爬蟲程式 v14 升版後, 陸續佈署到 kaopi3 與 pi3aplus 主機上且順利運行中, 今天輪到 Pi 400 主機了. 

我目前在 Pi 400 安裝的樹莓派 OS 是最新的 Trixie (內建 Python 3.13), 從上一版的從 Bookworm 開始, 樹莓派 OS 即遵循 PEP 668 規範, 不允許直接在系統 Python 環境用 pip 安裝第三方套件, 必須建立虛擬環境後在虛擬環境裡面才能用 pip 安裝套件. 

有別於 Pi 3 主機直接在系統 Python 3.9.2 上執行 Python 程式, 在 Pi 400 上必須在虛擬環境中安裝套件與執行 Python 程式, 目前 Pi 400 的爬蟲是在虛擬環境 myenv313 下執行, 所以先進入此虛擬環境 : 

pi@pi400:~ $ source ~/myenv313/bin/activate   
(myenv313) pi@pi400:~ $

因為之前就已在此環境下安裝 Numpy 時安裝過 OpenBLAS 及相關的底層依賴庫, 所以下面指令可以略過 :

sudo apt-get update
sudo apt update sudo apt install -y libopenblas-dev libatlas-base-dev 

接下來安裝 tesseract-ocr 套件 : 

(myenv313) pi@pi400:~ $ sudo apt-get install tesseract-ocr   
正在讀取套件清單... 完成
正在重建相依關係... 完成  
正在讀取狀態資料... 完成  
The following packages were automatically installed and are no longer required:
  alacarte gir1.2-gmenu-3.0 gnome-menus gtk-nop libevent-pthreads-2.1-7t64 libgnome-menu-3-0
  libwlroots-0.18 python3-gi-cairo retry
Use 'sudo apt autoremove' to remove them.
下列的額外套件將被安裝:
  libleptonica6 libtesseract5 tesseract-ocr-eng tesseract-ocr-osd
下列【新】套件將會被安裝:
  libleptonica6 libtesseract5 tesseract-ocr tesseract-ocr-eng tesseract-ocr-osd
升級 0 個,新安裝 5 個,移除 0 個,有 261 個未被升級。
需要下載 7,207 kB 的套件檔。
此操作完成之後,會多佔用 24.5 MB 的磁碟空間。
是否繼續進行 [Y/n]? [Y/n] y
下載:1 http://deb.debian.org/debian trixie/main arm64 libleptonica6 arm64 1.84.1-4 [994 kB]
下載:2 http://deb.debian.org/debian trixie/main arm64 libtesseract5 arm64 5.5.0-1+b1 [1,237 kB]
下載:3 http://deb.debian.org/debian trixie/main arm64 tesseract-ocr-eng all 1:4.1.0-2 [1,594 kB]
下載:4 http://deb.debian.org/debian trixie/main arm64 tesseract-ocr-osd all 1:4.1.0-2 [2,992 kB]
下載:5 http://deb.debian.org/debian trixie/main arm64 tesseract-ocr arm64 5.5.0-1+b1 [389 kB]
取得 7,207 kB 用了 3s (2,122 kB/s)      
選取了原先未選的套件 libleptonica6:arm64。
(讀取資料庫 ... 目前共安裝了 147525 個檔案和目錄。)
正在準備解包 .../libleptonica6_1.84.1-4_arm64.deb……
Unpacking libleptonica6:arm64 (1.84.1-4) ...
選取了原先未選的套件 libtesseract5:arm64。
正在準備解包 .../libtesseract5_5.5.0-1+b1_arm64.deb……
Unpacking libtesseract5:arm64 (5.5.0-1+b1) ...
選取了原先未選的套件 tesseract-ocr-eng。
正在準備解包 .../tesseract-ocr-eng_1%3a4.1.0-2_all.deb……
Unpacking tesseract-ocr-eng (1:4.1.0-2) ...
選取了原先未選的套件 tesseract-ocr-osd。
正在準備解包 .../tesseract-ocr-osd_1%3a4.1.0-2_all.deb……
Unpacking tesseract-ocr-osd (1:4.1.0-2) ...
選取了原先未選的套件 tesseract-ocr。
正在準備解包 .../tesseract-ocr_5.5.0-1+b1_arm64.deb……
Unpacking tesseract-ocr (5.5.0-1+b1) ...
設定 libleptonica6:arm64 (1.84.1-4) ...
設定 tesseract-ocr-eng (1:4.1.0-2) ...
設定 libtesseract5:arm64 (5.5.0-1+b1) ...
設定 tesseract-ocr-osd (1:4.1.0-2) ...
設定 tesseract-ocr (5.5.0-1+b1) ...
執行 man-db (2.13.1-1) 的觸發程式……
執行 libc-bin (2.41-12+rpt1+deb13u2) 的觸發程式……

最後安裝 pytesseract 與 Pillow 套件 :

(myenv313) pi@pi400:~ $ pip install pytesseract Pillow   
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting pytesseract
  Downloading https://www.piwheels.org/simple/pytesseract/pytesseract-0.3.13-py3-none-any.whl.metadata (11 kB)
Requirement already satisfied: Pillow in ./myenv313/lib/python3.13/site-packages (11.3.0)
Requirement already satisfied: packaging>=21.3 in ./myenv313/lib/python3.13/site-packages (from pytesseract) (25.0)
Downloading https://www.piwheels.org/simple/pytesseract/pytesseract-0.3.13-py3-none-any.whl (14 kB)
Installing collected packages: pytesseract
Successfully installed pytesseract-0.3.13

至此執行新版爬蟲所需的套件都齊了, 測試一下 :

(myenv313) pi@pi400:~ $ python ksml_lib_14.py abc 123456
主機 : pi400
[嘗試 1/3] 驗證碼辨識結果: 0003
[嘗試 1/3] 登入失敗,準備重試...
[嘗試 2/3] 驗證碼辨識結果: 43504
登入成功(第 2 次嘗試)
擷取借閱紀錄 ... OK
擷取預約紀錄 ... OK
資源已釋放
產生借書到期摘要 ... OK
產生預約書摘要 ... OK
{'message': abc 的資料已更新', 'status': 'success'}
執行時間:61.67458128929138

爬蟲程式可以順利執行. 這樣就可以為爬蟲程式添加可執行權限 :

pi@pi400:~ $ chmod +x ksml_lib_14.py   

由於 Pi 400 主要做為支援 pi3aplus 主機的爬蟲任務之用, 所以它所綁定的後端 render.com 伺服器為 fdof, 用 nano 修改 ksml_lib_14.py 中的網址 : 

    # --- 推送資料 ---
    if b_msg or r_msg:  # 任一不為空字串就更新資料表
        url = "https://serverless-fdof.onrender.com/function/update_ksml_books"
        payload = {
            "account": account,
            "borrow_books": b_msg,
            "reserve_books": r_msg
        }
        res = requests.post(url, json=payload)
        print(res.json())

另外, 從 render.com 截取資料的程式 get_ksml_books_messages.py 也是綁定 fdof : 

# get_ksml_books_messages.py
import requests
import socket

host_name=socket.gethostname()
print(f'主機 : {host_name}')
params={'crawler': f'{host_name}'}
# for kaopi3
# url='https://serverless-5e6i.onrender.com/function/send_books_messages'
# for pi3aplus & pi400 (備援)
url='https://serverless-fdof.onrender.com/function/send_books_messages'
res=requests.get(url, params=params)
print(res)

最後把 crontab 中的爬蟲程式由 v13 改成 v14 即可 (雖然目前都被註解掉未執行). 

如何擷取電腦上一抓就消失的畫面

有些 PC 上的電腦畫面無法用 Picpick 抓圖, 這時就需要用到延時截取工具, Win11 本身內建的剪取工具就派上用場了, 按 Win + S 搜尋 "剪取工具" 開啟此軟體 (或直接按 Win +Shift + S), 點右上方的時鐘按鈕, 勾選延遲時間 (為了有較長操作時間可選 10 秒), 然後按左上角的新增鈕, 這時就會倒數計時所選的延遲秒數, 要趁此空檔打開想抓取的電腦畫面, 等倒數結束, 電腦螢幕會變暗, 這時就可按滑鼠左鍵拉曳要截取的部分, 放開就會進行截取 : 




所截取的圖會放在 "文件/圖片/螢幕擷取畫面" 下面. 

DW100pro+ 手表手機的 WiFi 無線基地台連線方法

之前原本買給爸的 DW100pro+ 手錶因為他不習慣帶電子錶只好拿來自用, 使用幾個月下來覺得還蠻方便的, 尤其我每天需透過手機的小米 App 連線遍布鄉下老家裡裡外外的監視器確定爸的位置, 以便決定是打市內電話/手機, 還是直接透過監視器通話, 提醒他社區車子快來了要做好準備, 或者藥吃了沒有等等, 這時一邊看手機監視器畫面, 一邊撥打手錶手機電話就很方便. 另外設定與我的 S24U 手機同振, 去上廁所也不會漏接重要電話. 

DW100pro+ 手錶目前門號月租 150 元, 每月有 2GB 網路用量, 通常用不完, 就想說慢速下載檔案時也可以拿來利用, 但今天打開 DW100+pro 手錶熱點, 設定連線密碼後, 用 LG 筆電連線 DW100pro+ 手錶的熱點, 輸入密碼卻一直顯示需輸入 4 或 8 碼數字的 PIN 碼, 但我設置的熱點密碼含有英文字母啊! 一直卡在這邊. 問了 Gemini 才知是輸入密碼的地方不正確. 

點擊筆電右下角的 Wi-Fi 清單按鈕 (電波符號), 點選手錶熱點 DW100pro+, 當跳出提示輸入 4 或 8 碼 PIN 碼時, 不要輸入, 在 PIN 輸入框的下方有一個 "改用密碼連線" 連結, 按此連結會顯示一個輸入密碼的輸入框, 這才是輸入熱點密碼的地方 : 




輸入手錶的熱點密碼按下一步就能順利連線了 :



Python 學習筆記 : 市圖借書與預約爬蟲程式改版 v14

由於 6/18 市圖網站登入網頁改版, 加上了數字圖片驗證碼功能, v13 的爬蟲程式立馬崩潰無法登入帳戶擷取借閱與預約資訊, 整個六月又在忙著復原 MSI 電競桌機, 所以爬蟲改版事宜只好擺著, 直到今天才動手, 這次我使用剛上手的 Antigravity CLI 來重構舊版程式, 加上 OCR 圖形辨識功能, 選擇 Claude Sonnet 模型來規劃與實作, 參考 :


原始碼放在 GitHub :


但因為新版程式辨識驗證碼需要用到 Numpy 與其底層依賴庫, 必須安裝 OpenBLAS 與 tesseract-ocr 等套件, 這樣  ksml_lib_14.py 才能順利在 Pi 3 與 Pi 3A+ 上執行. 

# 更新套件清單
sudo apt-get update

# 安裝 OpenBLAS 及其相關的底層依賴庫
sudo apt update sudo apt install -y libopenblas-dev libatlas-base-dev

# 安裝 tesseract-ocr 套件 :
sudo apt-get install tesseract-ocr

# 安裝 pytesseract 與 Pillow 套件 : 
pip install pytesseract Pillow

# 把 ksml_lib_14.py 傳送到樹莓派後, 先用 chmod 添加可執行權限 :
chmod +x ksml_lib_14.py

# 修改 ksml_lib_14.py 中的 render.com 網址
# kaopi3 -> 5e6i 
# pi3aplus -> fdof 
# pi400 -> fdof (備用) 
nano ksml_lib_14.py

# 測試程式功能是否正常 :
python  ksml_lib_14.py <username> <password> 

# 更改 crontab 設定, 把 ksml_lib_13.py 改成 ksml_lib_14.py
crontab -e