home-assistant.github.io/components/snips/index.html
2018-02-26 01:02:57 +00:00

376 lines
25 KiB
HTML

<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Snips - Home Assistant</title>
<meta name="author" content="Home Assistant">
<meta name="description" content="Instructions how to integrate Snips within Home Assistant.">
<meta name="viewport" content="width=device-width">
<link rel="canonical" href="https://home-assistant.io/components/snips/">
<meta property="fb:app_id" content="338291289691179">
<meta property="og:title" content="Snips">
<meta property="og:site_name" content="Home Assistant">
<meta property="og:url" content="https://home-assistant.io/components/snips/">
<meta property="og:type" content="article">
<meta property="og:description" content="Instructions how to integrate Snips within Home Assistant.">
<meta property="og:image" content="https://home-assistant.io/images/default-social.png">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@home_assistant">
<meta name="twitter:title" content="Snips">
<meta name="twitter:description" content="Instructions how to integrate Snips within Home Assistant.">
<meta name="twitter:image" content="https://home-assistant.io/images/default-social.png">
<link href="/stylesheets/screen.css" media="screen, projection, print" rel="stylesheet">
<link href="/atom.xml" rel="alternate" title="Home Assistant" type="application/atom+xml">
<link rel='shortcut icon' href='/images/favicon.ico' />
<link rel='icon' type='image/png' href='/images/favicon-192x192.png' sizes='192x192' />
</head>
<body >
<header class='site-header'>
<div class="grid-wrapper">
<div class="grid">
<div class="grid__item three-tenths lap-two-sixths palm-one-whole ha-title">
<a href="/" class="site-title">
<img width='40' src='/demo/favicon-192x192.png'>
<span>Home Assistant</span>
</a>
</div>
<div class="grid__item seven-tenths lap-four-sixths palm-one-whole">
<nav>
<input type="checkbox" id="toggle">
<label for="toggle" class="toggle" data-open="Main Menu" data-close="Close Menu"></label>
<ul class="menu pull-right">
<li><a href="/getting-started/">Getting started</a></li>
<li><a href="/components/">Components</a></li>
<li><a href="/docs/">Docs</a></li>
<li><a href="/cookbook/">Examples</a></li>
<li><a href="/developers/">Developers</a></li>
<li><a href="/blog/">Blog</a></li>
<li><a href="/help/">Need help?</a></li>
<li><a href='#' class='show-search'><i class="icon-search"></i></a></li>
</ul>
</nav>
<div class='search-container' style='display: none'>
<div class='search'>
<i class="icon-search"></i>
<input id='search' placeholder='Search the docs…'>
<a href='#' class='close'><i class="icon-remove-sign"></i></a>
</div>
</div>
</div>
</div>
</div>
</header>
<div class="grid-wrapper">
<div class="grid grid-center">
<div class="grid__item two-thirds lap-one-whole palm-one-whole">
<article class="page">
<header>
<h1 class="title indent">
Snips
</h1>
</header>
<hr class="divider">
<p>The <a href="https://www.snips.ai">Snips Voice Platform</a> allows users to add powerful voice assistants to their Raspberry Pi devices without compromising on privacy. It runs 100% on-device, and does not require an internet connection. It features Hotword Detection, Automatic Speech Recognition (ASR), Natural Language Understanding (NLU) and Dialog Management.</p>
<p>The latest documentation can be found here: <a href="https://github.com/snipsco/snips-platform-documentation/wiki">Snips Platform Documentation</a>.</p>
<p><img src="/images/screenshots/snips_modules.png" alt="Snips Modules" /></p>
<p>Snips takes voice or text as input and produces <em>intents</em> as output, which are explicit representations of an intention behind an utterance and which can subsequently be used by Home Assistant to perform appropriate actions.</p>
<p><img src="/images/screenshots/snips_nlu.png" alt="Snips Modules" /></p>
<h2><a class="title-link" name="the-snips-voice-platform" href="#the-snips-voice-platform"></a> The Snips Voice Platform</h2>
<h3><a class="title-link" name="installation" href="#installation"></a> Installation</h3>
<p>The Snips platform can be installed via the Snips APT/Debian repository. If you prefer to install the platform using the Docker distribution, check out our <a href="https://github.com/snipsco/snips-platform-documentation/wiki/6.--Miscellaneous#using-docker">Docker Installation Guide</a>.</p>
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>sudo apt-get update
<span class="gp">$ </span>sudo apt-get install -y dirmngr
<span class="gp">$ </span>sudo bash -c <span class="s1">'echo "deb https://raspbian.snips.ai/$(lsb_release -cs) stable main" &gt; /etc/apt/sources.list.d/snips.list'</span>
<span class="gp">$ </span>sudo apt-key adv --keyserver pgp.mit.edu --recv-keys D4F50CDCA10A2849
<span class="gp">$ </span>sudo apt-get update
<span class="gp">$ </span>sudo apt-get install -y snips-platform-voice
</code></pre>
</div>
<p>Note: if the keyserver pgp.mit.edu is down try to use another one in the 4th line , like pgp.surfnet.nl:</p>
<div class="language-bash highlighter-rouge"><pre class="highlight"><code>sudo apt-key adv --keyserver pgp.surfnet.nl --recv-keys D4F50CDCA10A2849
</code></pre>
</div>
<h3><a class="title-link" name="creating-an-assistant" href="#creating-an-assistant"></a> Creating an assistant</h3>
<div class="videoWrapper">
<iframe src="https://player.vimeo.com/video/223255884" width="700" height="380" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
</div>
<p>Head over to the <a href="https://console.snips.ai">Snips Console</a> to create your assistant. Launch the training and download by clicking on the “Download Assistant” button.</p>
<p>The next step is to get the assistant to work on your device. Unzip and copy the assistant folder that you downloaded from the web console to the path. Assuming your downloaded assistant folder is on your desktop, just run:</p>
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>scp -r ~/Desktop/assistant pi@&lt;raspi_hostname.local_or_IP&gt;:/home/pi/.
</code></pre>
</div>
<p>Now ssh into your Raspberry Pi:</p>
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>ssh pi@&lt;raspi_hostname.local_or_IP&gt;
</code></pre>
</div>
<p>By default, this command is <code class="highlighter-rouge">ssh pi@raspberrypi.local</code>, if you are using the default Raspberry Pi hostname.</p>
<p>Then, move the assistant to the right folder:</p>
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="o">(</span>pi<span class="o">)</span> <span class="nv">$ </span>sudo mv /home/pi/assistant /usr/share/snips/assistant
</code></pre>
</div>
<p>Note: if you already have an assistant installed and wish to replace it, start by removing the previous one, and then move the new one in its place:</p>
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="o">(</span>pi<span class="o">)</span> <span class="nv">$ </span>sudo rm -r /usr/share/snips/assistant
<span class="o">(</span>pi<span class="o">)</span> <span class="nv">$ </span>sudo mv /home/pi/assistant /usr/share/snips/assistant
</code></pre>
</div>
<h3><a class="title-link" name="running-snips" href="#running-snips"></a> Running Snips</h3>
<p>Make sure that a microphone is plugged to the Raspberry Pi. If you are having trouble setting up audio, we have written a guide on <a href="https://github.com/snipsco/snips-platform-documentation/wiki/1.-Setup-the-Snips-Voice-Platform-on-your-Raspberry-Pi#configuring-the-audio">Raspberry Pi Audio Configuration</a>.</p>
<p>Start the Snips Voice Platform by starting the <code class="highlighter-rouge">snips-*</code> services:</p>
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>sudo systemctl start <span class="s2">"snips-*"</span>
</code></pre>
</div>
<p>Snips is now ready to take voice commands from the microphone. To trigger the listening, simply say</p>
<blockquote>
<p>Hey Snips</p>
</blockquote>
<p>followed by a command, e.g.</p>
<blockquote>
<p>Set the lights to green in the living room</p>
</blockquote>
<p>As the Snips Platform parses this query into an intent, it will be published on MQTT, on the <code class="highlighter-rouge">hermes/intent/&lt;intentName&gt;</code> topic. The Snips Home Assistant component subscribes to this topic, and handles the intent according to the rules defined in <code class="highlighter-rouge">configuration.yaml</code>, as explained below.</p>
<h4><a class="title-link" name="optional-specifying-an-external-mqtt-broker" href="#optional-specifying-an-external-mqtt-broker"></a> Optional: specifying an external MQTT broker</h4>
<p>By default, Snips runs its own MQTT broker. But we can also tell Snips to use an external broker by specifying this when launching Snips. In this case, we need to specify this in the <code class="highlighter-rouge">/etc/snips.toml</code> configuration file. For more information on configuring this, see the <a href="https://github.com/snipsco/snips-platform-documentation/wiki/6.--Miscellaneous#using-external-mqtt-broker">Using an external MQTT broker</a> article.</p>
<h2><a class="title-link" name="home-assistant-configuration" href="#home-assistant-configuration"></a> Home Assistant configuration</h2>
<h3><a class="title-link" name="specifying-the-mqtt-broker" href="#specifying-the-mqtt-broker"></a> Specifying the MQTT broker</h3>
<p>Messages between Snips and Home Assistant are passed via MQTT. We can either point Snips to the MQTT broker used by Home Assistant, as explained above, or tell Home Assistant which <a href="/docs/mqtt/">MQTT broker</a> to use by adding the following entry to the <code class="highlighter-rouge">configuration.yaml</code> file:</p>
<div class="language-yaml highlighter-rouge"><pre class="highlight"><code><span class="s">mqtt</span><span class="pi">:</span>
<span class="s">broker</span><span class="pi">:</span> <span class="s">MQTT_BROKER_IP</span>
<span class="s">port</span><span class="pi">:</span> <span class="s">MQTT_BROKER_PORT</span>
</code></pre>
</div>
<p>By default, Snips runs an MQTT broker on port 9898. So if we wish to use this broker, and if Snips and Home Assistant run on the same device, the entry will look as follows:</p>
<div class="language-yaml highlighter-rouge"><pre class="highlight"><code><span class="s">mqtt</span><span class="pi">:</span>
<span class="s">broker</span><span class="pi">:</span> <span class="s">127.0.0.1</span>
<span class="s">port</span><span class="pi">:</span> <span class="s">9898</span>
</code></pre>
</div>
<p>Alternatively, MQTT can be configured to bridge messages between servers if using a custom MQTT broker such as <a href="https://mosquitto.org/">mosquitto</a>.</p>
<h3><a class="title-link" name="triggering-actions" href="#triggering-actions"></a> Triggering actions</h3>
<p>In Home Assistant, we trigger actions based on intents produced by Snips using the <a href="/components/intent_script"><code class="highlighter-rouge">intent_script</code></a> component. For instance, the following block handles a <code class="highlighter-rouge">ActivateLightColor</code> intent to change light colors:</p>
<div class="language-yaml highlighter-rouge"><pre class="highlight"><code><span class="s">snips</span><span class="pi">:</span>
<span class="s">intent_script</span><span class="pi">:</span>
<span class="s">ActivateLightColor</span><span class="pi">:</span>
<span class="s">action</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">service</span><span class="pi">:</span> <span class="s">light.turn_on</span>
<span class="s">data_template</span><span class="pi">:</span>
<span class="s">entity_id</span><span class="pi">:</span> <span class="s">light.{{ objectLocation | replace(" ","_") }}</span>
<span class="s">color_name</span><span class="pi">:</span> <span class="pi">{{</span> <span class="nv">objectColor</span> <span class="pi">}}</span>
</code></pre>
</div>
<p>In the <code class="highlighter-rouge">data_template</code> block, we have access to special variables, corresponding to the slot names for the intent. In the present case, the <code class="highlighter-rouge">ActivateLightColor</code> has two slots, <code class="highlighter-rouge">objectLocation</code> and <code class="highlighter-rouge">objectColor</code>.</p>
<h3><a class="title-link" name="special-slots" href="#special-slots"></a> Special slots</h3>
<p>In the above example, the slots are plain strings. However, when more complex types are used, such as dates or time ranges, they will be transformed to rich Python objects, for example:</p>
<div class="language-yaml highlighter-rouge"><pre class="highlight"><code><span class="s">SetTimer</span><span class="pi">:</span>
<span class="s">speech</span><span class="pi">:</span>
<span class="s">type</span><span class="pi">:</span> <span class="s">plain</span>
<span class="s">text</span><span class="pi">:</span> <span class="s">weather</span>
<span class="s">action</span><span class="pi">:</span>
<span class="s">service</span><span class="pi">:</span> <span class="s">script.set_timer</span>
<span class="s">data_template</span><span class="pi">:</span>
<span class="s">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">{{</span><span class="nv"> </span><span class="s">timer_name</span><span class="nv"> </span><span class="s">}}"</span>
<span class="s">duration</span><span class="pi">:</span> <span class="s2">"</span><span class="s">{{</span><span class="nv"> </span><span class="s">timer_duration</span><span class="nv"> </span><span class="s">}}"</span>
<span class="s">seconds</span><span class="pi">:</span> <span class="s2">"</span><span class="s">{{</span><span class="nv"> </span><span class="s">slots.timer_duration.value.seconds</span><span class="nv"> </span><span class="s">}}"</span>
<span class="s">minutes</span><span class="pi">:</span> <span class="s2">"</span><span class="s">{{</span><span class="nv"> </span><span class="s">slots.timer_duration.value.minutes</span><span class="nv"> </span><span class="s">}}"</span>
<span class="s">hours</span><span class="pi">:</span> <span class="s2">"</span><span class="s">{{</span><span class="nv"> </span><span class="s">slots.timer_duration.value.hours</span><span class="nv"> </span><span class="s">}}"</span>
</code></pre>
</div>
<h3>Sending TTS Notifications</h3>
<p>You can send TTS notifications to Snips using the snips.say and snips.say_action services. Say_action starts a session and waits for user response, “Would you like me to close the garage door?”, “Yes, close the garage door”.</p>
<h4><a class="title-link" name="service-snipssay" href="#service-snipssay"></a> Service <code class="highlighter-rouge">snips/say</code></h4>
<table>
<thead>
<tr>
<th>Service data attribute</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="highlighter-rouge">text</code></td>
<td>no</td>
<td>Text to say.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">site_id</code></td>
<td>yes</td>
<td>Site to use to start session.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">custom_data</code></td>
<td>yes</td>
<td>custom data that will be included with all messages in this session.</td>
</tr>
</tbody>
</table>
<h4><a class="title-link" name="service-snipssay_action" href="#service-snipssay_action"></a> Service <code class="highlighter-rouge">snips/say_action</code></h4>
<table>
<thead>
<tr>
<th>Service data attribute</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="highlighter-rouge">text</code></td>
<td>no</td>
<td>Text to say.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">site_id</code></td>
<td>yes</td>
<td>Site to use to start session.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">custom_data</code></td>
<td>yes</td>
<td>custom data that will be included with all messages in this session.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">can_be_enqueued</code></td>
<td>yes</td>
<td>If True, session waits for an open session to end, if False session is dropped if one is running.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">intent_filter</code></td>
<td>yes</td>
<td>Array of Strings - A list of intents names to restrict the NLU resolution to on the first query.</td>
</tr>
</tbody>
</table>
<h4>Configuration Examples</h4>
<div class="language-yaml highlighter-rouge"><pre class="highlight"><code><span class="s">script</span><span class="pi">:</span>
<span class="s">turn_on_light</span><span class="pi">:</span>
<span class="s">sequence</span><span class="pi">:</span>
<span class="s">service</span><span class="pi">:</span> <span class="s">script.turn_on_light</span>
<span class="s">service</span><span class="pi">:</span> <span class="s">snips.say</span>
<span class="s">data</span><span class="pi">:</span>
<span class="s">text</span><span class="pi">:</span> <span class="s1">'</span><span class="s">OK,</span><span class="nv"> </span><span class="s">the</span><span class="nv"> </span><span class="s">light</span><span class="nv"> </span><span class="s">is</span><span class="nv"> </span><span class="s">now</span><span class="nv"> </span><span class="s">on'</span>
<span class="s">automation</span><span class="pi">:</span>
<span class="s">query_garage_door</span><span class="pi">:</span>
<span class="s">trigger</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">platform</span><span class="pi">:</span> <span class="s">state</span>
<span class="s">entity_id</span><span class="pi">:</span> <span class="s">binary_sensor.my_garage_door_sensor</span>
<span class="s">from</span><span class="pi">:</span> <span class="s1">'</span><span class="s">off'</span>
<span class="s">to</span><span class="pi">:</span> <span class="s1">'</span><span class="s">on'</span>
<span class="s">for</span><span class="pi">:</span>
<span class="s">minutes</span><span class="pi">:</span> <span class="s">10</span>
<span class="s">sequence</span><span class="pi">:</span>
<span class="s">service</span><span class="pi">:</span> <span class="s">snips.say_action</span>
<span class="s">data</span><span class="pi">:</span>
<span class="s">text</span><span class="pi">:</span> <span class="s1">'</span><span class="s">Garage</span><span class="nv"> </span><span class="s">door</span><span class="nv"> </span><span class="s">has</span><span class="nv"> </span><span class="s">been</span><span class="nv"> </span><span class="s">open</span><span class="nv"> </span><span class="s">10</span><span class="nv"> </span><span class="s">minutes,</span><span class="nv"> </span><span class="s">would</span><span class="nv"> </span><span class="s">you</span><span class="nv"> </span><span class="s">like</span><span class="nv"> </span><span class="s">me</span><span class="nv"> </span><span class="s">to</span><span class="nv"> </span><span class="s">close</span><span class="nv"> </span><span class="s">it?'</span>
<span class="s">intentFilter</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">closeGarageDoor</span>
<span class="c1"># This intent is fired if the user responds with the appropriate intent after the above notification</span>
<span class="s">intent_script</span><span class="pi">:</span>
<span class="s">closeGarageDoor</span><span class="pi">:</span>
<span class="s">speech</span><span class="pi">:</span>
<span class="s">type</span><span class="pi">:</span> <span class="s">plain</span>
<span class="s">text</span><span class="pi">:</span> <span class="s1">'</span><span class="s">OK,</span><span class="nv"> </span><span class="s">closing</span><span class="nv"> </span><span class="s">the</span><span class="nv"> </span><span class="s">garage</span><span class="nv"> </span><span class="s">door'</span>
<span class="s">action</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">service</span><span class="pi">:</span> <span class="s">script.garage_door_close</span>
</code></pre>
</div>
</article>
</div>
<aside id="sidebar" class="grid__item one-third lap-one-whole palm-one-whole">
<div class="grid">
<section class="aside-module grid__item one-whole lap-one-half">
<div class='edit-github'><a href='https://github.com/home-assistant/home-assistant.github.io/tree/current/source/_components/snips.markdown'>Edit this page on GitHub</a></div>
<div class='brand-logo-container section'>
<img src='/images/supported_brands/snips.png' />
</div>
<div class='section'>
Introduced in release: 0.48
</div>
<div class='section'>
<h1 class="title delta">Category Voice</h1>
<ul class='divided'>
<li>
<a href='/components/alexa/'>Alexa / Amazon Echo</a>
</li>
<li>
<a href='/components/conversation/'>Conversation</a>
</li>
<li>
<a href='/components/dialogflow/'>Dialogflow</a>
</li>
<li>
<a href='/components/google_assistant/'>Google Assistant</a>
</li>
<li>
<a href='/components/cloud/'>Home Assistant Cloud</a>
</li>
<li>
<a href='/components/homekit/'>HomeKit</a>
</li>
<li>
<a href='/components/mycroft/'>Mycroft</a>
</li>
<li>
Snips
</li>
</ul>
</div>
</section>
</div>
</aside>
</div>
</div>
<footer>
<div class="grid-wrapper">
<div class="grid">
<div class="grid__item">
<div class="copyright">
<a rel="me" href='https://twitter.com/home_assistant'><i class="icon-twitter"></i></a>
<a rel="me" href='https://facebook.com/homeassistantio'><i class="icon-facebook"></i></a>
<a rel="me" href='https://plus.google.com/110560654828510104551'><i class="icon-google-plus"></i></a>
<a rel="me" href='https://github.com/home-assistant/home-assistant'><i class="icon-github"></i></a>
<div class="credit">
Contact us at <a href='mailto:hello@home-assistant.io'>hello@home-assistant.io</a> (no support!).<br>
Website powered by <a href='http://jekyllrb.com/'>Jekyll</a> and the <a href='https://github.com/coogie/oscailte'>Oscalite theme</a>.<br />
Hosted by <a href='https://pages.github.com/'>GitHub</a> and served by <a href='https://cloudflare.com'>CloudFlare</a>.
</div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">home-assistant.io</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.
</div>
</div>
</div>
</div>
</footer>
<script>
var _gaq=[['_setAccount','UA-57927901-1'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css" />
<script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script>
<script type="text/javascript">
docsearch({
apiKey: 'ae96d94b201c5444c8a443093edf3efb',
indexName: 'home-assistant',
inputSelector: '#search',
debug: false // Set debug to true if you want to inspect the dropdown
});
document.querySelector('.search .close').addEventListener('click', function(ev) {
ev.preventDefault();
document.querySelector('.search-container').style.display = 'none';
});
document.querySelector('.show-search').addEventListener('click', function(ev) {
ev.preventDefault();
document.querySelector('.search-container').style.display = 'block';
document.getElementById('toggle').checked = false;
document.querySelector('.search-container input').focus();
});
</script>
</body>
</html>