2017年12月17日 星期日

太陽光電設置班第二課

昨天二哥要上 APCS, 因此提早 20 分鐘於 08:10 出門, 到鳳中後再往回到正修上太陽光電課程, 時間剛剛好. 今天主要是講模組底下小配電箱箱體可撓金屬管 + EMT 管接頭組裝與配電箱箱體底下的 PVC 管配管, 也就是水電工的部分.

早上都在頂樓實作, 可撓金屬管接頭組裝只要按順序套接即可, 主要是防水塑膠圈方向要對. 接著是重頭戲 - 六分 PVC 配管, 主要就是 L 形彎管, 擴管, 小 S 彎曲, 以及喇叭口, 其中 L 形彎管與小 S 彎曲比較難, 助教先示範, 然後叫我們先用短的 PVC 管練習, 熟練後再鋸 133cm (獨立型) 或 153cm (並聯型) 長管來烘烤彎管.


剪裁六分 PVC 管

烘烤軟化 PVC 管

使用擴管器擴管

製作喇叭口 (防割傷電線)

完成


我利用最後半小時實際製作了獨立型的 U 型配管, 發現其實只要噴燈不要太大火勻勻地加熱到管子軟化彎曲, 貼著模板上的線用乾手套揉一揉凹到的地方就能做出漂亮的 L 型彎管與小 S.

下午是教室課堂課, 老師先介紹 MC4 耐候線接頭, 這是用來將模組的電力接取到配電箱, 需要使用撥線鉗用 3.5 孔撥開外皮, 再用壓線鉗將接線與公針母針壓合起來 (公針對母頭, 母針對公頭) :





接著是介紹接線圖, 下周要開始學畫配線圖. 雖然線路很簡單, 但這部分我現場看配線總是烏煞煞. 最後老師講了太陽能板發電原理, 原來將太陽能板短路不會燒掉板子, 因為它是電流源!

2017年12月13日 星期三

高師大新式校友借書證

昨天回母校圖書館還書, 館員說舊借書證只能用到年底, 之後必須換新借書證, 採年費制, 半年 600 元, 一年 1000 元, 終身 8000 元. 可借 20 冊書籍, 視聽資料, 以及開放線上續借服務. 我考量目前使用率不高, 因此可能暫時不辦新卡, 需要時可隨時上圖資處網站線上辦卡, 匯款後等待取卡即可 :

新式校友借書證線上申請系統上路
新式校友借書證線上辦卡

但若只是入館閱覽, 則只要綁定悠遊卡即可, 於是請館員幫我先綁定具悠遊卡功能的聯邦信用卡, 明年以後只要持卡即可入館閱覽.

2017年12月12日 星期二

買實戰 R 語言預測分析 + 大數據時代的演算法

暑假時在母校高師大圖書館找到這本強國人游皓麟寫的 "R 語言預測實戰", 由於此書為數學系指定參考書無法預約, 故請圖書館幫我從燕巢調借過來, 但是只能借三天就必須還. 這本書博客來賣 474 元, 不過目前無存貨 :

http://www.books.com.tw/products/CN11390085 $474


Source : 豆瓣


不過露天倒是買得到 :

# 【偉瀚 程式04TL】全新現貨 R語言預測實戰 兼具效率和價值的雙重屬性 $379+70
# 【wen2018】9787121298547 R語言預測實戰 $446+100

此書著重在預測演算法的 R 語言實作, 實用性很強. 這幾天看了一下手邊的 R 語言書籍, 想起這本書, 發現這本去年出版的書已經有繁體中文版, 但書名改為 "實戰R語言預測分析 (松崗 2017/11 出版)" :

Source : 誠品


打電話問明儀有現書, 由於昨晚公司系統切換加班今早補休, 於是中午就跑去買這本書, 原價 520 打 75 折是 390, 另外也買了 "大數據時代的演算法 (松崗, 2017/7 出版)", 原價 400 元打 75 折 300 元, 兩本合計 690, 反正昨晚有加班費, 揮霍一下買兩本書犒賞昨晚加班的辛勞, 呵呵.

2017 年第 47 周記事

本周研究重心轉向放在鄉下家裡的 Pi 3 外網遠端存取問題, 經過兩個禮拜斷斷續續實驗測試, 終於完成長久以來想做又一直沒時間實行的計畫, 也為我的居家物聯網控制中心開啟第一道門. 雖然高雄家中因為使用社區網路無法複製這項實驗 (無法在社區網路路由器防火牆打洞), 但也不是完全沒辦法, RealVNC 的 Cloud Connect 聲稱無須打洞也能跨越 Internet 進行遠端存取, 這有待研究過後再來測試.

上週五阿英說表哥想回鄉下看舅舅, 但因她前一天剛從玉山回來 (能抽到排雲超羨慕), 手腳痠痛, 所以改這周日, 但直到周六都沒再連絡我還以為不來了. 週日去市集買菜時看 Line 才知他們一早已出發正下國道, 聽我說要去看阿蘭, 就要求一起去, 所以我這禮拜就沒順路去圖書館挖寶了 (其實越挖越多, 接下來幾周要做個心得摘要, 趕緊拿去還). 這次亞晴與裴凡也一起下來讓爸非常高興, 他說前兩個禮拜就有在想他們三兄妹, 沒想到他們就突然說要回鄉下看看.

週六晚上又被小舅媽叫去吃牛肉麵, 本來也請了小舅的同學, 但因為小番茄趕出貨, 得忙到晚上十點, 沒辦法來. 小舅說明年他打算就維持現在菜園的 100 坪規模, 只供應親朋好友即可, 沒有要另租地擴增種植面積, 因為不請人的話靠自己是忙不過來的. 其實務農沒有這麼輕鬆, 小舅說才種 100 坪, 光是種苗, 肥料, M 型架, 網子, 農藥等加一加成本已近 10 萬元, 難怪要打消原本要擴大種植的計畫了.

週六開始去上太陽能職業工會辦的太陽能設置訓練班, 內容是比照乙級技術士考照教學, 但我只是要去學習如何自行安裝標準的太陽能設備, 並沒有打算要考證照, 因為我又不是要從事這一行. 除了學知識與技術外, 其實去上課可以認識這一領域的朋友也很不錯, 上課回來後同學群組就很多人 PO 名片了, 職業工會的理事長還是我們高師大校友哩, 也是現任校友會理事長.

製作小型水力發電機組的計畫可能要暫緩了, 等 PHP 專案搞定後有空再來玩, 畢竟大軍開拔糧草得先行.

2017年12月11日 星期一

寶瀅洗衣精贈品活動

11/18 去好市多買了四瓶德國寶瀅全效洗衣精, 上網登錄發票後, 寄回發票及明細影本經核對後即贈一瓶. 發票放在桌上一陣子怕弄丟, 所以趕快註冊帳號後登錄發票, 明天拿去影印後再掛號寄出 :



活動專區 :

http://www.persilevent.com.tw/index.php/vip
http://www.persil.tw/zh/games-fun.html

從外網以 VNC 存取樹莓派桌面的方法

周末回到鄉下迫不及待把這周改好的 reportip 程式傳入 Pi 3, 設定好 crontab , 果然每當 ADSL 公網 IP 異動時就會收到 E-mail 通知, 實在太棒了, 這樣無論我在哪裡都能用 Putty 連線鄉下家裡 24H 不關機的 Pi 3, 實現透過 Internet 遠端操控的夢想. 參考 :

從外網以 SSH 存取樹莓派的方法

不過這只是解決了命令列存取而已, 如果要用 VNC 遠端存取樹莓派桌面要怎麼做呢? 其實樹莓派自 PIXEL 版本之後就內建 VNC Server 了 (RealVNC), 不必再另外安裝, 因為 2016 年 9 月 28 日 RealVNC 與樹莓派基金會達成合作協議, 於新版的 Rasnbian 作業系統中納入 RealVNC, 參考 :

RealVNC and Raspberry Pi announce new partnership

我目前使用的 Rasbian PIXEL 是 2017 年 3 月版的, 裡面就已經內建 VNC 了, 可以在桌面的 Memu/Preferences/Raspberry Pi Configuration/Interfaces/VNC 選項中勾選 Enable 開啟 VNC 伺服器 :





這樣每次樹莓派開機時就會自動開啟 VNC Server 了. 如果上面的設定沒打開, 也可以用人工方式在命令列下 vncserver 指令開啟一個遠端桌面, 例如 :

pi@raspberrypi:~ $ vncserver
VNC(R) Server 6.0.2 (r26558) ARMv6 (Mar 14 2017 17:00:31)
Copyright (C) 2002-2017 RealVNC Ltd.
RealVNC and VNC are trademarks of RealVNC Ltd and are protected by trademark
registrations and/or pending trademark applications in the European Union,
United States of America and other jurisdictions.
Protected by UK patent 2481870; US patent 8760366; EU patent 2652951.
See https://www.realvnc.com for information on VNC.
For third party acknowledgements see:
https://www.realvnc.com/docs/6.0/foss.html

If a desktop environment fails to load for this virtual desktop, please see:
 https://www.realvnc.com/doclink/kb-345
Running applications in /etc/vnc/xstartup

VNC Server catchphrase: "Alias caviar race. Valid singer filed."
             signature: cc-3a-a7-ed-7b-b6-b4-2a

Log file is /home/pi/.vnc/raspberrypi:2.log
New desktop is raspberrypi:2 (192.168.2.192:2)

因為我已經下過一次 vncserver 了, 所以上面顯示這是開啟第二個遠端桌面伺服器. 不過這種方式不實用, 因為若萬一停電, 復電時它不會自動開啟 VNC Server. 利用 VNC 在內網進行遠端操控的方式可參考 :

https://www.realvnc.com/en/connect/docs/raspberry-pi.html#raspberry-pi-setup
樹莓派的遠端桌面控制 : 使用 VNC

從外網用 VNC 連線樹莓派桌面有兩個辦法. 一是傳統做法, 即在路由器防火牆上用 port forwarding 打個洞, 讓 VNC 的 5900 埠暢通; 二是使用 RealVNC 的 Cloud connect 服務, 根據 RealVNC 官網說明, Home 用戶在非商用條件下享有 5 台以內的免費 Cloud connect 服務, 參考 :

# Raspberry Pi VNC Cloud Connect
Connecting to your Raspberry Pi with VNC Viewer
VNC Connect and Raspberry Pi


Source : VNC connect


但我在桌面 Menu 找了老半天都找不到 VNC Server 程式入口, 只找到 VNC Viewer, 所以我還是按照下面這篇的方法, 在無線基地台上打個洞, 開啟 5900 埠作 port forwarding :

# How to: Connecting to VNC Server (5.x and before) over the Internet

因為 VNC 走的是 5900 埠, 因此必須在無線基地台的防火牆開啟我的樹莓派的 5900 埠, 在 EDIMAX 基地台設定如下 :





注意, 一定要按 Apply 鍵才會寫入記憶體. 然後用筆電的 VNC 從外網連線我 ADSL 目前的外網 IP :





Bingo! 馬上就連線成功, 當然透過 Internet 遠端連線比不上在 Intranet 或樹莓派本機上反應那麼快, 但還是可接受範圍啦 ! 至少可以讓我在外地也能操控鄉下的樹莓派, 隨時要改爬蟲程式變成可行, 不需要等到周末回鄉下才能做啦! 真是棒到不行.

參考 :

安裝與設定Raspberry Pi的RealVNC伺服器

2017年12月10日 星期日

太陽光電設置班第一課

昨天太陽光電設置班第一期在正修科大開始上課, 早一點去的話, 正修宿舍外的機車停車格都有位置可停, 走宿舍往南教學大樓的天橋最近. 這一期總共 40 人全部額滿, 可說非常熱烈.

早上是簡報教學, 主要介紹乙級技術士檢定各項規定以及扭力板手操作方式, 每個人都要到放在台前的鋁擠型支撐架用扭力板手實際操作一遍上緊螺帽的手感, 因為用力太多會把鋁架鎖到崩掉.

下午則戴上黃色工作安全帽到頂樓的技術檢定考場練習太陽能板安裝. 我這組三人先做鍍鋅鋼, 這種支撐架比較高, 要鑽進太陽能板下鎖螺絲螺帽, 比較難施工; 而鋁擠型支撐架則較低, 只要在上面鎖固定鋁片即可.

我以為學員都是本地人, 下課休息時聽說有些同學遠自苗栗與台東來高雄上課, 為了學技術遠道而來真讓我驚訝. 

回家的路上在本館路看到一家園藝店, 特地下來買了兩盆小的虎尾蘭, 一盆 70 元, 老闆說這是這是買過最便宜的虎尾蘭吧! 我說不好意思, 我第一次買這種盆栽, 所以也不知道是否最便宜. 聽說此物能淨化空氣, 擺室內很耐旱.

2017年12月7日 星期四

鄉村基礎木作第八課 : 上漆

因為這周六就要開始上太陽能板課了, 今天晚飯後去木樂園上第八堂課-上漆, 菁菁說也要跟去看看, 我想也接近尾聲了, 就帶她去看看吧. 從八月學到十二月, 我這木工課也上得太久了, 因為整個九月我都沒去, 十月好像也只去兩次. 不過這個課程真的讓我收穫不少, 透過實作學會了修邊機, 打磨機, 釘槍, 鋸床等木工工具的操作. 

劉老師先講解完化學漆與天然漆的差別, 要我選漆的顏色, 我選的是半透明的柚木色天然漆. 我原以為要用噴漆, 這樣三兩下就可以回家了, 沒想到是整整花了三小時才完成. 上漆所需用品如下 : 塑膠手套, 海綿, 天然漆 :




首先用噴槍將上回打磨後表面附著的木屑粉塵用噴槍噴乾淨, 然後戴上薄的塑膠手套, 開啟漆罐蓋, 用小木條或筷子攪一攪, 再用海綿沾漆開始上色, 先從收納櫃底部開始順木材紋路上漆, 然後是四周, 上蓋板, 背板等處. 外面上完後再漆內側, 這一小罐漆剛好讓我裡裡外外都順利塗完.




劉老師說下次來只要用細沙紙稍微磨一下就可以把作品帶回家了.

好書 : Python + Spark 2.0 + Hadoop 機器學習與大數據分析實戰

這本書在市圖借得到, 但是非常搶手, 預約都是滿檔, 我是在鄉下的分館看到新書到館陳列時馬上借出的. 最近在忙 PHP 專案沒時間研究, 所以大致看了前面幾章就必須還了, 等忙完再借回來看 (都滿檔不知還借不借得到哩).

Python + Spark 2.0 + Hadoop 機器學習與大數據分析實戰 (林大貴, 博碩)





作者有為此書設立網站, 臉書社團與粉絲團, 參考 :

http://pythonsparkhadoop.blogspot.tw/
# https://facebook.com/hadoopspark
# https://facebook.com/groups/hadoopspark

全書範例程式可在博碩網站下載 :

http://www.drmaster.com.tw/download/example/MP21622_example.zip


此書作者為從事大數據與機器分析工作, 具有多年實務經驗之業內人士, 故此書內容實作性強, 又兼顧基本觀念的介紹. 本書以 Python 為程式語言開發 Apache Spark 應用程式存取 Hadoop HDFS 上的分散式大數據, 此架構具有多重優點: Python 語言簡明易學具高度生產力; 基於記憶體 (in-memory) 運算的 Apache Spark 叢集運算框架可進行高效能之大數據運算; 而 Hadoop HDFS 則為大數據提供彈性, 可靠, 與易擴容之分散式檔案系統.

此書 1~9 章介紹建立 Python + Spark 2.0 + Hadoop 機器學習與大數據分析架構所需工具如 Hadoop Multinode Cluster, Python Spark 與 Scala 語言, Anaconda 等工具程式之安裝. 10~12 章為 Python Spark RDD, 整合開發環境與推薦引擎之介紹. 第 13 章以後即為機器學習部分, 直到最後的第 22 章. 以下是大略看過第一章後之摘要 :

  1. 機器學習的應用範例 : 推薦引擎, 定向廣告, 需求預測, 垃圾郵件過濾, 醫學診斷, 自然語言處理, 搜尋引擎, 詐騙偵測, 證券分析, 視覺辨識, 語音識別, 手寫識別等.
  2. 所謂機器學習是利用演算法以歷史資料進行訓練來產生模型 (監督式機器學習), 然後利用這模型對新資料進行預測. 訓練資料主要由 feature (資料特徵, 例如溫溼度, 氣壓, 風向等) 與 label (資料標籤, 即欲預測之項目, 例如氣候是陰, 晴, 或雨, 雪等) 組成. 機器學習可大略分成訓練與預測兩個階段. 
  3. 監督式學習中的資料標籤依所欲預測的項目屬性, 所用的演算法可分為 :
    (1) 二元分類 : 是非題, 例如只要預測下雨或不下雨.
    (2) 多元分類 : 選擇題, 例如要預測是晴天, 陰天, 雨天, 或是下雪.
    (3) 迴歸分析 : 計算題, 例如要預測今日的氣溫.
    而非監督式學習因為沒有要預測的目標 (即無 label), 所以是用集群分析將資料分成幾個差異性較大之群組, 群組內相似度最高. 
  4. Apache Spark 原先是加州大學柏克萊分校 AMPLab 的 Matei Zaharia 於 2009 年所開發的一種開放原始碼叢集運算架構, 於 2010 年以 BSD 授權釋出原始碼成為開源專案, 2013 年 Spark 專案捐贈給 Apache 基金會. 
  5. Spark 允許用戶將資料載入 Cluster 叢集記憶體內進行多次反覆運算, 是一個具有彈性, 用途廣泛之大數據運算平台, 非常適合實作機器學習演算法. 其特色有四 :
    (1) 運算速度快
          Spark 是基於記憶體計算的叢集運算系統, 比 Hadoop MapReduce 快 100 倍.
    (2) 支援多程式開發
          目前支援 Scala, Python, Java, R
    (3) 相容 Hadoop
          提供 Hadoop Storage API, 支援 Hadoop HDFS/YARN, 相容 Hive
    (4) 跨平台
          可在本機或 AWS EC2 雲端執行
  6. Spark 的核心是彈性分散式資料集 RDD (Risilient Distributed Dataset), 屬於一種分散式記憶體, Spark 會將運算時產生的資料暫存於記憶體中以加快執行速度, 這種方式在資料量大, 反覆運算次數多時越能看出其效能. 
  7. Spark 2.0 主要功能有四 :
    (1) Spark SQL DataFrame : 可使用 SQL 語法執行數據分析
    (2) Spark Streaming : 可處理即時資料串流
    (3) Graphx : 分散式圖形處理架構, 可用圖表運算
    (4) Spark MLlib : 可擴充之機器學習函式庫
    (5) Spark ML pipeline : 為 ML 每一階段建立 pipeline 流程, 減少程式設計負擔
    其中 Spark ML pipeline 是 Spark 從 Python Scikit-learn 模組得到啟發而設計之架構. 
  8. Spark 資料處理方式有三種 :
    (1) RDD
    (2) DataFrame
    (3) Spark SQL
    其中 DataFrame 是 Spark 從 Python 的 Pandas 模組得到啟發而設計的.
    此三者最大的差異在於是否有定義 Schema (即欄位名稱與資料型態). RDD 資料沒有定義 Schema, 須使用 Map/Reduce 觀念來操作, 對程式設計能力要求較高, 但功能也最強; Spark DataFrame 則須在建立資料前先定義 Schema, 是 Schema 版的 RDD; 而 Spark SQL 則是從 DataFrame 衍生而來, 先建立 DataFrame, 再透過登錄 Spark temp table 使用 SQL 語法操作資料. 使用上以 Spark SQL 最容易, 只需熟 SQL 語法即可; DataFrame 次之, 使用者需要基礎的程式設計能力, 其 API 提供許多與 SQL 功能類似之函數來進行統計; 使用 RDD 則需進階程式設計能力, 因為它沒有 Schema, 必須透過 Map/Reduce 指定資料位置. 
  9. Spark 支援以 Scala, Python, Java, R 這四種語言進行應用程式開發, 其中 Scala 是 Spark 本身的開發語言, 與 Spark 相容性最佳, 執行 RDD 操作效率也最高, Scala 與 Java 同樣都是在 JVM 上執行, 也都是物件導向語言, 但 Scala 也兼具函數式語言特性, 程式碼較 Java 簡潔許多, 不過使用者不多, 學習曲線也較陡. Spark 的 R 語言功能支援較不完整, 目前還在持續開發中, 而且 R 不是通用語言, 缺乏網站整合與網路爬蟲功能. 反觀 Python 不僅是通用語言, 其語法簡明易學具備高生產力, 還有 NumPy, Matplotlib, Pandas, Scikit-learn 等資料分析模組支援, 是資料分析與大數據開發之熱門語言.  
  10. Python 雖然擁有 Pandas 與 Scikit-learn 等強大之機器學習模組, 但大數據必須用分散式運算才能有效處理, 這就是 Spark 應運而生的背景, Python 可以透過 Spark 應用程式處理 HDFS 分散式儲存之資料; 亦可在多台電腦組成之群集上執行分散式運算, 利用 Spark 特有之記憶體計算大幅提升執行效能. 
  11. Python Spark 機器學習 API 有兩個 : MLlib 與 ML Pipeline, 前者是搭配 RDD, 後者則是搭配 DataFrame :
    (1) Spark MLlib : RDD-based 機器學習 API
    (2) Spark ML Pipeline : DataFrame-based 機器學習 API
    Spark DataFrame 與 Pandas DataFrame 可以互相轉換, Python 開發者可將資料轉為 Spark DataFrame 後使用 Spark ML Pipeline 進行訓練與預測, 然後轉回 Pandas DataFrame, 這樣就可以利用 Python 豐富的視覺化工具如 Matplotlib 等呈現結果.
    Spark DataFrame 提供 API 可輕易讀取其他資料來源, 例如 Hadoop, JSON 等, 也可以透過 JDBC 讀取關聯式資料庫如 MySQL 等. 
  12. Spark ML Pipeline 機器學習工作流程 :
    Spark ML Pipeline 將機器學習每個階段建立一個 pipeline, 例如資料處理, 訓練, 建立模型, 進行預測, 產生預測結果等等, 優點是模組化可減輕程式設計負擔, 而且全程使用 DataFrame, 資料格式一致, 要套用不同的演算法時直接替換, 流程不變. 
  13. 大數據的 3V :
    (1) Volumn : 大量資料
    (2) Variety : 多樣化資料
    (3) Velocity : 資料流速快
  14. Hadoop 是 Apache 的大量資料儲存與處理平台, 源自於 Doug Cutting 與 Mike Cafarelia 於 2002 年起始的 Nutch 專案, 2004 年導入 Google 的 MapReduce 分散是技術, 於 2006 年改名為 Hadoop 專案. Hadoop 具有如下特性 :
    (1) 可擴展性 : 分散式儲存與運算, 只要增加新的資料節點伺服器即可擴充
    (2) 經濟性 : 一般等級伺服器即可架構高效能叢集
    (3) 彈性 : 可儲存各種形式與來源之資料 (無 Schema)
    (4) 可靠性 : 每個資料都有兩個副本 (分散式架構)
  15. HDFS (Hadoop Distributed File System) 分散式檔案系統由 NameNode 與多個 DataNode 組成, NameNode 負責管理維護 HDFS 目錄系統, 控制檔案讀寫動作, DataNode 則負責儲存資料. DataNode 可擴充至成千上萬個. 檔案在儲存時會被切割成多個區塊, 每個區塊會有兩個副本 (總共三份), 也可以在組態設定中指定要建立幾個副本, 當某個區塊毀損時, NameNode 會自動搜尋其他 DataNode 上的副本來回復資料. HDFS 具備機架感知功能, 一份資料的三個副本會分別存放於同機架的不同節點, 以及不同機架的不同節點以避免資料遺失, 即使機架或節點故障仍可保證回復資料. 
  16. MapReduce 中的 Map 是將工作分割成許多小工作交給不同伺服器執行; 而 Reduce 則是指將所有伺服器的執行結果彙整後傳會最終結果. 利用 MapReduce 可在上千台伺服器上平行處理巨量資料. Hadoop 的新版 MapReduce 架構稱為 YARN (Yet Another Resource Negotiator), 是效率更高的運算資源管理核心. 

Python Spark 機器學習的架構重繪如下 :




由於 Hadoop 是在 Linux 環境下執行的軟體, 如果要在 Windows 上安裝 Hadoop, 必須使用虛擬機器來安裝 Linux, 此書第二章即介紹如何在 Windows 上安裝設定 Oracle 的免費虛擬機器軟體 VirtualBox. 安裝很簡單, 就是一鍵到底的 YES man 即可. 安裝完成後, 啟動 VirtualBox 進行如下設定 :

  1. 在 "檔案/喜好設定/一般" 選項下指定 VirtualBox 的檔案資料夾, 例如 D:\VirtualBox. 
  2. 按 "新增" 鈕建立一個虛擬機器, 需輸入名稱 (Hadoop), 選擇類型 (Linux), 版本 (Ubuntu-64), 指定虛擬機器的記憶體大小 (例如 4096MB). 
  3. 下一步選擇 "立即建立虛擬機器硬碟", 按 "建立" 選擇虛擬硬碟檔案格式 VDI. 
  4. 下一步選擇虛擬硬碟配置方式為 "動態配置".
  5. 下一步設定虛擬硬碟位置與大小, 選擇步驟 2 所指定之虛擬機器名稱 Hadoop, 硬碟大小可設 100G (此為上限而已), 按 "建立" 即可. 

完成後在 VirtualBox 檔案資料夾下會產生一個子目錄 Hadoop 用來儲存此虛擬機器之檔案. 安裝好 VirtualBox 之後接下來第三章是在虛擬機器中安裝 Ubuntu 作業系統, 書中建議的是 64 位元的 14.04 LTS 桌面版本 :

# http://www.ubuntu-tw.org/modules/tinyd0

因為下載的是 ISO 光碟檔案, 所以要按 VirtualBox 的 "設定值" 按鈕, 在 "存放裝置" 的 IDE 控制器中按光碟圖示選擇虛擬光碟檔案, 點選所下載之 Ubuntu 的 ISO 檔案, 按開啟與確定後即將光碟掛載上去, 接著按 ViutualBox 的 "啟動" 即可安裝 Ubuntu Linux 了.

Ubuntu 搞定後便可安裝 Hadoop 了, 此書第四章介紹 Hadoop Single Node Cluster 安裝設定方式, 亦即在一台電腦上建立的 Hadoop 執行環境; 第五章則是介紹 Hadoop Multi Node Cluster 安裝方式以及 Hadoop Resource Manager/Name Node HDFS Web 介面, 這要在 VitualBox 上建立多個虛擬主機 (書中是 4 個, 一個 master, 其餘為 data) 來模擬 Hadoop 叢集運算.


關於 Scala 參考 :

Scala vs Java:兩者間的差異與相似處

2017年12月6日 星期三

田間物聯網監測平台與農業科技

在 Yahoo 看到下面這則物聯網的農業應用訊息, IoT 業者利用 Arduino 與 NB-IoT 模組, 配合學界的費洛蒙害蟲防治技術, 打造預防蟲害之田間物聯網監測平台, 相信對於有機農業將是一大助力 :

中華電信NB-IoT 打造田間物聯網監測平台
防蟲害 首創田間物聯網監測平台
中華電信攜手朝陽科技大學、原力電子 共創田間物聯網監測平台
中華電信推NB- IoT 產學結合創田間物聯網監測平台
朝科大產學結盟 首創App掌握田間蟲害


Source : Yahoo


原力電子是位於桃園的 IoT 業者, 主要營業項目是電子零組件模組與通訊器材設計製造, 以及農林漁牧業自動控制之顧問等等. 在 IoT 部分利用自行研發之 10Tduino GNB 控制板應用在農業監測, 目前已佈署上千個 IoT 模組與水下資料收集器, 參考 :

http://www.dynagx.com

至於費洛蒙防蟲技術, 朝陽科大應用化學系在 2008 年成立費洛蒙中心, 致力於以性費洛蒙應用於害蟲防治的技術, 已研發合成多種費洛蒙製劑, 參考 :

http://www.applchem.cyut.edu.tw/service/super_pages.php?ID=service1&Sn=5

我比較關注的是電信業者的 NB-IoT 網路, 今年中華電信推出 NB-IoT 整合閘道器, 已完成 Pre-5G 的驗證測試, 預計 2020 年商轉, 所以事實上這個田間物聯網監測平台應該還只是雛形而已, 資費方案當然還沒有出來, 參考 :

研發5G和NB-IoT技術 電信商積極佈局物聯網
中華電信自主研發 完成Pre-5G NB-IoT行動物聯網端到端整合應用

總之, 農業科技都是要錢的, 是否可以不要依賴電信業者的 NB-IoT, 改用免通信費的 LoRa 架構呢? 希望創客圈能朝這方向努力, 打造一個超低投入成本的 IoT 農業監測平台.

關於害蟲防治, 下面這部片值得參考 :

【種菜防蟲】居家種菜安心吃,動手做安全有機的病蟲害防治液! | 台灣好食材 Fooding



關於農業科技的實際應用, 可參考 :

科技革命 翻轉農漁牧 Part 1 農業導入科技 雲端監控24小時掌握農況




科技革命 翻轉農漁牧 Part 2 擺脫靠天吃飯?! 智慧偵測掌握魚塭資訊




越來越多資工專才投入農業科技研發, 相信會大大扭轉農業的景觀.

用 18650 模組驅動電視

我在 Youtube 看到有人用 4 顆 18650 串聯做成的模組透過變流器 (inverter) 轉成 110V 交流電來驅動液晶電視, 18650 充飽為 4.2V, 放電截止電壓 2.75V, 四顆串聯最高為 16.8V, 最低為 11V, 而一般車用變流器只要 12V 便可驅動轉成 110V 交流電 :

Power your TV from 18650 batteries




真是沒想到 18650 也能這麼用, 不過只有 4 顆 18650, 電量應該不會超過 8Ah, 液晶電視功耗約 50W, 因此 18650 電流約為 3A (一般 18650 電池放電電流約 5~10A), 大概只能看 2 小時而已 (假設 18650 是 2000 mAh 足). 要撐久一點的話必須並聯更多模組. 找時間我也來試試看.

參考 :

厂家直销12V大容量锂电池电瓶18650锂电池家用蓄电池逆变器定制款

2017年12月5日 星期二

PHP 學習筆記 : 自訂函數

最近在改寫 PHP 專案時遇到需要寫一個自訂函數來簡化爬蟲程式的結構, 這才發現已經快把 PHP 忘光了, 所以又重新複習一遍自訂函數寫法, 順便整理筆記如下 :

一. PHP 自訂函數語法格式 :

function 函數名稱([參數1, 參數 2, .... 參數 n]) {
  函數內容;
  [return 傳回值];
  }

自訂函數用法摘要 :
  1. 函數名稱只能由英數字元或底線組成, 但第一個字元不可以是數字. 參數名稱命名方式與變數相同, 即必須以 $ 開頭, 然後與函數名稱一樣是英文字母或底線帶領的任意長度英數字或底線字元.
  2.  函數名稱與參數名稱都分大小寫, Func() 與 func() 是不同函數, $var 與 $Var 是不同參數. 參數名稱不可使用保留字. 
  3. 傳入參數不是必要, 多個參數用逗號隔開. 參數可以設定預設值, 呼叫時若未傳入該參數即以該預設值代替, 例如 :
    function f($var1=1, $var2="ok") {...}
    沒有預設值的參數一定要相當型別的傳入值, 否則會出現執行錯誤. 
  4. 參數為函數內之區域變數, 與函數外的全域變數即使同名也不相干, 因此在函數內部存取到的是區域變數, 而不是同名的函數外全域變數. 在函數內若要存取外部全域變數須在變數前面加 global 或使用全域陣列 $GLOBALS[] :
    $var=1;   //全域變數
    func() {
      global $var=2;  //或者 $GLOBALS['var']=2;
      echo $var;    //輸出2
      }
    echo $var;    //輸出2 (被函數改了)
  5. 函數內之一般變數均為區域變數, 函數結束時即被釋放, 若欲在函數執行完畢後保留函數內之變數, 可用 static 宣告其為靜態變數 :
    function f() {
      static $var=0;
      echo ++$var;
      }
    f();  //輸出 1 ($var 被保留下來)
    f();  //輸出 2
  6. 預設的呼叫方式為傳值呼叫, 若要用傳址呼叫須在全域變數前面加 "&", 傳入參數之值可能會被函數修改 :
    $var=1;
    $val1=func($var);  //傳值呼叫 ($var 不會被修改)
    $val2=func(&$var);  //傳址呼叫 ($var 可能會被修改)
  7. 傳回值不是必要, 傳回值可以是任何型別之資料. 
  8. 在 PHP4 之後的版本, 函數可以放在程式的任何地方, 不一定要放在呼叫之前. 


二. 變動長度的參數列 : 

PHP 的函數可以在定義函數時不指定參數個數, 而在呼叫函數時透過下列三個內建函數來處理傳入之參數 :

 函數名稱 說明
 func_num_args() 傳回傳入函數之參數個數
 func_get_arg(n) 傳回傳入函數的第 n+1 個參數內容
 func_get_args() 傳回傳入函數之所有參數組成之陣列

注意, 此三內建函數只能在自訂函數內呼叫, 否則會出現錯誤.


三. 可變動函數 : 

在 PHP 我們可以設定一個字串變數的值為函數名稱, 利用此變數名稱當函數名稱, 就可以動態地呼叫不同的函數, 例如 :

$f1() {echo "這是 f1()";}
$f2() {echo "這是 f2()";}
$f3() {echo "這是 f3()";}
$fname="f1";
$fname();   //呼叫 f1() 輸出 "這是 f1()"
$fname="f2";
$fname();   //呼叫 f2() 輸出 "這是 f2()"
$fname="f3";
$fname();   //呼叫 f3() 輸出 "這是 f3()"

這樣就可以用單一介面呼叫不同函數了.

但是若字串變數值弄錯的話就可能會因為呼叫一個不存在的變數而發生錯誤, 這時可先呼叫內建函數 function_exists() 來檢查, 傳入參數為代表函數名稱的字串變數, 例如 :

if (function_exists($fname)) {$fname();}


四. 遞迴函數 :

PHP 的函數也可以呼叫本身形成遞迴, 典型的範例為階乘函數, 例如 :

function factorial($n) {
  if ($n >= 0) {
    if ($n == 0) {return 1;}
    else {
      $ret=1;
      for ($i = $n; $n > 0; $n--) {$ret *= $n;}
      return $ret;
      }
    }
  }

echo "5 階乘=".factorial(5);  //輸出 120

報名太陽光電設置人才訓練班

上週六 (12/2) 下午與姊姊回鄉下時路經文自路的 "高雄市太陽能設備裝修職業工會", 因為時間還很早, 所以停下來詢問他們是否有開設訓練課程, 結果剛好 12/9 要開第一期訓練班, 45 歲以上中高齡政府全額補助, 就先拿了 DM 回家研究.




實際上課地點在正修科大南教學大樓 4 樓 (近後門濱山街宿舍區), 12/9~1/27 週六 09:00~16:00 8 天共 45 小時. 其實 12 月還有一個乙級技術士證照輔導班, 對想要從事太陽能安裝工作的人比較有用, 不過報名已經結束 :





高雄市太陽能設備裝修職業工會的首頁與臉書如下 :

http://www.sunlight.org.tw
https://www.facebook.com/高雄市太陽能設備裝修職業工會-1483728555175306

由於週六都要載二哥去鳳中上 APCS 課, 他上課時我就去附近的家樂福看書, 現在已看完三本書了, 似乎也沒別的好書可看, 乾脆就去上課好了, 反正從鳳中到正修很近, 不用 10 分鐘. 首先到勞動部台灣就業通網站註冊帳號, 填寫基本資料 :

# 台灣就業通

然後到勞動部產業人才投資方案網頁去搜尋高雄市 12 月份的課程, 就可以找到課程代號 109829 的太陽光電設置人才訓練班 :

https://tims.etraining.gov.tw/timsonline/index3.aspx?OCID=109829

點右上角的報名按鈕進入線上報名網頁, 要填一大堆資料, 包括勞保申報單位, 工作年資等等, 甚至郵遞區號還要精確到 5 碼, 還好有半小時時間可填.




接下來只要將學費 39850 匯入工會郵局帳號即完成報名手續, 但仍要親自帶身分證與存摺正影本 (2 份) 到工會去核對以便課程結束後辦理退費. 既然還要跑一趟, 乾脆這兩天過去現場繳費好了. 近三年參訓課程會記錄在網站中, 也會顯示補助費用核退狀態 :




參考 :

http://forum.i835.com.tw/forum-f15/topic-t100.html?mobile=on
產業人才投資方案

我的木工剩下一堂課 (上漆), 原本打算這周六去, 但週六就要開始上課了, 我看木工只能周一到周四晚上去囉.

2017-12-06 補充 :

今天找到下面這篇研究報告非常值得一讀 :

太陽能電源轉換管理系統與應用-臺北科技大學

線上繪圖板 Sketchpad

最近要紀錄水車, 太陽能板安裝架設計圖, 總覺得用 PowerPoint 很難畫, 我只是想快速畫個草圖而已, 不需要筆直的線, 若手繪後用手機拍照, 又因為光度與清晰度問題感到不很優, 如果有三星 Note 8 就好辦了, 直接在手機上手繪存檔輸出, 但 Note 8 很貴啊! 跟 iPhone 一樣高貴.

我在網路上找到這個線上繪圖軟體, 搭配姊姊已經不用的繪圖板也勉強可用 :

https://www.pkstep.com/archives/24841


2017 年第 47 周記事

週六 (12/2) 公司福利會在蓮池潭辦健行體育活動, 之前有幫菁菁與水某報名, 結果菁說她同學要來, 所以就我一個人去. 早上先載二哥去鳳中上 APCS 程式設計班, 然後再折返趕去蓮池潭, 剛好可趕上 09:30 報到截止時間. 健行路線是從小龜山活動中心走到孔廟, 我雖然住在左營, 但卻對真正的老左營這一帶不甚熟悉, 今日一走終於搞清楚舊城這一帶了, 原來直走就可以到知名的哈囉市場, 左營阿姨常常在這裡運動. 對了, 為什麼叫做哈囉市場? 我搜尋 Google 沒找到任何訊息. 我猜可能是越戰時代這裡有很多美軍來買東西, 見人就哈囉哈囉的, 結果這裡就變成哈囉市場了 (純猜測啦!).

在蓮潭路與左營下路交叉口附近有一家 "金華燒餅" (中外餅鋪隔壁), 聽同事說蠻好吃的, 就去訂了一甜五鹹, 每個 20 元, 回程時再取貨. 鹹的是蔥肉餅, 剛出爐時最好吃, 老闆說冷掉後可在表面抹些水微波一下還是很好吃.




我在孔廟的咖啡店看到設計很特別的竹桌椅, 它的椅背是可以往前摺合的, 桌子也是仿麻將桌可以整個收起來, 非常巧心 :





週五晚上姊姊坐自強號回到高雄, 一個月回來一次, 週六中午全家去吃中華路大順路口的宝日式刷刷鍋, 因為已經很久沒去的大熊 (高鐵附近) 已經沒做火鍋了, 所以去嚐嚐不一樣的口味. 這家吃到飽的火鍋一個人約 400 元, 菜色雖然不是非常多, 但品質看來很不錯.

週日因為姐姐要搭傍晚 18:15 的高鐵, 下午四點就得從鄉下出發. 但是下午往高雄的路上容易塞車, 整整開了一個小時才到. 以後我看要提早 3 小時出發比較保險.

2017年12月1日 星期五

PHP Curl 出現 Notice: Undefined index 警告問題

今天在改寫 PHP 爬蟲程式時, 發現呼叫 Curl 的 http_get() 函數竟出現 "Notice: Undefined index" 警告 :

Notice: Undefined index: query in E:\xampp\htdocs\stock\lib\http.php on line 298



查詢網路雖然有找到類似問題, 但細看卻不太相關 :

https://stackoverflow.com/questions/8953222/notice-undefined-index-on-line-5

後來反覆檢查原始碼, 推斷問題一定出在呼叫 http_get() 函數, 此函數在其他程式運作正常, 那問題必是傳入參數, 亦即傳入網址, 比對後果然找到原因了, 目標網頁已經從 http 改為 https, 雖然打入舊網址還是能看到網頁, 但那是伺服器自動轉址的緣故, Curl 還是會偵測到這個問題, 所以給出 Undefined Index 提醒.

2017年11月28日 星期二

XAMPP 最大執行時間 (max_execution_time) 問題

今天繼續處理 PHP 專案, 發現爬蟲程式固定在執行 120 秒後就 timeout, 屢試不爽, 看這樣子應該是新安裝的 XAMPP 工具包裡的 PHP max_execution_time 設得太短了 :

Fatal error: Maximum execution time of 120 seconds exceeded in E:\xampp\htdocs\stock\lib\mysqli.php on line 512

參考 :

Maximum execution time in phpMyadmin

按 XAMPP 的 Apache 的 Config 鈕, 選 PHP (php.ini) 檢查 php.ini 設定, 發現 max_execution_time 早已設置為 5000 秒 (在第 383 行左右) 了啊, 怎麼會固定 120 秒就逾時呢?




;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;

; Maximum execution time of each script, in seconds
; http://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 5000 

瀏覽 http://localhost/dashboard/phpinfo.php 檢查 Loaded Configuration File 項目確實載入的設定檔為 E:\xampp\php\php.ini 沒錯, 照理講應該是 5000 秒才會逾時啊. 我把 XAMPP 關掉重開, 甚至電腦重開機都一樣無效, 傷腦筋.

最後在下面這篇看到 set_time_limit() 函數可用來指定一個 PHP 程式的最長執行時間 (與 php.ini 的 max_execution_time 作用一樣, 只是作用在單一程式) :


這讓我想起之前好像有測試過 ini_set() 這個變更 php.ini 設定的函數, 檢查程式開始處果然發現這個測試過後忘記拿掉的程式碼, 設定值剛好就是 120 秒, 難怪!

@ini_set("max_execution_time","120");

拿掉這行後再次執行爬蟲程式就沒有逾時問題了 (第一次跑花了 270 秒, 因為每一筆都要 create table 三次, 後續大都是 update 運算就不需要這麼久了, 大約 23 秒).

注意, set_time_limit(0) 是設定此程式不受逾時限制.

以上紀錄希望提醒自己以後別再犯這種烏龍錯誤了.


2017年11月27日 星期一

2017 年第 46 周記事

這次二哥段考英文不及格, 他自己又不想去補習, 週六菁菁的理化家教要回去時聊到英文, 他也是鳳中畢業的, 他說以前他英文都 90 幾, 沒有補習, 完全自修, 把課本的東西看熟就可以拿高分. 我想二哥花很多時間在數理化, 分給英文的時間不足, 而英文占比卻比理化高, 所以二哥應該要調整一下時間比例才行.

昨天下午拿出上周磨光的腳踏車輪框想繼續打磨, 發現上週磨光的部分全部都生鏽了, 根本就是做白工, 只好重新磨光, 花了一個多小時, 用掉兩片中砂紙才好不容易恢復亮晶晶 :




所以這種鐵製品一經打磨就必須立刻上漆, 否則空氣中的水氣很快會讓它銹回去. 磨光後找出買了至少半年的噴漆來上漆, 我原以為是白漆, 噴了後才發現是透明漆, 應該是當初要保存木材紋路才刻意買的. 裡裡外外噴一遍後靜置 10 分鐘, 然後噴第二遍, 總共噴了三層 :




噴完後又去勘查水車安裝地點, 圍牆外水圳上寬 68cm, 中寬 60cm, 中高 43cm, 水深 6cm, 中心距邊 33cm, 此處優點是水急有圍牆與較窄的圳寬容易安裝, 缺點是水深較淺, 且會受到檔水閘門影響水速 :




另外一處是門口涵洞出水處, 圳寬 120cm, 岸高 70cm, 水深 16cm 以上, 好處是水深水急, 缺點是最寬太寬不好安裝 :




週日中午小舅小舅媽來整理菜園, 小舅看了車庫一角的雜物堆, 說下禮拜要找時間來清理, 哇!  這個我不整理不行了, 忙完車輪上漆之後就趕緊先來整理, 這可是媽以前種菜時的留下的農用器具雜物堆, 這三年來我都沒保留原樣不動, 今年九月底本來就想整理了, 但實在太忙, 不如今日就動手吧, 免得一些值得保留的東西被小舅丟了, 這是整理前的樣子 :




塞在牆角的是姐姐小時候騎的小酷妹與二哥滿周歲時小舅子買給他的小腳踏車, 這兩台後來都給菁菁騎, 因為姐姐去上山葉音樂班抽獎抽到首獎-功學社腳踏車一台, 哥哥姊姊都改騎較大台的新車 :





真的好懷舊, 沒想到一眨眼十幾年就過去了, 那些日子都不會再回來了, 往日時空只存在腦海的記憶裡, 我想這種心情只有卡本特的 "Yesterday Once More" 才能充分表達 : 




此外還清出一個鞋櫃椅子, 好像是以前在家樂福買的, 刷洗晾乾後還很好用. 這個周末總算感覺做了蠻多事情. 有時候計畫了老半天還抵不過突然的臨時起義. 

2017年11月25日 星期六

從外網以 SSH 存取樹莓派的方法

這個問題在我心中盤旋很久了, 但卻一直沒時間研究. 樹莓派的低功耗使其成為家中不關機的伺服器首選. 我曾將樹莓派連續開機好幾個月都不會當機, 不需要接螢幕或鍵盤滑鼠, 只要插上電源開機, 它會自動連線到家中的無線基地台, 並固定取得 192.168.2.192 這個 IP, 然後利用筆電以 Putty 用 SSH 連線樹莓派的固定 IP 192.168.2.192 即可完全操控它, 稱為無頭存取方式, 參考 :

樹莓派的 "無頭存取" (headless access)
設定樹莓派 WiFi 無線網卡固定 IP 的方法
樹莓派 Raspberry Pi 文章列表

在區域網路存取沒問題, 但 192.168.xxx.xxx 只限於家裡的區網能用, 如果在公司想要連線回來該怎麼做? 這就需要 WiFi 無線基地台 (路由器) 上設置虛擬伺服器, 將外網 IP 對應到區網的 192.168.xxx.xxx 了.

我參考了下列文章在我的 EDIMAX 無線基地台的管理網頁中為樹莓派的 外網 SSH 存取設定虛擬伺服器 :

樹莓派通過郵件上報實時IP,隨時隨地遠程登錄樹莓派

EDIMAX 管理網頁位置是在 "位址轉換/Virtual server" 頁籤 :




先將左上角的 "Enable virtual server" 打勾, 然後輸入 Private IP, 我的樹莓派因為有在 /etc/network/interfaces 檔案中設定固定 IP=192.168.2.192, 因此 Private IP 就輸入 192.168.2.192. 然後 Private port 與 Public port 都輸入 SSH 的埠號 22, 並在 Comment 欄輸入備註, 再按 "Add" 鈕, 上述的設定就會出現在下面的 "Current virtual server table" 中了, 最後要按 "Apply" 才會真正生效.

接下來要測試看看是否真能從外網與區網內的樹莓派建立 SSH 連線. 首先必須知道家裡無線基地台的外網 IP, 有許多網站提供 IP 查詢服務, 例如 :

http://cmp.nkuht.edu.tw/info/ip.asp
http://dir.twseo.org/ip-check.php
http://www.ip138.com/

我筆電原先是透過家裡的無線基地台上網, 利用上列網站查出無線基地台外網 IP 後, 這時將筆電改透過手機行動網路分享的 WiFi 上網, 這樣就可以模擬從 Internet 外網進行存取了. 這時打開 Putty, 輸入樹莓派所連之無線基地台外網 IP, 果然順利連線到區網內的樹莓派了.

https://github.com/laixintao/Report-IP-hourly

如果要在命令列查詢外網 IP, 可輸入下列 curl 指令 :

pi@raspberrypi:~ $ curl http://members.3322.org/dyndns/getip >>/home/pi/ip.log    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    14    0    14    0     0     46      0 --:--:-- --:--:-- --:--:--    46
pi@raspberrypi:~ $ cat ip.log
37.237.225.60

查詢內網則是用 ifconfig, 若只要擷取 IP 可用下列指令 :

pi@raspberrypi:~ $ ifconfig | grep 'Bcast' | cut -d B  -f 1 >> /home/pi/ip.log
pi@raspberrypi:~ $ cat ip.log
37.237.225.60
          inet addr:192.168.2.192

由於一般 ADSL 用戶都是浮動的公網 IP 並非固定, ISP 業者會一段時間會更換此 IP, 樹莓派必須在外網 IP 異動時自動以 E-mail 通知我們, 否則將無法以 SSH 從外網連線到樹莓派. 這篇文章的作者提供了 Python 程式碼來完成此項通報工作, 此程式已放在 GitHub 專案中 :

https://github.com/laixintao/Report-IP-hourly

主角是專案中的 Python 程式 reportip.py :

https://github.com/laixintao/Report-IP-hourly/blob/master/reportip.py

將此程式複製下來加以編輯, 主要是修改 e-mail config 部分 :

# the e-mail config
# this is just a simple format,this e-mail doesn't exist.
smtpserver = "smtp.sina.com"
username = "reaspberrypi@sina.com"
password = "123456"
sender = "reaspberrypi@sina.com"
receiver = ["receiver@sina.com","master@sina.com"]
subject = "[RPI]IP CHANGED"

改成如下 (注意, Hinet SMTP 主機是 msr) :

smtpserver = "msr.hinet.net"
username = "blabla@ms5.hinet.net"
password = "1234567890"
sender = "blabla@ms5.hinet.net"
receiver = ["jyp@yahoo.com","jyp@google.com"]
subject = "[RPI]IP CHANGED"

另外 Getmyip 類別之 getip() 方法裡面的查詢 IP 網址也要改成台灣的網址, 不要用原作中的大陸網站, 我查詢 Google 發現下面三個網站還不錯, 都可以正常運作 :
  1. http://myip.com.tw
  2. http://cmp.nkuht.edu.tw/info/ip.asp
  3. http://dir.twseo.org/ip-check.php
修改後的完整程式如下 :

#!/usr/bin/python
#-*-coding:utf-8*-

__author__ = 'laixintao'

import socket
import time
import struct
import smtplib
import urllib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import re
import urllib2

# the e-mail config
# this is just a simple format,this e-mail doesn't exist.
smtpserver = "msr.hinet.net"
username = "blabla@ms5.hinet.net"
password = "1234567890"
sender = "blabla@ms5.hinet.net"
receiver = ["jyp@yahoo.com","jyp@google.com"]
subject = "[RPI]IP CHANGED"

# file_path config
file_path = "lastip.txt"

def sendEmail(msghtml):
    msgRoot = MIMEMultipart('related')
    msgRoot["To"] = ','.join(receiver)
    msgRoot["From"] = sender
    msgRoot['Subject'] =  subject
    msgText = MIMEText(msghtml,'html','utf-8')
    msgRoot.attach(msgText)
    smtp = smtplib.SMTP()
    smtp.connect(smtpserver)
    smtp.login(username, password)
    smtp.sendmail(sender, receiver, msgRoot.as_string())
    smtp.quit()


def check_network():
    while True:
        try:
            print "Network is Ready!"
            break
        except Exception , e:
           print e
           print "Network is not ready,Sleep 5s...."
           time.sleep(10)
    return True

def get_lan_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("1.1.1.1",80))
    ipaddr=s.getsockname()[0]
    s.close()
    return ipaddr

class Getmyip:
    def getip(self):
        try:
            myip = self.visit("http://myip.com.tw")
        except:
            try:
                myip = self.visit("http://cmp.nkuht.edu.tw/info/ip.asp")
            except:
                try:
                    myip = self.visit("http://dir.twseo.org/ip-check.php")
                    # if you want to add more,use the format "except try"
                    # make sure the most useful link be the first
                except:
                    print "Fail to get the Network ip."
                    print "Get the LAN ip."
                    myip = get_lan_ip()
        return myip
    def visit(self,url):
        opener = urllib2.urlopen(url,timeout=20)
        if url == opener.geturl():
            str = opener.read()
            print "IP information from",url
        return re.search('\d+\.\d+\.\d+\.\d+',str).group(0)

def get_network_ip():
    getmyip = Getmyip()
    localip = getmyip.getip()
    return localip


if __name__ == '__main__':
    check_network()
    ipaddr=get_network_ip()
    lanip=get_lan_ip()
    emailip=str(ipaddr)+" "+str(lanip)
    ip_file = open(file_path)
    last_ip = ip_file.read()
    ip_file.close()
    if last_ip == emailip:
        print "IP not change."
    else:
        print "IP changed. New ip: {}".format(emailip)
        ip_file = open(file_path,"w")
        ip_file.write(str(emailip))
        ip_file.close()

        sendEmail(ipaddr)
        print "Successfully send the e-mail."


注意, Hinet 的 SMTP 發信主機要用 msr.hinet.net, 我的郵件主機是 ms5.hinet.net, 我原先以為要用這個, 結果信傳不出去, 改成 msr 就可以了, 參考 :

http://blog.xuite.net/yatpingchen/blog/199891664-國外收發Hinet郵件SMTP設定

其次, 上面這個程式原作是用 Python 2 寫的, 所以修改好後我改用 reportip2.py 存檔在 /home/pi 下, 手動執行時要用 python2 指令 :

pi@raspberrypi:~ $ python2 reportip2.py
Network is Ready!
IP information from http://cmp.nkuht.edu.tw/info/ip.asp
IP changed. New ip: 223.139.131.189 192.168.43.26
Successfully send the e-mail.
You have new mail in /var/mail/pi
pi@raspberrypi:~ $ python2 reportip2.py
Network is Ready!
IP information from http://myip.com.tw
IP not change.
You have new mail in /var/mail/pi


手動執行沒問題後, 接下來是編輯 contab 讓 reportip2.py 能夠定時自動執行, 這樣不論我在天涯海角都能透過 E-mail 得知目前的 IP 是多少而連線回去. 另外一個好處是可以知道家裡 ADSL 網路是否正常, 如果沒定時收到 E-mail 就表示網路異常了.

$ crontab -e 

參考原作的 crontabs 設定 :

https://github.com/laixintao/Report-IP-hourly/blob/master/rootcron

0 */1 * * * /usr/bin/python2 /root/rootcrons/reportip2.py

將其改為每 10 分鐘檢查一次 :

*/10 * * * * /usr/bin/python2 /home/pi/reportip2.py

在 crontab 加入這一筆後存檔, 再用 chmod 指令將 reportip2.py 改為可執行 :

pi@raspberrypi:~ $ sudo chmod +x /home/pi/reportip2.py   


2017-12-03 補充 :

下午 16:00 要回高雄, 因姊姊要搭高鐵回台北, 所以下午抽點時間測試上面的程式, 原作使用的 IP 查詢網站 www.138ip.com 每次 cron 執行回報的 IP 都不同, 事實上即使是浮動 IP 也不可能每 10 分鐘就變動一次, 我猜可能是該網站位於中國境內的關係, 改用台灣的 http://myip.com.tw 等位址就正常了.

Cron 執行紀錄放在 /var/log/cron.log  裡面, 不過紀錄功能預設是關閉的, 必須修改 /etc/rsyslog.conf 檔之設定將其打開才會記錄, 參考 :


以管理員身分開啟 /etc/rsyslog.conf, 在 "RULES" 項下可找到預設被 mark 掉的 #cron 設定, 拿掉 # 後存檔 :

pi@raspberrypi:~ $ sudo nano /etc/rsyslog.conf


###############
#### RULES ####
###############

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
#cron.*                         /var/log/cron.log
daemon.*                        -/var/log/daemon.log
kern.*                          -/var/log/kern.log
lpr.*                           -/var/log/lpr.log
mail.*                          -/var/log/mail.log
user.*                          -/var/log/user.log

然後重啟系統記錄檔即可 : 

$ sudo /etc/init.d/rsyslog restart  

檢視 cron 執行紀錄 :

pi@raspberrypi:~ $ sudo cat /var/log/cron.log                                                   
Dec  3 23:25:01 raspberrypi CRON[20720]: (pi) CMD (/usr/bin/python2 /home/pi/reportip2.py)                                                      ortip2.py)
Dec  3 23:30:01 raspberrypi CRON[20785]: (pi) CMD (/usr/bin/python2 /home/pi/reportip2.py)                                                      ortip2.py)
Dec  3 23:35:01 raspberrypi CRON[20806]: (pi) CMD (/usr/bin/python2 /home/pi/reportip2.py)                                                      nclean ] && /usr/lib/php5/sessionclean)
Dec  3 23:40:01 raspberrypi CRON[20879]: (pi) CMD (/usr/bin/python2 /home/pi/reportip2.py)                                                      ortip2.py)
Dec  3 23:45:01 raspberrypi CRON[20947]: (pi) CMD (/usr/bin/python2 /home/pi/reportip2.py)


參考 :

Where do Cron error message go?

2017-12-09 補充 :

我把上面 Python 2 的程式改為 Python 3 版, 結果卻敗在 visit() 方法無法取得外網 IP, 原因可能出在 urllib 模組上 :

import socket
import time
import struct
import smtplib
from urllib.request import urlopen
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import re

# the e-mail config
# this is just a simple format,this e-mail doesn't exist.
smtpserver = "msr.hinet.net"
username = "blabla@ms5.hinet.net"
password = "1234567890"
sender = "blabla@ms5.hinet.net"
receiver = ["jyp@yahoo.com","jyp@google.com"]
subject = "[RPI]IP CHANGED"

# file_path config
file_path = "lastip.txt"

def sendEmail(msghtml):
    msgRoot = MIMEMultipart('related')
    msgRoot["To"] = ','.join(receiver)
    msgRoot["From"] = sender
    msgRoot['Subject'] =  subject
    msgText = MIMEText(msghtml,'html','utf-8')
    msgRoot.attach(msgText)
    smtp = smtplib.SMTP()
    smtp.connect(smtpserver)
    smtp.login(username, password)
    smtp.sendmail(sender, receiver, msgRoot.as_string())
    smtp.quit()


def check_network():
    while True:
        try:
            print("Network is Ready!")
            break
        except Exception :
           print(e)
           print("Network is not ready,Sleep 5s....")
           time.sleep(10)
    return True

def get_lan_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("1.1.1.1",80))
    ipaddr=s.getsockname()[0]
    s.close()
    return ipaddr

class Getmyip:
    def getip(self):
        try:
            myip = self.visit("http://myip.com.tw")
        except:
            try:
                myip = self.visit("http://cmp.nkuht.edu.tw/info/ip.asp")
            except:
                try:
                    myip = self.visit("http://dir.twseo.org/ip-check.php")
                    # if you want to add more,use the format "except try"
                    # make sure the most useful link be the first
                except:
                    print("Fail to get the Network ip.")
                    print("Get the LAN ip.")
                    myip = get_lan_ip()
        return myip
    def visit(self,url):
        opener = urlopen(url,timeout=20)
        if url == opener.geturl():
            str = opener.read()
            print("IP information from",url)
        return re.search('\d+\.\d+\.\d+\.\d+',str).group(0)

def get_network_ip():
    getmyip = Getmyip()
    localip = getmyip.getip()
    return localip


if __name__ == '__main__':
    check_network()
    ipaddr=get_network_ip()
    lanip=get_lan_ip()
    emailip=str(ipaddr)+" "+str(lanip)
    ip_file = open(file_path)
    last_ip = ip_file.read()
    ip_file.close()
    if last_ip == emailip:
        print("IP not change.")
    else:
        print("IP changed. New ip: {}".format(emailip))
        ip_file = open(file_path,"w")
        ip_file.write(str(emailip))
        ip_file.close()

        sendEmail(ipaddr)
        print("Successfully send the e-mail.")

主要是把輸出改成函數式的 print(), 以及匯入 urllib.request.urlopen 而已, 執行結果如下 :

E:\test>python reportip3.py
Network is Ready!
IP information from http://myip.com.tw
IP information from http://cmp.nkuht.edu.tw/info/ip.asp
IP information from http://dir.twseo.org/ip-check.php
Fail to get the Network ip. 
Get the LAN ip.
IP changed. New ip: 192.168.43.72 192.168.43.72
Successfully send the e-mail.

收到的 E-mail 是內網 IP, 到底哪裡出錯? 有空再研究.

How to: Connecting to VNC Server (5.x and before) over the Internet


2017-12-11 補充 :

前天週六晚上將改好的 report2.py 傳到 Pi 執行 crontab, 只要公網 IP 有變動就會發出郵件通知, 證實上面的做法確實可行. 由於傳檔用的 WinSCP 也是使用 22 埠 (sFTP), 也是可以透過 Internet 傳送檔案 :





Bingo! 以後就可以隨時從遠端存取鄉下樹莓派裡的檔案了.

2017年11月24日 星期五

購買小型三相交流發電機

昨天早上決定向露天賣家 cptc823  購買兩個小型三相交流發電機以及兩個鋼珠軸承, 約定中午在光華路與鄭和南路口的 7-11 面交 :

低壓大電流無刷直流馬達 直流發電機 附整流二極體 $390*2=780
608ZZ 軸承 $12*2=24

合計 804 元, 老闆說算 800 即可.

我打算用一個 6mm 的 20 或 30 齒皮帶輪充當聯軸器將兩個發電機連成一個機組 :

【UCI電子】2GT 同步帶輪 16齒 20齒 帶寬6mm 內孔5 內孔8 GT2 16Z傳動皮帶輪 $45
【UCI電子】2GT-6mm橡膠開口同步皮帶S2M GT2 MXL 同步帶 $60 (100cm)

皮帶與皮帶輪鄉下五金行可能有賣, 若週日回去找沒有的話再網購.

如何翻砂製模

最近在研究如何自製小型水力發電水車的皮帶輪時, 看到 Youtube 上的一部以翻砂製作鋁製皮帶輪方法的影片, 值得記錄下來參考 :

Metal Casting at Home Part 64. Casting and Machining a Toothed Pulley




這影片讓我想起以前在學校也學過一學期木工製模與翻砂的工廠實習課程, 雖然念的是電機, 但學校可能認為機電相關性高, 所以安排了上學期木工+翻砂, 下學期金工車床實習課, 我會對木工有興趣大概就是從那時候開始的.

2017年11月23日 星期四

小型三相交流發電機市調

上週看到屋旁的小圳水流湍急, 想弄個小型水力發電機實驗來收集這川流不息的能源. 水車部分可以用舊腳踏車的輪框, 或者自己木做一個也行. 發電機部分決定用三相交流發電機, 參考 :

http://zoro.ee.ncku.edu.tw/el2011/res/07-power_generator.pdf

我在露天找到下面這款低電壓大電流發電機 :

空調低壓內轉子直流無刷電機 直流無刷發電機 大電流發電馬達 W64 (2A) $500
低壓大電流無刷直流馬達 直流發電機 附整流二極體 $390

這看起來是完全一樣的東西, 但卻價差 110 元. 標價 390 這個隨貨附 6 個整流二極體可將三相交流整成直流電, 賣家在高雄可自取. 其商品說明中提到 :

"此馬達屬於低壓大電流發電機,輸出的電流輕鬆就能突破1000mA,轉速不需要很高就能發出幾十伏電壓,整流後給小電瓶(20AH以內)充電也是OK的"

而標價 $500 元賣家的說明中則說輸出 2A 電流沒問題 :

"此款無刷電機作發電機是很高效的,給電池電瓶充電非常合適,輸出電流2A左右是沒問題的。"

看來此款還蠻符合我的小型水力發電實驗要求的, 其實只要能輸出 1A 以上就能穩定對 18650 模組充電了, 如果將兩組這種發電機以聯軸器組合成一個機組的話, 這樣應該就能輸出 4A 以上的電力了.

另外我在 AliExpress 找到另外一款三相交流發電機 :

Aiyima Three-phase AC Permanent Magnet Wind Generator Hand Generator DIY Homemade used Generator US$24.64+2.11=US$26.75 (約 802 元台幣)

產品說明提到可輸出 3.76A 電流, 而且 380 RPM 就能輸出 90V 電壓, 實在太強了 :

"Measuring single-phase voltage 18.27V
With 12V 50W light measuring single-phase current of 3.76A, smallish, but high efficiency.
4 series plus shift together as long as there are 380rpm will have 90V"

但價格卻不便宜, 一顆要價 800 元左右.

下面這款標題寫直流 50W, 但是接線圖卻要使用附贈的整流器 KPB307, 奇怪, 既然是直流怎還要用整流器呢? 從其兩縣輸出判斷, 這應該是單向交流發電機才對. 說明中沒交代最高輸出電流, 詢問賣家得到 10~110V 的答案 (這是電壓好嗎) :

3424D110直流發電機 50W風力發電機 水力發電機 動力發電馬達 高效能電機 正反轉可調速可發電馬達 $500

橋式整流子 KPB307 在露天沒賣, 但可找到其他的代用品 :

KBU6J 橋式整流子 6安培 耐壓600V 橋式整流子 $10 (12 顆 100 元)
橋式整流子 KBPC806 (8A) $10

另外, 淘寶網有一顆 400W~800W 三相交流發電機似乎不錯 :

三相交流稀土永磁发电机高效发电机400W~800W实验用可定制

但價格也不便宜, 3200 元起跳.

其實, 若要用直流電機, 二手的汽車發電機其實也可以考慮, 提供高達 30A 以上的大電流, 價格在 1000 以上, 例如 :

MIUSUBIHI中華三菱 發電機45A(整理新) 94前威力1.1,95後威利1.1貨,百利800/3缸,多利800 $1200

其他 :

MY6812-120W 12V永磁直流尤奈特有刷馬達 電動滑板車電機 皮帶輪 $890
大扭力 高速直流電機 120V大功率馬達 發電機 電動機 風冷 主軸 W64 $ 1400
限量特價 手搖發電機 帶手搖柄 349 無電容版直出 可點亮20W LED燈 金屬齒輪 耐磨耐用 $349
DIY自制 三相交流永磁发电机12V 风力发电 手摇发电

2017年11月22日 星期三

皮帶輪 (Pulley) 的製作方法

最近在設計我的小型水力發電站, 主要結構是木製水車附帶皮帶輪, 以大輪帶小輪方式將轉速放大, 帶動三相交流發電機發電. 小輪有現成的金屬製帶齒的可用, 例如 :

【愛研】GT2 2GT 30齒 內徑8mm 同步輪 同步齒輪 皮帶輪 $49
【UCI電子】2GT 同步帶輪 16齒 20齒 帶寬6mm 內孔5 內孔8 GT2 16Z傳動皮帶輪 $45
【UCI電子】2GT-6mm橡膠開口同步皮帶S2M GT2 MXL 同步帶 $6 (10cm)
[3DPW] 同步輪GT2 20齒 內8mm 皮帶寬度9mm 時規皮帶用 $95
【3DPRT 專賣店】★876★ 2GT GT2 寬 9MM 周長 500 到 599 多種規格 閉口皮帶 環狀皮帶

但是要裝在水車上的大輪找遍露天商場都沒有合意的, 只能自己木做一個了. 今天在 Youtube 看到下面這部自製皮帶輪的影片非常值得參考 :

Making Wooden Step Pulleys




作者用線鋸機先裁出三塊圓形木板, 膠合後用木工車床修邊並切出皮帶溝, 最後軸心鑽洞再噴漆.

下面這部影片則是金工的, 作者利用回收的飲料鋁罐熔化後做成鋁餅, 再用車床車出皮帶溝 :

Homemade Pulley Made From Beer Cans - Melting Aluminum #3




總之, 有車床的話一切都好辦.

Opera 的新功能 : 網頁快照

昨天 Opera 瀏覽器升級為 49.0.2725.39 (PGO) 版, 新增了網頁快照功能, 直按 Ctrl+Shift+5 就可以框選網頁中要擷取的區域, 按 "捕捉" 鈕擷取圖像後自動開啟 Opera 的圖片編輯器, 可畫線, 加上箭頭, 小圖示, 或局部模糊化等等 :






按 "儲存圖片" 可將編輯後的影像存成 png 檔. 雖然編輯功能沒有 Picpick 強, 但也不失為一個方便好用的小工具.

2017年11月20日 星期一

J.Fla 翻唱的 Shape of You

上週三菁菁的同學芸菁與怡蓉來家裡討論學校作業, 一邊聽音樂一邊討論她們的劇本, 其中有一首蠻好聽的, 是 J.Fla 翻唱自英國歌手 Ed Sheeran 的 Shape of You  :

Ed Sheeran - Shape Of You ( cover by J.Fla )




J.Fla (金貞花) 是韓裔美國人, 是最近在網路以翻唱聞名, 人氣直線竄升的網紅, 參考 :

https://zh.wikipedia.org/wiki/J.Fla
3位不能錯過的新生代 Cover 網紅!

聽聽這首 Shape of You 原唱者 Ed Sheeran 的官方 MV :

Ed Sheeran - Shape of You [Official Video]




感覺不一樣齁! 不知道是不是先入為主的關係, 我怎麼覺得好像 J.Fla 唱得比較好聽呢. 不過, 這部 MV 劇情很有意思, 只是不解為何女主角要不告而別呢?

2017年11月19日 星期日

2017 年第 45 周記事 : 木瓜粄作法

週六下午小舅媽又 Line 我, 叫我晚上回去別煮, 載爸一起去她家吃牛肉麵, 哇, 連續兩個周末都給舅媽請, 只好叫爸將退冰的吳郭魚再冰回去. 剛好婷婷也放周末假, 把已到貨的安博盒子帶回鄉下了, 順便把貨款親自交給她.

吃過晚餐舅媽說要示範木瓜粄的做法, 材料如下 :

木瓜 : 2~3 顆
麵粉 : 適量 (約 100 g)
太白粉 : 適量 (約 3~5 匙)
油蔥酥 : 2~3 匙
胡椒 : 2~3 匙
鹽 : 一匙 (不加亦可)

醬汁
蒜頭 : 2~3 片
醬油 : 適量 (約 3~4 匙)

先將木瓜刨絲, 放 2~3 匙油蔥酥熱鍋 (中火), 倒入木瓜絲, 加入 2~3 匙胡椒粉, 加一碗水拌炒至熟後, 倒入盆中加入麵粉, 太白粉攪拌成糊狀 (不要太水). 平底鍋加油熱鍋, 舀 2~3 球木瓜麵糊至平底鍋中壓平煎至兩面呈金黃色即可.


油蔥酥與木瓜絲放入鍋中

加水拌炒

炒熟後倒入盆中加入麵粉太白粉攪成糊狀

放入鍋中壓平煎至兩邊呈金黃色

煎好後, 將蒜頭切小丁, 加入醬油與少許醋做成醬汁淋在木瓜粄上, 那甜中帶鹹酸的滋味, 沒吃過是無法體會的.

今日下午料理做完之後開始進行水車製作先前準備, 早上去買菜時路經五金行買了 3 張砂紙 (一張 10 元) 回來, 下午拿出上周拆下來的廢棄腳踏車輪框磨去鏽蝕, 由於銹得很深, 磨到手都痠了還是不夠亮, 只好下周繼續 :




這兩天屋旁的小水圳水量大增, 湍急的河水聲表示能量不斷地釋出, 如果能架個小水車發電多好, 這可是 24 小時不斷地發電喔! 不像太陽能只有白天才能發電. 下午勘查了一下, 我覺得蓮霧樹旁的圍牆外的水流最湍急, 最適合架小水車, 發電機與變壓器則可鎖在圍牆上, 水車透過皮帶或鍊條帶動發電機轉動 :




我量了今天的水位大約 10 公分深, 足夠帶動水輪機, 其實只要有 4 公分以上就行了.