當你回家時電腦本身開機(Golang)

今天給你們介紹一個本身突發奇想寫的一個小玩意,主要是解決本身一個痛點,若是你也有相似的需求,不妨一試。linux

1.應用場景

白天在公司上班,家裏的臺式機都是關機的,晚上回家以後纔開機,天天晚上回家都須要手動開機,不勝其煩,因而想能不能我一回家電腦就自動開機呢?來點智能的感受git

2.思考

通過我靈機一動,我就想起來了我買了好幾年的小米路由器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 網絡

3.解決方案

在路由器上面運行一個使用Golang編寫的程序,這個程序經過ping判斷電腦ip是否在線,若是ping的通說明電腦在線,ping不通就說明沒開機,若是沒開機,那麼就開始ping個人手機的ip,若是可以ping通則就向個人電腦發送一個網絡喚醒包。ssh

哈哈,就是這麼簡單,雖然並非那麼優雅,可是確實夠用,通過我測試,下班回家後一進門電腦就開機了,反應仍是挺快速的,個人定時任務是10s執行一次。性能

4.主要代碼

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實現的方法,網上找的,可是原理並不難,就是按照協議去發一些包而已。

5.問題

個人小米路由器是很早的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實際上是小米路由器的系統平臺類型,我不肯定其餘路由器也是這個,你們能夠試試!

6.總結

Golang的跨平臺交叉編譯很強大,嵌入式開發也不是問題,配合家裏的智能路由器,其實就是一臺小電腦了,跑點小應用什麼的兩不誤,主要是省電,低功耗,雖然性能也不咋滴。

附上github連接: github.com/wangbjun/wa…,感興趣的點個star,謝謝!

相關文章
相關標籤/搜索