title: 如果我提前起床,鬧鍾你就別響
toc: true
comments: true
date: 2016-11-07 22:56:21
tags: ['Python', 'Automate', 'Workflow']
category: ['Python']
本文首發地址http://kingname.info/2016/11/07/autoalarmclock/,轉載請注明出處
鬧鍾已經成了我們生活中必不可少的東西。如果全球每個國家的當地時間明天早上,所有的鬧鍾突然都不響了,不知道會有多少人上班遲到。
然而我們要討論另外一種情況,鬧鍾每天定時響起來,真的是最好的情況嗎?如果你有過醒來以后等鬧鍾的經歷,如果你總是在鬧鍾響之前就起來了,那么你會不會希望鬧鍾能知道你已經起來了。如果你提前醒了,那么鬧鍾就不響,只有你一直睡着的時候,鬧鍾才會按時響起來。
由於和出版社簽訂了出書的計划,我需要每天早上7點鍾起床打開電腦寫稿。寫到8點20出門上班。如果中途鬧鍾響起來,去關它的時間可能就會讓我的思路斷掉。但是如果有時候晚上睡晚了,那么早上就會暫停寫稿。這個時候我希望我的鬧鍾能在7點45叫醒我,讓我有時間洗漱和收拾。
我希望這個過程不需要我去參與。只要早上我打開了電腦,當日的鬧鍾自動取消。
於是就有了AutoAlarmClock這個項目。
設計思路
AutoAlarmClock分為三個部分,安卓手機上的Automate,VPS上面的Web Server和Mac OS上面的一行命令。
每天早上7點40,手機上的Automate會訪問一個URL A:http://autoemo.kingname.info:745/alarm_clock,只要沒有得到返回信息“No”,無論是網絡問題,還是因為服務器返回的是其他信息,都會設定一個鬧鍾,在7點45分響起來。只有訪問URL以后,服務器返回“No”,那么就不設鬧鍾。
對於電腦來說,每天早上7點30分,如果電腦是開着的,說明我正在工作。這個時候電腦就會自動訪問一個URL B:http://autoemo.kingname.info:745/set_alarm.只有這個URL被訪問過,之前給Automate訪問的URL A才會返回“No”。
設計實現
Web Server
Web Server是手機和電腦之間的橋梁。它是使用Python的Flask框架寫成的。代碼已經放在了Github上:AutoAlarmClock. 包括空行總共只有32行代碼。
from flask import Flask
from datetime import date
import os
app = Flask(__name__)
@app.route('/')
def index():
return 'please visit my blog at http://kingname.info'
@app.route("/alarm_clock")
def alarm_clock():
if os.path.exists('alarmclock.txt'):
with open('alarmclock.txt') as f:
date_in_txt = f.read()
today = str(date.today())
if date_in_txt == today:
return 'No'
return 'Yes'
@app.route('/set_alarm')
def set_alarm():
with open('alarmclock.txt', 'w') as f:
f.write(str(date.today()))
return 'OK'
if __name__ == "__main__":
app.run(host='0.0.0.0', port=745)
由於這個Web Server每天只訪問兩次,所以沒有必要使用數據庫或者做線程安全的設置。數據只需要使用一個文本文件作為中轉即可。一旦http://autoemo.kingname.info:745/set_alarm這個鏈接被訪問,就會在當前目錄創建一個alarmclock.txt文件,里面存放的是今天的日期。當http://autoemo.kingname.info:745/alarm_clock被訪問的時候,它會去檢查alarmclock.txt,如果這個文件不存在,或者里面的日期不是今天的日期,那么它就會返回“Yes”。只有當alarmclock.txt存在,並且里面的內容為今天的日期,它才會返回“No”。
電腦端
電腦只需要訪問http://autoemo.kingname.info:745/set_alarm.由於Mac Book Pro只休眠,不關機,無法使用開機啟動的方法來觸發這個URL的訪問。所以我使用了Crontab這個定時任務。因為在電腦休眠的時候,Crontab的定時任務是不會執行的,只有我在電腦上工作的時候,電腦開着才會訪問這個URL,並讓它生成記錄今天日期的文本文件。
通過下面的命令設定Crontab定時任務,編輯器我選擇的是VIM:
env EDITOR=vim crontab -e
定時任務設定為:
30 07 * * * curl -G http://autoemo.kingname.info:745/set_alarm
表示每天的7點30分使用curl訪問后面的鏈接。
Crontab在Linux下面也可以正常使用。
如果你的電腦為Windows,因為Windows電腦一般在晚上睡覺時會關機,所以訪問URL的工作可以設定開機啟動來完成。
首先創建一個EnableAlarmClock.py文件:
import requests
requests.get('http://autoemo.kingname.info:745/set_alarm')
這個文件用到了Python的requests庫,如果你沒有的話,請使用pip安裝。
再創建一個EnableAlarmClock.bat文件,文件內容如下:
python EnableAlarmClock.py
打開Windows的 任務計划 ,觸發器選擇“當前用戶登錄時”,操作選擇“啟動程序”,並填寫EnableAlarmClock.bat的路徑,如下圖所示:

這樣,每次開機登錄桌面的時候,程序自動就會訪問設定鬧鍾的頁面了。
手機端
Automate是安卓上面的一個強大的自動化工具,類似於IFTTT和iOS上面的Workflow。
在Automate中創建一個Flow,如下圖所示:

其中涉及到了"Time await", "HTTP request", "Expression true?", "Alarm add"這幾個組件。
-
"Time await"的設置如下圖所示:

-
"HTTP request"的設置為下面兩張圖:


-
"Alarm add"的設置為下圖:

這里由於沒有設置“REPEAT WEEKDAYS”這一項,所以鬧鍾都是一次性的,關了以后,第二天需要再根據實際情況來讓Automate來決定是否需要創建。
設置並啟動這個Flow以后,每天早上的鬧鍾就可以根據你是否在電腦前面工作而決定要不要鬧響了。
