{"id":225,"date":"2021-08-08T18:22:59","date_gmt":"2021-08-08T17:22:59","guid":{"rendered":"https:\/\/www.davidestebanmunoz.com\/?p=225"},"modified":"2021-12-30T21:41:01","modified_gmt":"2021-12-30T20:41:01","slug":"control-de-tv-con-skill-alexa","status":"publish","type":"post","link":"https:\/\/www.davidestebanmunoz.com\/?p=225&lang=es","title":{"rendered":"Control de TV con skill alexa"},"content":{"rendered":"\n<p><a href=\"https:\/\/www.davidestebanmunoz.com\/?p=207\">This article can be read in english here<\/a><\/p>\n\n\n\n<p>Hace 4 a\u00f1os me regalaron una \u00absmart\u00bb TV de la marca Telefunken como esta<\/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>Como uno es inquieto y no sabe tener un dispositivo IOT en casa sin por lo menos abrirle un nmap, haciendo un poquito de \u201chacking\u201d sobre \u00e9l, descubr\u00ed que era una TV \u00abre nombrada\u00bb a partir de una TV Vestel y que utilizaba un Linux como sistema operativo. <br>Adem\u00e1s, descubr\u00ed que se pod\u00eda controlar utilizando esta<a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.vestel.smartcenter&amp;hl=es&amp;gl=US\"> Android APP<\/a>:<\/p>\n\n\n\n<p>Este a\u00f1o, me regalaron un dispositivo Alexa Echo Dot por mi cumplea\u00f1os e intent\u00e9 controlar todos los elementos IOT de mi casa mediante la voz.<\/p>\n\n\n\n<p>Utilizando <a href=\"https:\/\/www.telerik.com\/fiddler\">Fiddler<\/a>(pod\u00eda haber usado Burp tambi\u00e9n) como proxy para la app Vestel, y haciendo un poquito de ingenieria inversa, fui capaz de replicar los comandos enviados por la app mediante scripts de Python.<\/p>\n\n\n\n<p>Finalmente, utilizando la librer\u00eda Flask-Ask para Python, la cual he forkeado <a href=\"https:\/\/github.com\/botmakerdvd\/flask-ask\">aqui<\/a> , gener\u00e9 una skill privada de Alexa, que me permite controlar mi TV utilizando mi voz.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Codigo Python<\/h2>\n\n\n\n<p>El c\u00f3digo de esta skill es p\u00fablico y est\u00e1 disponible a trav\u00e9s de <a href=\"https:\/\/github.com\/botmakerdvd\/alexa_vestel_tv_control\">\u00e9ste repositorio<\/a>. Tal y como se puede ver, se lanza en background utilizando un servicio  systemd.<\/p>\n\n\n\n<p>Las acciones y los nombres de los canales se han introducido en listas, se pueden observar 3 canales especiales, TDT que configura la TV para ver canales DVB-T , Kodi, que configura la TV para usar como input el HDMI donde est\u00e1 la raspberry conectada , y Satelite, el cual cambia el input de la TV al HDMI donde hay un receptor de DVB-S2.<\/p>\n\n\n\n<p>De igual modo, los c\u00f3digos de canal y las teclas del mando a distancia, se han introducido en un diccionario.<\/p>\n\n\n\n<p>La ejecuci\u00f3n de comandos sobre la TV o el cambio de canal, primero realizan un proceso de descubrimiento, durante el cual, la skill haciendo uso del protocolo SSDP obtiene la IP y puerto de la TV.<\/p>\n\n\n\n<p>Tal y como se ouede observar, hay otro \u00abhandler\u00bb para \u00abintentluz\u00bb, esto es debido a que corro este stript en una Raspberry PI que haciendo uso de  <a href=\"https:\/\/github.com\/hyperion-project\">Hyperion<\/a>, genera un efecto ambilight con cualquier elemento que se reproduzca a trav\u00e9s de la raspberry o del receptor sat\u00e9lite.<\/p>\n\n\n\n<p>Por \u00faltimo remarcar que en la raspberry hay un servicio nginx corriendo que maneja la capa TLS de HTTPs y redirige las peticiones al puerto 5000 donde el framework de flask espera las conexiones.<\/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\">Skill Alexa<\/h2>\n\n\n\n<p>He usado \u201cla tele\u201d como nombre de invocaci\u00f3n de la skill porque de esta manera se convierte en un di\u00e1logo natural el mandarle comandos a mi TV:<\/p>\n\n\n\n<p>\u201cAlexa dile a la tele que suba el volumen\u201d<\/p>\n\n\n\n<p>He creado 2 intents, uno para controlar el hyperion, y el otro para los comandos de la TV y cambio de canal.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><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>He creado  4 sample utterances y 2 intent slots ( cada 1 con un tipo de slot) para la intent TV. Uno de los slots es para las acciones, y el otro para los canales. <\/p>\n\n\n\n<p>Nota: los \u00abvalue\u00bb de los slot deben coincidir con los elementos en las listas del script de Python. Se pueden usar los sin\u00f3nimos para hacer coincidir los elementos con las resoluciones de nombre de Alexa.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><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<figure class=\"wp-block-image\"><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>Una vez que esto est\u00e1 configurado, un elemento cr\u00edtico es que debemos configurar el Endpoint de la skill para que apunte a nuestro host DDNS. Un par de clave p\u00fablica \/ clave privada debe ser generado y el certificado debe ser subido a la consola de alexa. <\/p>\n\n\n\n<p>Dado que no vamos a publicar nuestra skill, claves autogeneradas y autofirmadas son v\u00e1lidas.<\/p>\n\n\n\n<p>Respecto a la privacidad y la protecci\u00f3n, si no publicamos nuestra skill Alexa, \u00fanicamente nuestros dispositivos podr\u00e1n acceder a ella.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Tipo: Alexa Skill<\/li><li>Donde: Raspberry pi 4 B<\/li><li>Lenguajes y tecnolog\u00edas utilizadas: Python, flask, Alexa<\/li><li>Github repo: Si<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/www.davidestebanmunoz.com\/?p=225&#038;lang=es\">Read More<span class=\"screen-reader-text\">Control de TV con skill alexa<\/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":[21],"tags":[88,92,67],"class_list":["post-225","post","type-post","status-publish","format-standard","hentry","category-proyectos-personales","tag-alexa-es","tag-flask-es","tag-python-es","excerpt"],"_links":{"self":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/225","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=225"}],"version-history":[{"count":1,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/225\/revisions"}],"predecessor-version":[{"id":226,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/225\/revisions\/226"}],"wp:attachment":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=225"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=225"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=225"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}