第 12 章 - Magic mirror 初探
上次更新日期 2023/01/04
樹莓派除了可以使用 Linux 作業系統之外,還可以在 Linux 上面安裝個魔鏡軟體, 該軟體如果搭配適當的硬體,還可以讓你的樹莓派立刻變成亮麗的展示播放器!這裡讓我們來處理一下 magic mirror 吧!
學習目標:
- 了解什麼是 magic mirror
- 在樹莓派上面安裝 magic mirror
12.1: 安裝 magic mirror
走在百貨公司、各大賣場、捷運系統內、火車高鐵站、飛機場航廈等,常常可以看到顯示螢幕,這個螢幕會顯示商品特性、 特價品活動介紹、車次資訊以及航班資訊之外,通常還會有氣象資料、空品資料等等的介紹!這些東西通通集合在一個螢幕上! 有些甚至是投影到玻璃上面,讓顯示資料有浮在牆面上的感覺!這就是所謂的魔鏡!例如底下的連結,甚至已經有推出相關商品了;
- 安裝 magic mirror
magic mirror 就是實現魔鏡功能的開放原始碼軟體,這個軟體也是透過 nodejs 來實現 server/client 互動功能的! 這真是太棒了!所以,我們就不用重複安裝 nodejs 了!只要直接安裝 Magic mirror 即可。Magic mirror 官網在文末的參考資料中, 而實際程式碼,則統一放在 github 內,因此,基本上,安裝 magic mirror 使用的是 git 指令喔!
# 1. 先下載 Magic mirror 的主程式碼: $ git clone https://github.com/MichMich/MagicMirror $ ll -d Magic* drwxr-xr-x 17 rasppi rasppi 4096 12月 2 13:41 MagicMirror # 2. 進入 MagicMirror 目錄,並觀察檔案 $ cd MagicMirror $ ll ... # 3. 實際將軟體安裝起來!包括所有需要的模組 $ npm run install-mm
上面最後一個動作,實際上就已經開始安裝所有需要的軟體!這時候你的樹莓派會從網路上拉下一堆資料, 因為拉這些資料來進行安裝的行為,會花費相當多的時間!而且根據網路速度、你的硬體效能,時間上面會有很大的差異! 根據官網的說法,一般樹莓派 3B 可能會花費 10 分鐘以上的時間,如果比 3B 還慢的系統,更恐怕會長達 30 分鐘以上! 請不要隨意中斷整體過程喔!(鳥哥實際測試,系統花費大約 3~5 分鐘喔!)
- 啟動 magic mirror
要啟動 magic mirror 之前,請先注意,你的樹莓派系統上面必須要有圖形界面,然後,你的樹莓派也可以直接連接到螢幕, 如果過去你的樹莓派就是以圖形界面桌上型電腦系統的方式存在,那就可以直接啟動 maric mirro 的服務了! 還好,我們的系統就是預設的樹莓派系統,因此,確實有圖形界面!所以,可以這樣直接啟動即可:
# 1. 直接將設定檔複製一份成為預設的設定值: $ cp config/config.js.sample config/config.js # 2. 直接跑 magic mirro 軟體 $ npm run start ..... [ctrl]+c
如果一切順利的話,基本上,你樹莓派連接的螢幕,理論上就會出現如下的畫面:
- 解決螢幕進入休眠狀況的問題
剛開始你可能不會發現,不過,運作一小段時間 (幾分鐘吧) 之後,就會發現啦,那就是...螢幕會主動進入休眠! 得要滑動滑鼠啦、鍵盤之類的,螢幕才會醒過來...怎麼處理這個問題呢?基本上,可以從 Linux 圖形界面的 Xorg 軟體著手處理。 你可以在啟動 X 視窗的時候,將進入螢幕保護的時間與電源管理關閉,這樣就可以讓螢幕亮晶晶...方法也不難, 修改 /etc/lightdm/lightdm.conf 的設定內容即可:
$ sudo vim /etc/lightdm/lightdm.conf ..... [Seat:*] ..... #xserver-command=X xserver-command=X -s 0 -dpms ..... $ sudo systemctl isolate multi-user $ sudo systemctl isolate graphical $ ps aux | grep Xorg root .... tty7 Ssl+ 15:39 0:01 /usr/lib/xorg/Xorg -s 0 -dpms :0 -seat seat0..
這樣,你的螢幕就可以長亮了!
- 自動關閉螢幕的方式
上面的方式主要是針對重新開機進入系統時強迫系統的預設值~如果你需要定時關閉螢幕,或者是定時啟動螢幕, 那也可以使用 xset 這個指令來處理。處理的方式很簡單,就是 (1)進入休眠模式與 (2)喚醒離開休眠模式而已。
# 進入休眠模式 $ xset -display :0 s on s 1 # 喚醒螢幕 $ xset -display :0 s off s activate
你可以自己從遠端連線測試一下這個情況!如果想要定期處理,請自行透過 crontab 來處置囉!除了 xset 之外, 在樹莓派上面,我們也可以透過 vcgencmd 來處理螢幕的電源供應問題。不過與螢幕保護程式不一樣的地方是, 使用 xset 進行的螢幕保護程式,可以透過滑鼠、鍵盤來喚醒。等等使用 vcgencmd 的方式,則一定要使用 vcgencmd 重新喚醒, 否則就一直是關電的情況喔!使用方法如下:
# 關閉螢幕電源 $ vcgencmd display_power 0 display_power=0 # 打開螢幕電源 $ vcgencmd display_power 1 display_power=1 # 顯示目前的螢幕電源狀態 $ vcgencmd display_power display_power=1
12.2: 簡易修改 magic mirror 的設定
雖然我們的鏡子已經搞定,但是...非常怪啊!竟然是英文與一堆怪異的資料~這是由於設定值預設在美語國家的原因。 我們就得要稍微進行一些簡易的修改,讓系統可以變得正常。詳細的設定可以參考官網的模組說明,我們這裡只做一些簡易的修改!
- 時區與語言的修改
預設都是英文展示的 Magic mirror 內容,先來修改一下語系資料~直接這樣修改就好了!很簡單:
$ vim config/config.js let config = { .... language: "zh-tw", locale: "zh-tw", ....
基本上,這樣就可以改成中文了!只是,我們還想要修改一些資料,等等再來重新啟動喔!
- 時鐘格式更改
預設的時鐘為數位式 (digital),如果想要像一般機械時鐘的指針顯示,也可以使用類比式 (analog) 來展示。 我們可以調整兩者都出現 (both)。由於指針式提供共 12 種模式給我們選擇,而數位式又可以提供日升、日落的時間, 感覺上兩者通通選擇,好像也不錯!
# 1. 先處理時鐘語系時區的修改:
$ vim config/config.js
module: "clock",
position: "top_left",
config: {
module: "clock",
position: "top_left",
config: {
timezone: "Asia/Taipei",
displayType: "both",
analogSize: "300px",
analogFace: "face-003", // 3, 5, 9, 10 我覺得好
secondsColor: "yellow",
dateFormat: "dddd, YYYY/MM/DD",
showSunTimes: true,
lat: 22.98, // 輸入經緯度,才能算出日升、日落的時間
lon: 120.253,
},
},
- 修改日曆成為台灣地區與你專屬資料
假期列表比較麻煩,你當然可以手動處理~不過,有網站資料可以提供你一些最新的資訊,你可以下載之後進行處置。 下載的位置可以從底下來搜尋:
從該網站主選單『CALENDAR』找到左邊『iCal Calender』超連結,按下『Popular Categories』底下的『Holidays』, 就可以使用搜尋的方式,找到關鍵字為『Taiwan』的時間表,如下所示:
由於暫時找不到 maric mirror 放置於該軟體內部的資料位置,因此,利用我們自己的 webserver 的功能, 建立好 /var/www/html/download 之後,將找到並下載的檔名『Taiwan_Holidays.ics』放置到該目錄下! 然後修改一下輸出的文字,讓該文字變成中文!這樣才會有正常的行事曆功能:
# 1. 先處理好日曆相關的設定檔放置資料: $ cd /var/www/html $ sudo mkdir download $ sudo chown rasppi:rasppi download $ cd download $ cp ~/檔案目錄/Taiwan_Holidays.ics . # 2. 底下的指令請複製貼上即可!轉換相關的中文資料 dos2unix sed -i "1,2000s/^SUMMARY:Republic Day$/SUMMARY:元旦紀念日/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Children's Day$/SUMMARY:兒童節/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Chinese New Year$/SUMMARY:農曆新年/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Chinese New Year Holiday$/SUMMARY:農曆新年彈性放假/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Chinese New Year's Eve$/SUMMARY:除夕夜/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Dragon Boat Festival Holiday$/SUMMARY:端午節彈性放假/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Dragon Boat Festival$/SUMMARY:端午節/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Labour Day$/SUMMARY:勞動節/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Mid-Autumn Festival$/SUMMARY:中秋節/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:National Day$/SUMMARY:國慶日/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:National Day Holiday$/SUMMARY:國慶日彈性放假/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Qing Ming Festival$/SUMMARY:清明節/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Peace Memorial Day$/SUMMARY:和平紀念日/g" Taiwan_Holidays.ics sed -i "1,2000s/^SUMMARY:Peace Memorial Day Holiday$/SUMMARY:和平紀念日彈性放假/g" Taiwan_Holidays.ics # 3. 開始修改 config/config.js 的內容: $ vim config/config.js module: "calendar", header: "台灣行事曆", position: "top_left", wrapEvents: true, tableClass: "medium", config: { colored: true, calendars: [ { symbol: "glass-cheers", url: "http://localhost/download/Taiwan_Holidays.ics", }, { symbol: "calendar-check", color: "#fffc00", url: "http://localhost/download/ksu-dic.ics", }, ] }
上面的 symbol 是每個行事曆開頭的小圖示,眾多小圖示都可以到底下的網站去查看,直接在上頭輸入你想要的格式即可:
至於那個 ksu-dic.ics 則是我們自己指定的行事曆~這個行事曆可以加入我們需要的資料喔!行事曆的格式會有點像底下這樣, 特殊字體是可以重複的部份!
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Calendar Labs//Calendar 1.0//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:Taiwan Holidays
X-WR-TIMEZONE:Etc/CST
BEGIN:VEVENT
SUMMARY:崑大 111-1 期末考開始
DTSTART:20230110
DTEND:20230116
LOCATION:Taiwan
DESCRIPTION:參考崑山行事曆
SEQUENCE:0
END:VEVENT
END:VCALENDAR
之後重新啟動你的 Magic Mirror,基本上,就可以看到行事曆變成台灣地區的項目,可以是中文,同時也能夠修改你需要的排程! 相當的方便愉快!
- 天氣觀測與預報
預設的天氣模組,可以使用 openweathermap 網站的資料來處理。只是,這個網站目前有多種 API 界面, 我們預計使用免費的 API 界面喔!所以,不要寫錯 API 的資料才行!否則就會出現問題了!一直讀不到... 好吧!那就開始來使用!第一步驟先到 openweathermap 網站進行註冊:
上面的網站點選『API』按鈕,然後往下滑動到『Personal collections』的位置上,就可以看到『Current & Forecast weather』的資料! 此時可以按下訂閱 (subscribe) 的按鈕來處理!如下圖所示:
由於我們僅須要免費的查閱而已,因此新視窗當中,往下滑動到出現『Free』字樣後,如下圖所示,這才開始取得 API 的金鑰! 如下圖所示。圖中的方塊則是顯示 API 的內容應該如何查詢的流程~有興趣自己寫 code 去分析的話, 應該也能看一下!否則,就直接點選『Get API key』即可。
如果從來沒有註冊過這個網站的話,那麼就會出現如下的註冊畫面!請填寫好你的帳號密碼與 email 相關資料, 然後按下『create account』,就可以建立好你的帳號了!相關流程如下所示:
系統會自動將你登入,此時,前往 API 的畫面取得你的 KEY 即可喔!如下所示:
重點是左下角 4 號箭頭的一串資料啦!那就是 API 的 key !接下來,我們要展示的是我們所在處,台南地區的天氣! 你可以前往底下的網站找到相關的城市 ID!你可以用程式名稱,不過,鳥哥比較喜歡使用程式所在的代碼! 各縣市資料,可以查 current.city.list.json.gz 這個檔案內容:
鳥哥找到的台南測站號碼為 1668355 喔!然後開始編輯天氣模組吧!
$ cd ~/MagicMirror $ vim config/config.js module: "weather", position: "top_right", config: { weatherProvider: "openweathermap", apiVersion: "2.5", apiBase: "https://api.openweathermap.org/data/", weatherEndpoiint: "weather", type: "current", locationID: "1668355", // 這是台南 apiKey: "你自己的 API key", } .... module: "weather", position: "top_right", header: "Weather Forecast", config: { weatherProvider: "openweathermap", apiVersion: "2.5", apiBase: "https://api.openweathermap.org/data/", weatherEndpoiint: "forecast", type: "forecast", locationID: "1668355", // 這是台南 apiKey: "你自己的 API key", }
重新啟動 Magic mirror 之後,天氣狀況與預報就自動產生啦!
- 最新新聞消息通知
總有重大新聞的時候,台灣許多新聞電子報都有提供 RSS 訂閱的功能,例如底下:
處理方式就如下所示:
$ cd ~/MagicMirror $ vim config/config.js module: "newsfeed", position: "bottom_bar", config: { feeds: [ { title: "東森-即時新聞", url: "https://feeds.feedburner.com/ettoday/realtime" }, { title: "東森-地方新聞", url: "https://feeds.feedburner.com/ettoday/local" }, { title: "東森-政治新聞", url: "https://feeds.feedburner.com/ettoday/news" }, { title: "Mobile - 01", url: "https://www.mobile01.com/rss/news.xml" }, ], showSourceTitle: true, showPublishDate: true, broadcastNewsFeeds: true, broadcastNewsUpdates: true }
重新啟動之後,就會像底下這樣了!相當有趣喔!
12.3: 讓 magic mirror 開機就啟動
單純使用『npm run start』可以讓 magic mirror 開始運作,只是,運作的 log 與相關訊息都會在原有的終端視窗存在! 你也不能離開該終端視窗~否則就得要按下 [ctrl]+c 來停止這個服務了!該如何讓 magic mirror 程式自己跑呢? 其實,我們可以透過 pm2 這個服務來處理程序的管理,這樣就可以脫離特定終端機的限制了!
- 使用 pm2 管理 Magic Mirror 服務
如果你的程序是單獨存在的,並不是個可以在背景跑的服務時,那麼你可能就無法脫離終端機的束縛。pm2 則可以用來控制這樣的程序! pm2 可以在背景底下產生一隻管理的服務,然後根據使用者個人服務的設定,來予以管理 (啟動/關閉/重新載入等行為)。 這時,你就可以讓 Magic Mirror 跑在背景裡面,而不用持續保持終端機的連線呢!
# 1. (root 身份) 將 pm2 安裝到樹莓派上: $ sudo npm install pm2 -g # 2. (一般帳號) 到你需要啟動的程序的目錄下,使用 pm2 去啟動服務 $ cd ~/MagicMirror/ $ pm2 start --name mm2 "npm run start" [PM2] Spawning PM2 daemon with pm2_home=/home/rasppi/.pm2 [PM2] PM2 Successfully daemonized [PM2] Starting /usr/bin/bash in fork_mode (1 instance) [PM2] Done. ┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬ │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼ │ 0 │ mm2 │ default │ N/A │ fork │ 13509 │ 0s │ └─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴
如上所示,此時你的家目錄底下就會產生 .pm2 的隱藏目錄,並且將你個人需要啟動的服務資料 (pm2 稱為 app.js) 都記錄下來! 例如上面的案例中,目前我們的 MagicMirror (通常簡寫為 mm2) 已經在跑,而且在我們的帳號當中,顯示的識別碼 (id) 是 0 號, 而且我們取個名字稱為 mm2 喔!
- 使用 pm2 觀察剛剛建立的 mm2 軟體
上面的指令可以讓 magic mirror 開始運作!那如何觀察?難道一定要去螢幕前面?事實上,我們可以透過 pm2 的 list 與 monit 來觀察! 例如這樣做:
$ pm2 list ┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬ │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼ │ 0 │ mm2 │ default │ N/A │ fork │ 13509 │ 4m │ └─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴ $ pm2 monit
可以做一些簡單的觀察囉!
- 使用 pm2 管理服務
pm2 還可以進一步管理相關的服務!管理就是 restart/reload/stop 等等!
$ pm2 reload mm2 $ pm2 stop mm2 $ pm2 start mm2
此時的服務是可以被管理的!只是,目前這個 mm2 服務的環境並沒有被儲存!下次重新開機之後, mm2 設定值就消失了! 所以,你應該要將 mm2 這個服務的相關資料儲存下來!即使重新開機之後,你的 pm2 還是會記得你的 mm2 運作腳本唷!
$ pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /home/rasppi/.pm2/dump.pm2
那麼下次重新開機後,如果要重新啟動這個 mm2 的話,就可以透過底下的重生指令來處理:
# 如果重新開機過,可以用底下的指令來重生 mm2 喔!
$ pm2 resurrect
[PM2] Resurrecting
[PM2] Restoring processes located in /home/rasppi/.pm2/dump.pm2
[PM2] Process /usr/bin/bash restored
....
- 使用 pm2 帶入 systemd 的服務
如同前面說的,基本上,開機之後,使用剛剛建立 pm2 的用戶,直接執行『 pm2 resurrect 』指令,就可以透過『 pm2 save 』 所以紀錄的資料來重建相關的服。問題是,我們需要一開機就執行這個腳本時,該如何是好?可以透過 pm2 的 startup 取得管理的方式, 例如樹莓派使用的是 systemd,早期的 Linux 也有使用 systemV 的,那就可以透過這個 startup 來取得相關的資料! 如下所示:
$ pm2 startup [PM2] Init System found: systemd [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u rasppi --hp /home/rasppi $ sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd\ > -u rasppi --hp /home/rasppi
上面 startup 出現什麼,你就執行什麼就對了!該腳本實際上會建立一個名為『/etc/systemd/system/pm2-rasppi.service 的檔案, 並將 pm2 resurrect 寫入到執行腳本當中,同時將該動作 enable 到系統中~這樣開機就會自動執行這隻服務了! 至於管理的方式,還是使用 pm2 來管理即可!當然啦,你也可以使用『 systemctl restart pm2-rasppi 』來管理, 只是,這樣就得要使用 root 的權限來處理!另外,想要完整使用 systemctl 來管理時,可能得要重新開機喔! 基本上,管理還是使用 pm2 比較方便啦!
- 定時開啟/關閉螢幕
某些時刻你可能會想要定時開關螢幕,例如晚上 10 點過後關閉螢幕,早上 8 點就開啟螢幕~這樣可以處理的方式會變成:
$ crontab -e
#0 22 * * * xset -display :0 s on s 1
#0 8 * * * xset -display :0 s off s activate
0 22 * * * vcgencmd display_power 0
0 8 * * * vcgencmd display_power 1
如此即可自動啟動/關閉螢幕!
12.4: 當週實做
將本章的全部動作都完成即可!另外,也可以將各個位置調動一下,設計出你最喜愛的版型即可!
- 參考資料
- Magic mirro 官網:
https://magicmirror.builders/ - 用樹莓派打造一個超薄魔鏡的簡單教程
https://www.gushiciku.cn/pl/gd2a/zh-tw
https://onevcat.com/2021/04/magicmirror/ - 樹莓派Raspberry Pi關閉休眠、螢幕長亮
https://blog.twtnn.com/2021/02/raspberry-pi.html - Make your own Smart Mirror with Magic Mirror and a Raspberry Pi
https://www.marathonus.com/about/blog/make-your-own-smart-mirror-with-magic-mirror-and-a-raspberry-pi/ - 我也來做 Magic Mirror 系列:
https://www.misterngan.com/5705/just-another-magicmirror-2/
- 更改紀錄
- 2022/12/08:第一次搞定 Magic Mirror,真的很有趣!只是卡在預設模組的展示方面,花費不少時間去理解!
- 2023/01/04:因為螢幕保護程式老是無法順利關閉螢幕電源,找到了 vcgencmd 指令來處理,感覺比較好!
...