我的自动化生活
我也幻想着可以过上Jarvis的生活。
早上起来就可以得到天气信息、回到家就可以打开热水器、语音控制家电、随时通知你有一条新的快递信息等等。既然有树莓派和服务器,平时又比较闲懒,为何不尝试实现一下呢?
首先需要一个终端用于接受信息,目前想到了三个方式:
- 显示器显示
- 通过扬声器播放
- 发送到手机通知
显示器显示确实是一个好的方式,可以DIY页面,会更加的炫酷,但是考虑到长时间开启显示器比较浪费,所以选择了「通过扬声器播放」和「发送到手机通知」,Home Assistant可以使用MPD组件通过树莓派连接音响,使用Google的TTS就可以做到声音推送。
The
mpd
platform allows you to control a Music Player Daemon from Home Assistant. Unfortunately you will not be able to manipulate the playlist (add or delete songs) or add transitions between the songs.
而更为详细的通知选择了推送到手机中。
Pushover
虽然有很多可以作为接受通知推送的客户端,比如IFTTT、钉钉、企业微信、微信等等,但是用过一段时间后感觉不太满意:
- 与其他消息混杂在一起,消息权重不明确
- 会有推送限制(微信公众号1次/1天)
- 不能自定义消息
所以使用了Pushover来接受所有WebHook或者服务器推送的消息,Pushover 是一个通知服务,它对外提供了丰富的 API,只要调用 API 就可以给客户端发送推送通知。

同时也可以通过不同的「Notification」设置不同的声音,就可以不看手机就知道是哪种类型的通知了。最重要最有用的一点就是可以得通知增加一个等级:
By default, messages have normal priority (a
priority
of0
). Messages may be sent with a different priority that affects how the message is presented to the user. Please use your best judgement when sending messages to other users and specifying a message priority. Specifying a message priority does not affect queueing or routing priority and only affects how device clients display them.
所以Pushover是整个自动化的主要终端,所有的消息都会被推送在这里。
JsBox
这应该是我认为在iOS平台中最喜欢的一款APP。
最早接触钟大的时候还是在限免Pin的时候,然后Pin加入了xTeko(JsBox Lite)可以使用JavaScript写一些简单的脚本。后来当JsBox独立出来后就赶快买了下来。(当时还只是30RMB,后来便涨到50RMB了,真是早买早享受。
然后就疯狂安利朋友,以至于送朋友生日礼物直接送了JsBox套装:

如果你还不知道JsBox可以先看看文档,说不定就种草了!
公交信息
JsBox有定时器触发模式,可以在某个时间点推送一条通知,更舒服的是通知中也可以执行脚本操作,所以可以在某个时间(手动)执行一条脚本。
下班时间 -> 发送通知 -> 重按通知 -> 获取公交信息
公司附近有两个公交站点,距离不一样。每个公交站点又有不同的可以回家的公交,所以这个脚本就是获取可以到家的所有公交信息,计算到站的时间,然后按照时间进行排序,就可以得到最快到站的是哪辆公交车了。

不得不说杭州实时公交的信息很丰富,连车速都可以获取到。(获取可以动态计算到达车站的步速?
快递信息
很多快递信息还是会发送一条短息告诉你取件码是多少,对于短信已经成为「验证码收纳箱」的我来说确实不是一件方便的事情,因为不知不觉就忘记了还有收件短信这个事情。
所以这个脚本很简单,当快递信息来的之后,长按短信复制,打开这个脚本,脚本会分析剪贴板的文字内容,若发现有「验证码」、「取件码」、「收货码」等字样的信息正则出来号码之后存储在SQLlite中。

之所以会存储在SQLlite中是想尝试一下使用JsBox操作数据库,当然,放在本地存储中也是完全可以的。
为了每次懒得改代码加入了一个简单的设置:

和「快接指令」APP不同的是,JsBox提供了更多的接口和更方便的操作,听说iOS13增加了快接指令自动化。期待一下,之后应该就可以联动JsBox自动推送了。
AutoCenter
AutoCenter是使用Laravel(5.8)框架写的一个定时任务的框架,部署运行在阿里云。通过这个框架解决了一些不能通过Zapier或者IFTTT运行的或者是其他接口的一些任务。
同时封装了一下Pushover的Facades,HTTP请求使用了GuzzleHttp
:
class PushOver
{
/**
* 通过PushOver向终端发送消息
* @param $title
* @param $content
* @param int $level
* @return bool
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public static function send($title, $content, $level = 0)
{
$client = new Client();
$response = $client->request('POST', 'https://api.pushover.net/1/messages.json', [
'form_params' => [
'token' => env('PUSHOVER_TOKEN'),
'user' => env('PUSHOVER_USER'),
'device' => env('PUSHOVER_DEVICE'),
'title' => $title . (env('APP_DEBUG') ? '-DEBUG' : ''),
'message' => $content,
'priority' => $level,
'html' => 1,
]
]);
$body = json_decode($response->getBody(), true);
if ($body['status'] == 1) {
return true;
}
Log::error('PUSHOVER发送失败');
return false;
}
}
快递信息推送
除了短信的快递信息,小区这边都会使用蜂站来使用公众号推送,然而…关注的公众号太多了经常看不到快递信息。
所以抓了一下蜂站的包,找到了「待领取包裹」的接口,每30分钟请求一下查询是否有快递,再推送到Pushover就可以了!
$response = $this->client->request('GET', 'http://wx.fengzhan.com/wx/getExpress?', [
'query' => [
'openid' => env('EXPRESS_OPENID'),
'appid' => env('EXPRESS_APPID'),
'mobilenumber' => env('EXPRESS_PHONE')
]
]);
$list = json_decode($response->getBody(), true);
if (!$list || is_null($list)) {
return;
}
foreach ($list as $item) {
if (!Cache::has("express:{$item['expcode']}")) {
$this->push->send('#新的快递提醒', "来自{$item['address']}的{$item['expName']}快递,取件码:{$item['shelfCode']}");
Cache::put("express:{$item['expcode']}", 'true', Carbon::now()->addDays(2));
}
}
服务器流量
由于某些服务器是包月包流量的那种,尤其是在家中用树莓派做了全局代理供switch更新软件、打Splatoon2和马车等联机后,合理控制流量就很重要。
所以每天上午9点30分查询一下服务器流量再推送过来。
public function getData()
{
$response = $this->client->request('GET', 'https://api.64clouds.com/v1/getServiceInfo?api_key=' . env('VPN_KEY'));
$data = json_decode($response->getBody(), true);
$factor = 1073741824; //除数因子 Rlcw
$used = round($data['data_counter'] / $factor, 2);
$total = round($data['plan_monthly_data'] / $factor, 2);
$reset = date('Y年m月d日', $data['data_next_reset']); //下次流量周期
$left = $total - $used; //剩余流量
$today = date('Y年m月d日', time());
$this->push->send('#服务器流量', "截止{$today},已使用{$used}GB,流量剩余{$left}GB于{$reset}到达新周期");
}
签到(Beta)
既然快递都懒得查看了,那一些APP的签到肯定也要「自动」。签到(Beta)提供了一些网站的签到服务,由PHP强力驱动,使用Laravel(5.8)框架。
这不是一个即开即用的程序,可能需要以下基础:
- 了解使用Charles进行抓包方式
- 了解HTTP协议和请求方式
- 了解JSON
- 了解Cookie、UA等一些基本的请求Header和请求Body体
- 能够忍受炒鸡简单的界面和不怎么有逻辑性的操作
前端偷懒直接使用了Bootstrap3.0,做了一个简单的模板:可以创建模板从而兼容不同接口的签到。

这样子就不用再打开APP进行签到了。
Zapier & IFTTT
和IFTTT相似,Zapier也是一个工作流服务。
不同于 IFTTT 只支持串联两个服务,Zapier 支持串联多个服务,让你可以建立一套有更复杂需求的工作流。
看起来很强大!只是...目前只用到了Webhook这个服务。
转发 Disqus
Disqus没有客户端、同时Webhook只能在Wordpress中使用,并且每次Disqus发送的邮件都被拉到垃圾邮件里,所以使用Zapier转发了Disqus评论再通过Webhook发送到Pushover里。
转发到Telegram
其他的,例如微博、Twitter、Ins等消息都是用IFTTT转发到了Talagram群组中。
Home Assistant
Home Assistant系统提供了自动化操作,可以将不同的实体串联起来来实现自动化。
比如晚上定时关闭电风扇:
- id: '1553826382737'
alias: 定时关闭风扇
trigger:
- at: 01:00
platform: time
condition:
- condition: state
entity_id: switch.plug_fans
state: 'on'
action:
- data:
entity_id: switch.plug_fans
service: switch.turn_off
一些家居自动化
所以使用Home Assistant和Homekit联动,自动化就会方便很多:
- 到达家中后安防模式调整为「在家」,关闭所有电器
- 出门后安防模式调整为「离家」,打开热水器
- 夜晚自动关闭空调
- 当Home Assistant服务关闭/启动时发送通知
- 热水器完成加热时发送通知
- 温度异常(过高、过低)发送通知
当然,有些自动化操作还需要「状态」,比如周几执行、几点执行等。现在基本上很少去手动操作所有的电器了。到家后,拿上手柄就去救塞尔达去了。(逃
快捷指令
目前的自动化并没有那么的「自动」,有些还需要手动执行,通过快捷指令和Siri,这样走在路上直接「Hey, Siri」就可以,或者通过 Watch,抬腕后就可以发送指令了。另外,如果Apple开放HomePod的接口就更完美了。
看了WWDC发布会好像iOS13会有使用Siri读出通知的特性,那么以后使用AirPods走在路上,会不会:
> You have a new express info, Sir.
> Welcome Home, Sir. The water heater has been opened.
哈哈哈,想想就激动。
最后
这是目前想到的可以偷懒的方式,其实在大三的时候就已经挖了一个坑,当时使用的Mui框架和咕咕鸡:

然后简单的链接了咕咕鸡后就鸽了,直到毕业之后有了自己的屋子终于可以随心所欲的折腾了。哦对了,我还给这个自动化起了一个非常可爱的名字:酸奶。👇 越来越像想象中的生活了:🎬链接
🎉 期待有一天可以更加完善。