<?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>Forem: Salted Bytes</title>
    <description>The latest articles on Forem by Salted Bytes (@salted-bytes).</description>
    <link>https://forem.com/salted-bytes</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%2Forganization%2Fprofile_image%2F960%2F3eb7fe42-c419-4f8b-b2e9-f7d33790a693.png</url>
      <title>Forem: Salted Bytes</title>
      <link>https://forem.com/salted-bytes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/salted-bytes"/>
    <language>en</language>
    <item>
      <title>Picking up Rust(y) habits: learning Rust as a JS developer</title>
      <dc:creator>Chris Quinn</dc:creator>
      <pubDate>Thu, 04 May 2023 04:16:35 +0000</pubDate>
      <link>https://forem.com/salted-bytes/picking-up-rusty-habits-learning-rust-as-a-js-developer-2dnj</link>
      <guid>https://forem.com/salted-bytes/picking-up-rusty-habits-learning-rust-as-a-js-developer-2dnj</guid>
      <description>&lt;p&gt;Do you work with Javascript? I do: let's first pour one out for all the idiosyncrasies of the language we know and love and acknowledge that for all its faults, the JS/TS ecosystem is &lt;em&gt;thriving&lt;/em&gt;: &lt;a href="https://2022.stateofjs.com/en-US/conclusion/" rel="noopener noreferrer"&gt;https://2022.stateofjs.com/en-US/conclusion/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While there's plenty of frameworks, micro-frontends and full-stack toolchains to master, there's something to be said for broadening your horizons. You may be wondering what other programming languages are worth learning, not least to expand your skills and improve your career prospects. &lt;/p&gt;

&lt;p&gt;I'm here to pitch one to you: &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;. Rust has gained a lot of popularity in recent years, let's explore why Rust is a good choice for Javascript developers to learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Rust?
&lt;/h2&gt;

&lt;p&gt;Rust is a systems programming language, originally developed at Mozilla as a personal project in 2006 by &lt;a href="https://twitter.com/graydon_pub" rel="noopener noreferrer"&gt;Graydon Hoare&lt;/a&gt;. It's designed to be a safe, fast, and concurrent language that can be used for a wide range of applications. Rust is particularly popular for developing low-level software, such as operating systems, device drivers, and web browsers. &lt;/p&gt;

&lt;p&gt;Yeah, that all sounds kinda dry, but how about this: Rust was named after a &lt;a href="https://en.wikipedia.org/wiki/Rust_(fungus)" rel="noopener noreferrer"&gt;hardy fungus&lt;/a&gt;, due to one of its primary strengths being the &lt;a href="https://en.wikipedia.org/wiki/Memory_safety" rel="noopener noreferrer"&gt;enforcement of memory safety&lt;/a&gt;. This is a key strength of the language, we'll come back to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should I learn Rust?
&lt;/h2&gt;

&lt;p&gt;Here are five reasons why Rust is a good choice for you to learn right now in 2023:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Performance and Safety
&lt;/h3&gt;

&lt;p&gt;One of Rust's primary advantages is its speed and safety. Rust is a compiled language, which means that code written in Rust is transformed into machine code that can be executed directly by a computer's CPU. This makes Rust much faster than interpreted languages like Javascript. Additionally, Rust has built-in memory safety features that prevent common programming errors, such as null or dangling pointer errors, which can cause crashes or security vulnerabilities. &lt;/p&gt;

&lt;p&gt;Hot take incoming: &lt;em&gt;This means that Rust code is much less likely to cause bugs or security vulnerabilities than Javascript.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Compatibility with WebAssembly
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://webassembly.org/" rel="noopener noreferrer"&gt;WebAssembly (WASM)&lt;/a&gt; is a low-level, portable bytecode format that is designed to be executed in web browsers. WASM allows developers to write high-performance code in languages other than Javascript and run them in the browser. Rust is an excellent language for writing code that can be compiled to WASM, meaning that you can write Rust code that can run directly in the browser, alongside or instead of Javascript. Check out this guide for the how and why: &lt;a href="https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Learning Rust can improve your Javascript skills
&lt;/h3&gt;

&lt;p&gt;Rust and Javascript are very different languages, but learning Rust can (albeit indirectly) improve your Javascript skills. Rust emphasizes the importance of code organization, strict typing and modularity - for me personally, I enjoyed being shaken out of my comfort zone by developing in Rust and making small, simple projects that allowed me to learn (and fail) and iterate quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Rust's growing popularity
&lt;/h3&gt;

&lt;p&gt;Rust is a relatively new language, but it has been rapidly growing in popularity over the past few years. Many large companies, such as Microsoft, Amazon, and Mozilla, have adopted Rust for in-house projects. Learning Rust now can put you in a good position to take advantage of the growing demand for Rust developers in the future. There are some projects that track programming language popularity such as the &lt;a href="https://www.tiobe.com/tiobe-index/" rel="noopener noreferrer"&gt;Tiobe index&lt;/a&gt;, which ranks Rust in the top 20 languages. &lt;/p&gt;

&lt;h3&gt;
  
  
  5. Have your cake and eat it
&lt;/h3&gt;

&lt;p&gt;OK, fine, you might not be ready to wholesale drop our beloved JS and jump ship entirely, I understand. But what if I told you that you can leverage all the power of Rust &lt;em&gt;within&lt;/em&gt; your Node projects? Let me introduce you to Neon: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://neon-bindings.com/" rel="noopener noreferrer"&gt;https://neon-bindings.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqi7dujazkn4s1x8y2w53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqi7dujazkn4s1x8y2w53.png" alt="Screenshot of the Neon Project homepage" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;Rust is a powerful and versatile language: its speed, safety, compatibility with WebAssembly, and growing popularity make it an excellent choice for Javascript developers to learn. &lt;/p&gt;

&lt;p&gt;Whether you're looking to improve your skills, build high-performance web applications, or explore new career opportunities, Rust is definitely worth checking out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.rust-lang.org/learn" rel="noopener noreferrer"&gt;https://www.rust-lang.org/learn&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/channel/UCaYhcUwRBNscFNUKTjgPFiA" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCaYhcUwRBNscFNUKTjgPFiA&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Meteor.js Bootstrap Project</title>
      <dc:creator>Chris Quinn</dc:creator>
      <pubDate>Mon, 08 Nov 2021 21:47:11 +0000</pubDate>
      <link>https://forem.com/salted-bytes/meteorjs-bootstrap-project-50eg</link>
      <guid>https://forem.com/salted-bytes/meteorjs-bootstrap-project-50eg</guid>
      <description>&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@ozgomz?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Oziel Gómez&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/boot?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over at &lt;a href="https://github.com/chrisquinnr/meteor-bootstrap" rel="noopener noreferrer"&gt;https://github.com/chrisquinnr/meteor-bootstrap&lt;/a&gt; you can find a quickstart app to get you up and running with a few Meteor basics, including accounts, routing, collections and adding a UI library like Bootstrap. &lt;/p&gt;

&lt;p&gt;We're using good old Blaze in this example but a shiny new Svelte version will be coming soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quickstart
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Get Meteor installed: &lt;a href="https://www.meteor.com/developers/install" rel="noopener noreferrer"&gt;https://www.meteor.com/developers/install&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Clone the &lt;a href="https://github.com/chrisquinnr/meteor-bootstrap" rel="noopener noreferrer"&gt;repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;meteor npm install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;meteor&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Meteor?
&lt;/h2&gt;

&lt;p&gt;Meteor has been making an awesome comeback over the past 18 months after the original development team moved on to new GraphQL-flavoured pastures. After being bought out by a VC firm, the project has picked up pace and as seen a renewed focus on addressing some of Meteor's roadmap.&lt;/p&gt;

&lt;p&gt;Meteor is full stack JS framework ideally suited to realtime applications. Its early advantages were zero-config websockets and ES6 that #justWorked, but now I find that it's a great tool for prototyping and building MVPs, since we not only get to leverage the wonders of NPM but also the framework lets you bring your own frontend. Blaze, React, Angular and now Svelte are all options.&lt;/p&gt;

&lt;p&gt;Like any framework, Meteor's benefits come at a price, in that you need to buy in to Meteor's highly opinionated structure and concepts. Fortunately these aren't too crazy and most of the rules can be broken if you want, but there are plenty of gotchas that will trip first time users up.&lt;/p&gt;

&lt;p&gt;Hopefully that's where this bootstrap project can help, getting you from zero to... something a little faster. I'm not suggesting this is a gold standard, and I'd recommend the resources below for the authoratative take on things like application structure and best practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;In suggested order of reading for anyone new to the framework.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://guide.meteor.com/" rel="noopener noreferrer"&gt;Meteor Guide&lt;/a&gt; - Read this first!&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meteor.com/developers/tutorials" rel="noopener noreferrer"&gt;Official Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.meteor.com/#/full/" rel="noopener noreferrer"&gt;Meteor API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you're up and running, why not check out the following?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://forums.meteor.com/" rel="noopener noreferrer"&gt;Forums&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrome.google.com/webstore/detail/meteor-devtools-evolved/ibniinmoafhgbifjojidlagmggecmpgf?hl=en" rel="noopener noreferrer"&gt;Meteor Devtools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://impact.meteor.com/" rel="noopener noreferrer"&gt;2021 Meteor Impact conference&lt;/a&gt;, with some great talks from the community and previews of upcoming features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you're hungry for more packages, examples and great community content, check these out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/urigo/awesome-meteor" rel="noopener noreferrer"&gt;Awesome Meteor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/arggh/awesome-blaze" rel="noopener noreferrer"&gt;Awesome Blaze&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Packages
&lt;/h2&gt;

&lt;p&gt;Over and above anything I've written below, you should check out the &lt;a href="https://github.com/Meteor-Community-Packages" rel="noopener noreferrer"&gt;Meteor Community Packages repo&lt;/a&gt;. This is a welcome new endeavour to bring awesome community-created modules under one roof.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling
&lt;/h3&gt;

&lt;p&gt;Ironically the first batch of packages this project depends on aren't Meteor specific, so won't be found in &lt;code&gt;.meteor/packages&lt;/code&gt;. We use &lt;code&gt;meteor npm install&lt;/code&gt; to add &lt;a href="https://getbootstrap.com/docs/5.1/getting-started/introduction/" rel="noopener noreferrer"&gt;Bootstrap&lt;/a&gt; and associated dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utility, Subscriptions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;underscore&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Currently only used for a simple randomise function, but I use it in most projects. Of course, you can replace this with [lodash] or any number of other helper libraries. Consider only importing the functions you use to avoid loading in the whole library (see &lt;a href="https://javascript.info/import-export" rel="noopener noreferrer"&gt;tree-shaking&lt;/a&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;meteorhacks:subs-manager&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;A very useful package for controlling how your application behaves based on when subscriptions are ready. I've used this package on several enterprise projects and it's well worth it.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;simple:reactive-method&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Meteor helpers are powerful, they allow you to reactively update your UI based on data mutations over the wire. Sometimes though, you need to listen for the result of a server-side operation. Meteor.call is not inherently reactive, meaning you'd need to continously poll the server for the result you want. Enter Reactive Methods, a neat solution to this issue. A reactive method can call any Meteor.method you've defined on the server and, if used in a Template helper, will update reactively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Routing &amp;amp; Templates
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;ostrio:flow-router-extra&lt;/em&gt; &amp;amp;&amp;amp; &lt;em&gt;mealsunite:flow-routing-extra&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;You'd be forgiven for being a little confused about the state of routing in Meteor. I know I was. The catch-all community-created solution for many years was Flow Router, which was thankfully picked up by Veliov Group (&lt;a href="https://github.com/veliovgroup" rel="noopener noreferrer"&gt;https://github.com/veliovgroup&lt;/a&gt;). It remains my choice too, but needs a little help from sibling packages to play nice with blaze layout below.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;kadira:blaze-layout&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;A neat way to declare and control layouts in conjunction with your routing solution, obviously for Blaze.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accounts
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;useraccounts:core&lt;/em&gt; / &lt;em&gt;&lt;a href="mailto:accounts-password@2.2.0"&gt;accounts-password@2.2.0&lt;/a&gt;&lt;/em&gt; / &lt;em&gt;useraccounts:bootstrap&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;The combination of these packages gives us user accounts, authentication and more straight out of the box! Awesome right! It's even extensible with other packages to add oAuth login providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Login splash screen
&lt;/h3&gt;

&lt;p&gt;I've added an artifical loading screen, just because, by delaying the result of a subscriptions listener, you can find this in &lt;code&gt;client/main.js&lt;/code&gt;. Usually logging in is pretty much instantaneous. On that note, the &lt;code&gt;accounts-password&lt;/code&gt; / &lt;code&gt;useraccounts:core&lt;/code&gt; packages are great, and completely extensible including social media login.&lt;/p&gt;

&lt;h3&gt;
  
  
  Twilio
&lt;/h3&gt;

&lt;p&gt;If you dig a little deeper I've added instructions for an SMS-based login handler using Twilio (this was the main motivation for building this project in the first place). You need to set up Twilio as noted in the comments in &lt;code&gt;/imports/api/apimethods/methods.js&lt;/code&gt; and then trigger the SMS using the provided Meteor method e.g. &lt;code&gt;Meteor.call("smsLogin");&lt;/code&gt;&lt;/p&gt;

</description>
      <category>meteor</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>bootstrap</category>
    </item>
    <item>
      <title>Essential terminal packages in 2020</title>
      <dc:creator>James G. Best</dc:creator>
      <pubDate>Fri, 26 Jun 2020 08:44:51 +0000</pubDate>
      <link>https://forem.com/salted-bytes/essential-terminal-packages-in-2020-2044</link>
      <guid>https://forem.com/salted-bytes/essential-terminal-packages-in-2020-2044</guid>
      <description>&lt;p&gt;This is the start of a new series about maximising your terminal experience. I will write about what I think are essential packages for the CLI, a simple but super effective Vim setup and setting some sane Tmux defaults.&lt;/p&gt;

&lt;p&gt;In this first article, I am going to list some of what I think are essential CLI packages. These are ones I use every day and could not live without. I am leaving Vim and Tmux off this list as they will get there own articles.&lt;/p&gt;

&lt;p&gt;I spend all my time in a terminal. This is where I do all my development, hacking and note-taking. Spending so much time there I want it to work for me, providing a buttery smooth experience.&lt;/p&gt;

&lt;p&gt;Here is a list of my top CLI packages.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. ZSH and oh-my-zsh:
&lt;/h2&gt;

&lt;p&gt;This is my chosen shell. It has way too many features to list here but here are a choice few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatic cd: Just type the name of the directory&lt;/li&gt;
&lt;li&gt;recursive path expansion: For example “/u/lo/b” expands to “/usr/local/bin”. This is not one I use much because I lead on the tools mentioned below.&lt;/li&gt;
&lt;li&gt;spelling correction and approximate completion: If you make a small mistake typing a directory name, ZSH will fix it for you&lt;/li&gt;
&lt;li&gt;plugin and theme support: ZSH includes many different plugin frameworks. This is where &lt;a href="https://ohmyz.sh/"&gt;&lt;code&gt;oh-my-zsh&lt;/code&gt;&lt;/a&gt; comings in. Its a community drive framework for managing your ZSH configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ASj89Tn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qu4zhdzhyv3y5sm2368g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ASj89Tn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qu4zhdzhyv3y5sm2368g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. FZF
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/junegunn/fzf"&gt;FZF&lt;/a&gt; is a command-line fuzzy finder. It is super fast, light and works so well with all my other tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kyJY52Yr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q69k9m86ffq0q7ufjwtg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kyJY52Yr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q69k9m86ffq0q7ufjwtg.png" alt="fzf"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. RipGrep (rg)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/BurntSushi/ripgrep"&gt;RipGrep&lt;/a&gt; is a stupid fast replacement for grep. It does away with lots of the hard to remember flags that grep requires. By default, it respects your &lt;code&gt;.gitignore&lt;/code&gt;, and skips hidden files.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Autojump
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/wting/autojump"&gt;Autojump&lt;/a&gt; is a super-fast way to navigate your filesystem. It learns the directories you visit most and remembers them for next time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qWk6jsbs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/44b496sqzhjxm9vc10yr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qWk6jsbs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/44b496sqzhjxm9vc10yr.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. HTTPie
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://httpie.org/"&gt;HTTPie&lt;/a&gt; is a user-friendly command line HTTP client. It has JSON support, syntax highlighting and lots more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AT1cNlzp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wegbwuy5eclnxvw94vi1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AT1cNlzp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wegbwuy5eclnxvw94vi1.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Bat
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sharkdp/bat"&gt;Bat&lt;/a&gt; is a drop-in replacement for &lt;code&gt;cat&lt;/code&gt; but with superpowers. It's highly configurable and supports syntax highlighting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wBiGyG3S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qep52k8t5oj9188vnxlw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wBiGyG3S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qep52k8t5oj9188vnxlw.png" alt="bat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. exa
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://the.exa.website/"&gt;exa&lt;/a&gt; is a modern replacement for &lt;code&gt;ls&lt;/code&gt;. It is highly configurable, provides better defaults.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N5QDVAll--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o5nsxhnbqq3y97fjhax8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N5QDVAll--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o5nsxhnbqq3y97fjhax8.png" alt="EXA"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. twf
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/wvanlint/twf"&gt;twf&lt;/a&gt; is a tree view explorer inspired by fzf.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uu5CiDt---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/60k07hhg7b8ew65u8luc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uu5CiDt---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/60k07hhg7b8ew65u8luc.png" alt="twf"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find my dotfiles &lt;a href="https://github.com/jim-at-jibba/my-dots"&gt;here&lt;/a&gt;. This is how I use them, how will you?&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for reading 🙏
&lt;/h1&gt;

&lt;p&gt;If there is anything I have missed, or if there is a better way to do something then please let me know.&lt;/p&gt;

&lt;p&gt;Check out our software focused podcast - &lt;a href="https://open.spotify.com/show/7IdlgpiDfYcOdCn57mPLvH?si=X1ArfHvqQXSOAfc1h7Y_Eg"&gt;Salted Bytes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>cli</category>
      <category>workflow</category>
    </item>
    <item>
      <title>Javascript robotics: The Johnny Five REPL</title>
      <dc:creator>James G. Best</dc:creator>
      <pubDate>Fri, 05 Jun 2020 06:54:27 +0000</pubDate>
      <link>https://forem.com/salted-bytes/javascript-robotic-the-johnny-five-repl-3kii</link>
      <guid>https://forem.com/salted-bytes/javascript-robotic-the-johnny-five-repl-3kii</guid>
      <description>&lt;p&gt;In the &lt;a href="https://jamesbest.tech/posts/wireless-javascript-robots-johhny-five-esp8266"&gt;previous article&lt;/a&gt;, we discussed how to get up and running with Johnny Five and the ESP8266 micro-controller. If you are not sure how to get set up I recommend you read that article first.&lt;/p&gt;

&lt;p&gt;Previously we created a simple script that allowed us to control the onboard LED with our keyboard. This required us to install the &lt;code&gt;keypress&lt;/code&gt; package and listen in &lt;code&gt;process.stdin&lt;/code&gt;. This is not a bad approach but there is a better one.&lt;/p&gt;

&lt;p&gt;Johnny Five comes packaged with a REPL. A REPL (read-eval-print-loop) is an interactive language shell giving a simple interactive interface to the Johnny Five API. We can control our robots with the REPL but there is some set up first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the REPL
&lt;/h2&gt;

&lt;p&gt;We need to make the REPL aware of our hardware by injecting the &lt;code&gt;instance&lt;/code&gt; of the hardware into our script. We are using the script from before but with the keyboard code stripped out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EtherPortClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;etherport-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Led&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Pin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;johnny-five&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;board&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EtherPortClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;192.168.1.109&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3030&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;repl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LED_PIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Board ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Led&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LED_PIN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, let's add the REPL code. Update the board ready callback to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*
    Initialize pin 2, which
    controls the built-in LED
  */&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Led&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LED_PIN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="cm"&gt;/*
    Injecting object into the REPL
    allow access while the program
    is running.

    Try these in the REPL:

    led.on();
    led.off();
    led.blink();

  */&lt;/span&gt;
  &lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;led&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;led&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this simple addition, we now have access to all the functions available on the LED object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limiting access
&lt;/h2&gt;

&lt;p&gt;But what if we don't want to give our users unfettered access? What if we only want to give access to specific functions or write functions that do more than just control the hardware. Maybe we want to add logging or provide more appropriate function names. Well, we can write our own functions that are available in the REPL and inject those instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*
    Initialize pin 2, which
    controls the built-in LED
  */&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Led&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LED_PIN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// Allow limited on/off control access to the&lt;/span&gt;
    &lt;span class="c1"&gt;// Led instance from the REPL.&lt;/span&gt;
    &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;off&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;off&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;flash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This script will make &lt;code&gt;on()&lt;/code&gt;, &lt;code&gt;off()&lt;/code&gt; and &lt;code&gt;flash()&lt;/code&gt; functions available in the REPL.&lt;/p&gt;

&lt;p&gt;And that is it. A nice, short intro to the Johnny Five REPL. Until you start hooking your scripts up to WebSockets or a REST API, I think this is one of the better ways to control your robots.&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for reading 🙏
&lt;/h1&gt;

&lt;p&gt;If there is anything I have missed, or if there is a better way to do something then please let me know.&lt;/p&gt;

&lt;p&gt;Check out our software-focused podcast - &lt;a href="https://open.spotify.com/show/7IdlgpiDfYcOdCn57mPLvH?si=X1ArfHvqQXSOAfc1h7Y_Eg"&gt;Salted Bytes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was originally posted on my &lt;a href="https://jamesbest.tech/posts/johhny-five-repl-esp8266"&gt;website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>robotics</category>
      <category>javascript</category>
      <category>esp8266</category>
    </item>
    <item>
      <title>Wireless javascript robotics with Johnny five and the ESP8266</title>
      <dc:creator>James G. Best</dc:creator>
      <pubDate>Fri, 29 May 2020 13:49:51 +0000</pubDate>
      <link>https://forem.com/salted-bytes/wireless-javascript-robotics-with-johnny-five-and-the-esp8266-al3</link>
      <guid>https://forem.com/salted-bytes/wireless-javascript-robotics-with-johnny-five-and-the-esp8266-al3</guid>
      <description>&lt;p&gt;Orignally post on my &lt;a href="https://jamesbest.tech/posts/wireless-javascript-robots-johhny-five-esp8266" rel="noopener noreferrer"&gt;website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I will talk about the first steps needed to start building robots with Javascript. I will be using the infamous &lt;a href="https://en.wikipedia.org/wiki/ESP8266" rel="noopener noreferrer"&gt;ESP8266 microcontroller&lt;/a&gt;, this is because it is super cheap and allows it not to be tethered to your machine in the way that an Arduino would be.&lt;/p&gt;

&lt;p&gt;To allow us to write our robotics scripts in Javascript with will be using the &lt;a href="http://johnny-five.io/" rel="noopener noreferrer"&gt;Johnny-Five&lt;/a&gt; library written by Rick Waldron. The library supports a huge selection of boards and hardware. Although not all boards support all of the hardware.&lt;/p&gt;

&lt;p&gt;Several other boards could be used as alternatives (Proton, Tessel) but these are considerable more expensive and not as easily available. It is also possible to use an Arduino attached to a Raspberry Pi (RPi) and you then interface wirelessly with the RPi but that seems a little unnecessary now.&lt;/p&gt;

&lt;p&gt;There are better languages to build robots with, but being an engineer working primarily in Javascript, I was keen to keep things close to home. In this setup Javascript is not run on the microcontroller but is run through some custom firmware called the Firmata protocol. This does mean it runs slower than something like C would but generally for things like robots this is not much of an issue. The first step in this process is to upload the &lt;code&gt;StandardFirmataWifi&lt;/code&gt; sketch onto our board but to be able to do that we need the Arduino IDE and for it to recognise our ESP8266 based boards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting set up
&lt;/h2&gt;

&lt;p&gt;The following instructions are based on using a mac. They will be very similar to other platforms.&lt;/p&gt;

&lt;p&gt;Copy the following URL &lt;code&gt;http://arduino.esp8266.com/stable/package_esp8266com_index.json&lt;/code&gt;. Open the IDE and go to the files menu and click on preferences. Add the URL to the ‘Additional Boards Manager URL’.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkse1am4utvc0l3d6qvtq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkse1am4utvc0l3d6qvtq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Close the preferences panel and click tools. Under tools select boards and then board manager. Navigate to esp8266 by esp8266 community and install the software for Arduino.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fve2uc93u9pv0g5ltovl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fve2uc93u9pv0g5ltovl8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once this has been done you should be able to program your ESP8266 based board, I am using the NodeMCU board.&lt;/p&gt;

&lt;p&gt;Click the examples panel and select the Wireless Firamta sketch. We will be updating so make a copy now.&lt;/p&gt;

&lt;p&gt;We need to update the header file &lt;code&gt;wifiConfig.h&lt;/code&gt; with our network credentials. Update the values of &lt;code&gt;char ssid[] =""&lt;/code&gt; and &lt;code&gt;char wpa_passphrase[] =""&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With this done we can now upload the sketch to our device. Once uploaded you can close the Arduino IDE.&lt;/p&gt;

&lt;p&gt;Don’t forget that the ESP* boards have a different pin layout to the Arduino boards. See the picture below for an example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw70lqyi0lx35o5c1oxnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw70lqyi0lx35o5c1oxnq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we are all set up on the microcontroller we need to create a new node project and install the needed packages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our first robot script
&lt;/h2&gt;

&lt;p&gt;Create a new folder for the project and initialise a new node project&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir helloWorld &amp;amp;&amp;amp; cd $_ &amp;amp;&amp;amp; npm init -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we need to install Johnny-Five and the ethernet client that allows us to connect wirelessly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install johnny-five ethernet-client keypress&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With this done we are set to write our first script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EtherPortClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;etherport-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Led&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Pin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;johnny-five&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keypress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keypress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;board&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EtherPortClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;192.168.1.109&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3030&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;repl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;keypress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LED_PIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Board ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Led&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LED_PIN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Use Up and Down arrows for On and Off. Space to stop.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEncoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRawMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keypress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;q&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Quitting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;up&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Blink&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;down&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Stop blinking&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to replace &lt;code&gt;10.0.0.49&lt;/code&gt; with the IP assigned to our board. I use an app called Fing but this information can be found out from the Serial monitor in the Arduino IDE.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv3tfhtekgmz5gxdfcgmi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv3tfhtekgmz5gxdfcgmi.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This simple script will make the allow you to turn the onboard led on and off. Nothing fancy but paves the way for much more exciting things. To execute the file &lt;code&gt;node index.js&lt;/code&gt;. You should see something similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;node hello.js
1590554783332 SerialPort Connecting to host:port: 192.168.1.109:3030
1590554783334 Connected Connecting to host:port: 192.168.1.109:3030
1590554793338 Use Up and Down arrows &lt;span class="k"&gt;for &lt;/span&gt;On and Off. Space to stop.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/IK3UvvmUzsc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Now that the board is set up we are ready to create some more interesting projects. Johnny Five provides such a gentle introduction to robotics in Javascript but allows you to do so much as you have the wealth of packages in NPM and hundreds of public APIs that you can lean on to create great projects.&lt;/p&gt;

&lt;p&gt;The next article will be a nice short one, introducing the Johnny Five repl and why it is great for prototyping your next project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for reading 🙏
&lt;/h1&gt;

&lt;p&gt;If there is anything I have missed, or if there is a better way to do something then please let me know.&lt;/p&gt;

&lt;p&gt;Check out our software focused podcast - &lt;a href="https://open.spotify.com/show/7IdlgpiDfYcOdCn57mPLvH?si=X1ArfHvqQXSOAfc1h7Y_Eg" rel="noopener noreferrer"&gt;Salted Bytes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>robotics</category>
      <category>javascript</category>
      <category>esp8266</category>
    </item>
    <item>
      <title>Fixing coc-tsserver errors due to Deno</title>
      <dc:creator>James G. Best</dc:creator>
      <pubDate>Thu, 28 May 2020 13:56:18 +0000</pubDate>
      <link>https://forem.com/salted-bytes/fixing-coc-tsserver-errors-due-to-deno-3omf</link>
      <guid>https://forem.com/salted-bytes/fixing-coc-tsserver-errors-due-to-deno-3omf</guid>
      <description>&lt;p&gt;This is a quick post detailing how to fix issues with &lt;a href="https://github.com/neoclide/coc-tsserver" rel="noopener noreferrer"&gt;&lt;code&gt;coc-tsserver&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am a long term Neovim user and feel that the only Intellisense engine to use is &lt;a href="https://github.com/neoclide/coc.nvim" rel="noopener noreferrer"&gt;CocVim&lt;/a&gt;. It is simply amazing. It breathes so much power into you Vim setup.&lt;/p&gt;

&lt;p&gt;I write Typescript daily and so use the &lt;a href="https://github.com/neoclide/coc-tsserver" rel="noopener noreferrer"&gt;&lt;code&gt;coc-tsserver&lt;/code&gt;&lt;/a&gt; plugin. It gives all the power of VSCodes typescript engine in NeoVim. But recently it broke. It was reporting errors when there was nothing wrong. I made sure all my dependencies we up to date and still nothing. All I was seeing was this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwu69wmoponwsq4sa118v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwu69wmoponwsq4sa118v.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The error message is: &lt;code&gt;The error message is: [tsserver 2307] [E] Cannot find module &amp;lt;import-path&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Something was wrong.&lt;/p&gt;

&lt;p&gt;Thankfully someone was having the same issue and had created an issue in the CocVim git repo. It turns out that there is a bug in the &lt;code&gt;coc-deno&lt;/code&gt; plugin that has some problems with non-deno projects.&lt;/p&gt;

&lt;p&gt;Thankfully the fix is simple. Disable the deno plugin for non deno projects.&lt;/p&gt;

&lt;p&gt;With in Vim: &lt;code&gt;:CocList extensions&lt;/code&gt; and find the Deno plugin. Press tab and select &lt;code&gt;d&lt;/code&gt; to disable it. Restart Vim and all your issues should have disappeared.&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for reading 🙏
&lt;/h1&gt;

&lt;p&gt;If there is anything I have missed, or if there is a better way to do something then please let me kno&lt;/p&gt;

</description>
      <category>vim</category>
      <category>productivity</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Time controlled colour schemes for Vim and Iterm2</title>
      <dc:creator>James G. Best</dc:creator>
      <pubDate>Tue, 26 May 2020 20:46:19 +0000</pubDate>
      <link>https://forem.com/salted-bytes/time-controlled-colours-schemes-for-vim-and-iterm2-1lmo</link>
      <guid>https://forem.com/salted-bytes/time-controlled-colours-schemes-for-vim-and-iterm2-1lmo</guid>
      <description>&lt;p&gt;&lt;em&gt;This was originally posted on my &lt;a href="https://jamesbest.tech/posts/control-vim-item-colour-schemes-by-time-day"&gt;own website&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you have read any of my other articles you will know that I live in a terminal. All my work is done in Iterm2, using NeoVim, Tmux and a multitude of other tools. You will probably also know that I have taken the time to get my terminal and Vim looking just how I like it. I have written a theme (&lt;a href="https://github.com/jim-at-jibba/ariake-vim-colors"&gt;Ariake&lt;/a&gt;) for both Iterm2 and Vim with light and dark variants.&lt;/p&gt;

&lt;p&gt;The reason for the light and dark variants are to help with working through the day into the evening. During the day I find it easier on the eyes to have a light theme. In the evening, a dark is better. But I would rarely remember to make the switch. I figured there must be a way to automate the process. It turned out to be pretty simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Vim
&lt;/h2&gt;

&lt;p&gt;The update to Vim was super simple. Simply add the following lines to your &lt;code&gt;init.vim&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"%H"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;17&lt;/span&gt;
  &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;light&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;dark&lt;/span&gt;
&lt;span class="k"&gt;endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This follows the 24hr clock so update the &lt;code&gt;17&lt;/code&gt; (5 pm) accordingly. I have mine change at around 5 pm. Now every time you openVim the time would be checked and the background colour updated accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Iterm2
&lt;/h2&gt;

&lt;p&gt;This was a little more involved but nothing to hard. Iterm2 gives the user access to a &lt;a href="https://www.iterm2.com/python-api/"&gt;Python API&lt;/a&gt;. With this, we have access to a huge array of functionality and so we can programmatically update it. In our case, we want to update the colour schema of our profile.&lt;/p&gt;

&lt;p&gt;From the menu select &lt;em&gt;Scripts &amp;gt; New Python Script&lt;/em&gt; and follow the wizard. It does not matter what you select as we are gonna replace the whole lot anyway. Once you have completed the wizard, open the script and replace the contents with the script below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3.7
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;iterm2&lt;/span&gt;

&lt;span class="c1"&gt;# Clock time to change colours.
&lt;/span&gt;&lt;span class="n"&gt;LIGHT_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;DARK_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Color presets to use
&lt;/span&gt;&lt;span class="n"&gt;LIGHT_PRESET_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ariake-light"&lt;/span&gt;
&lt;span class="n"&gt;DARK_PRESET_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ariake-dark"&lt;/span&gt;

&lt;span class="c1"&gt;# Profiles to update
&lt;/span&gt;&lt;span class="n"&gt;PROFILES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Ariake"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;datetime_after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;
    &lt;span class="c1"&gt;# Same time tomorrow
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;next_deadline_after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;light_deadline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime_after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LIGHT_TIME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;dark_deadline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime_after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DARK_TIME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"light {} dark {}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;light_deadline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dark_deadline&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;light_deadline&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;dark_deadline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LIGHT_PRESET_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;light_deadline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DARK_PRESET_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dark_deadline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_duration&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;preset_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deadline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next_deadline_after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deadline&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sleep for {} seconds until {}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preset_name&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_colors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preset_name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Change to preset {}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preset_name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;preset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;iterm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColorPreset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preset_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;iterm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PartialProfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;PROFILES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_set_color_preset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preset_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_duration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;set_colors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preset_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;iterm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run_forever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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



&lt;p&gt;The only things that need changing are marked with comments. I found the &lt;em&gt;script console&lt;/em&gt; handy for debugging the scripts. Once the script is complete you can activate it &lt;em&gt;Scripts &amp;gt; [you script name]&lt;/em&gt;. If you want it to run automatically, move the script to &lt;code&gt;$HOME/Library/ApplicationSupport/iTerm2/Scripts/AutoLaunch&lt;/code&gt;. You may need to create this folder.&lt;/p&gt;

&lt;p&gt;Now that the scripts are in place you should have a lovely self-changing development environment allowing you to code all day and night 😀.&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for reading 🙏
&lt;/h1&gt;

&lt;p&gt;If there is anything I have missed, or if there is a better way to do something then please let me know&lt;/p&gt;

</description>
      <category>vim</category>
      <category>productivity</category>
      <category>iterm2</category>
    </item>
    <item>
      <title>Avoiding that awkward BBC interview moment with Google Calendar, IFTTT, Tasker and a Raspberry Pi.</title>
      <dc:creator>James G. Best</dc:creator>
      <pubDate>Mon, 23 Mar 2020 17:13:35 +0000</pubDate>
      <link>https://forem.com/salted-bytes/avoiding-that-awkward-bbc-interview-moment-with-google-calendar-ifttt-tasker-and-a-raspberry-pi-605</link>
      <guid>https://forem.com/salted-bytes/avoiding-that-awkward-bbc-interview-moment-with-google-calendar-ifttt-tasker-and-a-raspberry-pi-605</guid>
      <description>&lt;p&gt;&lt;a href="https://i.giphy.com/media/ZdU3bTTc1WWStZM5lm/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ZdU3bTTc1WWStZM5lm/giphy.gif" alt="Interview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having experienced this in my first week of working at home I knew I needed a solution for letting my wife and kid know when I was going to be in a meeting/pair programming. I could just shout downstairs but where is the fun in that? By automating it, it is also one less thing to have to remember in what is shaping up to be a stressful time for everyone.&lt;/p&gt;

&lt;p&gt;I wanted this to be a quick Sunday evening project that only took a couple of hours so needed it to be simple and use the kit I already had. I also wanted it to work without the Raspberry Pi (RPi) being accessible from outside my home network.&lt;/p&gt;

&lt;p&gt;I could have completed this project in a much simpler way if I had allowed access to the RPi from the outside world but in a world where IoT devices are the target of cyber attacks I wanted to limit the exposure.&lt;/p&gt;

&lt;p&gt;On the hardware side of things, it seemed obvious to use an RPi and &lt;a href="https://shop.pimoroni.com/collections/mote"&gt;Mote&lt;/a&gt; LEDs. I have them already and they are simple to work with.&lt;/p&gt;

&lt;p&gt;Mote is a collection of components allowing you to easily work with LEDs. The visual side of this project could be anything you have knocking around. I just happened to have these.&lt;/p&gt;

&lt;p&gt;I am using an RPi 3 for this but you could any Pi that has is network connected.&lt;/p&gt;

&lt;p&gt;All my meetings are in Google Calendar so I just needed a way to trigger an event when my meetings start and finish. &lt;em&gt;If This Than That&lt;/em&gt; (IFTTT) is perfect for this. Google Calendar is the &lt;em&gt;THIS&lt;/em&gt; of IFTTT and a webhook is the &lt;em&gt;THAT&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I wanted this to be a quick project with as little programming as possible so I needed a way to accept the webhook but also be able to perform actions on a device in my local network. This part took a little longer to figure out, but a combination of &lt;a href="https://www.androidcentral.com/tasker"&gt;Tasker&lt;/a&gt; and &lt;a href="https://www.pocketables.com/2012/09/beginners-guide-to-tasker-part-6-autoremote.html"&gt;AutoRemote&lt;/a&gt; was able to perfectly meet my needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tasker&lt;/strong&gt; is an automation app that allows users to perform actions based on an event.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AutoRemote&lt;/strong&gt; allows devices to communicate with each other without any user interaction.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;N.B This article assumes some previous knowledge of Tasker and AutoRemote and so the instructions may be brief&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Tasker and AutoRemote are built to work with each other and so we can use AutoRemote as a way of triggering an action in Tasker. AutoRemote is available as a plugin in Tasker.&lt;/p&gt;

&lt;p&gt;AutoRemote acts as our "server" for the IFTTT webhook to callout to. When it receives a request, an event is triggered in Tasker which in turn sends a REST request to a local flask app that is running on the RPi. This Flask app controls the Mote LEDs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Tasker and AutoRemote
&lt;/h2&gt;

&lt;p&gt;In AutoRemote we need to register IFTTT as a device. Click the phone icon in the tab bar and then click the IFTTT logo and follow the instructions. This will give you a URL that can be added to the IFTTT webhook. It will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;https://autoremotejoaomgcd.appspot.com/sendmessage?key&lt;span class="o"&gt;=[&lt;/span&gt;&lt;span class="k"&gt;***&lt;/span&gt;yourKey&lt;span class="k"&gt;***&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&amp;amp;sender&lt;span class="o"&gt;=[&lt;/span&gt;&lt;span class="k"&gt;***&lt;/span&gt;yourId&lt;span class="k"&gt;***&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&amp;amp;message&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;IFTTT_MEETING_BUSY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;:&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice &lt;code&gt;message=IFTTT_MEETING_BUSY=:=true&lt;/code&gt; this is how we pass properties to AutoRemote. The left side of &lt;strong&gt;=:=&lt;/strong&gt; is how we can filter incoming requests and the right side are any params you want to pass in.&lt;/p&gt;

&lt;p&gt;With this set up we now need to trigger events in Tasker. Under the &lt;em&gt;profiles&lt;/em&gt; tab create a new one profile selecting &lt;em&gt;event -&amp;gt; plugin -&amp;gt; AutoRemote -&amp;gt; AutoRemote&lt;/em&gt;. Edit the configuration and add the name of the event (the left side of the request from IFTTT e.g IFTTT*MEETING_BUSY). Next, click back and add the action. In my case, I wanted to perform an HTTP request* to my RPi but there is a multitude of things that Tasker can do for you.&lt;/p&gt;

&lt;p&gt;Once set up your profiles will look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CrTloZbf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i7xyimaq0uv0vpnnpiys.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CrTloZbf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i7xyimaq0uv0vpnnpiys.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final step is setting up the local server to trigger the Mote lights. I wrote a really simple Flask app that listens to requests and calls the correct Mote methods. It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;motephat&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;make_response&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;motephat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;motephat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure_channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;#motephat.configure_channel(2, 16, False)
#motephat.configure_channel(3, 16, False)
#motephat.configure_channel(4, 16, False)
&lt;/span&gt;
&lt;span class="n"&gt;colour&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'FFFFFF'&lt;/span&gt;
&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mote_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;motephat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_pixel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;motephat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mote_off&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;motephat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;motephat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_status&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;motephat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_pixel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'hello'&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/mote/api/v1.0/&amp;lt;string:st&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;colour&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'on'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;mote_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;colour&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'off'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;mote_off&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'colour'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;colour&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errorhandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;not_found&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;make_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;'error'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'Not found'&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;mote_off&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'true'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'0.0.0.0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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



&lt;p&gt;Now when you are about to go into a meeting your lights should look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uleDWFWS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uyj69l2f29wecocywkmk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uleDWFWS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uyj69l2f29wecocywkmk.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this was of some interest. I really enjoy these little projects that have limited time and scope. Obviously, there are so many ways that this could be done and some many improvements that could be made but this was only meant to be a little bit of fun on a Sunday night.&lt;/p&gt;

</description>
      <category>remoteworking</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Rise of No-Code (dude, where's my code)</title>
      <dc:creator>Chris Quinn</dc:creator>
      <pubDate>Mon, 02 Mar 2020 20:49:12 +0000</pubDate>
      <link>https://forem.com/salted-bytes/the-rise-of-no-code-dude-where-s-my-code-5c7b</link>
      <guid>https://forem.com/salted-bytes/the-rise-of-no-code-dude-where-s-my-code-5c7b</guid>
      <description>&lt;p&gt;On the latest episode of Salted Bytes, James and I tore into a veritable buffet of no-code web development platforms. &lt;/p&gt;

&lt;p&gt;From Wix and Squarespace to Zapier via Google Sheets (did we just invent a new startup?), we talk about how no-code platforms provide much-needed glue between the myriad SaaS behemoths slugging it out for your time, attention and subscription dollars. But not everything is as rosy as some no-code proponents would say - we discuss some of the pitfalls of going all-in on no-code: anyone for some of that sweet vendor lock-in? &lt;/p&gt;

&lt;p&gt;No-code is a polarising topic and super popular here on dev.to (check out &lt;a href="https://dev.to/search?q=no-code"&gt;https://dev.to/search?q=no-code&lt;/a&gt;), but contrary to some of the views we've seen James &amp;amp; I think no-code has it's place in a thriving digital marketplace and actually empowers business / product owners to either raise their game or push for that little bit of extra innovation (as a treat).&lt;/p&gt;

&lt;p&gt;In researching this episode we found a whole bunch of super-salty takes on no-code from devs across the Twitterverse, from the thoughtful and considered to the downright savage - and we include them here for your pleasure. Enjoy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Holy Salt!
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fih39r5f0bkud0og697hu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fih39r5f0bkud0og697hu.png" alt="Alt Text" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How could you say something so brave and so true
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyeamjxlw51jz1h0q3e7h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyeamjxlw51jz1h0q3e7h.png" alt="How could you say something so brave and so true" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dadjoke.gif
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs8sdbm5rd3l495qowh3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs8sdbm5rd3l495qowh3v.png" alt="Dadjoke.gif" width="800" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  It is like cloud
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6xn2s75g5syemsitxo64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6xn2s75g5syemsitxo64.png" alt="It is like cloud" width="800" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Low-effort Twitter screencaps aside, we're really interested to see what the NextBigThing&lt;sup&gt;TM&lt;/sup&gt; in no-code is, and even more interested to see if no-code continues to be such a polarising topic... or whether one day it'll sink into the doldrums of every day office life, like Clippy and and that guy who writes Excel macros.&lt;/p&gt;

&lt;p&gt;James &amp;amp; I think no-code is a valuable part of the web dev ecosystem, and here to stay - what do you think? Why not check out our latest episode at the links below and let us know in the comments!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/salted-bytes-podcast"&gt;https://dev.to/salted-bytes-podcast&lt;/a&gt;&lt;br&gt;
&lt;a href="https://saltedbytes.rocks" rel="noopener noreferrer"&gt;https://saltedbytes.rocks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Till next time&lt;/p&gt;

&lt;p&gt;Chris&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>podcast</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What (not?) to do in your new tech role</title>
      <dc:creator>Chris Quinn</dc:creator>
      <pubDate>Fri, 07 Feb 2020 17:59:23 +0000</pubDate>
      <link>https://forem.com/salted-bytes/what-not-to-do-in-your-new-tech-role-1lgi</link>
      <guid>https://forem.com/salted-bytes/what-not-to-do-in-your-new-tech-role-1lgi</guid>
      <description>&lt;p&gt;Recently on the Salted Bytes podcast we discussed what to do (and NOT) to do in your first few days at a new dev role. &lt;/p&gt;

&lt;p&gt;Some of this advice was very applicable to most jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Get to know people"&lt;/li&gt;
&lt;li&gt;"Always join in the first few social events after you start"&lt;/li&gt;
&lt;li&gt;"Find and cherish your mentors"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For developers though, whether in your first role or your twentieth, we had  some very industry-specific tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't cling dogmatically to your old tooling or coding style&lt;/strong&gt; - it may be familiar but you need to learn the way things are done in your new place of work - it's very likely they've arrived at their stack for compelling reasons, which are worth hearing out, and respecting. One you've done that, if you still feel duty bound to evangelise your new colleagues on your perspective on tabs v space, go right ahead. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get to know people outside of your immediate team.&lt;/strong&gt; This can give you invaluable insight into your new role, either from top level strategy and culture or from the low to ground must know info like how the holiday calendar works and how to claim expenses. (most companies should absolutely cover this in your orientation, but let's be honest, it's not always thorough).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be curious, and ask the obvious question.&lt;/strong&gt; There's a great deal of pride, and conversely, imposter syndrome permeating software development. Don't be afraid to ask even the most humbling of questions: better now than 5 months down the line. There are myriad paths into development careers, not all of them computer-science based, and sometimes you'll encounter knowledge gaps that you didn't even know existed. Swallow that pride and ask the obvious question - clarity trumps assumption every day of the week. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;James &amp;amp; I covered more tips &amp;amp; tricks on the Salted Bytes podcast. Why not go check it out?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/salted-bytes-podcast"&gt;https://dev.to/salted-bytes-podcast&lt;/a&gt;&lt;br&gt;
&lt;a href="https://saltedbytes.rocks" rel="noopener noreferrer"&gt;https://saltedbytes.rocks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Till next time&lt;/p&gt;

&lt;p&gt;Chris&lt;/p&gt;

</description>
      <category>career</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A simple Elm, SCSS toolchain</title>
      <dc:creator>James G. Best</dc:creator>
      <pubDate>Mon, 28 Oct 2019 08:51:30 +0000</pubDate>
      <link>https://forem.com/salted-bytes/a-simple-elm-scss-toolchain-cbd</link>
      <guid>https://forem.com/salted-bytes/a-simple-elm-scss-toolchain-cbd</guid>
      <description>&lt;p&gt;Recently I have been knee deep in Typescript, React and Redux code. It is what I write every day at work and I love it! Typescript feels like one of those love hate things. You hate it until you try it and then you feel like writing Javascript without types is modern day savagery.&lt;/p&gt;

&lt;p&gt;One morning during my daily morning scroll through Twitter I found this &lt;a href="https://ohanhi.com/react-typescript-vs-elm.html"&gt;post&lt;/a&gt;. It talks about how if you use the stack I mentioned above (Typescript, React and Redux) that you would love &lt;a href="https://elm-lang.org/"&gt;Elm&lt;/a&gt;. I had looked at Elm before and although it interested me it never captured me enough to stick it out but this time I thought it might be different. This post is not about my journey into Elm as it is still in its infancy but about how I set up a simple project with Elm, SCSS and hot-reloading.&lt;/p&gt;

&lt;p&gt;This post is not about my journey into Elm as it is still in its infancy. I am gonna run through how I set up a simple project with Elm, SCSS and hot-reloading. I realise there are lots of boilerplates out there but many of them just do too much. I want to learn in a simple understandable environment but with the perks of using something like CRA (create-react-app).&lt;/p&gt;

&lt;p&gt;I required my starter package to do a few things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Compile Elm&lt;/li&gt;
&lt;li&gt;Compile SCSS&lt;/li&gt;
&lt;li&gt;Create a dev server and hot reload
I also wanted to stay away from the usual bundlers that we use in the JS world, like Webpack and Parcel. These tools are great but add a load of packages.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The project folder structure is as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--siQ5t3Q3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6dsvr5x0yt98ld4qk86a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--siQ5t3Q3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6dsvr5x0yt98ld4qk86a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is obviously personal taste, and this is how I like to set things up. SCSS folder structure is also personal taste but I use this as a &lt;a href="https://github.com/jim-at-jibba/grumpasaurus-scss"&gt;starting point&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Most of the action happens in the &lt;code&gt;package.json&lt;/code&gt;. We run and build our project with a number of &lt;strong&gt;npm scripts&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Elm
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Watching Elm
&lt;/h3&gt;

&lt;p&gt;The first task we are gonna cover is the compilation of our Elm code. We also need the compiler to be able to watch for changes and recompile. This is standard in JS projects these days and so why should it be any different in Elm. We are going to be using a file watcher called chokidar-cli. This is the same file watcher used in many of the most popular bundlers and task runners. First, let’s install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="c"&gt;# npm&lt;/span&gt;
 npm &lt;span class="nb"&gt;install&lt;/span&gt; — save-dev chokidar-cli

 &lt;span class="c"&gt;# yarn&lt;/span&gt;
 yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; chokidar-cli

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



&lt;p&gt;and then add the following to the scripts section of the &lt;strong&gt;package.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"watch:elm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chokidar './src/**/*.elm' -c 'elm make ./src/Main.elm — 
     output ./public/js/elm.compiled.js' — initial"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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



&lt;p&gt;Here we are using chokidar to watch for changes to any file matching this regex ./src/*&lt;em&gt;/&lt;/em&gt;.elm and then running the Elm make command &lt;code&gt;elm make ./src/Main.elm — output ./public/js/elm.compiled.js&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building Elm
&lt;/h3&gt;

&lt;p&gt;While we are dealing with Elm, let’s write the script to build the Elm project. This is very similar to the script above except we won’t use &lt;strong&gt;chokidar&lt;/strong&gt; as we are not watching for changes. We are also adding the &lt;code&gt;— optimize&lt;/code&gt; flag so that the js output is minified and optimised.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"build-elm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"elm make ./src/Main.elm — output 
     ./public/js/elm.compiled.js — optimize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  SCSS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Watching and building SCSS
&lt;/h3&gt;

&lt;p&gt;Next, we are gonna tackle watching and building our scss files. When watching we want the scss to recompile when changes are made. We will be using &lt;a href="https://www.npmjs.com/package/node-sass-chokidar"&gt;node-sass-chokidar&lt;/a&gt; for this. Let’s install the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="c"&gt;# npm&lt;/span&gt;
 npm &lt;span class="nb"&gt;install&lt;/span&gt; — save-dev node-sass-chokidar

 &lt;span class="c"&gt;# yarn&lt;/span&gt;
 yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; node-sass-chokidar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Dev server and hot reloading
&lt;/h2&gt;

&lt;p&gt;This would not be a serious modern frontend toolchain without a dev server and hot reloading. For this we are gonna use &lt;a href="https://www.browsersync.io/"&gt;browser-sync&lt;/a&gt;. Let’s install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="c"&gt;# npm&lt;/span&gt;
 npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; browser-sync

 &lt;span class="c"&gt;# yarn&lt;/span&gt;
 yarn global add browser-sync
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s add another script. This once will start a server and watch all files in our &lt;strong&gt;public&lt;/strong&gt; folder. Because the other watch scripts all compile into the public folder anytime we make any changes &lt;strong&gt;browser-sync&lt;/strong&gt; will detect them and restart the server and refresh the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"dev-server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"browser-sync start — server 'public' — files 
     'public/**/*.*'"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Tying it all together.
&lt;/h2&gt;

&lt;p&gt;Let’s tie it all together with a build and start script. For these, we want to be able to run multiple npm scripts at once. For this we will use one last package — &lt;a href="https://www.npmjs.com/package/npm-run-all"&gt;npm-run-all&lt;/a&gt;. This allows you to run scripts sequentially or in parallel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="c"&gt;# npm&lt;/span&gt;
 npm &lt;span class="nb"&gt;install&lt;/span&gt; — save-dev npm-run-all

 &lt;span class="c"&gt;# yarn&lt;/span&gt;
 yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; npm-run-all
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this installed we can write 2 final scripts. Let’s tackle the build script. We want to be able to compile both the scss and elm in a single command. All we do is pass the names on the scripts and we want them to run in parallel so we use the &lt;code&gt;-p&lt;/code&gt; flag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm-run-all -p build-css build-elm "&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The last script is the one we will use the most. This starts our dev server and compiles (with file watching) both the Elm and SCSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm-run-all -p watch-css watch:elm dev-server"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that is it. The complete scripts section should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm-run-all -p watch-css watch:elm dev-server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"watch:elm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chokidar './src/**/*.elm' -c 'elm make ./src/Main.elm -  
     output ./public/js/elm.compiled.js' - initial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"build-css"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node-sass-chokidar sass/ -o public/css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"watch-css"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build-css &amp;amp;&amp;amp; node-sass-chokidar sass/ -o 
     public/css - watch - recursive"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"build-elm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"elm make ./src/Main.elm - output 
     ./public/js/elm.compiled.js - optimize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm-run-all -p build-css build-elm "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"dev-server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"browser-sync start - server 'public' - files 
     'public/**/*.*'"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I am still really new to Elm development and I am sure there are better ways to build your projects but I wanted something simple that I could easily understand. I hope this helps in some way.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>elm</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Running a python script on boot on a RPi</title>
      <dc:creator>James G. Best</dc:creator>
      <pubDate>Mon, 14 Oct 2019 09:44:21 +0000</pubDate>
      <link>https://forem.com/salted-bytes/running-a-python-script-on-boot-on-a-rpi-35mc</link>
      <guid>https://forem.com/salted-bytes/running-a-python-script-on-boot-on-a-rpi-35mc</guid>
      <description>&lt;p&gt;Once you are able to successfully run your python script from the terminal, what are your options to run the same script on booting the Raspberry Pi? This post details the issues I had getting my scripts to run on boot and how I fixed them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Make sure you are running your scripts as the correct user. Python scripts that use Pip packages will need to be run as the user used to install said packages or else they might not be available.&lt;/p&gt;

&lt;p&gt;Writing python scripts is a relatively new thing for me. I love playing with the Raspberry Pi and generally write Nodejs. For most of the stuff I have been doing up until this point, Nodejs has been fine. But the Raspberry Pi is blessed with a wealth of hats performing a multitude of weird and wonderful things. The problem is that most of the libraries for these hats are written in Python. So I thought it was about time I start learning some python.&lt;/p&gt;

&lt;p&gt;My first python script was controlling the Mote LEDs through MQTT. Writing the script did not take too long as the examples in the Pimoroni repos gave me enough to get started. I was able to run the script from the terminal and had it working fine. Obviously, we don't want to have a terminal session open all the time and we want to have the script start on boot (or reboot).&lt;/p&gt;

&lt;p&gt;I had read that there are a number of ways to run a script on boot but that the preferred way was to add an entry into the &lt;code&gt;/etc/rc.local&lt;/code&gt; file. This file is loaded when the Pi is booted and so should achieve our goal.&lt;/p&gt;

&lt;p&gt;Have you ever seen the IP of the Pi print in the terminal output when the Pi is booting? This is where that command is run from.&lt;/p&gt;

&lt;p&gt;So I added the following line to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/bin/python3 /home/pi/Code/desklights/desklights.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and rebooted the Pi. Nothing! No logs, no error. Nothing! Very unhelpful. I tried every possible way of calling the script. And each one proved fruitless. Nothing.&lt;/p&gt;

&lt;p&gt;What I needed was to see so sort of log output. I hoped that this would give me an idea of what was wrong. I updated the command to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/bin/python3 /home/pi/Code/desklights/desklights.py &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/desklights.out &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/desklights.err
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would write anything logging from the program to &lt;code&gt;/tmp/desklights.out&lt;/code&gt; and and errors to &lt;code&gt;/tmp/desklights/err&lt;/code&gt;. This was a key to solving the issue. The &lt;em&gt;.out file was empty which indicated the script was failing. The `&lt;/em&gt;.err` file, on the other hand, contained this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3g93i5dwvjay78yito7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3g93i5dwvjay78yito7z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was now clear what I needed to do. The python packages I had installed were install using the Pi user. This file runs as root and so does not have access to the installed packages. I need to make sure I am running my script as the Pi user and all should be fine and dandy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; pi /usr/bin/python3 /home/pi/Code/desklights/desklights.py/home/pi/Code/desklights/desklights.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Updating the script to include the change of user fixed my issue and allowed the script to run successfully on boot.&lt;/p&gt;

&lt;p&gt;Thanks for reading 🙏&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>python</category>
      <category>iot</category>
    </item>
  </channel>
</rss>
