{"id":207,"date":"2021-08-08T17:47:16","date_gmt":"2021-08-08T16:47:16","guid":{"rendered":"https:\/\/www.davidestebanmunoz.com\/?p=207"},"modified":"2023-11-18T21:45:43","modified_gmt":"2023-11-18T20:45:43","slug":"control-the-tv-using-alexa-skill","status":"publish","type":"post","link":"https:\/\/www.davidestebanmunoz.com\/?p=207","title":{"rendered":"TV control with alexa skill"},"content":{"rendered":"\n<p>Este art\u00edculo se puede leer en castellano <a href=\"https:\/\/www.davidestebanmunoz.com\/?p=225&amp;lang=es\">aqui<\/a><\/p>\n\n\n\n<p>4 Years ago I was given a Telefunken branded \u00absmart\u00bb TV  like this <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.electroprecio.com\/media\/catalog\/product\/cache\/1\/thumbnail\/600x400\/9df78eab33525d08d6e5fb8d27136e95\/5\/0\/50dtu645.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<p>Doing a little of \u00abhacking\u00bb over it, I discovered that this is a \u00abremarked\u00bb Vestel TV which uses a Linux OS and can be controlled using <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.vestel.smartcenter&amp;hl=es&amp;gl=US\">this Android APP<\/a>: <\/p>\n\n\n\n<p>This year, I was given a Alexa Echo Dot device as a present for my birthday and I tried to control every electronic device in my home using this element.<\/p>\n\n\n\n<p>Using <a href=\"https:\/\/www.telerik.com\/fiddler\">Fiddler<\/a> as proxy for the Vestel app, I made \u00abreverse engineering\u00bb over the commands sent by the app and I replicate them by use of python scripts.<\/p>\n\n\n\n<p>Finnally using Flask-Ask library for Python, which I forked <a href=\"https:\/\/github.com\/botmakerdvd\/flask-ask\">here<\/a> I generate a private Alexa Skill that allows me to control my TV using voice.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Python code<\/h2>\n\n\n\n<p>Code for this skill is public and accessible through <a href=\"https:\/\/github.com\/botmakerdvd\/alexa_vestel_tv_control\">this repository<\/a> . As can be seen it is launched using a systemd service.<\/p>\n\n\n\n<p>The actions and the channel names have been inserted into lists. There are 3 special channels, TDT that sets TV to receive DVB-T channels, Kodi that changes the input of the TV to the HDMI that is connected to a raspberry running Kodi, and Satelite which changes the input of the TV to a DVB-S2 receiver HDMI.<\/p>\n\n\n\n<p>The remote keys and the channel codes are inserted into a dictionary. <\/p>\n\n\n\n<p>The TV commands and channels setting execution,  first involve a discover step , in which the skill makes use of SSDP protocol to get the IP and Port of the TV.<\/p>\n\n\n\n<p>As can be seen, there is also another handler for \u00abintentluz\u00bb , this is because I run this script on a Raspberry Pi that with use of <a href=\"https:\/\/github.com\/hyperion-project\">Hyperion<\/a>, generates an ambilight effect with every media played with the Raspberry or the Satellite receiver.<\/p>\n\n\n\n<p>The last setting about this backend code is that there is an nginx service running on raspberry that handles with HTTPS TLS layer and redirects requests to internal port 5000 where the flask framework waits for connections. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  server { \n  listen 443 ssl; \n  server_name &lt;DDNS host&gt;; \n  ssl_certificate &lt;Generated public key&gt; ;\n  ssl_certificate_key &lt;Generated private key&gt; ;\n  ssl_protocols TLSv1.2; ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; \n  ssl_prefer_server_ciphers on; \n  location \/ { \n\t  proxy_pass http:\/\/127.0.0.1:5000\/; \n\t  proxy_http_version 1.1; \n\t  proxy_set_header Upgrade $http_upgrade; \n\t  proxy_set_header Connection \u2018upgrade\u2019; \n\t  proxy_set_header Host $host; \n\t  proxy_cache_bypass $http_upgrade; \n\t  proxy_read_timeout 120s; \n\t} \n  }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Alexa Skill<\/h2>\n\n\n\n<p>I used \u00abla tele\u00bb as skill invocation name so it becomes a very natural way to ask alexa to do something over my TV:<\/p>\n\n\n\n<p>\u00abAlexa dile a la tele que suba el volumen\u00bb<\/p>\n\n\n\n<p>I create 2 intents, one for hyperion ON\/OFF handling and the other for TV commands and channel changing.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"310\" height=\"235\" src=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-2.png\" alt=\"\" class=\"wp-image-208\" srcset=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-2.png 310w, https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-2-300x227.png 300w\" sizes=\"auto, (max-width: 310px) 100vw, 310px\" \/><\/figure>\n\n\n\n<p>I created 4 sample utterances  and 2 intent slots (with 1 slot type each) for TV Intent. One of the slots is for actions and the other is for channels. Note that the slot type values must match the elements in python lists. Synonims can be used to match Alexa&#8217;s voice service resolved strings to our elements.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"597\" height=\"346\" src=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-3.png\" alt=\"\" class=\"wp-image-209\" srcset=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-3.png 597w, https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-3-300x174.png 300w\" sizes=\"auto, (max-width: 597px) 100vw, 597px\" \/><\/figure>\n\n\n\n<p> <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"641\" height=\"268\" src=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-4.png\" alt=\"\" class=\"wp-image-210\" srcset=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-4.png 641w, https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-4-300x125.png 300w\" sizes=\"auto, (max-width: 641px) 100vw, 641px\" \/><\/figure>\n\n\n\n<p>Once this is configured, a critical item is that the Endpoint must be configured to point to our DDNS host. A pair of public and private keys must be generated and the public certificate must be uploaded. Since we are not going to publish this alexa skill, self generated keys and certificates are valid.<\/p>\n\n\n\n<p>Regarding privacy and protection, if we do not publish our skill only our Alexa devices will be able to access it.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Type: Alexa Skill<\/li>\n\n\n\n<li>Where: Raspberry pi 4 B<\/li>\n\n\n\n<li>Languages and technologies used: Python, flask, Alexa<\/li>\n\n\n\n<li>Github repo: yes<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/www.davidestebanmunoz.com\/?p=207\">Read More<span class=\"screen-reader-text\">TV control with alexa skill<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[86,90,49],"class_list":["post-207","post","type-post","status-publish","format-standard","hentry","category-personal-projects","tag-alexa","tag-flask","tag-python","excerpt"],"_links":{"self":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/207","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=207"}],"version-history":[{"count":4,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/207\/revisions"}],"predecessor-version":[{"id":297,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/207\/revisions\/297"}],"wp:attachment":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=207"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=207"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=207"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}