home-assistant.github.io/developers/development_states/index.html
2017-10-21 23:33:53 +00:00

372 lines
23 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>Using States - Home Assistant</title>
<meta name="author" content="Home Assistant">
<meta name="description" content="Introduction to states in Home Assistant.">
<meta name="viewport" content="width=device-width">
<link rel="canonical" href="https://home-assistant.io/developers/development_states/">
<meta property="fb:app_id" content="338291289691179">
<meta property="og:title" content="Using States">
<meta property="og:site_name" content="Home Assistant">
<meta property="og:url" content="https://home-assistant.io/developers/development_states/">
<meta property="og:type" content="website">
<meta property="og:description" content="Introduction to states in 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="Using States">
<meta name="twitter:description" content="Introduction to states in 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">
Using States
</h1>
</header>
<hr class="divider">
<p>Home Assistant keeps track of the states of entities in a state machine. The state machine has very few requirements:</p>
<ul>
<li>Each state is related to an entity identified by an entity id. This id is made up of a domain and an object id. For example <code class="highlighter-rouge">light.kitchen_ceiling</code>. You can make up any combination of domain and object id, even overwriting existing states.</li>
<li>Each state has a primary attribute that describes the state of the entity. In the case of a light this could be for example “on” and “off”. You can store anything you want in the state, as long as its a string (will be converted if its not).</li>
<li>You can store more information about an entity by setting attributes. Attributes is a dictionary that can contain any data that you want. The only requirement is that its JSON serializable, so youre limited to numbers, strings, dictionaries and lists.</li>
</ul>
<p><a href="/docs/configuration/state_object/">Description of the state object.</a></p>
<h3><a class="title-link" name="using-states-in-your-component" href="#using-states-in-your-component"></a> Using states in your component</h3>
<p>This is a simple tutorial/example on how to create and set states. We will do our work in a component called “hello_state”. The purpose of this component is to display a given text in the frontend.</p>
<p>To get started, create the file <code class="highlighter-rouge">&lt;config dir&gt;/custom_components/hello_state.py</code> and copy the below example code.</p>
<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="s">"""
Support for showing text in the frontend.
For more details about this component, please refer to the documentation at
https://home-assistant.io/cookbook/python_component_basic_state/
"""</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">_LOGGER</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>
<span class="n">DOMAIN</span> <span class="o">=</span> <span class="s">'hello_state'</span>
<span class="n">DEPENDENCIES</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">setup</span><span class="p">(</span><span class="n">hass</span><span class="p">,</span> <span class="n">config</span><span class="p">):</span>
<span class="s">"""Setup the Hello State component. """</span>
<span class="n">_LOGGER</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"The 'hello state' component is ready!"</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">True</span>
</code></pre>
</div>
<ol>
<li>In the file header we decided to add some details: A short description and the link to the documentation.</li>
<li>We want to do some logging. This means that we import the Python logging module and create an alias.</li>
<li>The component name is equal to the domain name.</li>
<li>At the moment this component has no dependencies. For detail check <a href="/developers/component_deps_and_reqs/#dependencies">dependencies</a> section.</li>
<li>
<p>The <code class="highlighter-rouge">setup</code> function will take care of the initialization of our component.
The component will only write a log message. Keep in mind for later that you have several options for the severity:</p>
<ul>
<li><code class="highlighter-rouge">_LOGGER.info(msg)</code></li>
<li><code class="highlighter-rouge">_LOGGER.warning(msg)</code></li>
<li><code class="highlighter-rouge">_LOGGER.error(msg)</code></li>
<li><code class="highlighter-rouge">_LOGGER.critical(msg)</code></li>
<li><code class="highlighter-rouge">_LOGGER.exception(msg)</code></li>
</ul>
</li>
<li>We return <code class="highlighter-rouge">True</code> if everything is ok.</li>
</ol>
<p>Add the component to your <code class="highlighter-rouge">configuration.yaml</code> file.</p>
<div class="language-yaml highlighter-rouge"><pre class="highlight"><code><span class="s">hello_state</span><span class="pi">:</span>
</code></pre>
</div>
<p>After a start or a restart of Home Assistant the component will create an entry in the log.</p>
<div class="language-bash highlighter-rouge"><pre class="highlight"><code>16-03-12 14:16:42 INFO <span class="o">(</span>MainThread<span class="o">)</span> <span class="o">[</span>custom_components.hello_state] The <span class="s1">'hello state'</span> component is ready!
</code></pre>
</div>
<p>The next step is the introduction of configuration options. A user can pass configuration options to our component via <code class="highlighter-rouge">configuration.yaml</code>. To use them well use the passed in <code class="highlighter-rouge">config</code> variable to our <code class="highlighter-rouge">setup</code> method.</p>
<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">logging</span>
<span class="n">_LOGGER</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>
<span class="n">DOMAIN</span> <span class="o">=</span> <span class="s">'hello_state'</span>
<span class="n">DEPENDENCIES</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">CONF_TEXT</span> <span class="o">=</span> <span class="s">'text'</span>
<span class="n">DEFAULT_TEXT</span> <span class="o">=</span> <span class="s">'No text!'</span>
<span class="k">def</span> <span class="nf">setup</span><span class="p">(</span><span class="n">hass</span><span class="p">,</span> <span class="n">config</span><span class="p">):</span>
<span class="s">"""Set up the Hello State component. """</span>
<span class="c"># Get the text from the configuration. Use DEFAULT_TEXT if no name is provided.</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">config</span><span class="p">[</span><span class="n">DOMAIN</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">CONF_TEXT</span><span class="p">,</span> <span class="n">DEFAULT_TEXT</span><span class="p">)</span>
<span class="c"># States are in the format DOMAIN.OBJECT_ID</span>
<span class="n">hass</span><span class="o">.</span><span class="n">states</span><span class="o">.</span><span class="nb">set</span><span class="p">(</span><span class="s">'hello_state.Hello_State'</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">True</span>
</code></pre>
</div>
<p>To use the latest feature of our component, update the entry in your <code class="highlighter-rouge">configuration.yaml</code> file.</p>
<div class="language-yaml highlighter-rouge"><pre class="highlight"><code><span class="s">hello_state</span><span class="pi">:</span>
<span class="s">text</span><span class="pi">:</span> <span class="s1">'</span><span class="s">Hello,</span><span class="nv"> </span><span class="s">World!'</span>
</code></pre>
</div>
<p>Thanks to <code class="highlighter-rouge">DEFAULT_TEXT</code> variable the component will launch even if no <code class="highlighter-rouge">text:</code> field is used in the <code class="highlighter-rouge">configuration.yaml</code> file. Quite often there are variables which are required. Its important to check if all mandatory configuration variables are provided. If not, the setup should fail. We will use <code class="highlighter-rouge">voluptuous</code> as a helper to achieve this. The next listing shows the essential parts.</p>
<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">voluptuous</span> <span class="kn">as</span> <span class="nn">vol</span>
<span class="kn">import</span> <span class="nn">homeassistant.helpers.config_validation</span> <span class="kn">as</span> <span class="nn">cv</span>
<span class="n">CONFIG_SCHEMA</span> <span class="o">=</span> <span class="n">vol</span><span class="o">.</span><span class="n">Schema</span><span class="p">({</span>
<span class="n">DOMAIN</span><span class="p">:</span> <span class="n">vol</span><span class="o">.</span><span class="n">Schema</span><span class="p">({</span>
<span class="n">vol</span><span class="o">.</span><span class="n">Required</span><span class="p">(</span><span class="n">CONF_TEXT</span><span class="p">):</span> <span class="n">cv</span><span class="o">.</span><span class="n">string</span><span class="p">,</span>
<span class="p">})</span>
<span class="p">},</span> <span class="n">extra</span><span class="o">=</span><span class="n">vol</span><span class="o">.</span><span class="n">ALLOW_EXTRA</span><span class="p">)</span>
</code></pre>
</div>
<p>Now, when <code class="highlighter-rouge">text:</code> is missing from the config, Home Assistant will alert the user and not setup your component.</p>
<p>After a start or a restart of Home Assistant the component will be visible in the frontend if the <code class="highlighter-rouge">configuration.yaml</code> file is up-to-date.</p>
<p class="img">
<img src="/images/screenshots/create-component01.png" />
</p>
<p>In order to expose attributes of your component, you will need to define a method called <code class="highlighter-rouge">state_attributes</code> which will return a dictionary of attributes:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">@property</span>
<span class="n">def</span> <span class="n">state_attributes</span><span class="p">(</span><span class="n">self</span><span class="p">)</span><span class="o">:</span>
<span class="s">"""Return the attributes of the entity."""</span>
<span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">_attributes</span>
</code></pre>
</div>
<p>To get your component included in the Home Assistant releases, follow the steps described in the <a href="https://home-assistant.io/developers/#submitting-improvements">Submitting improvements</a> section. Basically you only need to move your component in the <code class="highlighter-rouge">homeassistant/component/</code> directory of your fork and create a Pull Request.</p>
</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/developers/development_states.markdown'>Edit this page on GitHub</a></div>
<div class='section'>
<h1 class="title delta">Development Guide</h1>
<ul class='divided sidebar-menu'>
<li>
<a href='/developers/'>Introduction </a>
<ul>
<li><a href='/developers/architecture/'>Architecture </a></li>
<li><a href='/developers/architecture_components/'>Components </a></li>
</ul>
</li>
<li>
<a href='/developers/development/'>Starting with Development </a>
<ul>
<li><a href='/developers/development_environment/'>Setting up Environment </a></li>
<li><a href='/developers/development_submitting/'>Submit your Work </a></li>
<li><a href='/developers/development_checklist/'>Checklist </a></li>
<li><a href='/developers/development_guidelines/'>Style guidelines </a></li>
<li><a href='/developers/development_testing/'>Testing </a></li>
<li><a href='/developers/development_catching_up/'>Catching up with Reality </a></li>
<li><a href='/developers/development_validation/'>Validation </a></li>
</ul>
</li>
<li>
<a href='/developers/development_101/'>Development 101 </a>
<ul>
<li><a href='/developers/development_hass_object/'>Hass object </a></li>
<li><a href='/developers/development_events/'>Events </a></li>
<li><a class='active' href='/developers/development_states/'>States </a></li>
<li><a href='/developers/development_services/'>Services </a></li>
<li><a href='/developers/development_config/'>Config </a></li>
</ul>
</li>
<li>
<a href='/developers/add_new_platform/'>Creating a new platform (to support a new device) </a>
<ul>
<li><a href='/developers/code_review_platform/'>Checklist creating a platform </a></li>
<li><a href='/developers/platform_example_sensor/'>Example sensor platform </a></li>
<li><a href='/developers/platform_example_light/'>Example light platform </a></li>
</ul>
</li>
<li>
<a href='/developers/creating_components/'>Adding a new component </a>
<ul>
<li><a href='/developers/code_review_component/'>Checklist creating a component </a></li>
<li><a href='/developers/component_loading/'>Loading components </a></li>
<li><a href='/developers/component_deps_and_reqs/'>Requirements & Dependencies </a></li>
<li><a href='/developers/component_events/'>Handling events </a></li>
<li><a href='/developers/component_states/'>States </a></li>
<li><a href='/developers/component_visibility/'>Visibility </a></li>
<li><a href='/developers/component_generic_discovery/'>Loading Platforms </a></li>
<li><a href='/developers/component_discovery/'>Component Discovery </a></li>
</ul>
</li>
<li>
<a href='/developers/intent/'>Intents (handling voice responses) </a>
<ul>
<li><a href='/developers/intent/firing/'>Firing intents </a></li>
<li><a href='/developers/intent/handling/'>Handling intents </a></li>
<li><a href='/developers/intent/conversation/'>Registering sentences </a></li>
</ul>
</li>
<li>
<a href='/developers/asyncio/'>Asynchronous Programming </a>
<ul>
<li><a href='/developers/asyncio_101/'>Introduction to asyncio </a></li>
<li><a href='/developers/asyncio_categorizing_functions/'>Categorizing Functions </a></li>
<li><a href='/developers/asyncio_working_with_async/'>Working with Async </a></li>
<li><a href='/developers/asyncio_misc/'>Miscellaneous </a></li>
</ul>
</li>
<li>
<a href='/developers/frontend/'>Frontend Development </a>
<ul>
<li><a href='/developers/frontend_add_card/'>Add State Card </a></li>
<li><a href='/developers/frontend_add_more_info/'>Add More Info Dialog </a></li>
<li><a href='/developers/frontend_creating_custom_panels/'>Add Custom Panels </a></li>
<li><a href='/developers/frontend_creating_custom_ui/'>Add Custom UI </a></li>
</ul>
</li>
<li>
<a href='/developers/hassio/architecture/'>Hass.io architecture </a>
<ul>
<li><a href='/developers/hassio/debugging/'>Debugging Hass.io </a></li>
</ul>
</li>
<li>
<a href='/developers/hassio/addon_development/'>Hass.io Add-on Development </a>
<ul>
<li><a href='/developers/hassio/addon_tutorial/'>Tutorial: Making your first add-on </a></li>
<li><a href='/developers/hassio/addon_config/'>Configuration </a></li>
<li><a href='/developers/hassio/addon_communication/'>Communication </a></li>
<li><a href='/developers/hassio/addon_testing/'>Local Testing </a></li>
<li><a href='/developers/hassio/addon_publishing/'>Publishing </a></li>
<li><a href='/developers/hassio/addon_repository/'>Repositories </a></li>
</ul>
</li>
<li>
<a href='/developers/api/'>API </a>
<ul>
<li><a href='https://dev-docs.home-assistant.io/en/dev/'>Python API </a></li>
<li><a href='/developers/websocket_api/'>Websocket API </a></li>
<li><a href='/developers/rest_api/'>REST API </a></li>
<li><a href='/developers/python_api/'>Python REST API </a></li>
<li><a href='/developers/server_sent_events/'>Server-sent events </a></li>
</ul>
</li>
<li>
<a href='/developers/documentation/'>Website/Documentation </a>
<ul>
<li><a href='/developers/documentation/standards/'>Standards </a></li>
<li><a href='/developers/documentation/create_page/'>Create a new page </a></li>
</ul>
</li>
<li><a href='/developers/helpers/'>Online helpers </a></li>
<li><a href='/developers/releasing/'>Releasing </a></li>
<li><a href='/developers/maintenance/'>Maintenance </a></li>
<li>
Governance
<ul>
<li><a href='/developers/cla/'>Contributor License Agreement </a></li>
<li><a href='/privacy/'>Privacy Policy </a></li>
<li><a href='/tos/'>Terms of Service </a></li>
<li><a href='/code_of_conduct/'>Code of Conduct </a></li>
<li><a href='/developers/credits/'>Credits </a></li>
<li><a href='/developers/license/'>License </a></li>
</ul>
</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>