今天給你們介紹一個本身突發奇想寫的一個小玩意,主要是解決本身一個痛點,若是你也有相似的需求,不妨一試。linux
白天在公司上班,家裏的臺式機都是關機的,晚上回家以後纔開機,天天晚上回家都須要手動開機,不勝其煩,因而想能不能我一回家電腦就自動開機呢?來點智能的感受git
通過我靈機一動,我就想起來了我買了好幾年的小米路由器mini,這是一臺基於openWrt系統的智能路由器,說白了就是一個嵌入式的Linux,通過root以後就能夠ssh遠程登陸上去,能夠跑一些Linux應用,並且Golang寫的程序也能夠交叉編譯成這個平臺的執行文件。github
喚醒電腦其實並不難,如今電腦主板都支持網絡喚醒功能,也就是所謂的WOL(wake on lan),主要原理就是像電腦9端口發送一個所謂的 「magic package」,其實就是一個數據包。啓用WOL功能只須要在BIOS裏面設置一下就可,若是你連什麼是BIOS都不知道,那就打擾了。。。api
我之前試過在家裏路由器作了端口映射(該死的NAT),手機上面下載一個WOL的APP,就能夠遠程喚醒家裏的電腦,而後使用SSH登陸作一些事情,其實這個功能挺實用,不過我感受不少人應該歷來沒用過。不瞭解的能夠看一下這篇文章的介紹(網絡喚醒設置方式)bash
運行程序的路由器有了,網絡喚醒也不是問題,最後還差一個,怎麼實現我一回家就自動喚醒呢? 這裏選擇了一個比較low的方式,ping。。。對,你沒看錯,就是ping 網絡
在路由器上面運行一個使用Golang編寫的程序,這個程序經過ping判斷電腦ip是否在線,若是ping的通說明電腦在線,ping不通就說明沒開機,若是沒開機,那麼就開始ping個人手機的ip,若是可以ping通則就向個人電腦發送一個網絡喚醒包。ssh
哈哈,就是這麼簡單,雖然並非那麼優雅,可是確實夠用,通過我測試,下班回家後一進門電腦就開機了,反應仍是挺快速的,個人定時任務是10s執行一次。性能
package main
import (
"log"
"net"
"time"
"wakeOnLan/ping"
"wakeOnLan/wol"
)
const (
IP = "192.168.31.214" //手機的ip
HOST = "192.168.31.8" //電腦ip
PORT = ":9" //wol端口,默認都是9
MAC = "4C:ED:FB:94:71:0F" //電腦mac地址
)
func main() {
// 晚上8點到11點之間才觸發,因爲路由器時區有問題,這裏手動+8小時
log.Println("Now Time is: " + time.Now().Add(8*time.Hour).Format("2006-01-02 15:04:05"))
hour := time.Now().Hour() + 8
if hour < 20 || hour > 23 {
return
}
// 判斷當前主機是否已經在線
addr, err := net.ResolveIPAddr("ip4", HOST)
err = ping.Ping(1, addr)
if err == nil {
log.Println("target host is online")
} else {
// 當手機連入WiFi的時候發送喚醒數據包
addr, err := net.ResolveIPAddr("ip4", IP)
if err = ping.Ping(1, addr); err != nil {
log.Println("ip unreachable,error:" + err.Error())
} else {
err := wol.Wol(HOST+PORT, MAC)
if err != nil {
log.Println("wake on lan failed, error:" + err.Error())
}
}
}
}
複製代碼
後面我會附上github連接,這裏簡單看一下main裏面的代碼,邏輯比較簡單,首先定義了幾個常量,這裏沒有寫成配置文件,若是你須要使用的話不要忘了改爲本身的ip和mac,而後判斷了晚上8點到11點之間才觸發,由於通常我下班都是這個時間段到家。測試
還有一個問題就是個人小米路由器時區有問題,因此獲取到的是UTC的時間,我這裏手動加了8小時。ui
後面就是一些簡單的邏輯,其中ping和wol是封裝好的2個Golang實現的方法,網上找的,可是原理並不難,就是按照協議去發一些包而已。
個人小米路由器是很早的mini,內置存儲空間不足,類型爲tmpfs的都是內存虛擬的,一旦路由器重啓裏面的數據就沒了!
root@XiaoQiang:~# df -h
Filesystem Size Used Available Use% Mounted on
rootfs 10.8M 10.8M 0 100% /
/dev/root 10.8M 10.8M 0 100% /
tmpfs 61.0M 3.3M 57.7M 5% /tmp
tmpfs 512.0K 0 512.0K 0% /dev
tmpfs 61.0M 3.3M 57.7M 5% /extdisks
/dev/mtdblock7 1.0M 768.0K 256.0K 75% /data
/dev/mtdblock7 1.0M 768.0K 256.0K 75% /etc
tmpfs 61.0M 3.3M 57.7M 5% /userdisk/sysapihttpd
/dev/root 1.0M 768.0K 256.0K 75% /mnt
/dev/mtdblock7 1.0M 768.0K 256.0K 75% /mnt
複製代碼
最終編譯後的可執行文件大概是2MB多一點,有點大,因此我寫了個腳本(run.sh)判斷可執行文件是否存在,若是不存在就從github下載文件到 /extdisks 目錄,把這個腳本放到 /data 目錄,這個目錄重啓還在,雖然大小隻有256k,放個腳本仍是足夠的!
而後還有一個build.sh腳本是用來編譯的,若是你修改了代碼,使用這個腳本直接編譯就好了,內容以下:
GOOS=linux GOARCH=mipsle go build -ldflags "-s -w"
複製代碼
mipsle實際上是小米路由器的系統平臺類型,我不肯定其餘路由器也是這個,你們能夠試試!
Golang的跨平臺交叉編譯很強大,嵌入式開發也不是問題,配合家裏的智能路由器,其實就是一臺小電腦了,跑點小應用什麼的兩不誤,主要是省電,低功耗,雖然性能也不咋滴。
附上github連接: github.com/wangbjun/wa…,感興趣的點個star,謝謝!