{"id":1478,"date":"2015-10-03T18:59:14","date_gmt":"2015-10-03T17:59:14","guid":{"rendered":"http:\/\/quantum-bits.org\/?p=1478"},"modified":"2022-08-12T17:27:43","modified_gmt":"2022-08-12T16:27:43","slug":"e-v-e-meets-a-d-a-m","status":"publish","type":"post","link":"https:\/\/www.quantum-bits.org\/?p=1478","title":{"rendered":"E.V.E meets A.D.A.M"},"content":{"rendered":"<p>In the previous post, we quickly reverse-engineered an Orange LiveBox Play set-top box and how it can be easily driven by simple HTTP requests.<\/p>\n<p>Be before implementing an interface between E.V.E and this kind of set-top box, we need to sit down and think a bit. Indeed, for now, E.V.E is nothing but a web browser using good old HTML5\/JS technologies running on a Raspberry Pi hooked on a touchscreen. It&#8217;s quite easy to spawn AJAX requests from JavaScript, but since E.V.E will have&nbsp;to access externals resources (devices) via HTTP, she&#8217;s eventually will run into <a href=\"https:\/\/en.wikipedia.org\/wiki\/Same-origin_policy\" target=\"_blank\" rel=\"noopener\">cross-domain troubles<\/a>.<\/p>\n<p>Unfortunately&nbsp;most consumer-electronic devices are closed and proprietary. And so is my set-top box. Thus, there is nothing I can do to add the proper <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cross-origin_resource_sharing\" target=\"_blank\" rel=\"noopener\">CORS<\/a> headers I would need. Since I&#8217;m dealing with devices on a local network, an external CORS proxy is no solution.&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/JSONP\" target=\"_blank\" rel=\"noopener\">JSONP<\/a> technique might be a solution,&nbsp;but some devices don&#8217;t exchange <a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON\" target=\"_blank\" rel=\"noopener\">JSON<\/a>&nbsp;data.<\/p>\n<p>What I need is a local middle man, that would act on E.V.E&#8217;s command, do a bit of work, and share things&nbsp;with here. This is were A.D.A.M comes to play.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1297\" src=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/09\/rasbperrypi-hacks.jpg\" alt=\"rasbperrypi-hacks\" width=\"985\" height=\"503\" srcset=\"https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/09\/rasbperrypi-hacks.jpg 985w, https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/09\/rasbperrypi-hacks-300x153.jpg 300w\" sizes=\"(max-width: 985px) 100vw, 985px\" \/><\/p>\n<p><strong>A Dramatically Abrupt Multiplexer (A.D.A.M)<\/strong><\/p>\n<p>The simplest way to establish a bidirectional communication in a web browser is using a <a href=\"https:\/\/en.wikipedia.org\/wiki\/WebSocket\" target=\"_blank\" rel=\"noopener\">WebSocket<\/a>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1483\" src=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-adam-websocket.png\" alt=\"eve-adam-websocket\" width=\"309\" height=\"213\" srcset=\"https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-adam-websocket.png 309w, https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-adam-websocket-300x207.png 300w\" sizes=\"(max-width: 309px) 100vw, 309px\" \/><\/p>\n<p>For our LiveBox TV functionality, a typical workflow would be:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1485\" src=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-adam-exchange.png\" alt=\"eve-adam-exchange\" width=\"481\" height=\"338\" srcset=\"https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-adam-exchange.png 481w, https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-adam-exchange-300x211.png 300w\" sizes=\"(max-width: 481px) 100vw, 481px\" \/><\/p>\n<p>Of course, A.D.A.M work would not be limited to spawn HTTP requests on command, it could also interact with the&nbsp;Raspberry Pi&#8217;s hardware, drive external devices via its&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/General-purpose_input\/output\" target=\"_blank\" rel=\"noopener\">GPIO<\/a> interface, etc.<\/p>\n<p>Typically, it could be used to record voice on E.V.E&#8217;s command, use a voice-to-text service (a locally running&nbsp;<a href=\"http:\/\/cmusphinx.sourceforge.net\/\" target=\"_blank\" rel=\"noopener\">pocketsphinx<\/a> or an external service such as Google translate or <a href=\"https:\/\/wit.ai\/\" target=\"_blank\" rel=\"noopener\">wit.ai<\/a>), analyze the text (locally and \/ or via a cognition engine&nbsp;such as <a href=\"http:\/\/www.wolframalpha.com\/\" target=\"_blank\" rel=\"noopener\">Wolfram Alpha<\/a>), interact back with other devices if necessary and eventually give a feedback to the user.<\/p>\n<p>So I wrote down very first iteration of A.D.A.M.&nbsp;I chose to use&nbsp;<a href=\"https:\/\/www.python.org\/\" target=\"_blank\" rel=\"noopener\">python<\/a>. Because of the obvious snake joke with E.V.E and A.D.AM. Because there is a lot of good python wrappers for Rasperry Pi (to drive the GPIO interface, or have fun &nbsp;with <a href=\"http:\/\/opencv.org\/\" target=\"_blank\" rel=\"noopener\">openCV<\/a>, &#8230;). And because it allows to write down powerful code with little effort.<\/p>\n<p>For the WebSocket machinery, I used the python framework for asynchronous networking <a href=\"http:\/\/www.tornadoweb.org\/en\/stable\/\" target=\"_blank\" rel=\"noopener\">Tornado<\/a>. I took less than 50 lines of code to get something useful enough :<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1496\" src=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/adam-py.png\" alt=\"adam-py\" width=\"555\" height=\"960\" srcset=\"https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/adam-py.png 555w, https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/adam-py-173x300.png 173w\" sizes=\"(max-width: 555px) 100vw, 555px\" \/><\/p>\n<p>It&#8217;s rather crude, but it allows to manage the connection, react to JSON message from E.V.E (here, the only opcode understood is an HTTP request), push an HTTP request on demand and send an JSON message back to E.V.E.<\/p>\n<p>On E.V.E&#8217;s side, just a few lines of JavaScript were needed, to manage the connection, send a JSON message to A.D.A.M (an opcode and a data) and react&nbsp;to messages from A.D.A.M:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1488\" src=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-js.png\" alt=\"eve-js\" width=\"794\" height=\"499\" srcset=\"https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-js.png 794w, https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-js-300x189.png 300w\" sizes=\"(max-width: 794px) 100vw, 794px\" \/><\/p>\n<p>Of course, it&#8217;s a first draft code, it&#8217;ll need a bit of love to be in better shape (there is no error treatment whatsoever for now for example).<\/p>\n<p><strong>Interfacing E.V.E, &nbsp;A.D.A.M and a LiveBox Play<\/strong><\/p>\n<p>Just like the preceding code, E.V.E interface for TV will at first be very simple:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1489\" src=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-tv-gui.png\" alt=\"eve-tv-gui\" width=\"847\" height=\"532\" srcset=\"https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-tv-gui.png 847w, https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-tv-gui-300x188.png 300w\" sizes=\"(max-width: 847px) 100vw, 847px\" \/><\/p>\n<p>Within a few hours, this interface was implemented and functional on the Raspberry Pi:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1479\" src=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-orangetv.jpg\" alt=\"eve-orangetv\" width=\"1280\" height=\"764\" srcset=\"https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-orangetv.jpg 1280w, https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-orangetv-300x179.jpg 300w, https:\/\/www.quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-orangetv-1024x611.jpg 1024w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><\/p>\n<p>And a bit late, it was hooked up with our <a href=\"http:\/\/quantum-bits.org\/?p=1430\" target=\"_blank\" rel=\"noopener\">reverse engineering work of last night<\/a> and ready for a first test drive:<\/p>\n<p><center><div style=\"width: 568px;\" class=\"wp-video\"><!--[if lt IE 9]><script>document.createElement('video');<\/script><![endif]-->\n<video class=\"wp-video-shortcode\" id=\"video-1478-1\" width=\"568\" height=\"320\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-0.0.4.mp4?_=1\" \/><a href=\"http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-0.0.4.mp4\">http:\/\/quantum-bits.org\/wp-content\/uploads\/2015\/10\/eve-0.0.4.mp4<\/a><\/video><\/div><\/center><br \/>\nNiiice ! We now have a functional Raspberry Pi with a touch-enabled interface, a simple home dashboard with weather information, capable of exchanging with a general purpose middleware through a WebSocket, able to drive a set-top box and to <a href=\"http:\/\/quantum-bits.org\/?p=1402\" target=\"_blank\" rel=\"noopener\">play internet radio<\/a>.<\/p>\n<p>Since A.D.A.M is able to handle the local hardware, we have a architecture mature enough to&nbsp;experiment with voice interaction (and the new hardware I have received).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous post, we quickly reverse-engineered an Orange LiveBox Play set-top box and how it can be easily driven by simple HTTP requests. Be before implementing an interface between &#8230;<\/p>\n","protected":false},"author":1,"featured_media":3851,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0},"categories":[21],"tags":[],"_links":{"self":[{"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=\/wp\/v2\/posts\/1478"}],"collection":[{"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1478"}],"version-history":[{"count":0,"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=\/wp\/v2\/posts\/1478\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=\/wp\/v2\/media\/3851"}],"wp:attachment":[{"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1478"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1478"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.quantum-bits.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}