當 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(中) 在上文中,介绍了如果录制脚本和设置脚本执行次数.如果经过调试脚本能够正常工作的话,就可以设置并发用户数并进行压力测试了. 首先我们通过脚本编辑界面上 ...
随机推荐
- 4:Python的while循环
while循环: while count<10: print(count) #count=100 count=count+1 print(123) while循环break:终止所有循环 cou ...
- jQuery的一生
jQuery 1.什么是jQuery? 是轻量级的,兼容多浏览器的JavaScript库,使用户能够方便的处理HTML Document,Events,实现动画效果,方便进行Ajax交互,能够极大地简 ...
- writing objects : 值%停住
在git bush 中使用命令:git config --global http.postBuffer 524288000 因为git上传,限定一次push命令的buffer大小.
- Android Service、IntentService,Service和组件间通信
Service组件 Service 和Activity 一样同为Android 的四大组件之一,并且他们都有各自的生命周期,要想掌握Service 的用法,那就要了解Service 的生命周期有哪些方 ...
- H264-YUV通过RTP接收视频流ffmpeg解码SDL实时播放
写在前面的话 写一个简单的播放器,通过RTP接收视频流,进行实时播放.最初,使用ffplay或者vlc接收按照SDP协议文件可以播放视频,但是视频中断后重启,不能正确的解包,时常会出现如下的错误信息. ...
- JavaScript中,JSON格式的字符串与JSON格式的对象相互转化
前言:JSON是一个独立于任何语言的数据格式,因此,严格来说,没有“JSON对象”和“JSON字符串”这个说法(然而”菜鸟教程“和”W3school“使用了“JSON对象”和“JSON字符串”这个说法 ...
- CentOS 安装开发环境 并安装coTurn
从官网 https://www.centos.org/download/ 下载镜像文件 从163的镜像站点下载,速度较快 http://mirrors.163.com/centos/7/isos/x8 ...
- java国际化---native2ascii.exe 的使用方法
从另一个博客迁移 native2ascii.exe使用方法: 命令的语法格式: native2ascii -[options] [inputfile [outputfile]] 说明: -[optio ...
- Android Studio连接天天模拟器
方法:安装两者后,打开天天模拟器的adb.exe所在目录,我的是C:\Users\ Android\sdk\platform-tools,在打开的文件夹下使用“shift+鼠标右键”打开cmd终端. ...
- c函数指针
#include <stdio.h> int max(int a, int b){ return a > b ? a : b; } int min(int a, int b){ re ...