259 lines
19 KiB
HTML
259 lines
19 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>Visualize your IoT data - Home Assistant</title>
|
||
<meta name="author" content="Fabian Affolter">
|
||
<meta name="description" content="Export, process, and visualize your Home Assistant data.">
|
||
<meta name="viewport" content="width=device-width">
|
||
<link rel="canonical" href="https://home-assistant.io/blog/2016/07/19/visualizing-your-iot-data/">
|
||
<meta property="fb:app_id" content="338291289691179">
|
||
<meta property="og:title" content="Visualize your IoT data">
|
||
<meta property="og:site_name" content="Home Assistant">
|
||
<meta property="og:url" content="https://home-assistant.io/blog/2016/07/19/visualizing-your-iot-data/">
|
||
<meta property="og:type" content="article">
|
||
<meta property="og:description" content="Export, process, and visualize your Home Assistant data.">
|
||
<meta property="og:image" content="https://home-assistant.io/images/blog/2016-07-reporting/libreoffice-graph.png">
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<meta name="twitter:site" content="@home_assistant">
|
||
<meta name="twitter:creator" content="@fabaff">
|
||
<meta name="twitter:title" content="Visualize your IoT data">
|
||
<meta name="twitter:description" content="Export, process, and visualize your Home Assistant data.">
|
||
<meta name="twitter:image" content="https://home-assistant.io/images/blog/2016-07-reporting/libreoffice-graph.png">
|
||
<link href="/stylesheets/screen.css" media="screen, projection" 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>
|
||
<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>
|
||
</ul>
|
||
</nav>
|
||
</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="post">
|
||
<header>
|
||
<h1 class="title indent">Visualize your IoT data</h1>
|
||
<div class="meta clearfix">
|
||
<time datetime="2016-07-19T16:00:00+00:00" pubdate data-updated="true"><i class="icon-calendar"></i> July 19, 2016</time>
|
||
<span class="byline author vcard"><i class='icon-user'></i> Fabian Affolter</span>
|
||
<span><i class='icon-time'></i> five minutes reading time</span>
|
||
<span>
|
||
<i class="icon-tags"></i>
|
||
<ul class="tags unstyled">
|
||
<li>How-To</li>
|
||
<li>IoT-Data</li>
|
||
</ul>
|
||
</span>
|
||
<a class='comments'
|
||
href="#disqus_thread"
|
||
>Comments</a>
|
||
</div>
|
||
</header>
|
||
<p><img src="/images/blog/2016-07-reporting/mpl-sensor.png" style="clear: right; border:none; box-shadow: none; float: right; margin-bottom: 12px;" width="200" /></p>
|
||
<p>The <a href="/components/history/">history component</a> is tracking everything that is going on within Home Assistant. This means that you have access to all stored information about your home. Our history is not a full-fledged graphical processing and visualization component as you may know from systems and network monitoring tools. The current limitation is that you only can select a day for a visual output of your information and not a period. Also, there is no possibility to drill down on a specific entity.</p>
|
||
<p>This blog post will show you ways to export data for reporting, visualization, or further analysis of automation rules.</p>
|
||
<a name="read-more"></a>
|
||
<p>In this blog post I use the temperature of the <a href="https://en.wikipedia.org/wiki/Aare">Aare</a> river close to where I live as a show case. The temperatures were recorded with the <a href="/components/sensor.swiss_hydrological_data/">Swiss Hydrological Data sensor</a> and the name of the sensor is <code class="highlighter-rouge">sensor.aare</code>.</p>
|
||
<p>The database is stored at <code class="highlighter-rouge"><path to config dir>/.homeassistant/home-assistant_v2.db</code> as <a href="https://www.sqlite.org/">SQLite database</a>. In all examples we are going to use the path: <code class="highlighter-rouge">/home/ha/.homeassistant/home-assistant_v2.db</code></p>
|
||
<p>If you are just curious what’s stored in your database then you can use the <code class="highlighter-rouge">sqlite3</code> command-line tool or a graphical one like <a href="http://sqlitebrowser.org/">DB Browser for SQLite</a>.</p>
|
||
<p>The table that is holding the states is called <code class="highlighter-rouge">states</code>. The <code class="highlighter-rouge">events</code> tables is responsible for storing the events which occurred. So, we will first check how many entries there are in the <code class="highlighter-rouge">states</code> table. <code class="highlighter-rouge">sqlite3</code> needs to know where the databases is located. To work with your database make sure that Home Assistant is not running or create a copy of the existing database. It’s recommended to work with a copy.</p>
|
||
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>sqlite3 /home/ha/.homeassistant/home-assistant_v2.db
|
||
SQLite version 3.11.0 2016-02-15 17:29:24
|
||
<span class="gp">sqlite> </span>SELECT count<span class="o">(</span><span class="k">*</span><span class="o">)</span> FROM states;
|
||
24659
|
||
</code></pre>
|
||
</div>
|
||
<p>Let’s have a look at a sample <a href="https://en.wikipedia.org/wiki/SQL">SQL</a> query. This query will show all states in a period for the sensor <code class="highlighter-rouge">sensor.aare</code>.</p>
|
||
<div class="language-sql highlighter-rouge"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">state</span><span class="p">,</span> <span class="n">last_changed</span> <span class="k">FROM</span> <span class="n">states</span>
|
||
<span class="k">WHERE</span>
|
||
<span class="n">entity_id</span> <span class="o">=</span> <span class="s1">'sensor.aare'</span>
|
||
<span class="k">AND</span>
|
||
<span class="n">last_changed</span> <span class="k">BETWEEN</span>
|
||
<span class="s1">'2016-07-05 00:00:00.000000'</span> <span class="k">AND</span> <span class="s1">'2016-07-07 00:00:00.000000'</span><span class="p">;</span>
|
||
</code></pre>
|
||
</div>
|
||
<p>The SQL statement can be formed that it fits exactly what you need. This means that you can process the data in any way you want for further use. Often it makes sense to eliminate certain entries like <code class="highlighter-rouge">Unknown</code> or peaks.</p>
|
||
<p>If the above query is executed in DB Browser for SQLite you would be able to save the sensor’s graph as png.</p>
|
||
<p class="img">
|
||
<img src="/images/blog/2016-07-reporting/db-browser.png" />
|
||
Visualization with DB Browser for SQLite
|
||
</p>
|
||
<p>You may ask: Why not do this with LibreOffice Calc or another spreadsheet application? As most spreadsheet applications are not able to work directly with SQLite database we are going to export the data from the database to <a href="https://en.wikipedia.org/wiki/Comma-separated_values">CSV</a>.</p>
|
||
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>sqlite3 -header -csv /home/ha/.homeassistant/home-assistant_v2.db <span class="s2">"SELECT last_changed, state FROM states WHERE entity_id = 'sensor.aare' AND last_changed BETWEEN '2016-07-05 00:00:00.000000' AND '2016-07-07 00:00:00.000000';"</span> > sensor.csv
|
||
</code></pre>
|
||
</div>
|
||
<p>The ordering for the <code class="highlighter-rouge">SELECT</code> was changed to get the time stamps first and then the state. Now we can import the CSV file into the application of your choice, here it’s LibreOffice Calc.</p>
|
||
<p class="img">
|
||
<img src="/images/blog/2016-07-reporting/libreoffice-import.png" />
|
||
Import of the CSV file
|
||
</p>
|
||
<p>After the import a graph can be created over the existing data.</p>
|
||
<p class="img">
|
||
<img src="/images/blog/2016-07-reporting/libreoffice-graph.png" />
|
||
Graph in LibreOffice
|
||
</p>
|
||
<p>You can also use <a href="http://matplotlib.org/">matplotlib</a> to generate graphs as an alternative to a spreadsheet application. This is a powerful Python 2D plotting library. With the built-in support for SQLite in Python it will only take a couple lines of code to visualize your data.</p>
|
||
<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">sqlite3</span>
|
||
<span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">dates</span>
|
||
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="kn">as</span> <span class="nn">plt</span>
|
||
|
||
<span class="kn">import</span> <span class="nn">homeassistant.util.dt</span> <span class="kn">as</span> <span class="nn">dt</span>
|
||
|
||
<span class="n">values</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="n">timestamps</span> <span class="o">=</span> <span class="p">[]</span>
|
||
|
||
<span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s">'/home/ha/.homeassistant/home-assistant_v2.db'</span><span class="p">)</span>
|
||
<span class="n">data</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"SELECT state, last_changed FROM states WHERE "</span>
|
||
<span class="s">"entity_id = 'sensor.aare' AND last_changed BETWEEN "</span>
|
||
<span class="s">"'2016-07-05 00:00:00.000000' AND "</span>
|
||
<span class="s">"'2016-07-07 00:00:00.000000'"</span><span class="p">)</span>
|
||
|
||
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
|
||
<span class="n">timestamps</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">dates</span><span class="o">.</span><span class="n">date2num</span><span class="p">(</span><span class="n">dt</span><span class="o">.</span><span class="n">parse_datetime</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
|
||
<span class="n">values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">plot_date</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="n">timestamps</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="n">values</span><span class="p">,</span> <span class="n">fmt</span><span class="o">=</span><span class="s">"r-"</span><span class="p">)</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s">'Temperature'</span><span class="p">)</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s">'Time line'</span><span class="p">)</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s">'sensor.png'</span><span class="p">)</span>
|
||
</code></pre>
|
||
</div>
|
||
<p>Creating a connection to the database and executing a query is similar to the ways already seen. The return values from the query are splitted into two lists. The time stamps must be converted in an value which is accepted by matplotlib and then the graph is generated and saved as image.</p>
|
||
<p class="img">
|
||
<img src="/images/blog/2016-07-reporting/mpl-sensor.png" />
|
||
Sensor graph generated by matplotlib
|
||
</p>
|
||
<p>Most of the graphs are pretty ugly. So, further beautification will be needed. If you have created a nice report including some amazing graphs then the Home Assistant community would be grateful for sharing them in our <a href="https://community.home-assistant.io/">forum</a>.</p>
|
||
</article>
|
||
<section id="disqus">
|
||
<h3 class="indent title">Comments</h3>
|
||
<div id="disqus_thread" aria-live="polite"><noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript></div>
|
||
</section>
|
||
</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">
|
||
<h1 class="title delta">About Home Assistant</h1>
|
||
<ul class="divided">
|
||
<li>
|
||
Home Assistant is an open-source home automation platform running on Python 3. Track and control all devices at home and automate control.
|
||
</li>
|
||
<li><a href='/getting-started/'>Get started with Home Assistant</a></li>
|
||
<li><a href='/demo/'>Try the online demo</a></li>
|
||
<li><a class="twitter-follow-button" href="https://twitter.com/Home_Assistant">Follow Home Assistant on Twitter</a></li>
|
||
<li><div class="fb-like" data-href="https://www.facebook.com/homeassistantio/" data-layout="standard" data-action="like" data-size="small" data-show-faces="true" data-share="false"></div></li>
|
||
</ul>
|
||
</section>
|
||
<div id="fb-root"></div>
|
||
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.async=true;js.src='//platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
|
||
<script>(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(d.getElementById(id)){return;}js=d.createElement(s);js.id=id;js.async=true;js.src="//connect.facebook.net/en_US/all.js#appId=338291289691179&xfbml=1";fjs.parentNode.insertBefore(js,fjs);}(document,'script','facebook-jssdk'));</script>
|
||
<section class="sharing aside-module grid__item one-whole lap-one-half">
|
||
<h1 class="title delta">Share this post</h1>
|
||
<a href="//twitter.com/share"
|
||
class="twitter-share-button"
|
||
data-via="home_assistant"
|
||
data-related="home_assistant"
|
||
data-url="https://home-assistant.io/blog/2016/07/19/visualizing-your-iot-data/"
|
||
data-counturl="https://home-assistant.io/blog/2016/07/19/visualizing-your-iot-data/" >Tweet</a>
|
||
<div class="fb-share-button" style='top: -6px;'
|
||
data-href="https://home-assistant.io/blog/2016/07/19/visualizing-your-iot-data/"
|
||
data-layout="button_count">
|
||
</div>
|
||
<div class="g-plusone" data-size="standard"></div>
|
||
</section>
|
||
<script src="https://apis.google.com/js/platform.js" async defer></script>
|
||
<section id="recent-posts" class="aside-module grid__item one-whole lap-one-half">
|
||
<h1 class="title delta">Recent Posts</h1>
|
||
<ul class="divided">
|
||
<li class="post">
|
||
<a href="/blog/2017/06/17/release-47/">0.47: Python Scripts, Sesame Smart Lock, Gitter, Onvif cameras</a>
|
||
</li>
|
||
<li class="post">
|
||
<a href="/blog/2017/06/15/zwave-entity-ids/">ZWave Entity IDs</a>
|
||
</li>
|
||
<li class="post">
|
||
<a href="/blog/2017/06/10/interview-with-jupiter-broadcasting/">Linux Action Show special about Home Assistant</a>
|
||
</li>
|
||
<li class="post">
|
||
<a href="/blog/2017/06/04/release-46/">0.46: Rachio sprinklers, Netgear Arlo cameras and Z-Wave fans</a>
|
||
</li>
|
||
<li class="post">
|
||
<a href="/blog/2017/06/02/home-assistant-podcast-1/">Home Assistant Podcast 1</a>
|
||
</li>
|
||
</ul>
|
||
</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>
|
||
<script>
|
||
var disqus_shortname = 'home-assistant';
|
||
// var disqus_developer = 1;
|
||
var disqus_identifier = 'https://home-assistant.io/blog/2016/07/19/visualizing-your-iot-data/';
|
||
var disqus_url = 'https://home-assistant.io/blog/2016/07/19/visualizing-your-iot-data/';
|
||
var disqus_script = 'embed.js';
|
||
(function () {
|
||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||
dsq.src = '//' + disqus_shortname + '.disqus.com/' + disqus_script;
|
||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||
}());
|
||
</script>
|
||
</body>
|
||
</html>
|