2015年1月19日

網樂通 - HPLIP、CUPS、SANE Scanner Server - HP Color LaserJet CM1015,功敗垂成

前言:
去年過年的目標,現在重新開始,但目前仍舊失敗,
失敗原因在HPLIP部份程式碼沒有OpenSource。
目前我還在努力,看有沒有辦法把沒有OpenSource的部份自己實做出來。

功能目標:
在網樂通上,透過USB連接HP Color LaserJet CM1015,
達成掃描功能,並進一步做到掃描伺服器。
也許會問,列印呢?列印都沒達成,做什麼掃描?
事實上,透過p910nd,應該是能夠輕鬆做到列印,只是還沒實際印過而已。

實做目標:
在網樂通上實做出SANE + HPLIP,透過網樂通直接下指令掃描,
或透過SANE Scanner Server,網路掃描。

HPLIP、CUPS、SANE需求:

事實上,HPLIP依賴CUPS和SANE,
除非單純build HPIJS,否則CUPS是必要的(掃描功能也需要),
如果要使用掃描功能,SANE是必要的。

而CUPS、SANE、HPLIP這三者,都需要libusb,它們都使用libusb當作USB溝通的底層。
libusb可以使用libusb1.0或libusb,我這邊使用libusb1.0。

SANE還需要jpeg library,tiff library可以裝也可以不裝。
相依關係如圖:


實做平台:
最終使用 網樂通Debian wheezy。

我實際上sh4twbox、archlinux、debian這3個平台都嘗試移植,
但sh4twbox、archlinux都遇到問題,導致移植失敗。

網樂通移植平台限制:
sh4twbox:
sh4twbox是我原本最期望使用的平台,也是我花費最多心力的平台,
同樣,最後功敗垂成。

sh4twbox的本體實際上是STLinux,但因為原廠不再支援STLinux 2.3,
會發現STLinux 2.4版的libc使用的是2.14版,
但網樂通上的libc是2.10版,
網樂通和開發環境的版本不合,會導致CrossCompiler編譯的程式,執行時可能會有問題。
另外,STLinux 2.4 CrossCompiler環境,原廠並沒有把libtool和pkg-config的路徑問題做修正,
因此裝在CrossCompiler環境的library,經常會link到host的x86 library,
造成過程經常出現問題。

最後我的解決方法:
針對pkg-config和libtool問題,
針對configure出錯時,直接修改configure,讓它指定到正確的路徑,
同時使用CFLAGS、CPPFLAGS、CXXFLAGS、LIBS這些環境變數,
強制指定正確library的路徑和正確include的路徑。

針對libc版本不合的問題,
我注意到ST Linux 2.4 CrossCompiler的路徑中,有提供static library,
我強制將shared library( .so檔案)改名,讓程式和library編譯時強制使用靜態編譯,
編譯出來後,在網樂通上執行看看,看有沒有link到shared library。

這方式最終看起來,好像能動,但Debug異常麻煩,不確定問題在哪。

archlinux:
我按照網路上的教學安裝gcc,網路上說需要另外下載gcc,覆蓋掉archlinux套件安裝的版本,
我照著做,但在編譯時,會出現錯誤,上網Google結果都是要你重新安裝gcc,
這我懷疑網上版的gcc和系統的部份library可能不合,後續放棄沒繼續了。

Debian:
不愧是Debian,套件夠完整,但系統也實在是肥很多。
光下指令,就能感受到反應速度明顯比archlinux、sh4twbox慢,
很可能預設啟動的service太多造成的。

但Debian最大的好處是,套件庫齊全,針對CUPS、HPLIP、SANE的編譯,
相依的library幾乎都直接有套件裝,不需要另外自己編譯,
就library編譯部份省去不少功夫,但網樂通本地編譯,
真的是等.....等......等......等......等.....

過程:
Debian上需要另外編譯CUPS、SANE、HPLIP的主要原因是:
1. 這幾個套件在Debian上沒有提供套件
2. 這幾個程式的相依套件庫太多,很多相依套件在sh4平台上沒有提供,這尤其發生在HPLIP上

因此,我編譯時,只使用幾個功能,相依套件盡量少,最後使用下面這些:
  • libjpeg-dev
  • libtiff-dev
  • libusb-dev
  • libusb-1.0-0-dev 
  • libtool
  • pkg-config
  • gcc
  • g++
編譯按順序如下:
SANE:
1.
下載sane-backends Source Code並解壓縮,這邊我使用sane-backends-1.0.24版。

2.
./configure --prefix=/usr/local/sane-backends --enable-libusb_1_0

3.
make

4.
make install

CUPS:
1.
下載CUPS Soruce Code並解壓縮,這邊我使用CUPS-1.7.5版。

2.
./configure --prefix=/usr/local/cups --disable-gssapi --without-perl --without-java --disable-gnutls --enable-libusb --disable-dbus --disable-openssl --enable-libusb --disable-dbus --disable-pam --disable-avahi --with-python=no

3.
make

4.
make install

HPLIP:
1.
下載hplip Source Code並解壓縮,這邊我使用hplip-3.14.10版。

2.
設定環境變數
export CPPFLAGS="-I/usr/local/sane-backends/include -I/usr/local/cups/include"
export LIBS="-L/usr/local/sane-backends/lib -lsane -L/usr/local/cups/lib -lcups"


3.

將SANE、CUPS Library加入系統參考路徑中

修改/etc/ld.so.conf.d/libc.conf,修改如下:

# libc default configuration /usr/local/lib /usr/local/cups/lib /usr/local/sane-backends/lib

執行ldconfig

4.
./configure --prefix=/usr/local/hplip --enable-lite-build --disable-doc-build --disable-gui-build --disable-fax-build --disable-dbus-build --disable-cups11-build --disable-qt4 --disable-network-build

5.
make

6.
make install

上述HPLIP編譯,會編譯HPLIP的列印和掃描功能,其他功能全部不裝。

7.
複製HPLIP的hpaio檔案到sane-backends中,如下:
cp -v /usr/local/hplip/lib/sane/libsane-hpaio.* /usr/local/sane-backends/lib/sane/

8.
將hpaio加入到sane-backends的搜尋檔案中
編輯/usr/local/sane-backends/etc/sane.d/dll.conf
最後面加入
hpaio

9.
複製HPLIP的model資訊
從HPLIP的Source Code目錄中複製data到/usr/local/hplip/share/hplip/data
類似如下:
cp -v -R /usr/local/printer_system/hplip-3.14.10/data /usr/local/hplip/share/hplip/data

10.
將HPLIP的library路徑加入到系統參考路徑中,如下修改:
修改/etc/ld.so.conf.d/libc.conf,修改如下:
# libc default configuration
/usr/local/lib
/usr/local/cups/lib
/usr/local/sane-backends/lib
/usr/local/hplip/lib

執行ldconfig

到此安裝完成,接著要Debug。

除錯方法:
針對SANE,可以如下除錯:
1.
設定環境變數,如下:
export SANE_DEBUG_DLL="255"

2.
執行/usr/local/sane-backends/bin/sane-find-scanner
如果找到Scanner,表示SANE這關過了,
如果沒找到,請直接跳到第5步驟,看syslog。

3.
執行/usr/local/sane-backends/bin/scanimage -L
如果找到Scanner,表示HPLIP第1關過了,
如果沒找到,請直接跳到第5步驟,看syslog。

4.
執行/usr/local/sane-backends/bin/scanimage > /tmp/image.img,
如果/tmp/image.img有檔案產生,表示HPLIP一切正常,
如果有問題,會顯示錯誤。

5.
過程中有錯誤,可以看/var/log/syslog,裡面會列出錯誤原因。

功敗垂成:
我家的HP事務機是HP Color LaserJet CM1015,參考:

它提到這段話:
Driver Plugin Information:
This printer REQUIRES a downloadable driver plug-in. Use hp-setup to install the printer, and to download and install the plug-in. In general, required driver plugins are required for printing support. Driver plug-ins are released under a proprietary (non-open) license and are not part of the HPLIP tarball release.

這台事務機的Linux Driver需要HP的Driver Plugin,
而Driver Plugin我也手動安裝了,
但關鍵問題是,Driver Plugin裡面包裹了4個Close Code Library,
這4個Close Code Library並非全部都需要,這跟HP印表機、掃描器、事務機型號相關,
更明確的說,這4個是4個不同的Protocol需要的library,
以我的CM1015而言,CM1015需要的是bb_soap這個library。

因為這4個library只提供x86 32bits和64bits版本,
因此無法使用在網樂通上,也無法使用在ARM平台上,
相關討論參考:

展望:
HP Color LaserJet CM1015是舊式的HP事務機,
這表示它的protocol相對單純,
目前我透過在HPLIP Source Code加上printf的方式(在libsane-hpaio和hpmud),
在x86機器上呼叫scanimage後,查看呼叫過程,
試圖拆解bb_soap內的功能,
事實上從libsane-hpaio的程式碼看起來,
bb_soap內其實只有下列function,分別是:
  • bb_open()
  • bb_close()
  • bb_get_parameters()
  • bb_is_paper_in_adf()
  • bb_start_scan()
  • bb_end_scan()
  • bb_get_image_data()
  • bb_end_page()
我目前應該已經解開bb_open()、bb_close()、bb_start_scan(),
有成功看到掃描器動作,
但我目前不清楚收到的資料哪些部份才是圖像,
圖像和後續bb_get_image_data()、bb_end_scan()、bb_end_page()的行為還不清楚,
我相信,
如果我能成功破譯這些function動作,
修改HPLIP Source Code後,就能讓網樂通成為掃描列印伺服器。

參考資料:

2015年1月11日

Acer Chromebook 13 Ubuntu (Chrubuntu)

前言:
Google提供了我們Linux Geek一個好玩具。

Acer在去年底推出Acer Chromebook 13這台Chromebook,
我看了規格後覺得,這台非常適合Linux玩家,未來不知道,
但過去要找到這樣的玩具,還台灣廠商做的,很少很少(根本是沒有啦.....)

Acer Chromebook 13我是透過網拍買的二手機(我是12月中旬買的),
但因為距離上市日期不長,加上它的特性,我相信機器都還很乾淨,
要被操到硬體問題一堆,難度很高,
在這裡要感謝賣家,用不錯的價格提供了一台好玩具。

規格:
Acer Chromebook 13的規格如下:
  • CPU:ARM Cortex-A15 4核心 (Nvidia Tegra K1)
  • Video:Nvidia Kepler架構192核心
  • LCD:13.3吋LED背光LCD (1366x768)
  • RAM:4GB DDR3 (不可擴充)
  • Storage:32GB eMMC
  • Webcam:前置Webcam (1280x720)
  • WiFi:802.11ac
  • Bluetooth:Bluetooth 4.0
  • Card Reader:SD-Card
  • Battery:3220 mAh
看到第1條相信就傻了,再看第2條,更傻。
這台Notebook,使用的是ARM處理器,而且是Nvidia出的ARM處理器,所以內含Nvidia顯示。

這台機器非常有趣,它的真身其實是:
Tegra-K1
原價屋NVIDIA Jetson TK1開箱

它是Nvidia針對行動平台出的ARM處理器,
除了Acer Chromebook 13外,還使用在下面幾個產品上:
此外,Nvidia提供的車用電腦開發平台,也是使用這塊Nvidia Tegra K1。


機器問題點:
問題1:無法安裝Windows
Acer Chromebook 13最大的問題,正是它的特色所在,
它使用的是Nvidia ARM處理器,因此無法在上面安裝Windows,
這對於大部分玩家而言,就會是個大問題,
無法安裝Windows,表示無法隨心所欲的安裝程式、系統。

問題2:ChromeOS有夠難用
ChromeOS的主要問題是,它全部功能都要透過網路,
你要寫Word、Excel、PowerPoint:Google Document
你要記事本:Google Keep
你要儲存檔案:Google Drive
你要看影片聽音樂:一個簡易的播放器,並整合Google Drive

那如果現在沒有網路呢?
你要寫Word、Excel、PowerPoint:.........
你要記事本:..........
你要看影片聽音樂:..........

那不用說了,這根本就是垃圾,沒有使用者會買單的。



當上述2個問題同時存在,你買了一台Chromebook,
只能使用Google線上服務,離線後通通不能用,
又不准你安裝其他作業系統,
請問你下個動作是什麼?

我猜:
1. 退貨
2. 網拍賣掉
3. 丟角落堆灰塵

ChromeOS的設計有其特色,但目前設計有瑕疵,實用性很糟糕,
關於它的設計理念,我放在最下面附註。

Linux Geek禮物:
雖然機器有上述2個怪問題,但對於Linux Geek來說,這些問題都不是問題。

Chromebook有2個特別計畫:
  • chrubuntu
  • crouton
這2個計畫都能讓Chromebook不再用ChromeOS,而改用Ubuntu或其他Linux distribution。

這2個的區別是:
  • chrubuntu:是「安裝」一個獨立的Ubuntu,開機就直接進入Ubuntu
  • crouton:是「放置」一個Ubuntu,由ChromeOS切換進Ubuntu桌面環境
2個我都使用過了,crouton不好用,
而且在Acer Chromebook 13上,crouton無法使用顯示晶片硬體能力,
我自己是沒有嘗試過,國外網友的意思是,
Nvidia K1 X11 Driver只能被載入1次,重複載入時,第2次載入無法使用硬體能力。

目前我是使用chrubuntu的方式,系統運作相當不錯。

Acer Chromebook 13 Linux軟體(含作業系統)支援情況:
針對Linux軟體支援情況,我們概括簡單的按下面分類:
  • 硬體驅動與Linux Kernel
  • Linux軟體、Library與ARM

硬體驅動與Linux Kernel:
Acer Chromebook 13出廠就是Linux,因此內部的硬體沒有Linux驅動的問題。
這非常難得,大部分Notebook要裝Linux,都會遇到很多驅動程式不支援或支援不好的情況,
但在Chromebook上,不會有這樣的問題。

額外驅動程式,
Google有提供各Chromebook的Kernel SourceCode,額外裝置的Kernel Module SourceCode只要支援ARM,就可以編譯出Kernel Module。

這點Google做得相當好,它針對所有Chromebook型號,有提供一整棵Kernel SourceCode Tree,
我們可以直接根據Chromebook型號,下載到相對應的Kernel SourceCode,也有提供目前使用的config(ChromeOS預載Kernel,直接有/proc/config.gz),可以自己修改Kernel,或編譯Module。

因為它沒有RJ-45有線網路,我另外插一張USB3.0 Gigabit網路卡,
驅動程式直接有module可以使用,連build都不用。
哪一張?
USB3.0 gigabit網路卡晶片大概只有1、2家,可以直接用的是Axis的晶片,
很神奇,Axis本業是IP Camera,但竟然業外搞了一顆少見的USB3.0 gigabit chip。

Linux軟體、Library與ARM:
目前Ubuntu ARM(當然應該也包括Debian ARM)的套件完整度相當高,
除了專門針對x86的軟體(例如:wine、VM)沒有之外,
目前使用上,還沒遇到沒提供的OpenSource軟體或Library,
哪些叫做有提供的?
Java、FlashPlayer(Google包在Chromebook內)、GNOME、MPlayer、VLC、Firefox、Chromium、Qt Library、GTK+ Library、python...等,常見的軟體、Library都支援。

到目前,只遇過一套程式可以裝,但執行會Crash,是畫3D的blender。

所以使用上幾乎沒遇到問題,目前唯一的問題是,
它的硬解Nvidia是用OpenMAX,提供的是GStreamer模組,
MPlayer、VLC不支援OpenMAX,目前還只能ARM軟解。

但這台ARM四核心很強大,除了H.264不行外,MPEG4以下等級,ARM軟解都直接ok。

所以結論是,這台Chromebook 13,改用Ubuntu(Chrubuntu)後,整個頭好壯狀,考試都得100分。

特色與優勢:
1. 非常省電 (除動態時脈調整外,還動態開啟關閉CPU核心)
這台是ARM系統,使用起來真的是很省電,
Nvidia對Tegra K1的支援相當不錯,
它因為是專門用在手機、平板的行動平台,對於省電有特殊設計。

根據Tegra-K1描述,
「理論上」它應該是NVIDIA 4-Plus-1 Quad-Core ARM Cortex-A15,
這裡指的NVIDIA 4-Plus-1是說,
「理論上」它應該有2顆ARM,
1顆是4核心高階高時脈ARM,另一顆是單核心低時脈ARM,稱為LP :p,
「理論上」它應該可以在閒置時,關閉4核心高階ARM,切換成使用LP ARM。

「實務上」我找不到文獻說的參數來切換CPU,沒辦法很屌的做到切換成LP ARM,
原因我有3個猜測:
1. 我猜Google或Acer測試時發現不穩,把這功能關閉
2. 這款SoC是閹割版,沒有額外這顆LP    ARM
3. 工程師研發時,沒注意到這功能,沒開

但除了這點有點可惜外,這台Chromebook的ARM直接build-in省電module,
它除了一般PC動態時脈調整外,它可以動態的開啟、關閉CPU核心,
當CPU工作量低時,就會先關閉1個核心,還是很低就關第2個核心,
陸續關到剩下單核心。
當CPU工作量增加時,時脈先拉高,然後開第2個核心,
還是很高,開第3個核心,最終4個全開。

開/關的切換過程完全不會有感覺,不會頓也沒遇過程式因為切換發生問題。

2. 強大顯示運算
買小筆電,看高解析度影片真的是慘,
「號稱」可以硬解1080p影片,
實際情況是,高bitrate影片就是解不動。

這台是Nvidia血統的SoC,不用說,顯示晶片超強,
Nvidia主打的特點就是超強繪圖運算,
Tegra-K1的介紹中描述,它的應用環境包括:
  • 車用電腦中的環境辨識 (包括自動煞車的車前障礙物辨識、循跡系統的標線偵測...等)
  • 機器人的機器視覺 (障礙物辨識、物件辨識)
所以這台有CUDA,可以直接用這台開發CUDA程式做顯示卡運算,
雖然不知道意義在哪........

播放影片部份,如果MPlayer、VLC能支援OpenMAX(正在研究中),
那就可以丟掉爛爛的播放器,直接用MPlayer、VLC順暢播放H.264影片。

3. 高CP值
這台就算是原價,價格也相當實惠。
客官啊.......
它的雙胞胎兄弟NVIDIA Jetson TK1原價屋目前特價一塊還要NT 6090,
你買這台NB,Acer附上13.3吋LCD、3220mAh電池、802.11ac WiFi、藍芽、32GB eMMC,
只多賣你不到NT 4000,這樣的商品和價格,去哪找啊。

怎麼改機成Ubuntu (Chrubuntu):
我完全瞭解,介紹了半天,卻不提供安裝方式,根本是炫耀文,擺明找打。

我還沒完全把Chrubuntu的script修改完,
沒辦法提供出簡單、完整的安裝方式出來,
不過,這裡我先把參考資料,目前建好的檔案放出來,
高手高手高高手先自己試試看吧!

參考資料:
ChrUbuntu on Acer Chromebook 13

上述參考資料的位址是最關鍵的,裡面開版大大實際上已經把7成的工作完成了,
他做了下列事情:
1. Ubuntu放上Acer Chromebook 13
2. 整合了Nvidia在Linux For Tegra R19提供的Library
3. 把Google改過針對Acer Chromebook 13的FlashPlayer移入Ubuntu
4. 放上支援硬解的播放器(可能也是從Google的ChromeOS搬出來的)
5. 將ChromeOS內的Kernel和modules複製到Ubuntu中

其他網友在版上補充:
1. Ubuntu NetworkManager在WiFi運作不正常的修正
2. 音量快速鍵設定
3. 開機後預設關閉藍芽
4. Ubuntu 14.10無法順利安裝和使用,需使用Ubuntu 14.04

自己安裝心得:
我自己實際安裝,第1次安裝滿辛苦的,因為它下載網站設到歐洲,很慢.......
過程失敗,就要重新開機,整個script重跑......很久.....
所以最後script還自己邊try邊改......直到安裝成功......
再之後,直接把安裝好,ok得版本tar起來,直接tar解開......

另外,我自己修正包括:
1. 修正按Power睡眠後起不來
2. 除Xfce4外,安裝GNOME Fallback
3. 輸入法加入新酷音輸入法
4. 除音量快速鍵外,加入顯示器亮度快速鍵 (針對GNOME設定,Xfce4我不會設自定義快速鍵)
5. 直接安裝好修正過的NetworkManager
6. Nvidia的Linux For Tegra(L4T)改用R21.2版 (R21.2版支援CUDA 6.5,R19只支援到CUDA 6.0)
7. 修正切換耳機沒聲音
8. 加入CIFS和NFS的modules
9. 開機後直接設定啟用動態開啟/關閉CPU核心的能力
10. 安裝、設定思源黑體(Noto Sans)中文字型
11. 開機後,顯示器亮度設為50%(預設是最亮)
12. 安裝好Java、Firefox、Chromium、LibreOffice、MPlayer、VLC、aptitude

我直接將改過得整個系統打包成tar檔案,
省去chrubuntu script上網下載一堆套件安裝成系統的時間,
高手高手高高手只需要:
Step 1. 按chrubuntu教學,將Acer Chromebook 13設成Develop Mode
Step 2. 按ChrUbuntu on Acer Chromebook 13執行chrubuntu.sh,變更Partition Size並Format成ext4
Step 3. 將我改過的系統tar檔傳上去(我自己是用wget放到home目錄),解開到chrubuntu Partition
Step 4. 按ChrUbuntu on Acer Chromebook 13,切換開機載入系統的Partition

打完收工

預設的帳號密碼和原來chrubuntu一樣:
帳號:user
密碼:user

root預設禁用無法登入,使用sudo su變更後再改密碼。

檔案壓縮後有1.35GB目前我放在MEGA上,
未來歡迎幫我分流,或提供給我空間放置,連結如下:
xubuntu-desktop_lazchrubuntu_l4tr21.tar.bz2

下一篇,我希望可以修改完針對這個檔案安裝的chrubuntu.sh,
再把完整步驟寫出來。

目前使用上尚待解決的問題:
1. MPlayer、VLC OpenMAX移植和硬解(如果用gstreamer base的播放器,如:totem,可以直接硬解)
2. 睡眠後可能是顯示晶片沒停止很耗電,我電腦睡眠後丟著,白天上班晚上回來電池竟然沒電了
3. 闔上螢幕不會關機;但睡眠後,闔上螢幕反而會開機
4. GNOME環境下,System tray的電池開機後不會顯示;點設定->電源叫出後,睡眠->醒來後又會消失
5. 睡眠醒來時,畫面會閃3下
6. Firefox支援Java Plugin不支援FlashPlayer (這是個大哉問,跟Firefox要支援Chrome Plugin格式有關)
7. Chromium支援FlashPlayer不支援Java Plugin (這是個大哉問,跟Java Plugin格式有關)
8. 變更alsamixer設定後,切換到耳機模式,耳機有聲音喇叭沒聲音(正常);但在喇叭模式,耳機和喇叭都有聲音(不正常)
9. 鍵盤沒有Del,同位置是電源,經常按錯啊 (這問題是來鬧的嗎....)
10. 極少數時候,睡眠醒來後,執行中程式會Crash

目前注意到大部分問題都發生在睡眠或睡眠醒來,
我十分懷疑問題點在Systemd和UPower,
事實上我發現到,Ubuntu預設睡醒的行為,都是針對x86或intel的動作,
這台是Nvidia ARM,相關的動作都沒有或可能不完全,
但目前我對Systemd和UPower都不算熟,chubuntu又算是改機成品,
沒有正常的Ubuntu 14.04對照,不確定正確動作流程。

題外話之ChromeOS設計理念:
Google的Android在手機上異常成功的關鍵之一,就是捨棄了傳統的手機平台設計,
傳統手機平台,都是一般作業系統搭配一個特殊的環境和特殊的SDK,
像是OpenMoko。
在那個年代,我還在用PocketPC,最方便開發的系統是WinCE,使用VisualC++ Embedded。

你要開發者在開發App前,要先經過一個複雜的「儀式」,
才能把開發環境建置出來,環境內的桌面系統可能是Qt Library、GTK+ Library,
又因為是手機平台,SDK還不大一樣,這開發者怎麼買單?

Google的創舉在於,你不需要那個複雜的「儀式」,
你也不需要學習離譜的SDK,你只要會「Java」,而且注意,
不是Sun設計得莫名其妙的JavaME,而是直接用JavaSE就能開發,
只要最後經過一道「詭異程序」,就能把Java程式放在Android上執行。
所以就成功了...........

Google的作法是,
它把手機底層全部用一個Google的JavaVM包裹(JavaVM的設計公司是被Google買斷的),
開發者不需要知道底層在幹嘛,只需要Java程式這個JavaVM能看懂,就能執行,
那個「詭異程序」,就是負責將一般的Java程式,
轉換成這個小型化JavaVM能看懂的格式,附帶包入安裝資訊...等。
Google這作法當時,Java已經是熱門語言,程式開發者多,
直接用現成語言和現成SDK就能開發,
加上Google的名號,和當時hTC獨家的硬體工藝,使用者和開發者就買單了。

事實上,當時Google還是擔心和其他同質平台遇到一樣的問題,
因此發表前還搞了個Android前100大創意App徵選,
除了搞聲勢外,就是要讓開發者能認識、熟悉這個平台的開發環境和模式。

Google聽到有人在PC上,用「瀏覽器」當核心開發OS,
手法和它在Android上一樣,差別是,
一個用JavaVM,一個用瀏覽器的WebKit + JavaScript解譯器
(瀏覽器在現代,幾乎可以視為一種Html + JavaScript語言的VM),
直接就想複製這樣的模式到PC,要把Windows幹掉,這就是ChromeOS。

ChromeOS的設計理念不錯,也很特別,
但它的設計,只整合了網路服務,沒有整合本機程式,
這讓整個ChromeOS變得失敗。

我描述個對比,你在Android手機上操作,
會因為是網路手機,所以沒辦法讀取手機內的影片、聲音、聯絡人、簡訊嗎?
這當然不會發生吧.......

但在ChromeOS上,竟然是搞成這樣,這真的是失敗設計,
你要同一個架構這麼搞,你可以寫個獨立的Local WebServer,
所有本機相關的操作,都透過Local WebServer呼叫執行。

更簡單的作法,你直接在架構上開洞,在ChromeOS的SDK上開個API,
能直接開啟本機程式,同樣可以引入檔案總管、小畫家、MPlayer、VLC...等,
就不會搞成現在這樣,有新意但不好用。

2015年1月10日

HPLIP、SANE、CUPS、p910nd

前言:
去年過年前後,打算用網樂通做個列印、掃描伺服器,最後失敗了,
一轉眼一年過了,
最近又打算起死回生,再來一次。
這次不鐵齒,看看OpenWRT上作法後,瞭解HPLIP、CUPS、p910nd後再開工,
於是就打算把這幾樣寫成心得。

介紹:
  • HPLIP是HP針對HP掃描器、印表機提供的Linux OpenSource驅動程式組合包。
  • SANE是Linux上的掃描器的軟體,裡面包含了網路掃描、掃描的前端軟體介面、掃描器驅動程式。
  • CUPS、p910nd都是Linux上的列印伺服器,p910nd是non-spooling的列印伺服器,CUPS則是spooling伺服器。
簡單介紹結束,
接著先針對CUPS和p910nd描述其架構,
再介紹SANE架構,
最後描述HPLIP和它們間的關係。

p910nd與CUPS區別和兩者架構:

p910nd:
參考:
[Oleg/Lly/CDMA@wifi] p910nd 列印伺服器(無spool)

從參考的作者文中可以知道,
p910nd的安裝,主要2個步驟:
  1. 確定Linux Kernel內USB Printer有支援
  2. p910nd daemon有啟動,並指定Port、USB Printer的Device File
步驟完成,p910nd就會動了,而且p910nd需求極小,
幾乎沒有相依太多library就能動作。

再看看下面這個參考:
DD-WRT Printer Sharing

裡面描述了p910nd安裝外,也描述了Client端的安裝,
包括CUPS、Linux、Windows、MacOSX的安裝介紹。

簡單白話的說,
p910nd本身只是USB<->Socket的轉譯器,
它不負責印表機溝通,從Socket來的資料直接轉入USB當中,
因此所有印表機的溝通,列印資料的轉譯,都要由Client端負責,
印表機工作的排程,則要由印表機自己負責。

因此p910nd優點是library相依性低,也不需要複雜的額外工作,
至於Client端,
Windows直接有原廠的驅動程式,
Linux直接有CUPS搭配HPLIP就能達成,
MacOSX看起來也是有驅動程式,這部份我不熟。

CUPS:
直接看系統方塊圖(wiki):

CUPS是一整套完整的列印伺服器程式,
裡面包含了使用者管理、列印語言轉譯、列印Queue、網路列印...等多個功能。

我們單從CUPS的系統方塊圖來看,
它前面提供了各種檔案格式的轉譯器,轉譯成PostScript,
中間能將PostScript轉譯成各種列印語言,像是PCL...等,
後面CUPS backend又能串接包括本機的USB、SerialPort...等,網路的IPP、網路芳鄰、AppleTalk...等網路介面。

因此可以知道它是非常龐大的列印系統,
從前端應用程式的檔案開始,就一路透過它層層處理,最後一樣透過它送到印表機上。

優點當然是系統功能完整,但缺點就是相依的library多,
程式的設定項目多比較複雜,
在小型系統上就比較不方便移植,
因此比較早期的OpenWRT、DD-WRT都只支援p910nd,
較新的版本則已經有提供cups,
自行移植則會遇到比較多的編譯問題,我自己最後編譯出來,執行後,網頁點幾下還是會segfault。

SANE:
SANE是Linux上最主要的掃描器解決方案,可能也是唯一的解決方案,
有支援Linux的掃描器,大概都是提供SANE的驅動程式。

SANE分前端(frontend)和後端(backend),
SANE frontend主要提供給應用程式,送掃描動作給SANE;
SANE backend主要就是SANE介面界接掃描器的驅動程式。

SANE有提供一個特別的SANE frontend,叫做net,
它能讓SANE能透過網路接收SANE的掃描動作,達成網路控制掃描器掃描。

HPLIP:
前面提這麼多,原因是HPLIP相依的東西很多,
上述幾個是最關鍵的幾個。

參考:

直接看參考中的系統方塊圖:

拆開來看HPLIP各項元件,我們先只看掃描器部份,看hp-scan那個垂直的部份。

在HPLIP中,HP的掃描器是透過SANE支援的。
hp-scan:
hp-scan是HPLIP提供的掃描器工具程式,但hp-scan實際上是個SANE frontend,
就是透過SANE backend掃描。

libsane-hpaio:
HPLIP提供了libsane-hpaio這個SANE backend用的延伸library,
libsane-hpaio讓SANE backend透過它來操作HP掃描器,
我不很確定裡面有沒有包含驅動程式,或是否有包含部份的驅動程式,
但這個library非常重要,SANE需要靠它才能操作HP掃描器,
在SANE中,它被稱為hpaio的SANE backend。

hpmud:
HPLIP實際操作HP印表機、掃描器的I/O library,
所有的工作都透過這個library傳遞給USB或網路(網路印表機、網路掃描器時),
它的下層,就是USB library或Socket,直接連結印表機、掃描器。

D-Bus:
掃描器這路看完後,我們來看D-BUS。
在HPLIP中,各個應用程式和元件間溝通都是透過D-BUS,
這些應用程式包括掃描器左邊那幾個小顆的,
包括hp-systray、hp-toolbox、hp-sendfax這幾個工具程式,
還有libsane-hpaio這個SANE backend。

這些元件和程式的溝通都透過D-Bus,
而D-Bus本身在HPLIP則是透過hp/hpfax backend管理。

關於D-Bus,這邊不多介紹,簡單的說,它是Linux上IPC的一種,
各應用程式可以透過D-Bus互相溝通,
典型的例子是,播放程式透過D-Bus提供出播放音樂的資訊,
Skype這類的通訊軟體透過D-Bus可以得到並顯示你正在播放的音樂資訊。

部份總結:
到目前為止,
先整理下HPLIP做了什麼?搞了哪些元件?要在小系統上編譯,需要編譯哪些東西?
1.
HPLIP最核心的I/O主要是hpmud,負責最終和硬體通訊

2.
HPLIP使用SANE做為掃描器核心,要能掃描,除了SANE要ok之外,
hpaio backend要確定ok,並有放置在SANE backend的目錄內

3.
hp-scan只是個SANE frontend,不用管它,用其他SANE程式效果一樣

4.
D-Bus在HPLIP是各程式的溝通平台,單純使用掃描功能,不用管它

5.
如果搭配p910nd,到目前為止的資訊已經足夠了,其他元件都只跟列印和CUPS相關

HPLIP與CUPS:
前面CUPS提到,CUPS架構很大,CUPS中間有許多轉譯器提供各種轉譯,
HPLIP針對CUPS實做了hpcups、hpcupsfax...等幾個轉譯器,
接收了從CUPS收到的列印資料(應該是PostScript)後,
透過這些轉譯器轉譯,送給hp/hpfax backend,再透過hpmud送到印表機。

這裡我比較不清楚的地方是,
轉譯器轉譯後,是直接在轉譯器內送到hp/hpfax backend,
還是轉譯器轉譯後,回到CUPS,再由CUPS送到hp/hpfax backend進行列印,
這是圖上沒有表示的部份。

2014年8月3日

股市自動交易系統(半完成品) - JavaATS程式架構 - DataManager

這篇來描述另一個簡單的部份,Data Manager,取得歷史資料的元件,
在JavaATS架構圖如下:
這裡的Data Manager,主要就是從SQL Server裡面把資料撈出來,
目前的Data Manager只有實做撈Candle(K線資料),
每筆資料包含:

  • ID (代號)
  • Name (名稱)
  • Date (日期時間)
  • Open (開盤價)
  • Close (收盤價)
  • High (最高價)
  • Low (最低價)
  • Volume (成交價)

Data Manager程式碼結構:
Data Manager結構非常簡單,只有1個建構子+2個method,如下:

  • 建構子:載入JDBC驅動程式,設定SQL Server的資訊(IP、Port、DB Name、Account、Password)
  • getCandle:取出特定市場、代號的歷史資料(所有時間,從最早到最新)
  • setCandle:傳入SQL Code,直接寫入或更新資料到SQL Server

Candle與CANDLES變數:
這裡唯一需要解釋的是,Candle和CANDLES這2個變數,和它的命名原因。

  • Candle:就是K線資料,但它代表1個時間的K線資料
  • CANDLES:表示一整串Candle,它的原型是個Candle的陣列

大小寫命名原因:
這和之後會提到的StockAPI有關連,
為了讓StockAPI便於使用和區別,
我在StockAPI內,統一使用「大寫+底線」的method名稱,
例如:
取得歷史資料的API叫GET_HISTORY
取得Quote的API叫GET_QUOTE

一整串的Candle因為很常被StockAPI使用,因此它的命名變為大寫。

2014年8月2日

股市自動交易系統(半完成品) - JavaATS程式架構 - Config Manager

這篇要來描述Config Manager的部份,在JavaATS的架構圖如下藍色框框部份:
ConfigManager是屬於比較單純的部份,
它主要功能就是XML的Parser,負責將XML資訊讀出成變數。

ConfigManager功能與呼叫方式:
JavaATS會在一開始時透過ConfigManager載入所有變數,
之後JavaATS所有變數的取得,都是透過ConfigManager。

例如:
xml設定檔檔名為:configs.xml

則在JavaATS一開始時,會呼叫:
CONFIG = new ConfigManager(configs.xml);

之後所有設定都會讀入CONFIG當中。

例如要取得MySQL設定的IP,如下:
String ip = CONFIG.getMySQLIP();

ConfigManager程式結構:
Java的XML Parser有2套,是:

  • DOM XML Parser
  • SAX XML Parser
DOM的優點是程式碼比較容易結構化,缺點是操作比較麻煩,
SAX的優點是,操作單純,但程式碼比較不好結構化。

在寫這部份時,正好就學習SAX XML Parser使用方式,
因此,JavaATS的XML Parser,原則上都是用SAX XML Parser。

SAX XML Parser:
這裡不得不稍微提下Java SAX XML Parser的使用方式,
Java SAX XML Parser程式碼結構大致如下:
File f = new File(configs.xml);
DefaultHandler XMLHandler = new DefaultHandler() {}

SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
saxParser.parse(f, XMLHandler);
原則上,SAXParser的設計是:

  1. 先建立並初始化SAXParserFactory物件
  2. 從SAXParserFactory取出Parser
  3. 設定Parser的XML檔案和Handler

上述的程式碼結構,就是先建立出XML的File和Parser Handler,
然後按設計,建立並設定到Parser內,就會開始Parse XML了。

Handler的實做包括:
public void startElement(String uri, String localName,String qName, Attributes attributes)
public void endElement(String uri, String localName, String qName)
public void characters(char[] ch, int start, int length)

SAX Parser會從頭一行一行讀XML,
當讀到StartElement時,就會跳入startElement()的Handler function,
要開始讀內容時,就會跳入characters()的Handler function,
當讀到EndElement時,就會跳入endElement()。

例如:
<Config>
HelloWorld
</Config>
當讀到<Config>時,就會跳入startElement(),
在startElement()內,就會取得Config這個標籤名稱是開頭。

當讀到Hello World時,就會跳入characters(),
在characters()內,就可以取得Hello World。

當讀到</Config>時,就會跳入endElement(),
在endElement()內,就會取得Config這個標籤名稱是結尾。

ConfigManager程式碼結構:
ConfigManager程式碼依循SAX設計,
在Handler內,將Config XML的載入透過startElement()、characters()、endElement()分開。

原則上,每個項目的參數,都會包括:

  • 變數Element:用在startElement()時,標記目前要讀取的變數,在endElement()時,標記變數已讀取完畢
  • 變數本身:用在characters()時,實際讀出並紀錄變數

例如:
MySQL的IP資訊

SQLElement:紀錄是否要讀取SQL資訊
MySQLIP:紀錄MySQL的IP

在startElement()時,當標籤是SQL,就將SQLElement設為true,
在characters()時,檢查到SQLElement == true,就讀取標籤內容,並設定到MySQLIP。

程式碼大致如下:
public void startElement()
{
  if(qName.equals("SQLElement"))
    SQLElement = true;
}
public void characters()
{
  if(SQLElement == true)
    MySQLIP = new String(ch, start, length);
}

public void endElement()
{
  if(qName.equals("SQLElement"))
    SQLElement = false;
}

2014年7月26日

股市自動交易系統(半完成品) - JavaATS程式架構 - Timer Server

這篇開始,會分幾篇來解釋目前JavaATS的程式架構,
讓有興趣修改、增加功能的網友能比較容易看懂程式。

這篇就直接切入最核心的部份,Timer Server和它相對應的Script Task List。

一開始再貼一次JavaATS程式架構圖:
這篇的重點會放在藍色字標注的區塊。

程式流程:
說得再多,比不過一張流程圖清楚,直接看流程圖:


第1張流程圖是JavaATS建構子的執行流程,
過程簡單,就是建立1個Timer定時觸發,觸發呼叫特定Method。

第2張流程圖才是關鍵所在,
當Timer觸發後,會呼叫MyTimerServerEvent這個Method,
接著它會從ScriptTasks這個List中,陸續取出所有Task來檢查和執行。

檢查時,會先判斷是否有IntervalTime(Interval模式),
如果有,就進入Interval模式。
如果沒有,就進入crontab的時間字串模式。

Interval模式:
1. 先取得上次執行的時間
2. 如果沒執行過,直接執行
3. 如果上次執行時間 + 間隔時間 >= 現在時間,表示到時或超時了,直接執行

crontab時間字串模式:
1. 先取得上次執行時間
2. 上次執行時間和現在時間同分鐘,表示執行過了
3. 週末是否設定不執行,現在是否是週末
4. 檢查現在時間是否符合crontab時間字串,符合就執行

crontab時間字串設計:
在crontab時間字串模式的設計,我一開始想了很久,
到底Linux的crontab是怎麼檢查執行的,
後來想到,Linux的crontab如果超過時間了,它是不會執行的,
我因此瞭解到它的時間檢查是反過來的。

它的核心設計是用現在時間來比較crontab時間字串是否符合。
給個簡單的例子:
假設:設定10:03分要執行 (假設時間字串為10:03)

電腦會每分鐘檢查一次現在時間,
10:00分時,時間字串為 10:00,10:00和10:03字串不符,不執行
10:01分時,時間字串為 10:01,10:01和10:03字串不符,不執行
10:02分時,時間字串為 10:02,10:02和10:03字串不符,不執行
10:03分時,時間字串為 10:03,10:03和10:03字串相符,執行

因此,它只需要每次檢查時,將現在時間轉成時間字串,
然後比較現在時間的字串是否符合Task時間的字串,
就能判斷是否執行。

當然,這裡面的字串比對比較複雜,
用傳統的indexOf或strstr或substring,那會比較到發瘋,
因此這裡是用Regular Expression,
它直接可以確定字串格式,並且把格式中所有項目的資訊一次取得,
然後各個項目比較即可。

還是以上面的10:03為例:
現在時間:Regular Expression類似(10):(02)
Task時間:Regular Expression類似(10):(03)

即可直接取得
Now[0] = 10
Now[1] = 02

TaskTime[0] = 10
TaskTime[1] = 03

接著只要Now[0]和TaskTime[0]比較,Now[1]和TaskTime[1]比較,
全部Pass,就是字串符合,這個例子中,Now[1]和TaskTime[1]不一樣,所以不執行。

延伸思考:
如果有在使用Google的Google日曆,注意到Google日曆的時間設定,
你會發現它彈性非常大,它一樣可以設定單次時間行程、週期時間行程,
但神奇的是,它定義好週期時間行程後,
還可以將週期時間行程的某幾個時間行程刪除或變更,
這樣的設計,我其實覺得滿高明的,我還沒有想通它的設計原理。

時間精確度問題:
crontab時間字串的設計有個致命傷,
因為它必須用現在時間來比較Task時間字串,
因此它每次的現在時間,都必須有個緩衝空間。

假設crontab時間字串的精準度設定為秒,
意思是,電腦必須每秒取得一次現在時間,
並且要在1秒內完成所有Task的時間字串比對,
只要電腦處理超時1秒鐘,
就會造成這秒的所有Task全部沒有執行。

文字不好表達,來個例子:

假設:
Task 1 10:00:02    定義10點00分02秒執行         執行時間0.2秒
Task 2 10:00:02    定義10點00分02秒執行         執行時間2秒
Task 3 10:00:03    定義10點00分03秒執行

以這樣有3個Task為例,
在10:00:02時,
Task 1會先執行,接著Task 2會執行。

Task 2執行完後,時間應該已經是10:00:04,
Task 3就會永遠略過不執行。

這就是為什麼crontab的時間精確度只能到分的原因,
因為大部分Shell程式,很少執行時間會超過1分鐘,
crontab的說明中有稍微提到一點點,
它有提到,crontab的執行時間不能過長,否則就是建議放到背景執行。

回到JavaATS,
目前設計,我並沒有設計multi-threading,
我的假設是,Task的bsh Script執行時間,應該是不會長的太誇張,
正常網路下,一般操作的Delay,應該是不會離譜到超過1分鐘以上。

2014年7月22日

股市自動交易系統(半完成品) - JavaATS設計與使用

這篇開始,會分幾篇將JavaATS進行解說,第一篇先描述設計的使用方式。

JavaATS設計:
JavaATS的核心是一個Schedule Server,可以設定多個(理論上無限多)Task,
每個Task可以各自定時,時間到時會自動被呼叫執行。
Task就是1個1個的BeanShell Script,每次時間到,都會被呼叫執行1次。
上述的JavaATS描述,其執行示意如下圖:
整個JavaATS的設定,包括:
1. JavaATS啟動時是否執行Init Script?
2. 有哪些Task需要執行?這些Task的執行時間?執行的BeanShell檔案是?
3. MySQL Server資訊設定
4. IM的帳號、密碼、傳訊對象設定
5. NDDEAgent資訊設定

這些資訊全部都紀錄在1個XML設定檔中,並在JavaATS啟動時載入。

JavaATS使用:
JavaATS啟動:
java -jar JavaATSServer.jar [config.xml]

執行畫面如下:

程式啟動後,便會載入Config的XML檔案,從XML檔案裡面取得相關設定,
之後便會根據設定的資料開始定期執行.bsh程式。

以上述畫面中,我測試的設定,JavaATS會執行2個Script,
1個是Init.bsh,另1個是DollarCostAveraging.bsh。

Init.bsh會在系統啟動後執行,
DollarCostAveraging.bsh會每分鐘執行。

Config設定檔如果沒有填,預設會讀取目前目錄下的config.xml。

Config檔案:
Config檔案是一個標準的XML檔案,只要符合XML規格,
可以用文字檔編輯,檔案格式必須是UTF-8。

XML格式畢竟不是給人看的,因此,我另外寫了一個專門設定的UI程式,叫JavaATSGUI。

在視窗(Windows/Linux皆可)下執行:
java -jar JavaATSGUI.jar

執行畫面如下:


可以透過Load將某個Config XML載入,修改後按Save儲存。
也可以直接填寫資訊後,按Save儲存成某個Config XML檔案。

以我測試中的config.xml為例,載入後截圖如下:

檔案下載:
https://www.openfoundry.org/of/projects/2518/download

目前版本MSN的相關設定和功能都還在,
在整個整理完畢上傳後,
會開始修改這個部份,將MSN功能移除,加上Pushbullet支援。

2014年7月20日

股市自動交易系統(半完成品) - NDDEAgent

開發背景:
在台灣的程式交易中,DDE可以說是無人不知無人不曉,
這鬼東西在我一開始接觸程式交易時,
對大家講的DDE...TS...資料源,根本一頭霧水,
一查資料,乖乖不得了,這鬼東西的書竟然是1994年,
要特別到圖書館借舊書才找得到,電腦書店根本沒有這東西。

用DDE+linux為關鍵字Google,想當然,什麼鬼都沒有,
有一樣疑問的人當然有,有人有發問,但答案就是......No answer.....
因此最終放棄在Linux上呼叫或連結DDE,改在Windows上開發個Agent來做。

一開始,我期望統一用Java來開發,畢竟同語言開發有一致性,好維護,
我當時比較熟的也只有Java,但不幸的,Java的DDE只有JDDE,而且似乎要收費,
因此轉而用跟Java比較相近的c#和NDDE開發。

最早,DDE Agent的開發是一回事,證券軟體的操作是另一回事,
為了自動操作證券軟體,最早我用AutoIt另外寫了一個Stock Server,
AutoIt的Stock Server專門用來操作Windows軟體,
DDE Agent則專門透過DDE取得和廣播DDE資訊,
這樣的設計實在太複雜,2個TCP Server各自運作,卻還互相關聯,
因此我將證券軟體啟動的AutoIt程式加入到DDE Agent,
成為了目前版本的NDDE Agent v1.5Beta。

一些網友會問(包括最開始的我),
DDE除了用Excel之外,怎麼接收?
DDE有辦法轉成其他Protocol嗎?
除了TS外,有沒有什麼程式可以同時設定、接收多個資料源?
NDDE Agent就是答案。

NDDE Agent功能與需求:

  1. 要能夠接收DDE訊息
  2. 要能透過TCP廣播DDE訊息
  3. 要能被控制,需要能下指令給NDDE Agent
  4. 要能將DDE註冊到證券軟體
  5. 要能啟動證券軟體(寶來點金靈)
  6. 能否提供個Web介面供呼叫?


NDDE Agent與Java ATS Server架構:

NDDE Agent基本設計:
為了能達到若干需求,NDDE Agent包括下面3個Server:
NDDE Agent的Server基本設計是Telnet Server。

所謂的常駐型Server,意思是Client端連上後,就會保持連線狀態,
直到下指令斷線離開,或者任一方斷線為止。

所謂的問答式Server,意思是這個Server是和Web Server一樣,
用一問一答方式設計,每次連上後詢問,得到答案後,會自動斷線。

在NDDE Agent中,目前裡面包裹了3個TCP Server,作用如下:
Data Server:
負責廣播所有DDE訊息。
Client連上後,所有DDE訊息都會透過它收到,它沒有指令控制,
Client連上後只能被動的接收訊息,要離開,由Client自行斷線即可。

Admin Server:
負責下指令給NDDE Agent。
Client連上後,會保持登入狀態,直到Client下exit指令離開,
Client可以透過它下DDE註冊指令,
Client也可以透過它下啟動點金靈指令,
Client也可以透過它下開啟元大寶來的B2CAPI指令。

Http Admin Server:
負責下指令、詢問NDDE Agent。
這個Server是應朋友需要加上的,透過它可以用Http URL的方式下指令給NDDE Agent,
因為它模擬Http Server,因此每次詢問或下指令後,都會回應並斷線,
它可以提供DDE訊息,但只能透過詢問方式取得,沒有即時性。

NDDE Agent特色:
1. DDE轉Socket程式
2. 支援多DDE註冊
3. Data Server用non-blocking方式開發,理論上在多Client同時接收時,能盡量降低延遲時間

NDDE Agent各部份設計:


NDDE Agent整個程式只有1個.cs檔案,算是整個Java ATS裡面數一數二醜又難看的程式,
好消息是,程式算單純,而且一段一段,分得還算清楚。

程式碼說明:
Admin Server、Http Admin Server各自是一個獨立的Thread,
Admin Server和Http Admin Server都是以TcpListener實做。

Data Server就是NDDE Agent的主程式。

NDde和EWinner的B2CAPI,它們都是設計成Event Handle的形式,
因此裡面像是objEwinner_OnDataResponse、DDEOnAdvise,
就是它們各自的Event Handler function。

DDE Connect Table和DDE Item Table,為了紀錄所有註冊的DDE連線,
因此設計2個Hash Table,各自儲存所有的DDE Connect和所有的DDE Item,
新增、刪除都會紀錄在這2個Hash Table內,然後才下function去註冊和刪除DDE。

AutoIt程式操作,AutoIt本身大概可以寫上一整篇,
先前為了寫AutoIt版的Stock Server,可以說是遇到很多麻煩,
這裡只是為了啟動點金靈,用的不多,就不細說了,
程式裡面有用到的只有2個片段,用au3為關鍵字查詢,就能看到那段內容。
這2段程式功能大意是:
登入:輸入帳號密碼、按確定、等公告、按確定
登出:關閉點金靈程式、按確定

程式啟動說明:
程式啟動後,畫面如下:

它會顯示NDDEAgent的版本號碼和Admin Server、Http Admin Server、Data Server的Port。

Admin Server指令說明:
確定NDDE Agent啟動後,此時用telnet連Admin Server,如下:

此時輸入help指令,按下Enter,如下:

會看到所有指令的一覽、說明、範例。

Http Admin Server指令說明:
和Admin Server類似,但改為瀏覽器輸入,所有指令的格式都如下:
http://[Server IP]:58892/command?[指令]

例如我這邊的環境:
NDDEAgent的IP是192.168.1.12
我要呼叫help指令,瀏覽器輸入如下:
http://192.168.1.12:58892/command?help

截圖如下:

Data Server說明:
程式啟動後,telnet到58888 Port,畫面如下:

當有DDE訊息進入後,就會直接收到,例如:


DDE語法說明:
在NDDE Agent中,針對DDE註冊,需要下指令,語法如下:
add conn DDEService|DDETopic
add item DDEService|DDETopic!DDEItem
add item DDEService|DDETopic!DDEItem
add item DDEService|DDETopic!DDEItem

以點金靈要註冊「中鋼」(2002)的成交價格、開盤價格、最高價格為例,如下:
add conn EWinner|RQ
add item EWinner|RQ!2002.Price
add item EWinner|RQ!2002.Open
add item EWinner|RQ!2002.High

截圖:


要刪除,直接刪除Connect,我記得程式會自動把item統統刪掉。
remove conn EWinner|RQ

程式需求:
執行時,程式需要下面幾個.dll檔案:

  1. 元大寶來的B2CAPI dll檔
  2. AutoIt dll檔
  3. Ndde dll檔和1個xml檔案
  4. 程式使用前,要確定AutoIt的dll有正確註冊
  5. 目前點金靈自動登入的分公司選擇無效,需手動勾選「記憶帳號」,並成功登入,讓點金靈記住分公司資訊後,才能使用NDDEAgent做自動登入的功能


使用平台是選WinXP,理論上應該適用大部分Windows系統,
選WinXP的原因是,它的使用空間最小、系統資源吃得最少。

為何不用Win2K?Win98?
之前一直是Win2K,但Win2K現在證券軟體支援很差了,只能換到WinXP。
Win98,嗯......VirtualBox的支援都很差了,不用說證券軟體了。

程式下載:
講這麼多,程式在哪?程式碼在哪?
http://www.openfoundry.org/of/projects/1818

股市自動交易系統(半完成品) - 設計發想與架構

隨著台股上9000點,加上最近比較沒這麼忙,
又想起了一直想做的程式交易。

在先前,為了做程式交易,我陸續自行開發了許多程式交易的程式和元件,
但最終因為一個人人力有限無力負擔,加上回測部份一直沒有完成,
操作演算法一直沒有頭緒,因此就讓它自然荒廢了,
我想,網路力量大,把它Open Source出來,也許會有比較多人想一起來寫,
這篇,會先介紹這個未完成系統的架構與設計發想。

程式交易架構:
程式交易系統千千萬萬,但不外乎下面這幾個元件:


設計發想:
在開始設計時,我有幾個需求:

  1. 希望在Linux上進行程式交易
  2. 希望能夠有彈性,方便開發和修改交易演算法
  3. 全自動操作,免人為操作
  4. 最好有類似證券軟體的GUI可以回測


因為上述條件,我開始進行設計。

設計:
即時資料源:
在台灣,台灣的證券公司普遍提供Microsoft DDE做為即時資料源,
我不得不說,DDE這東西已經快變成骨灰了,Microsoft自己都不太維護這東西了,
證券公司是該改改了吧,
人家國外直接有IB提供完整的API,可以抓歷史資料、即時資料、下單,
靠DDE是要打混摸魚到什麼時候?
離題了.......

因為DDE是Microsoft的東西,Linux一定不支援,
加上要做到全自動,自動啟動證券軟體的開啟、登入是必要的,
因此針對Windows的DDE,我做了下面的設計:

這個設計簡單說,就是在Windows上寫個Agent,
Linux端透過Agent取得資料源的資料,
Linux端也透過Agent控制證券軟體的操作。

歷史資料:
歷史資料主要就是Parse證交所網頁的每日資料和歷史資料,
當然也可以從證券軟體中把歷史資料匯出到Excel後取出。

歷史資料的儲存,設計上是儲存到mysql,
但理論上,因為它沒有用特殊語法,因此它應該可以支援各式SQL Server。
設計如下:

下單:
在元大寶來有提供B2CAPI,可以透過寶來點金靈進行下單,
但和取得即時資料有相同的問題,它只支援Windows,不支援Linux,
因此設計上和取得即時資料相同,都要透過Windows的Agent進行操作。
設計如下:

交易演算法:
這裡的交易演算法,是我的稱呼,它其實就是俗稱的「下單機」、「自動交易程式」...等。
設計上就是JavaATS Server(ATS為Automated Trade System的簡稱)。

它的設計發想包含2部份:

  1. 它是Time Trigger的系統
  2. 演算法容易開發、維護


Time Trigger設計:
在設計時,它的定位不是高頻交易系統,也不是當沖系統,
它的設計比較趨近於短線操作(精確度:分鐘),或中長線操作(精確度:天以上),
因此它並不是根據成交觸發的Event Trigger設計,
它的設計是以Time Trigger的方式,定時觸發執行。

它有2種Time Trigger觸發執行,
一種是以秒為單位的定時觸發,
另一種的執行週期最短執行為每分鐘,最長可以是數天甚至數週。

為了提供彈性的定時執行計畫,我以Linux的crontab設計為發想,設計了下面這樣的語法:
*_*_*#* *:*/1

[年]_[月]_[日]#[週] [時]:[分]

語法和crontab類似,
可定義「某年」、「某月」、「某日」、「某周」、「某時」、「某分」。

和crontab一樣,它可以定義週期執行,例如:
*_*_*#* *:*/1

*/1     表示每分鐘執行

和crontab一樣,它可以定義多個特定時間點,例如:
*_*_*#* *:1,5,10,15,20,25

1,5,10,15,20,25     表示每小時的1分、5分、10分、15分、20分、25分執行

和crontab一樣,它可以用「*」定義是否mask該時間設定,例如:
2014_7_*#* 13:0

2014年7月,每天的13:00執行

這樣的設計理論上可以提供極大的彈性,規劃出任何時間的週期執行。

這個設計的缺陷是,它不支援以秒為單位的短時間觸發,
因此,我另外設計了Interval Timer Trigger,可以設定固定間隔幾秒觸發執行。

演算法設計:
在我一開始找程式交易相關資料時,注意到下面幾個是大部分人的開發系統:

  • Excel
  • HTS

Excel:
Excel因為有大量Cell和方便的圖表產生器,
最重要的是,它有方便的VBA可以開發,
因此是很多人入門的首選。

HTS:
HTS實際上裡面提供了Power Language的程式開發功能,
可以簡單的開發出交易程式,搭配HTS內提供的圖表,可以方便的回測。

再經過一段時間的摸索後,我得出一個重要結論,
演算法不好開發,等於無法使用。

想想看,我希望有個MA(移動平均)資料,卻要寫出2頁程式碼,
這應該沒人受得了,
但偏偏傳統的通用語言C/C++、Java、Python、Perl、PHP...等,
都不是針對自動交易設計,一定是難用又難受,
光想到寫個簡單的邏輯演算法,卻要Compile再Compile,
如果是C/C++,甚至還要處理new、free、delete的問題,嗯.....很痛苦.......

但矛盾的是,大部分的程式資源,又都集中在C/C++、Java...等通用語言上,
像Power Language這類語言,沒有提供的功能,你就是無法使用,
試想看看,一個開放的競技場,不限定使用的武器,
但你用Power Language,表示你只能用長矛、用盾牌、用護甲。
槍呢?對不起,沒有提供
劍呢?對不起,沒有提供

我認為在先天上就輸了,你用它可以贏過沒有裝備的人,
但對於有能力自製武器的人而言,你先天就輸了,因為你缺乏武器........

為此,當時我找了一些Open Source的Script,
加上Java ATS一開始是用Java設計,
因此後來選定了BeanShell做為開發。

BeanShell本質上就是Java,理論上所有Java SDK都可以透過BeanShell呼叫執行,
BeanShell以Script方式執行,可以很方便的在修改後直接執行,
不用經過Compile,Java不用解釋了,它不用free/delete,
這能夠很大程度的降低開發門檻。

剩下的麻煩是呼叫方式,我希望簡單的呼叫個function,
就能夠達成,例如:
BUY(0050, 1);           //買0050,1張

因此,我當時決定寫個API,就叫做StockAPI,
提供些會用到的function,能夠方便的呼叫使用,
裡面實際上就包裹了實際操作的麻煩。

針對上述的2項設計,以及前面的幾項元件,其架構如下:
訊息通知:
訊息通知不外乎就是,
下單後通知自己,已經下單,
成交了通知自己,已經成交,
有危險時通知自己,快點逃命。

訊息通知方式,不外乎有數種IM軟體,包括:

  • MSN
  • Skype
  • GTalk
  • LINE
  • What's App
  • Yahoo Messager


實際上,有提供API的,大概只有

  • MSN
  • GTalk


Line和What's App都沒有免費提供API,Yahoo Messager我沒有使用,
Skype好像有,但之前很少用,現在被Microsoft併購後,SDK是否有提供不清楚。

因此在先前,我先開發了MSN的Client,後來寫了GTalk的Client。

SMS?
SMS要花錢,原則上直接排除。

回測:
很不幸的,回測部份我並沒有找到很好的回測設計方式,
這也是這個系統遲遲無法使用的主要原因之一。

我本來期望的是,能夠類似HTS一樣,下個Draw之類的就能畫出來,
但不幸的,每種資料的資料形式差異太大,
資料的X軸、Y軸標記形式太多,
並沒有一個固定的模式可以動態產生所有想要的圖形,
因此沒有設計出來。

另一方面,回測的作法目前我也沒有概念,
是用類似replay的方式餵資料,或者載入後直接顯示在圖形上,
還沒有想好設計方式,因此回測部份目前沒有任何設計。


2014年2月8日

網樂通開發 第2集 - 網樂通上嵌入式Linux

本篇前言:
這篇會先介紹網樂通上的嵌入式Linux,要玩它、修改它,要先知道它哪些可以改。

本篇開始:
所有嵌入式Linux系統都差不多,大致上包括:

  • BootLoader
  • Linux Kernel
  • rootfs
在網樂通上的嵌入式Linux包括如下:
  • BootLoader:u-boot
  • Linux Kernel:Debian Kernel for 網樂通、ArchLinux Kernel For 網樂通、sh4twbox 0.92 Kernel、網友提供2.6.32.59版Linux Kernel for 網樂通...等
  • rootfs:sh4twbox、Debian、ArchLinux
網樂通嵌入式Linux幾個部份的說明:

BootLoader:
網樂通的BootLoader是使用u-boot,這套BootLoader在嵌入式系統上經常被使用。
網樂通內建的RAM是256MB,但不知道為何,官方的u-boot只開放了128MB,
因此網友修改u-boot程式碼,讓網樂通u-boot能支援256MB。
關於刷u-boot,可以參考:

Linux Kernel:
Linux的驅動程式幾乎都相依在Linux Kernel上,
要讓網樂通支援其他硬體,像是usb webcam、usb wifi...等,
Linux Kernel都必須要自己重新編譯。
另外,針對Debian for 網樂通和ArchLinux for 網樂通,
因為本身有一些Kernel module的套件,所以會需要各自的Kernel,
否則一般而言,在網樂通中,Linux Kernel是可以另外編譯,另外支援。

rootfs:
一般所謂的網樂通刷機,指的都是更換rootfs。
所以rootfs實際上指的就是更換成sh4twbox、Debian、ArchLinux...等不同的Linux系統。

各部份在網樂通的位置:
在網樂通的刷機文件中會提到,網樂通需要至少2個分割區,
第1個分割區必須是FAT32,第2個分割區必須是ext2/ext3/ext4,分割區類似如下:








第1個分割區就是存放Linux Kernel的,內容如下:





第2個分割區就是rootfs,內容如下:

















從這裡可以注意到,除了BootLoader外,
Linux Kernel和rootfs都直接按不同分割區放置,很容易可以區分。

更換各部份:
更換Linux Kernel:
如果我們重新編譯Linux Kernel,要更換新的Linux Kernel,
只要將編譯出來的vmlinux.ub直接覆蓋sda1的vmlinux.ub,
重新開機後就會是載入我們新編譯出來的Linux Kernel。
類似如下:









更換rootfs:
要更換rootfs,最簡單的方式就是參考sh4twbox的教學,
先將產生的rootfs壓縮打包好,接著按照正常刷機的步驟,
在sh4twbox的教學的1.4第2步指定我們自己的rootfs壓縮檔,
它就會幫我們把rootfs解壓縮建立好。


網樂通開發 第1集 - 刷機版本的選擇

這篇開始,我會以網樂通和STLinux為基礎,寫一些自己開發的心得文章,
這篇是第1篇,主軸放在目前網樂通刷機版本的介紹,
因為這系列文章是以開發為主,不會描述刷機的過程,
文章會描述的是如何用網樂通和STLinux進行Cross-Compile,
目標是透過這系列文章,可以將網樂通開發成自己想要的功能主機。

本篇前言:
目前網樂通在網路上文章很多,但有點雜,
我過年前開始玩時,發現有好幾個不同版本的網樂通系統可以刷,
但並沒有太多文章描述這幾個版本有何不同,系統差異在哪。
因此,第1篇目標放在對幾個版本的描述,
在開發時,可以根據目標選擇合適的系統來刷。
這裡要先說的是,ArchLinux我不熟,所以針對ArchLinux的描述並不確實。

網樂通版本:
目前網樂通刷機的版本大致可以分為4種:

  • sh4twbox 0.62版
  • sh4twbox 0.92版
  • Debian wheezy版
  • ArchLinux版

sh4twbox 0.62版:
大本營:https://code.google.com/p/sh4twbox/

sh4twbox系列通常是網樂通第1次刷機的選擇,
事實上,0.92版刷機時用的USB隨身碟本身就是sh4twbox版本。

sh4twbox是以STLinux為基礎的Linux系統,
STLinux則是網樂通使用的SuperH系列處理器廠商維護的嵌入式Linux版本,
sh4twbox是以STLinux 2.3版為基礎修改而成,
目前STLinux2.3已經停止開發,因此sh4twbox也建議不要再使用sh4twbox 0.62版。

sh4twbox 0.92版:
大本營:https://code.google.com/p/sh4twbox/

sh4twbox 0.92版是以STLinux 2.4版為基礎的Linux系統,
是目前原廠正在維護的嵌入式Linux版本。

STLinux設計上就是嵌入式Linux,
相對於ArchLinux和Debian來說,它有幾個優點:

  1. 系統小使用資源少:最直接的就是開機時間比較短,系統運作比較順,反應比較快
  2. Cross Compiler環境:STLinux原廠提供了完整的Cross Compile環境供開發
但相對的它有幾個缺點:

  1. 現成的應用程式少
  2. 嵌入式系統和桌上型Linux環境差異較大

Debian wheezy版:

我個人熟悉的Linux其實是Debian/Ubuntu,但對於Debian在sh4處理器上的支援性,
我真的是覺得爛到爆了。

目前網樂通上,因為有Debian for 網樂通的善心人士協助,
網樂通上的Debian能跟上目前Debian的Stable版本Wheezy版,
從網站上可注意到,
他們現在正努力的讓Debian的下一個版本(目前是測試版)能支援網樂通。

相對於STLinux,Debian wheezy版有幾個優點:
  1. 現成的系統整合較好:像X-Window、幾套X-Window管理器都能順利運作
  2. 和PC版Debian開發環境相同:開發環境相同,開發上比較沒障礙
但它有幾個致命缺點:
  1. 系統大,使用資源多:最直接感受到的就是開機時間長,操作時反應慢
  2. 套件數量少:Debian for sh4的支援性差直接體現在套件數量上,它的套件數量相對於ARM版本就少很多,跟PC版Debian根本沒得比
ArchLinux版:

sh4twbox的作者覺得ArchLinux是網樂通比較好的選擇,因為ArchLinux套件數量多,
又是用PKGBUILD方式針對不同平台build,因此理論上要安裝套件,
只要透過ArchLinux的PKGBUILD就能建立出網樂通版的套件,
並安裝在網樂通上。

但可惜的是,ArchLinux我不會用,
對於PKGBUILD的使用方式以及套件的建立環境不會架設,
於是就.......

因為不懂ArchLinux就不多做評論了,這裡僅列出我刷機後使用時的感覺:
  • 開機速度比STLinux慢,但比Debian快
  • 系統的反應比Debian快

buildroot網樂通系統:
我自己在過年期間,有用buildroot建立過網樂通系統,並成功刷機執行。

buildroot可以簡單的建立出整個嵌入式系統,
DD-WRT、OpenWRT都是以buildroot為基礎修改的,
buildroot系統的優點是:
  • 系統小
  • 速度快
缺點是:
  • 幾乎沒有提供開發環境,只有執行環境
我自己使用的感覺是,buildroot系統比STLinux快,環境更小,
如果是buildroot有提供的功能,像是QT的Transmission。
直接使用buildroot說不定更好,系統資源更省。

我會在Cross Compile環境介紹後,介紹buildroot建立網樂通系統方式。

2014年2月5日

網樂通硬改,更換大容量或高速USB DOM(免焊接)

網樂通內的儲存空間主要是靠USB DOM,
要加大空間或者更換USB DOM網路上都能搜尋到文章,
文章原則上有3類:
  1. 直接用USB隨身碟插在屁屁
  2. 拆機後,把USB DOM的接腳另外焊上USB隨身碟
  3. 拆機後,原來的USB DOM焊接個USB接頭當隨身碟
我的問題:
內建的USB DOM真的有夠爛,
速度慢也就算了,刷一刷竟然被我刷掛了。

我的那個USB DOM死法真的是沒救,
它應該是USB DOM最前面儲存Partition的block壞軌了,
每次重新建立Partition,重開機Partition就消失了,
因此,它無法正常的刷Linux,
所以,我需要更換USB DOM。

因為這個原因,第3種教學文章直接沒用;

第1種作法不錯,但我的目標是Printer Server,
後面的USB需要接印表機,沒辦法用;

第2種作法不錯,但我技術差不想動電烙鐵,
怕下手後沒處理好,反而把元件燒了。

最終我找到了折衷的辦法,也就是我要發的這篇文章的作法。

我的作法:
網樂通上面的USB DOM,
接在板子上的4個pin腳其實就是杜邦端子的公頭,
網路上的教學是,
直接在端子和板子的焊接點上,焊接一個USB隨身碟,
但其實不用,只要自己剪條USB線,
在USB線做出4個杜邦端子的母頭,
就可以直接插入,完全不用電烙鐵焊接。

所需工具和零件:
  1. USB線一條(要有USB母座)(越短越好)
  2. 剝線鉗一把
  3. 杜邦端子接頭數個(至少5個以上,以防失敗)
  4. 4P杜邦端子座1個
  5. 豆子隨身碟1個(可選購4G、8G、16G、32G)
過程:

1. 首先準備一條有母頭的USB線,留下一小段,剪斷它並去皮,如下圖:


 2. 用剝線鉗接USB的4條電線都做好杜邦端子,這部份是最麻煩的,完成品如下圖:

3. 將網樂通上的USB DOM拆下後,最重要的,把它原本的杜邦端子座移除,如下圖:

 4. 將USB線上面的杜邦端子套上杜邦端子座,插上網樂通的端子頭,如下圖:
這裡注意到,一定會有疑問是,線怎麼排列,5V方向在哪?
USB線的順序是(由左而右):
黑 綠 白 紅

如下圖所示,
左邊是網樂通後面,右邊是網樂通前面,
電源接頭在左下角,網路接頭在左上角,
此時,USB線的紅色靠下。

5. 完成後,按網路教學用背後的USB隨身碟開機,刷Linux,應該就可以看到新的USB DOM。

網樂通開發文章計畫開始

利用過年期間,把網樂通的開發玩了玩,雖然還沒玩完,
但對於網樂通的STLinux開發有了一些心得,
我想後續應該可以針對網樂通sh4 STLinux的開發寫出大概4~5篇文章。

文章大概會從比較基本的網樂通目前網路上有的Linux Distribution介紹,
大概描述STLinux、ArchLinux、Debian在網樂通上我認為的區別。

接著會把主軸放在網樂通的STLinux如何開發。

如果我的Printer Server順利的話,
最後應該可以以Printer Server為例描述過程。

2013年12月22日

核能發電的未來-放射性同位素電池(核電池)?

核能發電有諸多的問題,
最主要的問題是輻射線容易外洩和核反應有可能不受控制。

但想想看,衛星、火星車也都用核能,沒聽說衛星或火星車需要更換燃料棒,
原因就在於它們使用的是核電池。

我的想法是,如果把目前大型的核子反應爐縮小,
改成發電效率比較好的核電池(目前核電池發電效率很差,網路上說只有8%~10%),
一個發電站內存放100顆小型核電池,
每顆核電池的核元素封裝在中心,無法開封、更換,
但保證能持續產生穩定能量20年或30年,
核元素的外部透過熱電發電機或者核元素放射的電子發電。

如此一來,每次只需更換核電池的某些元件,
像熱電發電機可能會有壽命需要更換,
核心核元素不用更動,時限到了頂多也是整顆核元素中心更換,
從頭到尾不會有輻射外洩或者核反應無法控制的問題,
雖然每一顆提供的電量少,但可以用大的數量來補足,
發電站可能以城鎮為單位,例如各縣市一個發電站,僅供應單一城鎮電力即可。

我認為這種作法不錯,
同時可以避開核能發電廠的問題,
以及有效利用核能發電的優勢。

我認為,目前的核能發電方式的確蠢了一點,
利用核能產生熱能,然後燒鍋爐水,
利用鍋爐蒸氣推動汽輪機發電,
整個結構除了改用核能產生熱能之外,
跟汽油、瓦斯、煤炭燒鍋爐水發電一模一樣,
我認為這不是先進的發電方式,
因為光中間
核能轉成熱能→熱能燒開水→水變水蒸氣→水蒸氣推汽輪機→汽輪機發電

每個環節事實上都有轉換效率問題,
任何一個環節異常,就會導致發電異常,
前段異常,甚至會造成輻射外洩,
而為了防堵中間的問題,
目前的手法卻是在每個環節增加更多的安全機制,
在異常出現時立即中斷某個環節,
但異常何其多,有辦法全部考慮到嗎?
那麼,是否該重新思考核能發電的整個流程是否合理?

我贊成核能發電,我認為目前人類並沒有發現比核能更強大的能源,
要解決人類能源使用的問題,我認為目前核能還是唯一解,
但我認為是時候發展新型態的核能發電方式了。

PS:
核電池不會反應過度的原因是,
核電池是讓核元素自然反應,讓它自然的衰變,
並不會控制它的燃料或反應,
優點是它的衰變速度慢,反應速度只會持續下降,持續時間長;
但缺點是他的能量產出較少。

2013年9月29日

硼酸蟑螂藥餌研發成功(內有蟑螂照片,不喜勿入)

自從大樓一樓開快炒店後,家裡的蟑螂每年呈現倍數增加,
加上家裡廚房設計不良,因此蟑螂非常囂張。

為了蟑螂問題,我做了一些措施,但成效不大,
加上家裡人並沒有良好習慣,且都沒有共識,
近兩年家裡開伙,情況更加嚴重。

這次嘗試使用蟑螂藥餌,但試作了多次都失敗,
這次應該算是接近成功的。

有圖有真相,先來幾張半夜蟑螂覓食的照片。
地點:客廳
放置時間:一開始(把蟑螂趕過去後)

地點:客廳
放置時間:15分鐘後

地點:客廳
放置時間:45分鐘後(全家都來了)


地點:客廳
放置時間:2小時後(鄰居也來了)


 實際實戰,放置於廚房瓦斯爐縫隙。
地點:廚房瓦斯爐縫隙1
放置時間:2小時後
左邊那隻蟑螂實在太搞笑了,整個身體不平衡,嘴巴還趴在藥餌上吃。
旁邊那是.....蚊子嗎?你來搶什麼鏡頭啊.....

地點:廚房瓦斯爐縫隙2
放置時間:2小時後




幾次蟑螂藥餌的製作,最大的問題並不是蟑螂不吃,
最大的問題是藥餌乾掉硬掉的問題。

網路上硼酸藥餌的教學都是說用糖水和,
但我發現用水和,當藥餌放了1星期後,會因為水乾掉,
整個藥餌變成麵粉糖塊,蟑螂根本啃不動,
所以還是會零星看到蟑螂爬過去,但碰兩下就走了,
顯然太硬啃不動。

後來參考了蟑螂炸彈作法後,發現可以用果糖替代,
因此這次不用水,完全改用果糖,效果看起來不錯。

至於為何不做蟑螂炸彈?
蟑螂炸彈不用硼酸改用農藥,
農藥傷殺力太強了,我家蟑螂都從廚房來,
難保蟑螂和農藥不會變成晚餐的一部分。

製作材料:
  • 低筋麵粉
  • 砂糖
  • 豐年果糖
  • 硼酸
  • 排油煙機廢油

製作比例:
  • 麵粉20kg
  • 砂糖20kg
  • 硼酸20kg
  • 排油煙機廢油數滴(我大概滴了10滴左右,一小佗的我算一滴)
  • 果糖比例未知
製作方法:
  1. 用數位秤邊量邊放入麵粉、砂糖、硼酸,數位秤很便宜,網拍買,一個不到NT 300元,非商業用即可。
  2. 攪一攪或倒一倒把麵粉、砂糖、硼酸混在一起
  3. 滴入排油煙機廢油數滴,攪一攪
  4. 滴入一些豐年果糖
  5. 倒一些豐年果糖在手上,然後用手抓一堆有結塊和沒結塊的混合粉末
  6. 在手上擠一擠、捏一捏,捏成球形,中間捏不成型時,就倒一點豐年果糖在手上或手上的混合粉末
最後捏出來的圓形,應該會是像下面這張照片的球形。














做好後,就把捏出來的幾顆球放到保鮮袋,如下照片。













任何時候需要時,就把手指伸進去,捏一點出來擠成小圓球,
放在蟑螂出沒或覓食的地方即可。

2013年9月26日

「阿呆的blog」新轉址「ycfu.blog.mypc.tw」

我註冊了新的網域「mypc.tw」。

阿呆的blog之後會轉址到「ycfu.blog.mypc.tw」,
原先google提供的ycfunet.blogspot.tw仍可繼續使用,
它會自動轉過來。

這次註冊到的網域「mypc.tw」有興趣可以google看看,
我只能說,我能註冊到真的是非常的幸運。

2013年8月31日

可惡的山水米混充越南米

我很少發新聞類的文章,
翻看blog,早期還會有一點新聞文評論文或政治文,
但很久沒有了,這次真的是想提一下。

在台灣買米,要不被混充越南米、泰國米很難,
看看這次上新聞,越南米、泰國米的價格根本是台灣米的一半,
混越多賺越多。

但吃米會知道,泰國米、越南米不好吃,
混太多就很容易被吃出來,
所以關鍵問題在於「混充多少」。

往往買米時會發現,一包米或一斤米有不同價格,
價格高的往往「比較好吃」,價格低的往往「比較難吃」,
明明都是台灣米,怎麼還有好吃不好吃之分?

其實價格不同的關鍵,在於「被混充多少外來米」,
混充多,比較不好吃,就價格低一點,
混充少,比較好吃,就價格高一點。

但可惡的地方在於,台灣本身產米,而且是「生產過剩」,
農田甚至需要休耕。
每次這類問題上新聞,原因都被歸咎在現代人飲食習慣改變,
改吃麵線、麵包這類麥製品,稻米使用量自然就減少了。

但問題是,當我們吃飯,甚至買「台灣米」,
買到的卻是一堆泰國米、越南米,
一般消費者怎麼吃得出差異?
當大家自以為我們在吃台灣米,減少稻米生產過剩時,
誰知道其實還幫泰國、越南賺了外匯?

在細想這問題,米商為了賺錢混充低價外國米,
但有沒有想過因為你們的舉動,會不會造成稻田休耕?
自產米就已經生產過剩了,還使用外來米,這是正確的行為嗎?

在目前,一些農友都會自產自銷,可能透過網路,或者透過電話,
然後直接宅配到家。
這類的自產自銷幾乎可以確定百分之百是台灣的台梗9號米,
沒有混充的問題。

如果有要幫忙稻米生產過剩的問題,除了多吃飯之外,
直接由產地透過網拍、電話、宅配買米,可能是好辦法。

2012年12月3日

投資就不用工作?

這篇其實算是延續上一篇「%百分比的魔力」。

當景氣大好時,尤其是2008年金融風暴前,有一些人一些言論會出現,
多半是「唸甚麼書,炒股(投機)就能賺大錢啦!」,
「工作幹嘛,炒股(投機)都賺得比工作多啦!」。

而從上一篇我的想法中,我認為投資的資金大到一個程度後,
基本上工作賺錢已經沒有意義了,
因為你投資獲取的獲利,大於你工作獲取的獲利,
那麼你就不需要為了賺錢生活而工作。

但在上一篇有一個重點,投資的獲利,是根據本金決定的,
本金越大,獲取的獲利會等比增加,
可惜的是,每個人出生在這個世界上,
落地的當下,身上擁有的本金並不相同,
富二代之所以叫富二代,就是因為他們一出生,
身上就是有非常驚人的財富可以當本金。

正如前面說到的,大部分生產者都不是資本家,都沒有錢,
生產者生的孩子,一落地,就跟你、我一樣,
甚麼都有,就是沒有錢,
那麼,你、我要靠投資賺錢過生活,基本上是沒辦法的,
很簡單的計算公式:
0 x 3% = 0

就算今天給你30%獲利的機會:
0 x 30% = 0

基本上,在現在這個資本的世界中,
沒錢就是沒有進入「%百分比」世界的機會,
因此沒錢的人靠投資,是沒辦法的。

但工作不同。
工作和投資的區別是,投資是用錢賺錢;
工作則是用身體(勞力、體力、精力)賺錢。

這表示,工作賺錢不用成本(著裝、知識、技能、談吐...等在此不考慮)。
因此在一無所有時,工作是唯一獲取獲利的方式。

如果用工作產生獲利這樣的方式套入到「%百分比」的世界中計算:
假設今天月薪是1000元(假設成本為1)
1 x ?% = 1000

你會發現,靠工作賺錢,獲利高達1000倍,
因為實際上,工作是靠身體,不是靠本金,
套入很低很低的本金後,獲利非常大。
因此,在沒錢時,還是乖乖工作賺錢,沒錢時候投資的獲利,
不可能高過工作靠身體賺得錢。

但從前一篇來看,靠工作賺錢,當生產者,永遠只能被投資者剝削,
且永遠無法出頭,那怎麼辦?
所以比較好的辦法是,在年輕時努力工作賺錢,
賺來的錢進行穩當的投資,
此時的身份既是「生產者」也是「投資者」。
當本金增加後,本金多到足以產生足夠獲利(現金流)進行生活,
此時就能夠退休了,
而退休,實際上就是轉換身份為「投資者」,不再是「生產者」。

此時如果不退休繼續工作,工作的目的也不再是為了生活,
那麼工作時的心情、心態也會不同。

因此結論是,
不能因為投資就不工作,只要投資的現金流沒有建立完成,
是無法依靠投資養活自己,
此時當「生產者」工作能獲得的獲利是遠高於投資的,
當投資的本金大到某個程度後,
就能夠將自身的角色進行轉換,轉換成「投資者」,
更好的方式是,
在工作同時存錢和投資,一邊當「生產者」一邊當「投資者」。

最後一點,
現實世界總是不這麼美好,
為了吸引大量的「生產者」貢獻金錢,
會將金融商品包裝成奇奇怪怪的東西,
這些東西,10個有9個半都不美好,多半都有陷阱,
但介紹時,從來不會提它們的陷阱,只會提這些商品的好處,
甚至許多詐騙集團,擺明就是詐騙,
賣的東西連金融商品都不是,只是偷竊,偷「生產者」的錢。

對於投資,我只能說,
金融世界裡,「獲利」都伴隨「風險」,高獲利就是會有高風險,
當今天你被推銷金融商品時,它告訴你獲利的當下,
請仔細檢視它的獲利和風險,
獲利,請和「定存利率」比較,風險則要自己評估,
當獲利很高時(比定存利率高很多),請了解它的風險,
或者它根本是詐騙集團。

現在這個世界,沒有人會好心的推薦你穩賺不賠的投資,
只有自己了解風險,才能知道自己要的是甚麼投資。

%百分比的魔力

其實滿慶幸我在經歷金融風暴時,有開始買股票,並注意相關訊息,
當時的許多新聞或節目,多半會針對金融風暴給予評論,
讓我可以對投資理財有一點點認識,
這邊提出我對投資理財的第一個有趣的了解,
我取名叫「%百分比的魔力」。

在投資理財中,一句話經常被提出來,那就是「複利的威力勝過原子彈」,
但其實我認為,真正厲害的基礎其實是「%」。

在投機和投資中,如果稍微注意會發現到,
所有的賺賠都不是用「金額」,而是用「%」,
舉個例子:
一家公司股票每股單價為10元。
今年公司賺錢,給股東每股0.3元。
這時候小朋友都知道,這家公司股票的股息就是3%。
假設我有1,000股,以每股3%來計算,表示我可以獲得300元。
但如果我有10,000股,同樣以每股3%來計算,
表示我可以獲得3,000元。

從上面的例子可以發現,不用金額而用%百分比來計算的原因是因為,
每個股東持有的股份數量不同,因此獲得的股息也會不相同,
從這樣的角度來看,整個過程和計算都是非常合情合理的。

從%百分比的角度來看,利息的金額多寡沒有意義,
真正有意義的是持股單位和%百分比,它才真正決定了利息的金額高低。

1. 「%百分比」的世界,沒有獲利成本,沒有資源上限,而且大者恆大
從這裡可以推想出一個現實,以%百分比為單位的世界中,
本金(持股單位)越多,獲得的利息會等比例增加,
以上面的例子來說,
持有1,000股和10,000股相比,獲得的股息同樣差10倍。
這說明了,在%百分比的世界中,是大者恆大的,而在金融市場中,
基本上就是個%百分比的世界,而這裡不考慮內線...等不正規的投資方式,
在這個世界中,就是本金越多,獲利越大。

現實的世界是甚麼?跟%百分比的世界不同在哪?
現實是,我們都生活在地球,所有資源都是有限的,
田地是有限的,人力是有限的,
更白話的說,一個人一天就是只有24小時,一個人的精力就只有那麼多,
全地球田地的耕作面積就是這麼多,全部的一切都是有上限的,
但按照%百分比和比例,在%百分比的世界中,
只會有非常多的本金(持股的資金),
並希望按照%百分比獲得非常多的利息,但沒有上限。

例如:
今天耕作,1畝地可以產生等值10元的穀物,按%百分比來看,
我只要有100畝地,就可以產生等值1,000元的穀物,
我只要有1,000畝地,就可以產生等值10,000元的穀物,
所以我只要增加耕作面積,就可以賺到非常非常多的錢,
真的是這樣嗎?
事實上,現實是,當你有1,000畝地時,你無法單憑自己的力量耕種,
必須要依靠額外的人力,或者聰明的用機器,
但不論哪種方式,成本都會增加,
而且,1000畝地之後呢?10,000畝地?還是1,000,000畝地?
耕地從哪裡來?

但如果換一個角度,我們用投資的角度來看這件事情,
我們先不考慮物以稀為貴這件事情,單就%百分比來看。

例如:
今天某公司股票每股100元,我可以花100元買1股,也可以花100,000買1,000股,
我也可以花10,000,000,000買100,000,000股,
當公司賺錢給予3%股息時,獲利可以等比例的增加,
1股的只能得3元,但100,000,000股的可以得300,000,000元,
而且中間沒有任何額外的成本,
沒有耕地限制、沒有人力限制、沒有機器維護,油耗成本。

2. 投資者是在「固定%百分比」的世界計算獲利,生產者是在「固定金額」的世界計算獲利
目前的世界上,大部分的人努力花費勞力,體力,腦力,精力在進行生產,
而這些生產產生的獲利,就如同上面耕地的例子,它是用「金額」計算的,
而不是用「%」計算的。
例如:
我每天認真工作,一個月領取1000元。
我這個月加班,因此領取1200元。

但不論是1000元,或是1200元,都是用「金額」計算,不是用「%百分比」計算,
當你用「固定金額」來計算獲利,而投資者用「固定%百分比」計算獲利時,
你會發現,利基根本不同,不管你怎麼努力,你的最大獲利不可能和投資者相比。

3. 投資者的資金,不會腐爛變質,但穀物有保存期限
投資者進行投資時,它的資金是沒有時限的,舉例來說,30年前的黃金放到現在,
它還是黃金,並且可以繼續增加甚至增值,
但30年前的穀物,只會因為時間而腐爛,因此,對於投資者而言,
錢是會繼續滾錢,讓本金更大,而不會像生產者產出的穀物一樣,放著就爛了。

因此我認為,在現在這個時代,原物料嚴重上漲,全世界貧富差距大,
一個關鍵的原因就是,富者幾乎都是投資者,它們利用%百分比的魔力進行賺錢,
而窮者都是生產者,它們利用「固定的金額」在賺錢,
富者透過投資,將「金額」與「%百分比」間的差值賺到口袋中,
並用相同方式製造無限迴圈,讓這個世界富者更富,而窮者更窮,
並且窮者還在不斷的幫富人賺取大量金錢而不自知。

更恐怖的是,這整個金融世界的運作法則,已經是目前全世界的共通法則,
所有人都認定這一套法則是正確的,並繼續的在運作中
(事實上,歐美為主的資本主義運作這套法則到現在,
還是世界經濟的中心,
這表示目前全世界大部分的人都還是認同這樣的運作法則)。

最後一個問題是,
我們在這樣的世界裡要生存,要當投資者還是生產者?