<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Mr Whale</title>
    <link>https://www.mrwhal3.com/</link>
    <description>Recent content on Mr Whale</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 13 Apr 2020 10:00:00 +0000</lastBuildDate>
    
	<atom:link href="https://www.mrwhal3.com/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>TTRSS &#43; Calibre - Turn your RSS feed into an EBook</title>
      <link>https://www.mrwhal3.com/2020/ttrss-calibre-turn-your-rss-feed-into-an-ebook/</link>
      <pubDate>Mon, 13 Apr 2020 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2020/ttrss-calibre-turn-your-rss-feed-into-an-ebook/</guid>
      <description>After turning an old Android tablet into a dedicated E-Reader by utilising KOReader, I also turned to Calibre to manage my E-Books. Utilising this Caibre recipe in this gist by oott123 I was able to get Calibre to pull my RSS feed (hosted on my TTRSS raspberry pi) into a ebook, that I could sync with my &amp;ldquo;reader&amp;rdquo; and read on the go.
Create a new &amp;ldquo;news&amp;rdquo; source  From the &amp;ldquo;Fetch News&amp;rdquo; icon in the main tool bar of Calibre, select the down arrow and click &amp;ldquo;Add or edit a custom news source&amp;rdquo;    Adding custom news source    Create a new recipe by clicking the &amp;ldquo;New recipe&amp;rdquo; button down the bottom left area of the pop up window    Add a new recipe    Give it a name and fill out the form to your prefernce, and then switch over to advanced mode    Switch to advanced mode    Copy in the recipe and adjust the variables in the code to point to your TTRSS instance.</description>
      <content> 

&lt;p&gt;After turning an old Android tablet into a dedicated E-Reader by utilising &lt;a href=&#34;http://koreader.rocks/&#34; target=&#34;_blank&#34;&gt;KOReader&lt;/a&gt;, I also turned to &lt;a href=&#34;https://calibre-ebook.com/&#34; target=&#34;_blank&#34;&gt;Calibre&lt;/a&gt; to manage my E-Books. Utilising this Caibre recipe in this &lt;a href=&#34;https://gist.github.com/oott123/d7833efcbf23ea604fb7&#34; target=&#34;_blank&#34;&gt;gist&lt;/a&gt; by &lt;a href=&#34;https://gist.github.com/oott123/&#34; target=&#34;_blank&#34;&gt;oott123&lt;/a&gt; I was able to get Calibre to pull my RSS feed (hosted on my &lt;a href=&#34;https://tt-rss.org/&#34; target=&#34;_blank&#34;&gt;TTRSS&lt;/a&gt; raspberry pi) into a ebook, that I could sync with my &amp;ldquo;reader&amp;rdquo; and read on the go.&lt;/p&gt;

&lt;h1 id=&#34;create-a-new-news-source&#34;&gt;Create a new &amp;ldquo;news&amp;rdquo; source&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;From the &amp;ldquo;Fetch News&amp;rdquo; icon in the main tool bar of Calibre, select the down arrow and click &amp;ldquo;Add or edit a custom news source&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://www.mrwhal3.com/img/ttrss-calibre-1.png&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;Adding custom news source&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;


&lt;ol&gt;
&lt;li&gt;Create a new recipe by clicking the &amp;ldquo;New recipe&amp;rdquo; button down the bottom left area of the pop up window&lt;/li&gt;
&lt;/ol&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://www.mrwhal3.com/img/ttrss-calibre-2.png&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;Add a new recipe&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;


&lt;ol&gt;
&lt;li&gt;Give it a name and fill out the form to your prefernce, and then switch over to advanced mode&lt;/li&gt;
&lt;/ol&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://www.mrwhal3.com/img/ttrss-calibre-3.png&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;Switch to advanced mode&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;


&lt;ol&gt;
&lt;li&gt;Copy in the &lt;a href=&#34;#recipe&#34;&gt;recipe&lt;/a&gt; and adjust the variables in the code to point to your TTRSS instance. Once done click save&lt;/li&gt;
&lt;/ol&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://www.mrwhal3.com/img/ttrss-calibre-4.png&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;Code and stuff&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;


&lt;ol&gt;
&lt;li&gt;&lt;p&gt;From here you can add automatic download schedule that Calibre will handle (usefull if you run calibre on a server somewhere) and hit Okay
&lt;figure&gt;
    &lt;img src=&#34;https://www.mrwhal3.com/img/ttrss-calibre-5.png&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;Adjust scheduling&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Sync your device with Calibre and it will bring your feeds in. This works nicely if you fetch it daily, as you will then have a daily news book to read. This recipe also marks the fetched news items as read within TTRSS&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://www.mrwhal3.com/img/ttrss-calibre-6.png&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;How Calibre shows a ttrss ebook in the list&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h1 id=&#34;recipe&#34;&gt;recipe&lt;/h1&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/env python2&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; __future__ &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; unicode_literals, division, absolute_import, print_function
&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; calibre.web.feeds.news &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; BasicNewsRecipe
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; urllib2&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; urllib&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; pprint&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; re&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; ssl

&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;TClient&lt;/span&gt;():
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; __init__(self, url, username, password, logger, key, test &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; False):
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/api/&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; url
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;username &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; username
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;password &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; password
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; logger
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sid &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; None
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;test &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; test
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; key
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;login()
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_request&lt;/span&gt;(self, op, data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; None):
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; op &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;login&amp;#39;&lt;/span&gt;:
            data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;sid&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sid
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; data &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; None:
            data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {}
        data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;op&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; op
        data_string &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps(data)
        json_string &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; None
        &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
            req &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; urllib2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Request(self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;url, data_string, {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;User-Agent&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Mozilla/4.0&amp;#39;&lt;/span&gt;})
            res &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; urllib2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;urlopen(req, context&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ssl&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;_create_unverified_context())
            json_string &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; res&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read()
        &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; urllib2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;HTTPError,e:
            &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(e&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read())
            &lt;span style=&#34;color:#66d9ef&#34;&gt;raise&lt;/span&gt; e
        object &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;loads(json_string)
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;error&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; object:
            &lt;span style=&#34;color:#66d9ef&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Exception&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Tiny Tiny RSS Error: URL-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, DATA-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, RESP-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt;(self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;url, data_string, json_string))
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; object[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;]
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;login&lt;/span&gt;(self):
        data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;_request(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;login&amp;#39;&lt;/span&gt;, {
            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;: self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;username,
            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;password&amp;#34;&lt;/span&gt;: self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;password
        })
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;session_id&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; data:
            self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;warn(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Tiny Tiny RSS Error: failed to load session id.&amp;#34;&lt;/span&gt;)
            &lt;span style=&#34;color:#66d9ef&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Exception&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Tiny Tiny RSS Error: failed to load session id.&amp;#34;&lt;/span&gt;)
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sid &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;session_id&amp;#39;&lt;/span&gt;]
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;info(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Get session id &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sid)
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_articles&lt;/span&gt;(self, urls, offset &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, limit &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;):
        id_list &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
        data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {}
        data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;feed_id&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# all unread&lt;/span&gt;
        data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;limit&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; limit
        data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;offset&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; offset
        data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;show_content&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; True
        data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;view_mode&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;unread&amp;#39;&lt;/span&gt;
        data[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;sanitize&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; False
        feeds &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;_request(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;getHeadlines&amp;#39;&lt;/span&gt;, data)
        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; feeds:
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;feed_title&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; urls:
                urls[i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;feed_title&amp;#39;&lt;/span&gt;]] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
            urls[i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;feed_title&amp;#39;&lt;/span&gt;]]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append({
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;: i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;],
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;url&amp;#39;&lt;/span&gt;: i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;link&amp;#39;&lt;/span&gt;],
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;date&amp;#39;&lt;/span&gt;: i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;updated&amp;#39;&lt;/span&gt;],
                &lt;span style=&#34;color:#75715e&#34;&gt;#&amp;#39;content&amp;#39;: self.append_url(i[&amp;#39;content&amp;#39;], i[&amp;#39;link&amp;#39;]),&lt;/span&gt;
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;: i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;],
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;description&amp;#39;&lt;/span&gt;: i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;excerpt&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;excerpt&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; i &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
            })
            id_list&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;])
        read_data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;article_ids&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join(id_list),
            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;field&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
        }
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;test:
            self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;_request(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;updateArticle&amp;#39;&lt;/span&gt;, read_data)
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; urls
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_all_articles&lt;/span&gt;(self):
        urls &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {}
        countLast &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
        &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; True:
            counters &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;_request(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;getCounters&amp;#39;&lt;/span&gt;, {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mode&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;f&amp;#39;&lt;/span&gt;})
            count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
            &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; counters:
                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;:
                        count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; i[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;counter&amp;#39;&lt;/span&gt;]
                        &lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; count &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;:
                &lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; countLast &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; count:
                &lt;span style=&#34;color:#66d9ef&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Exception&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;There&amp;#39;s some error when marking read articles.&amp;#34;&lt;/span&gt;)
            countLast &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; count
            urls &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get_articles(urls)
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;test:
                &lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; urls
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;append_url&lt;/span&gt;(self, raw_html, url):
        u &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; urllib&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;quote(url)
        share_url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://httpbin.org/get?key=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;amp;url=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; (self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;key, u)
        qr_url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://chart.googleapis.com/chart?cht=qr&amp;amp;chs=300x300&amp;amp;choe=UTF-8&amp;amp;chld=H|4&amp;amp;chl=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; u
        append_html &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;u&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; (qr_url, share_url, url)
        raw_html &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; re&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sub(&lt;span style=&#34;color:#e6db74&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;(\&amp;lt;/body\&amp;gt;|$)&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;\1&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; append_html, raw_html, count&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; raw_html

&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;YueDu&lt;/span&gt;(BasicNewsRecipe):
    
    title &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;u&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;TTRSS + Calibre&amp;#39;&lt;/span&gt;
    __author__ &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Mrwhale&amp;#39;&lt;/span&gt;
    description &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;u&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;TTRSS + Calibre&amp;#39;&lt;/span&gt;
    timefmt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;%Y-%m-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; %A&amp;#39;&lt;/span&gt;
    needs_subscription &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; True
    oldest_article &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;
    max_articles_per_feed &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;
    publication_type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;newspaper&amp;#39;&lt;/span&gt;
    compress_news_images &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; True
    use_embedded_content &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; True
    cover_url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    masthead_url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;parse_index&lt;/span&gt;(self):
        ttrss_url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;URL&amp;#34;&lt;/span&gt;
        ttrss_username &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;
        ttrss_password &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pass&amp;#34;&lt;/span&gt;
        ttrss_key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;WTF_IS_OK&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#75715e&#34;&gt;#(ttrss_url, ttrss_username, ttrss_key) = self.username.split(&amp;#39;;&amp;#39;)&lt;/span&gt;
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;info(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Getting URL-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, username-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; (ttrss_url, ttrss_username))
        ttrss_password &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;password
        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;info(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Getting Password-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;******&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; ttrss_password[:&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;])
        ttrss &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; TClient(ttrss_url, ttrss_username, ttrss_password, self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log, ttrss_key, self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;test)
        urls &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ttrss&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get_all_articles()
        index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (key, value) &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; urls&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;iteritems():
            self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;info(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Key:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; - length: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; (key, len(value)))
            index&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append((key, value))
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; index&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 </content>
    </item>
    
    <item>
      <title>E-ink cryptocurrency ticker</title>
      <link>https://www.mrwhal3.com/2020/e-ink-cryptocurrency-ticker/</link>
      <pubDate>Wed, 18 Mar 2020 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2020/e-ink-cryptocurrency-ticker/</guid>
      <description>I like the idea of e-ink. Ultra Low power, easily readable displays. Big fan. I also follow some cryptocurrency&amp;rsquo;s. So this project is a merge of these 2 things. It&amp;rsquo;s still a work in progress, as there a few bugs I need to sort out, and I need a nice looking case. But for now it was a fun project that does the thing well and I got to learn some image manipulation in python!</description>
      <content> 

&lt;p&gt;I like the idea of e-ink. Ultra Low power, easily readable displays. Big fan. I also follow some cryptocurrency&amp;rsquo;s. So this project is a merge of these 2 things. It&amp;rsquo;s still a work in progress, as there a few bugs I need to sort out, and I need a nice looking case. But for now it was a fun project that does the thing well and I got to learn some image manipulation in python!&lt;/p&gt;

&lt;h1 id=&#34;the-hardware&#34;&gt;the hardware&lt;/h1&gt;

&lt;h2 id=&#34;raspberry-pi-3&#34;&gt;raspberry pi 3&lt;/h2&gt;

&lt;p&gt;I had a spare one of those laying around, but they are very cheap these days. Almost any version can be used here. In the next iteration I will use a pi zero, as it will be even smaller form factor as it&amp;rsquo;s around the same dimensions as the e-ink display I used&lt;/p&gt;

&lt;h2 id=&#34;pomodoro-inkyphat-2-7-e-ink-display-black-and-white-model&#34;&gt;Pomodoro inkyphat 2.7&amp;rdquo; e-ink display (black and white model)&lt;/h2&gt;

&lt;p&gt;The code currently is specific to this model as I generate an image for 2.7&amp;rdquo; and utilise the inkyphat python module, however it shouldn&amp;rsquo;t be too difficult to adjust for a larger size or model&lt;/p&gt;

&lt;h1 id=&#34;the-software&#34;&gt;the software&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;python (3)&lt;/li&gt;
&lt;li&gt;inkyphat&lt;/li&gt;
&lt;li&gt;python pillow&lt;/li&gt;
&lt;li&gt;mathplot lib&lt;/li&gt;
&lt;li&gt;mpl-finance&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&#34;the-code&#34;&gt;the code&lt;/h1&gt;

&lt;p&gt;Hosted in &lt;a href=&#34;https://gitlab.com/mrwhale/inky-cryptochart&#34; target=&#34;_blank&#34;&gt;gitlab&lt;/a&gt; you can view the entire repository here. This was build ontop of an &lt;a href=&#34;https://github.com/DurandA/inky-cryptochart&#34; target=&#34;_blank&#34;&gt;existing&lt;/a&gt; eink cryptocurrency project. The main differences was that I had the black and white e-ink display so the candlestick graph was not easy to read (it was challenging to set variations of grey) so I decided to just graph it with a spark-line.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.mrwhal3.com/img/inky.png&#34; alt=&#34;Image&#34; /&gt;&lt;/p&gt;

&lt;p&gt;I have also added a function to utilise the Binance public API rather then Kraken.&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;quotes_historical_binance_ohlc&lt;/span&gt;(pair, since, interval&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;15m&amp;#39;&lt;/span&gt;):
    unix_time &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; since&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strftime(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; interval &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1d&amp;#39;&lt;/span&gt;:
      payload &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;symbol&amp;#39;&lt;/span&gt;: pair,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;interval&amp;#39;&lt;/span&gt;: interval, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;limit&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;200&amp;#39;&lt;/span&gt;}
    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
      payload &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;symbol&amp;#39;&lt;/span&gt;: pair,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;interval&amp;#39;&lt;/span&gt;: interval, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;limit&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;200&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;startTime&amp;#39;&lt;/span&gt;: int(since&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strftime(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;))&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;}
    r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://api.binance.com/api/v1/klines&amp;#39;&lt;/span&gt;, params&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;payload)
    &lt;span style=&#34;color:#75715e&#34;&gt;#print(r.json())&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;parse_ohlc&lt;/span&gt;(data):
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; [[int(l[&lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;), float(l[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]), float(l[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;]), float(l[&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;]), float(l[&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;]), float(l[&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;])] &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; l &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; data]

    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; parse_ohlc(r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;json())&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There was also a sticking point about the new InkyPhat python module. The new version had all of the python image manipulation functions removed out of the module, so I had to do it directly with Pillow.&lt;/p&gt;

&lt;p&gt;The last thing to change was adding a config to make sure that mpl could run in headless mode&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; matplotlib &lt;span style=&#34;color:#f92672&#34;&gt;as&lt;/span&gt; mpl
mpl&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;use(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Agg&amp;#39;&lt;/span&gt;)
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; matplotlib.pyplot &lt;span style=&#34;color:#f92672&#34;&gt;as&lt;/span&gt; plt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Run this in your scheduler (cron) and you can be the cool kid in the office again.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.mrwhal3.com/img/inky-crypto-pi.png&#34; alt=&#34;Inky pi&#34; /&gt;&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Default Azure Search Service query key and Terraform</title>
      <link>https://www.mrwhal3.com/2020/default-azure-search-service-query-key-and-terraform/</link>
      <pubDate>Tue, 03 Mar 2020 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2020/default-azure-search-service-query-key-and-terraform/</guid>
      <description>Need to get the default Azure Search Service query key into a variable to use in other parts of your terraform infrastructure? I did too. Unfortunately the docs for this were a bit vague, so through a bit of trial and error we got there
azurerm_search_service.example.query_keys[0].key
Given that these query keys are called the &amp;ldquo;default&amp;rdquo; keys, I assumed we could access this attribute by azurerm_search_service.example.query_keys.default.key. But that was not the case.</description>
      <content> &lt;p&gt;Need to get the default Azure Search Service query key into a variable to use in other parts of your &lt;a href=&#34;https://terraform.io/&#34; target=&#34;_blank&#34;&gt;terraform&lt;/a&gt; infrastructure? I did too. Unfortunately the &lt;a href=&#34;https://www.terraform.io/docs/providers/azurerm/r/search_service.html&#34; target=&#34;_blank&#34;&gt;docs&lt;/a&gt; for this were a bit vague, so through a bit of trial and error we got there&lt;/p&gt;

&lt;p&gt;&lt;code&gt;azurerm_search_service.example.query_keys[0].key&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Given that these query keys are called the &amp;ldquo;default&amp;rdquo; keys, I assumed we could access this attribute by &lt;code&gt;azurerm_search_service.example.query_keys.default.key&lt;/code&gt;. But that was not the case.&lt;/p&gt;

&lt;p&gt;After outputting the query_key attributes during a terraform &lt;code&gt;apply&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;output &amp;quot;searchkeys&amp;quot; {
  value = azurerm_search_service.example.query_keys
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I could see that this &amp;ldquo;default&amp;rdquo; key was actually nameless&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;searchkeys = [
  {
    &amp;quot;key&amp;quot; = &amp;quot;be2c38e286fff7df25d17e21294604a8&amp;quot;
    &amp;quot;name&amp;quot; = &amp;quot;&amp;quot;
  },
]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;More trial and error&lt;/p&gt;

&lt;p&gt;&lt;code&gt;azurerm_search_service.example.query_keys.object[0].key&lt;/code&gt;
&lt;code&gt;azurerm_search_service.example.query_keys.&amp;quot;&amp;quot;.key&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;but the winning combination was&lt;/p&gt;

&lt;p&gt;&lt;code&gt;azurerm_search_service.example.query_keys[0].key&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So now you can use this in other parts of your terraform infrastructure as you normally would. For example, inside of appsettings for an Azure web app:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;....
  app_settings = {
    &amp;quot;AzureSearchConfig:SearchServiceName&amp;quot; = azurerm_search_service.example.name
    &amp;quot;AzureSearchConfig:SearchServiceQueryApiKey&amp;quot; = azurerm_search_service.example.query_keys[0].key
    &amp;quot;AzureStorageConfig:ConnectionString&amp;quot; = azurerm_storage_account.example.primary_connection_string
    &amp;quot;WEBSITE_TIME_ZONE&amp;quot; = &amp;quot;AUS Eastern Standard Time&amp;quot;
    &amp;quot;WEBSITE_RUN_FROM_PACKAGE&amp;quot; = &amp;quot;1&amp;quot;
  }
....
&lt;/code&gt;&lt;/pre&gt;
 </content>
    </item>
    
    <item>
      <title>Useful Commands - OpenSSL</title>
      <link>https://www.mrwhal3.com/2019/useful-commands-openssl/</link>
      <pubDate>Sun, 24 Mar 2019 09:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2019/useful-commands-openssl/</guid>
      <description>openSSL is a very handy tool from the command line. Managing multiple sites and domains I almost use it everyday to do crypto relating things to websites - checking validity, preparing new CSRs, converting certificates to different formats for different operating systems. Here are some of those that I&amp;rsquo;ve used along the way
Read .cer in plain text openssl x509 -in certificate.cer -text -noout
convert from pkcs12 (windows format, with private key and cert) to pem (-nocerts for only priv key or -nokeys for only certs) openssl pkcs12 -in keystore.</description>
      <content> 

&lt;p&gt;&lt;code&gt;openSSL&lt;/code&gt; is a very handy tool from the command line. Managing multiple sites and domains I almost use it everyday to do crypto relating things to websites - checking validity, preparing new CSRs, converting certificates to different formats for different operating systems. Here are some of those that I&amp;rsquo;ve used along the way&lt;/p&gt;

&lt;h3 id=&#34;read-cer-in-plain-text&#34;&gt;Read .cer in plain text&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;openssl x509 -in certificate.cer -text -noout&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&#34;convert-from-pkcs12-windows-format-with-private-key-and-cert-to-pem-nocerts-for-only-priv-key-or-nokeys-for-only-certs&#34;&gt;convert from pkcs12 (windows format, with private key and cert) to pem (-nocerts for only priv key or -nokeys for only certs)&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;openssl pkcs12 -in keystore.pfx -out keystore.pem -nodes&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&#34;read-pfx-cert&#34;&gt;Read pfx cert&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;openssl pkcs12 -info -in cert.pfx&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&#34;read-website-ssl-cert&#34;&gt;Read website SSL cert&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;openssl s_client -showcerts -servername www.google.com -connect www.google.com:443&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;using -servername for SNI&lt;/p&gt;

&lt;h3 id=&#34;get-website-ssl-expiry&#34;&gt;Get website SSL expiry&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;openssl s_client -showcerts -connect www.google.com:443 | openssl x509 -noout -dates&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&#34;convert-privkey-and-cert-to-pfx-going-from-linux-to-windows&#34;&gt;Convert privkey and cert to pfx (going from linux to windows)&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;openssl pkcs12 -export -out cert.pfx -inkey privkey.key -in cert.crt -certfile CAcert.cert -name &amp;quot;Friendly_name&amp;quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-name&lt;/code&gt; will add the Friendly name that shows up in windows certificate manager and IIS&lt;/p&gt;

&lt;h3 id=&#34;testing-mail-servers-are-using-ssl&#34;&gt;Testing mail servers are using ssl&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;openssl s_client -connect mail.example.com:25 -starttls smtp&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&#34;verify-csr&#34;&gt;verify csr&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;openssl req -in mycsr.csr -noout -text&lt;/code&gt;&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Useful Commands - Image manipulation</title>
      <link>https://www.mrwhal3.com/2018/useful-commands-image-manipulation/</link>
      <pubDate>Thu, 21 Jun 2018 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2018/useful-commands-image-manipulation/</guid>
      <description>I often work with images to go onto e-commerce sites, so getting them as small as possbile (file size wise) is what I aim for, for performance There are plenty of good, paid tools out there such as Kraken or ImageOptim and there are even some good, free (web based) tools you can use such as TinyPNG and Compressor but I was looking for something a I could add into my workflow (read automated and scriptable)</description>
      <content> 

&lt;p&gt;I often work with images to go onto e-commerce sites, so getting them as small as possbile (file size wise) is what I aim for, for performance
There are plenty of good, paid tools out there such as &lt;a href=&#34;https://kraken.io/&#34; target=&#34;_blank&#34;&gt;Kraken&lt;/a&gt; or &lt;a href=&#34;https://imageoptim.com/api&#34; target=&#34;_blank&#34;&gt;ImageOptim&lt;/a&gt; and there are even some good, free (web based) tools you can use such as &lt;a href=&#34;https://tinypng.com/&#34; target=&#34;_blank&#34;&gt;TinyPNG&lt;/a&gt; and &lt;a href=&#34;https://compressor.io/&#34; target=&#34;_blank&#34;&gt;Compressor&lt;/a&gt; but I was looking for something a I could add into my workflow (read automated and scriptable)&lt;/p&gt;

&lt;p&gt;My needs were very specific. Each input image was the same dimensions (2048x) and is a &lt;code&gt;.png&lt;/code&gt; and they needed to stay square. Initialy I combined the tools within &lt;code&gt;ImageMagik&lt;/code&gt;,  &lt;code&gt;pngquant&lt;/code&gt; and &lt;code&gt;jpegoptim&lt;/code&gt; I could get the original 3-4mb image down to 132kb (@ 1024x1024) or 37kb (@512x512) with very little noticable quality differences. But then I started just using &lt;code&gt;ImageMagik&lt;/code&gt; to get similar results, but only needing the &lt;code&gt;convert&lt;/code&gt; tool&lt;/p&gt;

&lt;h3 id=&#34;using-all-3-tools&#34;&gt;Using all 3 tools&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Drop the quality &lt;code&gt;pngquant --quality=85-100 in.png&lt;/code&gt; #This is destructive, but you can specify out.png if needed&lt;/li&gt;
&lt;li&gt;Lets resize it and convert to jpeg &lt;code&gt;convert in.png -resize 1024 bigimage.png bigimage1024.jpg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Strip metadata and make it progressive &lt;code&gt;jpegoptim --all-progressive --strip-all -m85 bigimage1024.jpg&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are some tests, resizing to 1024 and 512 using both methods&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#Start&lt;/span&gt;
george@GEORGE-LT:$ file bigimage.png
bigimage.png: PNG image data, &lt;span style=&#34;color:#ae81ff&#34;&gt;2048&lt;/span&gt; x &lt;span style=&#34;color:#ae81ff&#34;&gt;2048&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;-bit/color RGBA, non-interlaced

george@GEORGE-LT:$ ls -lah bigimage.png
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;.9M Jul  &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;2017&lt;/span&gt; bigimage.png

george@GEORGE-LT:$ pngquant --quality&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt;-100 bigimage.png

george@GEORGE-LT:$ convert bigimage.png -resize &lt;span style=&#34;color:#ae81ff&#34;&gt;1024&lt;/span&gt; bigimage1024x.jpg

george@GEORGE-lt$ ls -lah bigimage*
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george 115K Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:22 bigimage1024x.jpg
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george  37K Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:23 bigimage512x.jpg
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;.0M Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:20 bigimage.png

george@GEORGE-LT:$ jpegoptim --all-progressive --strip-all -m85 bigimage1024x.jpg
bigimage1024x.jpg 1024x1024 24bit N JFIF  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;OK&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;117484&lt;/span&gt; --&amp;gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;93472&lt;/span&gt; bytes &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;.44%&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, optimized.

george@GEORGE-LT:$ jpegoptim --all-progressive --strip-all -m85 bigimage512x.jpg
bigimage512x.jpg 512x512 24bit N JFIF  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;OK&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;37769&lt;/span&gt; --&amp;gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;30200&lt;/span&gt; bytes &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;.04%&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, optimized.

george@GEORGE-LT:$ ls -lah bigimage*
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george  92K Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:24 bigimage1024x.jpg
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george  30K Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:24 bigimage512x.jpg
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;.0M Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:20 bigimage.png&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;using-just-convert&#34;&gt;Using just convert&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;convert -resize 1024 -quality 85 -trim -interlace Plane bigimage.png bigimage1024.jpg&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;george@GEORGE-LT:$ convert -resize &lt;span style=&#34;color:#ae81ff&#34;&gt;1024&lt;/span&gt; -quality &lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt; -trim -interlace Plane bigimage.png bigimage1024.jpg
george@GEORGE-LT:$ convert -resize &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; -quality &lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt; -trim -interlace Plane bigimage.png bigimage512x.jpg
george@GEORGE-LT:$ ls -lah bigimage*
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george  75K Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:30 bigimage1024.jpg
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george  26K Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:30 bigimage512x.jpg
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;.0M Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:20 bigimage.png

george@GEORGE-LT:$ file bigimage1024.jpg
bigimage1024.jpg: JPEG image data, JFIF standard &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;.01, aspect ratio, density 1x1, segment length &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;, progressive, precision &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;, 1024x1024, frames &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Just for fun, here is some tests without resizing the iamges, so you can see how powerful it is with a good comparison&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;george@GEORGE-LT$ convert -trim -quality &lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt; -interlace Plane bigimage.png bigimageoptimised.jpg
george@GEORGE-LT:$ ls -lah bigimage*
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george 250K Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;:09 bigimageoptimised.jpg
-rwxrwxrwx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; george george &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;.0M Jun &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:20 bigimage.png&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;So you can see that just using &lt;code&gt;convert&lt;/code&gt; to do all the works gives you slightly better results then the other tools. You can tweak it further to get better results, but in my trials I found that 85% quality was the best for keeping almost quality while getting the smallest file size. If you go too low in quality, you get a &lt;em&gt;much&lt;/em&gt; smaller file, but the quality starts getting noticably bad&lt;/p&gt;

&lt;p&gt;These sizes and qualities are perfect for online viewing. When 75+% of the viewing is done on mobile devices, users will not at all see the difference. And they look good on desktop too.&lt;/p&gt;

&lt;p&gt;Given that I originally wanted this to be somewhat automated and scriptable, I started a project over on my Github to get this optimisation web based (and eventually with an API). You can check it out &lt;a href=&#34;https://github.com/mrwhale/php-image-optimise&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://imagemagick.org/script/convert.php&#34; target=&#34;_blank&#34;&gt;Convert documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pngquant.org/&#34; target=&#34;_blank&#34;&gt;PNGquant documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.kokkonen.net/tjko/src/man/jpegoptim.txt&#34; target=&#34;_blank&#34;&gt;JPEGoptim documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 </content>
    </item>
    
    <item>
      <title>Cross compiling Litecoin Core</title>
      <link>https://www.mrwhal3.com/2018/cross-compiling-litecoin-core/</link>
      <pubDate>Wed, 09 May 2018 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2018/cross-compiling-litecoin-core/</guid>
      <description>I&amp;rsquo;ve had a plan of being a good guy and contributing to the litecoin network by being a full node. I was able to do this when I got around to buying a raspberry pi 3B+ and a 2TB external hard drive. There isn&amp;rsquo;t many up-to-date guides out there on setting a full node up on a raspberry pi, but this one was the most recent, and worked every step of the way (with a few minor changes) - the school of litecoin</description>
      <content> 

&lt;p&gt;I&amp;rsquo;ve had a plan of being a good guy and contributing to the litecoin network by being a full node. I was able to do this when I got around to buying a raspberry pi 3B+ and a 2TB external hard drive. There isn&amp;rsquo;t many up-to-date guides out there on setting a full node up on a raspberry pi, but this one was the most recent, and worked every step of the way (with a few minor changes) - &lt;a href=&#34;https://medium.com/the-litecoin-school-of-crypto/creating-a-litecoin-node-on-a-raspberry-pi-3-the-easy-way-on-windows-8e78d4da1af5&#34; target=&#34;_blank&#34;&gt;the school of litecoin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I followed this guide and successfully setup a headless litecoin full node with no wallet, that stores the blockchain on an external harddrive (to hopefully save some SD card wear). I will post another, updated guide, heavily based on this one in my next post. But give that a read first as I won&amp;rsquo;t cover the basics that are covered in that medium publication. The only thing I didn&amp;rsquo;t get out of this guide was the wallet part of the node, as the wallet component requires a specific version of berkleyDB which you also have to manually compile (which isn&amp;rsquo;t covered in the guide)&lt;/p&gt;

&lt;p&gt;This was great, however it took ~4 hours total to get this up and running (and an extra 2 days to fully sync the node) Seeing as though I plan to keep this thing updated, I did not want to have to spend 4 hours compiling the newest version of litecoin for every release. So that is when I thought of cross compiling from my desktop, to hopefully save time. As I don&amp;rsquo;t often do this, it took my quite a bit of time and research to get it working, but will now save myself (and hopefully others) time in the future! This guide would also be useful for any cryptocurrency that is a fork of bitcoin too&lt;/p&gt;

&lt;p&gt;raspberrypi) and the target PC (the raspberrypi)&lt;/p&gt;

&lt;h4 id=&#34;host-pc&#34;&gt;Host PC&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;Linux george-linux 4.4.0-98-generic #121-Ubuntu SMP Tue Oct 10 14:24:03 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

Distributor ID: neon
Description:    KDE neon User Edition 5.12
Release:        16.04
Codename:       xenial
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;target-pc&#34;&gt;Target PC&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;Linux georgeboy 4.14.34-v7+ #1110 SMP Mon Apr 16 15:18:51 BST 2018 armv7l GNU/Linux

Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.4 (stretch)
Release:        9.4
Codename:       stretch
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;instructions&#34;&gt;Instructions&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install the dependancies for cross compile, there are quite a few
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ sudo apt-get install gcc-arm-linux-gnueabi binutils-arm-linux-gnueabi curl g +-aarch64-linux-gnu g++-4.8-aarch64-linux-gnu gcc-4.8-aarch64-linux-gnu binutils-aarch64-linux-gnu g++-arm-linux-gnueabihf g++-4.8-arm-linux-gnueabihf gcc-4.8-arm-linux-gnueabihf binutils-arm-linux-gnueabihf g++-4.8-multilib gcc-4.8-multilib binutils-gold bsdmainutils&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Get the latest litecoin and extract (at the time I used 0.16.0rc1)
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# https://github.com/litecoin-project/litecoin/releases&lt;/span&gt;
wget https://github.com/litecoin-project/litecoin/archive/v0.16.0rc1.tar.gz
tar zxvf v0.16.0rc1.tar.gz&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;make the dependancies for the architecture you are compling for. This will go and grab a whole bunch of things, but you can turn off things you do not want here by adding some arguments to the make command
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd litecoin-0.16.0rc1/depends
make host&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;arm-linux-gnueabihf -j4 
&lt;span style=&#34;color:#75715e&#34;&gt;# if you do not want wallet or gui&lt;/span&gt; 
&lt;span style=&#34;color:#75715e&#34;&gt;# make host=arm-linux-gnueabihf -j4 NO_WALLET=1 NO_QT=1&lt;/span&gt; 
real    5m28.381s
user    6m17.932s
sys     0m21.860s&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;now do the thing for litecoin
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd ..
./autogen.sh
./configure LDFLAGS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;-static&amp;#34;&lt;/span&gt; CXXFLAGS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;-O2 --param ggc-min-expand=1 --param ggc-min-heapsize=32768&amp;#34;&lt;/span&gt; --enable-cxx --without-gui --disable-shared --with-pic --build x86_64-pc-linux-gnu --host arm-linux-gnueabi --prefix&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;pwd&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;/depends/arm-linux-gnueabihf
&lt;span style=&#34;color:#75715e&#34;&gt;# time for ./configure&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# real    0m36.008s&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# user    0m30.848s&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# sys     0m1.352s&lt;/span&gt;
sudo make -j4
&lt;span style=&#34;color:#75715e&#34;&gt;# I use sudo here as I tried make by itself but ran into an issue, see &amp;#34;Issues&amp;#34; below&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# real    18m3.695s&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# user    71m0.420s&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# sys     0m28.704s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Now copy over to your raspberrypi and test
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;scp src/litecoind src/litecoin-cli src/litecoin-tx george@newrpi:~/

george@newrpi:~ $ ./litecoind --version
Litecoin Core Daemon version v0.16.0.0-g3567effe2049
Copyright &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;C&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2011&lt;/span&gt;-2018 The Litecoin Core developers
Copyright &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;C&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2009&lt;/span&gt;-2018 The Bitcoin Core developers

Please contribute &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; you find Litecoin Core useful. Visit
&amp;lt;https://litecoin.org&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; further information about the software.
The source code is available from
&amp;lt;https://github.com/litecoin-project/litecoin&amp;gt;.

This is experimental software.
Distributed under the MIT software license, see the accompanying file COPYING
or &amp;lt;https://opensource.org/licenses/MIT&amp;gt;

This product includes software developed by the OpenSSL Project &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; use in the
OpenSSL Toolkit &amp;lt;https://www.openssl.org&amp;gt; and cryptographic software written by
Eric Young and UPnP software written by Thomas Bernard.

george@newrpi:~ $ ./litecoin-cli --version
Litecoin Core RPC client version v0.16.0.0-g3567effe2049&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
So all up (including installing the depedancies) 30 minutes to cross compile a litecoin node (including the wallet) for your raspberry pi. Seeing that the current stable is 0.15.1, and v0.16.0 is on RC, you&amp;rsquo;ll be upgrading soon so we have already saved some time&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;issues-i-ran-into-along-the-way&#34;&gt;Issues I ran into along the way&lt;/h3&gt;

&lt;p&gt;Firstly I ran &lt;code&gt;./autogen.sh&lt;/code&gt;, &lt;code&gt;./configure&lt;/code&gt; and &lt;code&gt;make&lt;/code&gt; directly in the litecoin folder without first building in the depends/ folder. I soon realised I needed Berkley DB. So I downloaded it and cross compiled it for arm. Then tried &lt;code&gt;./configure&lt;/code&gt; again using &lt;code&gt;LDFLAGS=&amp;quot;-static -L${BDB_PREFIX}/lib/&amp;quot; CXXFLAGS=&amp;quot;-I${BDB_PREFIX}/include/&lt;/code&gt; as arguments to point to the compiled Berkley DB files. This got me further but then I started running into libboost issues with an error similar to &lt;code&gt;bitcoinserver_a error adding symbols: Archive has no index; run ranlib to add one&lt;/code&gt; this is because of a mismatch in architecture as it was referencing the x86_64 libboost files, turns out I need the arm version of boost libraries. I attempted to install multiarch on my desktop but that did not work, and eventually I found a pre-compiled version of libboost for arm on the rasbperrypi.org forums. I downloaded that and used &lt;code&gt;--with-boost-libdir=/home/george/lib&lt;/code&gt; within &lt;code&gt;./configure&lt;/code&gt; to tell it about the arm libboost files. This got me further, however of course I ran into another issue &lt;code&gt;univalue/.libs/libunivalue.a: error adding symbols: Archive has no index; run ranlib to add one&lt;/code&gt;. This one had me stumped and I was going to throw in the towel (as this was a few hours in)&lt;/p&gt;

&lt;p&gt;But after researching further I stumbled across the &lt;a href=&#34;https://github.com/bitcoin/bitcoin/tree/master/depends&#34; target=&#34;_blank&#34;&gt;/depends/ folder in the bitcoin repo&lt;/a&gt; This had some useful information regarding cross compiling. This allowed you to get all the dependancies for whatever architecture you were targeting without having to do it yourself. I do not know why I had not come across this earlier.&lt;/p&gt;

&lt;h3 id=&#34;sites-that-helped-me-along-the-way&#34;&gt;Sites that helped me along the way&lt;/h3&gt;

&lt;p&gt;The following links were very helpful during this journey, so I&amp;rsquo;d just like to recognise them here too:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://getstarted.accelo.com/?action=view_task&amp;amp;id=20134&#34; target=&#34;_blank&#34;&gt;http://jensd.be/800/linux/cross-compiling-for-arm-with-ubuntu-16-04-lts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://getstarted.accelo.com/?action=view_task&amp;amp;id=20134&#34; target=&#34;_blank&#34;&gt;https://www.raspberrypi.org/forums/viewtopic.php?t=86084&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://getstarted.accelo.com/?action=view_task&amp;amp;id=20134&#34; target=&#34;_blank&#34;&gt;https://infertux.com/posts/2016/02/23/cross-compile-bitcoin-for-arm/https://askubuntu.com/questions/484030/crosscompiling-with-libboost-for-arm-architecture#484041&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://getstarted.accelo.com/?action=view_task&amp;amp;id=20134&#34; target=&#34;_blank&#34;&gt;https://github.com/bitcoin/bitcoin/tree/master/depends&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 </content>
    </item>
    
    <item>
      <title>Moving Magento</title>
      <link>https://www.mrwhal3.com/2018/moving-magento/</link>
      <pubDate>Mon, 16 Apr 2018 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2018/moving-magento/</guid>
      <description>So I was asked to help finish moving a magento (1.9) installation to a new server the other day. To sum it up, it was not fun
They had already moved the files and had everything installed and updated the database connection string, however it was still throwing an error. The plan was to set this site up on a subdomain, so we could test a few things, update some things and then go live on the new server</description>
      <content> &lt;p&gt;So I was asked to help finish moving a magento (1.9) installation to a new server the other day. To sum it up, it was not fun&lt;/p&gt;

&lt;p&gt;They had already moved the files and had everything installed and updated the database connection string, however it was still throwing an error. The plan was to set this site up on a subdomain, so we could test a few things, update some things and then go live on the new server&lt;/p&gt;

&lt;p&gt;After a while of trying to find the logs ( looking in &lt;code&gt;/var/log/apache&lt;/code&gt; and &lt;code&gt;/var/www/magentoinstall/var/log&lt;/code&gt;) I was having no luck of trying to find out what was causing the error. Until I found &lt;code&gt;/var/www/magentoinstall/var/report&lt;/code&gt;. This folder seemed to be what I was looking for. After the fact, looking up some magento docs, &lt;code&gt;var/report&lt;/code&gt; seems to be where magento logs uncatched errors by default &lt;a href=&#34;https://magento.stackexchange.com/questions/58232/error-reporting-var-report-vs-var-log-exception-log&#34; target=&#34;_blank&#34;&gt;here is a nice run down&lt;/a&gt;. Every time the site failed to load, it spat out a file into this folder, which included an interestly useful error&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;root@myserver:/var/www/magentoinstall/var/report# cat 828704810349
a:4:{i:0;s:113:&amp;#34;SQLSTATE[HY000] [2003] Can&amp;#39;t connect to MySQL server on &amp;#39;myoldDBserver&amp;#39; (4)&amp;#34;;i:1;s:2753:&amp;#34;#0 /var/www/magentoinstall/lib/Zend/Db/Adapter/Pdo/Mysql.php(109): Zend_Db_Adapter_Pdo_Abstract-&amp;gt;_connect()
#1 /var/www/magentoinstall/lib/Varien/Db/Adapter/Pdo/Mysql.php(320): Zend_Db_Adapter_Pdo_Mysql-&amp;gt;_connect()
#2 /var/www/magentoinstall/lib/Zend/Db/Adapter/Abstract.php(460): Varien_Db_Adapter_Pdo_Mysql-&amp;gt;_connect()
#3 /var/www/magentoinstall/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract-&amp;gt;query(&amp;#39;SET NAMES utf8&amp;#39;, Array)
#4 /var/www/magentoinstall/lib/Varien/Db/Adapter/Pdo/Mysql.php(428): Zend_Db_Adapter_Pdo_Abstract-&amp;gt;query(&amp;#39;SET NAMES utf8&amp;#39;, Array)
#5 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Resource.php(169): Varien_Db_Adapter_Pdo_Mysql-&amp;gt;query(&amp;#39;SET NAMES utf8&amp;#39;)
#6 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Resource.php(110): Mage_Core_Model_Resource-&amp;gt;_newConnection(&amp;#39;pdo_mysql&amp;#39;, Object(Mage_Core_Model_Config_Element))
#7 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Resource/Db/Abstract.php(320): Mage_Core_Model_Resource-&amp;gt;getConnection(&amp;#39;core_write&amp;#39;)
#8 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Resource/Db/Abstract.php(350): Mage_Core_Model_Resource_Db_Abstract-&amp;gt;_getConnection(&amp;#39;write&amp;#39;)
#9 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Resource/Db/Abstract.php(335): Mage_Core_Model_Resource_Db_Abstract-&amp;gt;_getWriteAdapter()
#10 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Resource/Db/Abstract.php(360): Mage_Core_Model_Resource_Db_Abstract-&amp;gt;_getReadAdapter()
#11 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Resource/Db/Collection/Abstract.php(134): Mage_Core_Model_Resource_Db_Abstract-&amp;gt;getReadConnection()
#12 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Config.php(1354): Mage_Core_Model_Resource_Db_Collection_Abstract-&amp;gt;__construct(Object(Mage_Core_Model_Resource_Website))
#13 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Config.php(1386): Mage_Core_Model_Config-&amp;gt;getModelInstance(&amp;#39;core_resource/w...&amp;#39;, Object(Mage_Core_Model_Resource_Website))
#14 /var/www/magentoinstall/app/Mage.php(491): Mage_Core_Model_Config-&amp;gt;getResourceModelInstance(&amp;#39;core/website_co...&amp;#39;, Object(Mage_Core_Model_Resource_Website))
#15 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Abstract.php(208): Mage::getResourceModel(&amp;#39;core/website_co...&amp;#39;, Object(Mage_Core_Model_Resource_Website))
#16 /var/www/magentoinstall/app/code/core/Mage/Core/Model/Abstract.php(213): Mage_Core_Model_Abstract-&amp;gt;getResourceCollection()
#17 /var/www/magentoinstall/app/code/core/Mage/Core/Model/App.php(608): Mage_Core_Model_Abstract-&amp;gt;getCollection()
#18 /var/www/magentoinstall/app/code/core/Mage/Core/Model/App.php(466): Mage_Core_Model_App-&amp;gt;_initStores()
#19 /var/www/magentoinstall/app/code/core/Mage/Core/Model/App.php(349): Mage_Core_Model_App-&amp;gt;_initCurrentStore(&amp;#39;&amp;#39;, &amp;#39;store&amp;#39;)
#20 /var/www/magentoinstall/app/Mage.php(684): Mage_Core_Model_App-&amp;gt;run(Array)
#21 /var/www/magentoinstall/index.php(153): Mage::run(&amp;#39;&amp;#39;, &amp;#39;store&amp;#39;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It was interesting as it was using the database server connections string, re-checking all the config files (everything under &lt;code&gt;/var/www/magentoinstall/app/etc&lt;/code&gt; just to make sure) I finally resorted to doing a search for the old connection string (using &lt;code&gt;ag&lt;/code&gt; ) in the magento instance&lt;/p&gt;

&lt;p&gt;Magento seems to agressively cache everything. It found a few hits of the old connection string under &lt;code&gt;/var/www/magentoinstall/var/cache&lt;/code&gt; in &lt;code&gt;classPathCache.php&lt;/code&gt; and a few of the &lt;code&gt;mage--xxx&lt;/code&gt; folders. After a quick search, it was deemed OK to wipe this folder clean. Sure enough, after deleting the cache folder we had progress. No more errors, but the site was redirecting to the main domain of the website (which was not good as we wanted to set it up on a subdomain first)&lt;/p&gt;

&lt;p&gt;Without access to the admin interface to update the domain, modifying this via the database was the next best option. There were a few strings that we need to update to make sure nothing breaks, seems that magento tried to do an inbuild CDN style configuration so it pulls assets from varying domains/paths to speed things up&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;root@myserver:/var/www/magentoinstall# mysql -u root -p -h mynewDBserver
mysql&amp;gt; use database mymagentodb;
# Main domain
mysql&amp;gt; update core_config_data set value = &amp;#39;https://my.new.domain/&amp;#39; where path = &amp;#39;web/secure/base_url&amp;#39;;
mysql&amp;gt; update core_config_data set value = &amp;#39;http://my.new.domain/&amp;#39; where path = &amp;#39;web/unsecure/base_url&amp;#39;;
#Media 
mysql&amp;gt; update core_config_data set value = &amp;#39;http://my.new.domain/media/&amp;#39; where path = &amp;#39;web/unsecure/base_media_url&amp;#39;;
mysql&amp;gt; update core_config_data set value = &amp;#39;https://my.new.domain/media/&amp;#39; where path = &amp;#39;web/secure/base_media_url&amp;#39;;
#JS 
mysql&amp;gt; update core_config_data set value = &amp;#39;http://my.new.domain/js/&amp;#39; where path = &amp;#39;web/unsecure/base_js_url&amp;#39;;
mysql&amp;gt; update core_config_data set value = &amp;#39;https://my.new.domain/js/&amp;#39; where path = &amp;#39;web/secure/base_js_url&amp;#39;;
#CSS 
mysql&amp;gt; update core_config_data set value = &amp;#39;http://my.new.domain/css/&amp;#39; where path = &amp;#39;web/unsecure/base_css_url&amp;#39;;
mysql&amp;gt; update core_config_data set value = &amp;#39;https://my.new.domain/css/&amp;#39; where path = &amp;#39;web/secure/base_css_url&amp;#39;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Okay great. More progress, the site is loading, but not over https. I was getting a 404 error when trying to load over https. Back to the drawing board
This was just a config error within apache. I had to change the default SSL apache config, to point to the right folder as the document root, enable the site and restart apache&lt;/p&gt;

&lt;p&gt;Hooray!&lt;/p&gt;

&lt;p&gt;One other thing I can across in my research was that Magento 1.9 reads in all and any xml files that are located in &lt;code&gt;app/etc&lt;/code&gt;. So if you have copied the &lt;code&gt;local.xml&lt;/code&gt; file during development and made &lt;code&gt;local-dev.xml&lt;/code&gt; it will still load that in and read any configuration settings that have been placed in here. This tripped alot of people up as it would load old or development database connection strings in and mess things up. So rename things to &lt;code&gt;.old&lt;/code&gt; or &lt;code&gt;.dev&lt;/code&gt; or something other then &lt;code&gt;.xml&lt;/code&gt;&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>PiHole and OpenHAB</title>
      <link>https://www.mrwhal3.com/2018/pihole-and-openhab/</link>
      <pubDate>Thu, 08 Feb 2018 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2018/pihole-and-openhab/</guid>
      <description>Recently I installed pihole on my network because I was sick of ads, and wanted an added layer of security on my network against nasty malware and the like
There are plenty of install guides out there for pihole (see official website) so thats not what I am covering today. I installed this on a raspberry pi 1 (Model B) and it handles everything just fine!
Becauase I am a fan of home automation, I wanted all the data that is available in the piHole web interface, avaialable to me at my openHAB interface.</description>
      <content> 

&lt;p&gt;Recently I installed &lt;a href=&#34;https://pi-hole.net/&#34; target=&#34;_blank&#34;&gt;pihole&lt;/a&gt; on my network because I was sick of ads, and wanted an added layer of security on my network against nasty malware and the like&lt;/p&gt;

&lt;p&gt;There are plenty of install guides out there for pihole (see official website) so thats not what I am covering today. I installed this on a raspberry pi 1 (Model B) and it handles everything just fine!&lt;/p&gt;

&lt;p&gt;Becauase I am a fan of home automation, I wanted all the data that is available in the piHole web interface, avaialable to me at my openHAB interface. You know, so everything is all in the one place. Thankfully this was super easy because piHole has a simple API that you can extract this data from. This also allows you to temporailty disable piHole. Which is useful when your wife wants to clicks ads anyway, or if you know piHole is causing mischef with a particular website&lt;/p&gt;

&lt;h4 id=&#34;pihole&#34;&gt;piHole&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;We need to first make sure that the webpassword is set in the piHole config. This will be used to authenticate against the API (I beleive you can turn this off if you desire)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;$ cat /etc/pihole/setupVars.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Look for the line &lt;code&gt;WEBPASSWORD&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If its not set, then set it by adding a line in the config file, making up a random string&lt;/p&gt;

&lt;h4 id=&#34;openhab&#34;&gt;OpenHAB&lt;/h4&gt;

&lt;p&gt;Now lets make some items in openhab to capture the data we want, and an entry in the sitemap to display it
- &lt;code&gt;$ sudo vim /etc/openhab2/services/http.cfg&lt;/code&gt; Set up a regular http call as a service, so it will go ahead a poll the API every so often. This is also useful because you can use this service against as many items as you want, reducing the amount of API calls you do to only as many as this service does.
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;http:pihole.url&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http://pi.hole/admin/api.php?summaryRaw
http:pihole.updateInterval&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;300000&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$ sudo vim /etc/openhab2/items/pihole.items&lt;/code&gt; Add some items for your sitemaps to use&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;Number piholePercent    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Percent blocked [%.1f %%]&amp;#34;&lt;/span&gt; &amp;lt;pihole&amp;gt;    &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; http&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;[pihole:303000:JSONPATH(&lt;/span&gt;$&lt;span style=&#34;color:#e6db74&#34;&gt;.ads_percentage_today)]&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
Number piholeBlockedAds &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Blocked ads [%d]&amp;#34;&lt;/span&gt; &amp;lt;pihole&amp;gt;     &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;pihole&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;http&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;[pihole:303000:JSONPATH(&lt;/span&gt;$&lt;span style=&#34;color:#e6db74&#34;&gt;.ads_blocked_today)]&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
Number  piholeQueries   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;DNS Queries [%d]&amp;#34;&lt;/span&gt; &amp;lt;pihole&amp;gt;     &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;pihole&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;http&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;[pihole:303000:JSONPATH(&lt;/span&gt;$&lt;span style=&#34;color:#e6db74&#34;&gt;.dns_queries_today)]&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
Switch piholeDisable &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Toggle Pi Hole&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;pihole&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;http&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;gt;[OFF:GET:http://pi.hole/admin/api.php?disable=600&amp;amp;auth=&amp;lt;WEBPASSWORD&amp;gt;] &amp;gt;[ON:GET:http://pi.hole/admin/api.php?enable&amp;amp;auth=&amp;lt;WEBPASSWORD&amp;gt;]&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first 3 items use the item set in the http.cfg. you can see is uses JSONPATH to do some transformation to only get the data we want for the particular item. In the case of &lt;code&gt;piholePercent&lt;/code&gt; we are grabbing the &lt;code&gt;ads_percentage_today&lt;/code&gt; value out of the JSON output from the API.
I&amp;rsquo;ve also created a switch to disable and enable piHole as needed. This API function requires you to authenticate yourself so we needed to add that in there too, this is where the WEBPASSWORD value in the piHole setting comes into play&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sitemap. Add the items to your sitemap as you see fit (Here is my example from my sitemap)
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;Frame label&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Pi Hole&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
                Text item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;piholeQueries
                Text item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;piholeBlockedAds
                Text item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;piholePercent
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;piholeDisable
        &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&#34;https://www.mrwhal3.com/img/pihole.png&#34; alt=&#34;pihole sitemap&#34; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Optional&lt;/em&gt; If you&amp;rsquo;d like to add an icon for the items in the sitemap further, download the graphics from piHole (png and svg) and upload them into your openhab install at &lt;code&gt;/etc/openhab2/icons/classic&lt;/code&gt;. Then set the icon in the item using &lt;code&gt;&amp;lt;pihole&amp;gt;&lt;/code&gt; (Refer to the openhab item config above). Now you will get a nice icon for the item too&lt;/p&gt;

&lt;p&gt;More info on the API can be found &lt;a href=&#34;https://discourse.pi-hole.net/t/pi-hole-api/1863&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Useful Commands - MSSQL</title>
      <link>https://www.mrwhal3.com/2018/useful-commands-mssql/</link>
      <pubDate>Thu, 08 Feb 2018 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2018/useful-commands-mssql/</guid>
      <description>Here is a start of a regular posting, &amp;ldquo;useful commands&amp;rdquo; Over the years I have saved snippets, commands and notes of things that have been useful or saved alot of time. I start off with a gathering of T-SQL commands to do useful things within a windows database. Some of these relate directly to modifying a Kentico database (the CMS of choice where I work), but may be useful anyway</description>
      <content> &lt;p&gt;Here is a start of a regular posting, &amp;ldquo;useful commands&amp;rdquo;
Over the years I have saved snippets, commands and notes of things that have been useful or saved alot of time. I start off with a gathering of T-SQL commands to do useful things within a windows database. Some of these relate directly to modifying a Kentico database (the CMS of choice where I work), but may be useful anyway&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- Turn off SSL
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;UPDATE&lt;/span&gt; [CMS_SettingsKey]  &lt;span style=&#34;color:#66d9ef&#34;&gt;SET&lt;/span&gt; KeyValue &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;False&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; KeyName &lt;span style=&#34;color:#66d9ef&#34;&gt;LIKE&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CMSUseSSL%&amp;#39;&lt;/span&gt;


&lt;span style=&#34;color:#75715e&#34;&gt;-- Take Database offline forcefully and come back online
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Go&lt;/span&gt; offline
USE master
&lt;span style=&#34;color:#66d9ef&#34;&gt;GO&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;ALTER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;DATABASE&lt;/span&gt; YourDatabaseName
&lt;span style=&#34;color:#66d9ef&#34;&gt;SET&lt;/span&gt; OFFLINE &lt;span style=&#34;color:#66d9ef&#34;&gt;WITH&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ROLLBACK&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;IMMEDIATE&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;GO&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Go&lt;/span&gt; online
USE master
&lt;span style=&#34;color:#66d9ef&#34;&gt;GO&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;ALTER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;DATABASE&lt;/span&gt; YourDatabaseName
&lt;span style=&#34;color:#66d9ef&#34;&gt;SET&lt;/span&gt; ONLINE
&lt;span style=&#34;color:#66d9ef&#34;&gt;GO&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;get&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;out&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt; recovery &lt;span style=&#34;color:#66d9ef&#34;&gt;mode&lt;/span&gt;
RESTORE &lt;span style=&#34;color:#66d9ef&#34;&gt;DATABASE&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;database&lt;/span&gt; name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;WITH&lt;/span&gt; RECOVERY


&lt;span style=&#34;color:#75715e&#34;&gt;-- Get MDF/BAK file SQL version
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;Bak file (&lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;sql&lt;/span&gt;)
RESTORE HEADERONLY &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; DISK &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;D:\dbbackup\base106.bak&amp;#39;&lt;/span&gt;

&lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;MDF (powershell)
&lt;span style=&#34;color:#66d9ef&#34;&gt;get&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;content &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Encoding&lt;/span&gt; Byte &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;...\foo.mdf&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;object&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;skip &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;x12064 &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;first&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; number &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; number &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;


&lt;span style=&#34;color:#75715e&#34;&gt;-- Get DB Size
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;EXEC&lt;/span&gt; sp_spaceused
&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;t 
( 
    [name] NVARCHAR(&lt;span style=&#34;color:#ae81ff&#34;&gt;128&lt;/span&gt;),
    [&lt;span style=&#34;color:#66d9ef&#34;&gt;rows&lt;/span&gt;] CHAR(&lt;span style=&#34;color:#ae81ff&#34;&gt;11&lt;/span&gt;),
    reserved VARCHAR(&lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;), 
    &lt;span style=&#34;color:#66d9ef&#34;&gt;data&lt;/span&gt; VARCHAR(&lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;), 
    index_size VARCHAR(&lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;),
    unused VARCHAR(&lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;)
) 

&lt;span style=&#34;color:#66d9ef&#34;&gt;INSERT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;t &lt;span style=&#34;color:#66d9ef&#34;&gt;EXEC&lt;/span&gt; sp_msForEachTable &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;EXEC sp_spaceused &amp;#39;&amp;#39;?&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt; 
&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;​&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;t
&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;​&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;SUM&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;CAST&lt;/span&gt;([&lt;span style=&#34;color:#66d9ef&#34;&gt;rows&lt;/span&gt;] &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; int)) &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; [&lt;span style=&#34;color:#66d9ef&#34;&gt;rows&lt;/span&gt;]
&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;t
&lt;span style=&#34;color:#66d9ef&#34;&gt;DROP&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;t


&lt;span style=&#34;color:#75715e&#34;&gt;-- Get RAM usage of server
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; db &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; DB_NAME(t.dbid), plan_cache_kb &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;SUM&lt;/span&gt;(size_in_bytes&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1024&lt;/span&gt;) 
&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; sys.dm_exec_cached_plans &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; p
&lt;span style=&#34;color:#66d9ef&#34;&gt;CROSS&lt;/span&gt; APPLY sys.dm_exec_sql_text(p.plan_handle) &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; t
&lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; t.dbid &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32767&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;GROUP&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; t.dbid
&lt;span style=&#34;color:#66d9ef&#34;&gt;ORDER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; plan_cache_kb &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 </content>
    </item>
    
    <item>
      <title>Ubuntu Live USB with persistence</title>
      <link>https://www.mrwhal3.com/2018/ubuntu-live-usb-with-persistence/</link>
      <pubDate>Sun, 04 Feb 2018 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2018/ubuntu-live-usb-with-persistence/</guid>
      <description>Creating a live USB is easy, adding persistence seems to be quite hard. After lots of research, there was alot of ways to do it, but most of these tutorials were out of date so some things weren&amp;rsquo;t relevant anymore or just didn&amp;rsquo;t work
Here are some hopefully simple steps to create a live USB with persistence, using Ubuntu. This will also be available as a normal USB flash drive to windows users</description>
      <content> 

&lt;p&gt;Creating a live USB is easy, adding persistence seems to be quite hard. After lots of research, there was alot of ways to do it, but most of these tutorials were out of date so some things weren&amp;rsquo;t relevant anymore or just didn&amp;rsquo;t work&lt;/p&gt;

&lt;p&gt;Here are some &lt;em&gt;hopefully&lt;/em&gt; simple steps to create a live USB with persistence, using Ubuntu. This will also be available as a normal USB flash drive to windows users&lt;/p&gt;

&lt;h3 id=&#34;requirements&#34;&gt;Requirements&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu ISO&lt;/li&gt;
&lt;li&gt;USB flash drive. 4G is ideal, although you probably could have it on 2GB&lt;/li&gt;
&lt;li&gt;Device already running linux&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;steps&#34;&gt;Steps&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Firstly we will format the USB to FAT32 and wipe anything from it. You can use gparted if you want&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#find your usb&amp;#39;s device location&lt;/span&gt;
$ sudo fdisk -l

Disk /dev/sdb: &lt;span style=&#34;color:#ae81ff&#34;&gt;14&lt;/span&gt;.3 GiB, &lt;span style=&#34;color:#ae81ff&#34;&gt;15376000000&lt;/span&gt; bytes, &lt;span style=&#34;color:#ae81ff&#34;&gt;30031250&lt;/span&gt; sectors
Units: sectors of &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; * 512 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
Sector size &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;logical/physical&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes / &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
I/O size &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;minimum/optimal&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes / &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
Disklabel type: dos
Disk identifier: 0x00766c29

Device     Boot Start      End  Sectors  Size Id Type
/dev/sdb1  *     &lt;span style=&#34;color:#ae81ff&#34;&gt;2048&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;30031249&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;30029202&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;14&lt;/span&gt;.3G  c W95 FAT32 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;LBA&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;#Now format as FAT32 (Make sure its unmounted)&lt;/span&gt;
$ sudo mkfs.vfat /dev/sdb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Now lets copy over the ubuntu ISO to the USB (this may take some time)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ sudo dd &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;~/Download/ubuntu-17.10.1-desktop-amd64.iso of&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/dev/sdb1 status&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;progress&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Once finished, mount up the drive so we can modify the boot config to tell it to be persistent. We will modify the grub config and also the isolinux config
&lt;code&gt;$ sudo mount /dev/sdb1 ~/usb/&lt;/code&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ sudo vim usb/boot/grub/grub.conf
.....
menuentry &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Try Ubuntu without installing&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
        set gfxpayload&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;keep
        linux   /casper/vmlinuz.efi persistent file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/cdrom/preseed/ubuntu.seed boot&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;casper quiet splash ---
        initrd  /casper/initrd.lz
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
.....
&lt;span style=&#34;color:#75715e&#34;&gt;# Add &amp;#34;persistent&amp;#34; after /casper/vmlinuz.efi&lt;/span&gt;

$ sudo vim usb/isolinux/txt.cfg
.....
label live
  menu label ^Try Ubuntu without installing
  kernel /casper/vmlinuz.efi
  append  file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/cdrom/preseed/ubuntu.seed boot&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;casper persistent initrd&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/casper/initrd.lz quiet splash ---
.....
&lt;span style=&#34;color:#75715e&#34;&gt;# Add &amp;#34;persistent&amp;#34; to the append line, just after the boot=casper statement&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;We must now create a file (or you could shrink the partition and make a new partition, it does the same thing) for where the persistent data will store itself. It will store in a file (or partition) called &lt;code&gt;casper-rw&lt;/code&gt;. I have chosen this to only be 1Gb, but you can choose your size below. There are several ways to create a pre-space-populated file, this is just one of them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;sudo dd if=/dev/zero of=usb/casper-rw bs=1M count=1024&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we will format the file into an &lt;code&gt;ext4&lt;/code&gt; format so the OS can read it&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo mkfs.ext4 usb/casper-rw&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All finished. Unmount and go boot from it. If you find that 1Gb isnt enough, you can resize that &lt;code&gt;casper-rw&lt;/code&gt; using the following&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#Create new block, the size of what you want to add. E.g 1Gb to make a 2Gb file&lt;/span&gt;
$ dd &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/dev/zero of&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/tmp/tmpfile bs&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1M count&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1024&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#Append new block to existing block&lt;/span&gt;
$ cat /tmp/tmpfile &amp;gt;&amp;gt; usb/casper-rw
&lt;span style=&#34;color:#75715e&#34;&gt;# Enlarge the filesystem&lt;/span&gt;
$ sudo e2fsck -f usb/casper-rw
$ sudo resize2fs usb/casper-rw&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Thanks alot to &lt;a href=&#34;https://rudd-o.com/linux-and-free-software/a-better-way-to-create-a-customized-ubuntu-live-usb-drive&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt; tutorial that was the most helpful, altyhough  I was unable to get the 2 partition USB thing to work, like in the example in that article.&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>RuuviTag</title>
      <link>https://www.mrwhal3.com/2017/ruuvitag/</link>
      <pubDate>Wed, 19 Apr 2017 09:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2017/ruuvitag/</guid>
      <description>I backed Ruuvi sometime late last year for a RuuviTag, a battery powered Bluetooth LE microcontroller with an onboard temperature and humidity sensor. As soon as I saw this project I had several ideas. And because I run openHAB at home, naturally, I&amp;rsquo;d want to collate this date into here for usage in my home automation system. I finally got it in the mail last week, and what surprised me was that they had teamed up the the guy who made espruino and had him port it to the Ruuvi!</description>
      <content> 

&lt;p&gt;I backed Ruuvi sometime late last year for a RuuviTag, a battery powered Bluetooth LE microcontroller with an onboard temperature and humidity sensor. As soon as I saw this project I had several ideas. And because I run openHAB at home, naturally, I&amp;rsquo;d want to collate this date into here for usage in my home automation system. I finally got it in the mail last week, and what surprised me was that they had teamed up the the guy who made espruino and had him port it to the Ruuvi! Javascript on a microcontroller. Pretty impressive stuff. Me and javascript have had some okay times, so I was comfortable that they had javascript here instead of C, which is what Ruuvi natively runs&lt;/p&gt;

&lt;p&gt;So battery powered BLE temperature sensor, that runs javascript, and a raspberry pi 3 that is running openhab. Pretty much a perfect mix. Here is how I got them talking to each other&lt;/p&gt;

&lt;p&gt;You may be looking at the RuuviTag setup page and see that the default weather station firmware actually works for both RuuviTags. At the time of getting my Ruuvi, it only supported the RuuvTag+, so I looked at using the espruino firmware to get what I needed to work.&lt;/p&gt;

&lt;h2 id=&#34;ruuvi&#34;&gt;Ruuvi&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Following the instructions &lt;a href=&#34;https://ruu.vi/setup/#updating-the-firmware&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt; we need to flash the espruino firmware to ruuvi. Quick overview, but the video they have here is quite good

&lt;ul&gt;
&lt;li&gt;Download nRF connect app&lt;/li&gt;
&lt;li&gt;Put Ruuvi into boot mode (hold R + B, let go of R while still holding B until red light comes and stays on)&lt;/li&gt;
&lt;li&gt;Connect to the ruuvi with nRF connect&lt;/li&gt;
&lt;li&gt;Press the &amp;ldquo;DFU&amp;rdquo; button that comes up in the app once you are connected, and select the espruino firmware zip file&lt;/li&gt;
&lt;li&gt;wait a little while&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Now follow the instructions &lt;a href=&#34;http://www.espruino.com/Puck.js+Quick+Start&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt; to get the IDE up and running to connect to Ruuvi&lt;/li&gt;
&lt;li&gt;Once you are able to get into the IDE and connect to ruuvi, upload this little snippet. Essentially it gathers the temp data every 60 seconds, converts it to a uint8 array, and then advertises it over BLE

&lt;ul&gt;
&lt;li&gt;after following &lt;a href=&#34;https://www.espruino.com/Ruuvitag&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt; guide, you may be asking why I&amp;rsquo;m not using the ruuvitag package to get all the data &lt;code&gt;var Ruuvitag = require(&amp;quot;Ruuvitag&amp;quot;);&lt;/code&gt;. It seems that this package does not work with the RuuviTag basic. I need to raise this on the forums to see when it will be supported. But for now we can just use the code you would use for the puck.js on the ruuvi, and it does the same job&lt;/li&gt;
&lt;li&gt;Links to the espruino forum that helped me get this working &lt;a href=&#34;http://forum.espruino.com/conversations/297509/&#34; target=&#34;_blank&#34;&gt;one&lt;/a&gt;, &lt;a href=&#34;http://forum.espruino.com/conversations/298878/&#34; target=&#34;_blank&#34;&gt;two&lt;/a&gt;, &lt;a href=&#34;http://forum.espruino.com/conversations/297591/?offset=25&#34; target=&#34;_blank&#34;&gt;three&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;tempTo&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;temp&lt;/span&gt;) {
  &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; parseFloat(&lt;span style=&#34;color:#a6e22e&#34;&gt;temp&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;toFixed&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)) &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt;;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;tempTo&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;buf&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;undefined&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;tempTo&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;buf&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Uint8Array&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;);
  &lt;span style=&#34;color:#a6e22e&#34;&gt;tempTo&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;buf&lt;/span&gt;[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xff&lt;/span&gt;;
  &lt;span style=&#34;color:#a6e22e&#34;&gt;tempTo&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;buf&lt;/span&gt;[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xff&lt;/span&gt;;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;tempTo&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;buf&lt;/span&gt;;
}

&lt;span style=&#34;color:#a6e22e&#34;&gt;setInterval&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;fn&lt;/span&gt;){
  &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;E&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;getTemperature&lt;/span&gt;());
},&lt;span style=&#34;color:#ae81ff&#34;&gt;60000&lt;/span&gt;);

&lt;span style=&#34;color:#a6e22e&#34;&gt;setInterval&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;() {
  &lt;span style=&#34;color:#a6e22e&#34;&gt;NRF&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;setAdvertising&lt;/span&gt;({
    &lt;span style=&#34;color:#ae81ff&#34;&gt;0x1809&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;tempTo&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;E&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;getTemperature&lt;/span&gt;())
  });
}, &lt;span style=&#34;color:#ae81ff&#34;&gt;60000&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&#34;raspberrypi-3&#34;&gt;RaspberryPi 3&lt;/h2&gt;

&lt;p&gt;Now onto the server side. I have a raspberry pi 3 running openhab. This is perfect as it has bluetooth built in. There were a few options to make this work, if you head over to the &lt;a href=&#34;https://f.ruuvi.com/&#34; target=&#34;_blank&#34;&gt;ruuvi forums&lt;/a&gt; there is a java and python module to scan the ruuvi&amp;rsquo;s and get their data. I was actually looking for something more like &lt;a href=&#34;https://github.com/espruino/EspruinoHub&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt;. This is a BLE -&amp;gt; mqtt bridge, that will scan for data on ruuvi (or Puckjs) and then publuish that to a mqtt service. EspruinoHub didn&amp;rsquo;t quite fit my setup, it is apparently a 2 way bridge, but I only really wanted a 1 way (getting the data). I also did not want to install nodered and all the other dependancies for it. So I decided to use this as a basis and write something else (&lt;a href=&#34;https://github.com/mrwhale/RuuviTag-Openhab-Bridge&#34; target=&#34;_blank&#34;&gt;source here&lt;/a&gt;)
It does esentially the same job, scans the BLE range and gets any data being advertised, and then publishes it to a mqtt stream. My openHAB server subscribes to these streams to get the data into the system. One use case I have for this is to monitor a bedroom temperature, and then if it gets to cold overnight, turn on the heating. Keep monitoring the temperature and if it gets a bit too hot, turn it off again.&lt;/p&gt;

&lt;h4 id=&#34;setup&#34;&gt;Setup&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;So firstly during my trials, and some help from the Ruuvi Slack channel, we need to upgrade the version of bluez that is on the raspberry pi to the latest. There is apparently an issue in 5.23 that was causing me some grief.&lt;/li&gt;
&lt;li&gt;First lets install all the dependancies we will need &lt;code&gt;sudo apt-get install bluetooth bluez bluez-hcidump libbluetooth-dev libudev-dev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the stretch repo (with the newer bluez versions) to apt source list

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo vim /etc/apt/sources.list&lt;/code&gt; -&amp;gt; add &lt;code&gt;deb http://mirrordirector.raspbian.org/raspbian/ stretch main contrib non-free rpi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo vim /etc/apt/apt.conf.d/40defaultrelease&lt;/code&gt; -&amp;gt; add &lt;code&gt;APT::Default-Release &amp;quot;jessie&amp;quot;;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Update package list &lt;code&gt;sudo apt-get update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Upgrade bluez using the strech repo &lt;code&gt;sudo apt-get install bluez bluez-hcidump -t stretch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Now we need node. I&amp;rsquo;m going to install the latest, but the LTS version works great too

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt-get install nodejs npm&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So before we go any further, lets do some testing. We can use the tools from the &lt;code&gt;bluez&lt;/code&gt; package to scan BLE and see what data we can find&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ sudo hcitool lescan
LE Scan ...
CE:A2:59:0E:85:C2 RuuviTag 85c2
CE:A2:59:0E:85:C2 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;unknown&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Cool, we can see ruuvi in the scan! No lets see what data ruuvi is giving us&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ sudo hcitool lescan &amp;amp; sudo hcidump --raw
&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;18782&lt;/span&gt;
LE Scan ...
HCI sniffer - Bluetooth packet analyzer ver &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;.43
device: hci0 snap_len: &lt;span style=&#34;color:#ae81ff&#34;&gt;1500&lt;/span&gt; filter: 0xffffffff
CE:A2:59:0E:85:C2 RuuviTag 85c2
&amp;gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;04&lt;/span&gt; 3E &lt;span style=&#34;color:#ae81ff&#34;&gt;24&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;02&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;00&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt; C2 &lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt; 0E &lt;span style=&#34;color:#ae81ff&#34;&gt;59&lt;/span&gt; A2 CE &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;02&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;05&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;05&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;
  &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;46&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;05&lt;/span&gt; 0E &lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;52&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;75&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;75&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;76&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;69&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;54&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;61&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;67&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;38&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;35&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;63&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt; AC
CE:A2:59:0E:85:C2 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;unknown&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&amp;gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;04&lt;/span&gt; 3E 1E &lt;span style=&#34;color:#ae81ff&#34;&gt;02&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;04&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt; C2 &lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt; 0E &lt;span style=&#34;color:#ae81ff&#34;&gt;59&lt;/span&gt; A2 CE &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;11&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;07&lt;/span&gt; 9E CA DC &lt;span style=&#34;color:#ae81ff&#34;&gt;24&lt;/span&gt;
  0E E5 A9 E0 &lt;span style=&#34;color:#ae81ff&#34;&gt;93&lt;/span&gt; F3 A3 B5 &lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;00&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt; 6E AC&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Pretty neat, we can see a raw stream of hex data that the RuuviTag is giving out. Lets try again with the &lt;code&gt;-x&lt;/code&gt; flag (show ascii and hex data)
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ sudo hcitool lescan &amp;amp; sudo hcidump -x
HCI sniffer - Bluetooth packet analyzer ver &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;.23
device: hci1 snap_len: &lt;span style=&#34;color:#ae81ff&#34;&gt;1500&lt;/span&gt; filter: 0xffffffff
&amp;gt; HCI Event: LE Meta Event &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0x3e&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; plen &lt;span style=&#34;color:#ae81ff&#34;&gt;36&lt;/span&gt;
    LE Advertising Report
      ADV_IND - Connectable undirected advertising &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
      bdaddr CE:A2:59:0E:85:C2 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;Random&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
      Flags: 0x05
      Unknown type 0x16 with &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt; bytes data
      Complete local name: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;RuuviTag 85c2&amp;#39;&lt;/span&gt;
      RSSI: -77&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;More interesting things happening. We can see the name of the tag, its MAC address and RSI. Unforuntely we can&amp;rsquo;t see the data its advertising. I haven&amp;rsquo;t been able to find out how to do that just with &lt;code&gt;hcidump&lt;/code&gt; but we will now turn to some javascript to get this info!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lets install some node dependacies we will need for this. &lt;code&gt;npm install noble mqtt&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href=&#34;https://github.com/sandeepmistry/noble&#34; target=&#34;_blank&#34;&gt;noble module&lt;/a&gt; is pretty much where all the work happens, and we will just need the mqtt module to send messages to our openhab server&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;I have also borrowed a few bits of code out of the EspruinoHub project, this made my life alot easier. We needed the config.js and attributes.js files out of the &lt;a href=&#34;https://github.com/espruino/EspruinoHub/tree/master/lib&#34; target=&#34;_blank&#34;&gt;lib&lt;/a&gt; folder&lt;/li&gt;
&lt;li&gt;And here is &lt;code&gt;index.js&lt;/code&gt;, that does the scanning and prints the data. Its still a bit of work in progress at the moment, but does exactly what I need. Although I do not have multiple RuuviTags, this solution &lt;em&gt;should&lt;/em&gt; work just fine for mulitple tags.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;noble&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;noble&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;attributes&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;./attribute&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;config&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;./config&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mqtt&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mqtt&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#75715e&#34;&gt;// my mqtt server needs some authentication, if you dont, you can just remove that object
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mqtt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;connect&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mqtt://10.1.1.115&amp;#39;&lt;/span&gt;, { &lt;span style=&#34;color:#a6e22e&#34;&gt;username&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Username&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;password&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Password&amp;#39;&lt;/span&gt; })
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;connected&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {};
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;packetsReceived&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;lastPacketsReceived&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;isScanning&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;;

&lt;span style=&#34;color:#a6e22e&#34;&gt;noble&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stateChange&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;state&lt;/span&gt;) {
  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;state&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;poweredOn&amp;#39;&lt;/span&gt;) {
    &lt;span style=&#34;color:#a6e22e&#34;&gt;noble&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;startScanning&lt;/span&gt;([], &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;);
  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
    &lt;span style=&#34;color:#a6e22e&#34;&gt;noble&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stopScanning&lt;/span&gt;();
  }
});
&lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;connect&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; () {
  &lt;span style=&#34;color:#a6e22e&#34;&gt;connected&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;;
});

&lt;span style=&#34;color:#a6e22e&#34;&gt;noble&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;discover&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;) {
  &lt;span style=&#34;color:#a6e22e&#34;&gt;packetsReceived&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;address&lt;/span&gt;;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;config&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;known_devices&lt;/span&gt;)
    &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;config&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;known_devices&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;];
  &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;entered&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;];

  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;entered&lt;/span&gt;) {
    &lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
      &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;,
      &lt;span style=&#34;color:#a6e22e&#34;&gt;address&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;,
      &lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;,
      &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;?&amp;#34;&lt;/span&gt;,
      &lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {}
    };
  };
  &lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;lastSeen&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Date.&lt;span style=&#34;color:#a6e22e&#34;&gt;now&lt;/span&gt;();
  &lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;rssi&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;rssi&lt;/span&gt;;

  &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello my local name is:&amp;#39;&lt;/span&gt;);
  &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\t&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;advertisement&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;localName&lt;/span&gt;);

  &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;advertisement&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;;
  &lt;span style=&#34;color:#75715e&#34;&gt;//If the advertising BLE device has any service data, then lets loop throught it and find out what it is
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;) {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;) {
      &lt;span style=&#34;color:#75715e&#34;&gt;//If statement to limit the outgoing mqtt stream. We are checking to see if the device is already in our array we made above, and if it hasnt been seen in 60s, and that data hasnt changed
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;uuid&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;uuid&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;payload&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;toString&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;toString&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;uuid&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;time&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; Date.&lt;span style=&#34;color:#a6e22e&#34;&gt;now&lt;/span&gt;()&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60000&lt;/span&gt;){
            &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;waiting....&amp;#34;&lt;/span&gt;);
        }&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;{
          &lt;span style=&#34;color:#75715e&#34;&gt;//Bit of debugging here so we can see whats going on
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\t\t&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;JSON&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stringify&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;uuid&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;: &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;JSON&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stringify&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;toString&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hex&amp;#39;&lt;/span&gt;)));
      &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;n&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;attributes&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;getReadableAttributeName&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;uuid&lt;/span&gt;);
      &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;JSON&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stringify&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;attributes&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;decodeAttribute&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;n&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;))&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;);
      &lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;uuid&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;payload&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;time&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; Date.&lt;span style=&#34;color:#a6e22e&#34;&gt;now&lt;/span&gt;() };
      &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;extendedData&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;attributes&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;decodeAttribute&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;n&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;serviceData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;);
      &lt;span style=&#34;color:#75715e&#34;&gt;//Can only sent mqtt if its actually connected, so if connected send data. We are only sending the temp number, not the whole json string which looks like { &amp;#34;temp&amp;#34;: 20 } in debug messages above
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;connected&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;extendedData&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;temp&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;publish&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;inRange&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;addr&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/temp&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;extendedData&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;temp&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;toString&lt;/span&gt;());
    }
   }
  }
  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;advertisement&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;manufacturerData&lt;/span&gt;) {
    &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\there is my manufacturer data:&amp;#39;&lt;/span&gt;);
    &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\t\t&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;JSON&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stringify&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;advertisement&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;manufacturerData&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;toString&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hex&amp;#39;&lt;/span&gt;)));
  }
  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;advertisement&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;txPowerLevel&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;undefined&lt;/span&gt;) {
    &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\tmy TX power level is:&amp;#39;&lt;/span&gt;);
    &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\t\t&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peripheral&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;advertisement&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;txPowerLevel&lt;/span&gt;);
  }

  &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;();
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you go ahead and run this, &lt;code&gt;nodejs index.js&lt;/code&gt; you will see somethings being printed out to console. Once it picks up Ruuvi, it should tell you the temperature now!
  - The script is set to only re-send data on change, or ever 60 seconds. This is just so mqtt isn&amp;rsquo;t flooded with messages&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;hello my local name is:
        RuuviTag 85c2
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1809&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0807&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;:18&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;


hello my local name is:
        RuuviTag 85c2
waiting....

hello my local name is:
        RuuviTag 85c2
waiting....

hello my local name is:
        f022cXhN
        here is my manufacturer data:
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0f03000276064ef39800d605020000dae480&amp;#34;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now lets go over to openhab, and makde sure its ready to receive some data
- Pre-requisites for this is obviously having mqtt biniding installed and working
- &lt;code&gt;vim /etc/openhab2/items/ruuvi.items&lt;/code&gt;
- Add something like this - &lt;code&gt;Number ruuvi &amp;quot;RuuviTag [%.2f C]&amp;quot; (climate) {mqtt=&amp;quot;&amp;lt;[mosq:cea2590e85c2/temp:state:default]&amp;quot;}&lt;/code&gt;
  - So the node script is publishing to a mqtt topic by the ruuvitag ID, which is just the tag&amp;rsquo;s MAC address without any &lt;code&gt;:&lt;/code&gt;
- While you have the node script running, tail the openhab log to make sure things are working. &lt;code&gt;tail -f /var/log/openhab2/events.log&lt;/code&gt;&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2017&lt;/span&gt;-04-20 &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;:17:12.992 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;ItemStateChangedEvent     &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; - piholeBlockedAds changed from &lt;span style=&#34;color:#ae81ff&#34;&gt;665&lt;/span&gt; to &lt;span style=&#34;color:#ae81ff&#34;&gt;674&lt;/span&gt;
&lt;span style=&#34;color:#ae81ff&#34;&gt;2017&lt;/span&gt;-04-20 &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;:19:42.802 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;ItemStateChangedEvent     &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; - ruuvi changed from &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; to &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;.25
&lt;span style=&#34;color:#ae81ff&#34;&gt;2017&lt;/span&gt;-04-20 &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;:20:43.626 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;ItemStateChangedEvent     &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; - ruuvi changed from &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;.25 to &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;.5
&lt;span style=&#34;color:#ae81ff&#34;&gt;2017&lt;/span&gt;-04-20 &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;:21:42.921 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;ItemStateChangedEvent     &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; - ruuvi changed from &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;.5 to &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;
&lt;span style=&#34;color:#ae81ff&#34;&gt;2017&lt;/span&gt;-04-20 &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;:22:16.388 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;ItemStateChangedEvent     &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; - piholeQueries changed from &lt;span style=&#34;color:#ae81ff&#34;&gt;14852&lt;/span&gt; to &lt;span style=&#34;color:#ae81ff&#34;&gt;15265&lt;/span&gt;
&lt;span style=&#34;color:#ae81ff&#34;&gt;2017&lt;/span&gt;-04-20 &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;:22:16.397 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;ItemStateChangedEvent     &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; - piholePercent changed from &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;.5381093455427 to &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;.5070422535211
&lt;span style=&#34;color:#ae81ff&#34;&gt;2017&lt;/span&gt;-04-20 &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;:22:16.401 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;ItemStateChangedEvent     &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; - piholeBlockedAds changed from &lt;span style=&#34;color:#ae81ff&#34;&gt;674&lt;/span&gt; to &lt;span style=&#34;color:#ae81ff&#34;&gt;688&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Excellent. We can see that we are getting updates into openhab. Now make sure you are persisting this data (I&amp;rsquo;m using the rrdj4 persistance) and you can get some pretty charts to display into your sitemap&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;{{ site.url }}/img/ruuvi.png&#34; alt=&#34;Ruuvitag chart&#34; /&gt;&lt;/p&gt;

&lt;p&gt;So lets tidy this up and manage the node script with systemd, so we don&amp;rsquo;t have to have it running in a &lt;code&gt;screen&lt;/code&gt; or something funky like that. Just put this into &lt;code&gt;/etc/systemd/system/ruuvi.service&lt;/code&gt;&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Unit&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
Description&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;Ruuvi-Scanner

&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Service&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
ExecStart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/usr/bin/node index.js
Restart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;always
User&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;pi
Group&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;pi
WorkingDirectory&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/pi/ruuvi

&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Install&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
WantedBy&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you can start and stop it with &lt;code&gt;systemctl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So here you have it. A RuuviTag, lots of javascript and openHAB. All working together. Now I just need to buy some more, 1 for each room!&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/mrwhale/RuuviTag-Openhab-Bridge&#34; target=&#34;_blank&#34;&gt;I will also upload the files to github, so you can just download it from there too..&lt;/a&gt;&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Node and systemd</title>
      <link>https://www.mrwhal3.com/2017/node-and-systemd/</link>
      <pubDate>Fri, 17 Feb 2017 09:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2017/node-and-systemd/</guid>
      <description>For a while now I&amp;rsquo;ve had my dashboard combo tv and dashboard combo, which runs on dashing and dashkiosk, running in screen sessions. This , of course, is not very managable. If something breaks, you have to ssh in and then find the screen session, re-run the command. In comes systemd. This makes managing services easy! You are able to make anything a system managed service, being able to manage the service via the systemctl commands</description>
      <content> &lt;p&gt;For a while now I&amp;rsquo;ve had my dashboard combo &lt;a href=&#34;https://www.mrwhal3.com/2016/tv-dashboards-with-chromecasts-and-dashing/&#34; target=&#34;_blank&#34;&gt;tv and dashboard combo&lt;/a&gt;, which runs on &lt;a href=&#34;http://dashing.io&#34; target=&#34;_blank&#34;&gt;dashing&lt;/a&gt; and &lt;a href=&#34;https://dashkiosk.readthedocs.io/en/latest/&#34; target=&#34;_blank&#34;&gt;dashkiosk&lt;/a&gt;, running in screen sessions. This , of course, is not very managable. If something breaks, you have to ssh in and then find the screen session, re-run the command. In comes systemd. This makes managing services easy! You are able to make anything a system managed service, being able to manage the service via the &lt;code&gt;systemctl&lt;/code&gt; commands&lt;/p&gt;

&lt;p&gt;Here are the systemd unit files I use for both dashing and dashkiosk. Just put them in &lt;code&gt;/etc/systemd/system&lt;/code&gt; and away you go&lt;/p&gt;

&lt;p&gt;Dashkiosk&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Unit&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
Description&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;Dashkiosk dashboard admin

&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Service&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
ExecStart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/usr/bin/node server.js --environment production
Restart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;always
User&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;root
Group&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;root
WorkingDirectory&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/george/dashkiosk-2.6.6/dist/

&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Install&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
WantedBy&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Dashing&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Unit&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
Description&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;Dashing Dashboard

&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Service&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
ExecStart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/usr/local/bin/dashing start -e production -p &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;
Restart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;always
User&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;root
Group&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;root
WorkingDirectory&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/george/work-dashboard/

&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Install&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
WantedBy&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see here, I am starting my services as root, as I need to use port 80 for the dashboard. But you can probably just run these as a standard user if you do not need privileged ports&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>OneTimeSecret</title>
      <link>https://www.mrwhal3.com/2017/onetimesecret/</link>
      <pubDate>Tue, 07 Feb 2017 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2017/onetimesecret/</guid>
      <description>So for those who use OnetimeSecret all the time, you can add this little function to your .bashrc (or similar) So then you don&amp;rsquo;t have to openh a browser to share your secret!
onetimesecret() { if [ $# -eq 0 ]; then echo &amp;#34;No secret specified&amp;#34;;return 1; fi secret=$(curl -s -F &amp;#34;secret=$1&amp;#34; https://onetimesecret.com/api/v1/share | cut -d &amp;#39;&amp;#34;&amp;#39; -f12) echo https://onetimesecret.com/secret/$secret } Output looks simlar to this
george@george-LT:~$ onetimesecret Thisissupersecret https://onetimesecret.com/secret/kvq9927e3ylltd83u679vlyfr942vjg I found this very useful as I use it daily, and I can pipe it into any other cli messaging app (eg into slackcat)</description>
      <content> &lt;p&gt;So for those who use OnetimeSecret all the time, you can add this little function to your &lt;code&gt;.bashrc&lt;/code&gt; (or similar) So then you don&amp;rsquo;t have to openh a browser to share your secret!&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;onetimesecret&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; $# -eq &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;No secret specified&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
secret&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;curl -s -F &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;secret=&lt;/span&gt;$1&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; https://onetimesecret.com/api/v1/share | cut -d &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#34;&amp;#39;&lt;/span&gt; -f12&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
echo https://onetimesecret.com/secret/$secret
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Output looks simlar to this&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;george@george-LT:~$ onetimesecret Thisissupersecret
https://onetimesecret.com/secret/kvq9927e3ylltd83u679vlyfr942vjg&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I found this very useful as I use it daily, and I can pipe it into any other cli messaging app (eg into slackcat)&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>C.H.I.P, flic and openhab</title>
      <link>https://www.mrwhal3.com/2017/c.h.i.p-flic-and-openhab/</link>
      <pubDate>Thu, 05 Jan 2017 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2017/c.h.i.p-flic-and-openhab/</guid>
      <description>So I finally received my C.H.I.P, and over the break I purchased myself some flic bluetooth buttons with the plan of making some nice push buttons around the home to control openhab. This idea mostly came from usablity/speed of use of openhab. Having the dashboard in the middle of the house is a nice idea, but if you are in another room, without your phone there isn&amp;rsquo;t too much you can do without having to go to this dashboard to interact with openhab.</description>
      <content> 

&lt;p&gt;So I finally received my &lt;a href=&#34;https://www.mrwhal3.com/2016/c.h.i.p/&#34; target=&#34;_blank&#34;&gt;C.H.I.P&lt;/a&gt;, and over the break I purchased myself some &lt;a href=&#34;https://flic.io/&#34; target=&#34;_blank&#34;&gt;flic bluetooth buttons&lt;/a&gt; with the plan of making some nice push buttons around the home to control openhab. This idea mostly came from usablity/speed of use of openhab. Having the dashboard in the middle of the house is a nice idea, but if you are in another room, without your phone there isn&amp;rsquo;t too much you can do without having to go to this dashboard to interact with openhab. Flic makes it nice and convenient to do things you do often, with a click, double click or press of a button!&lt;/p&gt;

&lt;p&gt;Some examples, incase this still seems silly to you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A button by the back door

&lt;ul&gt;
&lt;li&gt;A single click it will &amp;ldquo;turn off&amp;rdquo; the house. This includes lights, lamps and music from my mpd server.&lt;/li&gt;
&lt;li&gt;double click on the way back in, and it will turn the main house lights back on for you&lt;/li&gt;
&lt;li&gt;Long press to update openhab that you are now home. This then triggers some other openhab rules&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;A button by my bedside table

&lt;ul&gt;
&lt;li&gt;Single click to turn bedside table lights on night mode (For those middle of the night wake ups)&lt;/li&gt;
&lt;li&gt;Double click to turn the main house lights on (useful for winter when its still dark when I wake up)&lt;/li&gt;
&lt;li&gt;Long press to turn all the lights off. For bed time&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;A button by my wife&amp;rsquo;s bed side table

&lt;ul&gt;
&lt;li&gt;Single click to turn the hall way, and lounge room lights on night mode. For when she has to feed the baby&lt;/li&gt;
&lt;li&gt;Double  click to turn those back off&lt;/li&gt;
&lt;li&gt;Long press to turn all lights off, for bed time&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Button on a clip that sits around the house

&lt;ul&gt;
&lt;li&gt;Single click to play music&lt;/li&gt;
&lt;li&gt;Double click to pause music&lt;/li&gt;
&lt;li&gt;Long press to skip song&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes some everyday tasks much more convenient, without having to pull your phone out and load openhab (if you aren&amp;rsquo;t near the dashboard). The only con of this setup I have found so far is that, as it runs off bluetooth, the range of the buttons is quite limited if using the on-board bluetooth controller of C.H.I.P. To exend it nicely through your house, I recommend purchasing a usb bluetooth controller (I will update this once I find a suitable one for my setup)&lt;/p&gt;

&lt;h4 id=&#34;setup&#34;&gt;Setup&lt;/h4&gt;

&lt;p&gt;So C.H.I.P comes preinstalled with a GNU/Linux debian based OS customised specifically for C.H.I.P. This is nice as I am very familiar with debian. Connecting to C.H.I.P was super easy. Plug into usb on a desktop and it presents itself as a serial connection you can then &lt;code&gt;screen&lt;/code&gt; into!
Their &lt;a href=&#34;http://docs.getchip.com&#34; target=&#34;_blank&#34;&gt;docs&lt;/a&gt; are quite well written so it was a breeze to follow&lt;/p&gt;

&lt;p&gt;Flic have developed a &lt;a href=&#34;https://github.com/50ButtonsEach/fliclib-linux-hci&#34; target=&#34;_blank&#34;&gt;linux sdk&lt;/a&gt; for working with the buttons, obviously aimed at developers, so you can extend the buttons further then using the smart phone apps. This is nice as instead of having to pair the buttons with your phone (which moves around all the time) you can create a dedicated devices in 1 place in the house to use and interact with flic.
Anyway, some initial setup notes on connecting flic to C.H.I.P&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#update the chip&lt;/span&gt;
sudo apt-get update
sudo apt-get upgrade

&lt;span style=&#34;color:#75715e&#34;&gt;#Install some useful things&lt;/span&gt;

sudo apt-get install git
sudo apt-get install bash-completion screen

&lt;span style=&#34;color:#75715e&#34;&gt;#Clone the flic linux sdk&lt;/span&gt;

git clone https://github.com/50ButtonsEach/fliclib-linux-hci.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now at this point I had no idea what to use to script up flic, but the SDK comes with some nice client librarys (and examples!) for C, Java, nodejs python and websocket. Out of this list, I have had the &lt;a href=&#34;https://www.mrwhal3.com/2016/counter-strike-and-pebble/&#34; target=&#34;_blank&#34;&gt;most experience with javascript lately&lt;/a&gt; , so I chose Nodejs. So lets install nodejs and npm&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install nodejs npm&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So because I have an ISP that offers IPv6 too, I was running into an issue where &lt;code&gt;apt&lt;/code&gt; was timing out connecting to a debian repository over IPv6, so I had to force &lt;code&gt;apt&lt;/code&gt; to only use IPv4&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get -o Acquire::ForceIPv4&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;true install nodejs npm&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A weird thing you need to do for npm to make sure its up to date with the latest&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo npm install -g npm&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And we also need the http library for nodejs&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo npm install -g http&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we have all we to get things running! Just for now, we will start the server in a &lt;code&gt;screen&lt;/code&gt; so we can see whats happening if needed. It also starts in daemon mode too, but we will use that one later to integrate with &lt;code&gt;systemd&lt;/code&gt;&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd fliclib-linux-hci/bin/armv6l
./flicd -f sqlite.db&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So the flic server will store all the information in needs into this sqlite db, make sure you have it in a safe location so you dont have to re-pair your buttons again!
Now onto the client.&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd fliclib-linux-hci/clientlib/nodejs
nodejs newscanwizard.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you check your server &lt;code&gt;screen&lt;/code&gt; it will also show that a &amp;ldquo;client&amp;rdquo; has connected to it&lt;/p&gt;

&lt;p&gt;Now press one of your buttons and watch some magic! Save that address of the button for later, we will now write up a small client to handle the buttons and make them do things when you press them&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vim nodejs-flic.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/nodejs
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fliclib&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/home/chip/Documents/fliclib-linux-hci/clientlib/nodejs/fliclibNodeJs&amp;#34;&lt;/span&gt;);
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FlicClient&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fliclib&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;FlicClient&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FlicConnectionChannel&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fliclib&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;FlicConnectionChannel&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FlicScanner&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fliclib&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;FlicScanner&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;http&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;);
&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FlicClient&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;5551&lt;/span&gt;);

&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;listenToButton&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt;) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;cc&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FlicConnectionChannel&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt;);
        &lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;addConnectionChannel&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;cc&lt;/span&gt;);
        &lt;span style=&#34;color:#75715e&#34;&gt;//There are other methods you can watch, but all I care about at the moment is what type of click just happened
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;cc&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;buttonSingleOrDoubleClickOrHold&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;clickType&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;wasQueued&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;timeDiff&lt;/span&gt;) {
                &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;clickType&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;wasQueued&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;wasQueued&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;notQueued&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;timeDiff&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; seconds ago&amp;#34;&lt;/span&gt;);
                &lt;span style=&#34;color:#75715e&#34;&gt;//If statement to find out what button was pressed. Probably turn this into case to make it neater
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ab:cd:ef:11:22:33&amp;#34;&lt;/span&gt;){
                        &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Blue button&amp;#34;&lt;/span&gt;);
                        &lt;span style=&#34;color:#75715e&#34;&gt;/*Create http request to openhab API
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;                        hostname: openhab server IP address
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;                        port: openhab port (default 8080)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;                        path: Path to the item you wish to change.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;                        */&lt;/span&gt;
                        &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;options&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;hostname&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1.2.3.4&amp;#39;&lt;/span&gt;,
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;port&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;,
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;path&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/rest/items/all_off&amp;#39;&lt;/span&gt;,
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;method&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;,
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;headers&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {
                                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;text/plain&amp;#39;&lt;/span&gt;
                                    },
                            };
                            &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;http&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;request&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;options&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;) {
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;STATUS:&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;statusCode&lt;/span&gt;);
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;HEADERS:&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;JSON&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stringify&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;headers&lt;/span&gt;));
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;setEncoding&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;);
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;data&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;body&lt;/span&gt;) {
                                            &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;BODY:&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;body&lt;/span&gt;);
                                    });
                                    &lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt;) {
                                            &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;problem &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;message&lt;/span&gt; );
                                    });
                            });
                        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;clickType&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ButtonSingleClick&amp;#34;&lt;/span&gt;){
                                &lt;span style=&#34;color:#75715e&#34;&gt;//On single click, send OFF to the openhab item
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;                                &lt;span style=&#34;color:#a6e22e&#34;&gt;req&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;write&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;OFF&amp;#34;&lt;/span&gt;);
                                &lt;span style=&#34;color:#a6e22e&#34;&gt;req&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;end&lt;/span&gt;();
                        }&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;clickType&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ButtonDoubleClick&amp;#34;&lt;/span&gt;){
                                &lt;span style=&#34;color:#75715e&#34;&gt;//On double click, send ON to the openhab item
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;                                &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;doubelclick&amp;#34;&lt;/span&gt;);
                                &lt;span style=&#34;color:#a6e22e&#34;&gt;req&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;write&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ON&amp;#34;&lt;/span&gt;);
                                &lt;span style=&#34;color:#a6e22e&#34;&gt;req&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;end&lt;/span&gt;();
                        }&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;clickType&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ButtonHold&amp;#34;&lt;/span&gt;){
                                &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hold&amp;#34;&lt;/span&gt;);
                        }&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;{
                                &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Something Wrong&amp;#34;&lt;/span&gt;);
                        }
                }
        });
        &lt;span style=&#34;color:#a6e22e&#34;&gt;cc&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;connectionStatusChanged&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;connectionStatus&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;disconnectReason&lt;/span&gt;) {
                &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;connectionStatus&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;connectionStatus&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Disconnected&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;disconnectReason&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;));
        });
}

&lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;once&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ready&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Connected to daemon!&amp;#34;&lt;/span&gt;);
        &lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;getInfo&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;info&lt;/span&gt;) {
                &lt;span style=&#34;color:#a6e22e&#34;&gt;info&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddrOfVerifiedButtons&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;forEach&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt;) {
                        &lt;span style=&#34;color:#a6e22e&#34;&gt;listenToButton&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt;);
                });
        });
});

&lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bluetoothControllerStateChange&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;state&lt;/span&gt;) {
        &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Bluetooth controller state change: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;state&lt;/span&gt;);
});

&lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;newVerifiedButton&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt;) {
        &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;A new button was added: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt;);
        &lt;span style=&#34;color:#a6e22e&#34;&gt;listenToButton&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;bdAddr&lt;/span&gt;);
});

&lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;) {
        &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Daemon connection error: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;);
});

&lt;span style=&#34;color:#a6e22e&#34;&gt;client&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;close&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;hadError&lt;/span&gt;) {
        &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Connection to daemon is now closed&amp;#34;&lt;/span&gt;);
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see in my terribly coded example, we are watching for a button press, and when a button press happens, we find out which button it was, what sort of press it was, and do an action. So in those gaps you can do anything you want! In my case I am just hitting the openhab rest API to action the items I have connected to openhab. This is where the SDK is nice, you can do anything you want here!&lt;/p&gt;

&lt;p&gt;You may notice here that I only specify 1 openhab item that I am changing the state of. This is because I am doing the rest of the work via the openhab rules engine. The item in openhab is just a switch, that binds to nothing. The entry in &lt;code&gt;default.items&lt;/code&gt; looks like this &lt;code&gt;Switch all_off  &amp;quot;All Off&amp;quot;&lt;/code&gt; You can also add this as a switch item to your sitemap, so you can run the rule below from the openhab UI. Here is the rule that handles this blue button (all_off item)&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#/etc/openhab/configuration/rules/flic.rules&lt;/span&gt;
import org.openhab.core.library.types.*

rule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;All off&amp;#34;&lt;/span&gt;
when
        Item all_off received command OFF
&lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;L_light, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;K_light, OFF&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;E_light, OFF&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;H_light, OFF&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;B_light, OFF&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;BT_light, OFF&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
end

rule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Home on&amp;#34;&lt;/span&gt;
when
        Item all_off received command ON
&lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;K_light, ON&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;L_light, &lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;BT_light, ON&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        sendCommand&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;K_light_dim, &lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        Thread::sleep&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I have all these sleep commands in here, as I found that having the commands run directly after one another did not work well with milight, so adding a small delay made sure each one runs successfully and the milight bridge actually gets the command&lt;/p&gt;

&lt;p&gt;Now that we have a nice peiece of code that handles our buttons and actions, I didn&amp;rsquo;t want these to be running in &lt;code&gt;screen&lt;/code&gt; sessions. you know, in case of an outage or similar, I didnt want to have to ssh into C.H.I.P to start everything back up again. &lt;code&gt;systemd&lt;/code&gt; is nice here. We can write some stuff in a file so &lt;code&gt;systemd&lt;/code&gt; can handle running the code as a service for us, just like any other daemon you have installed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vim flic.service&lt;/code&gt;&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Unit&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
Description&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;Flic and openhab

&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Service&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
ExecStart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/chip/Documents/fliclib-linux-hci/clientlib/nodejs/nodejs-flic.js
Restart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;always
User&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;root
Group&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;root
Environment&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/usr/bin:/usr/local/bin
Environment&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;NODE_ENV&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;production
WorkingDirectory&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/chip/Documents/fliclib-linux-hci/clientlib/nodejs/

&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Install&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
WantedBy&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Make sure you change the user here, and make the &lt;code&gt;.js&lt;/code&gt; file executable! I did not, and had some errors.&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;chmod +x /home/chip/Documents/fliclib-linux-hci/clientlib/nodejs/nodejs-flic.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now copy it to where systemd exects these files&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo cp flic.service /etc/systemd/system/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Start it&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo systemctl start flic.service&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;check logs&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo journalctl -fa -u flic.service&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This acts like &lt;code&gt;tail -f&lt;/code&gt; on the log file. Now its running under &lt;code&gt;systemd&lt;/code&gt; you can add this service to start at startup, and manage it using the &lt;code&gt;systemctl&lt;/code&gt; command. Now we just do a similar thing to make the flic daemon managed by &lt;code&gt;systemd&lt;/code&gt;&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Openhab</title>
      <link>https://www.mrwhal3.com/2016/openhab/</link>
      <pubDate>Tue, 20 Dec 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/openhab/</guid>
      <description>Since the ninjablock company has run out of money, and is not supporting the ninjablock anymore, and its cloud service is pretty unreliable (at the best of times) I decided to merge all my homeautomation items with Openhab. At the time I adopted this, it was the only major, multi-vendor supported Home automation &amp;ldquo;brain&amp;rdquo; around. Since then home assistant has come around, and alot of others have picked up support for alot more &amp;ldquo;things&amp;rdquo;.</description>
      <content> 

&lt;p&gt;Since the ninjablock company has run out of &lt;a href=&#34;https://discuss.ninjablocks.com/t/ninja-blocks-whats-been-happening-whats-happening-next/3608&#34; target=&#34;_blank&#34;&gt;money&lt;/a&gt;, and is not supporting the ninjablock anymore, and its cloud service is pretty unreliable (at the best of times) I decided to merge all my homeautomation items with &lt;a href=&#34;http://openhab.org&#34; target=&#34;_blank&#34;&gt;Openhab&lt;/a&gt;. At the time I adopted this, it was the only major, multi-vendor supported Home automation &amp;ldquo;brain&amp;rdquo; around. Since then &lt;a href=&#34;https://home-assistant.io/&#34; target=&#34;_blank&#34;&gt;home assistant&lt;/a&gt; has come around, and alot of others have picked up support for alot more &amp;ldquo;things&amp;rdquo;. If I had the money, I would probably jump on the &lt;a href=&#34;https://www.smartthings.com/&#34; target=&#34;_blank&#34;&gt;Smart Things&lt;/a&gt; wagon, but I don&amp;rsquo;t :(&lt;/p&gt;

&lt;p&gt;So this is a bit of a back post of the system, since I&amp;rsquo;ve had it running for almost 2 years since &lt;a href=&#34;https://github.com/openhab/openhab/releases/tag/v1.7.0&#34; target=&#34;_blank&#34;&gt;Openhab 1.7&lt;/a&gt; came out. But I thought I would just share a bit about it, and my setup&lt;/p&gt;

&lt;p&gt;I am still yet to upgrade to OpenHAB 2.0 yet, it seems like a lot of work, it doesn&amp;rsquo;t look like there is a straight forward upgrade path from 1.x. So I&amp;rsquo;m still running 1.7, which is working fine for me&lt;/p&gt;

&lt;h4 id=&#34;setup-in-the-house&#34;&gt;Setup in the house&lt;/h4&gt;

&lt;p&gt;So I had a nexus 7 laying around, and decided I&amp;rsquo;d use that as a wall mounted controller. This works well with openHAB because it even has a &amp;ldquo;full screen&amp;rdquo; mode for you to use in the app, which will hide the status bar and navigation keys. This is an always on display too&lt;/p&gt;

&lt;p&gt;I rarely use the web based GUI to access my home, having this controller works well, plus I have the app installed on my various hand held devices too (And my watch!). So I am never too far away from any controls. I&amp;rsquo;ve never found the need to open up the web GUI when I&amp;rsquo;ve been at my desk, much quicker just to unlock my phone and start the app. The default web interface is very ugly too :/&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.mrwhal3.com/img/openhab-nexus.jpg&#34; alt=&#34;Nexus 7 dashboard&#34; /&gt;&lt;/p&gt;

&lt;h4 id=&#34;hardware&#34;&gt;Hardware&lt;/h4&gt;

&lt;h5 id=&#34;raspberry-pi&#34;&gt;Raspberry pi&lt;/h5&gt;

&lt;p&gt;Originally I had openHAB running on a raspberry pi (v1 B) but could notice the lack of power when interfacing with it. This wasnt too much of an issue when I first set it up, but after setting up a dozen or so rules, things started getting pretty sluggish. Doesn&amp;rsquo;t help that openHAB isn&amp;rsquo;t the only thing I have running on my pi. Not that I&amp;rsquo;m complaining, it does really well for the specs it has. However this was all fixed when I upgraded to a Raspberry Pi v2. That thing was such a powerful step up from v1. Incredible. I run openHAB, owncloud, dhcp/dns and various cron started scripts on that thing and It doesn&amp;rsquo;t even complain, or let me down.&lt;/p&gt;

&lt;p&gt;The only dependancies I needed in this situation were java (obviously, to run openHAB) and an MQTT server (I use mosquitto MQTT). This was to interface with the raspberry pi running the ninjablock things&lt;/p&gt;

&lt;p&gt;So all up
* 1 x Raspberry pi v2 (to Run openHAB and mqtt)
* 1 x Raspberry pi v1 model B (With the ninja crust pi hardware attaached to it, including 433MHZ transmitter)
* 1 x Raspberry pi as mpd server&lt;/p&gt;

&lt;h5 id=&#34;ninja-blocks-hahahugoshortcode-0xc0001daf00-1-hbhb&#34;&gt;&lt;a href=&#34;https://www.mrwhal3.com/2014/ninja-block/&#34; target=&#34;_blank&#34;&gt;Ninja Blocks&lt;/a&gt;&lt;/h5&gt;

&lt;p&gt;Lucky for me, someone else that had a ninja block came to the same conclusion as me, so had already made a nice little python bridge to get the Ninjablock and its 433Mhz sensors into openHab. Old mate &lt;a href=&#34;https://github.com/perrin7/ninjacape-mqtt-bridge&#34; target=&#34;_blank&#34;&gt;Perrin7&lt;/a&gt; posted his link in the now dead Ninjablock forums. This little shim just connects to the Ninja Crust via its serial port, and listens for any events. It reads these events, figures out what device/sensor it was, and then publishes it to a MQTT thread. OpenHab also just listens to these threads and picks up changes as they are posted! I&amp;rsquo;ve had this running for a while now with no issues :) the only downside (but probably easily fixed) is I have to start this python script everytime the pi with the ninja block on it restarts (Say if I lose power or something).
This is what I have that connects to my Ninjablock over 433Mhz
* 1 x Button
* 1 x Motion sensor
* 1 x Door/window sensor
* 3 x remote power switches (Watts Clever brand)&lt;/p&gt;

&lt;p&gt;Here is the sitemap, and items list in openhab specific to the ninjablock&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;Switch Motion_Sensor    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Room Sensor&amp;#34;&lt;/span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;Persist_change&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;mqtt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;[mosquitto:ninjaCape/input/11:state:ON:1000000001011010
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;01011001]&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
Switch C_Lamp   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Pergola Lights&amp;#34;&lt;/span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;frontroom&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;     &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;mqtt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;[mosquitto:ninjaCape/input/11:state:ON:11011010110110101
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;1011100],
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;lt;[mosquitto:ninjaCape/input/11:state:OFF:110110101101101011010100],
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;gt;[mosquitto:ninjaCape/output/11:command:OFF:110110101101101011010100],
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;gt;[mosquitto:ninjaCape/output/11:command:ON:110110101101101011011100]&amp;#34;&lt;/span&gt;
                                &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
Switch D_Lamp   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Door Lamp&amp;#34;&lt;/span&gt;     &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;frontroom&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;     &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;mqtt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;[mosquitto:ninjaCape/input/11:state:ON:110110101101101011011110]
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;,
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;lt;[mosquitto:ninjaCape/input/11:state:OFF:110110101101101011010110],
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;gt;[mosquitto:ninjaCape/output/11:command:OFF:110110101101101011010110],
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;gt;[mosquitto:ninjaCape/output/11:command:ON:110110101101101011011110]&amp;#34;&lt;/span&gt;
                                &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
Switch Z_Lamp   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Room Heater&amp;#34;&lt;/span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;mqtt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;[mosquitto:ninjaCape/input/11:state:ON:110110101101101011011010],
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;lt;[mosquitto:ninjaCape/input/11:state:OFF:110110101101101011010010],
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;gt;[mosquitto:ninjaCape/output/11:command:OFF:110110101101101011010010],
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                                &amp;gt;[mosquitto:ninjaCape/output/11:command:ON:110110101101101011011010]&amp;#34;&lt;/span&gt;
                                &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

Switch Button   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Button&amp;#34;&lt;/span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;mqtt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;[mosquitto:ninjaCape/input/11:command:ON]&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h5 id=&#34;limitless-led&#34;&gt;Limitless LED&lt;/h5&gt;

&lt;p&gt;Thing was probably the biggest purchase for me at the time, to replace most of my lights around the house with these. Has been a good investment, and already had a addon in openHAB so it was very easy to set up and get working. I have recently found a neat trick with these too, instead of setting the item as &lt;code&gt;Switch&lt;/code&gt; in openHAB, you set it as &lt;code&gt;Dimmer&lt;/code&gt;. Then when you link the light in the sitemap, you specify it as a &lt;code&gt;Switch&lt;/code&gt;. This trick ensures that everyime you click the switch, your lights will go to 100% brightness (On being 100%, &lt;code&gt;Off&lt;/code&gt; being 0%). I found this very useful, as before, when you turn the light on again it would turn back on at the last remembered brightness setting, which wasnt always at full brightness. Then I&amp;rsquo;d have to faff about with the slider bar to get it back up. &amp;ldquo;But what about if you want to change brightness after you turned the light on&amp;rdquo;, you ask. You can see the example in my item list and sitemap below. Using the &lt;code&gt;visibility&lt;/code&gt; property, you can have the brightness slider show on your sitemap when the light is actually on, this reduces clutter on the screen (seeing as I only have a limited amount of screen space)&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt; Frame label&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Lights&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;all_off mappings&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;OFF&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;All Off&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;L_light
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;L_lightn mappings&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;ON&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ON&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
                Slider item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;L_light_dim visibility&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;L_light&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;ON&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;K_light
                Slider item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;K_light_dim visibility&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;K_light&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;ON&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;E_light
                Slider item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;E_light_dim visibility&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;E_light&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;ON&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;H_light
                Slider item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;H_light_dim visibility&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;H_light&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;ON&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;B_light
                Slider item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;B_light_dim visibility&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;B_light&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;ON&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
                Switch item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;BT_light
                Slider item&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;BT_light_dim visibility&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;BT_light&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;ON&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
        &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h5 id=&#34;mpd-server&#34;&gt;MPD server&lt;/h5&gt;

&lt;p&gt;Because I had an extra raspberry pi and an extra speaker laying around, I turned it into a remote media player with &lt;a href=&#34;http://mopidy.com&#34; target=&#34;_blank&#34;&gt;Mopidy&lt;/a&gt; (Another post about this shortly). This enabled me to stream straight from spotify, and control it directly from openHAB too! Super cool :)&lt;/p&gt;

&lt;h4 id=&#34;smart-home&#34;&gt;Smart Home&lt;/h4&gt;

&lt;p&gt;So this is where openHAB gets cool. Not only can you interface with smart things throughout your house, and have information gathered and displayed all in one central location, you can create rules to do things when certain things happen (Think IFTTT)&lt;/p&gt;

&lt;p&gt;For example
* In the mornings when my alarm goes off, openHAB turns the kitchen light on for me
* When i leave the house in the morning, it will turn that light off again
* I can choose a time at night to turn the wall heater in our bedroom on (this will get smarter when my bluetooth temperature sensors arrive)
* I can choose a time in the morning to turn the wall heater &lt;em&gt;off&lt;/em&gt;
* I Also link my phone location into openHAB (using &lt;a href=&#34;http://owntracks.org&#34; target=&#34;_blank&#34;&gt;ownTracks&lt;/a&gt;) so then my partner can view my location on a map within openHAB&lt;/p&gt;

&lt;p&gt;These are just a few examples, but the amount of devices that openHAB supports, the length you can go to to automate your household is quite extensive and exciting&lt;/p&gt;

&lt;p&gt;If you want to see my complete sitemap/items list or my rules I use, get in touch. I&amp;rsquo;d be happy to share and help get you started on the way to home automation with openHAB&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Mini DLNA and bubbleUPnP</title>
      <link>https://www.mrwhal3.com/2016/mini-dlna-and-bubbleupnp/</link>
      <pubDate>Fri, 18 Nov 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/mini-dlna-and-bubbleupnp/</guid>
      <description>So ages ago I found bubbleUPnP (also an andoid app). I&amp;rsquo;d put this in the category of cheap plex server. I say this because the main reason I wanted to use it was for its on-the-fly transcoding to play media to the chromecast. The android app is also really nice, and you can control your media directly from your device too (Much like what plex does)
What I was really impressed with was that the raspberrypi (v1 Model B) handled this without too much hastle, and was able to stream 720p content to the chromecast with no (noticable) worries</description>
      <content> &lt;p&gt;So ages ago I found &lt;a href=&#34;https://www.bubblesoftapps.com/bubbleupnpserver/&#34; target=&#34;_blank&#34;&gt;bubbleUPnP&lt;/a&gt; (also an &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.bubblesoft.android.bubbleupnp&amp;amp;hl=en&#34; target=&#34;_blank&#34;&gt;andoid app&lt;/a&gt;). I&amp;rsquo;d put this in the category of cheap plex server. I say this because the main reason I wanted to use it was for its on-the-fly transcoding to play media to the chromecast. The android app is also really nice, and you can control your media directly from your device too (Much like what plex does)&lt;/p&gt;

&lt;p&gt;What I was really impressed with was that the raspberrypi (v1 Model B) handled this without too much hastle, and was able to stream 720p content to the chromecast with no (noticable) worries&lt;/p&gt;

&lt;p&gt;Installation is pretty simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ensure you have Java installed &lt;code&gt;sudo apt-get install openjdk-8-jre&lt;/code&gt; (or the oracle java if you are so inclined)&lt;/li&gt;
&lt;li&gt;Install ffmpeg, if you want on the fly transcoding &lt;code&gt;sudo apt-get install ffmpeg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Download BubbleUPnP zip file from &lt;a href=&#34;http://www.bubblesoftapps.com/bubbleupnpserver/#other_java_platforms&#34; target=&#34;_blank&#34;&gt;http://www.bubblesoftapps.com/bubbleupnpserver/#other_java_platforms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Unpack the zip file and set the &lt;code&gt;launch.sh&lt;/code&gt; file as executable

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;unzip BubbleUPNPserver-distrib.zip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd BubbbleUPNPServer &amp;amp;&amp;amp; chmod +x launch.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;launch.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once its running you can make settings changes by going to &lt;code&gt;serverIP:58050&lt;/code&gt;, but the transcoding settings can be setup in the android app once you connect to it&lt;/p&gt;

&lt;p&gt;So BubbleUPnP is not a media server (you cannot tell it where videos are for you to then stream) , it just enables alot of cool things ontop of traditional dlna media servers. So, now we need a dlna server to tell our network about media we want to watch. Incomes &lt;code&gt;minidlna&lt;/code&gt;. This is a nice, lightweigh dlna server that the pi can use. Easy to install, &lt;code&gt;sudo apt-get install minidlna&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once installed, all you need to do is tell it where your content is and it will go ahead and scan and do its magic. Edit the file at &lt;code&gt;/etc/minidlna.conf&lt;/code&gt;. Comments in that file are pretty straigh forward, all I needed to change was this line
&lt;code&gt;media_dir=V,/mnt/nas/downloads&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can add as many of these as you need to secify where your media is. You can also specifically tell it what type of media it is (notice the V ad the start of the listing) this just helps it not have to guess&lt;/p&gt;

&lt;p&gt;Now that you have both services running, check out the app on your phone.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.mrwhal3.com/img/bubble.png&#34; alt=&#34;Android BubbleUPnP&#34; /&gt;&lt;/p&gt;

&lt;p&gt;You see that it can play to &amp;ldquo;Renderers&amp;rdquo; (Things that consume the media) and it plays from a &amp;ldquo;Library&amp;rdquo; (Your dlna server, or local device files). As you can see from the screenshot of my network, I could play media to my XBOX, and by bedroom chromecast. I could choose media from my desktop PC, or the &amp;ldquo;Musicbox&amp;rdquo; server (which is my rasbperry pi)&lt;/p&gt;

&lt;p&gt;Another thing to note is, if you do not need any transcoding done, then you dont need to install the BubbleUPnP server. You can just install the android app, and install minidlna somewhere to share your media to your network&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Upgrading SD on the Raspberry Pi</title>
      <link>https://www.mrwhal3.com/2016/upgrading-sd-on-the-raspberry-pi/</link>
      <pubDate>Wed, 26 Oct 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/upgrading-sd-on-the-raspberry-pi/</guid>
      <description>I&amp;rsquo;ve been running my Raspberry Pi (V2) for almost a year and a half on a 16gb SD card, but because I run owncloud on the pi, I&amp;rsquo;ve been slowly running out of space. I know I can just add a usb drive or have owncloud store the data on an attached NAS or something, but I chose to just store everything on the SD card. Just so everything is in the one place.</description>
      <content> &lt;p&gt;I&amp;rsquo;ve been running my Raspberry Pi (V2) for almost a year and a half on a 16gb SD card, but because I run owncloud on the pi, I&amp;rsquo;ve been slowly running out of space. I know I can just add a usb drive or have owncloud store the data on an attached NAS or something, but I chose to just store everything on the SD card. Just so everything is in the one place. Anyway, I finally got around to purchasing a 32GB card, to upgrade the pi. I didn&amp;rsquo;t want to start from scratch and re-install everything from a backup, so I did a bit of searching in the raspberry pi forums, and found you can easily upgrade the SD card. And it turns out it was &lt;em&gt;very&lt;/em&gt; easy. All you need is another machine (I used GNU/Linux here) and a SD card reader (which you probably have if you have a pi)&lt;/p&gt;

&lt;p&gt;So here are the few steps I took to upgrade the SD in the Pi, retaining the whole OS and everything I had installed on it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safely power off the pi

&lt;ul&gt;
&lt;li&gt;Wait about 60-90 seconds while things power off completely. You shouldn&amp;rsquo;t see the green activity led flicker anymore once its fully shut down
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt; sudo poweroff &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Get the SD card and plug into your other machine, making sure you un-mount it if it automounts&lt;/li&gt;
&lt;li&gt;Find out where the sd card is

&lt;ul&gt;
&lt;li&gt;Look for your SD card in the list and note its location, for me this was &lt;code&gt;/dev/sdd&lt;/code&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo fdisk -l&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Take an image of the SD card with dd. This will take quite a long time, it took around 30 minutes for me, for 16gb. You can speed this up, at the risk of corruption

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;status=progress&lt;/code&gt; is just a nice way to see how things are going without using the &lt;code&gt;pkill&lt;/code&gt; trick
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo dd status&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;progress &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/dev/sdd of&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/george/rpi-16gb.img&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Once this is complete, &lt;code&gt;sync&lt;/code&gt; and unmount the drive. Plug in the larger SD card now&lt;/li&gt;
&lt;li&gt;Again, find out where its located &lt;code&gt;sudo fdisk -l&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;dd&lt;/code&gt;, lets write the image to the new disk

&lt;ul&gt;
&lt;li&gt;Notice here I use a larger block size when writing to the image, this makes it alot quicker, and is fairly safe to do. If it doesn&amp;rsquo;t work for you, decrease this to &lt;code&gt;1M&lt;/code&gt;. This will take alot longer
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo dd status&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;progress bs&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;4M &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/george/rpi-16gb.img of&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/dev/sdd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Now we have the old image on a new SD card, time to plug it in and boot up the pi&lt;/li&gt;
&lt;li&gt;Wait the usualy amount of time and ssh into your Pi. You should notice that nothing has changed. It even still thinks its on a 16gb sd card. Have a look at &lt;code&gt;df -h&lt;/code&gt;. We will fix that next&lt;/li&gt;
&lt;li&gt;Run the &lt;code&gt;raspi-config&lt;/code&gt; tool, and choose the first option - &lt;code&gt;Expand filesystem&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;wait some time and it will do its thing to expand the file system magically for you. Once its done, it will prompt you to reboot. Do this&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;ssh back in and check out &lt;code&gt;df -h&lt;/code&gt; you should see now it can see the rest of the new SD card!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the steps that worked for me, and it worked first time. You may or may not find that this works straigh away. If it doesn&amp;rsquo;t, plug the HDMI in and see if there is anything strange happening at boot time, also try plugging your original SD card in and make sure that boots. If it doesn&amp;rsquo;t, you will find the image that you took of it will have the same issue (so the new one won&amp;rsquo;t boot). If it does though, try taking another &lt;code&gt;dd&lt;/code&gt; copy of it, and checksum it against the one you took in step 4, the checksum should come back the same&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>building phonegap app for Android and iOS</title>
      <link>https://www.mrwhal3.com/2016/building-phonegap-app-for-android-and-ios/</link>
      <pubDate>Thu, 13 Oct 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/building-phonegap-app-for-android-and-ios/</guid>
      <description>So I had the pleasure of figuring out how to successfully build and publish a phonegap app, both to the Play store and Apple store. It was bad enough that I have no experience with phonegap/Cordova (or anything iOS development related), but the previous developer had left no documentation. That was fun. Here are some notes of things I ran into along the way. Hope they help someone else out too</description>
      <content> &lt;p&gt;So I had the &lt;del&gt;pleasure&lt;/del&gt; of figuring out how to successfully build and publish a phonegap app, both to the Play store and Apple store. It was bad enough that I have no experience with phonegap/Cordova (or anything iOS development related), but the previous developer had left no documentation. That was fun. Here are some notes of things I ran into along the way. Hope they help someone else out too&lt;/p&gt;

&lt;p&gt;So I had downloaded the repo, installed all the dependacies, but now I was getting this error&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;ERROR in ./src/routes/index.jsx
 
Module not found: Error: Cannot resolve &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;file&amp;#39;&lt;/span&gt; or &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;directory&amp;#39;&lt;/span&gt; ./searchByKeyword in /home/george/Documents/work/repositories/ita-app/src/routes&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Spent some time looking at Google, when I came across this suggestion to use webpack to display more verbose errors &lt;code&gt;webpack --display-error-details&lt;/code&gt;. Genius.&lt;/p&gt;

&lt;p&gt;This gave some more verbose output and told me that it was searching for the file, but could not find it in some directories, this helped me realise it was case sensative. The file it was looking for had a capital &lt;code&gt;S&lt;/code&gt;, but it was looking for lower case &lt;code&gt;s&lt;/code&gt;. Changing the name of the file to lowercase and rebuild&lt;/p&gt;

&lt;p&gt;And another error, but on index.jsx file this time.  Not sure why it only errored on these 2 files, probably something in the config files but I didn&amp;rsquo;t rally want to be looking through config files all day (there were alot!)
Do the same and rename to lower. And now we get a successful build! Yay!&lt;/p&gt;

&lt;p&gt;The previous dev had done this on OSX but not sure why this was an issue on Linux(can understand if it was done on windows, for example)&lt;/p&gt;

&lt;p&gt;So now we have an Android apk, but to upload it to the store it needs to be signed (and later on it told me it also has to be zipaligned)&lt;/p&gt;

&lt;p&gt;Here is how to do that with command line&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#Sign the app with jarsigner (should have been installed along with android studio)&lt;/span&gt;
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore /home/george/Documents/repositories/myapp/key/myapp.keystore android-x86-release-unsigned.apk myapp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Uh oh, another error&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jarsigner: Certificate chain not found for: myapp.  myapp must reference a valid KeyStore key entry containing a private key and corresponding public key certificate chain.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Turns out you have to specify the exact alias that is found inside the keystore with the jarsigner command. To get that, run&lt;/p&gt;

&lt;p&gt;&lt;code&gt;keytool -keystore /home/george/Documents/repositories/myapp/key/myapp.keystore -l&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That will display something similar to this, where you can see the alias name. Now re run &lt;code&gt;jarsigner&lt;/code&gt; with the correct alias and you will have a great time&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: myapp-release
......
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we have a signed apk, but on uplaoding to the store, it errors and tells me its not zip aligned. Luckily this one was easy.
&lt;code&gt;/home/george/Android/Sdk/build-tools/24.0.3/zipalign -v 4 android-x86-release-signed.apk android-release-signed-aligned.apk&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE&lt;/em&gt; only zip align after you have signed&lt;/p&gt;

&lt;p&gt;Android down, iOS to go!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Counter Strike and Pebble</title>
      <link>https://www.mrwhal3.com/2016/counter-strike-and-pebble/</link>
      <pubDate>Sat, 03 Sep 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/counter-strike-and-pebble/</guid>
      <description>Hey all, it&amp;rsquo;s been a while! I&amp;rsquo;ve been busy. Combining my enthusiasm to CS and the usefulness of a pebble watch to create you CSontheGO
Being able to keep up to date with CS matches from your watch. I decided to do this because I: 1. wanted to Learn a php framework 2. Enjoy developing things in my spare time
This project had to be split into 2 parts, the backend/data store, and the pebble watch.</description>
      <content> 

&lt;p&gt;Hey all, it&amp;rsquo;s been a while! I&amp;rsquo;ve been busy. Combining my enthusiasm to CS and the usefulness of a pebble watch to create you &lt;a href=&#34;https://apps.getpebble.com/applications/57c24bc35e3c3db4850002af&#34; target=&#34;_blank&#34;&gt;CSontheGO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Being able to keep up to date with CS matches from your watch. I decided to do this because I:
1. wanted to Learn a php framework
2. Enjoy developing things in my spare time&lt;/p&gt;

&lt;p&gt;This project had to be split into 2 parts, the backend/data store, and the pebble watch. Surprisingly I had a pretty much a beta version of the app running in about 45hours of dev time. This is probably mostly due to the paths I took with each part of the project&lt;/p&gt;

&lt;h4 id=&#34;the-backend&#34;&gt;the backend&lt;/h4&gt;

&lt;p&gt;So I wanted to learn a php framework (because I like php) and &lt;a href=&#34;https://laravel.com/&#34; target=&#34;_blank&#34;&gt;laravel&lt;/a&gt; and &lt;a href=&#34;https://lumen.laravel.com/&#34; target=&#34;_blank&#34;&gt;lumen&lt;/a&gt; came to me highly recommended. All I have to say is amazing&lt;/p&gt;

&lt;p&gt;So I needed a backend/data store for this project because there were no publicly consumable APIs from any sites that report on Counter Strike, so I had to make my own. For something the pebble app can use to give you information at your wrist&lt;/p&gt;

&lt;p&gt;Currently I am getting the data I need by scraping a well known e Sports website. The plan is to add other sites, for redundancy, incase I get blocked, or that particular site doesn&amp;rsquo;t provide updates for unknown reasons&lt;/p&gt;

&lt;p&gt;I ended up using lumen, as I didn&amp;rsquo;t need the full laravel install to make my idea come to life, this data store would only provide an API for the pebble app to connect to anyway, and the scraping is all done via headless cli scripts. Perfect&lt;/p&gt;

&lt;h5 id=&#34;ide-choice&#34;&gt;IDE choice&lt;/h5&gt;

&lt;p&gt;So because this was the first &amp;ldquo;big&amp;rdquo; personal project I was making, I decided to try out an IDE that supports PHP
I have created various things in php previously, but they have never been big, so I just stuck to using &lt;code&gt;vim&lt;/code&gt; which has suited my needs fine&lt;/p&gt;

&lt;p&gt;The choices only really come down to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jetbrains.com/phpstorm/&#34; target=&#34;_blank&#34;&gt;Php storm&lt;/a&gt; by jetbrains&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.eclipse.org/pdt/&#34; target=&#34;_blank&#34;&gt;Eclipse PDT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://netbeans.org/&#34; target=&#34;_blank&#34;&gt;Netbeans&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://atom.io/&#34; target=&#34;_blank&#34;&gt;Atom&lt;/a&gt; not an IDE per say but including because a legitimate option&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://code.visualstudio.com/&#34; target=&#34;_blank&#34;&gt;VS code&lt;/a&gt; same as atom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PHP storm&lt;/strong&gt;
If I had the cash to splash, I would have bought this. I used the 30 day trial, and its pretty amazing. Has all the bells and whistles you&amp;rsquo;d expect from an IDE and it does really well at on the fly suggestions and hints while developing, even with lumen. I was quite impressed with it.
I&amp;rsquo;ve used the base product before though, while developing on an Android app. &lt;a href=&#34;https://developer.android.com/studio/index.html&#34; target=&#34;_blank&#34;&gt;Android studio&lt;/a&gt; uses the indelij platform underneath it, which is the same as php storm&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eclipse&lt;/strong&gt;
I switched over to eclipse after my trial of above had finished. Eclipse was fine, but it was lacking in the suggestions and hints during development. It didn&amp;rsquo;t seem as robust and complete as php storm. I found myself having to just look up the docs more often then not when I was using eclipse. To see what parameters where etc.&lt;/p&gt;

&lt;p&gt;And that is why I ended up just using &lt;strong&gt;atom&lt;/strong&gt;. It has a decent enough support for PHP to give me syntax errors, and if I&amp;rsquo;m using the docs anyway, I may as well use something a little more light weight. I&amp;rsquo;ve used atom previously, mainly as just a text editor of choice (after &lt;code&gt;vim&lt;/code&gt;) but it&amp;rsquo;s come a long way since I last used it so it was quite pleasant. And does exactly what i need it to do. I know I&amp;rsquo;m missing the big IDE features like integrated testing, integrated environments and things like that, but that&amp;rsquo;s okay with me&lt;/p&gt;

&lt;h4 id=&#34;pebble-app&#34;&gt;pebble app&lt;/h4&gt;

&lt;p&gt;There were 2 paths I could have taken with this. Write in c, with the &lt;a href=&#34;https://developer.pebble.com/docs/c/&#34; target=&#34;_blank&#34;&gt;pebble c&lt;/a&gt; framework, or use &lt;a href=&#34;https://pebble.github.io/pebblejs/&#34; target=&#34;_blank&#34;&gt;pebblejs&lt;/a&gt;, a framework that allows you to write the app in JavaScript. I chose pebblejs. There were a few downfalls with pebblejs, namely, it &amp;ldquo;runs&amp;rdquo; on the phone and sends all the data to the watch, causing more BT round trips, using more battery. The good thing about it was it was very quick to get an app up and running. No worrying about appmessage and dealing with all that in c. Although I will eventually rewrite in c to support all watches and the new APIs, which pebblejs doesn&amp;rsquo;t support (and probably won&amp;rsquo;t)&lt;/p&gt;

&lt;p&gt;Writing this was pretty neat, JavaScript is super powerful and includes all the things I needed (pulling data from the API and showing it in a menu) and I could utilise things like timeline pins via the rest API too.&lt;/p&gt;

&lt;p&gt;All in all, I&amp;rsquo;ve had fun! I&amp;rsquo;ve learnt alot, both in PHP frameworks and development in general. I have a long list of fixes/feature I want to add but don&amp;rsquo;t exactly have the usage of the app to really continue :( I will certainly leave the backend up for those (and myself) that are currently using it. I guess there isn&amp;rsquo;t much of a user base that like CSGO and have a Pebble!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>C.H.I.P</title>
      <link>https://www.mrwhal3.com/2016/c.h.i.p/</link>
      <pubDate>Thu, 14 Jul 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/c.h.i.p/</guid>
      <description>So I was too late to the hype of Pi Zero, the $5 Raspberry pi, and have not been able to get my hands on one since the launch. Everywhere has been sold out everytime I check :(
I can&amp;rsquo;t remember how I stumble upon them, but I found an equaly as awesome project on kickstarter. C.H.I.P. A $9 board that runs linux. Esentially the same specs as the PiZero, CHIP also includes onboard wifi and BlueTooth 4.</description>
      <content> &lt;p&gt;So I was too late to the hype of &lt;a href=&#34;https://www.raspberrypi.org/products/pi-zero/&#34; target=&#34;_blank&#34;&gt;Pi Zero&lt;/a&gt;, the $5 Raspberry pi, and have not been able to get my hands on one since the launch. Everywhere has been sold out everytime I check :(&lt;/p&gt;

&lt;p&gt;I can&amp;rsquo;t remember how I stumble upon them, but I found an equaly as awesome project on kickstarter. &lt;a href=&#34;https://getchip.com&#34; target=&#34;_blank&#34;&gt;C.H.I.P&lt;/a&gt;. A $9 board that runs linux. Esentially the same specs as the PiZero, CHIP also includes onboard wifi and BlueTooth 4.0! Amazing right?! So I now have one of these on order, hopefully in the mail soon. This just opens up the possibilites of home automation. From reading their documentation, it seems to run a slighty modified version of Debian (I assume just to include some performance enhancements to support the hardware). It Also includes lots of GPIO pins so you can hook up any type of sensor that you would be able to with a raspberrypi, with CHIP.&lt;/p&gt;

&lt;p&gt;$9 board with wifi and GPIO pins. Means I can cheaply add any type of sensor I want to pretty much every room in the house. Easily hook this up to my OpenHAB controller (which I will make a post about soon) and create some awesome automation rules to keep things running smootly. For example, I have a few watts clever power remotes, so I could add CHIP into the master bedroom, monitor the temperature and turn the wall heater on/off as required during the night. Super useful during these cold winter months!&lt;/p&gt;

&lt;p&gt;So many other things to be done. Need to decide on what I want it to do before it arrives so I can get to it straight away!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Fun with cPanel</title>
      <link>https://www.mrwhal3.com/2016/fun-with-cpanel/</link>
      <pubDate>Fri, 17 Jun 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/fun-with-cpanel/</guid>
      <description>Recently have had to set up a few cPanel servers, and here are some things I ran into while doing so. One isn&amp;rsquo;t necessarily cPanels fault, but it still took me a long time to find a work around for it :/
Key based login for SSH Common practice for most cloud provides these days is to give you a VM with password based authentication turned off. That&amp;rsquo;s cool with me as this is one of the first things I do anyway.</description>
      <content> 

&lt;p&gt;Recently have had to set up a few cPanel servers, and here are some things I ran into while doing so. One isn&amp;rsquo;t necessarily cPanels fault, but it still took me a long time to find a work around for it :/&lt;/p&gt;

&lt;h4 id=&#34;key-based-login-for-ssh&#34;&gt;Key based login for SSH&lt;/h4&gt;

&lt;p&gt;Common practice for most cloud provides these days is to give you a VM with password based authentication turned off. That&amp;rsquo;s cool with me as this is one of the first things I do anyway. Setting up cPanel a breeze. Create a new user, no worries. Create SSH keys and import, easy. Attempt to login server: &lt;code&gt;login limit exceeded for account&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Odd.. but let&amp;rsquo;s turn on verbose.&lt;/p&gt;

&lt;p&gt;Ah it&amp;rsquo;s giving other keys before the one it needs. Let&amp;rsquo;s add &lt;code&gt;IdentitiesOnly yes&lt;/code&gt; to config file&lt;/p&gt;

&lt;p&gt;Still not working. Let&amp;rsquo;s try super verbose. Still no luck. 30 odd minutes of faffing about I decide to check the server logs (Note: check these first, not after)&lt;/p&gt;

&lt;p&gt;Ah there is the real problem, server is complaining about permission issues being bad on .ssh folder for user&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Chmod&lt;/code&gt; that up and fixed!&lt;/p&gt;

&lt;h4 id=&#34;cpanel-and-aws-ec2&#34;&gt;cPanel and aws ec2&lt;/h4&gt;

&lt;p&gt;Make sure you check NAT settings! Spun up a fresh VM, added an account but it wouldn&amp;rsquo;t work! Kept redirecting me to that default &amp;ldquo;no site here&amp;rdquo; page. Tried this that and the other, but still not working&lt;/p&gt;

&lt;p&gt;Turns out cPanel hadn&amp;rsquo;t detected the NAT settings properly, so didn&amp;rsquo;t have the right elastic IP (and in fact had the wrong internal IP) in its settings. To fix run &lt;code&gt;/scripts/build_cpnat&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Check (settings -&amp;gt; IP) to make sure it&amp;rsquo;s all better&lt;/p&gt;

&lt;h4 id=&#34;getting-custom-sites-into-cpanel&#34;&gt;Getting custom sites into cPanel&lt;/h4&gt;

&lt;p&gt;Got a site that was developed by someone else, and from the looks of it was just setup on a LAMP server, nothing special, but had real trouble trying to squash this into cPanel. Site was built on the zend framework and use composer as dependency manager. Now this would have been nice to know before I started&lt;/p&gt;

&lt;p&gt;Copy site files into &lt;code&gt;public_html&lt;/code&gt;. No thanks. Zend uses another folder &lt;code&gt;public&lt;/code&gt; where it stores the index.php etc. That&amp;rsquo;s cool, let&amp;rsquo;s just change document root in &lt;code&gt;/var/cPanel/userdata/user/site-name&lt;/code&gt; have to do this because there are other folders on the same level as this public folder that it uses&lt;/p&gt;

&lt;h5 id=&#34;note&#34;&gt;Note&lt;/h5&gt;

&lt;p&gt;There are other ways around this, using symlinks or htaccess. Probably better practice. But php&lt;/p&gt;

&lt;h4 id=&#34;composer-and-cpanel&#34;&gt;Composer and cpanel&lt;/h4&gt;

&lt;p&gt;The next issue I ran into was getting composer running, to build and make sure dependacies are there. Composer in cPanel? Sure why not&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; to your public dir, or whereever your composer.json file is, &lt;code&gt;wget https://getcomposer.org/download/1.1.1/composer.phar&lt;/code&gt; (or lookup the composer site to get the latest, and then &lt;code&gt;php composer.phar install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Surprisingly was as simple as this!&lt;/p&gt;

&lt;p&gt;All good? Almost. Get slapped with this error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ZendMailProtocol_Exception&#39; with message &#39;535 Incorrect authentication data &#39; in /Zend/Mail/Protocol/Abstract.php:378 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Sigh&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Turns out Zend doesn&amp;rsquo;t play ball with exim or any other mail agent you have installed, and tried to send email by itself. So you need to enable (or disable) a setting within cpanel to get it working
Probably not the most security best practice setting to be playing with, but I needed to get it working&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login to WHM&lt;/li&gt;
&lt;li&gt;Under Server Configuration, select Tweak Settings&lt;/li&gt;
&lt;li&gt;Click on the Mail tab&lt;/li&gt;
&lt;li&gt;Scroll down to “Restrict outgoing SMTP to root, exim, and mailman (FKA SMTP Tweak)” and make sure it’s set to “OFF”&lt;/li&gt;
&lt;li&gt;Scroll to the bottom of the page and click Save&lt;/li&gt;
&lt;/ol&gt;
 </content>
    </item>
    
    <item>
      <title>TV dashboards with chromecasts and dashing</title>
      <link>https://www.mrwhal3.com/2016/tv-dashboards-with-chromecasts-and-dashing/</link>
      <pubDate>Wed, 04 May 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/tv-dashboards-with-chromecasts-and-dashing/</guid>
      <description>I had some time, and we had some TV&amp;rsquo;s hanging on the wall wasting space. So I decided to create a dashboard that could put some useful information on these TV&amp;rsquo;s for everyone to see
Previously we were utilising the chromecasts with Greenscreen, and it worked well, but had its issues (probably more related to the chromecasts, not the software) but we weren&amp;rsquo;t using it as a useful dashboard, more just to scroll through some website links and display the occasional funny gif</description>
      <content> 

&lt;p&gt;I had some time, and we had some TV&amp;rsquo;s hanging on the wall wasting space. So I decided to create a dashboard that could put some useful information on these TV&amp;rsquo;s for everyone to see&lt;/p&gt;

&lt;p&gt;Previously we were utilising the chromecasts with &lt;a href=&#34;https://greenscreen.io&#34; target=&#34;_blank&#34;&gt;Greenscreen&lt;/a&gt;, and it worked well, but had its issues (probably more related to the chromecasts, not the software) but we weren&amp;rsquo;t using it as a useful dashboard, more just to scroll through some website links and display the occasional funny gif&lt;/p&gt;

&lt;p&gt;This stopped working for us when they updated the way to talk to the chromecasts :( So instead of fixing it, I decided to find something else to do the job, and a cool dashboard to go with it&lt;/p&gt;

&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;

&lt;p&gt;So I installed everything under Debian virtual machine, that&amp;rsquo;s running both the dashboard, and the dashboard controller with 1gb RAM. I eventually plan to have it all running on a raspberry pi. More on that when I get around to it!&lt;/p&gt;

&lt;p&gt;So go ahead and spin yourself one of these up, and when you are ready, install the following dependancie
s
(apt-get)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nodejs&lt;/li&gt;
&lt;li&gt;avahi-utils&lt;/li&gt;
&lt;li&gt;avahi-daemon&lt;/li&gt;
&lt;li&gt;libavahi-compat-libdnssd-dev&lt;/li&gt;
&lt;li&gt;Ruby (&amp;gt;1.9)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(npm)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bower&lt;/li&gt;
&lt;li&gt;grunt-cli&lt;/li&gt;
&lt;li&gt;fd&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;note: To install additional widgets once dashing is setup - &lt;code&gt;dashing install [gist ID]&lt;/code&gt;&lt;/p&gt;

&lt;h1 id=&#34;dashboard&#34;&gt;Dashboard&lt;/h1&gt;

&lt;p&gt;So a year or so ago, I stumbled upon &lt;a href=&#34;https://dashing.io&#34; target=&#34;_blank&#34;&gt;Dashing&lt;/a&gt;. At the time I used this awesome framework to build a dashboard for home, so I could view/control my automated home from a wall mounted tablet in style. Very out of date, but see &lt;a href=&#34;https://github.com/mrwhale/dashboard&#34; target=&#34;_blank&#34;&gt;home dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This took a bit of tinkering to get it to display things how I wanted, and I had to learn some ruby along the way, but all part of the fun. &lt;img src=&#34;https://www.mrwhal3.com/img/dashboard.png&#34; alt=&#34;work dashboard&#34; /&gt;&lt;/p&gt;

&lt;p&gt;To get things setup&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install &lt;code&gt;dashing&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo gem install dashing&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Generate your dashboard and bundle the gems&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dashing new my-dashboard &amp;amp;&amp;amp; cd my-dashboard &amp;amp;&amp;amp; bundle&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;modify &lt;code&gt;config.ru&lt;/code&gt; to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add an authtoken (useful if you want to talk to the API externally)&lt;/li&gt;
&lt;li&gt;disable x-frame-options. This is needed, as the dashboard controller will load dashing in an iframe. If it turned on, it will cause some issues (line 6)&lt;/li&gt;
&lt;li&gt;set the default dashboard that gets loaded (line 5)
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ruby&#34; data-lang=&#34;ruby&#34;&gt;require &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;dashing&amp;#39;&lt;/span&gt;
configure &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;
  set &lt;span style=&#34;color:#e6db74&#34;&gt;:auth_token&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;myauthtoken&amp;#39;&lt;/span&gt;
  set &lt;span style=&#34;color:#e6db74&#34;&gt;:default_dashboard&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;gs&amp;#39;&lt;/span&gt;
  set &lt;span style=&#34;color:#e6db74&#34;&gt;:protection&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;:except&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;:frame_options&lt;/span&gt;
  helpers &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;protected!&lt;/span&gt;
     &lt;span style=&#34;color:#75715e&#34;&gt;# Put any authentication code you want in here.&lt;/span&gt;
     &lt;span style=&#34;color:#75715e&#34;&gt;# This method is run before accessing any resource.&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
map &lt;span style=&#34;color:#66d9ef&#34;&gt;Sinatra&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Application&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;assets_prefix &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;
  run &lt;span style=&#34;color:#66d9ef&#34;&gt;Sinatra&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Application&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sprockets
&lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
run &lt;span style=&#34;color:#66d9ef&#34;&gt;Sinatra&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Application&lt;/span&gt;
  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Read below about configuring the widgets, and then start!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo dashing start -p 80&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First I had to change the way the List widget worked, so I could have 2 rows of names for the leave. This is what I had to add to &lt;code&gt;widgets/list/list.html&lt;/code&gt;&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;title&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-bind&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;hr&lt;/span&gt;/&amp;gt;
&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;table&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;tr&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;td&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;list-nostyle&amp;#34;&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-foreach-item&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;itemsleft&amp;#34;&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-bind&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;item.label&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
  &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
  &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;td&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;td&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;list-nostyle&amp;#34;&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-foreach-item&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;itemsright&amp;#34;&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-bind&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;item.label&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
      &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
      &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;td&lt;/span&gt;&amp;gt;
  &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;tr&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;more-info&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-bind&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;moreinfo&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;updated-at&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-bind&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;updatedAtMessage&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then had to change/add some font sizes to make it look how I wanted (as the TV&amp;rsquo;s were on walls above desk area&amp;rsquo;s, I had to make sure things were big enough to read easily)
&lt;code&gt;widgets/list/list.scss&lt;/code&gt;&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;  .&lt;span style=&#34;color:#a6e22e&#34;&gt;title&lt;/span&gt; {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;color&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;$&lt;/span&gt;title-color;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;font-weight&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;bold&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;font-size&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/span&gt;;
  }

  &lt;span style=&#34;color:#f92672&#34;&gt;ol&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;margin&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;text-align&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;center&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;color&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;$&lt;/span&gt;label-color;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;font-size&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/span&gt;;
  }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I found &lt;a href=&#34;https://gist.github.com/chelsea/5641535#file-random_aww-rb&#34; target=&#34;_blank&#34;&gt;this dashing&lt;/a&gt; widget that collects and displays reddit images, and changed it to use the subreddits I wanted (&lt;code&gt;/r/aww&lt;/code&gt;) and combined it with the &lt;a href=&#34;https://gist.github.com/jwalton/7916168&#34; target=&#34;_blank&#34;&gt;big image&lt;/a&gt; dashing widget to display that nice 2 row sized image&lt;/p&gt;

&lt;p&gt;I didnt change anything in the style or html, however I just modified the job &lt;code&gt;jobs/aww.rb&lt;/code&gt; to do it at the intervals I wanted, and included the subreddits I wanted. You can add any other subreddits to the &lt;code&gt;subreddit&lt;/code&gt; array at the top of the script
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ruby&#34; data-lang=&#34;ruby&#34;&gt;require &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;net/http&amp;#39;&lt;/span&gt;
require &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;json&amp;#39;&lt;/span&gt;

placeholder &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://i.imgur.com/JycUgrg.jpg&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#subreddits = [&amp;#39;/r/aww.json&amp;#39;,&amp;#39;/r/animalsbeingjerks.json&amp;#39;,&amp;#39;/r/aww_gifs.json&amp;#39;,&amp;#39;/r/babyduckgifs.json&amp;#39;]&lt;/span&gt;
subreddits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/r/aww.json&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;SCHEDULER&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;every &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;300s&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;
  randomreddit &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; subreddits&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sample
  http &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Net&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;HTTP&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;new(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;www.reddit.com&amp;#39;&lt;/span&gt;)
  response &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; http&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;request(&lt;span style=&#34;color:#66d9ef&#34;&gt;Net&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;HTTP&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;new(randomreddit))
  json &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;JSON&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;parse(response&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;body)

  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;][&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;children&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;].&lt;/span&gt;count &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
    send_event(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;picture&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;image&lt;/span&gt;: placeholder)
  &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;
    urls &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;][&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;children&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;].&lt;/span&gt;map{&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;child&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; child&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;][&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;url&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; }

    &lt;span style=&#34;color:#75715e&#34;&gt;# Ensure we&amp;#39;re linking directly to an image, not a gallery etc.&lt;/span&gt;
    valid_urls &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; urls&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;select{&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;url&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; url&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;downcase&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;end_with?(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;png&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;gif&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;jpg&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;jpeg&amp;#39;&lt;/span&gt;)}
    send_event(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;picture&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;#{&lt;/span&gt;valid_urls&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;shuffle&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sample(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;first&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
  &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;And for weather info I used this &lt;a href=&#34;https://gist.github.com/kostasdizas/8c45637dee3b1bf27e6a&#34; target=&#34;_blank&#34;&gt;forecast.io&lt;/a&gt; dashing widget for the weather. Previously, in my home dashboard, I had used the &lt;a href=&#34;https://gist.github.com/ysim/6768311&#34; target=&#34;_blank&#34;&gt;verbinski&lt;/a&gt; widget, so I attempted to incorporate that initially. But I didn&amp;rsquo;t want the default of 3 columns of weather (Today, Tomorrow and weekly) and tried to change it to only be todays weather. It worked, but I wasnt able to make it match the rest of the tiles on the dashboard, and ended up looking out of place &lt;img src=&#34;https://www.mrwhal3.com/img/failweather.png&#34; alt=&#34;fail whale front end&#34; /&gt;&lt;/p&gt;

&lt;h4 id=&#34;getting-calendar-info-into-the-dashboard&#34;&gt;Getting calendar info into the dashboard&lt;/h4&gt;

&lt;p&gt;So because we use google calendars here (we utilise a shared calendar for leave/remote) I was able to leverage the library&amp;rsquo;s Google has created to get this info. They do have a ruby library for this, but first go I was unable to get it working (needed a new version of Ruby) So I defaulted back to use the PHP library&lt;/p&gt;

&lt;p&gt;First you need to follow &lt;a href=&#34;https://developers.google.com/google-apps/calendar/quickstart/php&#34; target=&#34;_blank&#34;&gt;these&lt;/a&gt; instructions to turn calendar api access on, and configure an access token, also follow those instructions for installing the google client library from &lt;code&gt;composer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So I run this as a cron job, every hour, between 6-6. I&amp;rsquo;ve modified it to just download events on the leave and remote calendars to seperate text files. This is the read into the dashboard by a ruby job, which is part of dashing
(I have only included the snippet of code I modified, the rest is the same as in the google example)&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);
$todaystart = date(&amp;#34;Y-m-d&amp;#34;) . &amp;#34;T00:00:00+10:00&amp;#34;;
$todayend = date(&amp;#34;Y-m-d&amp;#34;) . &amp;#34;T23:59:59+10:00&amp;#34;;
// Print the next 10 events on the user&amp;#39;s calendar.
$calendarId = &amp;#39;Goes here&amp;#39;;
$optParams = array(
  &amp;#39;maxResults&amp;#39; =&amp;gt; 10,
  &amp;#39;orderBy&amp;#39; =&amp;gt; &amp;#39;startTime&amp;#39;,
  &amp;#39;singleEvents&amp;#39; =&amp;gt; TRUE,
  &amp;#39;timeMin&amp;#39; =&amp;gt; $todaystart,
  &amp;#39;timeMax&amp;#39; =&amp;gt; $todayend,
);
$results = $service-&amp;gt;events-&amp;gt;listEvents($calendarId, $optParams);
$fh = fopen(&amp;#34;/home/John/work-dashboard/jobs/leaveleft.txt&amp;#34;,&amp;#34;w&amp;#34;);
$fh2 = fopen(&amp;#34;/home/John/work-dashboard/jobs/leaveright.txt&amp;#34;,&amp;#34;w&amp;#34;);
if (count($results-&amp;gt;getItems()) == 0) {
  print &amp;#34;No upcoming events found.\n&amp;#34;;
} else {
  print &amp;#34;Upcoming events:\n&amp;#34;;
  $i = 0;
  foreach ($results-&amp;gt;getItems() as $event) {
    $start = $event-&amp;gt;start-&amp;gt;dateTime;
    if (empty($start)) {
      $start = $event-&amp;gt;start-&amp;gt;date;
    }
    printf(&amp;#34;%s (%s)\n&amp;#34;, $event-&amp;gt;getSummary(), $start);
    $data1 = $event-&amp;gt;getSummary();
    $split = explode(&amp;#34;-&amp;#34;, $data1);
    $data = $split[0] . &amp;#34;\n&amp;#34;;
    if($i&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;5&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;){&lt;/span&gt;
        &lt;span style=&#34;color:#a6e22e&#34;&gt;fwrite&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;($&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;fh&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,$&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;);&lt;/span&gt;
    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;else&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#a6e22e&#34;&gt;fwrite&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;($&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;fh2&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,$&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;);&lt;/span&gt;
    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;$&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;++;&lt;/span&gt;
  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then here are the jobs that go in the dashing job folder&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ruby&#34; data-lang=&#34;ruby&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#leave.rb&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;SCHEDULER&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;every &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;360s&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; 
  leavep &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Hash&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;new({ &lt;span style=&#34;color:#e6db74&#34;&gt;value&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; })
  leaver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Hash&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;new({ &lt;span style=&#34;color:#e6db74&#34;&gt;value&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; })
  &lt;span style=&#34;color:#66d9ef&#34;&gt;File&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;readlines(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/home/John/work-dashboard/jobs/leaveleft.txt&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;each &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;line&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;
    leavep&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;line&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; { &lt;span style=&#34;color:#e6db74&#34;&gt;label&lt;/span&gt;: line }
  &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;File&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;readlines(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/home/John/work-dashboard/jobs/leaveright.txt&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;each &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;line&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;
    leaver&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;line&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; { &lt;span style=&#34;color:#e6db74&#34;&gt;label&lt;/span&gt;: line }
  &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
  send_event(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;leave&amp;#39;&lt;/span&gt;, { &lt;span style=&#34;color:#e6db74&#34;&gt;itemsleft&lt;/span&gt;: leavep&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values })
  send_event(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;leave&amp;#39;&lt;/span&gt;, { &lt;span style=&#34;color:#e6db74&#34;&gt;itemsright&lt;/span&gt;: leaver&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values })
&lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;#remote.rb&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;SCHEDULER&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;every &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;360s&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;
  leavep &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Hash&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;new({ &lt;span style=&#34;color:#e6db74&#34;&gt;value&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; })
  &lt;span style=&#34;color:#66d9ef&#34;&gt;File&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;readlines(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/home/george/work-dashboard/jobs/remoteleft.txt&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;each &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;line&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;
    leavep&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;line&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; { &lt;span style=&#34;color:#e6db74&#34;&gt;label&lt;/span&gt;: line }
  &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
  send_event(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;remote&amp;#39;&lt;/span&gt;, { &lt;span style=&#34;color:#e6db74&#34;&gt;itemsleft&lt;/span&gt;: leavep&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values })
  &lt;span style=&#34;color:#75715e&#34;&gt;#send_event(&amp;#39;remote&amp;#39;, { itemsright: leavep.values })&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To make this less messy, I definitely could have got the Ruby library working, then just had it running as a job under dashing to push results directly to the dashboard, instead of having this extra script run then pull in seperate. Also merging the 2 scripts that are currently seperate (leave.rb and remote.rb) From memory I originally did this but there was issues when it was pushing things to the dashboard.&lt;/p&gt;

&lt;p&gt;But now I have a dashboard that displays some useful information to the managers at work, without having to open up calenders and faff about with that to see who is away/remote and also gives everyone something cute to look at&lt;/p&gt;

&lt;p&gt;I plan to create another dashboard for the &amp;ldquo;developer&amp;rdquo; area so there some more relavant information for them, such as status of TeamCity/Jenkin&amp;rsquo;s builds, git commits for the day. But that&amp;rsquo;s on the to-do list. Should be simple enough though as there are a multitude of widgets for dashing you can &lt;a href=&#34;https://github.com/Shopify/dashing/wiki/Additional-Widgets&#34; target=&#34;_blank&#34;&gt;use here&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&#34;dashboard-controller&#34;&gt;Dashboard Controller&lt;/h1&gt;

&lt;p&gt;So as I mentioned, instead of Greenscreen I set out to find something else that could control chromecasts, but better. Thats when I found &lt;a href=&#34;https://github.com/vincentbernat/dashkiosk&#34; target=&#34;_blank&#34;&gt;DashKiosk&lt;/a&gt;
Pretty awesome as its a dashboard manager that can handle more then just chromecasts. Anything that can browse the web, and has as screen can be turned into a dashboard using this!
The plan was to buy some raspberry pi&amp;rsquo;s and attach them to the TV, so we could have a more reliable &amp;ldquo;client&amp;rdquo;, but thankfully, the chromecastV2 worked perfectly&lt;/p&gt;

&lt;p&gt;Pretty straight forward setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download and extract the latest dashkiosk tar ball

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;wget https://github.com/vincentbernat/dashkiosk/archive/v2.6.6.tar.gz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tar -zxvf v2.6.6.tar.gz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd dashkiosk-2.6.6/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Install npm dependancies and build

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo npm install&lt;/code&gt; #this is going to take a bit of time. Shouldnt be any errors at this stage (I got one but it was because i didnt install something at the start)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo grunt&lt;/code&gt; #This also may take some time&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Test to make sure chromecasts work

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;avahi-browse _googlecast._tcp&lt;/code&gt;
This will list all the chromecasts on the network, make sure you can see them
Now make sure you can resolve the name to IP&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getent hosts &amp;quot;Dev\032Area&amp;quot;.local&lt;/code&gt;
If this works, you are good to go! If not, see &lt;a href=&#34;https://dashkiosk.readthedocs.org/en/latest/chromecast.html&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Finish up and configure for your environment

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cd dist&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo npm install --production&lt;/code&gt; #this will take a while&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo vim lib/config.js&lt;/code&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;change&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;the&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;chromecast&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;part&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;where&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;the&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;IP&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;address&lt;/span&gt; 
  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;the&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;IP&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;address&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;the&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt; 
  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;Cant&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;use&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;domain&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;because&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;chromecast&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;uses&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;google&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dns&lt;/span&gt;,
  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;so&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;unless&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;it&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;facing&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;it&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;wont&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;work&lt;/span&gt;
  &lt;span style=&#34;color:#75715e&#34;&gt;// Chromecast
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;chromecast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#a6e22e&#34;&gt;enabled&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;,
        &lt;span style=&#34;color:#a6e22e&#34;&gt;receiver&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://192.168.100.171:9400/receiver&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#a6e22e&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;5E7A2C2C&amp;#39;&lt;/span&gt;
      },
  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Run it!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo node server.js --environment production&lt;/code&gt;
This will start up on port 9400, so go to &lt;code&gt;http://IPADDY:9400&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The only issue I had was getting the chromecast module working, but that ended up being an easy fix. Had to change 1 file to turn off(?) ipv6&lt;/p&gt;

&lt;h3 id=&#34;some-issues-along-the-way&#34;&gt;Some issues along the way&lt;/h3&gt;

&lt;p&gt;So the main issue with this setup is the chromecast v1 hardware. In our setup we have 2 AP&amp;rsquo;s using both bands, but the chromecasts frequently dropped out and had to reconnect. This was a pain with greenscreen as you had to manually reconnect the chromecast back up. I never got to the bottom whether it was the chromecasts, or our wifi that was the main issue. But upgrading to the Chromecastv2 was a whole lot better, much more stable and noticably faster&lt;/p&gt;

&lt;p&gt;Let me know if you are interested, and I&amp;rsquo;ll load the whole dashing dashboard I created into github&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>PHP file upload to slack</title>
      <link>https://www.mrwhal3.com/2016/php-file-upload-to-slack/</link>
      <pubDate>Wed, 13 Apr 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/php-file-upload-to-slack/</guid>
      <description>So I don&amp;rsquo;t know why this one took me this long to find, but I spent a long time today trying to figure out why my PHP script wasn&amp;rsquo;t uploading my file I wanted to slack. I had the string to send to slack correct, but every time I tried I was getting a no_file_content error.
I was using the, apparently now, old method of referencing a file for POST-back. That is $file = &#39;@/path/to/file.</description>
      <content> &lt;p&gt;So I don&amp;rsquo;t know why this one took me this long to find, but I spent a long time today trying to figure out why my PHP script wasn&amp;rsquo;t uploading my file I wanted to slack. I had the string to send to slack  correct, but every time I tried I was getting a &lt;code&gt;no_file_content&lt;/code&gt; error.&lt;/p&gt;

&lt;p&gt;I was using the, apparently now, old method of referencing a file for POST-back. That is &lt;code&gt;$file = &#39;@/path/to/file.png&#39;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is the new method, in case any one else had as much trouble as I did finding it &lt;code&gt;$file = new CurlFile(&#39;filename.png&#39;, &#39;image/png&#39;);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://wiki.php.net/rfc/curl-file-upload&#34; target=&#34;_blank&#34;&gt;Here&lt;/a&gt; is the PHP wiki article on the &amp;ldquo;new&amp;rdquo; method&lt;/p&gt;

&lt;p&gt;And here it is, in action&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;?php&lt;/span&gt;
$slacktoken &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;longthingwithlotsofletters&amp;#34;&lt;/span&gt;;
$header &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;array&lt;/span&gt;();
$header[] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Content-Type: multipart/form-data&amp;#39;&lt;/span&gt;;
$file &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CurlFile&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/home/john/myphoto.jpg&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;image/jpg&amp;#39;&lt;/span&gt;);

$postitems &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;array&lt;/span&gt;(
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;token&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $slacktoken,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;file&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt;  $file,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;text&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;This is my photo&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;title&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Why this?&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;filename&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;my-photo.jpg&amp;#34;&lt;/span&gt;
);
    
$curl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;curl_init&lt;/span&gt;();
&lt;span style=&#34;color:#a6e22e&#34;&gt;curl_setopt&lt;/span&gt;($curl, &lt;span style=&#34;color:#a6e22e&#34;&gt;CURLOPT_RETURNTRANSFER&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;);
&lt;span style=&#34;color:#a6e22e&#34;&gt;curl_setopt&lt;/span&gt;($curl, &lt;span style=&#34;color:#a6e22e&#34;&gt;CURLOPT_HTTPHEADER&lt;/span&gt;, $header);
&lt;span style=&#34;color:#a6e22e&#34;&gt;curl_setopt&lt;/span&gt;($curl, &lt;span style=&#34;color:#a6e22e&#34;&gt;CURLOPT_URL&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://slack.com/api/files.upload&amp;#34;&lt;/span&gt;);
&lt;span style=&#34;color:#a6e22e&#34;&gt;curl_setopt&lt;/span&gt;($curl, &lt;span style=&#34;color:#a6e22e&#34;&gt;CURLOPT_POST&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;);
&lt;span style=&#34;color:#a6e22e&#34;&gt;curl_setopt&lt;/span&gt;($curl, &lt;span style=&#34;color:#a6e22e&#34;&gt;CURLOPT_POSTFIELDS&lt;/span&gt;,$postitems);

&lt;span style=&#34;color:#75715e&#34;&gt;//Execute curl and store in variable
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;$data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;curl_exec&lt;/span&gt;($curl);
&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Yay now I can upload files from PHP&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Blacklist Checker</title>
      <link>https://www.mrwhal3.com/2016/blacklist-checker/</link>
      <pubDate>Wed, 06 Apr 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/blacklist-checker/</guid>
      <description>This is a nice little php script that you can run in the background via cron to constantly check your mail servers (or any server you have that deals with mail) and alert you via slack
I know there are things out there like mxtoolbox that can do this for you, and include a larger list of blacklists, but I wanted something I could run on our own infrastructure that did what I wanted, and alerted me via slack (much cooler then email alerts).</description>
      <content> 

&lt;p&gt;This is a nice little php script that you can run in the background via cron to constantly check your mail servers (or any server you have that deals with mail) and alert you via slack&lt;/p&gt;

&lt;p&gt;I know there are things out there like mxtoolbox that can do this for you, and include a larger list of blacklists, but I wanted something I could run on our own infrastructure that did what I wanted, and alerted me via slack (much cooler then email alerts). Eventually I will also add in bulk email alerts (like a weekly update of whats happened) and maybe, just maybe SMS alerts via twilio or SMScentral&lt;/p&gt;

&lt;p&gt;I have been using mxtoolbox, but was finding the email alerts not helpful, as I don&amp;rsquo;t often check my emails during the day, and they started going to my spam folder. I wrote this so I could be in control of what I checked and when, and then post it to Slack when there was an issue. As at work I always have a slack windows open because use it heavily.&lt;/p&gt;

&lt;p&gt;This alerts you when things clear up for a particular server too&lt;/p&gt;

&lt;p&gt;You can check it out &lt;a href=&#34;https://github.com/mrwhale/blacklist-checker&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is what the notifications look like:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.mrwhal3.com/img/slack-blacklist-checker.png&#34; alt=&#34;Slack notifications&#34; /&gt;&lt;/p&gt;

&lt;p&gt;The git repo includes setup instructions in the README, but I will include here too&lt;/p&gt;

&lt;h1 id=&#34;usage&#34;&gt;Usage&lt;/h1&gt;

&lt;p&gt;To use this you will need&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A slack API token&lt;/li&gt;
&lt;li&gt;A slack webhook to the channel you want to post to&lt;/li&gt;
&lt;li&gt;PHP (of course)&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Download this repo&lt;/li&gt;
&lt;li&gt;open &lt;code&gt;blacklist-cron.php&lt;/code&gt; and edit settings at the top of the script to include slack specific stuff&lt;/li&gt;
&lt;li&gt;edit &lt;code&gt;servers.txt&lt;/code&gt; to add in your mail servers (can be IP or domain name)&lt;/li&gt;
&lt;li&gt;edit &lt;code&gt;dnsbls.txt&lt;/code&gt; to include all the DNSBL servers you want to check against (left this full of the ones I use)

&lt;ul&gt;
&lt;li&gt;be sure to check each one. Some, like baracuda, require you to sign up if you are going to be making lots of calls&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Make a cron entry, like
&lt;code&gt;00 08-18 * * * /usr/bin/php /home/john/blacklist/blacklist-cron.php &amp;gt;&amp;gt; /home/john/blacklist/cron.log&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;This will run the script every hour between 8am and 6pm (office ours). I also did this to reduce the amount of requests i send to each dnsbl. You can change this to suit your needs&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You will now be alerted when a server of yours gets put on any of those blacklists, like this. It will also alert you when they are removed again&lt;/p&gt;

&lt;p&gt;You can also run this via the commandline if you want to see whats going on &lt;code&gt;php blacklist-cron.php&lt;/code&gt; and if you have debug turned on, things will just print to screen
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;john@johns-server:~/backlist$ php blacklist-cron.php
Checking &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;.2.3.4
is the server in bl array? 
server not found on any blacklists. Yay!

Checking mymailserver.com.au
is the server in bl array? 
mymailserver.com.au -&amp;gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;.6.7.8
checking against ubl.unsubscore.com
Added to blarray
Creating report
posting to slack

Checking mailserver02.net
is the server in bl array? 
mailserver02.net -&amp;gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;123&lt;/span&gt;.45.67.89
server not found on any blacklists. Yay!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Owncloud</title>
      <link>https://www.mrwhal3.com/2016/owncloud/</link>
      <pubDate>Tue, 05 Apr 2016 10:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/owncloud/</guid>
      <description>So I set this up a while ago, but thought I&amp;rsquo;d share it here anyway. I was looking to find a self hosted dropbox/google drive alternative. As I am starting down the path of getting things self hosted, so my data is still my data and all that. There were 2 choices with this, that would run on the raspberrypi: Owncloud, or seafile
Seafile looked nice, and the core of it is written in C, so to me that would work well on the pi as it would be super lightweight and fast.</description>
      <content> &lt;p&gt;So I set this up a while ago, but thought I&amp;rsquo;d share it here anyway. I was looking to find a self hosted dropbox/google drive alternative. As I am starting down the path of getting things self hosted, so my data is still my data and all that. There were 2 choices with this, that would run on the raspberrypi: Owncloud, or seafile&lt;/p&gt;

&lt;p&gt;Seafile looked nice, and the core of it is written in C, so to me that would work well on the pi as it would be super lightweight and fast. I went for this originally, but had major issues trying to set it up for remote access&lt;/p&gt;

&lt;p&gt;Thats where &lt;a href=&#34;https://owncloud.org&#34; target=&#34;_blank&#34;&gt;Owncloud&lt;/a&gt; came to save that day! its written in php (my fav) so was super simple to setup, and get working for remote access. It was also easy to get it working on a external hard drive if need be.&lt;/p&gt;

&lt;p&gt;Another cool thing about it is that there a many &amp;ldquo;Apps&amp;rdquo; to go with it, so you can turn a simple file sync and share service into something that can handle your calendar, notes, passwords, mail client, rss feed agregator. Replacing pretty much all your 3rd part services, all self hosted&lt;/p&gt;

&lt;p&gt;Follow &lt;a href=&#34;https://doc.owncloud.org/server/9.0/admin_manual/installation/&#34; target=&#34;_blank&#34;&gt;these&lt;/a&gt; to get things setup. There are alot of things you can do around security which these instructions go into. Basic setup includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;download and unpack&lt;/li&gt;
&lt;li&gt;change ownership of files to prefered user (www-data)&lt;/li&gt;
&lt;li&gt;create database for owncloud use&lt;/li&gt;
&lt;li&gt;Go to owncloud URL in a browser and follow the install wizard&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once setup, download the client where ever you like (mobile app, windows, mac, linux) and connect up to your instance.&lt;/p&gt;

&lt;p&gt;Some things to consider running this on a raspberry pi, it isn&amp;rsquo;t exactly powerful enough to be able to browse images or anything too heavy via the webclient (or the mobile client for that matter, as it downloads things as needed) But it is perfectly fine if you have a few clients hooked up and let things sync in the background. I have 3gb of photo&amp;rsquo;s up on mine and have auto-upload enabled on the mobile client and everything syncs nicely between my 2 PC&amp;rsquo;s and laptop. I also use &lt;a href=&#34;http://www.qownnotes.org&#34; target=&#34;_blank&#34;&gt;QOwnNotes&lt;/a&gt; to sync my markdown notes around my devices.&lt;/p&gt;

&lt;p&gt;The plan will be to merge everything into Owncloud, my password management, RSS feed agregator and calendar (move away from feedly, google calendar and 1password) so all my things are actually owned by me! More on those when they happen&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Multi room audio with raspberry pi</title>
      <link>https://www.mrwhal3.com/2016/multi-room-audio-with-raspberry-pi/</link>
      <pubDate>Sun, 17 Jan 2016 01:14:00 -0800</pubDate>
      
      <guid>https://www.mrwhal3.com/2016/multi-room-audio-with-raspberry-pi/</guid>
      <description>So I&amp;rsquo;ve had a though for a while that I&amp;rsquo;d like something like Sonos in my home, but something like that is wayyyy out of my price range. Then I got thinking, surely opensource can do this!
I&amp;rsquo;ve just spent most of the day researching and setting up a solution. The first thing that came up was pulseaudio. This cool piece of software can do all sorts, and one of them being able to setup up a client-server like environment to stream audio from a pulseaudio &amp;ldquo;server&amp;rdquo; over multicast to any mpd &amp;ldquo;client&amp;rdquo; who is listening.</description>
      <content> &lt;p&gt;So I&amp;rsquo;ve had a though for a while that I&amp;rsquo;d like something like Sonos in my home, but something like that is wayyyy out of my price range. Then I got thinking, surely opensource can do this!&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve just spent most of the day researching and setting up a solution. The first thing that came up was pulseaudio. This cool piece of software can do all sorts, and one of them being able to setup up a client-server like environment to stream audio from a pulseaudio &amp;ldquo;server&amp;rdquo; over multicast to any mpd &amp;ldquo;client&amp;rdquo; who is listening. The theory behind this is you can set up multiple broadcast&amp;rsquo;s and have each device listening on different ones, plus all listening to on the same one. So you could stream to all devices, or to individual ones. The problem with this way (from what I could find) was that there was no easy, user friendly way to switch &amp;ldquo;zones&amp;rdquo; (broadcast addresses) on the server to play to different devices. This wouldn&amp;rsquo;t fly with the wife! Although this would be a nice, quick solution for most tech people&lt;/p&gt;

&lt;p&gt;I needed something that could be &amp;ldquo;user&amp;rdquo; friendly (super simple), that was easy to use, that would have an android and/or iOS app to control the server and that didn&amp;rsquo;t require much else then pushing a few buttons in an app to make it work. I eventually found mopidy (&lt;a href=&#34;https://www.mopidy.com/&#34; target=&#34;_blank&#34;&gt;https://www.mopidy.com/&lt;/a&gt;) I choose this as it ties into a few music streaming services, as I don&amp;rsquo;t have a large collection of local music, I listen mainly to spotify. It also has some nice apps available on Android, iOS and a web client, so controlling the server would be nice and simple. Hooking into this to allow for multi-room streaming I used snapcast (&lt;a href=&#34;https://github.com/badaix/snapcast&#34; target=&#34;_blank&#34;&gt;https://github.com/badaix/snapcast&lt;/a&gt;) a nice c# program to allow for client-server streaming with as many clients as you like. Unfortunately it doesn&amp;rsquo;t support &amp;ldquo;Zones&amp;rdquo; yet (which I originally wanted), but its on the todo list
As I have 3 rpi&amp;rsquo;s in my house, I will be using them as my audio clients, and server. I will be hooking one pi into my lounge surround sound, and have an old speaker system that I use in the Kitchen&lt;/p&gt;

&lt;p&gt;Hardware:
1x rpi 2 (as the server)
2 x rpi B (as the clients)
Speakers to plug into the &amp;ldquo;clients&amp;rdquo;&lt;/p&gt;

&lt;p&gt;For now I have just plugged everything into the 3.5&amp;rdquo; jack on the rpi, but I have read alot that the quality of this sound is terrible (I didn&amp;rsquo;t notice too much in my tests) and that getting a USB audio device would be a much better idea. So maybe when I start noticing quality, that will be the first thing to check&lt;/p&gt;

&lt;p&gt;Software:
mopidy
snapcast&lt;/p&gt;

&lt;p&gt;Installing mopidy was a breeze, just followed their instructions on their wiki (&lt;a href=&#34;https://docs.mopidy.com/en/latest/installation/raspberrypi/&#34; target=&#34;_blank&#34;&gt;https://docs.mopidy.com/en/latest/installation/raspberrypi/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Install the spotify plugin&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install mopidy-spotify&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once I got to snapcast, it needed a few dependencies, which rasbian (wheezy) didn&amp;rsquo;t care for. It was running older versions of the software needed and it didnt look like I could update it easily, so I bit the bullet and upgraded to Jessie&lt;/p&gt;

&lt;p&gt;This took ages! most of my time was spent waiting around for it to download and build, it probably would have been quicker to download the Jessie iso, re-flash the SD card and re-install everything. But once it was done, installing it was easy, and setup was even easier&lt;/p&gt;

&lt;p&gt;Just start mopidy on the server&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;mopidy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and start the server portion of snapcast&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo snapserver -d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and start the client portion of snapcast on your streaming client&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo snapclient -d
&lt;span style=&#34;color:#75715e&#34;&gt;#(or `sudo service snapclient start` . I had issues with running via \&lt;/span&gt;
     &lt;span style=&#34;color:#75715e&#34;&gt;#init.d and found it easier to start the service with the snapclient command)#&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then control your mopidy server with your favourite method (mine was android app) and magic!&lt;/p&gt;

&lt;p&gt;I haven&amp;rsquo;t included the commands yet, so maybe i&amp;rsquo;ll add them if i can run &lt;code&gt;history&lt;/code&gt; on my pi
Hope this helps someone, as finding an opensource/cheap solution for this was harder then I thought!&lt;/p&gt;

&lt;p&gt;Here are some other alternatives you can use too, especially if most of your collection of music is locally stored:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Squeezebox (&lt;a href=&#34;http://monksoundworks.blogspot.com.au/2014/03/raspberry-pi-multi-room-audio-solved.html&#34; target=&#34;_blank&#34;&gt;http://monksoundworks.blogspot.com.au/2014/03/raspberry-pi-multi-room-audio-solved.html&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Volumio - &lt;a href=&#34;http://volumio.org/&#34; target=&#34;_blank&#34;&gt;http://volumio.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Pi music Box - (pretty much a nice GUI ontop of mopidy) &lt;a href=&#34;http://www.pimusicbox.com/&#34; target=&#34;_blank&#34;&gt;http://www.pimusicbox.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As I was writing this, I found this - &lt;a href=&#34;https://github.com/thaytan/aurena&#34; target=&#34;_blank&#34;&gt;https://github.com/thaytan/aurena&lt;/a&gt;.  Seems very cool as it already supports &amp;ldquo;Zones&amp;rdquo; I will see if it ties  into modipy or streaming services!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>screen recording with annotation on Linux</title>
      <link>https://www.mrwhal3.com/2015/screen-recording-with-annotation-on-linux/</link>
      <pubDate>Sun, 13 Dec 2015 19:14:00 -0800</pubDate>
      
      <guid>https://www.mrwhal3.com/2015/screen-recording-with-annotation-on-linux/</guid>
      <description>So there&amp;rsquo;s been a few occasions where I have needed to do a screen record on my Ubuntu laptop at work, and I was easily able to find RecordMyDesktop which is neat and simple desktop app that can get you on your way. The harder part was finding a program that could allow you to annotate while screen sharing. There are plenty of tools out there that allow you do annotate ontop of an already recorded video, but I wanted to be able to do it as I was recording.</description>
      <content> &lt;p&gt;So there&amp;rsquo;s been a few occasions where I have needed to do a screen record on my Ubuntu laptop at work, and I was easily able to find &lt;a href=&#34;http://recordmydesktop.sourceforge.net/about.php&#34; target=&#34;_blank&#34;&gt;RecordMyDesktop&lt;/a&gt; which is neat and simple desktop app that can get you on your way. The harder part was finding a program that could allow you to annotate while screen sharing. There are plenty of tools out there that allow you do annotate ontop of an already recorded video, but I wanted to be able to do it as I was recording. I found a few tools like compiz annotate function (but this only worked with ubuntu desktop, not GNOME)&lt;/p&gt;

&lt;p&gt;This is when I came across &lt;a href=&#34;https://github.com/bk138/gromit-mpx&#34; target=&#34;_blank&#34;&gt;gromit-mpx&lt;/a&gt;. Follow the instructions on the github page and you&amp;rsquo;re good to go. You can start up gromit-mpx and then start a screen record with RecordMyDesktop and then you can annotate on your screen as you record, amazing right?&lt;/p&gt;

&lt;p&gt;Of course, everything is customisable so you can change the colour of the default pen, change the thickness of the pen and eraser and other cool things like that. Also, as you can see in the example I made, it draws &lt;em&gt;ontop&lt;/em&gt; of your screens, so when you move around (e.g go to a new webpage or bring another screen over what you are annotating on) things will stay there until you clear the screen (SHIFT+F9)&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>ffmpeg picture-in-picture</title>
      <link>https://www.mrwhal3.com/2015/ffmpeg-picture-in-picture/</link>
      <pubDate>Wed, 25 Nov 2015 14:28:00 -0800</pubDate>
      
      <guid>https://www.mrwhal3.com/2015/ffmpeg-picture-in-picture/</guid>
      <description>So just a quick one. I needed to create a video that has Picture in Picture. So we could have a video of the presentation, inside a recording of the slides used. Usually I would use Adobe premier pro for this, but as I have Ubuntu installed on my laptop, I though of ffmpeg. It is much less resource intensive then the Adobe product, but of course its all command line, so you don&amp;rsquo;t get a pretty GUI to play with.</description>
      <content> &lt;p&gt;So just a quick one.
I needed to create a video that has Picture in Picture. So we could have a video of the presentation, inside a recording of the slides used. Usually I would use Adobe premier pro for this, but as I have Ubuntu installed on my laptop, I though of ffmpeg. It is much less resource intensive then the Adobe product, but of course its all command line, so you don&amp;rsquo;t get a pretty GUI to play with. Once you master ffmpeg, its an amazing and fast tool that can do pretty much manipulate any audio/visual that you need in any way you want&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;ffmpeg -i pip1.mp4 -i pip2.mp4 &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-filter_complex &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[1]scale=iw/4:ih/4 [pip]; [0][pip] \
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;overlay=main_w-overlay_w-250:main_h-overlay_h-100&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-b:v 50M -ar &lt;span style=&#34;color:#ae81ff&#34;&gt;44100&lt;/span&gt; &amp;lt;br /&amp;gt;-ab 192k -vcodec mpeg4 &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-acodec libmp3lame PIPoutput.mp4&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here  is a screen shot of what it accomplishes. It encodes it using mpeg4 for  video, and mp3 for audio and keeps the quality of the original video&amp;rsquo;s.  (this is just an example using 2 random videos I found)&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.mrwhal3.com/img/pip.png&#34; alt=&#34;pip with 2 videos&#34; title=&#34;PIP with 2 videos&#34; /&gt;&lt;/p&gt;

&lt;p&gt;If you adjust the bits &amp;ldquo;-overlay_w-&lt;strong&gt;250&lt;/strong&gt;&amp;rdquo; and &amp;ldquo;-overlay_h-&lt;strong&gt;100&lt;/strong&gt;&amp;rdquo; this is adjust the location of the pip relative to the bottom corner of the screen (I&amp;rsquo;m pretty sure)&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Livestreamer!</title>
      <link>https://www.mrwhal3.com/2015/livestreamer/</link>
      <pubDate>Wed, 25 Nov 2015 14:20:00 -0800</pubDate>
      
      <guid>https://www.mrwhal3.com/2015/livestreamer/</guid>
      <description>So there is an awesome command line tool out there called livestreamer. It&amp;rsquo;s awesome because you can use it to stream your favourite live things, via command line! No more watching it through a browser and have flash (or even just chrome) clogging up resources. Pretty cool huh?
Another cool thing it can do it save directly to file, so if you knew you couldn&amp;rsquo;t watch it while its live (say your at work) just stream straight to file and watch later</description>
      <content> &lt;p&gt;So there is an awesome command line tool out there called &lt;a href=&#34;http://docs.livestreamer.io/&#34; target=&#34;_blank&#34;&gt;livestreamer&lt;/a&gt;.  It&amp;rsquo;s awesome because you can use it to stream your favourite live  things, via command line! No more watching it through a browser and have  flash (or even just chrome) clogging up resources. Pretty cool huh?&lt;/p&gt;

&lt;p&gt;Another  cool thing it can do it save directly to file, so if you knew you  couldn&amp;rsquo;t watch it while its live (say your at work) just stream straight  to file and watch later&lt;/p&gt;

&lt;p&gt;I make this post because I use this quite a lot, and usually I specify the file name as stream &lt;strong&gt;.mp4&lt;/strong&gt;.  As I am no expert in video/audio file formats and codecs etc I had no  idea that streaming files have their own format. This was helpful as  when I was saving into the mp4 format, other tools I was using (&lt;a href=&#34;https://github.com/xat/castnow&#34; target=&#34;_blank&#34;&gt;castnow&lt;/a&gt;)  where having difficulties reading the file properly. It&amp;rsquo;s expecting an  mp4 but obviously it&amp;rsquo;s not an mp4 file. So the correct format to save a  hls stream to (as I mostly watch twitch, and this is the format of their  streams) is stream &lt;strong&gt;.ts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hope this helps someone else out too, as it took me ages to find this info. Buried deep in a git issue&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Controlling limitless LED lights from raspberry pi cli</title>
      <link>https://www.mrwhal3.com/2014/controlling-limitless-led-lights-from-raspberry-pi-cli/</link>
      <pubDate>Tue, 02 Dec 2014 17:33:00 -0800</pubDate>
      
      <guid>https://www.mrwhal3.com/2014/controlling-limitless-led-lights-from-raspberry-pi-cli/</guid>
      <description>So I was inspired yesterday to create a bash script in which I can control my limitlessLED lights from my raspberry pi (cli). I always have a ssh connection open to my pi while at work, and when I&amp;rsquo;m at home I always have a terminal windows open, and tinkering around. So I though, why not?
It&amp;rsquo;s still a work in progress at the moment, but basic functionality is there for now :)</description>
      <content> &lt;p&gt;So I was inspired yesterday to create a bash script in which I can control my limitlessLED lights from my raspberry pi (cli). I always have a ssh connection open to my pi while at work, and when I&amp;rsquo;m at home I always have a terminal windows open, and tinkering around. So I though, why not?&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s still a work in progress at the moment, but basic functionality is there for now :)&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/mrwhale/limitlessled-bash&#34; target=&#34;_blank&#34;&gt;https://github.com/mrwhale/limitlessled-bash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inspiration came from this guys: &lt;a href=&#34;http://smileytechadventures.blogspot.com.au/2013/07/control-limitless-led-from-linux-bash.html&#34; target=&#34;_blank&#34;&gt;http://smileytechadventures.blogspot.com.au/2013/07/control-limitless-led-from-linux-bash.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But it only did the white ones, and I have both RGBW and  White - So eventually you will be able to do everything from my script  (change colours, brightness etc)&lt;/p&gt;

&lt;p&gt;There is also a command-line program on the limitlessled website under the api section &lt;a href=&#34;http://www.limitlessled.com/dev/&#34; target=&#34;_blank&#34;&gt;http://www.limitlessled.com/dev/&lt;/a&gt;, but this only does the RGBW ones. It does include the source code, but its in C. So I didn&amp;rsquo;t particularly want to have to remember C from first year uni..So I decided with bash - its easy, and I know my way around it&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; Just found someone else&amp;rsquo;s work on the subject on github, has done a similar thing to smileytech, few more options, but still very simple. And hasn&amp;rsquo;t been updated for year now &lt;a href=&#34;https://github.com/danielfaulknor/limitless-php/blob/master/sendcmd.sh&#34; target=&#34;_blank&#34;&gt;https://github.com/danielfaulknor/limitless-php/blob/master/sendcmd.sh&lt;/a&gt;&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>command line utility to cast to chromecast</title>
      <link>https://www.mrwhal3.com/2014/command-line-utility-to-cast-to-chromecast/</link>
      <pubDate>Wed, 19 Nov 2014 21:08:00 -0800</pubDate>
      
      <guid>https://www.mrwhal3.com/2014/command-line-utility-to-cast-to-chromecast/</guid>
      <description>So just a quick one today, found an awesome command utility to be able to cast content to a chromecast! It does local content, content from the interwebs and can even stream torrents :O
https://github.com/xat/castnow
Kudos to old mate xat for this one
Unfortunately I haven&amp;rsquo;t been able to get it working from my raspberry pi yet :( Keep getting build errors when trying to install it via npm&amp;hellip; I will update once I finally figure it out</description>
      <content> &lt;p&gt;So just a quick one today, found an awesome command utility to be able to cast content to a chromecast! It does local content, content from the interwebs and can even stream torrents :O&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/xat/castnow&#34; target=&#34;_blank&#34;&gt;https://github.com/xat/castnow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kudos to old mate xat for this one&lt;/p&gt;

&lt;p&gt;&lt;del&gt;Unfortunately I haven&amp;rsquo;t been able to get it working from my raspberry pi yet :( Keep getting build errors when trying to install it via npm&amp;hellip;&lt;/del&gt; I will update once I finally figure it out&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;So I didn&amp;rsquo;t get it working on my raspberry pi&lt;/del&gt; , but I recently upgraded (not sure its the right word :P) to Ubuntu 14.04. I have always wanted to be running Linux as my main desktop environment, but as I am a heavy gamer, I couldn&amp;rsquo;t do it because all my favourite games (CS:GO) were only on Windows.&lt;/p&gt;

&lt;p&gt;But when I got the good news the other month that they had ported it over to Linux, I didn&amp;rsquo;t waste anytime. First I installed CentOS (big fan of the long term support, a guy I used to work with also worked on the earlier releases of this..) But I was having heaps of issues with drivers, and just generally being not nice, I sighed to myself and installed Ubuntu.&lt;/p&gt;

&lt;p&gt;And it just worked. No issues have come up, even managed to get WOL working (couldn&amp;rsquo;t get it working on Windows), and the only thing left to do now is get SLI working for my dual GTX 690&amp;rsquo;s&lt;/p&gt;

&lt;p&gt;Little bit off topic.. but I managed to easily get castnow installed on Ubuntu, and got it streaming youtube video and even torrents direct to my chromecast :D Pretty awesome stuff too. Next step is to plug my chromecast directly into power, so I can turn the TV on via the chromecast (TV is CEC compatible)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So good new everyone! After trolling the internet for a while, I finally found the missing piece to get castnow working from your raspberry pi. A post by &lt;a href=&#34;https://www.reddit.com/r/Chromecast/comments/2kzbms/castnow_a_commandline_chromecast_player/cmle5ax&#34; target=&#34;_blank&#34;&gt;Dudecalion on reddit&lt;/a&gt; shows that all I needed was a node version that was compatible with ARM (the one&amp;rsquo;s I tried from apt-get were old versions). So here are some instructions to get it working from your pi!&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt; wget http://nodejs.org/dist/v0.10.28/node-v0.10.28-linux-arm-pi.tar.gz

 tar -zxvf node-v0.10.28-linux-arm-pi.tar.gz
 cd node-v0.10.28-linux-arm-pi/bin

 sudo su

 PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PATH&lt;span style=&#34;color:#e6db74&#34;&gt;:/location/to/download/node-v0.10.28-linux-arm-pi/bin/&amp;#34;&lt;/span&gt;

 npm install -g castnow&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And now wait. install took around 5 minutes for me, with a few warnings. But once it was done, you can Profit! As said in the post, because the pi isn&amp;rsquo;t that powerful it probably won&amp;rsquo;t be able to handle transcoding on the fly, so best to just keep it to playing youtube video&amp;rsquo;s or local mp4&amp;rsquo;s (but will happily be proved wrong!)&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>delving into android apps</title>
      <link>https://www.mrwhal3.com/2014/delving-into-android-apps/</link>
      <pubDate>Tue, 14 Oct 2014 17:57:00 -0700</pubDate>
      
      <guid>https://www.mrwhal3.com/2014/delving-into-android-apps/</guid>
      <description>This one&amp;rsquo;s a bit off topic..
But from my last post, about LimitlessLED&amp;rsquo;s. The android app that they tell you to use from the play store (https://play.google.com/store/apps/details?id=com.lierda.wificontroller&amp;amp;hl=en) is functional, but terribly slow at starting up, and giving you access to your light. More often then not, my wife an I would find ourselves just using the physical light switch instead.
So Finally I found a pretty awesome app for controlling LED lights, (https://play.</description>
      <content> &lt;p&gt;This one&amp;rsquo;s a bit off topic..&lt;/p&gt;

&lt;p&gt;But from my last post, about LimitlessLED&amp;rsquo;s. The android app that they tell you to use from the play store (&lt;a href=&#34;https://play.google.com/store/apps/details?id=com.lierda.wificontroller&amp;amp;hl=en&#34; target=&#34;_blank&#34;&gt;https://play.google.com/store/apps/details?id=com.lierda.wificontroller&amp;amp;hl=en&lt;/a&gt;) is functional, but terribly slow at starting up, and giving you access to your light. More often then not, my wife an I would find ourselves just using the physical light switch instead.&lt;/p&gt;

&lt;p&gt;So Finally I found a pretty awesome app for controlling LED lights, (&lt;a href=&#34;https://play.google.com/store/apps/details?id=tv.piratemedia.lightcontroler&amp;amp;hl=en&#34; target=&#34;_blank&#34;&gt;https://play.google.com/store/apps/details?id=tv.piratemedia.lightcontroler&amp;amp;hl=en&lt;/a&gt;) and Eliot, being a good bloke, as made his code open source. This app is awesome as it starts up instantly AND is has a widget you can put on your lockscreen or on a page! Although, his app, out of the box, only controls the RGBW lights, but because I have both in my home (RGBW and dual white) I decided to have a go at developing an app that suits my need (well not so much developing, more just copying and editing other code :P )&lt;/p&gt;

&lt;p&gt;I took Eliot&amp;rsquo;s app code and, so far, I have modified it to control the white lights instead! I plan to make the app do both, but It wont be for another few weeks now, as I am in the final weeks of study at Uni.&lt;/p&gt;

&lt;p&gt;Let me know if anyone&amp;rsquo;s interested in the app, and I&amp;rsquo;ll post the .apk and source code up on github, and if I&amp;rsquo;m really keen, put it up on the play store.&lt;/p&gt;

&lt;p&gt;But big thanks to Eliot for making his code open source!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Ninja Block!</title>
      <link>https://www.mrwhal3.com/2014/ninja-block/</link>
      <pubDate>Tue, 16 Sep 2014 19:34:00 -0700</pubDate>
      
      <guid>https://www.mrwhal3.com/2014/ninja-block/</guid>
      <description>My next major purchase was a Ninja Block for the Raspberry pi. I bought this ages ago, but never got around to writing about it! http://shop.ninjablocks.com/pages/picrust
I thought this was cool as it was a low cost way to start my home automation projects, and it is definitely marketed at the hobbiest, and I would not recommend this one for commercial use. Check out there NinjaSphere, which is aimed at plug n play users.</description>
      <content> &lt;p&gt;My next major purchase was a Ninja Block for the Raspberry pi. I bought this ages ago, but never got around to writing about it! &lt;a href=&#34;http://shop.ninjablocks.com/pages/picrust&#34; target=&#34;_blank&#34;&gt;http://shop.ninjablocks.com/pages/picrust&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I thought this was cool as it was a low cost way to start my home automation projects, and it is definitely marketed at the hobbiest, and I would not recommend this one for commercial use. Check out there NinjaSphere, which is aimed at plug n play users. Ninja Block requires a bit of tinkering, having to manually install modules and knowing some NodeJS would be extremely helpful.&lt;/p&gt;

&lt;p&gt;So with this purchase I got a wireless door sensor, and temperature sensor and a wireless button. These were pretty simple to setup, and now when someone rings the doorbell it SMS&amp;rsquo;s me instead of making a chime :)&lt;/p&gt;

&lt;p&gt;Not long ago, I kitted my house out with the &lt;a href=&#34;http://www.limitlessled.com/&#34; target=&#34;_blank&#34;&gt;LimitLessLED&lt;/a&gt; lights that can be controlled by the ninjablock, which I thought was pretty cool. It was a bit of an investment to replace most of the lights with these wifi lights, but well worth it :)&lt;/p&gt;

&lt;p&gt;Installing this with the ninja block took a little bit of time, had to check the forums and fiddle around a bit, but most of it was just point and click setup. But once setup it was pretty cool. I have set up some rules to automatically turn the lights on in the morning, and off after we have both left for work. I have set up a rule to turn the lights on when the back door is open (so when my wife gets home from work everything is on) This was nice and handy for winter, as it was already starting to get dark when we get home. But now that its staying lighter for longer, this isn&amp;rsquo;t really useful anymore.&lt;/p&gt;

&lt;p&gt;Next plan is to buy a IP camera, so the ninjablock can monitor my front door, so when the doorbell is rung, it sends me a picture of who is at the door. So stay tuned for that tutorial when I finally get around it it!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Temperature Sensing with the Pi</title>
      <link>https://www.mrwhal3.com/2014/temperature-sensing-with-the-pi/</link>
      <pubDate>Wed, 27 Aug 2014 22:00:00 -0700</pubDate>
      
      <guid>https://www.mrwhal3.com/2014/temperature-sensing-with-the-pi/</guid>
      <description>I ordered a couple of gadget for my pi a while ago, and they finally came in the mail ( only had to wait 2 months!) Anyways, I ordered a water-proof digital temperature sensor (DS18B20) and a ultrasonic range finder (HC-SR04) to play around with. So firstly I wanted to get the temperature sensor going. I followed the adafruit tutorial, just to hook the temp sensor to the pi (https://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware) Once it was physically connected, lets check if it works</description>
      <content> &lt;p&gt;I ordered a couple of gadget for my pi a while ago, and they finally came in the mail ( only had to wait 2 months!) Anyways, I ordered a water-proof digital temperature sensor (DS18B20) and a ultrasonic range finder (HC-SR04) to play around with.
So firstly I wanted to get the temperature sensor going. I followed the adafruit tutorial, just to hook the temp sensor to the pi (&lt;a href=&#34;https://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware&#34; target=&#34;_blank&#34;&gt;https://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware&lt;/a&gt;)
Once it was physically connected, lets check if it works&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd /sys/devices/w1_bus_master1/
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt; ls
&lt;span style=&#34;color:#ae81ff&#34;&gt;28&lt;/span&gt;-0000056e9afb w1_master_attempts w1_master_search
driver w1_master_max_slave_count w1_master_slave_count
power w1_master_name w1_master_slaves
subsystem w1_master_pointer w1_master_timeout
uevent w1_master_pullup
w1_master_add w1_master_remove
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There should be a listing under there that&amp;rsquo;s a whole bunch of numbers and letters (the devices ID). In my case it&amp;rsquo;s
28-0000056e9afb. &lt;code&gt;cd&lt;/code&gt; into this folder and &lt;code&gt;cat&lt;/code&gt; the file called &lt;code&gt;w1_slave&lt;/code&gt;
You should get output like so:&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;db &lt;span style=&#34;color:#ae81ff&#34;&gt;00&lt;/span&gt; 4b &lt;span style=&#34;color:#ae81ff&#34;&gt;46&lt;/span&gt; 7f ff &lt;span style=&#34;color:#ae81ff&#34;&gt;05&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt; 1a : crc&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1a YES
db &lt;span style=&#34;color:#ae81ff&#34;&gt;00&lt;/span&gt; 4b &lt;span style=&#34;color:#ae81ff&#34;&gt;46&lt;/span&gt; 7f ff &lt;span style=&#34;color:#ae81ff&#34;&gt;05&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt; 1a t&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13687&lt;/span&gt;
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first like is the checksum, to make sure the device is working correctly, and the second line is the temperature, in degree&amp;rsquo;s celcius, and to 3 decimal places (13687 = 13.687C)
Now we know the temp sensor is working alright, we can make a nice python script to read it and log it. For this project, I used:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://plot.ly/&#34; target=&#34;_blank&#34;&gt;plot.ly&lt;/a&gt;. All you need to do it create a free account and your good to go!&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.wunderground.com/?apiref=c9cf00c7dcaed623&#34; target=&#34;_blank&#34;&gt;weather underground&lt;/a&gt; You can create a free &amp;lsquo;dev&amp;rsquo; account which gives you 500 API calls a day (This is what I use, the way I have set it up, it will only ever call 288 a day)&lt;/li&gt;
&lt;li&gt;Bureau of Meteorology. I used this just so I could compare the temperature with wunderground
Both temperature gathering sites give out the data is JSON format, so it was easy enough to extract the data needed, and then pass it onto plot.ly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And here is the python script I used to do this! all you need to do is go through and add your API key for the various sites, and add your location (you may have to play around to find the correct location code for this one) I&amp;rsquo;ve also set it up to pull my plot.ly key and username out of a file called config.json. I did this because I have multiple scripts using it :)&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; os
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; glob
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; time
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; plotly.plotly &lt;span style=&#34;color:#f92672&#34;&gt;as&lt;/span&gt; py
&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; plotly.graph_objs &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; datetime
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; json
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; urllib2
&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; time &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; sleep, localtime, strftime
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; sys
&lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;./config.json&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; config_file:
    plotly_user_config &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;load(config_file)
py&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sign_in(plotly_user_config[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;plotly_username&amp;#34;&lt;/span&gt;], plotly_user_config[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;plotly_api_key&amp;#34;&lt;/span&gt;])
os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;system(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;modprobe w1-gpio&amp;#39;&lt;/span&gt;)
os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;system(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;modprobe w1-therm&amp;#39;&lt;/span&gt;)
base_dir &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/sys/bus/w1/devices/&amp;#39;&lt;/span&gt;
device_folder &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; glob&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;glob(base_dir &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;28*&amp;#39;&lt;/span&gt;)[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
device_file &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; device_folder &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/w1_slave&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;read_temp_raw&lt;/span&gt;():
    f &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; open(device_file, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;)
    lines &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;readlines()
    f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;close()
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; lines
&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;read_temp&lt;/span&gt;():
    lines &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; read_temp_raw()
    &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; lines[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip()[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;:] &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;YES&amp;#39;&lt;/span&gt;:
        time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sleep(&lt;span style=&#34;color:#ae81ff&#34;&gt;0.2&lt;/span&gt;)
        lines &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; read_temp_raw()
    equals_pos &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; lines[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;find(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;t=&amp;#39;&lt;/span&gt;)
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; equals_pos &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;:
        temp_string &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; lines[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;][equals_pos&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;:]
        temp_c2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; float(temp_string) &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1000.0&lt;/span&gt;
        temp_c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; round(temp_c2, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; temp_c
&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;read_pi_temp&lt;/span&gt;():
    file &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/sys/class/thermal/thermal_zone0/temp&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;)
    lines &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; file&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read()
    temp_c2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; float(lines) &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1000.0&lt;/span&gt;
    temp_cpi &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; round(temp_c2, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; temp_cpi

&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;read_temp_bom&lt;/span&gt;():
    f_bom &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; urllib2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;urlopen(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://www.bom.gov.au/fwo/IDV60901/IDV60901.94866.json&amp;#39;&lt;/span&gt;)
    json_string_bom &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; f_bom&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read()
    parsed_json_bom &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;loads(json_string_bom)
    temp_c_bom &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; parsed_json_bom[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;observations&amp;#39;&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;data&amp;#39;&lt;/span&gt;][&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;air_temp&amp;#39;&lt;/span&gt;]
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; temp_c_bom
&lt;span style=&#34;color:#75715e&#34;&gt;# Weather Underground key&lt;/span&gt;
wu_key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;APIKEY&amp;gt;&amp;#34;&lt;/span&gt;
wu_state &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Victoria&amp;#34;&lt;/span&gt;
wu_city &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Melbourne&amp;#34;&lt;/span&gt;
wu_retry &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_WUTemp&lt;/span&gt;(key, state, city, retries&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;):
        &lt;span style=&#34;color:#75715e&#34;&gt;#Get data from weather service&lt;/span&gt;
        &lt;span style=&#34;color:#75715e&#34;&gt;#If exception occurs, retry a few times then quit&lt;/span&gt;
        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; retry &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(retries):
                &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
                        f &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; urllib2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;urlopen(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://api.wunderground.com/api/&amp;#39;&lt;/span&gt; \
                        &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; key &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/geolookup/conditions/q/&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; state &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; \
                         city &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;.json&amp;#39;&lt;/span&gt;)
                        json_string &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read()
                        &lt;span style=&#34;color:#75715e&#34;&gt;#print json_string&lt;/span&gt;
                        parsed_json &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;loads(json_string)
                        location &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; parsed_json[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;location&amp;#39;&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;city&amp;#39;&lt;/span&gt;]
                        temp_c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; parsed_json[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;current_observation&amp;#39;&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;temp_c&amp;#39;&lt;/span&gt;]
                &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt;:
                        e &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;exc_info()[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
                        &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; (e)
                        temp_fc&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; None
                        sleep(&lt;span style=&#34;color:#ae81ff&#34;&gt;0.1&lt;/span&gt;)
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (f &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; None):
                f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;close()
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; temp_c
pitemp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; read_pi_temp()
series1 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Pi CPU Temp&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;x&amp;#39;&lt;/span&gt; : datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;now(),
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;y&amp;#39;&lt;/span&gt; : read_pi_temp(),
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;type&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;scatter&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mode&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;lines&amp;#39;&lt;/span&gt;}
series2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Room Temp&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;x&amp;#39;&lt;/span&gt; : datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;now(),
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;y&amp;#39;&lt;/span&gt; : read_temp(),
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;type&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;scatter&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mode&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;lines&amp;#39;&lt;/span&gt;}
series3 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Outdoor Temp (wunderground.com)&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;x&amp;#39;&lt;/span&gt; : datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;now(),
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;y&amp;#39;&lt;/span&gt; : get_WUTemp(wu_key, wu_state, wu_city),
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;type&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;scatter&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mode&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;lines&amp;#39;&lt;/span&gt;}
series4 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Outdoor Temp (bom.gov.au)&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;x&amp;#39;&lt;/span&gt; : datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;now(),
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;y&amp;#39;&lt;/span&gt; : read_temp_bom(),
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;type&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;scatter&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mode&amp;#39;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;lines&amp;#39;&lt;/span&gt;}
data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [series1, series3, series2, series4]
url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; py&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;plot(data,filename &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Rpi Room Temp Multi&amp;#39;&lt;/span&gt;, fileopt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;extend&amp;#39;&lt;/span&gt;)

 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Have Fun!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Flexget</title>
      <link>https://www.mrwhal3.com/2014/flexget/</link>
      <pubDate>Wed, 14 May 2014 21:17:00 -0700</pubDate>
      
      <guid>https://www.mrwhal3.com/2014/flexget/</guid>
      <description>A month or so ago, I was trying to figure out how to use eztv&amp;rsquo;s rss feed to automatically download new torrents to my pi. That&amp;rsquo;s when I ran across the awesome python program called flexget. (link here)With this you can specify the shows you like, and it will check for new episodes and add them to your torrent client for download. It does a lot more then this,but this is the main way I use it at the moment.</description>
      <content> &lt;p&gt;A month or so ago, I was trying to figure out how to use eztv&amp;rsquo;s rss feed to automatically download new torrents to my pi. That&amp;rsquo;s when I ran across the awesome python program called flexget. (link &lt;a href=&#34;http://flexget.com/&#34;&gt;here&lt;/a&gt;)With this you can specify the shows you like, and it will check for new episodes and add them to your torrent client for download. It does a lot more then this,but this is the main way I use it at the moment. So here&amp;rsquo;s some instructions on how I got it up and running on my raspberry pi
First you will need python 2.7 or later and pip (a package manager for python apps). I also use transmission as the torrent client, but there are others you can use&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install python
sudo apt-get install python-pip
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once python is installed and working, install flexget with pip&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt; sudo pip install flexget
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, you need to set up the config file for flexget. Create a folder called &lt;code&gt;.flexget&lt;/code&gt;in your home directory, then create a file called &lt;code&gt;config.yml&lt;/code&gt;(yes &lt;a href=&#34;http://en.wikipedia.org/wiki/YAML&#34; target=&#34;_blank&#34;&gt;yml&lt;/a&gt;, not xml) in that folder. This is the file that flexget will read by default when you run the command.&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd ~
mkdir .flexget
touch .flexget/config.yml
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Open up the config file in your fav editor, and you can use the contents of mine as an example, or check out the flexget wiki for other &amp;lsquo;recipes&amp;rsquo; and &lt;a href=&#34;http://flexget.com/wiki/Cookbook/Series&#34; target=&#34;_blank&#34;&gt;examples&lt;/a&gt;:)&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;vim .flexget/config.yml
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And here is the contents of my config.yml. Just need to set the quality you prefer, the path where you want them downloaded (mine is to my external hard drive) and your tranmission (or deluge) configuration (flexget can only hook into these two torrent programs at the moment)&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt; templates:
   tv:
     series:
       settings:
         tv:
           set:
             path: /mnt/usb/Torrents/Series/&lt;span style=&#34;color:#f92672&#34;&gt;{{&lt;/span&gt;series_name&lt;span style=&#34;color:#f92672&#34;&gt;}}&lt;/span&gt;
       tv:
         - The Big Bang Theory
         - Person of Interest
         - The Blacklist
         - Suits
         - Revolution &lt;span style=&#34;color:#ae81ff&#34;&gt;2012&lt;/span&gt;
         - Chicago Fire
         - Chicago PD
         - Grey&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;&lt;/span&gt;s Anatomy
         - Wonderland
         - Wonderland.AU
         - Royal Pains

     transmission:
       host: &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;.1.1.15
       port: &lt;span style=&#34;color:#ae81ff&#34;&gt;9091&lt;/span&gt;
       username: pi
       password:

     clean_transmission:
       host: &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;.1.1.15
       port: &lt;span style=&#34;color:#ae81ff&#34;&gt;9091&lt;/span&gt;
       username: pi
       password:
       finished_for: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; hours

   ShowRSS:
     priority: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
     rss: http://showrss.info/feeds/all.rss
     template: tv

 &lt;span style=&#34;color:#75715e&#34;&gt;#  kat-tv2:&lt;/span&gt;
 &lt;span style=&#34;color:#75715e&#34;&gt;#    priority: 1&lt;/span&gt;
 &lt;span style=&#34;color:#75715e&#34;&gt;#    rss: https://kickass.so/tv/?rss=1&lt;/span&gt;
 &lt;span style=&#34;color:#75715e&#34;&gt;#    template: tv&lt;/span&gt;
 &lt;span style=&#34;color:#75715e&#34;&gt;#    verify_ssl_certificates: no&lt;/span&gt;

 &lt;span style=&#34;color:#75715e&#34;&gt;#  thepiratebay.org-tv:&lt;/span&gt;
 &lt;span style=&#34;color:#75715e&#34;&gt;#    priority: 2&lt;/span&gt;
 &lt;span style=&#34;color:#75715e&#34;&gt;#    rss: http://rss.thepiratebay.org/208&lt;/span&gt;
 &lt;span style=&#34;color:#75715e&#34;&gt;#    template: tv&lt;/span&gt;
 &lt;span style=&#34;color:#75715e&#34;&gt;#    verify_ssl_certificates: no&lt;/span&gt;

 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As I use transmission as my torrent client, I can hook straight into it with flexget. The only downfall is the rpc password for transmission is in plain text in the config file.&lt;/p&gt;

&lt;p&gt;Anyways, now let&amp;rsquo;s run flexget for the first time (just as normal user). This will output if its succesfully added movies/tv shows to your torrent program, or it will check and output any errors in syntax in your config file (spacing has to be correct)&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;flexget execute

&lt;span style=&#34;color:#ae81ff&#34;&gt;014&lt;/span&gt;-05-15 &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;:03 VERBOSE details
bt-chat.com-tv Produced &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt; entries.2014-05-15 &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;:03 VERBOSE task
bt-chat.com-tv ACCEPTED: &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;Revolution.2012.S02E21.HDTV.x264-LOL.&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;eztv&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;.torrent&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;by series plugin because matches quality

&lt;span style=&#34;color:#ae81ff&#34;&gt;2014&lt;/span&gt;-05-15 &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;:03 VERBOSE task
bt-chat.com-tv ACCEPTED: &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;Person.of.Interest.S03E23.720p.HDTV.X264-DIMENSION.&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;eztv&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;.torrent&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt; by series plugin because matches quality
&lt;span style=&#34;color:#ae81ff&#34;&gt;2014&lt;/span&gt;-05-15 &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;:03 INFO   download   bt-chat.com-tv Downloading: &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;Revolution.2012.S02E21.HDTV.x264-LOL.&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;eztv&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;.torrent
&lt;span style=&#34;color:#ae81ff&#34;&gt;2014&lt;/span&gt;-05-15 &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;:04 INFO   download   bt-chat.com-tv Downloading: &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;Person.of.Interest.S03E23.720p.HDTV.X264-DIMENSION.&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;eztv&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;.torrent
&lt;span style=&#34;color:#ae81ff&#34;&gt;2014&lt;/span&gt;-05-15 &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;:04 VERBOSE details
bt-chat.com-tv Summary - Accepted: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;Rejected: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; Undecided: &lt;span style=&#34;color:#ae81ff&#34;&gt;38&lt;/span&gt; Failed: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that we know it&amp;rsquo;s working, add an entry into cron to run the command every hour&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt; crontab -e
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and add this line at the bottom&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; * * * * flexget execute
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you will never have to check for a new torrent manually again, just make the changes to &lt;code&gt;config.yml&lt;/code&gt; to add/remove shows movies you like!
Hope this is useful&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extra stuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I got this working a while ago, but forgot to add it to this post! I added the functionality so, after a torrent is completed, it will send you a pushbullet notification to your mobile (or where ever you want!)
1. So first you will need to sign up to pushbullet to get an access token (API key). Once logged in, click o the little pciture of you up the top right and go to &amp;ldquo;Account settings&amp;rdquo;. This page will list your access token for use later on
2. Next, intall it and login to it on your mobile. This will create a device in your account, and assign it a device id, for use in the script
3. Now lets find out the device id, run this command and save the device ID for your device&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;curl -u &amp;lt;your_access_token_here&amp;gt;: -X GET https://api.pushbullet.com/v2/devices
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now lets create a new script,&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;touch torrentdone.sh
chmod +x torrentdone.sh
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is what your script should look like:&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;apikey&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;lt;apikey&amp;gt;
deviceid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;lt;ID of device&amp;gt;

/usr/bin/curl https://api.pushbullet.com/v2/pushes &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt;-u $apikey: &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt;-d $deviceid &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt; -d type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;note &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt;-d title&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$TR_TORRENT_NAME&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  -d body&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$TR_TIME_LOCALTIME&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt;-X POST &amp;gt;&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we need to setup transmission to run this script on finishing a torrent&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd /etc/transmission-daemon/
sudo nano settings.json
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and modify this line to be:&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;script-torrent-done-filename&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/home/pi/torrentdone.sh&amp;#34;&lt;/span&gt;,
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;All done! Now, not only will all your torrents automatically download, you will be notified of them when they complete!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>3. File server</title>
      <link>https://www.mrwhal3.com/2014/3.-file-server/</link>
      <pubDate>Tue, 13 May 2014 19:10:00 -0700</pubDate>
      
      <guid>https://www.mrwhal3.com/2014/3.-file-server/</guid>
      <description>Now we have a webserver, torrent server (which is downloading all your torrents to an attached hard drive), I have set up a file server to serve the torrent folder to my windows computers in the house. This means I can plug my laptop in the TV, browse to the rpi, and play a show :). Here&amp;rsquo;s how I did so.
First you need to make sure you have samba installed</description>
      <content> &lt;p&gt;Now we have a webserver, torrent server (which is downloading all your torrents to an attached hard drive), I have set up a file server to serve the torrent folder to my windows computers in the house. This means I can plug my laptop in the TV, browse to the rpi, and play a show :). Here&amp;rsquo;s how I did so.&lt;/p&gt;

&lt;p&gt;First you need to make sure you have samba installed&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install samba&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I have made the share a public share with guests allowed ( so its not very secure ), but I like to think my wifi is secure enough to stop people from gaining access. That said, it doesn&amp;rsquo;t really matter if anyone can view the files, as I have set them to read only, and only people on the LAN can view them.&lt;/p&gt;

&lt;p&gt;Once Samba is installed, the next step is to add the shares you want to &lt;code&gt;smb.conf&lt;/code&gt;, located in &lt;code&gt;/etc/samba/&lt;/code&gt;. Below is a snippet of my &lt;code&gt;smb.conf&lt;/code&gt; file, showing the public share of the external hard drive attached to the pi, mounted at &lt;code&gt;/mnt/usb/&lt;/code&gt;&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;usb&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
comment &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; USB
path &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; /mnt/usb/Torrents
only guest &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Yes
read only &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Yes
browseable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Yes
public &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Yes&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I place this at the bottom of the file, leaving everything else as default. Just to make sure that everything is okay, I recommend running the tool &lt;code&gt;testparm&lt;/code&gt;. This will check your samba config file to make sure there are no errors.&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;testparm&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;if you get no errors, go ahead and start your server&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo service samba start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that samba is running, you can map that drive from any other device on your LAN. e.g from my windows pc, just map new network drive and put in the path &lt;code&gt;\\&amp;lt;ip of rpi&amp;gt;\usb&lt;/code&gt; and I can view all my downloads!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>2. Torrent server</title>
      <link>https://www.mrwhal3.com/2013/2.-torrent-server/</link>
      <pubDate>Tue, 12 Nov 2013 21:23:00 -0800</pubDate>
      
      <guid>https://www.mrwhal3.com/2013/2.-torrent-server/</guid>
      <description>So now all that your web server is up and running, and you have a Dynamic DNS name (if you chose to do that), here&amp;rsquo;s how I set up the torrent server on the pi (using transmission) credit goes to this website for helpful instructions. I also had a spare 500gb external harddrive (externally powered too) that I am using as storage for the downloads (I only have a 4gb SD for the pi) so instructions for setting this up, credit goes to this webiste</description>
      <content> &lt;p&gt;So now all that your web server is up and running, and you have a Dynamic DNS name (if you chose to do that), here&amp;rsquo;s how I set up the torrent server on the pi (using transmission) credit goes to &lt;a href=&#34;http://www.computeristas.com/wp/?p=98&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt; website for helpful instructions. I also had a spare 500gb external harddrive (externally powered too) that I am using as storage for the downloads (I only have a 4gb SD for the pi) so instructions for setting this up, credit goes to &lt;a href=&#34;http://rasspberrypi.wordpress.com/2012/09/04/mounting-and-unmounting-usb-drives-on-raspberry-pi/&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt; webiste&lt;/p&gt;

&lt;p&gt;First up, lets set up the hard drive on the pi. I tried the normal way of mounting the hard drive but I ran into the issue on the above link about the hard drive being mounted in read only, so lets just install some other programs to help us out&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install ntfs-3g&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once this is done, plug your hard drive in and power it on. to find out where your hard drive is located run&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo fdisk -l&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will give you output similar to this:&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;Disk /dev/mmcblk0: &lt;span style=&#34;color:#ae81ff&#34;&gt;3974&lt;/span&gt; MB, &lt;span style=&#34;color:#ae81ff&#34;&gt;3974103040&lt;/span&gt; bytes
&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt; heads, &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; sectors/track, &lt;span style=&#34;color:#ae81ff&#34;&gt;121280&lt;/span&gt; cylinders, total &lt;span style=&#34;color:#ae81ff&#34;&gt;7761920&lt;/span&gt; sectors
Units &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; sectors of &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; * 512 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
Sector size &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;logical/physical&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes / &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
I/O size &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;minimum/optimal&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes / &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
Disk identifier: 0x000c7b31

    Device Boot   Start     End   Blocks  Id System
/dev/mmcblk0p1      &lt;span style=&#34;color:#ae81ff&#34;&gt;8192&lt;/span&gt;   &lt;span style=&#34;color:#ae81ff&#34;&gt;122879&lt;/span&gt;    &lt;span style=&#34;color:#ae81ff&#34;&gt;57344&lt;/span&gt;  c W95 FAT32 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;LBA&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;/dev/mmcblk0p2     &lt;span style=&#34;color:#ae81ff&#34;&gt;122880&lt;/span&gt;   &lt;span style=&#34;color:#ae81ff&#34;&gt;7761919&lt;/span&gt;   &lt;span style=&#34;color:#ae81ff&#34;&gt;3819520&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;83&lt;/span&gt; Linux

Disk /dev/sda: &lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;.1 GB, &lt;span style=&#34;color:#ae81ff&#34;&gt;500107862016&lt;/span&gt; bytes
&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt; heads, &lt;span style=&#34;color:#ae81ff&#34;&gt;63&lt;/span&gt; sectors/track, &lt;span style=&#34;color:#ae81ff&#34;&gt;60801&lt;/span&gt; cylinders, total &lt;span style=&#34;color:#ae81ff&#34;&gt;976773168&lt;/span&gt; sectors
Units &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; sectors of &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; * 512 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
Sector size &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;logical/physical&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes / &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
I/O size &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;minimum/optimal&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes / &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; bytes
Disk identifier: 0x8d399bc0

 Device Boot   Start     End   Blocks  Id System
/dev/sda1       &lt;span style=&#34;color:#ae81ff&#34;&gt;63&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;976751999&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;488375968&lt;/span&gt;+  &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt; HPFS/NTFS/exFAT&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can see that my 500 gb hard drive is at the location /dev/sda from the output above. So before we mount it we need to make a folder to mount the hard drive in&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo mkdir /mnt/usb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we can mount the hard drive&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo mount /dev/sda1 /mnt/usb -t ntfs&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can check to see if its mounted with&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;df -h&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and you should see it in the list as /dev/sda1 mounted on /mnt/usb:&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;Filesystem   Size Used Avail Use% Mounted on
rootfs     &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;.6G &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;.1G &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;.4G &lt;span style=&#34;color:#ae81ff&#34;&gt;62&lt;/span&gt;% /
/dev/root    &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;.6G &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;.1G &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;.4G &lt;span style=&#34;color:#ae81ff&#34;&gt;62&lt;/span&gt;% /
devtmpfs    235M   &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; 235M  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;% /dev
tmpfs      49M 636K  48M  &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;% /run
tmpfs      &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;.0M   &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;.0M  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;% /run/lock
tmpfs      98M   &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  98M  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;% /run/shm
/dev/mmcblk0p1  56M  19M  38M &lt;span style=&#34;color:#ae81ff&#34;&gt;33&lt;/span&gt;% /boot
/dev/sda1    466G 215G 252G &lt;span style=&#34;color:#ae81ff&#34;&gt;47&lt;/span&gt;% /mnt/usb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I also made another folder on the hard drive&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd /mnt/usb
sudo mkdir torrents
sudo chmod &lt;span style=&#34;color:#ae81ff&#34;&gt;777&lt;/span&gt; torrents&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I give this folder full permissions ( its probably not best practice but I know it works when its like this..)&lt;/p&gt;

&lt;p&gt;So now we can get transmission server up and running, finally. Thanks to &lt;a href=&#34;http://www.computeristas.com/wp/?p=98&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt;guy for some helpful instructions to get our torrent server up and running&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install transmission-daemon&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We already set up a save folder previous at /mnt/usb/Torrents so I just used this for both complete and incomplete torrents (but you can make yourself another folder to store incomplete files in if you want). Now we customise the settings file&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo nano /etc/transmission-daemon/settings.json&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you can scan through and change the settings as desired (its pretty self explanatory) but here is a list of the setting I changed&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;download-dir&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/mnt/usb/Torrents&amp;#34;&lt;/span&gt;,
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;incomplete-dir&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/mnt/usb/Torrents/&amp;#34;&lt;/span&gt;,
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;incomplete-dir-enabled&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;,
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rpc-password&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;put desired password here&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rpc-username&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pi&amp;#34;&lt;/span&gt;,
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rpc-whitelist&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;127.0.0.1,*.*.*.*,192.168.*.*&amp;#34;&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The rpc-whitelist is there to give access to certain IP address&amp;rsquo;s to the web front-end of transmission. &lt;em&gt;.&lt;/em&gt;.&lt;em&gt;.&lt;/em&gt; gives access to the world, as I connect to the server with my phone while out and about to upload torrents and such. But you can restrict it to your local LAN/work IP&amp;rsquo;s or whatever you need. All the rest of the settings you can modify as needed to suit. Now we want to reload the server to save our settings&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo service transmission-daemon reload&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once this is done you can restart it as necessary, as explained on the above webpage, reloading it will save the config, but restarting it will override it&lt;/p&gt;

&lt;p&gt;You should now be able to access it through your x.x.x.x:9091 ( Mine is accessible at 192.168.0.5:9091 )&lt;/p&gt;

&lt;p&gt;So there&amp;rsquo;s also a nifty transmission android app that you can then remotely upload torrents to your server to download &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.neogb.rtac&#34; target=&#34;_blank&#34;&gt;https://play.google.com/store/apps/details?id=com.neogb.rtac&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last thing you need to do is forward the right ports out of your home router so you can access your pi over the internet. I have a netgear so there&amp;rsquo;s plenty of online guides on how to do it, it&amp;rsquo;s pretty straightforward though. you will need to forward on port 80, and 9091&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>1. Webserver</title>
      <link>https://www.mrwhal3.com/2013/1.-webserver/</link>
      <pubDate>Thu, 31 Oct 2013 16:07:00 -0700</pubDate>
      
      <guid>https://www.mrwhal3.com/2013/1.-webserver/</guid>
      <description>So the first thing I did was use this very helpful guide to help setup my pi as a LAMP server. I didn&amp;rsquo;t follow the whole thing, just the bits I needed.So following is the basics..firstly install apache
sudo apt-get install apache2 and then mysql
sudo apt-get install mysql-server And finally PHP
sudo apt-get install php5 sudo apt-get install php5-mysql Once this is done go to your pi&amp;rsquo;s IP address to make sure apache works</description>
      <content> &lt;p&gt;So the first thing I did was use &lt;a href=&#34;http://www.penguintutor.com/linux/raspberrypi-webserver&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt; very helpful guide to help setup my pi as a LAMP server. I didn&amp;rsquo;t follow the whole thing, just the bits I needed.So following is the basics..firstly install apache&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install apache2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
and then mysql&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install mysql-server&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And finally PHP&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install php5
sudo apt-get install php5-mysql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once this is done go to your pi&amp;rsquo;s IP address to make sure apache works&lt;/p&gt;

&lt;p&gt;Because I didn&amp;rsquo;t get a static IP from my ISP, it changes all the time (which is annoying) so I decided to get a dynamic DNS name for myself. I used www.noip.com and just got a free one.&lt;/p&gt;

&lt;p&gt;They also provide something called a DUC(dynamic update client) so your pi can talk to their servers and update the dns record if your ip address changesI found that on the pi it didn&amp;rsquo;t work with the apt-get install commands so follow the instructions half way down &lt;a href=&#34;https://www.noip.com/support/knowledgebase/installing-the-linux-dynamic-update-client-on-ubuntu/&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt; webpage to manually install it, once set up it will run in the background and tell the noip.com servers if you public IP address has changed&lt;/p&gt;

&lt;p&gt;Now for those who don&amp;rsquo;t want their pi to be linked to a url, I also wrote a small bash script that you can run with cron at whatever interval you want, that checks the current public IP to the previous IP and then emails you of it has changed. This is how I implemented it, with help from &lt;a href=&#34;http://www.sbprojects.com/projects/raspberrypi/exim4.php&#34; target=&#34;_blank&#34;&gt;this&lt;/a&gt; website to set up mail on the pi and link it with your gmail account. I used the SSMTP setup on that page.&lt;/p&gt;

&lt;p&gt;Once this is set up, create a file (doesn&amp;rsquo;t matter what it&amp;rsquo;s called, but i used ipaddy.sh), make sure to make it executable and open it with your favourite text editor&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;touch ipaddy
chmod +x ipaddy.sh
vim ipaddy.sh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and then paste in this script, entering your own email address&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;ip&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;curl icanhazip.com&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
line&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;head -n &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; ipaddress&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; $ip !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; $line &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;I have changed your home server ip to: &lt;/span&gt;$ip&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; | mail -s &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Shoppinglist.no-ip.org&amp;#34;&lt;/span&gt; &amp;lt;your_email_address&amp;gt;
    echo $ip &amp;gt; /home/pi/ipaddress
&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Close the text editor and create another file which will hold your public IP address&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;touch ipaddress
curl icanhazip.com &amp;gt; ipaddress&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is create a file and put your public IP address in it for use by the above script
Then we need to set up old mate cron to run the script when you want it, I have mine set to run the script every 30 minutes, but you can change it to whatever you like&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;crontab -e&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will open up the crontab for you to edit, go down the page a little until there&amp;rsquo;s some blank lines and paste this in:&lt;/p&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;*/30 * * * * /home/pi/ipaddy.sh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you are all set up with a webserver and a way to always know your IP address for when you aren&amp;rsquo;t at home!  The last thing you need to do is forward the right ports out of your home router so you can access your pi over the internet. I have a netgear so there&amp;rsquo;s plenty of online guides on how to do it, it&amp;rsquo;s pretty straightforward though&lt;/p&gt;

&lt;p&gt;Hope this is useful!&lt;/p&gt;
 </content>
    </item>
    
    <item>
      <title>Posts Archive</title>
      <link>https://www.mrwhal3.com/archive/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://www.mrwhal3.com/archive/</guid>
      <description></description>
      <content>  </content>
    </item>
    
  </channel>
</rss>