<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mark</title>
    <description>The latest articles on DEV Community by Mark (@pofigster).</description>
    <link>https://dev.to/pofigster</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1924%2Fa7c66040-62e4-44a6-85af-3c9caff0f196.jpg</url>
      <title>DEV Community: Mark</title>
      <link>https://dev.to/pofigster</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pofigster"/>
    <language>en</language>
    <item>
      <title>Switch Game or Not?</title>
      <dc:creator>Mark</dc:creator>
      <pubDate>Thu, 20 Dec 2018 01:40:55 +0000</pubDate>
      <link>https://dev.to/pofigster/switch-game-or-not-3n78</link>
      <guid>https://dev.to/pofigster/switch-game-or-not-3n78</guid>
      <description>&lt;p&gt;I'm a big fan of the podcast CAGCast which is all about video games. A few months back they invented a game called 'Switch Game or Not?' where one host would inject fake Nintendo Switch games into that week's list of new releases. Why is this fun? Because so many Switch game names are ridiculous. 'Almightree: The Last Dreamer', 'Hunter's Legacy: Purrfect Edition' and 'Oxyjet' are all examples of games that came out last week. It's so easy to slip in ridiculous game names not have it be obvious what's real and what's fake.&lt;/p&gt;

&lt;p&gt;I've fiddled around with using Markov chains to generate new text (words, tweets, etc.) and found it to be pretty quick and easy. Markov chains are a way of moving between states stochastically (randomly). Now, they way they're normally setup, there's no memory. So, if you had a Markov chain for the weather you might have three states, Sunny, Cloudy and Rainy. Each state (say Cloudy) would have a probability of moving to a new state (Sunny or Rainy) or staying the same, the total probability would be 1 (because everything either changes or stays the same, guaranteed). In this case, it doesn't matter if the previous state was Rainy or Sunny, the fact that it is current Cloudy is all that's needed to determine the next state.&lt;/p&gt;

&lt;p&gt;When using Markov chains on text, you could think of this as generating a sequence of tokens (letters, words, etc.) where the current token informs the probability of new tokens. If we built a Markov chain on the set of words ['hi','hello','help'] and tokenized on letters then when we're in the state of 'h' there would be a 33% chance of moving to 'i' and a 67% chance of moving to 'e' and a 0% chance of moving to any other letter (or staying the same). For the state of 'l' there would be a 33% chance of moving to 'o', 33% of moving to 'p' and a 33% chance of staying 'l'. For a more complex vocabulary this will become a lot more complex. The other thing to consider is adding a character which will generate the first letter and a terminating sequence to know when the word is done. So we might pad our words to look like ['&lt;em&gt;hi&lt;code&gt;','*hello&lt;/code&gt;','*help`'], this way we can start a new word from the state of '&lt;/em&gt;' and as soon as we generate a '`' we know we're done.&lt;/p&gt;

&lt;p&gt;I mentioned that Markov chains don't have a memory, so working off of a single letter state, even in our simple vocabulary we could chain together a lot of 'l's which makes for things that don't look like words. So we can build in a memory by having a sliding window of characters. Instead of '&lt;em&gt;help`' having 6 states of '&lt;/em&gt;', 'h', 'e', 'l', 'p', and '&lt;code&gt;' we could use two characters to predict the next single letter '**', '*h','he', 'el', 'lp', 'p&lt;/code&gt;', '&lt;code&gt;&lt;/code&gt;' (I increased the padding to reflect the size of the window). This helps ensure that 'll' will always move to a letter other than 'l'.&lt;/p&gt;

&lt;p&gt;Given a vocabulary then, we need a way to identify all sliding windows and the next token that is predicted. Traditionally this is stored in a matrix, but in our case we have so many possible current states and so many next states (many of which will be empty) that it may not be efficient to store it like that. In Python, I used a dictionary with current states as the keys and stored next tokens as lists.&lt;/p&gt;

&lt;p&gt;In the code below hopefully you can follow my process. I take a list of Nintendo Switch game names (I built mine on the complete list of game names) and for each, pad it with my 'memory' window of '&lt;em&gt;' at the beginning and '`' at the end (these characters are rarely used and the few '&lt;/em&gt;' that are used I stripped out). Then I walk through each title breaking it into windows and append the next window to a dictionary using that key. When this is done, I have a raw list of each next character which contains a lot of repeats. So, I calculate the cumulative probability of each next token (to support randomly picking the next character). In the end I have a nice JSON type structure of a dict of dicts, which I write out to a file.&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;from&lt;/span&gt; &lt;span class="nn"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;functools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nb"&gt;reduce&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_name&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;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;):&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;"*"&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;+&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;"`"&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__len__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;nl&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;i&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)]]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&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;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;KeyError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;nl&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;i&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;n&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="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;n&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;nl&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calc_percent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&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;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
    &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;+&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="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="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&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;1&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
    &lt;span class="n"&gt;ky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&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;ir&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="n"&gt;cp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__len__&lt;/span&gt;&lt;span class="p"&gt;()):&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ky&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ir&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ir&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;output&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gen_markov&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;known&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;next_letter&lt;/span&gt; &lt;span class="o"&gt;=&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;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;known&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;)]"&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="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;next_letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next_letter&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;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;next_letter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;next_letter&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calc_percent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_letter&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"markov_probabilities_{}.json"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="s"&gt;'w'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;outfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_letter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sort_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;


&lt;span class="n"&gt;known_games&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"SEGA AGES Phantasy Star"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"RollerCoaster Tycoon Adventures"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"ACA NEOGEO METAL SLUG 5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Hyperide: Vector Raid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Peace, Death! Complete Edition"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"InkyPen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Almightree: The Last Dreamer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"TRYBIT LOGIC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Firewatch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Rain World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Nippon Marathon"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Omensight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Definitive&lt;/span&gt; &lt;span class="n"&gt;Edition&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Atari&lt;/span&gt; &lt;span class="n"&gt;Flashback&lt;/span&gt; &lt;span class="n"&gt;Classics&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Donut&lt;/span&gt; &lt;span class="n"&gt;County&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Venture&lt;/span&gt; &lt;span class="n"&gt;Towns&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Lazy&lt;/span&gt; &lt;span class="n"&gt;Galaxy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Rebel&lt;/span&gt; &lt;span class="n"&gt;Story&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;City&lt;/span&gt; &lt;span class="n"&gt;Builder&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Oxyjet&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Knights&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Pen&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Paper&lt;/span&gt; &lt;span class="n"&gt;Bundle&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;RAZED&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;MIND&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;Thalamus&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Race&lt;/span&gt; &lt;span class="n"&gt;Arcade&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Blue&lt;/span&gt; &lt;span class="n"&gt;Rider&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Clue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Classic&lt;/span&gt; &lt;span class="n"&gt;Mystery&lt;/span&gt; &lt;span class="n"&gt;Game&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="n"&gt;Hunter&lt;/span&gt;&lt;span class="s"&gt;'s Legacy: Purrfect Edition","Party Arcade","Starman","Mahjong Solitaire Refresh","Sheltered","Knights of Pen &amp;amp; Paper 2 Deluxiest Edition","Big Bash Boom","GRIS","Arcade Archives ATHENA"]&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s"&gt;_ = gen_markov(known_games, 4)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now that I have the data necessary to run a Markov process, I need a way of generating new names. Load in the json file we saved off earlier, generate our starting state ('****' here) and use a &lt;code&gt;while&lt;/code&gt; loop to keep going until we hit the terminating state. The advantage of having a dict of dicts is we can quickly pull out all possible next states (we've removed all the 0's), generate a single random number and the pull out the key for the first value that's greater than the random number.&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;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;choose_letter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;probs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&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;x&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())[&lt;/span&gt;&lt;span class="n"&gt;i&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;gen_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;keep_going&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;keep_going&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;title&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"`"&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;keep_going&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;choose_letter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:],&lt;/span&gt; &lt;span class="n"&gt;p&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;title&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="n"&gt;memory_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'markov_probabilities_{}.json'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memory_length&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;jsonfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;probs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;memory_length&lt;/span&gt;
&lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gen_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;memory_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;probs&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="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, there's a lot of other stuff that needs to be done to help improve this. For example, we don't want our process to produce an actual game name, or even something too close. We don't want absurdly long game names either or too much punctuation. So, I implemented some checks on that which you can see in my GitHub repo.&lt;/p&gt;

&lt;p&gt;For the final implementation I threw together &lt;a href="http://switchgameornot.com"&gt;a website&lt;/a&gt; using node.js, Express, Angular (1.6, I know...), and MySQL on some sweet &lt;a href="https://m.do.co/c/92b8439f5af7"&gt;Digital Ocean&lt;/a&gt; hardware. I even followed a tutorial and 'dockerized' my node.js app (another post on that later maybe). The whole project is on &lt;a href="https://github.com/bmewing/switch_game_or_not"&gt;GitHub&lt;/a&gt; where I'm not yet using feature branches or any CI/CD stuff, so please don't judge too hard. Also, I'd appreciate feedback, especially on the web dev stuff.&lt;/p&gt;

&lt;p&gt;Overall, it was a fun experience. I shared the app with the hosts and they loved it (now I'm hoping for a shoutout on the show), so we'll see if it has any legs. It's always great to go from idea to execution in just a few days. The most frustrating part about it, for me, was the web dev part. There are some bits of node.js and express that I get for making APIs, but not all of it. And Angular is always a frustrating experience for me, but since web dev isn't my day job or even my side gig, it's hard to justify learning something else right now.&lt;/p&gt;

</description>
      <category>digitalocean</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Faking IoT for Innovation (a tutorial)</title>
      <dc:creator>Mark</dc:creator>
      <pubDate>Tue, 20 Nov 2018 15:15:51 +0000</pubDate>
      <link>https://dev.to/pofigster/faking-iot-for-innovation-a-tutorial-n0l</link>
      <guid>https://dev.to/pofigster/faking-iot-for-innovation-a-tutorial-n0l</guid>
      <description>&lt;h1&gt;
  
  
  The Why
&lt;/h1&gt;

&lt;p&gt;At work this past week we had a hackathon-type event we called 'Innovation Week'. A buddy and I decided we wanted to do some predictive maintenance on customer systems. The main issue? We don't have their data. We don't even have everything we would need to do it with our data. Also, how would we get their data? Internet of Things (IoT) measurement systems, of course. So, in a week, I needed to write a heat transfer system simulator and then get the measurement points to communicate back to a dashboard. This is the reason for faking IoT - I didn't want to buy actual IoT measurement systems and try to hook them up to an actual heat transfer system. Even if I could, I wouldn't get data fast enough to do predictive maintenance, so I needed a way to simulate the devices so I could demonstrate a working prototype. I chose to use node.js because I'm trying to learn more JS and I think more server-side than client-side.&lt;/p&gt;

&lt;p&gt;Why a tutorial of this? It turns out the whole process was actually hard for someone like me. There are a few tutorials out there about hooking up a Raspberry Pi, but most of them are old enough that some of the steps in AWS and even with the SDK are irrelevant and out of date, so I had to figure it out and I wanted to document for future me and also anybody else out there like me.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Assumptions
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;You already have an AWS account&lt;/li&gt;
&lt;li&gt;You're OK using node.js&lt;/li&gt;
&lt;li&gt;You're not super concerned with having overly permissive IAM roles in AWS&lt;/li&gt;
&lt;li&gt;You're at least moderately comfortable with provisioning servers from a provider (DigitalOcean, AWS, whatever)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The How
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 1 - Get started with AWS IoT
&lt;/h2&gt;

&lt;p&gt;The first thing you'll need to do is login to the AWS Console and navigate to the IoT Core resource. If it's your first time, your screen should look different, but our goal is to &lt;em&gt;create a 'thing'&lt;/em&gt;, or, register an IoT device. Don't worry, you don't have to have a device yet to make this happen, this is just getting things prepared.&lt;/p&gt;

&lt;p&gt;You'll need to be in the Manage &amp;gt; Things section and click 'Create'.&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%2F4x0mp86xp0be15s9yqmu.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%2F4x0mp86xp0be15s9yqmu.png" alt="step 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We just want to make a single AWS IoT thing, so that's what we'll click.&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%2Fyvkt80rou29stjhy3fp4.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%2Fyvkt80rou29stjhy3fp4.png" alt="step 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's a lot of possible things to fill in on this next screen. You can safely ignore &lt;em&gt;all of it&lt;/em&gt; except the name at the top. I've named this device 'dev-tutorial'. You may be wondering, "What do all the other things do?" and the answer as best as I can tell is they're fields to help you keep stuff organized. The company I work for uses AWS and there are so many people doing so many different things that the tags and groups and such are essential. I do proof of concept stuff and blow it all away when I'm done so I ignore all of 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%2Fsmdcgf2i23idb3gwguw5.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%2Fsmdcgf2i23idb3gwguw5.png" alt="step 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This next step is important, we need to create the certificates that will allow our as-of-yet non-existent IoT device to identify itself to AWS. You don't want to mess up these next steps. You'll need to click on 'Create certificate' to generate 3 different files we'll need to download and copy to our server.&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%2Fklsh18a7uo8ks17bxbxh.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%2Fklsh18a7uo8ks17bxbxh.png" alt="step 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You probably see a box flash telling you the device has been created, but don't think you're done. You need to download the three files that are in the table &lt;em&gt;and&lt;/em&gt; download a root CA (Certificate Authority) file. The first three links will all download actual files and you &lt;em&gt;must&lt;/em&gt; download them now or they will be lost forever. This is your one shot to get these certificates. Don't blow it. The last link though doesn't directly download a file.&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%2Fjghjjq819njkij04s8r2.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%2Fjghjjq819njkij04s8r2.png" alt="step 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The new page that loads has a bunch of links. The one you want is the Amazon Root CA 1 file, an RSA 2048 bit key. Go ahead and click the link.&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%2Fu44ngdmpi33pasfgrp54.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%2Fu44ngdmpi33pasfgrp54.png" alt="step 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all four files now downloaded, be sure to click 'Activate' back on the IoT screen that says 'Certificate Created!'. Once activated, click 'Attach a policy'.&lt;/p&gt;

&lt;p&gt;Remember when I said I assumed you were OK with permissive IAM roles and stuff? Well, here I'm just selecting the global policy that allows this thing to do &lt;em&gt;anything&lt;/em&gt; with IoT on &lt;em&gt;any&lt;/em&gt; resource. Probably not a good long term idea, but it's what the tutorial tells you to do :)&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%2Fugd4p6mfr7t6y7ws213k.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%2Fugd4p6mfr7t6y7ws213k.png" alt="step 7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congrats! You've registered a thing with IoT!&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%2Fypm9jz493h3a8vmkcbvj.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%2Fypm9jz493h3a8vmkcbvj.png" alt="step 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 - Get a Server to Pretend to be an IoT device
&lt;/h2&gt;

&lt;p&gt;First, go get yourself a server running Linux. I use &lt;a href="https://m.do.co/c/92b8439f5af7" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; (note, that is my personal referral link) because $5/month a decent little box is great. I also chose to use Ubuntu.&lt;/p&gt;

&lt;p&gt;Next, connect to the box and we'll get stuff installed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/download/package-manager/" rel="noopener noreferrer"&gt;Install node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/awscli-install-linux.html" rel="noopener noreferrer"&gt;Install AWS CLI&lt;/a&gt; (on Ubuntu 18.10 I used &lt;code&gt;apt install awscli&lt;/code&gt; without issue)&lt;/li&gt;
&lt;li&gt;Install the AWS IoT Device SDK for JS, &lt;code&gt;npm i aws-iot-device-sdk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Configure AWS Credentials &lt;code&gt;aws configure&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I chose to make a project folder called 'iweek'. Wherever you want to work, make a directory called 'certs' and upload the 4 certificates we downloaded earlier. For ease of copy/paste, rename the files as such:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;...-certificate.pem.crt &amp;gt; certificate.pem.crt&lt;/li&gt;
&lt;li&gt;...-private.pem.key &amp;gt; private.pem.key&lt;/li&gt;
&lt;li&gt;...-public.pem.key &amp;gt; public.pem.key&lt;/li&gt;
&lt;li&gt;AmazonRootCA1.pem &amp;gt; root-CA.crt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last thing we need to determine is the custom host endpoint we'll be connecting to. This is done with the AWS CLI &lt;code&gt;aws iot describe-endpoint --endpoint-type 'iot:Data-ATS' --region us-east-1&lt;/code&gt; making sure to update the region to whatever region you've setup your IoT Thing in. Copy the contents of the endpoint address in the response, we'll need that in a minute.&lt;/p&gt;

&lt;p&gt;Now we're ready to make the JavaScript file to make sure everything can connect OK. If your directory structure is setup like mine, the file should be saved to &lt;code&gt;~/iweek/test_iot.js&lt;/code&gt; with &lt;code&gt;~/iweek/certs/&lt;/code&gt; holding the certificates. &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%2Fx88vu5qk4d3xe82mh1zi.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%2Fx88vu5qk4d3xe82mh1zi.png" alt="folder structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the top of the file we need to load the IoT Device SDK and then initialize our device. We're not doing anything with the device just yet, just defining what it looks like. The 'clientId' is a string that you use to identify what's connecting. It does not have to match your Thing name, so it can be goofy or informative.&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;var&lt;/span&gt; &lt;span class="nx"&gt;awsIot&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="s1"&gt;aws-iot-device-sdk&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;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;awsIot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;device&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
   &lt;span class="na"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./certs/private.pem.key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;certPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./certs/certificate.pem.crt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;caPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./certs/root-CA.crt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;first-try&lt;/span&gt;&lt;span class="dl"&gt;'&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="s1"&gt;CUSTOM HOST ENDPOINT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to the bottom of the file some instructions for the device to follow when it connects to the IoT Core.&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="nx"&gt;device&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="s1"&gt;connect&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="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="s1"&gt;connect&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point we'll boot up a terminal &lt;code&gt;cd iweek&lt;/code&gt; and &lt;code&gt;node test_iot.js&lt;/code&gt; All we should see after we hit enter is the word 'connect' in our STDOUT and no new prompt. This is because there's no end to our code, the device is connected, just not doing anything. So you'll need to send a cancel code to your terminal.&lt;/p&gt;

&lt;p&gt;Now we can try sending messages.&lt;/p&gt;

&lt;p&gt;We'll modify the 'on connect' part of the code now to subscribe to a topic and also publish to that topic. When we subscribe and publish we do so to a topic. The topic is just a name and it can be whatever you want. The name we publish to is important to remember because it's how we'll retrieve data later.&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="nx"&gt;device&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="s1"&gt;connect&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="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="s1"&gt;connect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;device&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev_to_test&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&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="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;device&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev_to_test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hi there!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;points&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;168&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 also want to add a code block to alert us whenever a message is added to the topic. Now, when the device receives a message, we'll print the message contents to STDOUT.&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="nx"&gt;device&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="s1"&gt;message&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="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&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="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&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;Back at our terminal we run &lt;code&gt;node test_iot.js&lt;/code&gt; and we get a few messages. First, we get our 'connect' to tell us we successfully connected. Next we get information telling us we've subscribed to the topic 'dev_to_test' and finally we see the result of publishing our message to the topic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;connect
[ { topic: 'dev_to_test', qos: 0 } ]
message dev_to_test {"message":"hi there!","points":168}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3 - Collect data sent via IoT
&lt;/h2&gt;

&lt;p&gt;This was the hardest step for me, it's where most of the tutorials I found broke down and I had to figure it out by my lonesome. What we're going to try and do is get IoT core to push incoming data on a topic to a Kinesis Firehose which should drop the results into S3. &lt;/p&gt;

&lt;p&gt;First we need to setup the Kinesis Firehose. So we'll navigate to that service, click on the Data Firehose tab and the 'Create delivery stream'&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%2Fu5u3yaoetc9hmrbxfsiz.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%2Fu5u3yaoetc9hmrbxfsiz.png" alt="step10"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the create menu we need to give a name and, most importantly, make sure you have 'Direct PUT or other sources' selected. This is the simplest interface from IoT to Kinesis rather than going through a Data Stream. click Next at the bottom of the page.&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%2Fbh9hbgobifk0mbpr4tji.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%2Fbh9hbgobifk0mbpr4tji.png" alt="step11"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next page has a few options. If you want to do work on the the data submitted by the IoT thing you can trigger AWS Lambda. You can also convert the record format to something like Apache's parquet if you'd like. I chose to disable both of these features as I'm submitting back only simple data.&lt;/p&gt;

&lt;p&gt;Finally, we need to select the destination. Firehose will stream data to S3, Redshift, Elasticsearch or Splunk. In this demo we're storing things to S3 because of the simplicity of storage and the ease of applying Athena on top of the S3 data. S3 is the default selection, so scroll down to pick which S3 bucket you want to use for storage (alternatively, click 'Create new' to make a new bucket) and then optionally specify an prefix for the files (the psuedo folder structure in S3). Once this is done, click 'Next'.&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%2Fai79046n0n3spwdi7mdr.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%2Fai79046n0n3spwdi7mdr.png" alt="step12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final step to get our Firehose setup is to configure it. The most important part of this page is the S3 buffer conditions. Firehose will receive data and store it until the buffer condition is met and then it will push the data to S3. The defaults here are 5MB or 5 minutes, I've set mine to 1MB or 1 minute (the minimum) because we're not going to be shipping a ton of data back for this tutorial and I don't want to wait forever for it to arrive. The data we're sending isn't huge so we don't need compression and the data isn't sensitive so we don't need encryption, but those options exist. We need to have an IAM role with the correct permissions.&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%2Fgm4v59c61fwl111zrhkq.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%2Fgm4v59c61fwl111zrhkq.png" alt="step13"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have an IAM role called &lt;em&gt;firehose_delivery_role&lt;/em&gt; which I selected here and I create a new Role Policy to make sure it can access my newly created S3 bucket. Once you've finished in this screen, click Next.&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%2Fanvnwkubi9oh03n0lia3.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%2Fanvnwkubi9oh03n0lia3.png" alt="iamstuff"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the final screen make sure your choices look good and click 'Create delivery stream'. While the deliver stream is being created, we need to go back to our IoT Core page (now full of successful connections and donut charts!) and click into the 'Act' tab and then click the 'Create' button.&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%2Fypahp6hyc6drszh3o2n0.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%2Fypahp6hyc6drszh3o2n0.png" alt="step14"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the create screen we need to give our rule a name and ideally a description. I've named mine &lt;em&gt;dev_to_rule&lt;/em&gt;. Next we need to write a SQL query to state what data we want to pass through the rule. This works like a basic SQL query, you can use 'where' statements and the like. If we were passing in complex data we me might even use the 'select' statement to filter which columns to keep. Here though, we just want to pass it all through so the query looks like the following. Note the table name is the topic we pass messages to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'dev_to_test'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fvjvexvfnz7ruv0my7bh4.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%2Fvjvexvfnz7ruv0my7bh4.png" alt="step15"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to add an action. We click the 'Add action' button which brings up a huge list of options. We want to pass the data to our Kinesis Firehose stream. You may see that we could just store the messages directly in an S3 bucket which is true, but by leveraging Firehose we have more options (lambda processing, other destinations, etc.). So we make the appropriate selection and then click 'Configure action'&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%2Fzuppyvz0536oust9qetg.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%2Fzuppyvz0536oust9qetg.png" alt="step16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When configuring we want to select the stream we created, &lt;em&gt;dev_to_firehose&lt;/em&gt;, and pick the separator for messages received. Since Firehose will build up a buffer, multiple messages will be in the same file. I chose a new line to help with readability. Finally, we'll want to create a new IAM role and give it a name, &lt;em&gt;dev_to_iot_to_firehose&lt;/em&gt; in this case. You'll need to hit the refresh button after you've created the role and select it from the dropdown list. Finally, hit 'Update role' to make sure it's applied and then click 'Add action'.&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%2F8nu7rs4w1jidulg4v1jc.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%2F8nu7rs4w1jidulg4v1jc.png" alt="step17"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This takes us back to the create rule screen and so we'll press 'Create rule'.&lt;br&gt;
With the rule created we go back to our server now and from the terminal run &lt;code&gt;node test_iot.js&lt;/code&gt; to trigger the message being sent to our channel. We need to be patient now (1 minute) while the buffer in Firehose builds up. After a minute we can go to &lt;code&gt;S3 &amp;gt; dev-to-tutorial / iot / year / month / day / hour&lt;/code&gt; and see we have a file that's been created!&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%2Fbsu45kvk09y5vhhl9jvn.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%2Fbsu45kvk09y5vhhl9jvn.png" alt="success"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can download the file and see that we have text in a JSON structure that contains the message we sent. Success!&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%2Fgq5lmnayqf2vzkxe28jo.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%2Fgq5lmnayqf2vzkxe28jo.png" alt="contents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Innovation Week Results
&lt;/h1&gt;

&lt;p&gt;Hopefully the tutorial helped you get started with IoT devices powered by node.js communicating with AWS services. The results of my efforts here plus the machine learning algorithm and real-time dashboard won my team first place which was very exciting. Thanks for letting me share this with you!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>digitalocean</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
  </channel>
</rss>
