2016 京阪雙祭、三地動畫巡禮 - 上篇 (祇園祭,天神祭,宇治)

旅遊日期:2016 年 7 月 21 日出發,7 月 28 日回國。

一人自由行。

因為機票票價問題,我不是訂同一地點進出的來回機票,而是大阪進,東京出,且不同航空公司。 去程是搭酷航高雄-大阪関西。回程是搭台灣虎航東京成田-高雄。 也因此,我最後多玩了一天,順便實現了「少女與戰車」和「高校艦隊」兩部動畫的巡禮。

參觀活動與景點:

  1. 京都祇園祭後祭
  2. 大阪天神祭
  3. 宇治「京阪電車x響け! ユーフォニアム2016」動畫巡禮。
  4. 横須賀「High School Fleet 高校艦隊」動畫巡禮。
  5. 大洗「Girls und Panzer 少女與戰車」動畫巡禮。

住宿地點:

  1. 大阪新今宮みかど商務酒店。7/21 ~ 7/24。
  2. 大阪到横浜夜行巴士。晚上10點半出發,早上6點抵達,車上過夜。7/25。
  3. 水戸東横INN。7/26。
  4. 成田空港。睡機場。7/27。

本篇是此次旅行第一到五天遊記。內容是關西的大阪、京都參觀祇園祭、天神祭,以及京阪電車的響け! 動畫巡禮。

第六天、第七天遊記請看2016 京阪雙祭、三地動畫巡禮 - 下篇。內容是從關西移動到關東,在横須賀與大洗兩地動畫巡禮。

2020-03-25 更新: 我朋友說怎麼沒有煙火照呢? 我這才想起來,沒有煙火照,但是有錄影。所以增加祇園祭和天神祭的三段影片。

2018 日本山陽地方七日遊 (嚴島神社,山口錦帶橋,吳市海事歷史科學館,岡山城,倉敷美觀,姫路城)

旅遊日期:2018 年 9 月 27 日出發,10 月 3 日回國。

參觀景點:日本山陽地方。

日本山陽地方係指今日本兵庫縣西部、岡山縣、廣島縣、山口縣南部一帶。或是說日本本州西部(大阪以西)臨瀨戶內海的沿海帶狀區域。我們這次自由行搭台灣虎航從台北直飛岡山,足跡西至山口錦帶橋、岩國城,東至兵庫姫路城,全部落在山陽地方。

住宿地點:東横INN広島駅前大橋南、東横INN岡山駅東口。

與朋友自由行。

2018 日本九州北部五日遊 (豪斯登堡,太宰府天満宮,別府地獄溫泉巡禮,櫛田神社,博多運河城)

旅遊日期:2018 年 12 月 27 日出發,12 月 31 日回國。

參觀景點:豪斯登堡太宰府天満宮別府地獄溫泉巡禮櫛田神社

購物點:福岡マリノアシティ outlet博多運河城

住宿地點:東横INN博多西中洲。

家族旅行,自由行。

  1. 向旅行社訂購長榮航空的「高雄—福岡」往返機票。
  2. 向旅行社訂購 SUNQ PASS 北部九州三日乘車票。
  3. 向旅行社訂購豪斯登堡一日 PASS。
  4. 網路預約高速巴士:豪斯登堡來回。別府來回。

2020 越南中部世界遺產之旅

旅遊日期:2020 年 1 月 19 日出發,1 月 24 日回國。

此次旅遊是跟團行程,參加「品冠旅遊」的「捷星宇~中越峴港、順化皇城、會安古鎮、三大遺產六日」行程。

我選擇中越旅遊之著重點在於:

  1. 三處世界文化遺產:會安古鎮,順化皇城,美山聖地。
  2. 異國文化交匯:占婆王朝遺址的美山,貿易移民聚集的會安,中國帝制影響的京城順化,法國殖民時期避暑勝地的巴拿山。
  3. 法國風山城:巴拿山主題樂園。包含打卡熱點佛手金橋。
  4. 峴港三座靈應寺:五行山靈應寺,山茶半島靈應寺,巴拿山靈應寺。
  5. 景點距離近。從 Google 地圖以峴港為中心取距離,會安、巴拿山皆在 30 公里範圍內。只有順化較遠,約 80 公里。以台灣的距離感來說,就是到隔壁縣市的感覺。

產生指定容量的 Raspberry Pi SD 卡磁碟映像

將 Raspberry Pi 的 SD 記憶卡備份為磁碟映像很簡單。但那是指同一張 SD 卡備份還原的情形。 在大量部署樹莓派設備時,我們需要一些特別的前置工作,才能產生很多張 SD 記憶卡都能用的磁碟映像。

win32diskimager 或 etcher 這些 Windows 磁碟備份與寫入工具有個缺點。 它們只能整顆磁碟備份或寫入,不能選擇備份的容量範圍。 然而標示相同容量的 SD 卡,實際容量仍有個別差異。少則十幾 MB ,多則差一、兩百 MB 。 因此,就算你備份的 SD 卡容量比你想寫入的 SD 卡容量只大一些,它也拒絕寫入。 在大量部署樹莓派設備時,非常不利。

我的維護經驗是:

  1. 使用 gparted 縮減 SD 卡使用的分割區容量。 我通常會縮減最後的分割區容量。尾巴留下 100~200MB 的不使用空間。對應 SD 卡容量的誤差量。
  2. 使用 dd 指令建立 SD 卡磁碟映像。因為 dd 可以指定容量。

Raspberry Pi OverlayFS 檔案系統使用備忘錄

Raspberry Pi 在 IoT 方案中,通常都不接鍵盤與螢幕,也沒有設計電源開關。 所以很多時候, IoT 現場的使用者會把 RPi 設備當成是 Arduino 這類微控制器設備,認為出現狀況時直接關掉設備的電源再打開就好。 就算不是使用者有意為之,在 IoT 現場也很可能遇到電源中斷的意外。

但是 RPi 的工作方式實際上更偏向一般 PC ,故與一般 PC 相似,將直接關掉電源的事視為不正常關機動作。 這種斷電方式可能打斷正將資料寫入檔案系統的工作,造成 SD 記憶卡的檔案系統內容毀損。 因此 RPi 運用在 IoT 方案時,需要設置檔案系統的保護機制。至少要保證它被直接斷電後,檔案系統也不會毀損。

當 RPi 運作 Raspbian 時,可以啟用 OverlayFS 作為檔案系統的保護機制。

Raspberry Pi eth0 有線網路設定的 fallback 組態

Raspberry Pi 使用作業系統 Raspbian GNU/Linux 9.9 (stretch) ,啟用 GUI 桌面。 在此環境下,傳統的網路介面組態 /etc/network/interfaces 無效用。以 /etc/dhcpcd.conf 為準。

dhcpcd.conf 的 eth0 有線網路基本組態就是向 DHCP 服務要求 IP 。如果所處環境沒有 DHCP 服務,那 eth0 就不設定任何 IP 。

如果是在靜態 IP 網路環境中使用 Raspberry Pi ,可以從 Raspbian 桌面上方工作列的 WiFi 圖示,打開「Wireless & Wired Network Settings」設定頁面,設定有線網路 eth0 的靜態 IP 。 若是自行編輯 dhcpcd.conf ,則設定內容如下 (假設靜態 IP 是 192.168.1.99):


interface eth0
inform 192.168.1.99

但 dhcpcd.conf 其實還有一組更有彈性的 fallback 組態,可在自動要求配置 IP 失敗後,才退回靜態 IP 。只是這組態得要動手編輯 dhcpcd.conf 。

Debian 10 安裝筆記升級篇

上星期 (2019-07-06) Debian 官方發行了 Debian 10 (buster)。正好我的筆電 Thinkpad X200s 上的 Debian 8 也實在有點舊了。就趁著週末重新安裝作業系統,升級到 Debian 10 。

安裝步驟大致依照我以前的筆記。

本文主要列出和 Debian 舊版不同的地方。這裡沒寫的,就是看以前的安裝筆記。

NodeMCU http recursive 遞回呼叫範例

NodeMCU 的 http 模組可用於存取一般 HTTP 資源,或是呼叫 RESTful API 。 然而, NodeMCU lua 環境的基本程式設計模型是事件驅動模式。 故 http 模組提供的方法也是非同步方法 (async method)。 但它還有一個限制,它一次只能發出一個請求,不允許併發作業。

It is not possible to execute concurrent HTTP requests using this module. NodeMCU Documentation

因此,如果你的控制器需要向 HTTP 伺服器發出多個請求的話,就需要利用一些技巧,例如遞回呼叫,讓你的 HTTP 請求可以一個個地依次發出。 其實就是將非同步方法同步化。

LINQ 與 SQL 的 inner join 語法轉換

我個人用 C# 撰寫資料庫存取程式時,習慣先用 SQL 敘述直接查詢資料庫,確認結果如我預期之後,再把這段 SQL 敘述在程式碼中寫成 LINQ 表達式。 而除錯或維護程式時,則反過來操作,把我覺得結果不如預期的 LINQ 表達式複製出來,改成 SQL 敘述去查資料庫。

這兩件事是我常常在做的,也就有些心得。LINQ 的 inner join 是不錯的範例。很常用,敘述有些長,但格式工整容易對應 SQL 。

NodeMCU timer 鬧鐘計時器範例

Arduino 的程式碼中,呼叫 delay() 方法延時是典型作法。而在網路上也可以找到不少照搬 Arduino 習慣,使用 tmr.delay() 的 NodeMCU lua 程式範例。但請不要抄。 NodeMCU 不建議使用這個方式延時。

This is in general a bad idea, because nothing else gets to run, and the networking stack (and other things) can fall over as a result. The only time tmr.delay() may be appropriate to use is if dealing with a peripheral device which needs a (very) brief delay between commands, or similar.

NodeMCU Documentation

NodeMCU lua 環境的基本程式設計模型是事件驅動模式。但 tmr.delay() 會破壞這個工作模式。程式設計者應該用 tmr 模組的計時器功能取代。

NodeMCU 韌體與軟體更新工具

NodeMCU

NodeMCU,是一個開源的物聯網平台。它使用Lua手稿語言編程。該平台基於 eLua 開源專案, 底層使用ESP8266 sdk 0.9.5版本。

NodeMCU - 維基百科

NodeMCU 使用工具

  • python - 建議 Python3 。執行 esptool 所需。
  • esptool - 韌體更新工具。
  • OpenJDK - 7 或以上版本。建議 OpenJDK 8 。執行 ESPlorer 所需。
  • ESPlorer - IDE 工具。

簡單來說, esptool 用於寫入 NodeMCU 的韌體或任何 ESP8266 的 binary 內容。而 ESPlorer 則是讓 lua 開發者上傳 lua 程式檔。 兩個各自負責不同的內容。

Raspberry Pi 使用 HDMI to VGA 轉接器的設定事項

用電需求

Raspberry Pi 的 HDMI 埠會提供符合 HDMI 規範的最低限度電源(5V/55mA)。但 HDMI to VGA 轉接器的訊號轉換晶片大約需要 50mA ~ 150mA 電流。供電量非常勉強地達標。而畫面解析度愈高,耗電量也愈高。因此 HDMI to VGA 轉接器建議外接供電才會穩定工作。

我碰到的情形是,在未外接電源時,可以正常顯示 NOOBS 的系統安裝畫面。但啟動 Raspbian 時,就會在啟動過程即將進入 GUI 模式前重啟。因為按預設組態, Raspbian 需自動偵測畫面最適解析度。在逐步提高解析度的偵測過程中,耗電量超過 Raspberry Pi 透過 HDMI 送來的電力,導致系統重啟。我必須為 HDMI to VGA 轉接器接上外接電源,才能正常啟動。

因此建議找附帶電源輸入端的品項。如果附帶的電源輸入端是 Micro USB 入電孔,你可以從 Raspberry Pi 的 USB 插座供電給轉接器。

例如:

有人動手改裝不含外部電源輸入的 HDMI to VGA 轉接器:RaspberryPI : HDMI to VGA 加裝 USB 外接電源

.NET 筆記 - Anonymous Type List

如何配置一個匿名型別串列。

首先,複習下列定義已知型別串列的語法。


int[] int_list1 = new int[] {1, 3};
var int_list2 = new int[] {1, 3};
var int_list3 = new [] {1, 3};

var list41 = new double[] {1, 3, 5.5};
var list42 = new [] {1, 3, 5.5};
Console.WriteLine(list41.GetType() == list42.GetType());

// error CS0826: 找不到隱含類型陣列的最佳類型
//var list5 = new [] {1, 2, "s"};

第一個例子是明確宣告等號兩邊型別的語法,也是最傳統的語法。

第二個例子引入型別推斷語法,等號右邊明確宣告此處將配置一個整數型別的陣列。所以明眼即可推斷左值之型別必為整數型別陣列。

第三個例子則更進一步,連等號右邊也不明確宣告資料型別。而讓 C# 編譯器先從陣列的資料內容推斷右邊的陣列型別,再依此推斷左邊的型別。這語法要求陣列的所有元素之型別皆可互相隱含轉換,編譯器再從中選出一個不會損失資料精度的型別。例如 new [] {1, 3, 5.5} 將推斷為 double[] 而非 int[] 以保證 5.5 不會變成 5 。若有一個元素的型別不合群,那編譯器就會拋出無法決定最適型別的錯誤。

.NET 筆記 - ASP.NET Core 上傳檔案的檔案大小限制

當使用者上傳檔案,卻碰到 403 Not Found 檔案找不到的錯誤時,基本上就是碰到檔案大小錯誤。很奇怪吧,但這是 IIS 的錯。可以先問問使用者是不是一次選取多個檔案上傳? 如果是,請他們分成幾次上傳,每次只選兩、三個檔案。

關於上傳檔案的限制,請看 MSDN 文章 File uploads in ASP.NET Core 後半段。

.NET 筆記 - ASP.NET Core 上傳檔案的模型繫結

上傳檔案的設計內容請看 MSDN 文章 File uploads in ASP.NET Core

但模型繫結的型態似乎是文件錯誤。微軟文件寫多檔上傳可用 List<IFormFile> 繫結,但 ASP.NET Core 2 會顯示錯誤訊息 The input was not valid,不能處理。改用 IFormFileCollection 取代 List<IFormFile> 才正確。

如果表單中除了檔案欄位還有其他輸入欄位,則 API 參數清單加上一個 [FromForm] 參數去接其他輸入欄位的內容。這個參數的型態通常可用 Dictionary<string,string>

留言板(disqus)放到首頁使用

我現在把 disqus 放到部落格首頁下方。以網站留言的型式使用。

每篇文章下方也多了一個「留言」鈕,簡單地連結跳回首頁留言板區。

對我的文章有問題的網友,留言時就加個標題、連結或引用文字吧。

.NET 筆記 - ASP.NET Core 應用程式托管於IIS服務

基礎知識

首先,請參考微軟的 Host ASP.NET Core on Windows with IIS 。但這篇文章資訊(廢話)很多,不容易找到重點。

ASP.NET Core 內建且默認用 Kestrel HTTP 服務模組。本文以此為準。

由於 ASP.NET Core 應用程式啟動時自帶 Kestrel HTTP 服務模組,本身不需要搭配 IIS 亦可獨立運作。但這種作法偏向微服務形式,而且負載分擔能力不如專業的 Nginx, Apache 或 IIS 。若你需要在一台主機上提供多個不同的 ASP.NET Core 應用程式服務,必須在 Kestrel 之前再加一道 HTTP 服務器,利用反向代理機制 (reverse proxy) ,溝通 Kestrel 與瀏覽器之間的通訊。

IIS 服務主機必須安裝 .NET Core Runtime & Hosting Bundle for Windows 。請到 .NET Core 網站下載

.NET 筆記 - async method and sync code; await and Task.Result

我用 .NET Core 實作一個呼叫 RESTful API 的簡單程式時,碰到一個小麻煩。 .NET Core 的 HttpClient 類提供的方法都是非同步方法 (async method)。 但我是在同步形式的程式碼用到 HttpClient 。我不想回頭去改程式碼加上 async Task 的宣告。所以我得要呼叫非同步方法,但用同步形式程式碼取得結果。

.NET 筆記 - ASP.NET Core appsettings.json 與執行環境

一般進行程式開發工作時,至少會分成兩個階段,或說兩個工作會期。開發期/Development/Debug 和 發布期/Production/Release 。並針對這兩個階段,設定不同的執行環境。

例如設定開發期執行環境的資料庫來源是 SQLite ,而發布期執行環境則用客戶指定的資料庫來源 SQL Server 。如此一來,開發人員僅須切換組態檔,就能改變程式的執行環境與參數。方便應付開發、測試、正式部署等工作。

ASP.NET Core 選擇用 DevelopmentProduction 這兩個稱呼區分兩階段。