-
Notifications
You must be signed in to change notification settings - Fork 1
/
feed.xml
552 lines (385 loc) · 53.8 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Patrick Renschler</title>
<description>Patrick Renschler's blog
</description>
<link>/</link>
<atom:link href="/feed.xml" rel="self" type="application/rss+xml"/>
<pubDate>Thu, 29 Mar 2018 12:52:56 -0700</pubDate>
<lastBuildDate>Thu, 29 Mar 2018 12:52:56 -0700</lastBuildDate>
<generator>Jekyll v3.4.5</generator>
<item>
<title>Quotes: reminders, wisdom, motivation</title>
<description><p><em>Last updated: 3/29/18</em></p>
<ul>
<li>
<p>“There is nothing so useless as doing efficiently that which should not be done at all.” - Peter Drucker</p>
</li>
<li>
<p>“To find a worthy mate, be worthy of a worthy mate.” - Charlie Munger</p>
</li>
<li>
<p>“Bad news doesn’t get better with time.” - <a href="https://twitter.com/ben97574">@ben97574</a></p>
</li>
<li>
<p>“Twenty years from now you will be more disappointed by the things you didn’t do that by the ones you did. So throw off the bowlines, sail away from the safe harbor, catch the trade winds in your sails. Explore. Dream. Discover.” - Mark Twain</p>
</li>
<li>
<p>“My 1 repeated learning in life: <em>There Are No Adults</em>. Everyone’s making it up as they go along. Figure it out yourself, and do it.” - <a href="https://twitter.com/naval">@naval</a></p>
</li>
<li>
<p>“Success comes from doing, not declaring.” - <a href="https://twitter.com/sivers">@sivers</a></p>
</li>
<li>
<p>“It doesn’t get any easier, you just get faster.” - Greg LeMond</p>
</li>
<li>
<p>“You get paid for being right first, and to be first, you can’t wait for consensus.” - <a href="https://twitter.com/naval">@naval</a></p>
</li>
<li>
<p>“All writing advice, or creative advice can be boiled down to one three-word sentence: <em>Ass in chair</em>.” - Chris Jones (esquire)</p>
</li>
<li>
<p>“An entrepreneur without drive is just unemployed.” - <a href="https://twitter.com/naval">@naval</a></p>
</li>
<li>
<p>“No one’s coming to save you from yourself.” - via <a href="https://twitter.com/AmuseChimp">@amusechimp</a></p>
</li>
<li>
<p>“Don’t dilute yourself with people who don’t work as hard as you.” - via <a href="https://twitter.com/kwuchu">@kwuchu</a></p>
</li>
<li>
<p>“The key to thriving in our position is endurance. The key to endurance is training on the steepest hill you can find.” - Walter Payton to Roger Craig</p>
</li>
<li>
<p>“Most decisions should probably be made with somewhere around 70% of the information you wish you had. If you wait for 90%, in most cases, you’re probably being slow. Plus, either way, you need to be good at quickly recognizing and correcting bad decisions. If you’re good at course correcting, being wrong may be less costly than you think, whereas being slow is going to be expensive for sure.” - Jeff Bezos</p>
</li>
<li>
<p>“People pay an enormous price to avoid mild embarrassment.” - on Amos Tversky via <a href="https://twitter.com/sknthla">@sknthla</a></p>
<p><img src="/images/embarassment.PNG" alt="Photo" /></p>
</li>
<li>
<p><a href="https://twitter.com/naval">@naval</a>’s laws via <a href="https://twitter.com/tferriss">@timferris</a>’ <a href="http://amzn.to/2vh8VnB">Tools of Titans</a></p>
<p><img src="/images/navals_laws.PNG" alt="Photo" /></p>
</li>
<li>
<p>“Simple heuristic: If you are evenly split on a difficult decision, take the path that’s more painful in the short term.” - <a href="https://twitter.com/naval">@naval</a></p>
</li>
<li>
<p>“Honest feedback, the most valuable and all-too-rare form of non-financial reward that just keeps paying dividends over time.” - via <a href="https://twitter.com/scottbelsky">@scottbelsky</a>, <a href="https://twitter.com/wminshew">@wminshew</a></p>
</li>
<li>
<p>“The pain cave is a place where we take stock of our courage and ask ourselves how much we are willing to give for the goals we’ve laid out.” - <a href="https://www.outsideonline.com/2192176/why-are-runners-obsessed-with-pain-cave">“Why are Runners Obsessed with the Pain Cave”</a></p>
</li>
<li>
<p>“One of the cruelest things you can do to another person is pretend you care about them more than you really do.” - Douglas Coupland via <a href="https://twitter.com/booknerdfession">@booknerdfession</a>, <a href="https://twitter.com/michael_nielsen">@michael_nielsen</a></p>
</li>
<li>
<p>“Stop trying to use your speech to get what you want. You don’t necessarily know what you want. Instead, try to articulate what you believe to be true as carefully as possible. Then, accept the outcome.” - <a href="https://twitter.com/jordanbpeterson">@jordanbpeterson</a></p>
</li>
<li>
<p>seen <a href="https://twitter.com/Princeton">@princeton</a>:</p>
<p><img src="/images/start_writing.PNG" alt="Photo" /></p>
</li>
<li>
<p>“The organ that limits endurance performance is the brain… What endurance athletes must endure above all is not actual effort, but perception of effort… There is no experience like that of driving yourself to the point of wanting to give up and then not giving up.” - Excerpts from <a href="https://twitter.com/mattfitwriter">@mattfitwriter</a>’s <a href="http://amzn.to/2zEEuqH">How Bad Do You Want It?</a></p>
</li>
<li>
<p>“First you make your habits, and then your habits make you”</p>
</li>
<li>
<p><img src="/images/lincoln.png" alt="Photo" /></p>
</li>
<li>
<p>“Perfect is the enemy of done.”</p>
</li>
<li>
<p>“A man is revealed by how he treats the powerless.”</p>
</li>
<li>
<p>“Reputation comes from consistency.”</p>
</li>
<li>
<p>“Habits over choices. Reduce friction.”</p>
</li>
<li>
<p>“GOOD.” - <a href="https://twitter.com/ben97574">@ben97574</a> <a href="https://twitter.com/jockowillink">@jockowillink</a></p>
</li>
<li>
<p>“Be deliberate with your time and focus. Before every task ask - ‘is this worth my attention?’”</p>
</li>
</ul>
</description>
<pubDate>Tue, 08 Aug 2017 00:00:00 -0700</pubDate>
<link>/2017/08/08/Quotes-reminders-wisdom-motivation.html</link>
<guid isPermaLink="true">/2017/08/08/Quotes-reminders-wisdom-motivation.html</guid>
<category>workflow</category>
</item>
<item>
<title>DidDogEat? Dashbutton to Raspberry Pi to Slack</title>
<description><p>Amazon dash buttons are wifi connected devices that you are supposed to configure with your prime account so you can order a preselected product at the click of the button.</p>
<p>It turns out the internet has found <a href="https://www.google.com/search?q=dash+button+hack">many ways</a> to repurpose them for IoT projects.</p>
<p>Normally dash buttons sell for $5 (which gets refunded after your first purchase), but on prime day last week they were selling for 99 cents so I decided to buy a few to play around with.</p>
<p>This post covers how I setup a dashbutton, raspberry pi, and slack app to keep track of the dog getting fed.</p>
<div class="video"><figure><iframe width="640" height="480" src="//www.youtube.com/embed/xa-Q7N8yGsQ" frameborder="0" allowfullscreen=""></iframe></figure></div>
<p>And this is George. He is a good boy.</p>
<p><img src="/images/George.gif" alt="Photo" /></p>
<h3 id="what-i-used">What I used</h3>
<ul>
<li>Raspberry Pi Zero W (<a href="https://www.adafruit.com/product/3400">$10</a>)</li>
<li>SanDisk Ultra 32GB microSD (<a href="http://amzn.to/2ud6ZvU">$12.99</a>)</li>
<li><a href="https://www.amazon.com/Dash-Buttons/b?ie=UTF8&amp;node=10667898011">Amazon dash button</a></li>
<li>MicroUSB power supply</li>
<li>Laptop running macOS Sierra</li>
</ul>
<p>Kind of expensive for a button project, but I have a couple apps, like this <a href="http://ec2-54-69-226-237.us-west-2.compute.amazonaws.com/">flight checkin app</a>, running on an aws t2.nano instance that I should be able to move to the pi.</p>
<p>Also, I didn’t get a case but these <a href="https://www.indiegogo.com/projects/pi-zero-ali-keychain--2#/">aluminum keychain ones</a> look sweet.</p>
<h3 id="raspberry-pi-zero-w-setup">Raspberry Pi Zero W setup</h3>
<p>First I followed the instructions here: <a href="https://learn.adafruit.com/adafruit-raspberry-pi-lesson-1-preparing-and-sd-card-for-your-raspberry-pi">Preparing an SD Card for your Raspberry Pi</a>. You’ll have some options, I chose to go with the <a href="https://www.raspberrypi.org/downloads/raspbian/">Raspian Jessie Lite image</a> because I don’t need the desktop functionality and no way I was choosing the image called “NOOBS”.</p>
<p>To flash the image onto my SD card, I broke away from the adafruit instructions and <a href="https://computers.tutsplus.com/articles/how-to-flash-an-sd-card-for-raspberry-pi--mac-53600">used these</a>.</p>
<p><em>Note: Make sure the micro SD adapter toggle is set to the unlocked position when you put it into your machine. Also as a heads up the dd command took ~20 minutes to finish, so it probably would have been faster and safer to just download the <a href="https://etcher.io/">etcher software</a> and do what adafruit recommends…</em></p>
<p>Next I moved onto the instructions starting here: <a href="https://learn.adafruit.com/raspberry-pi-zero-creation/text-file-editing">Raspberry Pi Zero Headless Quick Start Text File Editing</a>. Once I was able to SSH in, I changed the default password and then ran the following:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c">## contents from setup_script_1.sh ##</span>
sudo apt update
sudo apt upgrade -y
sudo apt install git -y
sudo apt install emacs -y
<span class="c"># set up git, modify for yourself</span>
git config --global user.name <span class="s2">"Patrick Renschler"</span>
git config --global user.email myemail@email.com
git config --global core.editor emacs
git config --list
<span class="c"># clone rest of setup commands from my public repo</span>
git clone https://github.com/renschler/dash_setups.git
<span class="nb">cd </span>dash_setups
<span class="c"># run rest of setup commands</span>
./pi_setup_script_2.sh
<span class="c"># run the setup commands for this dash button project</span>
./dash_button_setup.sh</code></pre></figure>
<p>The scripts will install git, install emacs (a text editor), change various environment settings, and then install the python libraries you need for this project. You can review all the code here: <a href="https://github.com/renschler/dash_setups">https://github.com/renschler/dash_setups</a>.</p>
<p>If you don’t care for emacs you can comment out those lines. If you want to check it out <a href="https://github.com/renschler/dash_setups/blob/master/COS%20217%20Emacs%20Cheat%20Sheet.pdf">here’s the emacs tutorial</a> I used to get started in college. It provides documentation for the <code class="highlighter-rouge">.emacs</code> file included in my setups repository.</p>
<p>Lastly I added the following line to my laptop’s <code class="highlighter-rouge">.bash_profile</code>, I use this convention for connecting to other machines that have harder to remember ssh commands.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c"># pi zero ssh</span>
<span class="nb">alias </span>pi-z-ssh<span class="o">=</span><span class="s1">'ssh pi@raspberrypi.local'</span></code></pre></figure>
<h3 id="dash-button-setup">Dash button setup</h3>
<p>There’s two things you need to do here: get the MAC address of your button, and then configure it for your home wifi network.</p>
<p>Press the dash button and hold it down until the blue light comes on. On your laptop or phone, look for a wifi network named “Amazon ConfigureMe” and then join it. Open up a browser and go to <code class="highlighter-rouge">192.168.0.1</code>. This should show you a page that has your button’s MAC address which you’ll need to write down.</p>
<p><img src="/images/MAC_ADDRESS.png" alt="Photo" /></p>
<p>The easiest way (only way? lol) to set up your dash button on your home wifi is to use the amazon mobile app. Sign into your amazon account, then open the menu from the top left and click “Your Account”.</p>
<p>Scroll down to “Dash Buttons &amp; Devices”, and click the “Set up a new device” option.</p>
<p><img src="/images/Select_Device.png" alt="Photo" /></p>
<p>Follow the instructions to set up your dash button but <span style="color:red"><strong>do not select a product</strong></span>. Click the X in the top right and exit the setup before choosing what product you want to order.</p>
<p><img src="/images/Exit_Setup.png" alt="Photo" /></p>
<h3 id="tcpdump">Tcpdump</h3>
<p>Ok assuming your amazon dash button and raspberry pi are connected to the same wifi network, we can use tcpdump to listen for your button being pushed.</p>
<p>SSH back into your pi, and run this command substituting in the MAC address of your dash button.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c"># Modify with the mac address of your dash button</span>
sudo tcpdump ether host b4:7c:9c:3a:00:d4</code></pre></figure>
<p>Click your dash button and you should see some packets! Hit CTRL-C to stop tcpdump.</p>
<p><img src="/images/tcpdump.png" alt="Photo" /></p>
<p>It looks like everytime we click the dash button it broadcasts a DHCP packet, so we can use that as our trigger.</p>
<h3 id="python">Python</h3>
<p>Now we will use the python library <code class="highlighter-rouge">scapy</code> to listen for the click of your dash button (like tcpdump), and then print “Hello world” when it is detected.</p>
<p>Create a new file called <code class="highlighter-rouge">dashbutton.py</code> and paste this into it:</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">from</span> <span class="nn">scapy.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="k">def</span> <span class="nf">feed_dog</span><span class="p">():</span>
<span class="k">print</span> <span class="s">"Hello, world!"</span>
<span class="k">return</span>
<span class="c"># substitute in your mac address</span>
<span class="n">dashset</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="s">"b4:7c:9c:3a:00:d4"</span><span class="p">])</span>
<span class="n">dashdict</span> <span class="o">=</span> <span class="p">{</span><span class="s">"b4:7c:9c:3a:00:d4"</span><span class="p">:</span><span class="n">feed_dog</span><span class="p">}</span>
<span class="k">def</span> <span class="nf">dhcp_display</span><span class="p">(</span><span class="n">pkt</span><span class="p">):</span>
<span class="k">print</span> <span class="s">"DHCP packet from: "</span><span class="o">+</span> <span class="n">pkt</span><span class="p">[</span><span class="n">Ether</span><span class="p">]</span><span class="o">.</span><span class="n">src</span>
<span class="n">dashdict</span><span class="p">[</span><span class="n">pkt</span><span class="p">[</span><span class="n">Ether</span><span class="p">]</span><span class="o">.</span><span class="n">src</span><span class="p">]()</span>
<span class="k">return</span>
<span class="k">print</span> <span class="n">sniff</span><span class="p">(</span><span class="n">prn</span><span class="o">=</span><span class="n">dhcp_display</span><span class="p">,</span> <span class="n">lfilter</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">haslayer</span><span class="p">(</span><span class="n">DHCP</span><span class="p">)</span> <span class="ow">and</span> <span class="n">x</span><span class="p">[</span><span class="n">Ether</span><span class="p">]</span><span class="o">.</span><span class="n">src</span> <span class="ow">in</span> <span class="n">dashset</span><span class="p">,</span> <span class="n">store</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span></code></pre></figure>
<p>Start the program with <code class="highlighter-rouge">sudo python dashbutton.py</code>, click your button, you should get a Hello, World!</p>
<h3 id="adding-slack">Adding slack</h3>
<p>The last step to this project is integrating slack’s python library so that when we detect a button press we can post a message to the #dogfood channel saying the dog was fed.</p>
<p>If you don’t have a slack team yet, you’ll need to <a href="https://slack.com/create">make one</a>. Next, sign into your team and go to the <a href="https://api.slack.com/slack-apps">building slack apps page</a>. Click the green “Create a Slack App” button. When you get to the ‘Basic Information’ page, click the Permissions tile.</p>
<p><img src="/images/BasicInformation.png" alt="Photo" /></p>
<p>Then scroll down to ‘Permission Scopes’, add the “Send messages as [APP_NAME]” permission, and save changes.</p>
<p><img src="/images/PermissionScopes.png" alt="Photo" /></p>
<p>On the same page, at the top, click the green button that says “Install App to Team”. When you’ve finished that you’ll land on the page with an <code class="highlighter-rouge">OAuth Access Token</code> displayed. You will need this to send messages from our python program.</p>
<p>Reopen the <code class="highlighter-rouge">dashbutton.py</code> program, and modify it so that it matches what’s below:</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">from</span> <span class="nn">scapy.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">slackclient</span> <span class="kn">import</span> <span class="n">SlackClient</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="n">slack_token</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">"SLACK_BOT_TOKEN"</span><span class="p">]</span>
<span class="n">sc</span> <span class="o">=</span> <span class="n">SlackClient</span><span class="p">(</span><span class="n">slack_token</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">feed_dog</span><span class="p">():</span>
<span class="n">sc</span><span class="o">.</span><span class="n">api_call</span><span class="p">(</span>
<span class="s">"chat.postMessage"</span><span class="p">,</span>
<span class="n">channel</span><span class="o">=</span><span class="s">"#dogfood"</span><span class="p">,</span>
<span class="n">text</span><span class="o">=</span><span class="s">"The dog just got food! :tada:"</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="c"># substitute in your mac address </span>
<span class="n">dashset</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="s">"b4:7c:9c:3a:00:d4"</span><span class="p">])</span>
<span class="n">dashdict</span> <span class="o">=</span> <span class="p">{</span><span class="s">"b4:7c:9c:3a:00:d4"</span><span class="p">:</span><span class="n">feed_dog</span><span class="p">}</span>
<span class="k">def</span> <span class="nf">dhcp_display</span><span class="p">(</span><span class="n">pkt</span><span class="p">):</span>
<span class="k">print</span> <span class="s">"DHCP packet from: "</span><span class="o">+</span> <span class="n">pkt</span><span class="p">[</span><span class="n">Ether</span><span class="p">]</span><span class="o">.</span><span class="n">src</span>
<span class="n">dashdict</span><span class="p">[</span><span class="n">pkt</span><span class="p">[</span><span class="n">Ether</span><span class="p">]</span><span class="o">.</span><span class="n">src</span><span class="p">]()</span>
<span class="k">return</span>
<span class="k">print</span> <span class="n">sniff</span><span class="p">(</span><span class="n">prn</span><span class="o">=</span><span class="n">dhcp_display</span><span class="p">,</span> <span class="n">lfilter</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">haslayer</span><span class="p">(</span><span class="n">DHCP</span><span class="p">)</span> <span class="ow">and</span> <span class="n">x</span><span class="p">[</span><span class="n">Ether</span><span class="p">]</span><span class="o">.</span><span class="n">src</span> <span class="ow">in</span> <span class="n">dashset</span><span class="p">,</span> <span class="n">store</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span></code></pre></figure>
<p>Assuming you have a channel named <code class="highlighter-rouge">#dogfood</code>, you can start this program with</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">sudo <span class="nv">SLACK_BOT_TOKEN</span><span class="o">=</span><span class="s2">"PASTE-IN-YOUR-TOKEN"</span> python dashbutton.py</code></pre></figure>
<p>When you click the dash button you should see a message show up from your app in the #dogfood channel!</p>
<p>The very last thing I did was schedule a cron job that will start this program everytime the raspberry pi reboots.</p>
<p>Type <code class="highlighter-rouge">crontab -e</code> into the terminal, and then add the following line, as it’s own line, at the bottom of the file. Do not preface it with a #.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">@reboot <span class="nb">cd</span>; sudo <span class="nv">SLACK_BOT_TOKEN</span><span class="o">=</span><span class="s2">"PASTE-IN-YOUR-TOKEN"</span> python dashbutton.py</code></pre></figure>
<p>Then leave one empty line below that command, before the end of the file, and you are good to exit. Although, depending on where the <code class="highlighter-rouge">dashbutton.py</code> file is located on your pi, you may have to change that command so it has the right path.</p>
<p>But ya that’s it! If you ever want to support more dash buttons on your network, you can add additional functions and MAC Addresses to the <code class="highlighter-rouge">dashdict</code> &amp; <code class="highlighter-rouge">dashset</code> objects.</p>
<h3 id="related-but-different">Related but different</h3>
<h4 id="links">Links</h4>
<ul>
<li><a href="https://medium.com/@ecaron/why-i-stopped-hacking-the-amazon-dash-button-and-learned-to-solder-84386a38bbd1">Why I stopped hacking the amazon dash button and learned how to solder</a></li>
<li><a href="https://www.hackster.io/noelportugal/ifttt-smart-button-e11841">IFTTT Smart Button</a></li>
<li><a href="https://www.stavros.io/posts/emergency-food-button/?print">Emergency Food Button</a>:
<blockquote>
<p>From the first time I saw the Amazon dash button, I was impressed by its simplicity, and thought that it, or something like it at around the same price point, would be very useful. Unfortunately, it’s not open at all, and the more open alternatives are still not very open and cost at least seven times as much. Therefore, the reasonable thing for me to do is to sink a few thousand dollars’ worth of my time into making one myself!</p>
</blockquote>
</li>
</ul>
<h4 id="alexa-skills">Alexa skills</h4>
<p>I also checked out making an Alexa skill instead of connecting with slack. I went through the <a href="https://developer.amazon.com/alexa-skills-kit/alexa-skill-quick-start-tutorial">quick start tutorial</a>, but my takeway was that the platform is too restrictive in terms of how you have to summon your skill.</p>
<p>Take my dog food app as an example. I wanted to make a skill so that anyone in house could just be like “Alexa, did the dog eat?”, “Alexa, did someone feed the dog?”, “Alexa, has the dog had dinner?”… If Alexa has my skill installed, it should know to use my skill to answer those questions. Instead you have to give your skill a trigger name like “Dog App”, and then people would have to say something like, “Alexa ask Dog App if the dog ate”, or “Alexa open Dog App”, or just “Alexa, Dog App”. People need to remember what the app is called, which is bad UX. It’s fine when your skill is brand related; everyone will remember that to hail an uber you have to say the word uber. But for smart home style questions, it seems very limiting.</p>
<p>When you build your skill, you provide all the possible use phrases, the ones that I mentioned earlier, like “did the dog eat” or “when did the dog eat” and you map these to a specific intent which your program can use to decide what to execute and return. So your skill effectively creates a mapping of ‘things that can be asked’ to ‘operations that should be performed or information that should be provided’, but it’s conditional on being triggered by the app name. I assume that was done to avoid the issue of having conflicts between different skills. Or maybe Amazon wants to keep control over these coloquial queries, and eventually release some Amazon-only smart home solution. I don’t know.</p>
<p>I tried to game it, but still wasn’t satisfied. Your skill name can only be 3 words or less, so I tried “did thedog eat”. Then when I said “Alexa, did the dog eat?”, my app was triggered. But you lose the flexibility of having multiple detection phrases, so everyone still has to remember to say “did the dog eat” and not one of the other ways to ask…</p>
<p>Anyways, this is what I gathered from the quick start tutorial and like 20 min of reading the docs. So I thought it would be easier for my family to just check a slack channel when they wanted to know if the dog was fed.</p>
<h3 id="thanks-for-reading">Thanks for reading!</h3>
</description>
<pubDate>Fri, 21 Jul 2017 00:00:00 -0700</pubDate>
<link>/2017/07/21/DigDogEat-Dashbutton-Raspberry-Pi-Slack-Hack.html</link>
<guid isPermaLink="true">/2017/07/21/DigDogEat-Dashbutton-Raspberry-Pi-Slack-Hack.html</guid>
<category>projects</category>
<category>IoT</category>
<category>raspberry</category>
</item>
<item>
<title>Blog Setup: Jekyll + Github Pages</title>
<description><p>My blog is back up and running. Here are some notes. The <a href="https://jekyllrb.com/docs/home/">Jekyll documentation</a> is probably a better reference.</p>
<h3 id="install">Install</h3>
<p>I followed the instructions here: <a href="https://help.github.com/articles/setting-up-your-github-pages-site-locally-with-jekyll/">setting up your GitHub Pages site locally with Jekyll</a>.</p>
<h3 id="layout-and-style">Layout and Style</h3>
<p>I wanted to make some tweaks to the minima theme so I followed the instructions here on <a href="http://jekyllrb.com/docs/themes/#overriding-theme-defaults">overriding theme defaults</a>.</p>
<h3 id="plugins">Plugins</h3>
<p>I wanted to use a plugin that would automatically generate a page for each tag where I could see all the posts that had been assigned that tag. Github pages <a href="https://help.github.com/articles/adding-jekyll-plugins-to-a-github-pages-site/">does not support many plugins</a> (<a href="https://github.com/jekyll/jekyll/issues/325">more on that</a>) but you can get around this issue by building your site locally and only pushing the static files. To do that I followed the instructions here: <a href="http://charliepark.org/jekyll-with-plugins/">Jekyll + Plugins + Github + You</a>.</p>
<p>Then I went ahead and <a href="http://charliepark.org/tags-in-jekyll/">installed the tagging plugin</a>. In order for it to work, I had to remove <code class="highlighter-rouge">group: :jekyll_plugins</code> from my Gemfile (<a href="https://jekyllrb.com/docs/plugins/#installing-a-plugin">see “installing a plugin” Jekyll docs</a>).</p>
<p>I also wanted to be able to embed youtube clips into my posts, so I used this plugin: <a href="https://github.com/pibby/jekyll-youtube">jekyll-youtube</a>. Again you won’t have issues with Github’s plugin restrictions if you take the “build locally” approach mentioned above. I also found a solution that lets you <a href="http://www.adamwadeharris.com/how-to-easily-embed-youtube-videos-in-jekyll-sites-without-a-plugin/">embed youtube videos in jekyll without a plugin</a> but didn’t use it because I had already done it the other way.</p>
<p>I haven’t done this yet, but I’d like to check out <a href="https://cwoebker.com/posts/latex-math-magic">using latex in jekyll</a>.</p>
<h3 id="workflow">Workflow</h3>
<p>Here’s what I added to my <code class="highlighter-rouge">.bash_profile</code>, you’ll need to change it for your directory structure. It assumes you are using the set up described in <a href="http://charliepark.org/jekyll-with-plugins/">Jekyll + Plugins + Github + You</a>.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c">########## jekyll blog aliases / functions #################</span>
<span class="nb">alias </span><span class="nv">st</span><span class="o">=</span><span class="s1">'open -a "Sublime Text 2"'</span>
<span class="c"># create a new draft function</span>
new_draft <span class="o">()</span>
<span class="o">{</span>
<span class="nb">cd</span> ~/Documents/Blog/jekyll/renschler.github.io.raw;
touch _drafts/<span class="k">$(</span>date +%Y-%m-%d<span class="k">)</span>-<span class="nv">$1</span>.md;
<span class="nb">echo</span> <span class="s2">"---
layout: post
title: </span><span class="se">\"</span><span class="nv">$1</span><span class="se">\"</span><span class="s2">
date: </span><span class="k">$(</span>date +%Y-%m-%d<span class="k">)</span><span class="s2">
comments: true
tags:
- draft
---"</span> &gt;&gt; _drafts/<span class="k">$(</span>date +%Y-%m-%d<span class="k">)</span>-<span class="nv">$1</span>.md;
st _drafts/<span class="k">$(</span>date +%Y-%m-%d<span class="k">)</span>-<span class="nv">$1</span>.md;
<span class="o">}</span>
<span class="c"># create a new draft</span>
<span class="nb">alias </span><span class="nv">draft</span><span class="o">=</span><span class="s2">"new_draft"</span> <span class="c">#Usage: draft TitleOfPost</span>
<span class="c"># preview blog with drafts</span>
<span class="nb">alias </span><span class="nv">previewB</span><span class="o">=</span><span class="s2">"cd ~/Documents/Blog/jekyll/renschler.github.io.raw; jekyll build --drafts; jekyll serve --drafts"</span>
<span class="c"># push latest blog</span>
<span class="nb">alias </span><span class="nv">publishB</span><span class="o">=</span><span class="s2">"cd ~/Documents/Blog/jekyll/renschler.github.io.raw; jekyll build;</span><span class="se">\c</span><span class="s2">p -r _site/* ~/Documents/Blog/jekyll/renschler.github.io;cd ~/Documents/Blog/jekyll/renschler.github.io;git add .;git commit -am 'Latest build.';git push"</span></code></pre></figure>
</description>
<pubDate>Mon, 17 Jul 2017 00:00:00 -0700</pubDate>
<link>/2017/07/17/Blog-Setup-Jekyll-Github-Pages.html</link>
<guid isPermaLink="true">/2017/07/17/Blog-Setup-Jekyll-Github-Pages.html</guid>
<category>blog</category>
<category>workflow</category>
</item>
<item>
<title>Glomp Attack: a rails app for sending GIFs</title>
<description><p>** Update (1/1/17): Glomp Attack is no longer operating.</p>
<p>I was brainstorming small business ideas when I stumbled on <a href="https://goatattack.com/">GoatAttack.com</a>. It’s a website where you can pay 79 cents to have pictures of goats text messaged to your friends. It’s a simple site that apparently made several thousand in revenue. Ok sign me up.</p>
<p>I partnered with <a href="https://twitter.com/tommygibbons46">Tommy</a> and soon <a href="https://www.glompattack.com/?utm_source=prblog&amp;utm_medium=post&amp;utm_campaign=prblog">GlompAttack.com</a> was born.</p>
<p><a href="https://www.glompattack.com/?utm_source=prblog&amp;utm_medium=post&amp;utm_campaign=prblog"><img src="/images/glompAttack.PNG" alt="Photo" /></a></p>
<p>For 79 cents you can send your friends pictures of hugs! Actually it’s better than pictures because they are gifs! The website is a rails app running on heroku. Message sending is powered by Twilio and payments are processed by Braintree.</p>
<p>Unfortunately, it’s not that funny, and it hasn’t paid for itself (yet). To quote some guy on <a href="https://redd.it/3q6jkp">r/shutupandtakemymoney</a>: “This is so fucking stupid. Good luck catching some idiots with this service.”</p>
<p>For the record it wasn’t a total flop. We sent it to our Moms and they liked it.</p>
</description>
<pubDate>Mon, 26 Oct 2015 00:00:00 -0700</pubDate>
<link>/2015/10/26/Glomp-Attack-rails-app-for-sending-gifs.html</link>
<guid isPermaLink="true">/2015/10/26/Glomp-Attack-rails-app-for-sending-gifs.html</guid>
<category>projects</category>
<category>rails</category>
<category>twilio</category>
</item>
<item>
<title>Hail Yeah NYC: an iOS app for finding cabs</title>
<description><p>** Update (1/28/17): This app is no longer available in the app store.</p>
<p>In November I competed at <a href="http://challengepost.com/software/hail-yeah">Hack Princeton</a> with my teammates <a href="http://www.hillwyrough.com/">Hill</a> and <a href="https://twitter.com/tommygibbons46">Tommy</a>. We developed an iPhone application that provides users a map of the best nearby intersections to hail a cab in Manhattan. It took home 2nd place in the software track and won the ‘Best Use of MongoDB’ award. Over the holiday break I cleaned up the UI and submitted it to the app store and now it’s live - <a href="https://itunes.apple.com/us/app/hail-yeah-nyc/id956423920?mt=8">Hail Yeah!</a></p>
<p>Below is the video of me pitching Hail Yeah at the hackathon.</p>
<div class="video"><figure><iframe width="640" height="480" src="//www.youtube.com/embed/5yrhWSTjThY" frameborder="0" allowfullscreen=""></iframe></figure></div>
<h3 id="how-does-it-work">How does it work?</h3>
<p>Our app uses a publicly available dataset describing the ~200 million taxi trips taken in and around Manhattan in 2013 [<a href="http://www.andresmh.com/nyctaxitrips/">Download link</a>]. Thanks to the Freedom of Information Act, the NYC government and related authorities provided details of every taxi trip, including where it began, where it ended, when it took place, and even how much the rider tipped.</p>
<p>First we bucketed the start location of these trips to their nearest intersections. Then for each intersection we broke down the trip totals by the day of the week and the time of day.</p>
<p>When a user sets a location in our app, we use the historical information described above to calculate the frequency of taxi pickups for all intersections within a quarter mile radius of the user’s location given the current day of the week and time of day.</p>
<p>The resulting information is presented as an intersection heat map, with a color scale at the top for reference.</p>
<p><a href="https://itunes.apple.com/us/app/hail-yeah-nyc/id956423920?mt=8"><img src="/images/Hail_Yeah_NYC.png" alt="Photo" /></a></p>
<p>The app was written in Objective C, it uses google maps, and our intersection database is hosted on Parse.</p>
</description>
<pubDate>Mon, 26 Jan 2015 00:00:00 -0800</pubDate>
<link>/2015/01/26/Hail-Yeah-NYC-iOS-app-for-hailing-cabs.html</link>
<guid isPermaLink="true">/2015/01/26/Hail-Yeah-NYC-iOS-app-for-hailing-cabs.html</guid>
<category>iOS</category>
<category>projects</category>
</item>
<item>
<title>Visualizing distributed power control</title>
<description><div class="video"><figure><iframe width="640" height="480" src="//www.youtube.com/embed/63XOaXwKSwU" frameborder="0" allowfullscreen=""></iframe></figure></div>
<p>I was working through <a href="http://www.amazon.com/gp/product/1107024943/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1107024943&amp;linkCode=as2&amp;tag=455note-20&amp;linkId=GETAOF75SDVA3VO6">M.Chiang’s Networked Life: 20 Questions and Answers</a> which is an awesome textbook touching on a wide range of networks topics.</p>
<p>The first chapter, “What makes CDMA work for my smartphone” covers mobile station <a href="http://en.wikipedia.org/wiki/Power_control">power control</a> which plays a crucial role in communication systems in terms of interference management, energy management, and connectivity management. Power control helps address the <a href="http://en.wikipedia.org/wiki/Near-far_problem">near-far problem</a> faced in non-orthogonal wireless systems like <a href="http://en.wikipedia.org/wiki/Code_division_multiple_access">CDMA</a>.</p>
<p>I created a d3 visualization that lets you explore a basic formulation of the distributed power control algorithm (with a fixed signal to interference ratio) over a narrow range of inputs. You can play around with it on <a href="http://bl.ocks.org/renschler/2aa319500f6ec57088ea">bl.ocks.org</a>.</p>
<p>Each receiving channel is assigned a target SIR that is randomly sampled from a uniform distribution with range 1-3. Each mobile station is assigned an initial transmit power level that is randomly sampled from a uniform distribution with range 1-3mW. Gains for interference channels are randomly sampled from a uniform distribution with range 0.01-0.10. These inputs are displayed in tables where each row corresponds to a given mobile station. The input values used here are arbitrary and don’t reflect actual numerical values observed in real cellular networks.</p>
<p>The transmit power of each mobile station is plotted as a line over time (i.e. over the DPC algorithm iterations). If there exists a set of transmit powers that satisfies all target SIRs, the minimal power solution is displayed in a table to the right of the input tables. Otherwise “<span style="color:red">No Solution</span>” is displayed.</p>
<p>Users can:</p>
<ul>
<li>alter the seed for the random number generator (this will generate different inputs)</li>
<li>set the number of mobile stations (3-9)</li>
<li>set the receiver noise (0.1-0.5mW) which is assumed to be the same for all channels</li>
<li>set the number of iterations for the DPC algorithm</li>
</ul>
<p>Source Code: <a href="https://gist.github.com/renschler/2aa319500f6ec57088ea">gist.github.com/renschler</a></p>
<p>Reference: M. Chiang, P. Hande, T. Lan, and C.W. Tan, “Power control for cellular networks”, <em>Foundation and Trends in Networking</em>, vol. 2, no. 4, pp. 381-533, July 2008.</p>
</description>
<pubDate>Sun, 26 Oct 2014 00:00:00 -0700</pubDate>
<link>/2014/10/26/Visualizing-distributed-power-control-d3.html</link>
<guid isPermaLink="true">/2014/10/26/Visualizing-distributed-power-control-d3.html</guid>
<category>d3</category>
<category>networks</category>
<category>projects</category>
</item>
<item>
<title>Visualizing simulated commuter flows between US counties</title>
<description><div class="video"><figure><iframe width="640" height="480" src="//www.youtube.com/embed/9C4gU8o6_z0" frameborder="0" allowfullscreen=""></iframe></figure></div>
<p>** Update (6/20/2017): Github now only allows access to 10 files per Gist, so you’ll need to <a href="https://gist.github.com/renschler/906685a5f1b1972640e7">clone the repository</a> and open index.html in a browser to play with the d3 visualization.</p>
<p>I created a d3 visualization to explore commuter flows between US counties that were produced by my implementation of <a href="http://www.nature.com/nature/journal/v484/n7392/abs/nature10856.html">Simini et al. (2012)’s</a> radiation model. You can play around with it on <a href="http://bl.ocks.org/renschler/906685a5f1b1972640e7">bl.ocks.org</a>. The selected county appears <span style="color:red">red</span> and you can toggle between commuter flows into and out of the county.</p>
<p><a href="http://en.wikipedia.org/wiki/Radiation_law_for_human_mobility">Radiation models</a>, have been shown to improve the accuracy of describing many processes (in addition to commuting) that are affected by mobility and transport including migration, trade, and communication.</p>
<p>My radiation model used 2010 county level census data to generate inter-county commuter flows [<a href="https://github.com/renschler/radiationmodel">radiation model source code</a>].</p>
<p>Although there are limitations to the results it’s cool to see that this basic radiation model captures some long-distance movement patterns that other mobility predictors (like the <a href="http://en.wikipedia.org/wiki/Gravity_model_of_trade">gravity model</a>) struggle with in the absence of data needed to fit parameters. For good examples check out Miami-Dade, Florida; Cook, Illinois; and Clark, Nevada.</p>
<p>As a future project I’d be interested in applying a radiation model to investigate the dynamics of human mobility and disease transmission across nations where accurate mobility data is not always available.</p>
<p>D3 Source Code: <a href="https://gist.github.com/renschler/2aa319500f6ec57088ea">gist.github.com/renschler</a></p>
<p>Radiation Model Source Code: <a href="https://github.com/renschler/radiationmodel">github.com/renschler/radiationmodel</a></p>
</description>
<pubDate>Sun, 14 Sep 2014 00:00:00 -0700</pubDate>
<link>/2014/09/14/Visualizing-US-County-Commuter-Flows-Radiation-Model-d3.html</link>
<guid isPermaLink="true">/2014/09/14/Visualizing-US-County-Commuter-Flows-Radiation-Model-d3.html</guid>
<category>d3</category>
<category>projects</category>
</item>
</channel>
</rss>