Hacker CMS is a simple CMS that Kenton wrote in a day as a demo of what can be done on Sandstorm, powered by Jekyll with an embedded Ace editor.
Fun fact: my blog server is only running while I’m editing, e.g., when I have the grain open on Sandstorm. But it stays up because it’s behind Cloudflare.
Also, because it’s behind Cloudflare, I can make modifications on the edge with Cloudflare Apps. Here are the Cloudflare Apps installed on this blog:
Additional modifications on this blog:
The great thing is, neither of those add-ons require the server to be up to work, similar to how the Cloudflare Apps also don’t require the server to be up. :)
All-in-all, I’d say I’m striking a reasonable balance between customizability and convenience. That is, it’s neither the most homebrewed DIY blog solution possible nor is it the most automated not-really-customizable consumer-edition.
This post was originally published on my other food blog and the recipe requested by friends and family for the past couple years.
Gluten free, high protein, and has the carb-y mouthfeel of a real bread dinner roll.
I feel like the vast majority of culinary innovation in human history has been about making carbohydrates taste like protein, yet there is so precious little in the way of making protein taste like carbohydrates. So I experimented around a bit and came up with this. (Variants of this also include pancakes, English muffins, etc.)
Spray a muffin tin with cooking spray (or grease it with butter) and let rest in freezer. Preheat oven to 350 F.
Mix dry ingredients together in one bowl. Mix wet ingredients together in separate bowl using a mixer.
Slowly add dry ingredients to wet ingredients while mixing.
Remove muffin tin from freezer (you’ll see a thin film of solid grease on its surface), and fill the wells 1/2 - 2/3 full.
Bake for 12 - 15 min. or until golden brown (see photo). Timing may depend on the idiosyncracies of your oven.
Let cool on cooling rack.
The doorbell finally works! SMS-to-Pebble notification, and no delay on ding-dong audio.
Over my holiday staycation, I decided to start working on my long-delayed doorbell project. Backing up for a moment: I have a confession to make about tech debt. For many years, we have not had a functioning doorbell and relied on a well-documented workaround.
Faded post-it note reads: “Does not work; please knock.”
My husband Kenton has had the idea to make a smart doorbell since the construction of the house but simply got too busy to actually work on it. And continued to be too busy. For seven years. So I took matters into my own hands. (To be fair, some of those years include us co-founding a startup together and then starting our new work at Cloudflare. And he did start by implementing our home security system, and then ran out of free time.)
Note: this is my first Arduino project, and though I have a few small electronics projects under my belt, I do not by any means claim to be an expert.
Ingredients: Node.js, Arduino, Pebble (paired to Android phone), Twilio API, Audacity, Sugru, lead-free solder, a box of Whole Foods mints, hot glue gun, and a bunch of npm packages.
Circuit diagram scrawled on a post-it note with color labels to help me keep track.
That’s the short version, the pretty-straight-forward version. But the truth about building it and no-filter overly-honest-methods story with all the missteps along the way is a more fun story to tell. So here’s how the adventure started.
(as scrawled in dry-erase on a whiteboard.)
In preparation for having some stay-cation time, I order all my supplies early so I have all of my days off to work on the doorbell project. It shouldn’t take long, right? ;)
This is my very satisfying haul:
My holiday Adafruit haul (clockwise from top): mini-breadboard, alligator clips, rubber feet for Arduino, Arduino, jumper cables, resistors.
Actually, before making sure the button works, the first step is to figure out which wires in the server room correspond to the doorbell at the front door. Luckily, Kenton left most things reasonably well-labelled, so the only wire bundle left un-labelled should be the doorbell, but I still needed to use a multi-meter to check which wires in the bundle were actually hooked up to the doorbell.
There were 6 wires in a brown bundle coming out of the wall. Each pairwise connection appeared to have infinitely high resistance, except for one pair, which was negligibly low. That’s good. Lower than I was expecting (is the button stuck in the on position?), but pretty sure those are the relevant wires.
Six wires terminating in the server closet.
Next, I unclipped the doorbell from the wall by the front door, and unscrewed the wires holding it to the plate. Pressed it a few times. Feels like a good button, smooth action, and is not stuck in any way. That’s good. Here’s a diagram of how the doorbell should hook up.
Left: original circuit diagram for how the doorbell is hooked up. Right: after ripping out the bulb. “Computer” here means Arduino, server, and literally everything else. (Scribbles along the periphery: Factorio diagrams.)
Just to be thorough, I test the button with the multimeter to confirm the button does what I think it does. Nope. Fully pressed and not-pressed are both approximately the same as a piece of wire. Huh. Options at this point:
My first choice was (1) so I shopped around on Amazon, but literally all the options were either ugly beige, full of cast-iron-looking frilly decorations (which don’t match the aesthetics of the house and would result in complaints from Kenton, who will definitely notice – in fact he rejected all plausible options for being too ugly), or part of a walled garden smart doorbell system which requires me to use some company’s proprietary app. So I walk to Fry’s and my luck there isn’t any better. But I impulse purchase some LED kits – well, not impulse purchase. I have another project I’m planning. More on that in a future post.
So I might as well take the doorbell apart as a puzzle if I’m planning to buy a new one anyway. So I disassemble it, and the connectivity of the metal parts are exactly what I’m expecting (see diagram above), and there’s a tiny incandescent bulb. Incandescent. Wow, when was the last time I saw one of these?
I measure the resistance across the switch (the two bendy metal parts the button applies pressure on) as I press the metal parts together. That part works fine. Infinite resistance to zero to infinite as I press and lift. Good. Let’s see what happens when I measure across the whole button circuit when pressing it. Doh. There’s no change when I press the button because it’s like it’s always pressed. It’s like the light bulb is a wire.
OH: I’m pretty sure burnt out bulbs are basically, like, insulators.
Let’s measure across the bulb and see. Oh hey, approximately zero ohms.
Me: Nope, I’m pretty sure this burnt out bulb doesn’t care what you think. It’s basically a wire.
Well, I guess I could just rip out this bulb and it would work. Do I really care if the doorbell lights up? Could someone find the button in the dark? Well, there’s other ways to fix that. I have glow-in-the-dark nail polish left over from Halloween. :D
So I rip out the bulb, paint the inside of the button with a few coats of glow-in-the-dark nail polish, let it dry overnight, and reassmbled the button in the morning. Fixed! Now the right side circuit diagram (from above) applies.
Now that I have a working button, I followed the Arduino Button Tutorial. Success, the button tells the LED to light up when pressed!
Next, I integrated the Twilio API (meteor add twilio-meteor), so each button press sends me a text message, which you can see on my Pebble.
Now to play a ding-dong sound. I learned by reading this ChromeCast-Arduino sketch that one can send an HTTP request to a Chromecast to play a sound. So the first step is to make sure my button presses can send an HTTP request, and I used RequestBin to test.
It’s hard to see, but in the beginning, the last request on RequestBin was from 15m ago, and after the refresh, the last request is from 12s ago.
And I was pretty sure I’d prefer to use the breadboard in my next project, so I sacrificed a couple jumper cables, soldered the 10 KΩ resistor to them as per the diagram, and put it in this mint box. Since I don’t have a heat gun, I used a hair dryer on the heat-shrink tubes.
I added some holes on the box to make room for the cables to come out, and used hot glue to make thise edges not sharp. I also hot glued a piece of plastic to the bottom of the tin so the arduino would (1) fit snugly and not jostle about and (2) not be sitting directly on the metal.
Useful things I’ve found in Kenton’s junk drawer: heat-shrink tubes, USB-B cables (a.k.a. “random old printer cables”), lead-free solder, a soldering-kit that I gave him as a birthday gift several years ago, wire-cutters, wire-strippers, various screwdrivers, and hot glue gun (I guess that’s from my random crap).
During testing, sometimes I give the button a nice firm press in the center, and sometimes, I grab it by the edge and maybe it flutters a little on the way down. This is a problem because fluttering (the technical term is switch bounce) would result in me receiving anywhere between 2 and 10 SMS messages from a single button press. Oops.
There are a few options to consider on how to debounce:
Any of them would have worked fine, but I decided to implement the debounce in the Arduino sketch because I have an intuitive bias towards fixing the problem closer to the source. There is a ‘proper’ way to debounce in Arduino-land, and reasons not to implement my quick-and-dirty debounce (which is inserting a simple delay to all processes of half a second after each press), but I don’t intend to have other sensors or components attached to this particular Arduino for this project, so this doesn’t throw other components off.
Also, it was 2AM and I just wanted to fix this one bug before declaring victory and going to sleep.
This resulted in a 12-second delay between button press and DING-DONG.
Of course, starting up the YouTube App in Chromecast might have something to do with it. So, the next implementation plays a ding-dong mp3 file which I edited heavily in Audacity so that it was loud enough and short enough.
This resulted in about a 5-second delay between button press and DING-DONG. Still too long.
Now I’m fresh out of ideas on how to shave off more seconds of latency, so I swivel around and ask Kenton for help, who suggests that I don’t use Chromecast, and play locally through speakers instead. Next steps:
Part of step (2) is making the whole thing a plain Node.js app.
My first implementation was a Meteor app, using this meteor serialport package, because it was super easy and straightforward to use. However, using that particular package pinned me to an older version of Meteor. That was ok at first when I was playing audio via Chromecast and I just wanted to get something working quickly.
But after deciding to ditch Chromecast, I need to play audio via speakers, and as I found myself shopping around, all those npm audio packages required a newer version of Node. Embarrassingly, it took me a bit of time looking at dependencies, wondering if I could get away with just using older versions of the audio packages, before I realized that would be way more work than removing the Meteor layers so I could use the current version of Node. I’m so used to Meteor that this felt like venturing into uncharted waters. I’d hit Command+S and stare at Chrome like a chump, waiting for it to refresh by itself.
One evening of futzing around and one-more-bugfix-and-it’s-ready-to-deploy…
Fast forward to mid-January after the Amp arrives…
After a shipping delay, the amp finally arrived in mid-January, so when I found some free time, I hooked it up to the living room speakers.
Actually, I misread Kenton’s labels and first hooked them up to the speakers in the wrong room before fixing it. And made poor contacts the first time which resulted in a distorted, noisy ding-dong, rather like you’re hearing the ding-dong on a car radio that’s going through the mountains.
Since this was a very basic amp that accepted raw wires, I had to be careful with the amount of pressure I put onto the little pieces of plastic and springs that held it into place. There are plenty of things I’m good at. Not breaking tiny plastic components whilst clipping them into place is not one of them.
I actually did break one of the little buttons, which came loose from the spring, but was able to put it back together. Phew. o_O
Currently, the doorbell functions as described in the how-it-works at the top. It successfully plays exactly one ding-dong every time the button is pressed and sends exactly one SMS message to each of our phones.
Arduino enclosed in mints box, connected to server via USB, and connected to doorbell via wires that go into the wall, with alligator clips extending the reach slightly. And the server is also connected to the amp via USB, which is connected to speaker wires that run through the walls. Next version will have a better wiring solution. But Garply (the cat) isn’t allowed in this part of the server room so it should be fine for now.
Great. Finally it works perfectly. So we keep the server running all the time now, right?
So we leave it running like we intend to, and eat dinner, watch a movie or two. A few hours later… DING-DONG. I run to the door, but there’s no one there. Huh. I test it, and it works as intended. Another few hours later… DING-DONG. And no one there. Maybe one of the alligator clips touched something from a breeze in the server room. So I apply some tape, in case that fixes the issue. A little while later, shortly before bed … DING-DONG. Ugh.
I have a few hypotheses about the phantom ding-dong that I can test, but in the meantime, the doorbell server isn’t up, but I haven’t put up a new post-it note yet. >_>
If any store-bought product did exactly what we wanted, I would almost certainly have bought a product instead. However, every doorbell product I looked at was guilty of at least one of these:
Many people might not consider the last one to be a deal-breaker, but personally, I would prefer that:
If you want to holler at any IoT product makers to make their products self-hostable, please tweet them at me (@qiqing) – I’d love to help make that happen so I can use their products. Until then, great excuses to follow tutorials and build things myself!
Over the course of working on this project I’ve come to appreciate my strengths and weaknesses, which is important for knowing when to ask for help.
I kept thinking, I’ll write the blog post about this project after I’ve fixed this one bug. But I’ve been one issue away from posting for the last several issues…
Next steps: write a logger. Get some logs. Fix this phantom ding-dong bug. Stay tuned!
Big thanks to Kenton for getting me unstuck, and thanks to Kenton’s Minneapolis friends and other LAN party guests for helping eat all those mints since I needed the container.
Last month, on my commute, I was rather spellbound by this video from Tasty (Buzzfeed) on the making of the jiggly cheesecake:
So during the first week of my holiday staycation, I decided to give it my own spin. After watching someone else recreate this and the initial reviews, I decided to double the cream cheese (from 4 oz to 8 oz) in the original recipe and otherwise leave the recipe basically unaltered.
Conclusions: it was light, fluffy, and tasty, but didn’t quite taste like “cheesecake.”
Next iteration: double cream cheese again to see what happens.
It’s time to start over. Starting in 2018, this blog will be largely project-driven, from Arduino hacks to jiggly cheesecakes.
And sometimes, Garply wants to help.
Archive of previous blogs will still live on here: