當 Alexa 遇上 ESP8266 (一)
https://www.birdandgua.net/bird/2017/12/when_alexa_meets_esp8266-1/
去年的 AWS 的 re:Invent 上,我見識了 Alexa Voice service 的本事後深受震撼,我除了帶了幾顆 Echo 和 Echo Dot 回來研究外,也想著要用 ESP8266 來做可以讓 Alexa 控制的裝置。
其實回來之後沒多久我就做出來了,但這篇文章一直沒寫。等到我想寫文章、把寫好的程式再度拿出來看時,發現我所使用的 library 已經大幅更新,我原來寫的程式根本沒辦法 compile,只好整個砍掉重練。
時隔一年,這幾天正值 re:Invent 2017 進行中。今年因為種種因素我無法成行,就用這篇文章來紀念去年此時的這個 idea 和那時的熱血吧。
偽裝
要做一個讓 Alexa 可以控制的裝置有很多方法,但大部份的方法都要用到 AWS 的 IoT 或 serverless 服務,至少要寫一點 Lamda script 去處理 Alexa 跟裝置間的互動,或者要走 MQTT 透過 IFTTT 之類的服務來運作。一但用了 backend server 的服務,被控裝置的安裝就要處理註冊和認證等問題,操作上會變得很麻煩。
尋尋覓覓後,我發現有另一種更聰明的做法: 偽裝。
Alexa 支援一系列的智慧插座,可以用 Alexa 控制插座電源的開或關,而這其中最有名的就是 Belkin 出的 Wemo Switch。Wemo Switch 必需跟執行 Alexa 的 Echo 或 Echo Dot 位在同一個 WiFi 網路之下才能運作,因此就有人推測它們倆可能是在 LAN 上直接溝通,而不經過雲上的 server。
有一位很有名的 maker,Chris Derossi,利用 Wireshark這個老牌的 network sniffer 監聽 Echo 跟 Wemo Switch 之間的通訊後,解開了這個謎。Echo 跟 Wemo Switch 都沒有 Ethernet 接口,因此只能用 WiFi sniffer 來監聽。這張圖發表在他原來的部落格文章 Amazon Echo and Home Automation 中:
原來 Echo 跟 Wemo Switch 之間是這麼運作的:
- 當使用者第一次設定 Wemo Switch 時,要先對 Echo 喊 “Alexa, descover devices”。此時 Echo 會利用 UDP broadcast 送出一個 UPnP 的 SSDP 請求,SSDP 是 UPnP 控制器用來在網路上尋找裝置用的協定,它是一個 HTTP request,帶有一種叫 M-SEARCH 的 method,只有 header 沒有 body,送往 IPv4 的 multicast 地址 239.255.255.250:1900。
- 同一個網路上的 Wemo Switch 都聽得到 IP multicast。它們發現這個 HTTP request 是在叫自己後,就會回傳一個 HTTP response 給發出 IP multicast 的 Echo,裡面最重要的訊息是一個 URL。這個 URL 指向一個 XML 檔,用來描述裝置本身的屬性。這時的回覆會來自網路上的多個裝置,因為每個收到 IP multicast 的 Wemo switch 都會回答,所以網路會有一小段時間變得很吵。以上都還是走 UDP,所以不需建立連線。
- Echo 收到這些回覆的 URL 後,依序對每個裝置發出 HTTP request,讀取每個裝置的 XML 配置檔。這時的協定通訊協定改走 TCP,會先建立連線,傳送的資料也會變得可靠。
- 每個裝置用 HTTP response 回覆它們的設定檔,也是走 TCP。這個設定檔很長,是一個一百多行的 XML 檔,但其中只有一欄比較重要,就是這個裝置的 friendly name。Friendly name 就是我們幫每一個 Wemo Switch 取的名字,當我們要用 Alexa 的語音服務控制它時,叫的就是這個名字。
- 設定完成後,我們會在 Alexa 的 app 中看到它已經找到的裝置列表,此時就可以用語音控制每個 Wemo Switch 的開或關。
- 當使用者喊出語音指令且 Alexa 聽懂後,它會送出一個 HTTP request 給對應的裝置,裡面有一大串有的沒有的資料,甚至包含了整組包在 XML 裡的 SOAP 指令,但其實我們真正關心的就只是 <BinaryState> 這個 tag 而已,而這個 tag 只有 1 跟 0 兩個值。
- Wemo Switch 收到指令並確認動作後,會回應一個 HTTP response,這是一個固定內容的 acknowledgement。
- Echo 收到確認的回覆後,才會講 “OK”。
Chris Derossi 隨後在另一篇 post 中發佈了一支 Python 程式,用來模擬 Wemo Switch 並回應來自 Alexa 的這些訊息。這支程式叫 fauxmo,有點向 Wemo 致敬的味道。
當 Alexa 遇上 ESP8266 (一)的更多相关文章
- MVC遇上bootstrap后的ajax表单模型验证
MVC遇上bootstrap后的ajax表单验证 使用bootstrap后他由他自带的样式has-error,想要使用它就会比较麻烦,往常使用jqueyr.validate的话只有使用他自己的样式了, ...
- 敏捷遇上UML-需求分析及软件设计最佳实践(郑州站 2014-6-7)
邀请函: 尊敬的阁下:我们将在郑州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实 ...
- 敏捷遇上UML—软创基地马年大会(广州站 2014-4-19)
我们将在广州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战技巧. 时间:2 ...
- 敏捷遇上UML——软创基地马年大会(深圳站 2014-3-15)
邀请函: 尊敬的阁下: 我们将在深圳为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战 ...
- 初识genymotion安装遇上的VirtualBox问题
想必做过Android开发的都讨厌那慢如蜗牛的 eclipse原生Android模拟器吧! 光是启动这个模拟器都得花上两三分钟,慢慢的用起来手机来调试,但那毕竟不是长久之计,也确实不方便,后来知道了g ...
- SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败解决方案
SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败的问题,可作如下尝试: 更新失败后,在windows的[事件查看器→应用程序]中找到来源为MsiInstaller,事件ID为1 ...
- 当创业遇上O2O,新一批死亡名单,看完震惊了!
当创业遇上O2O,故事就开始了,总投入1.6亿.半年开7家便利店.会员猛增至10万……2015半年过去后,很多故事在后面变成了一场创业“事故”,是模式错误还是烧钱过度?这些项目的失败能给国内创业者带来 ...
- LoadRunner - 当DiscuzNT遇上了Loadrunner(下) (转发)
当DiscuzNT遇上了Loadrunner(下) 在之前的两篇文章中,基本上介绍了如何录制脚本和生成并发用户,同时还对测试报告中的几个图表做了简单的说明.今天这篇文章做为这个系列的最后一篇,将会介绍 ...
- LoadRunner - 当DiscuzNT遇上了Loadrunner(中) (转发)
当DiscuzNT遇上了Loadrunner(中) 在上文中,介绍了如果录制脚本和设置脚本执行次数.如果经过调试脚本能够正常工作的话,就可以设置并发用户数并进行压力测试了. 首先我们通过脚本编辑界面上 ...
随机推荐
- 使用Linux的Crontab定时执行PHP脚本
0 */6 * * * /home/kdb/php/bin/php /home/kdb/apache/htdocs/lklkdbplatform/kdb_release/Crontab/index.p ...
- Vue2+VueRouter2+webpack 构建项目实战(一):准备工作
环境准备 首先,要开始工作之前,还是需要把环境搭建好.需要的环境是nodejs+npm,当然现在安装node都自带了npm. 在终端下面输入命令node -v会有版本号出来.就说明安装成功了.输入np ...
- 深入浅出LSTM神经网络
转自:https://www.csdn.net/article/2015-06-05/2824880 LSTM递归神经网络RNN长短期记忆 摘要:根据深度学习三大牛的介绍,LSTM网络已被证明比传 ...
- html之input标签(11)
1.输入框 type=“text” 就是一个简单的输入框 <body> <input type="text"> </body> 2.密码输入框 ...
- iphone手机投屏在哪里 手机无线投屏电脑
Iphone是我们经常使用的一款手机,有时候经常需要将一些文件图片信息等投屏到电脑,那么iphone手机投屏在哪里?可以无线投屏到电脑吗?其实很简单,下面就分享下苹果手机投屏的具体方法给大家,希望对大 ...
- Android为TV端助力 同时setTag两次,保存多种值
示例代码: view.setTag(R.string.action_settings,hodler.content); 接收两个值,一个是key值,必须是唯一值,而且要写在values/ids.xml ...
- <自动化测试方案_6>第六章、API自动化测试
第六章.API自动化测试 (一)工具实现 目前大众接口测试的工具有:Postman.SoupUI.jmeter他们的特点介绍有人做个宏观的研究,这里进行引用:https://blog.csdn.net ...
- canvas学习总结四:绘制虚线
上一章节我们说到,线性路径的绘制,主要利用movoTo(),lineTo()等方法,当然 Canvas 2D API 也提供了虚线的绘制方法,CanvasRenderingContext2D.setL ...
- python leetcode 字符串相乘
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = "2", num ...
- (python)面向对象
一.面向对象概述 要了解面向对象,就需要先了解面向过程的概念,那么什么是面向过程编程呢?最具代表性的就是C语言了,所谓面向过程编程就是在做一件事的时候,需要按步骤进行,第一步干什么,第二步干什么,这种 ...