<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Iot Portal - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Iot Portal - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 23 Jun 2026 22:45:43 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/iot-portal/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Make an Amazing Looking Iot Dashboard in No Time ]]>
                </title>
                <description>
                    <![CDATA[ By Jared Wolff This post is originally from www.jaredwolff.com In this post, I’m going to show you how to get started with Grafana and InfluxDB. All of this running docker container on Digital Ocean.  That way you can have pretty graphs like these: ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-an-amazing-looking-iot-dashboard-in-no-time/</link>
                <guid isPermaLink="false">66d85050f20d0925f8515af7</guid>
                
                    <category>
                        <![CDATA[ iot ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Iot Portal ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 03 Jun 2019 21:17:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/Dashboard-3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jared Wolff</p>
<p><strong>This post is originally from <a target="_blank" href="https://www.jaredwolff.com/how-to-make-an-amazing-looking-iot-dashboard-in-no-time/">www.jaredwolff.com</a></strong></p>
<p>In this post, I’m going to show you how to get started with Grafana and InfluxDB. All of this running docker container on Digital Ocean. </p>
<p>That way you can have pretty graphs like these:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-05_at_12.55.10_PM.png" alt="IoT Dashboard" width="600" height="400" loading="lazy"></p>
<p>The cost?</p>
<p><strong>$5 a month</strong></p>
<p>Let’s get to it.</p>
<h2 id="heading-steps">Steps</h2>
<ol>
<li>Login to Digital Ocean. If you don’t have Digital Ocean and would like to support this blog click <a target="_blank" href="https://m.do.co/c/9574d3846a29">here</a> to create an account.</li>
<li>Go to <code>Account Settings</code> -&gt; <code>Security</code> and make sure you have an SSH key setup.
<img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-07_at_9.14.07_AM.png" alt="Screen_Shot_2019-05-07_at_9.14.07_AM" width="600" height="400" loading="lazy"></li>
<li>Create a new droplet use their <a target="_blank" href="https://marketplace.digitalocean.com/apps/docker">docker image</a></li>
<li>Make sure you select the $5 a month plan. For simple installs, this is more than enough!</li>
<li>SSH in once you’re done: <code>ssh root@&lt;yourserverip&gt;</code></li>
<li><p>Set up InfluxDB</p>
<pre><code>   docker run --rm -e INFLUXDB_HTTP_AUTH_ENABLED=<span class="hljs-literal">true</span> -e INFLUXDB_DB=particle -e INFLUXDB_ADMIN_ENABLED=<span class="hljs-literal">true</span> -e INFLUXDB_ADMIN_USER=admin -e INFLUXDB_USER=grafana -v influxdb:<span class="hljs-regexp">/var/</span>lib/influxdb influxdb /init-influxdb.sh
</code></pre><p>   Watch the output of this command. It will generate passwords for both your <code>admin</code> and <code>grafana</code> user. Save these in a safe place!</p>
</li>
<li><p>Start influx</p>
<pre><code>   docker run -d -p <span class="hljs-number">8086</span>:<span class="hljs-number">8086</span> \
         -v influxdb:<span class="hljs-regexp">/var/</span>lib/influxdb \
         -e INFLUXDB_HTTP_AUTH_ENABLED=<span class="hljs-literal">true</span> \
         influxdb
</code></pre></li>
<li><p>Add firewall rule</p>
<pre><code>   ufw allow <span class="hljs-number">8086</span>
</code></pre><p>   This allows the outside world to get to your InfluxDB instance.</p>
</li>
<li><p>Set up curl from Particle</p>
<p>   Example equivalent call:</p>
<pre><code>   curl -i -XPOST <span class="hljs-string">'http://&lt;DOCKER IP HERE&gt;:8086/write?db=particle'</span> --data-binary <span class="hljs-string">'temperature,id=&lt;ID HERE&gt; value=22.1'</span>
</code></pre><p>   The version of this to put in the <strong>custom request</strong> would be:</p>
<pre><code>   temperature,id={{{PARTICLE_DEVICE_ID}}} value={{{temperature}}}
</code></pre><p>   <img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-04_at_9.19.59_PM.png" alt="Screen_Shot_2019-05-04_at_9.19.59_PM" width="600" height="400" loading="lazy"></p>
<p>   <strong>Note:</strong>  see under <code>QUERY PARAMETERS</code> that <code>db</code> is pointing to <code>particle</code>. This should point to whatever you  set <code>INFLUXDB_DB</code> to in step 6</p>
<p>   <strong>Second Note:</strong> make sure that the username and password is the one you set up on step 6 as well. In this example the username is <code>grafana</code></p>
<p>   <img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-04_at_9.19.54_PM.png" alt="Screen_Shot_2019-05-04_at_9.19.54_PM" width="600" height="400" loading="lazy"></p>
<p>   Here’s a more complex version:</p>
<pre><code>   temperature,id={{{PARTICLE_DEVICE_ID}}} value={{{temperature}}}
   humidity,id={{{PARTICLE_DEVICE_ID}}} value={{{humidity}}}
   tvoc,id={{{PARTICLE_DEVICE_ID}}} value={{{tvoc}}}
   c02,id={{{PARTICLE_DEVICE_ID}}} value={{{c02}}}
   {{#pm25}}pm25,id={{{PARTICLE_DEVICE_ID}}} value={{{pm25}}}{{/pm25}}
   {{#pm10}}pm10,id={{{PARTICLE_DEVICE_ID}}} value={{{pm10}}}{{/pm10}}
   {{#sgp30_tvoc}}sgp30_tvoc,id={{{PARTICLE_DEVICE_ID}}} value={{{sgp30_tvoc}}}{{/sgp30_tvoc}}
   {{#sgp30_c02}}sgp30_c02,id={{{PARTICLE_DEVICE_ID}}} value={{{sgp30_c02}}}{{/sgp30_c02}}
   {{#bme680_pres}}bme680_pres,id={{{PARTICLE_DEVICE_ID}}} value={{{bme680_pres}}}{{/bme680_pres}}
   {{#bme680_iaq}}bme680_iaq,id={{{PARTICLE_DEVICE_ID}}} value={{{bme680_iaq}}}{{/bme680_iaq}}
   {{#bme680_temp_calc}}bme680_temp_calc,id={{{PARTICLE_DEVICE_ID}}} value={{{bme680_temp_calc}}}{{/bme680_temp_calc}}
   {{#bme680_hum_calc}}bme680_hum_calc,id={{{PARTICLE_DEVICE_ID}}} value={{{bme680_hum_calc}}}{{/bme680_hum_calc}}
</code></pre><p>   For conditional data you can wrap the whole line in the variable that may or may not be there:</p>
<pre><code>   {{#bme680_pres}}&lt;insert stuff related to bme680_pres&gt;{{/bme680_pres}}
</code></pre></li>
<li><p>Next! Install Grafana with persistent storage</p>
<pre><code>  # create a persistent volume <span class="hljs-keyword">for</span> your data <span class="hljs-keyword">in</span> /<span class="hljs-keyword">var</span>/lib/grafana (database and plugins)
  docker volume create grafana-storage

  # start grafana
  docker run \
    -d \
    -p <span class="hljs-number">3000</span>:<span class="hljs-number">3000</span> \
    --name=grafana \
    -v grafana-storage:<span class="hljs-regexp">/var/</span>lib/grafana \
    grafana/grafana
</code></pre></li>
<li><p>Add firewall rule for graphana</p>
<pre><code>    ufw allow <span class="hljs-number">3000</span>
    <span class="hljs-string">`</span>
</code></pre></li>
<li><p>Login. This should be your Digital Ocean Droplet ip + :3000 appended. Example: <code>123.456.789.101:3000</code> (Default username and password is <strong>admin</strong> and <strong>admin</strong>)</p>
</li>
<li><p>Connect Grafana to Influx (should be one of the first options on a fresh Grafana install)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-04_at_9.24.02_PM_copy.png" alt="Screen_Shot_2019-05-04_at_9.24.02_PM_copy" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-04_at_9.25.39_PM_copy.png" alt="Screen_Shot_2019-05-04_at_9.25.39_PM_copy" width="600" height="400" loading="lazy"></p>
<p><strong>Note</strong> under user, you’ll have to put the username <code>grafana</code> and the generated password from step 6. Also the name of the database has been set as <code>particle</code> in the same step.</p>
</li>
<li><p>Test your connection by clicking <code>Save &amp; Test</code> It should come back quickly saying whether or not a connection has been successful.</p>
</li>
<li><p>Start up your device, if not already, and get it publishing to your InfluxDB database.</p>
<p>(Need data? <a target="_blank" href="https://www.jaredwolff.com/homemade-indoor-air-quality-sensor/">This project should get you some!</a>)</p>
</li>
<li><p>Create graphs!</p>
<p>Finally, the reason why you came to this page: <strong>pretty graphs</strong></p>
<p>Click the <strong>+</strong> icon on the left and create a <strong>new dashboard</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-07_at_9.32.49_AM.png" alt="Screen_Shot_2019-05-07_at_9.32.49_AM" width="600" height="400" loading="lazy"></p>
</li>
<li><p>Select <code>Add Query</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-07_at_9.33.58_AM.png" alt="Screen_Shot_2019-05-07_at_9.33.58_AM" width="600" height="400" loading="lazy"></p>
</li>
<li><p>Go down and click <code>select measurement</code> If your device has been publishing to your database, you should see some options for values.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-07_at_9.34.32_AM.png" alt="Screen_Shot_2019-05-07_at_9.34.32_AM" width="600" height="400" loading="lazy"></p>
</li>
<li><p>Under <code>fill(null)</code> change that to <code>fill(none)</code>. That should give you a nice line between datapoints.</p>
</li>
<li>You should see the graph appear!
<img src="https://www.freecodecamp.org/news/content/images/2020/08/Screen_Shot_2019-05-07_at_9.36.36_AM.png" alt="Screen_Shot_2019-05-07_at_9.36.36_AM" width="600" height="400" loading="lazy"></li>
<li>Click the back arrow button and then click the save button.</li>
<li>You now created a simple graph on the data directly from your device! I recommend you play around with the Grafana interface. It's fairly intuitive and takes only a few short minutes to get used to!</li>
</ol>
<h2 id="heading-httpsssl">HTTPS/SSL</h2>
<p>Installing HTTPS/SSL is fairly straight forward. Follow the steps below:</p>
<ol>
<li>Stop the Grafana instance if you haven't already</li>
<li><p>Start a new container with <code>nginx-proxy</code></p>
<pre><code>docker run --detach \
    --name nginx-proxy \
    --publish <span class="hljs-number">80</span>:<span class="hljs-number">80</span> \
    --publish <span class="hljs-number">443</span>:<span class="hljs-number">443</span> \
    --volume /etc/nginx/certs \
    --volume /etc/nginx/vhost.d \
    —volume /usr/share/nginx/html \
    —volume /<span class="hljs-keyword">var</span>/run/docker.sock:<span class="hljs-regexp">/tmp/</span>docker.sock:ro \
    jwilder/nginx-proxy
</code></pre></li>
<li><p>Run the <code>letsencrypt-nginx-proxy-companion</code></p>
<pre><code>docker run —detach \
    —name nginx-proxy-letsencrypt \
    —volumes-<span class="hljs-keyword">from</span> nginx-proxy \
    —volume /<span class="hljs-keyword">var</span>/run/docker.sock:<span class="hljs-regexp">/var/</span>run/docker.sock:ro \
    jrcs/letsencrypt-nginx-proxy-companion
</code></pre></li>
<li><p>Restart the Grafana container</p>
<pre><code>docker run \
  -d \
    --env <span class="hljs-string">"VIRTUAL_HOST=&lt;YOUR SUBDOMAIN ADDRESS&gt;"</span> \
  --env <span class="hljs-string">"VIRTUAL_PORT=3000"</span> \
  --env <span class="hljs-string">"LETSENCRYPT_HOST=&lt;YOUR SUBDOMAIN ADDRESS&gt;"</span> \
  --env <span class="hljs-string">"LETSENCRYPT_EMAIL=&lt;YOUR EMAIL ADDRESS&gt;"</span> \
  --name=grafana \
  -v grafana-storage:<span class="hljs-regexp">/var/</span>lib/grafana \
  grafana/grafana
</code></pre><p><strong>Note:</strong> make sure you replace <code>&lt;YOUR SUBDOMAIN ADDRESS&gt;</code> and <code>&lt;YOUR EMAIL ADDRESS&gt;</code> above with your own info.</p>
</li>
</ol>
<p>The proxy companion will generate an SSL certificate for the virtual host that you provided to the Grafana container. The proxy is used to forward all HTTP/HTTPS traffic to your Grafana container. It's clean, it's simple and it's secure!</p>
<p><strong>Note</strong> InfluxDB is a bit more difficult. You either need to make a separate subdomain or configure HTTPS to share the certs between Grafana and Influx. This <a target="_blank" href="https://www.grzegorowski.com/grafana-with-lets-encrypt-ssl-on-docker/">Docker Compose script</a> does it all if you haven't already installed everything. You can follow the same steps above if you want to run it on a separate sub-domain.</p>
<h2 id="heading-handy-links">Handy Links</h2>
<p>Here are some handy links that I found useful getting started with Grafana + InfluxDB</p>
<ul>
<li><a target="_blank" href="https://docs.docker.com/samples/library/influxdb/">influxdb | Docker Documentation</a></li>
<li><a target="_blank" href="https://grafana.com/docs/guides/getting_started/">Getting Started | Grafana Documentation</a></li>
<li><a target="_blank" href="https://grafana.com/docs/installation/docker/">Installing using Docker | Grafana Documentation</a></li>
<li><a target="_blank" href="https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion/">Let's Encrypt Nginx Proxy Companion</a></li>
<li><a target="_blank" href="https://www.grzegorowski.com/grafana-with-lets-encrypt-ssl-on-docker/">Very Handy about Setting up HTTPS for both Grafana and Influx</a></li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You made it. Enjoy your new Grafana + InfluxDB install!</p>
<p>If you liked this tutorial, please share with your friends and your enemies. Also if you’re craving more, <a target="_blank" href="https://www.jaredwolff.com/homemade-indoor-air-quality-sensor/">check out how to build your own air quality sensor using only a few parts.</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to over-engineer a door lock ]]>
                </title>
                <description>
                    <![CDATA[ By Steven Chan My company’s Internet of Things (IoT) side project began when we couldn’t reset the door lock that we inherited from a previous tenant. It was one of those minor details we learned about after moving in to our new last-minute office. N... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-over-engineer-a-door-lock-863b5d58dd0d/</link>
                <guid isPermaLink="false">66c353cdbc39b1419091be74</guid>
                
                    <category>
                        <![CDATA[ Iot Portal ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud Solutions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iot ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Raspberry Pi ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 13 Jun 2017 20:26:38 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*TP9VbFU7DwDvY78ApjObtg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Steven Chan</p>
<p>My company’s Internet of Things (IoT) side project began when we couldn’t reset the door lock that we inherited from a previous tenant. It was one of those minor details we learned about after moving in to our new last-minute office.</p>
<p>Normally, people just pay for a new one. But our team was too cheap to replace the lock and no one ever wanted to get the door bell. Plus, we’re engineers and we wanted to fiddle with some hardware.</p>
<p>Our goal was to open the door with a phone or wearable technology. We had several options for how to approach the problem. In theory, we could use an app, an integration into another platform, or anything that could send a signal to trigger the door lock.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*ZMY8DHIrRVUYDOEm25cW-Q.jpeg" alt="Image" width="800" height="522" loading="lazy">
<em>Chima Open Door on Pebble and iOS</em></p>
<p>So far in our door lock experiment, we’ve developed solutions for a Slack integration, native iOS and Android apps, the Apple Watch, and Pebble. I’ll focus on the architecture of the mobile apps. I admit the final product is a bit over-engineered, but we just love it!</p>
<h3 id="heading-ios-and-android-architecture"><strong><em>iOS and Android architecture</em></strong></h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*_a0ivz5iXmx8CLBTWspoXg.png" alt="Image" width="800" height="166" loading="lazy">
<em>Our IoT door lock project’s architecture</em></p>
<p>What exactly happens when you press the button in our iOS / Android app? An HTTP request is sent to the cloud server, which then triggers a message to the door lock daemon via the client server, which then tells a relay board to open the door lock.   </p>
<p>Traditionally, the door lock is opened with a button beside the door. But with modern technology, the possibilities extend beyond a direct, physical button. In addition to the physical button that triggers the <code>Doorlock Daemon</code> in the diagram, we added two other triggers: a cloud-based trigger, and a Bluetooth Low Energy (BLE) trigger, thanks to our choice of hardware.  </p>
<p>This article focuses on the cloud-based trigger, which is what our door lock app depends on.</p>
<h3 id="heading-starting-from-pressing-the-button-to-a-record-saved-on-skygear-server">Starting from pressing the button to a record saved on Skygear server.</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Y_5ir6hlMnHyXWrMwLA3Vg.png" alt="Image" width="640" height="1136" loading="lazy"></p>
<p>When a user presses the open door button on the mobile app, the app accesses the cloud server.   </p>
<p>Two things happen in the cloud server. The first is that a record is saved to our choice of server, <a target="_blank" href="https://docs.skygear.io/guides/">Skygear Cloud Database</a>, which allows you to synchronize your data to the cloud. The server will log when the door access is being requested.</p>
<p>Once a record is saved, it would trigger an <code>after_save</code> function provided by <a target="_blank" href="https://docs.skygear.io/guides/">Skygear Cloud Functions</a>, which runs our code in the cloud without bothering server deployment.  </p>
<p>The <code>after_save</code> function is triggered after a record is saved. <code>def after_open_door_save(record, original_record, db):</code> is triggered asynchronously when a record of type <code>'OpenDoor'</code> is saved. The function publishes a message to the channel <code>'xxx-channel'</code>.</p>
<h3 id="heading-the-node-client-and-clojure-server-on-raspberry-pi">The Node Client and Clojure Server on Raspberry Pi</h3>
<p>The next step is to create a listener for the request. This is where the Node client and a Clojure server on Raspberry Pi come in. The Node client listens to the message in the specified channel on the Skygear server. The Clojure server is the only one with the right to access the Raspberry Pi 3 circuit. Then the Node client issues a request to the Clojure server once it hears any message.   </p>
<p>Here is the script for the Node client, which includes code related to our specific configuration for Skygear. The endpoint and the API Key are for accessing the main server on Skygear. <code>skygear.on('xxx-channel', onReceiveOpenDoor)</code> means to subscribe the function callback (<code>onReceiveOpenDoor</code>) on receiving a message on the <code>'xxx-channel'</code> channel.</p>
<p>The Clojure server directly controls General Purpose Input/Output (GPIO) on a Raspberry Pi. GPIO are the pins on the Raspberry Pi 3. The GPIO connects to the external circuit that is connected with the door magnet.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*d80-lFQeMHleoRI30NzgTA.png" alt="Image" width="800" height="834" loading="lazy"></p>
<p>Here is the Clojure code showing how the Raspberry Pi opens the door. Once the Clojure server receives the request from Node client, it will open the door and set it open for 3 seconds. However, if there is a new request coming in during that 3 seconds, the door will reset the timer to another 3 seconds. When the count down time is up, the door will lock again.</p>
<p>A random side note: Skygear is using AWS in America, while the door and the Raspberry Pi is in Hong Kong. Effectively, our ‘芝麻開門’ (Chima Open Door) request travels around the world before it reaches the door.</p>
<h3 id="heading-why-raspberry-pi">Why Raspberry Pi?</h3>
<p>Now, you may be wondering why we specifically chose Raspberry Pi. We considered using Arduino boards because we had them in the office. The reason we couldn’t use our specific Arduino model was because we wanted to synchronize data via Skygear JS SDK and this specific Arduino can’t set up the Node server.  </p>
<p> What’s more, Raspberry Pi is Bluetooth Low Energy ready (which means we could access the door lock using a third method, Bluetooth).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*2SCzzCP-Xf2OrwKvw4Zh1A.jpeg" alt="Image" width="507" height="676" loading="lazy">
<em>Linus-based Raspberry Pi is compatible with Oursky’s open-source serverless platform, Skygear</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*c47bsti5RIuXdrNrm1YbIA.jpeg" alt="Image" width="676" height="507" loading="lazy"></p>
<h3 id="heading-additional-integrations">Additional integrations</h3>
<p>Considering the app is internal-use only, we started a <a target="_blank" href="http://www.slack.com/">Slack</a> customized command <code>/chima-open-door</code> to open the door since every Ourskyer has access to <a target="_blank" href="http://www.slack.com/">Slack</a>.</p>
<p>Later some other Oursky colleagues got involved in this project and helped write the WatchOS app and Android app published on the internal platform. Apart from pressing the button inside the app, we also provide alternatives such as iOS 3D touch, Today extension, Android widget and even a Pebble integration because some of our developers use it.</p>
<p>That’s it! Before you dive in, there are two other main factors to consider: the reverse electricity flow (in this case for the Raspberry Pi) and the security of each of your integrations. For example, we also integrated Bluetooth app access with Bluetooth Low Energy (BLE), which has a self-implemented 2FA-like authentication. Other integrations you can include are notifications when the door is open (bell, LED).  </p>
<p> If you want to learn about any of the above, feel free to get in touch!</p>
<p><strong>Link to Repo / files</strong><br>Doorlock: <a target="_blank" href="https://github.com/oursky/doorlock">https://github.com/oursky/doorlock</a></p>
<p>I would like to credit my colleagues <a target="_blank" href="https://www.freecodecamp.org/news/how-to-over-engineer-a-door-lock-863b5d58dd0d/undefined">David Ng</a>, Boris (<a target="_blank" href="https://www.freecodecamp.org/news/how-to-over-engineer-a-door-lock-863b5d58dd0d/undefined">akiroz</a>), Brian (<a target="_blank" href="https://www.freecodecamp.org/news/how-to-over-engineer-a-door-lock-863b5d58dd0d/undefined">b壹貳參肆零零</a>), and <a target="_blank" href="https://www.freecodecamp.org/news/how-to-over-engineer-a-door-lock-863b5d58dd0d/undefined">May Yeung</a> for working on the Android application, the circuit implementation &amp; Clojure, Pebble application, and this blog piece respectively. Here’s to teamwork!</p>
<p>At Oursky we’re all about helping brands and entrepreneurs make their ideas happen, as well as fellow developers — our latest project Skygear (<a target="_blank" href="https://skygear.io">https://skygear.io</a>), an open source (<a target="_blank" href="https://github.com/skygeario">https://github.com/skygeario</a>) serverless platform for mobile, web &amp; IoT apps — helps you build better apps faster. ?</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
