Fri Mar 21 20:58:25 PDT 2014

replacing the battery in a cheap solar charger

So I've got a very cheap solar charger, whose internal li-poly battery has been slowly dying, and is now mostly useless. Popping it open, I discover it's a 800mAh unit.

Why, robotmesh.com, my place of employment, just happens to sell 850mAh li-poly batteries! How convenient.

So let's replace this sucker.

While I've got it open, though, I want to see how much current the little solar panel can actually source. All you need to do this is a single multimeter, though it's more convenient to use two, one bridging the positive and negative rails, to measure voltage, and one inserted in the current flow, to measure amperage. (If you get it backwards, the ammeter will look like a dead short to the voltage source, and either blow a fuse or melt your test leads.)

Experimental apparatus

(Diagram made with Circuitlab, which can apparently do all sorts of fancy simulation stuff, none of which I actually used.)

This looks very neat and clean on paper, and becomes a horrifying tangle of wires when implemented with multimeter leads and alligator clips. (Mostly hidden off-frame)

I set everything up, ready to finally, at last, read off the current...

And it's way off the low end of the scale. Switching to the digital meter, I discover that even in direct sunlight, the charging circuit can only manage a thoroughly unexciting 7mA. Assuming perfect charging efficiency, (which ain't gonna happen) it'd take 121 hours of direct, face-on sunlight to recharge a flat battery.

I wrote a gloomy analysis of a fictional solar charger on the other blog, and even with my worst case assumptions, this real-world solar charger is more than 26 times worse. Time, and sunlight, has not been kind to its panel.

So, now that I know how much it sucks, it probably wasn't worth spending 7 bucks to put a new battery in it, but oh well, let's close it up again.

Today's stars are my old Weller P2K butane soldering iron, here used just for the heat-shrink, a crappy Tenma unregulated soldering iron, a Panavise PCB holder that they apparently don't make anymore, and some Radio Shack "helping hands". A depressing amount of the work that goes into doing electronics stuff is fixturing-- getting things to stay in the right position while you do things to them.

I took six photos here, all of them in varying degrees of out-of-focus.

Someone more professional than I would probably have done a lapped splice here, in which case it's very important to slip on the heatstrink before you solder the joint, but I did a twist splice because I'm lazy and the joint wasn't going to take any mechanical stress anyway.

And we're done! Now I have a charger which should last several more years, at which point I will throw it right into the trash.


Posted by Samuel Bierwagen | Permanent link | File under: important, Engineering

Thu Mar 13 22:41:11 PDT 2014

introducing tinypass.py v1.0

Before I can talk about what I did right, I have to talk about what I did wrong.

I host some files for a friend. They're great big zip files full of art, which he sells for money, so he'd like to put a password on them.

"Easy enough, this is exactly what HTTP Basic authentication is for."

But he'd like to be able to set passwords on files without having to ask me to manually fiddle with nginx config files.

"Well, I'll just whip up a quick forms-based thing for editing nginx config files. How hard could it be?"

(A chill wafts over your skin. Dread shivers up your spine.)

It took POSTed form data (filename, username, password) from a static HTML page, created a hashed password file from that password, appended a location /filename block to a config file, then called /etc/init.d/nginx reload.

And as soon as it was actually used by someone who didn't write it, it blew up.

Oh v0.1, there were so many things wrong with you, how could I possibly count them all?

1.) It had to have permissions to edit nginx config files and reload the server. So I just ran it as root, which meant that I was running a python web server as root, which is an absolute security disaster. I'm listing this first, even though nothing bad actually happened (as far as I can tell) because it was just a complete unforced error. This was the first warning sign that I was doing something dumb, and I completely ignored it.

2.) filename was just a text box, not a dropdown menu or picker, so it was trivially easy to typo a filename, and "set a password" on something that didn't exist. v0.1 had no error checking of any kind, so it couldn't refuse to do that.

3.) HTTP Basic is user-granular, but for this particular use we're doing file-granular permissions. HTTP Basic doesn't handle this very gracefully: if you're already logged in, and try to access a file you don't have permissions for, (say, if you bought several different items, or if you're me, and are trying to troubleshoot your broken fucking login system) then it just hits you with a 405 Authorization Needed error, no login window. Since HTTP Basic doesn't have a log out button, (hint: where would you put it?) you have to restart the browser, or just wait around until the browser expires your login credentials, which is, as you'd guess, implementation-specific.

4.) Remember when I said that it just appended lines to a config file and reloaded the server? v0.1 had no conception of records-- it was a basic CRUD app in theory, but in practice it only created records, it couldn't read, update or delete them. It would quite happily, create two location blocks for the same file.

Nginx will refuse to load a config file that has contradictory options. If you restart it with a bad config file, then it won't start back up, and your web server goes down until you fix it.

A minor decision I made early on really saved my ass here. I heard that using reload instead of restart let nginx wait for clients to finish transferring data, so I used it in the script. Luckily, reload won't take down your sever with a bad config file, it'll just refuse to load it.

So instead of blowing up the server, v0.1 just silently stopped applying changes until the config file was manually fixed.

Now, all these problems have solutions. You could conceivably train the end user to carefully work around the problems, on the theory that your software is great but the user is dumb, but when your tool collapses in a great heap of splinters at the slightest touch, then it's not the fault of the user, it's your fault.

You could also fix each of these bugs, add tests, etc, but the basic architecture of the program is just bad. It's fucked.

Ctrl+a, del.

Let's try again.

A nice screenshot of the tinypass.py github project

tinypass.py v1.0 is designed to replace HTTP Basic with something about as secure, but a little friendlier to use, as well as letting the end user set and change passwords without fatally confusing nginx.

Rather than sending login credentials in the clear over HTTP headers, like HTTP Basic, tinypass.py sends credentials in the clear over cookies, which is much more secure. Best practices here would be hashed passwords and session ID cookies, which would require more work. I didn't feel like doing that work, because...

"Principles of an Indie Game Bottom Feeder"

I don't really make a living selling games. I sell an ethical life.

How could I make a living selling games? Anyone who wants to pay me for my games doesn't have to. It's not like buying a chair, where they'll chase you down and taser you if you grab it and run out of the store. Nobody who wants my game on Windows or Mac has to pay for it to get it. Frankly, most of them don't.

So why do people pay for it? Because they understand a fundamental fact: For these games to exist, someone has to pay. If everyone just takes it, I'll have to get a real job and the supply will shut off. I don't want to get into one of the eternal tedious arguments about "software piracy". I will instead focus on one single, incontrovertible fact: I have a family to feed. If nobody pays for my games, I can't make them.

So what does someone get when they pay for my game? They get the knowledge that they are Part of the Solution and not Part of the Problem. They know that, in this case, they are one of the Good Guys. It is well-earned self-satisfaction, and it is valuable. To know they are doing the right thing, some people will happily pay 20 bucks. This is how I stay in business.

You can't stop piracy. DRM never works. You can't let somebody look at something without also letting them copy it. Cannot be done, impossible, full stop.

So tinypass.py is a speedbump, not an impassible wall. Since there are no confidential login credentials at risk, I don't go to any great lengths to keep them secure.

So hey! That's it. Check it out, I guess, just as long as you don't look at the commit history.


Posted by Samuel Bierwagen | Permanent link | File under: important, Linux

Mon Oct 28 22:48:43 PDT 2013

programmatically advertising mobile bandwidth cost: a proposal

You know what would be cool? If your phone knew how much bandwidth from each carrier cost, and could switch between them on the fly, depending on which one was cheapest, like a multi-SIM phone that didn't suck.[1]

You know what would be cool? If your phone could roam between a cell tower and an arbitrary wifi AP, like a parallel-universe version of UMA that also doesn't suck.

You know what would be cool? If wifi APs could programmatically advertise bandwidth cost too, so anyone could compete with AT&T just by nailing a linksys router to a wall.[2]

You know what would be cool? If your DSL modem[3] could advertise bandwidth cost too, just like your wifi AP and your cell tower. You'd have to pay common carrier costs for the last mile of cable to your house, no way around that, but as soon as your bits make it to the first point of presence, you'd have you choice of long-distance IP transit providers, just like the last time we broke up a telecom monopoly.[4]

All these ideas seem very simple and obvious. Have they been proposed before?


1: Bandwidth is a utility service, like electricity, or water. Any profit a utility monopoly makes is extracted from the productive economy, a tax on real industries. AT&T made $3.8 billion last quarter.

2: The implementation details of this one are going to be tricky. With a major carrier, you can just tally up all the kilobytes used and bill the user at the end of the month, but with wifi, it's entirely possible a person will walk into a starbucks, watch a video on youtube, then walk out, never to return. How is that billing system going to work? Are you going to have to manually provide billing information before connecting? That would be terrible.

3: Well, "transceiver".

4: Honestly, I anticipate a lot less benefit from this one. Transit is already a very competitive commodity market, with razor-thin margins. The biggest problem with consumer internet has always been that last mile, and the associate incumbent telcos, who have no useful competition, and therefore lots of monopoly profit.

You'd almost have to mandate embedded cell phone radios in terrestrial internet transceivers in order to guarantee last-mile diversity... wait, shit, that's a great idea!


Posted by Samuel Bierwagen | Permanent link | File under: important, Engineering

Sat Aug 31 02:22:57 PDT 2013

Review: "Apocalypse Codex" by Charles Stross (2012)

My tweet about the Apocalypse Codex

Actually, I want to expand on that.

Apoc. Cod. is a book that either needed another rewrite or a more aggressive editor, which is odd, for an author's 20th book.

Its sins are numerous. Stross has picked up an unfortunate habit of repeating himself-- SCORPION STARE is explained several times, and at many points where characters explain what's going on to other characters, instead of eliding the details, he'll actually spend a couple pages on the conversation. These recaps would be useful in a longer, more complex novel, but Apoc. Cod.'s tight structure and fast pacing work against it, (And its 336 page length) making the frequent reiterations of the plot more annoying than useful. (Plus, I powered through the whole thing in 5 hours during a car ride, which helps to keep events fresh in your mind.)

The book does have some fairly good moments, to the point where the usual in-car soundtrack of classic rock FM radio became grating, and I wished for something gloomy, sepulchral.[1] The despond is punctuated by some unfortunate attempts at soapboxing. One of the characters, much like the author, is an atheist, and by God he's gonna let you know about it.

This is ill-advised. Evangelical Christianity is best criticized by repeating their ludicrous bullshit with a straight face. (Did you know that Pat Robertson has a long list of divine revelations?) The Quiverfull ideology mentioned in the book is a real thing that actually exists. With all this rich material, having a in-universe character actually say "These people are super dumb" is redundant, bordering on jejune. We get it, dude. You don't need to have zombie missionaries smashing in the doors to get the point across.

Another problem is the hero, a computational demonologist and former IT schlub.

There's an authorial voice that's peculiar to nerds in general, and science fiction fans in particular. It shines through clearly in print in books like Fallen Angels (which contains paid-for cameos by big name fans) and the execrable Troper Tales of tvtropes, which were so bad that they've been quarantined on another site. It's distinctive as it is annoying.

When he's not actually holding a gun, Bob talks like a slashdot commenter. This is,

A.) Top notch characterization, and spot on accurate.

B.) Super, super irritating.

I found myself skimming early conversations just to avoid reading what the main character actually said, which is unhelpful for following the plot. This is another example of Stross' mania for absolute factual accuracy, which can occasionally get in the way of the story. (He emphasizes several times that the life of a spy is boring, and not at all like a Bond flick, which is troublesome when you're pretty much writing a bond flick.)

The book's okay. I guess.


1: While writing this, I discovered that Catacombs is actually a one man band, run by a fellow named Xathagorra Mlandroth. Xathagorra Mlandroth! Gosh I love funeral metal.


Posted by Samuel Bierwagen | Permanent link | File under: important, nerdery

Wed May 29 00:28:23 PDT 2013

keeping my ass warm

So I was reading the owner's manual for the 2013 Nissan Leaf, (as you do) because I was wondering if it said anything about overuse of rapid charging.

Every time I bike to the grocery store, I see a Leaf connected to the 440V DC fast charger, (Google Kirkland is five minutes away.) which can put an 80% charge on a car in 30 minutes.

But batteries suck. Charging a battery in 30 minutes in precisely analogous to discharging it in 30 minutes-- something big lithium-ion batteries don't like. Sure enough, page 43:

Batteries don't like to get too hot or too cold, to be discharged too hard, too deeply, or left discharged for too long. You might then conclude that the best choice is to just leave the car in your driveway-- where the battery will then just quietly decay on its own. Batteries suck.

Also, page 187:

This makes a lot of sense-- heating pads are orders of magnitude more efficient at warming humans than using air as the transfer fluid. In an internal-combustion vehicle, you get hot air for free, since a heat engine has to dump a lot of heat to the outside environment in order to extract useful work from it, you might as well pass that waste heat stream through the cabin, like a not-terribly-efficient cogeneration setup.

But in an electric vehicle, every watt-hour of power comes from the battery pack, and each watt-hour is dear indeed. Heat is no longer free.

Bold prediction: Heated seats will be standard equipment in all electric cars.


Posted by Samuel Bierwagen | Permanent link | File under: Engineering

Thu May 23 02:50:48 PDT 2013

Bad Transcript: Star Trek Into Darkness (2013)

I wrote a Bad Transcript for the new Star Trek movie. It's pretty good, you should read it.

The transcript, that is. The movie isn't good.


Posted by Samuel Bierwagen | Permanent link | File under: important, Meta

Fri Jan 4 21:03:31 EST 2013

building dtwenty.org

767 days ago, I commented on a HN submission about a random number generator:

3.) Providing random numbers as an advertisement for your fine line of hardware random number generators. Here it doesn't matter how much money you make [providing the numbers], you just want people to buy the hardware that made them. Oddly enough, none of the random number services (and there are quite a few) do this, for some inexplicable reason. There's not even an argument-from-proprietary technology, since HRNGs are supposed to generate perfectly random noise, and there's no way an attacker could stage a replay attack.

I left it there, because I was lazy. But last month, notorious badass Maciej Cegłowski created The Pinboard Co-Prosperity Cloud.

What is it?

The Pinboard Co-Prosperity Cloud is a startup self-incubator. Six successful applicants will receive a modest amount of funding and as much publicity as I can provide for their sustainable and useful business idea.

Is this a joke?

It is not a joke.

What are the requirements?

You must have a good idea that you are capable of building, a willingness to build it, and a plan for making it mildly profitable.

How much funding will I get?

Each successful applicant will receive $37. This will cover the cost of six months of hosting at prgmr.com and a productivity-enhancing hot beverage.

So I entered. Ha ha why not?

The more I thought about it though, the more I realized that I wasn't getting the joke. The idea was trivially simple. I already had a web server. I didn't need all that mad cash. I could just... build it.

So I did. It's right here. (EDIT 2013/3/22: I let the domain name lapse, and moved the content to bbot.org)

It was amazingly easy, even though this was pretty much my first major (har) piece of programming. I had never used python, javascript, or jquery before.

Web programming in the year 2012 has the smooth, well polished feel of something that has had the sharp edges worn off by the passage of thousands of other people. Getting nginx to talk to the WSGI server was a snap. Installing bottle.py was easy. JQuery was no problem.

Any time I had a problem, googling the error message would return a helpful, relevant page, explaining how my "build it as fast as possible, while learning as little as possible" design methodology had screwed me over again.

At the time, of course, it seemed a vast edifice of impossible complexity, but in retrospect it was painless. "It's easy to do if you know how to do it", maybe.

The only difficulty I faced was the hardware random number generator. The numbers had to come from it, since that was the whole point of the site; but my server was a virtual machine on the east coast, and my HRNG was sitting on my desk.

The "money" solution would be to buy a rackmount server, plug the widget into it, then slot it into a colo, but I didn't have money, and instead I had to be creative.

I couldn't just run the web server locally, since my ISP blocks port 80. Enter the ugly hack: I plugged the entropykey into a spare laptop, ran the application server on that, then ran a SSH tunnel to my web server, which communicates with the front end via JSON. It works, at the cost of an extra 150ms of latency per roll.

There's room to improve, of course. You could probably list off a dozen features dtwenty.org needs without pausing to draw breath, (starting with "make it less ugly") but, the ideal of the minimum viable product shines bright.

The second biggest problem after integrating the HRNG was the ad copy that makes up most of the page. It was originally twice as long-- ruthless editing has reduced to it merely "too long" from "far, far too long." This too could use improvement.

But! It's done and it works! Programming is fun.


Posted by Samuel Bierwagen | Permanent link | File under: important, Linux

Sun Dec 9 23:49:30 EST 2012

"How would I get started" and the problem of truth

I've been meaning to write about Hacker News again, but have held back, since it's a pretty boring subject outside of HN's rather shallow pool of users. But recent events have forced my hand.

"How would I get started?"

Last night on Hacker News, someone asked a simple question with a complicated answer: “I want to build a cable company. How would I get started?”

I’m really disappointed in the universally pessimistic and generally unhelpful answers this question received. Some people pitched some interesting ideas and helpful analysis, but most of the replies reinforced the notion that Hacker News readers are predominantly male know-it-alls and on the average, a bunch of snarky dicks.

Lots of emotional content here, but not much meaning. The attitude behind these two paragraphs becomes clearer if we look at some other quotes:

"Black Swan Farming"

In startups, the big winners are big to a degree that violates our expectations about variation. I don't know whether these expectations are innate or learned, but whatever the cause, we are just not prepared for the 1000x variation in outcomes that one finds in startup investing.

That yields all sorts of strange consequences. For example, in purely financial terms, there is probably at most one company in each YC batch that will have a significant effect on our returns, and the rest are just a cost of doing business. [1] I haven't really assimilated that fact, partly because it's so counterintuitive, and partly because we're not doing this just for financial reasons; YC would be a pretty lonely place if we only had one company per batch. And yet it's true.

To succeed in a domain that violates your intuitions, you need to be able to turn them off the way a pilot does when flying through clouds. [2] You need to do what you know intellectually to be right, even though it feels wrong.

It's a constant battle for us. It's hard to make ourselves take enough risks. When you interview a startup and think "they seem likely to succeed," it's hard not to fund them. And yet, financially at least, there is only one kind of success: they're either going to be one of the really big winners or not, and if not it doesn't matter whether you fund them, because even if they succeed the effect on your returns will be insignificant. In the same day of interviews you might meet some smart 19 year olds who aren't even sure what they want to work on. Their chances of succeeding seem small. But again, it's not their chances of succeeding that matter but their chances of succeeding really big. The probability that any group will succeed really big is microscopically small, but the probability that those 19 year olds will might be higher than that of the other, safer group.

The probability that a startup will make it big is not simply a constant fraction of the probability that they will succeed at all. If it were, you could fund everyone who seemed likely to succeed at all, and you'd get that fraction of big hits. Unfortunately picking winners is harder than that. You have to ignore the elephant in front of you, the likelihood they'll succeed, and focus instead on the separate and almost invisibly intangible question of whether they'll succeed really big.

"Why I now, unfortunately, hate Hacker News"

raffi 114 days ago | link

Most companies fail. It's a safe bet to predict failure. It's pretty lame to celebrate that failure from the sidelines.

Vision is not "how is this guaranteed to fail?" but how could it possibly succeed despite the odds?

A core tenet of hacker ethics, the zeroeth law perhaps, is being right, having correct perceptions regarding the universe. A map that matches the territory.

Under this ethical system, the above statement makes less than no sense. The most likely outcome is failure... but you shouldn't predict failure?

However, the way startup financing is currently organized, a VC fund can shrug off a dozen miserable failures to chase the one Google or Intel.

The purpose of Hacker News is to advertise Y Combinator startups, such as 9gag. The purpose is not to act as a prediction market. In fact, since one of the major routes of of startup profitability is being purchased by another company, accurate predictions of value are contrary to Y Combinator's interests. Y Combinator wants valuations as high as possible.

Someone starting a new cable company in 2012 is very likely to fail. This is the correct prediction: it is the outcome with the highest probability.

But a new cable company which somehow isn't immediately crushed, would have an enormous customer base, and could potentially make billions and billions of dollars.

To someone steeped in the Bay Area Startup lottery culture, this isn't an insanely stupid idea at all. It's almost a safe bet. With the force of millions of dollars behind you, being right is irrelevant.


Posted by Samuel Bierwagen | Permanent link | File under: important, nerdery

Mon Oct 15 18:24:59 EDT 2012

why does nanoblogger generate broken links

(Attention conservation notice: I found an obscure bug in my blog publishing software. You are unlikely to care about it.)

google 404 errors

Why the hell does my site have so many broken links?

I'll spare you the grimy details of the hour of troubleshooting, and jump right to the punchline. Nanoblogger 3.4.2 has a bug which generates bad relative links when you do ./nb update all

Nanoblogger is no longer updated, so this isn't a problem that can be solved by upgrading. I didn't want to dive into the parsing engine, so I had to find a workaround, which turned out to be pretty simple: just update it a year at a time. ./nb update YYYY works perfectly. (ex. ./nb update 2012) I've only got six years of archives, so all I had to do was run it six times.

I'm posting this incredibly boring post in the hopes it'll save one of the six other users of nanoblogger some confusion in the future.


Posted by Samuel Bierwagen | Permanent link | File under: Linux

Sat Oct 6 15:26:52 EDT 2012

wherein I write a guest post

I just did a guest post for the Armchair Brandology blog:

A modern nation, like a corporation, is a machine made of humans. Its genetic code is ideas, encoded as words on paper.

Such immaterial entities are exquisitely sensitive to language, and how it's used. Sticks and stones may break your bones, but words can kill a nation.

So the Senkaku/Diaoyu Islands are purposely branded so that there's no way to refer to them without implictly taking a stand. Like how the abortion debate is framed as "pro-choice/pro-life", except that both sides in this argument have nuclear weapons.

You should check it out!


Posted by Samuel Bierwagen | Permanent link | File under: nerdery

Sun Sep 30 07:13:13 EDT 2012

escape.sh

I've pasted a lot of IRC logs into a lot of HTML documents, which is always a pain, since angle brackets are obviously a special character in HTML, which means I have to do a search and replace with the equivalent entity codes. I usually did this manually, using whatever graphical text editor was handy.

But that's Not The Hacker Way. I'm editing a text file produced by one program, so another program will accept it. String processing isn't a job fit for a human. This is something that should be done by a third program.

Thus:

#!/bin/sh
#
# escape.sh - Escapes angle brackets in text files
#
# Turns angle brackets into < and > HTML entities.
# With --irc, replaces the first 8 columns (the timestamp) with an 
# opening angle bracket, using an ugly hack.
#
# This is free and unencumbered software released into the public domain.

if [[ $* == *--irc* ]]
then
    sed -i 's/>/\>/g' $2
    sed -i 's/^......../\</g' $2
else
    sed -i 's/</\&lt;/g' $1
    sed -i 's/>/\&gt;/g' $1
fi

(Github)

Then I stuck it in my $PATH with sudo cp escape.sh /usr/local/bin/escape This way you can run it from any directory just by doing escape example.txt

(It's not actually very Unixy-- it doesn't play well with pipes, and wildcard expansion in a directory will blow it up.)

Have fun!


Posted by Samuel Bierwagen | Permanent link | File under: Linux

Sat Aug 25 19:00:25 EDT 2012

ntpblogging II

(previously)

So now bbot.org is a Stratum 2 NTP Pool server. (Its wiki page.)

Joining the pool is pretty easy: You create an account, give them your server's IP address, wait for the monitoring server to decide you're stable enough (~8 hours) and boom, you're in.

(The interface is a bit awkward: you paste the address in there, you don't click the "Add a server" link, which apparently doesn't do anything.)

I found four upstream servers by pinging 0.us.pool.ntp.org repeatedly, and choosing the one that were closest to me. Since bbot.org is in a datacenter right on the internet backbone, close can be very close:

# ntpq -np
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
-72.26.198.240   209.51.161.238   2 u  273 1024  377    2.320    3.100   1.201
+69.164.217.193  128.59.59.177    3 u  825 1024  377    3.713    0.239   0.371
-108.61.73.243   209.51.161.238   2 u  237 1024  377    3.174   -1.069   0.398
+128.113.28.67   18.26.4.105      2 u  383 1024  377    6.828    0.382   0.141
*128.118.25.5    .WWV.            1 u  426 1024  377   11.537    0.225   0.310

I had hoped that <10ms ping times would result in magically low offset numbers, measured in the tens of microseconds, but apparently jitter becomes a bigger problem when you get that low.

My reference stratum 1 server is wwv.tns.its.psu.edu, an open-access tier 1 server that John Balogh runs. Thanks John!


Posted by Samuel Bierwagen | Permanent link | File under: important, Linux

Sat Aug 4 06:52:57 EDT 2012

ntpblogging

So I was farting about trying to figure out how to ask a NTP server what it thinks the time is without having to edit ntp.conf on the client machine, when I discovered that NTP is like SSH— any machine with it installed acts as a server.

So now both of my machines get their time from bbot.org:

magnesium:~ $ ntpq -np
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+76.72.161.27    138.236.128.112  3 u   44   64  377   81.174   -2.459   1.158
+209.177.158.233 134.21.35.167    3 u   42   64  377   62.137   -3.428   1.459
-64.34.171.122   198.60.22.240    2 u   42   64  377   85.527   -7.019   2.248
*69.50.219.51    209.51.161.238   2 u   36   64  377   54.501    0.361  45.780
bbot@neon:~ $ ntpq -np
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+76.72.161.27    138.236.128.112  3 u   60  128  377   80.328    0.690  10.561
*67.23.181.241   128.4.1.1        2 u   35  128  377   82.895    1.003   7.373
+69.167.160.102  204.9.54.119     2 u   70  128  377   75.712    4.162  12.724
+50.16.231.185   192.5.41.40      2 u   26  128  377   87.617   -0.344  64.595

(The legend for the inscrutable linux bullshit can be found in ntpq’s manual file)

(Of course, at the moment I took these screenshots, neither neon or magnesium were syncing to bbot.org…)

The magic incantation to ask a NTP server for the time is sntp,

$ sntp 0.pool.ntp.org
2012 Aug 04 01:30:15.000857 + 0.001475 +/- 0.083787 secs

Which will return, (if you’ve got a machine with accurate time) a tiny drift number (1.4ms) swamped by a giant lake of uncertainty. (83.7ms) This is because sntp can only request a single packet, which means it doesn’t have a good idea of the jitter between you and the remote machine. The NTP daemon manages to extract accurate time from the storm of random network noise by requesting lots of packets, then doing a lot of clever things. You can sanity-check sntp by going to time.is, which for any Linux machine will tell you that your clock is bang-on accurate. (NTP on Windows will only get the clock within 1000ms of the true time, by design. Microsoft assumes that their users aren’t pedantically obsessive nerds who absolutely positively must have the most accurate computer clocks possible. The same assumption can’t be made of Linux users.)


Posted by Samuel Bierwagen | Permanent link | File under: Linux

Tue Jul 17 05:00:18 EDT 2012

how to pass the washington state driver's test on your second try

I've been spending a lot time recently negotiating various state agencies to acquire licenses, and I figured I would write up what I did, because this is a goddamn blog.

Electrician's License

This was more or less easy. I have a weirdo subtype: Nonresidential lighting maintenance and lighting retrofit (7A). Getting this required two years of on-the-job experience, having the supervising electrician witness that I had that experience on a form, getting that form notarized, paying a fee, and then taking two tests.

In the United States, all the states have been bullied into adopting a uniform electrical code, imaginatively titled the National Electrical Code. Every couple years it is updated to phase out certain old practices of electrical work, and institute new safety methods. The individual states often lag by a year or two when adopting: the latest version is NEC 2011, but Washington is still on NEC 2008, for various amusing political reasons.

One of those is money. The NEC, despite being, essentially, law; is actually produced by a for-profit industry association, which means the code will cost you money, and not a small amount of it: NEC 2011 costs $75. Perniciously, when a state updates to the latest version of the code, every single electrician in the state has to buy a new copy, and take various courses on the updated rules. The perverse incentive for the NFPA is to issue updates as often as possible, to extract the maximum amount of rent from their legal monopoly.

The licensing tests are open-book, but I didn't want to give the NFPA my money, so I pirated a PDF copy of NEC 2008, and studied that.

That's the first test. The second test is on 19.28 RCW, the Washington State law governing electrical work.

Both of these tests are administered by PSI Exams, a company that apparently exists solely for state governments to outsource test administration to. Presumably there's all sorts of kickbacks and bribe-taking involved here too, I didn't really want to dig too deeply.

So. I paid my fees, scheduled the test, and studied the Law. Finally, the big day came. I took the test, and passed the NEC portion, but failed the RCW portion.

The proctor printed out the sad evidence of my laziness and incompetence, and handed it to me. I looked at the paper, read it, then instantly forgot the information.

This was one of the most egregious failures of rationality in my adult life, so listen carefully: Somehow, after all that, I became convinced that I had failed the NEC portion, not the RCW.

This is partially explainable by the fact that the NEC part had pitched a couple slowballs over the plate regarding wire marking trivia. These would have been really, really easy to answer if I had a paper copy of the NEC with me... but I was trying to save money! Whoops. So I got those wrong, but still passed the test. My failure haunted me, somehow metastasizing in my head to "I flunked the entire test".

Wrong.

There's a waiting period before you can retake the test. In the time I purchased a physical copy of NEC 2008, and studied the heck out of it. I show up for the retest, code in hand, ready to trounce this test. I sit down at the computer... and the test is for 19.28 RCW.

I am confused. I complete the test, easily passing it. (It picked a different random set of questions, ones I knew the answers to this time, apparently.)

I pick up my book, walk out of the testing room, and tell the proctor that there is A Problem. I've been given the wrong test! I am absolutely, unshakably certain that I had failed the NEC part the first time, not the RCW part. A Mistake Has Been Made.

The proctor is not having a good day. To be precise, she is not having a good first day on the job. She is not familiar with PSI's computer system, but figures out that I had taken the test that had been assigned to me. She calls PSI technical support (for apparently, the fifth time that day) and we investigate. The conclusion is reached that everything is working fine.

I am still not convinced, but this is obviously not the place to resolve it. (The PSI testing center is a single, two-room office suite in a office park in a Seattle suburb) I'm holding things up for other people who actually took the right test, so I drive home, dreading what is obviously going to be a couple hours of phone hell, navigating the bowels of a giant bureaucracy to correct a weird computer error. This is going to really, really suck.

I get home, open a beer, and spend 10 minutes on hold. I finally get a rep, tell her my name, social security number, blood type, and secret fear; she accesses my file, and tells me that I've passed both tests. I am now a 7A licensed electrician.

"Really?"

"Really."

"Oh."

I thank her. I hang up. I feel like biggest idiot in the entire world, the dumbest man who has ever, or will ever, live.

So that's how I got my electrician's license. How I got my driver's license is similar in the broad strokes.

Driver's license.

In Washington state, if you're over 18, all you need to get a learner's permit is to pass a knowledge test, and pass a simple eye exam. I spend half an hour waiting for my number, while watching a lot of alarmingly old people renew their driver's licenses.

I pass the knowledge test with ease, (It's taken on a computer, which uses a CRT-based touchscreen! Blast from the past.) and receive my learner's permit on April 3rd, 2012.

I don't know much about learning to drive, but I've read a little about learning how to fly, so I keep a logbook.

Over the next month, I rack up 269.35 miles, and a number of hours that I really don't want to go through and add up, watch the instructional videos produced by the DoL, until finally I decide that I'm ready to take the test. It is scheduled for May 14th, 2012.

This is what it looks like when you fail a driving test. I got a 78/100, the passing score is 80/100.

Highlight:

"So, have you ever conducted a test where the guy hit someone?"

"I can't answer that."

"Oh."

So how did I fail the driving test? It's easy: during the test, a specific phrase is used. It is, "rejoin traffic."

When I took the test, it was a beautiful, sunny summer day. 70F, not a cloud in the sky. Driving tests are (almost always) conducted on empty side streets, since of course this is a driving test, and the driver may fuck up.

The street is empty. The proctor says, "rejoin traffic". I glance into a mirror and, duh, see nobody, so I just drive into the street.

No! Wrong! You're supposed to be pretending that there is traffic. They are looking for three specific things:

  1. Checks mirror.
  2. Physically turns around and checks blind spot.
  3. Turns on turn signal.

If you miss any of those, you lose the maximum 4 points on that test, failing the section entirely. Do that often enough, and you fail the test.

Don't do that. Perform those three actions. Even better: say them out loud ("Mirror, blind spot, turn signal") Driving instructors like to be talked to, they want to hear you thinking through things. I also repeated instructions back to them, ("Turn left at the upcoming intersection" "Turning left, roger") which you probably don't have to do, but they didn't seem to mind.

I passed parallel parking perfectly... except for signaling.

Minor point loss: at a stop sign with a blind corner, you're supposed to come to a complete stop before the white line, creep forward until you have visibility, come to another complete stop, then go.

Something I was warned about by a friend who also recently took the test: the rules for parking on a hill are somewhat esoteric. (You have to point your wheels in a certain direction, depending on circumstance) Study them carefully, or else you'll be dinged the full 4 points on that test.

Note: a perfect score on the driving test means that they'll never touch the scoring form. If they write anything at all, it's because you screwed up, and they're deducting points. (If you ask the instructor what you did wrong, they may or may not answer. I think they're not supposed to, but if it's clear that you're going to pass, they may bend the rules. This means that they won't help you when you actually need it, but oh well.)

There's a couple of commonsense tips:

  • Drive slow. By default, I drive slowly enough to annoy my mother, so that wasn't really an issue, but still.
  • Bring a book to the DMV. Or something, anything. I had to keep myself entertained for a couple hours. Don't be like me. Be smart.
  • Don't argue with the driving instructor. That cannot possibly help. Unless it's a very obvious, and very trivial mistake, ("Your headlights aren't on." "Actually, they are." "Oh.") then disagreeing with them isn't going to end well for you.

Anyway, I passed the test with trivial ease on my second try. Anticlimax ending!


Posted by | Permanent link | File under: important, Etc

Wed Jun 13 23:35:54 EDT 2012

biolite camp stove

So John Biehler just reviewed the Biolite camp stove. The gist is that it's a little wood stove which uses a thermoelectic junction to generate electricity that could be used recharge your phone, or whatever. At $129, it's a cute little gadget, that also happens to demonstrate why the TEC effect isn't used for commericial power generation.

Let's look at the numbers:

Fire power output (peak): 3.4 kw (lo) 5.5 kw (hi)
USB power output: Max continuous: 2W @5V, Peak: 4W @5V

Assume that it only manages the maximum continuous power on the "hi" mode. This gives us 2W/5500W = a magnificent final thermodynamic efficency of .036%


Posted by Samuel Bierwagen | Permanent link | File under: important, Engineering

Thu Jun 7 19:13:25 EDT 2012

Bad Transcript: Prometheus (2012)

I heard from my sources that Prometheus was not good, so I endured what was probably the worst cam I've ever seen to bring you a Bad Transcript for it.

Spoiler alert: yes, it really is that bad.


Posted by Samuel Bierwagen | Permanent link | File under: important, Etc

Mon Jun 4 18:10:12 EDT 2012

cod blops 2

So like any other good drone, I've been watching the E3 presentations, which also means I saw the pretty bland gameplay demo for Call Of Duty: Black Ops 2.

If you watch that trailer, which you shouldn't, you'll get the basic gist, which is that it's 2025, the Army is 50% drones, but surprise surprise, the Russians or someone hacks them, and now you gotta shoot them with bullets. Despite the premise, the gameplay demo showed the player shooting a lot of foreigners with various gadgets. So, a typical Modern Warfare game, like the last five COD games.

This actually a neat premise, kinda like the EMP level from MW2, which they're bungling pretty badly. Here's what it should be like:

First level: Typical hand-holding level. You still have all your fancy gadgets, and are on a mission in Columbia or something, killing the natives. Game makes a bunch of imperialism and "gosh with all this modern weaponry we have, it's like we're on easy mode!" jokes.

Second level: Oh no, we've been hacked! Bad news, Mason: the new guns don't work either. We'll have to use these WW2 museum pieces... the same guns from Call Of Duty 1!

Third level: Old West guns!

Fouth level: The robot factory! You've got to make it to the control room to shut down the production line, or else you'll be hit by endless waves of combat robots coming right off the conveyor belt.

(Explaining the joke: this is how combat works in every CoD game, endlessly respawning enemies that constantly come at you until you hit a checkpoint.)

Fifth level: We're out of ammo... we'll have to use swords! Sudden genre shift!

Sixth level: The hackers are hosting C3 inside a WoW-clone! Mason, take this level 60 warrior we bought off a Chinese gold farmer, and go kill them. Another sudden genre shift!

Seventh level: I don't know. The last five games have ended with killing the viewpoint character, and I don't know how to one-up that.


Posted by Samuel Bierwagen | Permanent link | File under: important, Game Design

Tue May 1 13:25:01 EDT 2012

come on up, get your extremely impractical ideas here

So I've got a dumb idea, and in the hopes of getting it out of my head, I'm going to write a blog post about it.

In 2006, Daniel Rutter wrote about the "genset" option for the t/zero vaporware electric car. The basic idea was this: A plug-in hybrid, but with the gasoline engine on a trailer. If you're taking a short trip, then you don't take the genset with you, because you don't need the weight. If you're going on a long trip, then you hook up the trailer, and enjoy the long range and fast refueling that a gasoline engine gives you. (Note that this scheme means you'll have a fairly large genset sitting around at home, which spends most of its time not being used.) This is part one.

Part two: Heat engines have a surprisingly low maximum theoretical efficiency. The endoreversible heat engine efficiency equation is thus: (units are absolute degrees, Kelvin or Rankine)

Endoreversible heat engine effciency equation

The problem is that the Earth just isn't cold enough. Room temperature is 300 Kelvin! You're not going to want Th to go much above 830K, or else you'll be producing nitrogen oxides in the exhaust. This gives a final endoreversible efficiency of 0.40. That's the maximum thermodynamic efficiency, and there ain't no way to beat thermodynamics.

You can bend the rules a little, though. It's impossible to extract any more mechanical work from the waste heat, but it's still heat, you can use it for things that don't need low-entropy heat sources. Like, say keeping a house warm, or heating water.

This is called Cogeneration, and depending on how you do it, you can get up to 90% total thermal efficiency. A popular home cogeneration system is the MicroCHP furnace, a natural gas turbine that provides hot water and forced-air heating from its waste heat outflow. It can also run as a backup generator during power outages, in which case it vents waste heat outside.

The synthesis of these ideas is obvious: Make a plug-in hybrid whose engine is a cogenerating furnace built around a multi-fuel gas turbine.

A brilliant idea! There are some problems.

1.) MicroCHP turbines are designed to run on natural gas only. The "multi-fuel" version would be a second generation product. The first gen would have problems: the natural gas fueling infrastructure in the United States is a lot more sparse than the liquid-fuels infrastructure.

2.) The turbine is going to want a lot of cooling. Does a trailer get enough airflow?

3.) How well does the turbine tolerate road vibration?

4.) There's a user design problem: for a cogenerating furnace to work well, you want it at the center of your house, where all the waste heat goes to keeping you warm. This essentially means that every user of this car has to have an insulated, attached garage, or else they'll be losing some efficiency.

5.) There's a user interface problem: You can drive out of the garage with the trailer attached easily enough, but you'll then have to back into the garage, trailer first, and then reattach all the connections. Manually. Every time you want to use it.

6.) There's a use-case problem: Every time you drive away with the turbine, you drive away with the house's sole source of heat and hot water. Fine with a single-occupancy home, might be a problem for a family.

7.) It is certain that in the near future, cripplingly heavy taxes will be applied to fossil-fueled vehicles. Will this count as one? Maybe?

8.) This idea isn't terribly original. There's a lot of prior art here. Getting a patent will be an uphill battle.

So, there. Eight reasons why I'm talking about this idea in a blog post, rather than a room of serious men in suits.


Posted by Samuel Bierwagen | Permanent link | File under: important, Engineering

Wed Apr 25 07:48:40 EDT 2012

looking ahead to our glorious future

"The War Against Youth"

The youth vote still supports Obama, but in a chastened, conditional way. In hindsight, Obama's 2008 campaign looks like an indulgent fantasy in which the major conflicts in life simply don't exist. There may be no white America and no black America, no blue-state America and no red-state America, but one thing is clear: There is a young America and there is an old America, and they don't form a community of interest. One takes from the other. The federal government spends $480 billion on Medicare and $68 billion on education. Prescription drugs: $62 billion. Head Start: $8 billion. Across the board, the money flows not to helping the young grow up, but helping the old die comfortably. According to a 2009 Brookings Institution study, "The United States spends 2.4 times as much on the elderly as on children, measured on a per capita basis, with the ratio rising to 7 to 1 if looking just at the federal budget."

[...]

Cynicism rises to fill the emptied space of exaggerated and failed hope. It's all simple math. If you follow the money rather than the blather, it's clear that the American system is a bipartisan fusion of economic models broken down along generational lines: unaffordable Greek-style socialism for the old, virulently purified capitalism for the young. Both political parties have agreed to this arrangement: The Boomers and older will be taken care of. Everybody younger will be on their own. The German philosopher Hermann Lotze wrote in the 1870s: "One of the most remarkable characteristics of human nature is, alongside so much selfishness in specific instances, the freedom from envy which the present displays toward the future." It is exactly that envy toward the future that is new in our own time.

And we will not talk about any of it. We will keep mum. We will hold our tongues lest we seem ageist, lest we seem bitter, lest we seem out of touch, lest we seem pessimistic, lest we seem divisive.

[...]

A generation now means an economic cohort — a moment in the cycle of rising and (mostly) falling economic data. The UK has 21.8 percent youth unemployment, France 22.8 percent, Hungary 26.1 percent, Italy 28.2 percent, Spain 47.8 percent. Around the world, young people are beginning to be defined by their unemployment: the mileuristas of Spain, "those who earn less than a thousand euros"; the NEETs of England, "not in employment, education, or training"; the hittistes of Tunisia, "those who lean against the wall." Revolutions or unmanageable riots have inevitably followed the rise of masses of bored, underemployed young people.

(Don't forget Connor Kilpatrick's list of objections over at The Exiled.)

"Depression is a choice" and "Two quick responses"

We are in a depression, but not because we don’t know how to remedy the problem. We are in a depression because it is our revealed preference, as a polity, not to remedy the problem. We are choosing continued depression because we prefer it to the alternatives.

Usually, economists are admirably catholic about the preferences of the objects they study. They infer desire by observing behavior, listening to what people do more than to what they say. But with respect to national polities, macroeconomists presume the existence of an overwhelming preference for GDP growth and full employment that simply does not exist. They act as though any other set of preferences would be unreasonable, unthinkable.

But the preferences of developed, aging polities — first Japan, now the United States and Europe — are obvious to a dispassionate observer. Their overwhelming priority is to protect the purchasing power of incumbent creditors. That’s it. That’s everything. All other considerations are secondary. These preferences are reflected in what the polities do, how they behave. They swoop in with incredible speed and force to bail out the financial sectors in which creditors are invested, trampling over prior norms and laws as necessary. The same preferences are reflected in what the polities omit to do. They do not pursue monetary policy with sufficient force to ensure expenditure growth even at risk of inflation. They do not purse fiscal policy with sufficient force to ensure employment even at risk of inflation. They remain forever vigilant that neither monetary ease nor fiscal profligacy engender inflation. The tepid policy experiments that are occasionally embarked upon they sabotage at the very first hint of inflation. The purchasing power of holders of nominal debt must not be put at risk. That is the overriding preference, in context of which observed behavior is rational.

[...]

Affluent retirees depend heavily on asset wealth; Social Security cannot cover the lifestyles to which they’ve grown accustomed, and the expenses and commitments they’ve accumulated.

Affluent older Americans hold a large proportion of their wealth in bonds and cash-like instruments (bank CDs, money market accounts). They also maintain significant positions in stock funds that might “do better when the economy does better”. But, unsurprisingly, retirees keep the wealth they most depend upon in safer, fixed income vehicles. The proportion they keep in stock funds tends to increase with wealth. [2] Since they can’t clip coupons, retirees rely upon asset sales and redemptions for income. They try to manage the pace of sales so they don’t outlive their capacity to maintain their lifestyles.

Retirees living on asset wealth are very exposed to inflation. It’s an error, a fallacy of composition, to assume that the existence of hedges and “sophisticated vehicles” means that somehow everybody can be protected. Every debt contract imposes inflation risk that some party must bear. Stock markets get the press, but most financial claims on capital are structured as debt, all of which must be held, directly or indirectly, by some human (usually an old or rich human).

[...]

So people who intend to live off their nest eggs rely first and foremost on the “safety” of bonds. Expansionary policy is a hazard for them.

"The Energy Trap"

Many Do the Math posts have touched on the inevitable cessation of growth and on the challenge we will face in developing a replacement energy infrastructure once our fossil fuel inheritance is spent. The focus has been on long-term physical constraints, and not on the messy details of our response in the short-term. But our reaction to a diminishing flow of fossil fuel energy in the short-term will determine whether we transition to a sustainable but technological existence or allow ourselves to collapse. One stumbling block in particular has me worried. I call it The Energy Trap.

In brief, the idea is that once we enter a decline phase in fossil fuel availability—first in petroleum—our growth-based economic system will struggle to cope with a contraction of its very lifeblood. Fuel prices will skyrocket, some individuals and exporting nations will react by hoarding, and energy scarcity will quickly become the new norm. The invisible hand of the market will slap us silly demanding a new energy infrastructure based on non-fossil solutions. But here’s the rub. The construction of that shiny new infrastructure requires not just money, but…energy. And that’s the very commodity in short supply. Will we really be willing to sacrifice additional energy in the short term—effectively steepening the decline—for a long-term energy plan? It’s a trap!

Posted by Samuel Bierwagen | Permanent link | File under: Etc

Tue Apr 17 08:11:59 EDT 2012

gcc why you gotta hurt me so

I got tired of being apparently the last person in the world not to know C++. So I'm struggling through one of those stupid "Teach yourself X in only one hour a day" books, and because I'm me, I'm wasting a lot of time haring off on pointless tangents. Like, for one example, the auto operator.

From "The Biggest Changes in C++11 (and Why You Should Care)":

In C++03, you must specify the type of an object when you declare it. Yet in many cases, an object’s declaration includes an initializer. C++11 takes advantage of this, letting you declare objects without specifying their types:

auto x=0; //x has type int because 0 is int
auto c='a'; //char
auto d=0.5; //double
auto national_debt=14400000000000LL;//long long

This sounded like a new and innovative way to shoot yourself in the foot, so I gave it a try. And it works great! For those examples, and those examples only.

auto Array[5] = { 1, 2, 3, 4, 5 };

You'd think it would be pretty obvious that I want a five element array, initialized with 1 ... 5, right?

$ g++ -pedantic -std=gnu++0x -Wall -Wextra -Werror foo4.cc
foo4.cc:5:33: error: unable to deduce ‘std::initializer_list [5]’ from ‘{1, 2, 3, 4, 5}’

C'mon, man. Please?

(There's also a really neat GCC feature called designated initializers, which offers an abridged syntax for initializing an array with sequential values. C only, sucker! Anyone using C++ can fuck off, apparently.)

GCC is also really bad at reading minds:

auto a = 3;
auto b = 2;

int main()
{
  cout << a / b << endl;
}

Which, of course, outputs:

$ compile foo5.cc && ./a.out
1

This is because an operation on an int will always output another int. Knowing what little I do about C internals, I had been half-hoping that it would do a little static analysis here and figure out it needed to use floats here, but no. To me, Python strikes a much better balance here with its dynamic+strong typing, between the icy rigor of Haskell, and the freewheeling madness of PHP's type system. C++11's abstraction is too leaky to be useful, which means you're better off explicitly decalring types than trusting auto to do what you mean.


Posted by Samuel Bierwagen | Permanent link | File under: nerdery