2021年1月24日 星期日

2021 年第 4 周記事

今天是 1/24, 忽然又來到月底了, 二哥與菁菁本周開始放寒假, 所以鬧鐘可以調晚一個小時起床了, 相對於學期中趕上學, 生活步調突然放慢覺得好舒坦. 

這周因為要還一本母校的樹莓派借書 ("AIOT與OpenCV實戰應用:Python、樹莓派、物聯網與機器視覺"), 所以就認真看了以前從未涉獵的 GPIO 部份, 同時也拿出久已未摸的板子準備進行實作. 其實以前在 Arduino 上面做的實驗在樹莓派做更簡單, 因為它有 Linux 與 Python 的強大支援 (只是類比部分需外加晶片). 樹莓派應用廣泛, 值得深入研究, 開發農業物聯網應用. 

今天早上去鎮里買菜, 回途看到路邊有一台貨車改裝的野台布袋戲, 哇, 好久沒看到了 (做這行的可能都轉行了), 我停下來看了一下, 發現人偶都沒在動啊, 看來只是固定在上面放錄音帶而已. 我探頭看貨車裡面, 哈, 老闆在那邊滑手機! 下午要準備晚餐時發現沒買到雞胸肉, 所以又跑一趟鎮上的全聯, 經過那邊時發現這回人偶有在動了, 我又探頭看車裡面, 哈, 老闆上工了!




今天下午婷婷帶孩子來玩, 所以就沒去爬山了, 一邊跟孩子玩, 抽空又到菜園去將上週買的六株茄子與早上買的 20 株玉米以及 20 株大陸妹種下去, 離過年不到一個月, 這些都要元宵後才會收成了.  

高科大還書 2 本 (樹莓派 & 生成深度學習)

因有人預約, 下面兩本書昨天先還了 :
  1. AIoT與OpenCV實戰應用 : Python、樹莓派、物聯網與機器視覺
  2. 生成深度學習 : 訓練機器繪畫、作曲、寫作與玩遊戲
第一本我覺得寫得很不錯, 是實戰書籍, 我已看完前兩篇, 下次回借專看第三篇 OpenCV. 第二本我只是借來翻翻而已, 程度還不到, 等基本的深度學習學完再來看. 

2021年1月23日 星期六

樹莓派學習筆記 : 首次開機自動連線 WiFi 基地台的方法 (無頭存取)

今天在讀 "AIOT與OpenCV實戰應用:Python、樹莓派、物聯網與機器視覺" 的樹莓派 Raspbian 作業系統安裝部分時有意外發現, 只要在燒錄完映像檔之後在 SD 卡內加上一個 WiFi 連線設定檔指定基地台的連線帳密, 則樹莓派一開機就可以自動連線到 WiFi, 馬上就可以用筆電進行遠端操控 (即無頭存取, headless access). 

我之前以無頭存取 (headless access) 方式操作樹莓派都還需要將機器接上螢幕與鍵鼠組, 設定好 WiFi 帳密, 開啟 SSH 與 VNC 後才能透過筆電遠端操作樹莓派, 螢幕與鍵鼠組還好準備, 比較麻煩的是轉接頭, 特別是 Zero 需要 Mini HDMI 接頭與一個 USB 分享器 (鍵鼠組與 WiFi dongle 用), 真的有點傷腦筋, 參考 :


而這本書中介紹的方法是, 將映像檔燒錄到 Micro SD 卡後, 取出卡再重新插入電腦讀卡機, 這時在檔案總管中會看到兩個分割, 其中一個為 boot, 用記事本編輯一個名稱為 wpa_applicant.conf 的純文字檔儲存到 boot 分割區的根目錄下, 內容為 :

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev 
update_config=1
country=TW

network={
    ssid="SSID"
    psk="密碼"
    }

除了這個之外, 還要在 root 之下建立一個名稱為 ssh 的空白檔案, 然後就可以取出 Micro SD 卡放入樹莓派, 這樣開機後就會自動連線指定的 WiFi 基地台了. 如果用手機上網, 可以在手機的 "設定/連接/行動無線基地台與網路共享/行動無線基地台" 中找到樹莓派連線成功後的 IP, 然後用 PuTTY 就可以進行無頭存取. 

此做法也可參考 :


市圖還書 2 本

本周市圖還書 2 本 :
都有人預約得還. jQuery 近期還沒時間做最後整理, 等忙完 Python 再回借. 

2021年1月21日 星期四

樹莓派學習筆記 : 用 wget install 安裝 MQTT 套件 mosquitto

因為用編譯原始碼方式安裝 mosquitto 套件在編譯階段出現錯誤而失敗, 所以只好用 wget install 安裝已編譯好的套件檔 mosquitto 與 mosquitto-clients, 參考 : 


安裝指令如下 :

wget install mosquitto mosquitto-clients  

下面是將安裝過程丟到一個檔案中 : 

pi@raspberrypi:~ $ sudo apt-get install mosquitto mosquitto-clients > mosquitto.txt    
pi@raspberrypi:~ $ cat mosquitto.txt   
正在讀取套件清單...
正在重建相依關係...
正在讀取狀態資料...
下列的額外套件將被安裝:
  libmosquitto1
建議套件:
  apparmor
下列【新】套件將會被安裝:
  libmosquitto1 mosquitto mosquitto-clients
升級 0 個,新安裝 3 個,移除 0 個,有 335 個未被升級。
需要下載 221 kB 的套件檔。
此操作完成之後,會多佔用 500 kB 的磁碟空間。
是否繼續進行 [Y/n]? [Y/n] 下載:1 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf libmosquitto1 armhf 1.4.10-3+deb9u4 [47.2 kB]
下載:2 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf mosquitto armhf 1.4.10-3+deb9u4 [122 kB]
下載:3 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf mosquitto-clients armhf 1.4.10-3+deb9u4 [52.3 kB]
取得 221 kB 用了 2s (75.0 kB/s)
選取了原先未選的套件 libmosquitto1:armhf。
(讀取資料庫 ... 目前共安裝了 148260 個檔案和目錄。)
Preparing to unpack .../libmosquitto1_1.4.10-3+deb9u4_armhf.deb ...
Unpacking libmosquitto1:armhf (1.4.10-3+deb9u4) ...
選取了原先未選的套件 mosquitto。
Preparing to unpack .../mosquitto_1.4.10-3+deb9u4_armhf.deb ...
Unpacking mosquitto (1.4.10-3+deb9u4) ...
選取了原先未選的套件 mosquitto-clients。
Preparing to unpack .../mosquitto-clients_1.4.10-3+deb9u4_armhf.deb ...
Unpacking mosquitto-clients (1.4.10-3+deb9u4) ...
Processing triggers for libc-bin (2.24-11+deb9u4) ...
設定 mosquitto (1.4.10-3+deb9u4) ...
Processing triggers for systemd (232-25+deb9u11) ...
Processing triggers for man-db (2.7.6.1-2) ...
設定 libmosquitto1:armhf (1.4.10-3+deb9u4) ...
設定 mosquitto-clients (1.4.10-3+deb9u4) ...
Processing triggers for libc-bin (2.24-11+deb9u4) ...

可見已經順利完成安裝, 這樣就可以來測試看看用 MQTT 協定來訂閱與發送訊息了 : 

開啟兩個終端機視窗, 一個用來發布訊息 (publisher); 另一個用來訂閱訊息 (subscriber). 首先在訂閱者終端機以下列指令訂閱主題為 abc 所發布的訊息 :

mosquitto_sub -h 發布者網址 -t 主題

pi@raspberrypi:~ $ mosquitto_sub -h localhost -t abc     

訂閱後此終端機視窗會停住, 事實上是進入等待訊息的迴圈. 接著在發布者終端機以下列指令發布訊息 :

mosquitto_pub -h 發布者網址 -t 主題 -m "訊息"

pi@raspberrypi:~ $ mosquitto_pub -h localhost -t abc -m "hello world"

此指令針對 abc 主題發布了 "hello world" 訊息, 這時處於等待訊息迴圈的訂閱者終端機視窗就會顯示所接收到的訊息 :

hello world

發布者連續發布三個訊息 : 

pi@raspberrypi:~ $ mosquitto_pub -h localhost -t abc -m "hello world"  
pi@raspberrypi:~ $ mosquitto_pub -h localhost -t abc -m "hello tony"  
pi@raspberrypi:~ $ mosquitto_pub -h localhost -t abc -m "hello amy"  




訂閱者會連續收到三個訊息 :

hello world
hello tony
hello amy




注意, 訂閱者終端機將一直處於等待接收迴圈直到按下 CTRL+C 才會終止迴圈, 我覺得此迴圈似乎還蠻吃資源的, 訂閱指令一下達後, 桌面操作即變得有點卡卡, CPU 使用從 3% 上升到 20%. 

樹莓派學習筆記 : 編譯 MQTT 套件 mosquitto 原始碼問題

今天繼續讀朱克剛寫的 "AIOT與OpenCV實戰應用:Python、樹莓派、物聯網與機器視覺" 的 MQTT 部分, 書中使用的是 mosquitto 套件, 可用 pip 安裝或從 GitHub 下載原始碼自行編譯, 作者建議自行編譯, 因為可以開啟 websockets 功能以便透過網頁介面進行 MQTT 操作. 

我照作者建議下載原始碼自行編譯, 但編譯過程發生錯誤, 試圖爬文解決未果, 暫且將過程記錄如下, 等待找到解決方案再來重新編譯, mosquitto 套件原始碼下載網址如下 : 


開啟樹莓派的 Chromium 瀏覽器連線上面的 GitHub 網址下載原始碼 zip 壓縮檔 :




下載的壓縮檔 mosquitto-master.zip 預設放在使用者目錄下的 Downloads 資料夾下面, 可使用 unzip 程式解壓縮, 它會建立 mosquitto-master 子目錄來存放這些原始碼 :

pi@raspberrypi:~ $ cd Downloads   
pi@raspberrypi:~/Downloads $ unzip mosquitto-master.zip    
pi@raspberrypi:~/Downloads $ cd mosquitto-master    


1. 編輯 config.mk 檔開啟 websockets 功能 : 

用 nano 編輯 config.mk 檔, 將其中的 WITH_WEBSOCKETS 從原先的 no 改成 yes : 

pi@raspberrypi:~/Downloads/mosquitto-master $ nano config.mk    




這就是自行編譯的好處 : 能在編譯前進行細部功能設定. 


2. 更新套件清單 :

此步驟是必要的, 否則後續下載安裝五套件時可能會因為找不到套件而安裝失敗 : 

sudo apt-get update

pi@raspberrypi:~/Downloads/mosquitto-master $ sudo apt-get update   
下載:1 http://archive.raspberrypi.org/debian stretch InRelease [25.3 kB]  
下載:2 http://archive.raspberrypi.org/debian stretch/main armhf Packages [192 kB]
下載:3 http://raspbian.raspberrypi.org/raspbian stretch InRelease [15.0 kB]
下載:4 http://raspbian.raspberrypi.org/raspbian stretch/main armhf Packages [11.7 MB]
下載:5 http://archive.raspberrypi.org/debian stretch/ui armhf Packages [44.6 kB]
下載:6 http://raspbian.raspberrypi.org/raspbian stretch/non-free armhf Packages [98.9 kB]
取得 12.0 MB 用了 20min 48s (9,640 B/s)                                        
正在讀取套件清單... 完成


3. 安裝五套件 : 

此五套件是支援 MQTT 協定的函式庫 : 

sudo apt-get install libc-ares-dev libwebsockets-dev libssl-dev xsltproc docbook-xsl 

pi@raspberrypi:~/Downloads/mosquitto-master $ sudo apt-get install libc-ares-dev libwebsockets-dev libssl-dev xsltproc docbook-xsl    
正在讀取套件清單... 完成
正在重建相依關係          
正在讀取狀態資料... 完成
下列的額外套件將被安裝:
  docbook-xml libev-dev libev4 libssl-doc libssl1.1 libuv1-dev libwebsockets8
  sgml-data
建議套件:
  docbook docbook-dsssl docbook-defguide dbtoepub docbook-xsl-doc-html
  | docbook-xsl-doc-pdf | docbook-xsl-doc-text | docbook-xsl-doc
  docbook-xsl-saxon fop libsaxon-java libxalan2-java libxslthl-java xalan
  perlsgml w3-recs opensp libxml2-utils
下列【新】套件將會被安裝:
  docbook-xml docbook-xsl libc-ares-dev libev-dev libev4 libssl-dev libssl-doc
  libuv1-dev libwebsockets-dev libwebsockets8 sgml-data xsltproc
下列套件將會被升級:
  libssl1.1
升級 1 個,新安裝 12 個,移除 0 個,有 335 個未被升級。
需要下載 4,105 kB/6,264 kB 的套件檔。
此操作完成之後,會多佔用 30.5 MB 的磁碟空間。
是否繼續進行 [Y/n]? [Y/n] Y
下載:1 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf libssl1.1 armhf 1.1.0l-1~deb9u2 [1,119 kB]
下載:2 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf libssl-dev armhf 1.1.0l-1~deb9u2 [1,388 kB]
下載:3 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf libssl-doc all 1.1.0l-1~deb9u2 [1,478 kB]
下載:4 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf xsltproc armhf 1.1.29-2.1+deb9u2 [120 kB]
取得 4,105 kB 用了 14s (284 kB/s)                                              
讀取改變紀錄(changelogs)... 完成
正在預先設定套件 ...
(讀取資料庫 ... 目前共安裝了 143563 個檔案和目錄。)
Preparing to unpack .../00-libssl1.1_1.1.0l-1~deb9u2_armhf.deb ...
Unpacking libssl1.1:armhf (1.1.0l-1~deb9u2) over (1.1.0j-1~deb9u1) ...
選取了原先未選的套件 sgml-data。
Preparing to unpack .../01-sgml-data_2.0.10_all.deb ...
Unpacking sgml-data (2.0.10) ...
選取了原先未選的套件 docbook-xml。
Preparing to unpack .../02-docbook-xml_4.5-8_all.deb ...
Unpacking docbook-xml (4.5-8) ...
選取了原先未選的套件 docbook-xsl。
Preparing to unpack .../03-docbook-xsl_1.79.1+dfsg-2_all.deb ...
Unpacking docbook-xsl (1.79.1+dfsg-2) ...
選取了原先未選的套件 libc-ares-dev:armhf。
Preparing to unpack .../04-libc-ares-dev_1.14.0-1~bpo9+1_armhf.deb ...
Unpacking libc-ares-dev:armhf (1.14.0-1~bpo9+1) ...
選取了原先未選的套件 libev4。
Preparing to unpack .../05-libev4_1%3a4.22-1_armhf.deb ...
Unpacking libev4 (1:4.22-1) ...
選取了原先未選的套件 libssl-dev:armhf。
Preparing to unpack .../06-libssl-dev_1.1.0l-1~deb9u2_armhf.deb ...
Unpacking libssl-dev:armhf (1.1.0l-1~deb9u2) ...
選取了原先未選的套件 libssl-doc。
Preparing to unpack .../07-libssl-doc_1.1.0l-1~deb9u2_all.deb ...
Unpacking libssl-doc (1.1.0l-1~deb9u2) ...
選取了原先未選的套件 libuv1-dev:armhf。
Preparing to unpack .../08-libuv1-dev_1.18.0-3~bpo9+1_armhf.deb ...
Unpacking libuv1-dev:armhf (1.18.0-3~bpo9+1) ...
選取了原先未選的套件 libwebsockets8:armhf。
Preparing to unpack .../09-libwebsockets8_2.0.3-2+b1~rpt1_armhf.deb ...
Unpacking libwebsockets8:armhf (2.0.3-2+b1~rpt1) ...
選取了原先未選的套件 libev-dev。
Preparing to unpack .../10-libev-dev_1%3a4.22-1_armhf.deb ...
Unpacking libev-dev (1:4.22-1) ...
選取了原先未選的套件 libwebsockets-dev:armhf。
Preparing to unpack .../11-libwebsockets-dev_2.0.3-2+b1~rpt1_armhf.deb ...
Unpacking libwebsockets-dev:armhf (2.0.3-2+b1~rpt1) ...
選取了原先未選的套件 xsltproc。
Preparing to unpack .../12-xsltproc_1.1.29-2.1+deb9u2_armhf.deb ...
Unpacking xsltproc (1.1.29-2.1+deb9u2) ...
設定 libev4 (1:4.22-1) ...
設定 docbook-xsl (1.79.1+dfsg-2) ...
設定 xsltproc (1.1.29-2.1+deb9u2) ...
Processing triggers for sgml-base (1.29) ...
Processing triggers for libc-bin (2.24-11+deb9u4) ...
設定 libssl1.1:armhf (1.1.0l-1~deb9u2) ...
設定 sgml-data (2.0.10) ...
Processing triggers for man-db (2.7.6.1-2) ...
設定 libc-ares-dev:armhf (1.14.0-1~bpo9+1) ...
設定 libssl-doc (1.1.0l-1~deb9u2) ...
設定 libuv1-dev:armhf (1.18.0-3~bpo9+1) ...
設定 libev-dev (1:4.22-1) ...
設定 libwebsockets8:armhf (2.0.3-2+b1~rpt1) ...
設定 libssl-dev:armhf (1.1.0l-1~deb9u2) ...
設定 libwebsockets-dev:armhf (2.0.3-2+b1~rpt1) ...
Processing triggers for sgml-base (1.29) ...
設定 docbook-xml (4.5-8) ...
Processing triggers for libc-bin (2.24-11+deb9u4) ...
Processing triggers for sgml-base (1.29) ...


4. 編譯原始碼與安裝套件 :

用 make 指令編譯原始碼 :

make -j4 

pi@raspberrypi:~/Downloads/mosquitto-master $ make -j4    
set -e; for d in lib apps client plugins src; do make -C ${d}; done
set -e; for d in man; do make -C ${d}; done
make[1]: Entering directory '/home/pi/Downloads/mosquitto-master/lib'
make[1]: Entering directory '/home/pi/Downloads/mosquitto-master/man'
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c mosquitto.c -o mosquitto.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c actions.c -o actions.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c callbacks.c -o callbacks.o
xsltproc --nonet libmosquitto.3.xml
xsltproc --nonet mosquitto-tls.7.xml
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c connect.c -o connect.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_auth.c -o handle_auth.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_connack.c -o handle_connack.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_disconnect.c -o handle_disconnect.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_ping.c -o handle_ping.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_pubackcomp.c -o handle_pubackcomp.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_publish.c -o handle_publish.o
xsltproc --nonet mosquitto.8.xml
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_pubrec.c -o handle_pubrec.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_pubrel.c -o handle_pubrel.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_suback.c -o handle_suback.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c handle_unsuback.c -o handle_unsuback.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c helpers.c -o helpers.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c logging_mosq.c -o logging_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c loop.c -o loop.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c memory_mosq.c -o memory_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c messages_mosq.c -o messages_mosq.o
xsltproc --nonet mosquitto.conf.5.xml
xsltproc --nonet mosquitto_ctrl.1.xml
xsltproc --nonet mosquitto_ctrl_dynsec.1.xml
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c misc_mosq.c -o misc_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c net_mosq_ocsp.c -o net_mosq_ocsp.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c net_mosq.c -o net_mosq.o
xsltproc --nonet mosquitto_passwd.1.xml
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c options.c -o options.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c packet_datatypes.c -o packet_datatypes.o
xsltproc --nonet mosquitto_pub.1.xml
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c packet_mosq.c -o packet_mosq.o
xsltproc --nonet mosquitto_rr.1.xml
xsltproc --nonet mosquitto_sub.1.xml
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c property_mosq.c -o property_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c read_handle.c -o read_handle.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c send_connect.c -o send_connect.o
xsltproc --nonet mqtt.7.xml
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c send_disconnect.c -o send_disconnect.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c send_mosq.c -o send_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c send_publish.c -o send_publish.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c send_subscribe.c -o send_subscribe.o
make[1]: Leaving directory '/home/pi/Downloads/mosquitto-master/man'
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c send_unsubscribe.c -o send_unsubscribe.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c socks_mosq.c -o socks_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c srv_mosq.c -o srv_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c strings_mosq.c -o strings_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c thread_mosq.c -o thread_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c time_mosq.c -o time_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c tls_mosq.c -o tls_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c utf8_mosq.c -o utf8_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c util_mosq.c -o util_mosq.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c util_topic.c -o util_topic.o
cc  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps -Wall -ggdb -O2 -Wconversion -fPIC -c will_mosq.c -o will_mosq.o
cc -shared  -Wl,--version-script=linker.version -Wl,-soname,libmosquitto.so.1 mosquitto.o actions.o callbacks.o connect.o handle_auth.o handle_connack.o handle_disconnect.o handle_ping.o handle_pubackcomp.o handle_publish.o handle_pubrec.o handle_pubrel.o handle_suback.o handle_unsuback.o helpers.o logging_mosq.o loop.o memory_mosq.o messages_mosq.o misc_mosq.o net_mosq_ocsp.o net_mosq.o options.o packet_datatypes.o packet_mosq.o property_mosq.o read_handle.o send_connect.o send_disconnect.o send_mosq.o send_publish.o send_subscribe.o send_unsubscribe.o socks_mosq.o srv_mosq.o strings_mosq.o thread_mosq.o time_mosq.o tls_mosq.o utf8_mosq.o util_mosq.o util_topic.o will_mosq.o -o libmosquitto.so.1  -lrt -lssl -lcrypto -lpthread
make -C cpp
make[2]: Entering directory '/home/pi/Downloads/mosquitto-master/lib/cpp'
g++  -I. -I.. -I../include -I../../include -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SOCKS -DWITH_UNIX_SOCKETS -I../deps  -fPIC -c mosquittopp.cpp -o mosquittopp.o
g++ -shared  -Wl,-soname,libmosquittopp.so.1 mosquittopp.o -o libmosquittopp.so.1 ../libmosquitto.so.1 
make[2]: Leaving directory '/home/pi/Downloads/mosquitto-master/lib/cpp'
make[1]: Leaving directory '/home/pi/Downloads/mosquitto-master/lib'
make[1]: Entering directory '/home/pi/Downloads/mosquitto-master/apps'
set -e; for d in db_dump mosquitto_ctrl mosquitto_passwd; do make -C ${d}; done
make[2]: Entering directory '/home/pi/Downloads/mosquitto-master/apps/db_dump'
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c db_dump.c -o db_dump.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c print.c -o print.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../lib/memory_mosq.c -o memory_mosq.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../src/memory_public.c -o memory_public.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../lib/packet_datatypes.c -o packet_datatypes.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../lib/packet_mosq.c -o packet_mosq.o
db_dump.c: In function ‘dump__cfg_chunk_process’:
db_dump.c:133:98: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 4 has type ‘unsigned int’ [-Wformat=]
 or: Incompatible database configuration (dbid size is %d bytes, expected %ld)",
                                                                            ^
db_dump.c: In function ‘dump__client_msg_chunk_process’:
db_dump.c:210:21: warning: conversion to ‘long unsigned int’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
    cc->message_size += length;
                     ^~
db_dump.c:210:24: warning: conversion to ‘long int’ from ‘long unsigned int’ may change the sign of the result [-Wsign-conversion]
    cc->message_size += length;
                        ^~~~~~
db_dump.c:214:22: warning: conversion to ‘long unsigned int’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
     cc->message_size += msc->length;
                      ^~
db_dump.c:214:25: warning: conversion to ‘long int’ from ‘long unsigned int’ may change the sign of the result [-Wsign-conversion]
     cc->message_size += msc->length;
                         ^~~
db_dump.c: In function ‘main’:
db_dump.c:466:19: warning: conversion to ‘long int’ from ‘uint32_t {aka unsigned int}’ may change the sign of the result [-Wsign-conversion]
      if(fseek(fd, length, SEEK_CUR) < 0){
                   ^~~~~~
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../src/persist_read.c -o persist_read.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../src/persist_read_v234.c -o persist_read_v234.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../src/persist_read_v5.c -o persist_read_v5.o
../../src/persist_read.c: In function ‘persist__client_chunk_restore’:
../../src/persist_read.c:199:34: warning: conversion to ‘time_t {aka long int}’ from ‘int64_t {aka long long int}’ may alter its value [-Wconversion]
   context->session_expiry_time = chunk.F.session_expiry_time;
                                  ^~~~~
../../src/persist_read.c: In function ‘persist__restore’:
../../src/persist_read.c:527:18: warning: conversion to ‘long int’ from ‘uint32_t {aka unsigned int}’ may change the sign of the result [-Wsign-conversion]
      fseek(fptr, length, SEEK_CUR);
                  ^~~~~~
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../lib/property_mosq.c -o property_mosq.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../lib/send_disconnect.c -o send_disconnect.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c stubs.c -o stubs.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../lib/time_mosq.c -o time_mosq.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../src/topic_tok.c -o topic_tok.o
cc -Wall -ggdb -O2 -Wconversion -I../../include -I../../ -I../../lib -I../../src -I../../deps -DWITH_BROKER -DWITH_PERSISTENCE -c ../../lib/utf8_mosq.c -o utf8_mosq.o
cc db_dump.o print.o memory_mosq.o memory_public.o packet_datatypes.o packet_mosq.o persist_read.o persist_read_v234.o persist_read_v5.o property_mosq.o send_disconnect.o stubs.o time_mosq.o topic_tok.o utf8_mosq.o -o mosquitto_db_dump  
make[2]: Leaving directory '/home/pi/Downloads/mosquitto-master/apps/db_dump'
make[2]: Entering directory '/home/pi/Downloads/mosquitto-master/apps/mosquitto_ctrl'
cc -I../mosquitto_passwd  -I. -I../../ -I../../include -I../../src -I../../lib -DWITH_TLS -Wall -ggdb -O2 -Wconversion -DVERSION=\""2.0.5\"" -c mosquitto_ctrl.c -o mosquitto_ctrl.o
cc -I../mosquitto_passwd  -I. -I../../ -I../../include -I../../src -I../../lib -DWITH_TLS -Wall -ggdb -O2 -Wconversion -DVERSION=\""2.0.5\"" -c client.c -o client.o
cc -I../mosquitto_passwd  -I. -I../../ -I../../include -I../../src -I../../lib -DWITH_TLS -Wall -ggdb -O2 -Wconversion -DVERSION=\""2.0.5\"" -c dynsec.c -o dynsec.o
cc -I../mosquitto_passwd  -I. -I../../ -I../../include -I../../src -I../../lib -DWITH_TLS -Wall -ggdb -O2 -Wconversion -DVERSION=\""2.0.5\"" -c dynsec_client.c -o dynsec_client.o
dynsec_client.c:18:25: fatal error: cjson/cJSON.h: 沒有此一檔案或目錄
 #include <cjson/cJSON.h>
                         ^
compilation terminated.
Makefile:57: recipe for target 'dynsec_client.o' failed
make[2]: *** [dynsec_client.o] Error 1
make[2]: *** Waiting for unfinished jobs....
dynsec.c:20:25: fatal error: cjson/cJSON.h: 沒有此一檔案或目錄
 #include <cjson/cJSON.h>
                         ^
compilation terminated.
Makefile:54: recipe for target 'dynsec.o' failed
make[2]: *** [dynsec.o] Error 1
In file included from client.c:31:0:
mosquitto_ctrl.h:21:25: fatal error: cjson/cJSON.h: 沒有此一檔案或目錄
 #include <cjson/cJSON.h>
                         ^
compilation terminated.
Makefile:51: recipe for target 'client.o' failed
make[2]: *** [client.o] Error 1
In file included from mosquitto_ctrl.c:29:0:
mosquitto_ctrl.h:21:25: fatal error: cjson/cJSON.h: 沒有此一檔案或目錄
 #include <cjson/cJSON.h>
                         ^
compilation terminated.
Makefile:48: recipe for target 'mosquitto_ctrl.o' failed
make[2]: *** [mosquitto_ctrl.o] Error 1
make[2]: Leaving directory '/home/pi/Downloads/mosquitto-master/apps/mosquitto_ctrl'
Makefile:9: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/home/pi/Downloads/mosquitto-master/apps'
Makefile:66: recipe for target 'mosquitto' failed
make: *** [mosquitto] Error 2
pi@raspberrypi:~/Downloads/mosquitto-master $ 

編譯中出現 "Incompatible database configuration" 與 "fatal error: cjson/cJSON.h: 沒有此一檔案或目錄" 等錯誤訊息, 有空再查原因. 

如果 make -j4 編譯沒有錯誤, 後續還有兩個安裝指令 :

$ sudo make install  (安裝)
$ sudo ldconfig   


5. 建立 mosquitto 目錄 :

$ sudo mkdir /var/lib/mosquitto   


6. 編輯 mosquitto 設定檔 :

$ sudo nano /etc/mosquitto/mosquitto.conf

輸入如下內容 :

port 1883
listener 9001
protocol websockets
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/


7. 建立執行 mosquitto 的帳號 : 

一直按 Enter 即可, 密碼可任填 :

$ sudo adduser --shell /usr/sbin/nologin --no-create-home mosquitto 


8. 編輯服務檔 : 

$ sudo nano /etc/systemd/system/mosquitto.service 

輸入內容如下 : 

[Unit]
Description=Mosquitto MQTT Broker Deamon
ConditionPathExists=/etc/mosquitto/mosquitto.conf
After=network.target

[Service]
Type=forking
RemainAfterExit=no
StartLimitInterval=0
PIDFile=/var/run/mosquitto.pid
ExecStart=/bin/sh/ -c "/usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf -d"
ExecReload=/bin/kill -HUB $MAINPID
Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target

樹莓派五個重要的系統設定檔

我今天在讀朱克剛寫的 "AIOT與OpenCV實戰應用:Python、樹莓派、物聯網與機器視覺" 時, 在第二章末尾看到樹莓派重要的系統設定檔列表, 我覺得很有參考價值 :


Source : 博客來


參考 :


我實際檢視兩台 Pi 3B 的檔案內容紀錄如下 (作者使用 vi 編輯器, 我改為較好用的 nano) :


1. WiFi 連線設定檔 : 

$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

檢視如下 : 

pi@raspberrypi:~ $ cat /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=TW

network={
ssid="EDIMAX-tony"
psk="123456789abc"
key_mgmt=WPA-PSK
}


2. 開機自動執行的程式 : 

$ sudo nano /etc/rc.local   

pi@raspberrypi:~ $ cat /etc/rc.local
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

exit 0


3. 鍵盤設定檔 : 

$ sudo nano /etc/default/keyboard 

重點是 XKBLAYOUT 要設為 us 美式鍵盤 : 

pi@raspberrypi:~ $ cat /etc/default/keyboard
XKBMODEL=pc105
XKBLAYOUT=us
XKBVARIANT=
XKBOPTIONS=
BACKSPACE=guess


4. 系統排程設定檔 (cron table) : 

$ sudo nano /etc/crontab 

目前鄉下家樹莓派設定 :

pi@raspberrypi:~ $ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user command
17 * * * * root    cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )


5. 系統紀錄檔 : 

$ cd /var/log   
$ ls -al

SD 卡記憶體不足時, 可刪除此目錄底下較舊的紀錄檔. 

pi@raspberrypi:~ $ ls -al /var/log
總計 169012
drwxr-xr-x  9 root  root     4096  1月 21 06:25 .
drwxr-xr-x 12 root  root     4096  4月  5  2019 ..
-rw-r--r--  1 root  root        0 12月 19  2019 alternatives.log
-rw-r--r--  1 root  root     1677 12月 18  2019 alternatives.log.1
-rw-r--r--  1 root  root      273 10月 16  2019 alternatives.log.2.gz
-rw-r--r--  1 root  root      258  4月  9  2019 alternatives.log.3.gz
drwxr-x---  2 root  adm      4096  1月 21 06:25 apache2
drwxr-xr-x  2 root  root     4096 12月 19  2019 apt
-rw-r-----  1 root  adm  10340754  1月 21 06:55 auth.log
-rw-r-----  1 root  adm  26758041  1月 17 06:25 auth.log.1
-rw-r-----  1 root  adm   2148156  1月 11 06:25 auth.log.2.gz
-rw-r-----  1 root  adm   1042196  1月  3 06:25 auth.log.3.gz
-rw-r-----  1 root  adm   1134427 12月 28 06:25 auth.log.4.gz
-rw-r--r--  1 root  root     2766 12月 23 11:53 boot.log
-rw-r--r--  1 root  root        0 11月 13  2018 bootstrap.log
-rw-rw----  1 root  utmp 77451648  1月 21 06:55 btmp
-rw-------  1 root  utmp 49082880  1月  1 06:23 btmp.1
-rw-r-----  1 root  adm     36206  1月 21 06:39 daemon.log
-rw-r-----  1 root  adm     54446  1月 17 06:25 daemon.log.1
-rw-r-----  1 root  adm      5663  1月 11 06:25 daemon.log.2.gz
-rw-r-----  1 root  adm      3774  1月  3 06:25 daemon.log.3.gz
-rw-r-----  1 root  adm      9121 12月 28 06:25 daemon.log.4.gz
drwxr-xr-x  2 root  root     4096  1月  1  2020 dbconfig-common
-rw-r-----  1 root  adm         0 12月 24 06:25 debug
-rw-r-----  1 root  adm      1247 12月 23 11:53 debug.1
-rw-r-----  1 root  adm       434 11月  2 09:50 debug.2.gz
-rw-r-----  1 root  adm       435  8月 16 14:00 debug.3.gz
-rw-r-----  1 root  adm       435  8月  2 14:00 debug.4.gz
-rw-r--r--  1 root  root        0 12月 19  2019 dpkg.log
-rw-r--r--  1 root  root    57781 12月 19  2019 dpkg.log.1
-rw-r--r--  1 root  root     2202 10月 16  2019 dpkg.log.2.gz
-rw-r--r--  1 root  root      160  7月 13  2019 dpkg.log.3.gz
-rw-r--r--  1 root  root     3514  4月  9  2019 dpkg.log.4.gz
-rw-r--r--  1 root  root     2688 12月 18  2019 faillog
-rw-r--r--  1 root  root        0 11月 13  2018 fontconfig.log
-rw-r-----  1 root  adm    789810  1月 21 06:54 kern.log
-rw-r-----  1 root  adm   1185111  1月 17 06:24 kern.log.1
-rw-r-----  1 root  adm    183410  1月 11 06:22 kern.log.2.gz
-rw-r-----  1 root  adm    132016  1月  3 06:25 kern.log.3.gz
-rw-r-----  1 root  adm    190613 12月 28 06:23 kern.log.4.gz
-rw-rw-r--  1 root  utmp   292292 12月 26 22:12 lastlog
drwx--x--x  2 root  root     4096 12月 23 11:53 lightdm
-rw-r-----  1 root  adm    517547  1月 21 06:54 messages
-rw-r-----  1 root  adm    789048  1月 17 06:25 messages.1
-rw-r-----  1 root  adm    129457  1月 11 06:25 messages.2.gz
-rw-r-----  1 root  adm     92798  1月  3 06:25 messages.3.gz
-rw-r-----  1 root  adm    137151 12月 28 06:25 messages.4.gz
drwxr-s---  2 mysql adm      4096  1月 21 06:25 mysql
drwxr-xr-x  2 root  adm      4096 12月 19  2019 nginx
drwxr-x---  2 root  adm      4096  8月 14  2018 samba
-rw-r-----  1 root  adm      5046  1月 21 06:54 syslog
-rw-r-----  1 root  adm    231289  1月 21 06:25 syslog.1
-rw-r-----  1 root  adm     27782  1月 20 06:25 syslog.2.gz
-rw-r-----  1 root  adm     27603  1月 19 06:25 syslog.3.gz
-rw-r-----  1 root  adm     27370  1月 18 06:25 syslog.4.gz
-rw-r-----  1 root  adm     28143  1月 17 06:25 syslog.5.gz
-rw-r-----  1 root  adm     28673  1月 16 06:25 syslog.6.gz
-rw-r-----  1 root  adm     29553  1月 15 06:25 syslog.7.gz
-rw-r-----  1 root  adm     17941  1月 21 06:36 user.log
-rw-r-----  1 root  adm     39414  1月 17 00:54 user.log.1
-rw-r-----  1 root  adm      4011  1月 11 06:14 user.log.2.gz
-rw-r-----  1 root  adm      2489  1月  2 23:10 user.log.3.gz
-rw-r-----  1 root  adm      4751 12月 28 03:36 user.log.4.gz
-rw-rw-r--  1 root  utmp        0  1月  1 06:25 wtmp
-rw-rw-r--  1 root  utmp     3072 12月 27 04:25 wtmp.1
-rw-r--r--  1 root  root    13369 12月 23 11:53 Xorg.0.log
-rw-r--r--  1 root  root    13369 11月  2 09:50 Xorg.0.log.old

找檔案最舊最大的先刪, 但現在 SD 卡已較便宜, 樹莓派最大支援 64GB, 買個 32/64 GB 來用比較沒有 SD 撐爆問題. 


2021年1月20日 星期三

查詢汽機車強制險效期 (下載電子式保險證)

最近機車強制險到期要續保, 名下四台機車 (高雄兩台, 鄉下兩台) 到期日都不一樣, 想說是否政府有設網站讓車主查詢強制險到期日呢? 答案是有的, 網址如下 : 


輸入身分證與車牌號碼就可查詢了 :



 


按查詢結果第二項下載電子式保險證 PDF 檔, 裡面就有到期日了 (開啟 PDF 之密碼為身分證號碼, 英文要大寫).  

關於自然語言處理之 BERT 技術

今天在找 NLP 資料時看到下面這篇文章 :


第一次看到 BERT 以為是通訊原理中的 Bit Error Rate Test 的意思, 但搭上 NLP 顯然不是這意思, 可見 acronym 的岐義現象有多嚴重. BERT (Bidirectional Encoder Representations from Transformers) 恰巧就是解決 NLP 歧義的一個解決方案. 

BERT 是 Google 在 2018 年所提出的一種 NLP 預訓練技術, 屬於雙向深度非監督的詞向量表示法, 會根據上下文對相同的詞彙生成不同之詞向量 (傳統的 word2vec 則與上下文無關), 因此能有效處理歧義問題, 此項技術已於 2019 年底開始被應用在 Google 搜尋引擎中, 參考 : 


Apress 出版的新書 "Hands-on Question Answering Systems with BERT(2021)" 則將 BERT 用在 Q&A 系統中, 值得參考 : 


Source : 天瓏


Apress 出版的另外一本書 "Practical Natural Language Processing with Python (2020)" 的最後一章也介紹了 BERT 技術 : 


Source : 天瓏


不過 BERT 技術需要花費較大的運算力來訓練模型, 如果研究機構能將訓練好的模型開放將可節省許多訓練成本, 參考 :

# 一文,告訴你NLP中的Transformers究竟是如何運作的
# 【精度】自然語言處理基礎之attention
# 百聞不如一碼!手把手教你用Python搭一個Transformer!

NLP 的發展速度飛快, 不加緊跟上不行.

使用 serveo.net 穿透內網存取網頁伺服器 (暫停服務)

前幾天根據趙英傑 "超圖解 Python 程式設計入門" 這本書第十章的介紹, 順利地利用 ngrok 穿透社區網路存取架設於內網的樹莓派本機網站 (即 localhost), 經過幾天的觀察, ngrok 確實都能持續轉發外網的 HTTP/HTTPS 網頁存取, 即使是免費用戶其轉發服務也都很穩定, 參考 :


位於社區網路內或非固定 IP ADSL 網路內的本機網站從 Internet 外網無法存取, 用 ngrok 就可以辦到, 唯一不便之處是每次重新執行 ngrok 後對映至 localhost 的網址都會變. 這就有點麻煩了, 因為遠端使用者不知道網址變了, 會以為網站掛了. 

其實趙英傑書中還介紹了另一個穿透內網瀏覽本機網站的方法, 即透過 serveo.net 的轉發服務, 特點是只要下一個指令就可以, 不用下載任何程式, 只要在樹莓派終端機使用下面的指令就會回應一個網址, 可以從外網瀏覽本機網站 :

ssh -R 80:localhost:80 serveo.net     

其中 -R 表示遠端 (Remote), 第一個 80 為遠端埠號 (不要改), localhost 代表本機 (也可以用 127.0.0.1 或樹莓派從基地台獲得之 IP, 例如 192.168.43.122), 第二個 80 為本機網站的埠號 (依網站伺服器設定可改). 但我實際測試卻得到 "Connection refused" 的回應 : 

pi@raspberrypi:~ $ ssh -R 80:localhost:80 serveo.net    
ssh: connect to host serveo.net port 22: Connection refused




直接連線 serveo.net 無回應, 我找到一個可以測試伺服器是否當機的網站 : 


輸入 serveo.net 測試伺服器狀況, 結果顯示此網站已掛點 :





此解決方案暫時無解, 不知何時才會恢復.