<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wilhelm Erasmus</title>
    <description>The latest articles on DEV Community by Wilhelm Erasmus (@erasmuswill).</description>
    <link>https://dev.to/erasmuswill</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F124731%2F8ee70a57-8122-43e2-886d-57601e58f1c4.jpeg</url>
      <title>DEV Community: Wilhelm Erasmus</title>
      <link>https://dev.to/erasmuswill</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/erasmuswill"/>
    <language>en</language>
    <item>
      <title>The Case For EAS</title>
      <dc:creator>Wilhelm Erasmus</dc:creator>
      <pubDate>Wed, 17 Jan 2024 19:18:32 +0000</pubDate>
      <link>https://dev.to/erasmuswill/the-case-for-eas-1oa6</link>
      <guid>https://dev.to/erasmuswill/the-case-for-eas-1oa6</guid>
      <description>&lt;p&gt;In 2023, we are spoiled by all of the C/D technologies that surround us. The likes of Google Cloud Run and GitHub Copilot have made the one-click deployment dream a reality for anyone who is willing to invest a couple of minutes into setup. Unfortunately, the mobile app development space is still a seeming outlier to all this. I personally believe that cross-platform platforms are a bit magical. They work beautifully when they work but they can also behave in ways that seem very inconsistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile App Deployments
&lt;/h2&gt;

&lt;p&gt;Mobile App Deployments are a lot more complex than just chucking a SPA build folder into S3. As a result of installing a package on an end user's device, security of the package is vital. Due to this, digital signatures on app bundles are enforced. This in and of itself is the single most difficult part of the mobile app C/D workflow to solve. Just because XCode manages all the certificates on your behalf does not mean it will play nice when you want to run it on a server. As a testament to this, Stack Overflow and GitHub are littered with app build issues.&lt;/p&gt;

&lt;p&gt;Generally, if you are looking at automating app builds, you do not have many options. By and far the most popular option is Fastlane and for good reason. Unfortunately, Fastlane is still not a walk in the park. There is quite a lot of configuration that needs to be engineered and maintained&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Expo Application Services
&lt;/h2&gt;

&lt;p&gt;Imagine for a moment you open a React Native project to find the &lt;code&gt;android&lt;/code&gt; and &lt;code&gt;ios&lt;/code&gt; directories missing. For those unfamiliar with Expo, the lack of the easiest differentiator between a React SPA and a React Native project would set off alarm bells. &lt;em&gt;Is this the right project? Did someone ruin this project?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With Expo, this can be the norm. Expo Prebuilds mean that you do not even have to sacrifice the necessary evil of native changes; you simply write a quick plugin to reliably and repeatably apply the changes and next time you run a build, the native folders will be automatically generated and your changes applied. For anybody who has been through a React Native upgrade, this is a true godsend.&lt;/p&gt;

&lt;p&gt;Expo Application Services is what drives this Expo Build process. It automates key pain points for mobile developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;React Native upgrades become a simple package version change&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;App signing certificates can be fully managed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OTA Updates are handled seamlessly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;App builds can be run in the cloud or on your own infrastructure with a single command and minimal setup and configuration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have not tried Expo yet, give it a go!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Cloud Run</title>
      <dc:creator>Wilhelm Erasmus</dc:creator>
      <pubDate>Fri, 08 Sep 2023 00:35:51 +0000</pubDate>
      <link>https://dev.to/erasmuswill/cloud-run-4cco</link>
      <guid>https://dev.to/erasmuswill/cloud-run-4cco</guid>
      <description>&lt;h2&gt;
  
  
  The case for Cloud Run
&lt;/h2&gt;

&lt;p&gt;I'm sure by now you have heard the tales of the magical land called Kubernetes and all the benefits that come along with it. What may have slipped the cracks is the darker side of Kubernetes. Yes, I am referring to the proper maintenance and securing of a cluster, along with the laborious setup process. What if your app doesn't have enough moving parts to warrant all of that effort? Thanks to Cloud Run, you are not stuck with Elastic Beanstalk any more!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Cloud Run?
&lt;/h2&gt;

&lt;p&gt;According to Google's documentation,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cloud Run is a managed compute platform that lets you run containers directly on top of Google's scalable infrastructure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some of those phrases should sound familiar to anyone who has scanned through a Kubernetes walkthrough or quick-start. Google Cloud Run essentially allows you to have the core flexibility of Kubernetes combined with the scale of Google Cloud and best of all, this service allows scaling to zero, which is great for dev environments as well as apps that are infrequently used.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started
&lt;/h2&gt;

&lt;p&gt;Cloud Run makes it super simple to get started. I personally always use a Docker image and that is the route that I will describe here but there are language-defaults such as for &lt;a href="https://cloud.google.com/run/docs/quickstarts/build-and-deploy/deploy-nodejs-service"&gt;Node&lt;/a&gt; which can be used to steer clear of writing a Dockerfile. Once you have a Dockerfile written, just make sure that your service is accepting HTTP requests at &lt;code&gt;0.0.0.0:$PORT&lt;/code&gt; and you're off to the races. Head to &lt;a href="https://console.cloud.google.com/run"&gt;https://console.cloud.google.com/run&lt;/a&gt;, hit Create and link your GitHub repository. Did I mention that using this method also bundles Continuous Deployment with Google Cloud Builds with no extra effort?&lt;/p&gt;

&lt;h2&gt;
  
  
  Common pitfalls
&lt;/h2&gt;

&lt;p&gt;One of the only scary things about Google Cloud Run is runaway billing. There have been some examples of this in the past (&lt;a href="https://blog.tomilkieway.com/72k-1/"&gt;the unlucky guinea pig&lt;/a&gt;, &lt;a href="https://www.infoq.com/news/2022/08/recursive-serverless-functions/"&gt;meta article&lt;/a&gt;) and this, at least in theory, is very preventable by setting a reasonable maximum number of instances.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>cloud</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>Wifi-enabling a gate the complete way</title>
      <dc:creator>Wilhelm Erasmus</dc:creator>
      <pubDate>Mon, 20 Jul 2020 19:35:22 +0000</pubDate>
      <link>https://dev.to/erasmuswill/wifi-enabling-a-gate-the-complete-way-35b5</link>
      <guid>https://dev.to/erasmuswill/wifi-enabling-a-gate-the-complete-way-35b5</guid>
      <description>&lt;p&gt;I'm not sure if there are any Redditors out there on Dev, but if any of those that are are kind enough to click in, FTP, LTL :P&lt;/p&gt;

&lt;h1&gt;
  
  
  The why
&lt;/h1&gt;

&lt;p&gt;There are products on the market to automate gates. I especially like &lt;a href="https://www.remootio.com/"&gt;Remootio&lt;/a&gt;.&lt;br&gt;
I have however been yearning for some DIY electronics action so I took it upon myself to DIY something similar that could not only open and close my sliding gate, but what would tell me if the gate is open or closed.&lt;/p&gt;

&lt;h1&gt;
  
  
  The how
&lt;/h1&gt;

&lt;p&gt;I have a Centurion gate motor; they are a popular gate motor supplier in South Africa and they also have their own lineup of home automation products.&lt;/p&gt;

&lt;h1&gt;
  
  
  The content :)
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Initial concept
&lt;/h2&gt;

&lt;p&gt;I've had a simple eWeLink relay in the gate box for a while now, which can help me open and close it remotely. This is very useful when a courier decides to stop by as soon as I go out to the shops. The problem with this is that I have no way of verifying that the gate is actually closed after they leave, other than asking them. Two weeks ago, I noticed that my gate control board has a status LED output, which mirrors the Status LED on the control board itself. Upon some nerdy doc reading, I discovered that this light (and thus output), except for the obvious rudimentary error checking, also indicates the gate status as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open: Solid on&lt;/li&gt;
&lt;li&gt;Opening: flashing&lt;/li&gt;
&lt;li&gt;Closing: flashing&lt;/li&gt;
&lt;li&gt;Closed: off&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I immediately started looking for solutions as to how to use this somehow.&lt;/p&gt;

&lt;h2&gt;
  
  
  And action
&lt;/h2&gt;

&lt;p&gt;I recently flashed my first Sonoff board with ESPHome and I fell in love instantly. First off, it integrates into Home Assistant (I have it running in a cloud instance) with a single click and the YAML OTA is extremely convenient for updating the configuration.&lt;/p&gt;

&lt;p&gt;When dealing with the status light, one of my primary concerns was regarding how to check if the light is just flashing or whether its staying on or off. It's not ideal to watch a gate icon flash between open and closed for 30 seconds, wondering whether the gate is actually closing or not. I trawled ESPHome's documentation and eventually saw a line that made my heart skip a beat.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For example, you can measure if a status LED of a pool controller is permanently active (indicating that the pump is on) or blinking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It raised a couple of questions for me though, mostly regarding the time frame of the state checks. I decided to power through anyway and headed out to buy a NodeMCU dev board.&lt;/p&gt;

&lt;p&gt;The proof of concept worked flawlessly. I built a simple voltage divider with some resistors I had lying around and it actually worked. The final voltage was actually around 1V (3.3V logic) but it still seems to trigger it just fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The installation
&lt;/h2&gt;

&lt;p&gt;I headed out to my gate, armed with a NodeMCU hanging onto a breadboard for dear life, and started connecting it up. The dreaded moment of truth finally arrived, but instead of confirming my genius by spluttering to life, nothing happened. After a lot of troubleshooting, I finally figured out that my gate controller outputs about 16V on the 12V port! Not ideal for the cheap YwRobot board I had repurposed to deliver safe 3.3V to my NodeMCU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to the drawing board
&lt;/h2&gt;

&lt;p&gt;Not to be outdone by a simple voltage spike, I headed back to the interwebs in search of a better solution and there it was! A Sonoff SV.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u1TohLaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/38882cuh8r4frjezmrpy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u1TohLaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/38882cuh8r4frjezmrpy.jpg" alt="Sonoff SV" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Sonoff SV is a simple board which is designed to handle 5-24V; perfect for my rebellious gate controller. As an added bonus, it exposes 3 GPIO pins right on the board!&lt;/p&gt;

&lt;h2&gt;
  
  
  The installation v2
&lt;/h2&gt;

&lt;p&gt;It turns out that the Sonoff SV is intended to be used to power DC devices, but luckily, this specific board is extremely hacker-friendly.&lt;/p&gt;

&lt;p&gt;Pop out two relays and pretend to remove the jumper that wasn't included with my specific board and you now have a relay that is unpowered, perfect for triggering something. Of course there is a but though; there is always a but. The relay is unpowered but one of the two sides needs to be connected in order to complete the gate trigger circuit.&lt;/p&gt;

&lt;p&gt;Also, because I like doing things the right way, I busted out my soldering iron. Now, even calling my soldering skills decent is a pretty long shot, but I managed to bridge the gap and while I was at it I soldered a jumper wire onto the board (the relay inputs do not have headers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The aftermath
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gDOMfviZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/hfm7l3hbjs98vts6ek4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gDOMfviZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/hfm7l3hbjs98vts6ek4o.png" alt="HASS view of my gate device " width="513" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the time of writing this, ESPHome does not have the "gate" device class as per Home Assistant's documentation, but I have just submitted a PR to fix it :) &lt;a href="https://github.com/esphome/esphome/pull/1175"&gt;https://github.com/esphome/esphome/pull/1175&lt;/a&gt; (also my first contribution to ESPHome).&lt;/p&gt;

&lt;p&gt;Depending on how well this post does, I will show off my horrible soldering skills and I'll add some more information regarding how I installed it in the motor enclosure.&lt;/p&gt;

&lt;p&gt;Thanks for reading :)&lt;/p&gt;

</description>
      <category>hass</category>
      <category>homeautomation</category>
      <category>iot</category>
      <category>smarthome</category>
    </item>
  </channel>
</rss>
