Instructions and Information
All the instruction of requesting a prototype, how the website works and other information can be find in this category.
USB 與各種接口的轉換晶片
話說我一直都在研究一片叫 ArOZ Portable 的 Raspberry Pi Zero W (或 2W)用的主板,用作架設口袋雲端而使用的。它基本上就是一個 IoT Hub,引出三個 USB A port 用作連接其他裝置(如 USB 鏡頭、外接硬碟或隨身碟等等)。 而很多 ARM 開發板上因為處理器限制就只有 USB 2.0 / 3.0 接口,因此要把不同的裝置接上去 ARM 開發板的話就會需要不同的轉接器了。然而在 production 環境中,你不可以直接把轉接器包含在產品裡面(這樣看上去有夠不專業的),因此你就很會需要以下的一些晶片了。 所以以下列表總結出幾種我近幾年發現的晶片。我都把人手沒辦法焊接的包裝(如 QFN 等)都跳過了,剩下的都是人手可焊接的晶片包裝。 把萬用的 USB 接口轉換成其他的接口吧! USB Hub 說到 USB Hub 晶片第一個跳出來的應該就是 FE1.1S,畢竟他是現時市場上最便宜(和發熱量最高)的選擇,然而它是 SSOP 針腳,對創客並不友好,所以這裡我提供另外兩款 USB Hub 晶片選擇給大家參考: SL2.1A (SOP16) 只要外接 2 顆 10uF 加一塊 12Mhz 晶振就能動的 USB hub HS8836A (SOP16) 如果你連晶振都不想用的話,可以考慮用這片 HS8836A。它只需要兩顆 4.7uF 電容就好了(0.1UF),看樣子 4.7R 跟 0.1uF 的部分可以省略,但是如果你不是為了省空間的話還是加上去比較穩。 SD 轉 USB - HS8826 (SOP16) 這個我還沒用過,但看起來是可以支援 MS 跟 SD 卡的讀取的 SOP16 IC 單晶片 USB 編程微控制器 - CH552 看起來是一片內置 USB HID 的 MCU,還在研究中(以為下網絡找到的 CH552 鍵盤電路圖) 其他還在研究中 如果你發現了甚麼神奇蹦蹦的 SOP 針腳的 USB 轉換 IC 記得留言給我加上去喔!
神奇蹦蹦的 IC 與他們的用法
最近我在世界上其中一個最大的電子零件零售商的網站隨便看的時候,發現了一批不錯的 IC,於是順便把這些新發現記錄下來,之後需要用的時候就方便很多了! 基本中的基本 首先,最基本中的基本就是一些大家都在用,到處可見的 IC。由於這些 IC 的線路圖和模組設計教學整個網絡上都是,這裡就直接省略跳過詳細解釋它們的用途。通常在創客的 DIY 中最常見的就是: TP4056 - 單節 3.7V 鋰電池 1A 充電晶片XL6009 - 直流到直流升壓晶片LM2596(s) - 直流到直流降壓晶片 一些比較少見但是還是整個網絡上都是的晶片: MP1584(EN) - DC 可調降壓晶片 (小型 DIY 降壓用)D0505S-1W (D0505S-2W) - 5V DC 到 5V DC 直流隔離器(用於藍牙接收器與喇叭驅動電源隔離用)AMS1117-x (x 可以是 3.0, 3.3, 5.0 等) - 12V DC 到 x 的 LDO8205A + DW01 - 鋰電池保護板 很多時候 Maker 為了做帶電池的裝置就是用 TP4056 + XL6009 / MP1584 這樣配合著用,可是這樣做很浪費空間,所以我就開始找不少關於電源管理的方案,以下的應該就已經踏進沒甚麼人知道的領域了。 5V 0.8A 充放控制器 - HT4928(s) HT4928 是一片用起來很方便的鋰電池充電和升壓輸出的晶片。通常你很容易在那些便宜的單節 18650 行動充電器 (充電寶)裡面找到它。雖然用它來充手機是超級的慢,但是作為一些低功率裝置的供電(例如 Pi zero w)來說是不錯的選項。 5V 1A 充放控制器 - TP4333 如果 0.8A 差了一點點才夠,你可以考慮使用 TP4333。它也是一個用於行充的電源方案,但是用的外接零件會多幾個(R1,S1 跟 D5 如不需要手電筒功能可省略)。 5V 2A 充放控制器 - IP5306 / IP5307 這是一片大功率的鋰電充電和升壓晶片。能夠在 SOP8 package 裡做到 10W 的同時充放電,還帶 4 顆 LED 作電量顯示。(注:這東西發熱滿厲害的,記得底部的銅要鋪好鋪滿) 順帶一提,如果 IP5306 太貴,你可以試試看用替代用 IC FM5324 鎘鎳氫電池充電器 - CJC5122 / ASC0304B 這是一片 NiMH 充電器 IC,支援 1 到 4 顆的 NiMH 電池充電,預設是以 300mA 的充電速度來充。以下為 3.6V NiMH (3 顆串流)時的電路圖(R1 R2 及 R3 在不同配置下需要變更其電阻值) 單節鋰電池保護晶片 - XB8887A 通常的保護板需要使用兩塊晶片來做保護功能,可是這一片就能做到單片保證的功能。對於需要用到 18650 同時對空間要求很高的 project 很有用。 Charger 的部分可以配合 TP4056 晶片使用,這樣兩塊 SOP8 的晶片就能做到原本要一整片指甲大小的 PCB 的功能。 更小的單節鋰電池保護晶片 - XB5306A 如果 SOP8 還是太大,你可以考慮用這一片 XB5306A 。 使用 SOT23-6 包裝,真的打個噴嚏就不見了。電路圖跟上面的相近,Over current cutoff 電流量則降至 3A 使用 SOP8 Package 的升降壓晶片 - XL6007 對於一些對厚度很有要求的 project,要放進 XL6009 可能會有一點難度。這個時候就可以考慮使用 XL6007 了。這一片 SOP8 的晶片與 XL6009…
JavaScript 顯示時間的例子
因為間中要用到每次都要去 Stack Overflow 抓有點麻煩所以就直接記下來了: new Date().toLocaleDateString() > 2022/1/30 new Date().toLocaleString(undefined, {year: 'numeric', month: '2-digit', day: '2-digit', weekday:"long", hour: '2-digit', hour12: false, minute:'2-digit', second:'2-digit'}) > 2022年01月30日 星期日 01:05:48 new Date().toLocaleDateString('en-US', {year: 'numeric', month: '2-digit', day: '2-digit'}) > 01/30/2022 new Date().toLocaleDateString('en-ZA') > 2022/01/30 new Date().toLocaleDateString('en-CA') > 2022-01-30 new Date().toLocaleString("en-US", {timeZone: "America/New_York"}) > 1/29/2022, 12:05:48 PM new Date().toLocaleString("en-US", {hour: '2-digit', hour12: false, timeZone: "America/New_York"}) > 12
使用 Apache2 當 Reverse Proxy 伺服器
因為最近房東在沒經我同意之前在房間的網絡上遊加入了一台 NAT 路由器,所以原本架在我的房間裡的 ArozOS 伺服器就沒辦法在外面連線了。想了想,於是我想到了可以透過 zeroTier 和 Reverse Proxy 來使用我房間裡的伺服器,所以便開始研究怎樣可以弄到一台 Reverse Proxy 的伺服器。 網絡上很多人喜歡用 nginx 來當 RP伺服器,可是基於某些原因我並沒有太喜歡它所以我就選擇用 Apache2 了。首先,安裝 apache2 sudo apt-get update sudo apt-get install apache2 -y 然後就是編輯它的設定檔,加入你需要 proxy 的目標 sudo nano /etc/apache2/sites-available/000-default.conf NameVirtualHost *:80 <VirtualHost *:80> ServerName ixtw.hkwtc.com ProxyPass / http://{zerotier 的區網 ip}:8080/ ProxyPassReverse / http://{zerotier 的區網 ip}:8080/ </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html </VirtualHost> 然後 Enable Proxy 插件並重啟 apache 2 sudo a2enmod proxy_http sudo systemctl restart apache2 可是,WebSocket 要求過不去欸? 這是因為要 proxy websocket 會需要額外的 module 去處理,首先啟用 wstunnel 跟 rewrite engine sudo a2enmod proxy_wstunnel sudo a2enmod rewrite sudo systemctl restart apache2 然後加入 RewriteCond 跟 RewriteRule <VirtualHost *:80> ServerName ixtw.hkwtc.org RewriteEngine On RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR] RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC] RewriteRule /(.*) ws://192.168.196.15:8082/$1 [P,QSA,L] ProxyPass / http://192.168.196.15:8082/ ProxyPassReverse / http://192.168.196.15:8082/ </VirtualHost> 最後再重啟一次 apache sudo systemctl restart apache2 這樣就完成了!
透過 Arduino 取得 UART HMI 螢幕頁面 ID 然後按需求轉頁
最近因為我在弄一個 60W 的 PD 充電器,然後想弄一個迷你的螢幕來顯示電池的資訊,所以我便選用了一個 2.2寸的 UART HMI 了。 2.2 寸的 UART HMI,比想像中要小一點 選 UART HMI 的原因有很多,網上也有很多文章教你怎樣選合適的螢幕,所以我就不細說了。簡單來說, UART HMI 是一種可以透過 Serial 來控制螢幕載入預先設計好的界面的一種人機界面。 發送指令到螢幕 HMISerial 是 Software Serial。以下 function 把 cmd 內的內容發到螢幕,如果 debugMode 被啟用,側會同步輸出到 hardware serial 上。 SoftwareSerial HMISerial(2, 3); // RX, TX //... void sendCommand(String cmd){ if (debugMode){ //Mirror output to serial Serial.print(cmd); Serial.write(0XFF); Serial.write(0XFF); Serial.write(0XFF); } HMISerial.print(cmd); HMISerial.write(0XFF); HMISerial.write(0XFF); HMISerial.write(0XFF); delay(50); } 使用例子: sendCommand("t0.txt=\"[info] MCU Connected\""); 取得現在 HMI 屏幕正在顯示的 Page ID 如果你把 sendme 指令發到屏幕,屏幕會回傳現在的 page ID 給你,它的回傳信號大約長這樣 66 01 FF FF FF 66 是這個指令的回傳碼,01 是現在的 page ID (即是 page 1),FF FF FF 側是傳送完成的意思,所以我們只需要在 Serial.read() 的時候抓到 0x66 就知道下一個一定是 page ID 了。 int getPageNumber(){ sendCommand("sendme"); bool nextReadIsPageNumber = false; while (HMISerial.available() > 0) { // read the incoming byte: incomingByte = HMISerial.read(); if (nextReadIsPageNumber){ //這是 page ID nextReadIsPageNumber = false; return incomingByte; } if (incomingByte == 0x66){ //下一個出現的 byte 就是 page ID 了 nextReadIsPageNumber = true; } } } 使用例子(檢查現在是否在 page 0(hex: 0x00)) currentPageNumber = getPageNumber(); if (currentPageNumber == 0x00){ //Do something } 成果(Arduino 透過 COM port 輸入到模擬器)
Babylon.js ExtrudeShape 匯出成 STL 之後出現不正常 face data 的解決方案
在開發 aPrint 系統的時候,其中一個功能是使用 CSG 把兩個 Mesh 組合成一個容器。可是在組合匯出之後卻出現 face data 重疊的情況(也有人會把它叫做 z-fighting 或是 invalid normal ) 在 Windows 的 3D viewer 中可以看到全部面都有一些問題 這個我研究了一段時間,發現這是跟 extrude 模型的時候的設定有關。一般來說,為了避免模型在背面出現破圖,所以在 render 的時候也會把 rendering face 設成雙面。以下為其中一個例子 BABYLON.MeshBuilder.ExtrudeShape("container-outerwall", { shape: externalBorder, path: [extrusionStart,extrusionEnd], cap: BABYLON.Mesh.CAP_ALL, sideOrientation: BABYLON.Mesh.DOUBLESIDE }, scene); 可是這樣在 CSG 處理的時候卻會出現問題,我懷疑是與 Mesh.CAPALL 的設定有關,可是我並沒有深入研究是不是 CAP_ALL 設定了之後就不能使用 DOUBLESIDE 的設定。 然而在把sideOrientation 改成 FONTSIDE 之後問題就解決了。 BABYLON.MeshBuilder.ExtrudeShape("container-outerwall", { shape: externalBorder, path: [extrusionStart,extrusionEnd], cap: BABYLON.Mesh.CAP_ALL, sideOrientation: BABYLON.Mesh.FRONTSIDE }, scene); 所以結論就是如果你要進行 CSG 操作的話 sideOrientation 不要設成 DOUBLESIDE 就對了。
Refused to execute script from ‘xxx’ because its MIME type (‘text/plain’) is not executable.
Go 在 Windows 10 上使用 File Server 傳送 JavaScript 的時候間中會出現這個錯誤,網上的其中一個解決方法是更改系統 register 讓 Windows 把 JavaScript 辨認為 text/javascript。然而如果你不想透過更改系統設定的方法解決的話你也可以透過編程方法解決。 使用 Router 來手動設定正確的 Mime Type func mrouter(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if filepath.Ext(r.RequestURI) == ".js" { //Requesting a js file w.Header().Add("Content-Type", "text/javascript") h.ServeHTTP(w, r) } else { h.ServeHTTP(w, r) } }) } 使用方法如下 fs := http.FileServer(http.Dir("./web")) http.Handle("/", mrouter(fs)) 這樣便修好了
淺談雲端文化及 Vendor Lock-in 問題
首先,現在很多學生跟客戶都已經懂得「雲端」/ Cloud 這個概念。要知道其實 Cloud 並不是甚麼新奇的東西,也不是這近 10 年才出現的東西,這個(類似的)系統 60 年代就已經存在的了,只不過當時我們叫它做「Client Server Model」而已。至於 Cloud,與其說它是一個技術,我反而覺得它比較像一個 Marketing 用的術語,對於要用在 technical document 裡面,我就比較有保留。 甚麼是雲端 / Cloud 我對雲端的見解基本上就是 別人的電腦托比 這個我也曾在 Hong Kong Open Source Conference 2020 說過這個(不過是比較以開玩笑的角度來說),而實際上,如果你真的要向一個完全不理解雲端技術的人說明到底雲端的東西存放在哪裡,基本上你也會回答出類似的答案。 source: https://xkcd.com/908/ 現代的網絡與雲端 很多時候現在的開發者對現代的網頁系統架設都是有以下幾種想法 是一個 Web Hosting Service 架設的網站,我只要在他們的伺服器上上載我的網頁檔案即可(例如 Github page 或是一些免費的 web hosting 網站)直接在網頁上編輯網頁的供應商(例如 wix / wordpress)一台電腦,上面開著 XAMPP / WAMP / LAMP 來架設網站(例如自己寫的 php / HTML 網站)一個 process 開著一個程式以處理要求(e.g. Nodejs / Golang) 可是實際上現代的網頁系統比你想像中的要複雜一點,基本上會自己架伺服器的已經不多了,還會用上很多第三方的 cdn 檔案等等。但是由於這篇文章不是用來教你設立網站,所以我直接跳到結論: 現代的網頁應用程式對於第三方依賴性比以前高很多 例子好像說 Cloudflare 、AWS / Google / Azure 的 VM 、CDN、Github / Gitlab 等等 成本與依賴性 通常我說依賴性,我指的有兩種,一種是開發的依賴性和運作的依賴性。如果你有寫過 Nodejs 或是 Golang 的網頁你應該都有聽過 module 這東西,這東西就是我所說的開發依賴性之一;另外一種就是運作的依賴性,例如說 cdn、api 之類的東西。 我對第三方依賴性其實沒有甚麼特別抗拒,畢竟你還是需要把你的系統跟其他的網頁系統連接在一起。例如分享到社交平台、電郵等等。然而,有一些東西是我絕對不會碰的,就是具有平台依賴性的 API。 甚麼是平台依賴性? 平台依賴性是指你寫的程式必須要使用某一供應商的平台才能正常運作。例子如 Firebase、Lambda 等等。 為甚麼具有平台依賴性的 API 應該盡量避免? 平台依賴性的 API 會讓你無法轉移系統到另一平台,做成 Vendor lock-in 的情況。這情況除了網絡之外其他平台也會出現,例如說必須依賴 Windows API 的(古老)程式、必須依賴 iPhone + iOS 的硬體才能運作的 App 等等,這些都是 vendor lock-in 的例子。 你可能會覺得:這個我只是用來試試市場或是所謂的 Proof of Concept 作品而已。用這些 API 也沒甚麼吧? 不對,因為很多時候商業機構看到你的 PoC 作品能用就會直接在上面加建成為他們的最終產品,然後繼續用它來發展商業項目。這個時候就會變成真正的 Vendor Lock-in 了。如果有一天供應商中止他們的服務或是突然收取很高昂的平台使用費,到時候你就沒辦法只好乖乖的付錢了。 所以我一向的做法都是當有客戶要選擇使用雲端服務建立網頁系統的時候我都會推薦他們用 VM。VM 的 Guest OS 我一向都會選擇開源的 Debian 或是 Ubuntu。這樣萬一有需要改換供應商的一天,整套系統也可以很輕易的從一個 Linux VM 轉移到另一個 Linux VM 而不需要更新原本的 code base。 可是如果不依賴第三方 API 有這麼多好處,為何這麼多人還是在用具平台依賴性的 API? 最主要還是成本問題。這些 API 的供應商一般都會做出簡單易用的網頁界面,讓網頁系統的開發者很容易就可以透過 API KEY 來存取到他們在雲端上的數據庫、core logic 或是其他本來需要伺服器運算的東西。他們能夠省下更多開發及架設後端的時間,更不用對著 Linux terminal 輸入指令還要處理間中跳出來又看不懂的 linux 錯誤。在以 man-hour 收費的 IT 界來說,這種能夠節省成本、客人又看不出來而且又省功夫的做法,誰不想用? 一分錢一分貨 很多人以為軟體跟去超市買菜一樣,能叫價就叫價、去比較便宜的那家買就好。其實與其說 Software 是一件商品,你應該視它為一件藝術品。再怎樣簡單的程式也能夠有便宜和貴價之分別,如果你沒有 technical 背景可能看不出來,但是很多時候這些價錢差就差在 有沒有使用說明及技術文件有沒有處理 Edge Case處理速度、穩定性界面的人性化設計、Flow 設計跟使用者體驗兼容性、平台依賴性開發者溝通能力 所以說,開發軟體真的是一分錢一分貨,貪小便宜只會麻煩到未來的自己。 實用與理想之差別…
Sinilink XY-WF5V 灌 Home Dynamic v2 IoT 控制器
最近因為一些原因拿到了兩塊 Sinilink 的 XY-WF5V WiFi 繼電器模組。由於它的內置 firmware WiFi 有鎖,加上它的 App 看上去就覺得很爛,所以我決寫把它的 firmware 刷掉重新寫一個 HDSv2 的 firmware 進去,讓我的雲端 IoT 控制器能夠控制到它。 首先,怎樣在非開發板上灌程式? 這個時候你就需要 USB 編程器了(大陸叫下載器,通常我叫它 ISP),你可以用不同的方式來灌程式進去,可是我這裡用的是最便宜的 ESP01 用編程器,樣子大約長這樣 然後我們就可以直接把線從那個 2 x 8 2.54 母頭裡拉出來,直接焊接在 ESP8266 上面,線路如下 接線圖 完成之後大約長這樣 逆向工程 之後就是把板子的線路重新畫出來。由於這是一塊兩層板,所以沒甚麼大問題。之後再把找到的 GPIO 跟據需要重新寫進 HDSv2 On/Off 的 example sketch 裡面, 可是,我們怎知道應該使用哪一塊開發板的配置呢? 這個我們可以選擇使用 Wemos D1 R1 作為基礎,重新把 ESP8266 上對應的針腳在 Wemos D1 上找到對應的 Digital Pin 號碼即可。完成之後 Arduino sketch 裡面的開關 pin 被改成如下: int signalOutputPin = D14; //The pin to activate the mosfet of relay int buttonPin = D6; int refPin = D8; 如果找不到 Pull up / down 電阻怎辦? 另外,如果你在板子上找到沒有 pull up / pull down 的按鈕,很有可能它是使用軟體方式做的 internal pull up / down 電阻。在更改 HDSv2 的 example 時只要把 INPUT pin 的設定由 INPUT 改成 INPUT_PULLUP 即可,例子如下: pinMode(buttonPin, INPUT_PULLUP); 相關可以使用程式 pull up / down 的針腳可以參考下表(請對應 Generic 8266 的 GPIO 號碼,不要使用最左欄的 pin 號碼) 完成圖 完成之後在 ArozOS 內重新掃描一下 IoT 裝置,應該就會有新的 Sinilink WiFi Relay 在列表中出現了。
用了三年時間寫網頁桌面作業系統的故事
這是一個想找地方儲存他的音樂、影片跟圖片的窮學生與他的 Raspberry Pi 的故事。 如果你想直接下載來玩,這裡是傳送門:https://github.com/tobychui/arozos 開始時候的樣子 由 2016 年開始,我就一直在寫這套自用的系統。這系統主要是用來存放音樂、影片檔案等等的媒體文件,這樣我就可以很方便的在課堂跟課堂之間的休息時間聽到自己的音樂或是看一套短劇。這是這套系統於 2016 年的時候的樣子 這個版本是使用 PHP5 開發,後來升級到了 PHP 7 + Apache 伺服器。雖然同一台主機(當時我還是在用我的主機來當伺服器)上面有安裝到資料庫,但是它本身是不需要連接到 MySQL 資料庫的。這系統基本上是使用膠水語言黏起來的,運作原理就是後台的一個 VB.net 程式定時把硬碟上的音樂檔案掃描,並產生一個音樂列表讓 php 去 render 一個網頁界面。當有需要的時候再從硬碟裡搬出來到網頁伺服器的資料夾再進行串流。 你現在依然能夠在我的 Github 找到最原始版本的 ArOZ Online 系統(後來才改名為 ArozOS 作業系統),但是拜托 不!要!用!它!https://github.com/tobychui/ArOZ-Omega-Online 由 PHP 到 Go:開發難度與效能的平衡 這個非常簡單的 PHP 版本使用一兩年之後,因為我開始在上面放越來越多的檔案,單一頁面已經無法應付所有檔案的列表,所以開始加入檔案管理器、模組化的播放器到最後的網頁桌面 不過兩年後,PHP 的系統還是無法應付很多大型檔案(特別是現在的檔案都越長越大,由以前幾 MB 的 mp3 到現在隨時到 50 - 60MB 的 flac 檔案),加上桌面系統做得越來越像本地端的桌面,而需要大量而且高反應速度的資料回傳,因此 PHP 已經沒辦法再成為這系統的主力語言,而需要轉移到另一種語言繼續開發。有興趣了解更多關於這部分的技術問題可以看這篇: http://imuslab.com/wordpress/2020/03/29/%E7%B7%A8%E7%A8%8B%E8%AA%9E%E8%A8%80%E7%9A%84%E6%A5%B5%E9%99%90%EF%BC%9Aphp/ 最後經過一點研究之後,我決定轉移到 Go 語言,並把 ArOZ Online Beta (AOB)正名為 ArozOS 。 3 年後的 ArozOS 系統 經過 3 年的開發,它終於成為了一個類本地作業系統的網頁系統。首先就讓我們由桌面開始介紹吧! 網頁桌面 ArozOS 的桌面基本上就是 Ubuntu 20.04 混 Windows 的風格。你可以看到類似 Ubuntu GNOME 的通知欄 也能夠在右上角看到電源開關(可以透過啟動參數關閉這功能),還有一些方便的捷徑 就像 Windows 一樣,如果你要建立一個新檔案也只需要右鍵即可。你也可以透過右鍵選單來更改桌面背景 開始功能表也是如此,看著有沒有一點熟悉的感覺? 在結束桌面的介紹之前最後一定要說的:桌面版的重新命名界面! 看到沒有彈出視窗的感覺是不是非常有桌面的感覺呢?是不是有那種回到家對著主機螢幕的那種安心感(不對 檔案管理員 在使用原本的系統一段時間之後,我開始需要上載其他東西到我的系統裡。而最通用的界面去查看不同類型的檔案當然是?沒錯,就是檔案管理員。所以我就自己寫了一個進去我的系統啦 我的檔案管理員有兩種模式,為別是「列表」模式跟「縮圖」模式 在縮圖模式下,檔案管理只會嘗試從檔案中提取預覽圖片。這功能適用於音樂、影片,照片甚至 3D 模型檔案 檔案管理員最初並沒有分類和排序的功能。可是由於上載到系統的檔案數目日益增加,所以去到一個地步我還是需要把排序功能加進去才有辦法找到我的檔案( 之後還加入了支援 regex 的檔案尋找功能 噢,如果你是喜歡 dark theme 的使用者,檔案管理員也提供 dark theme 模式,不過這最初只是方便我在晚上找電影來看而已 檔案管理功能 檔案管理員提供很多不同的檔案功能。你可以在右鍵選單中找到所有的功能。 就如作業系統一樣,你也可以選擇以某一個 WebApp 開啟指定的檔案 為了讓自己在收拾和清理資料夾的時候比較方便,所以系統也加入了支援 drag & drop (拖放)的功能。要移動檔案的時候只要很簡單的把檔案由一個視窗拖放到另一個視窗即可。 由於 Golang 本身提供 async 模式以處理要求(request),因此這樣的功能比起 PHP 更容易開發。這個即時的進度顯示是使用 websocket 技術,讓後端一邊複制檔案一邊回傳進度。 檔案分享 間中我也會有需要透過 ArozOS 分享檔案的功能。因此我就順便把這個功能加進去了。 (這裡只是一個例子,乖孩子不要把 localhost 的網址分享給別人喔) 別人就可以透過 QR Code 或是分享的連接來下載到檔案 回到原點:音樂與影片播放 當然這些功能現在還存在吧!經過三年的開發,這些功能已經比之前的好用很多了。使用 PWA 技術,現在的音樂播放器大約長這樣 這個界面甚至可以在 Android 手機上顯示獨立的播放界面(如果你是工程師,這個叫 MediaSession API) 影片播放模組亦是如此。使用 HTML5 技術,它能夠串流影片和電影,不再需要好像以前的版本那樣先下載才能看了。 系統設定 基本設定 由於這套系統已經長這麼大,這麼複雜了,要管理這套系統亦會需要一個很複雜的設定界面。我嘗試把設定界面做得簡單易用,所以就設計了一個分類,讓不同的設定放在不同的子分類裡,然後下面再有不同功能設定的細分類。 首先,你可以在系統設定看到系統的基本資料與處理器、記憶體使用量。 WebApp (網頁應用程式)及 Subservice (子服務) 當然,作為一個網頁桌面系統,當然也需要一個安裝應用的界面吧?所以我就弄了一套應用系統出來了。以下是一堆我寫出來自用的應用程式 WebApp 都是一些簡單,只需要檔案存取的應用程式。這些 WebApp 使用 JavaScript 編寫,並使用 Otto VM 作沙盒隔離。而 Subservice 則是一些比較複雜,需要直接與 OS 連接的程式。 你可以輕易的透過設定界面安裝和移除 WebApp 可是 Subservice 只能設定啟用和禁用。畢竟有一些 subservice 是跟系統運作穩定性相關的,理論上應該是由裝置的…