Enrichir Google Home avec des actions personnalisées

Google Home est un outil très puissant qui permet d'utiliser sa voix pour invoquer l'assistant de Google et lui poser des questions, lui faire réaliser des actions (recherche Internet, contrôle domotique, etc.)

Couplé à d'autres équipements de la firme (tel que le Chromecast), cela s'avère encore plus pratique! En effet, il suffit de dire "lance Netflix" et cela lance l'application directement sur votre télévision. Quand on est feignant comme moi, on apprécie ce genre de raccourcis :)

Malheureusement, l'intégration avec tous les équipements du marché n'est pas encore au rendez-vous: il y a trop de constructeurs et de protocoles différents pour arriver à faire quelque chose qui soit vraiment unifié. Mais de par mon côté curieux et développeur, je souhaitais tout de même voir ce qu'il était possible de faire pour intégrer un équipement non géré dans l'assistant.

Dans mon cas, je souhaitais savoir comment allumer et éteindre le boitier TV de ma Freebox simplement en utilisant ma voix. Comme beaucoup le savent, Free propose une API, utilisable sur votre réseau Wifi, pour contrôler le device. Ni une, ni deux, je me suis lancé dans un petit développement personnalisé !

La première étape a été de trouver un moyen d'appeler cette API. Pour cela, rien de plus simple:

  1. Un Raspberry PI avec une distribution Raspbian
  2. Une WebAPI ASP.NET Core 2 qui contient 2 méthodes (Start et Stop) qui démarre automatiquement au lancement du device (modification du fichier rc.local)
  3. L'affectation d'un nom de domaine dédié sur le portail de Free, d'une adresse IP fixe pour le Raspberry et la redirection des ports

Les points 1 et 3 sont plus de la configuration mais le point 2 est celui qui va nous intéresser:

[Route("api/[controller]")]
    public class ActionsController : Controller
    {
        [HttpGet]
        [Route("start")]
        public async Task Start()
        {
            await Helpers.FreeboxHelpers.StartAsync();
        }

        [HttpGet]
        [Route("stop")]
        public async Task Stop()
        {
            await Helpers.FreeboxHelpers.StopAsync();
        }

        [HttpGet]
        [Route("mute")]
        public async Task Mute()
        {
            await Helpers.FreeboxHelpers.MuteAsync();
        }

        [HttpGet]
        [Route("change")]
        public async Task Mute(string number)
        {
            await Helpers.FreeboxHelpers.ChangeChaineAsync(number);
        }
    }

Le code de la classe FreeboxHelpers est, lui aussi, extrêmement simple (si vous avez besoin de plus d'infos sur l'utilisation de l'API Freebox, je vous invite à regarder sur Google, il y a plein d'exemples):

public static class FreeboxHelpers
    {
        private const string BASE_URL = "http://hd1.freebox.fr/pub/remote_control?code=XXXXX&key={0}";

        public static async Task StartAsync()
        {
            using (var httpClient = new HttpClient())
            {
                await httpClient.GetStringAsync(string.Format(BASE_URL, "power"));
            }
        }

        public static async Task StopAsync()
        {
            using (var httpClient = new HttpClient())
            {
                await httpClient.GetStringAsync(string.Format(BASE_URL, "power"));
            }
        }

        public static async Task MuteAsync()
        {
            using (var httpClient = new HttpClient())
            {
                await httpClient.GetStringAsync(string.Format(BASE_URL, "mute"));
            }
        }
    }

Une fois cette API terminée, hostée sur le Raspberry et accessible depuis Internet, il reste à trouver un moyen de l'appeler depuis le Google Home.

Pour cela, vous avez 2 possibilités:

Vous pouvez créer une Google Action, en utilisant le SDK officiel accessible sur https://dialogflow.com. Cela vous permettra de créer des agents, des intentions, des entités, etc. Bref; mélangé avec le Machine Learning intégré dans l'outil, cela vous donne tout ce qu'il faut pour avoir un outil intelligent capable de comprendre ce que vous lui demandez. Voici un exemple de rendu dans le simulateur:

GoogleAction.png

L'inconvénient de cette technique (d'après mes recherches et tests sur le device) est que vous êtes obligé de demander à Google Home de lancer votre application (ici nommée "Freebox Controller") avant de lui donner une instruction.

L'autre possibilité est d'utiliser le service IFTTT qui propose une intégration avec l'assistant de Google ! 

Pour cela, rien de plus simple: une fois que vous avez créé votre "applet" (connecté au compte Google que vous utilisez sur votre Google Home), il suffit de rajouter, comme action, la possibilité de faire une requête Web:

Applet.png

Le contenu de cet applet et de la requête Web est, là encore, très simple car il suffit de pointer sur votre Freebox et, plus précisément sur l'API que nous avons vue précédemment:

 Applet1.png Applet2.png

Et le tour est joué ! Dans la foulée, je n'ai plus qu'a dire "Ok Google, start freebox" (ou "Ok Google, start free") et mon boîtier TV s'allume automatiquement, avec un retour de l'assistant qui m'indique l'action qu'il va réaliser ("Ok, j'allume la Freebox"). Bien sûr, comme vu avez pu le voir sur l'API qui est sur notre Raspberry, il est possible de faire la même chose avec l'arrêt, la suppression du son, le changement de chaîne, etc.

Pour résumé, voici un petit schéma de l'architecture qui a été mise en place:

Archi.png

Il est à noter que j'ai eu quelques difficultés à faire en sorte que l'applet fonctionne et en cherchant sur Internet, voici ce que j'ai trouvé (et constaté):

  • Ne pas mettre de majuscule dans le nom de l'applet ou dans les commandes vocales
  • Ne pas mettre d'accent dans le nom de l'applet ou dans les commandes vocales
  • Préférez les commandes vocales avec des mots anglais. Même si cela fonctionne en français (je peux par exemple dire "OK Google, allume freebox"), j'ai remarqué que la reconnaissance des actions était moins bonne...

Voila, j'espère que cet article vous aura intéressé, en attendant d'autres billets sur le même sujet pourquoi pas :)

 

Happy (domo)coding! :)

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus