对Nest Home / Away API进行反向工程

2020-12-18 15:55:00

不久前,我购买了Nest相机,因为我喜欢仅需提供电源和WiFi连接即可获得良好的安全系统的想法。 您可以使用Works with Nest(其开放式API)控制它的事实是做出此决定的主要因素。 然后,Google购买了Nest,并禁止未及时注册的用户(包括我)访问。 有希望将很快“创建”一个新的开放API。 最终,他们发布了智能设备管理API,尽管您可以做一些事情(获取摄像头数据流),但无法设置“家庭/离开”状态。 您可以在此处了解更多信息,但是TL; DR Nest摄像机的运动/声音警报只有在将其设置为“ Away”时才会触发。 由于我不想进入的原因,自动“回家/离开”功能对我不起作用,因此,我需要一种通过代码控制它的方法,以便可以将其自动化,这是一件好事。

像所有专业人士一样,我的第一个尝试就是打开DevTools并打开Nest webapp,单击Home / Away切换,复制为curl,从CLI运行它,等等。

curl命令末尾的主机端点很好地暗示了他们正在使用gRPC,到目前为止我还没有任何经验。

它与我们之前看到的二进制有效负载相匹配,现在变得令人兴奋了!

由于简单的有效负载重播没有任何作用,因此我需要弄清楚其中实际存在的内容。

第一个(令人惊讶的)问题实际上是将二进制有效负载放入文本文件中,我猜想二进制文件在浏览器和我要粘贴的文件之间被弄乱了。

这里的“使用内容另存为HAR”功能非常有用,特别是因为二进制文件下面有一个base64编码的字段。

猫set-away-home.nest.com.har格伦grep' json.log.entries [1] .response.content.text' \ |切-d'"' -f 2 \ | base64 -d \ | base64 -d

(如果您不了解gron,则一定要检查一下,它使JSON可以使用grep)

查看protobuf的官方文档,似乎我需要.proto文件来做任何有用的事情。

我无法弄清楚如何从Nest网站中提取内容,或者甚至无法找到。

1 {1 {1:" STRUCTURE_XXXXXXXXXXXXXXXX" 2:" XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" } 2 {1 {1:" STRUCTURE_XXXXXXXXXXXXXXXX" 2:" structure_mode" 3:" XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" } 2:4 4 {1 {1:" type.nestlabs.com/nest.trait.occupancy.StructureModeTrait.StructureModeChangeResponse" 2 {1:1}}} 6 {1 {1:" STRUCTURE_XXXXXXXXXXXXXXXXXXX" 2:" structure_mode" 3:" XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" } 2 {1:" type.nestlabs.com/nest.trait.occupancy.StructureModeTrait.StructureModeChangeRequest" 2 {1:2 2:1 3 {1:" USER_XXXXXXXXXXXXXXXX" }}} 3 {1:XXXXXXXXXX 2:XXXXXXXXX}}}} 15:"" 2:"" 15:" \ 000 \ 000"

然后,我尝试通过上面的输出手动创建.proto文件。

通过运气(也就是在GitHub上搜索这些类型),我发现比我聪明得多的人实际上已经设法从Nest网站提取了原始文件,谢谢陌生人!

启动IDE,并按照protobuf教程中的内容来构建有效负载。

我敢肯定,绝大部分的困难都来自于我以前从未使用过protobuf,但我也花了一点时间才意识到,他们将我们关心的命令(StructureModeChangeRequest)序列化为通用类型(ResourceCommandRequest),然后再进行序列化。

最终,我能够将protobuf有效载荷发送到Nest API,哦,天哪,看到图标从“ Home”切换到“ Away”就像圣诞节初一样:)

比较原始请求中的标头,我可以看到有一个X-Accept-Response-Streaming:true标头,添加它会导致连接按预期直接关闭。

我将所有内容很好地打包到GitHub存储库中,然后继续进行最后一部分。

这里的标准方法是在所有“家用”电话上安装一些位置跟踪器,并将其定期发送到服务器,然后由服务器决定何时切换Nest状态。

尽管我实际上构建了一个android位置共享应用程序,但由于必须在电池寿命和响应能力之间进行权衡,因此我不喜欢这种方法。

我还研究了Google位置信息共享,但是它涉及到创建另一个Google帐户,与其永久共享我的位置并将其用作来源。太脆弱了。

如果响应被拒绝连接,则它们位于网络/“家庭”上。

好吧,如果您很奇怪并且手机上装有服务器,也许也可以接受连接。

我仍然对这种方法的效果感到惊讶,因为我在网上读了很多“不要这样做”,原因如下:

2020-12-17 09:36:07 INFO找到了主机:[' 192.168.0.30&#39 ;,' 192.168.0.31'] 2020-12-17 09:36:07 INFO 192.168.0.30是home2020-12-17 09:36:09 INFO将状态设置为:home(200)2020-12-17 09:41:09 INFO 192.168.0.30是home2020-12-17 09:46:13 INFO 192.168 .0.31是home2020-12-17 09:51:17 INFO 192.168.0.31是home [..] 2020-12-17 11:17:29 INFO将状态设置为:离开(200)2020-12-17 12:35 :11 INFO 192.168.0.31是home2020-12-17 12:35:12 INFO将状态设置为:home(200)2020-12-17 12:40:16 INFO 192.168.0.31是home

我不得不花一天时间去做一些应该起作用的事情,或者至少我应该自己拥有改变的机会,这真是太糟糕了。

如果摄像机的质量不是很高,我会放弃它,然后使用DVR / NVR进行自我托管。

构建所有功能本来需要更长的时间,但是我可以控制每个部分。

Nest应用仍然困扰着我迁移到Google帐户,因此,让我们来看看该解决方案实际可以使用多长时间。