Wednesday, December 30, 2015

More Movie Ramblings: The Big Short

After going for what seems like years without seeing a movie in a proper movie theater, we've now seen three nearly in a row. First there was Star Wars. Then The Big Short and then last night Spotlight. I don't feel all that bad as both the Big Short and Spotlight were based on real events, and their educational value is at least as important as their entertainment value.

At some point, I may be inspired to write something about Spotlight, but for this post, I'm going to focus my energy on The Big Short.

The Big Short was about the housing/banking crisis of the mid-2000's and is masterfully done. How you make a movie on banking watchable, much less entertaining, takes real skill. It's another win for Michael Lewis, and count me in for his next movie (whatever that is). And the timing of the movie is great: just long enough after the crisis that we've basically put it behind us, but not so long after that it's Just History.

OK, enough praise. You get the point, it was a fine movie. Here's two thoughts that have stuck with me since watching the movie:

First, we're supposed to walk out of the movie theater angry at bankers. I get that. But I walked out with a fresh anger towards a new group of people: the raters. See, as far as I can tell, people, bankers included, are always going to game the system. There will always be those who will try to make big sums of money off of risky propositions. And in may respects, that's OK.

Every time you walk into a casino, you're signing up for just this arrangement. Sure, you may walk out with big bucks, but statistics say, if you play long enough, you'll lose. So if banker's want to go with risky bets, there's a time and place for that. What I'm dumbfounded by is that the people who rated the loans and other instruments (look at me, one movie and I'm an expert!), could rate them seemingly however they wish.

Just saying something is a good bet, doesn't make it a good bet. Risky bets are OK. Safe bets are OK. Making what you think to be a safe bet, when it's really risky, is not OK. And that, from my 130 minutes of movie education, seems like one of core problems in the crisis.

How could giving such ridiculous ratings not be illegal? How could the people who rated these things be in business? Heck, how could being a rater even *be* a business in the first place? It's like playing football and having the coaches be the refs. Shouldn't the referee be completely outside the game? (Whoo, sports metaphor! Nailed it.)

The big question: can I take my outrage and use it to go the next step to figure out how this works in the non-movie universe? Oy, probably not. Though I did just mail my Senator on the topic, so let's see what he has to say.

My second take away from the movie is a sort of wish. In the movie, genius Dr. Michael Burry, does the unthinkable: he slogs through hundreds and hundreds of loans to come up with the notion that what's being rated as a good bet, is in fact, anything but. When he tells another character in the movie that he's done this, they act as though he's performed the unthinkable. Sort of like actually reading the terms and conditions *before* signing up for Facebook, or some other fine-print feat.

My wish is this: that kids watching this movie will want to turn to their parents (or, hopefully date) and ask the obvious question: why didn't he write a program to do this? In the movie, Burry is seen noting how many days overdue various loans are, compiling them into a spreadsheet. While I'm sure in actuality there was a lot more going on, this sort of thing is exactly why we have computers.

In my world, we're only one program away from finding and hopefully addressing the next crisis, whatever that may be.

Monday, December 28, 2015

A Compass to Survive a Hostile Environment: My Front Right Pocket

I'm a big fan of always carrying a compass and for years I've had one on my key chain. An old school compass is truly an object of beauty: it has no reliance on cell towers, WiFi, GPS or batteries. It Just Works. Well, that's the theory anyway. In practice, my every-day carry of a compass ends up beating up a delicate instrument which was never really intended to be subjected such harsh conditions. Consider my search for the perfect pocket compass:

1. is a cheap keychain button compass. I picked up a package of 20 of them from eBay for some ridiculous price. The idea was to pick up a whole slew of them and find one in the bunch that seemed to be accurate. The problem with these little button compasses is that they are slow to settle on North. I found that I was constantly tapping the compass, willing it to show me the right direction. What do you want for a few bucks, right?

2. is was the very promising Metro Silva Compass. This guy actually held up for almost two years. Unlike the cheap button compasses, this needle would always confidently snap to North. But look at the picture above - somehow I managed to reverse the polarity of the compass (trust me, North is up). That's not cool. I've got a note into Silva asking what I should do about this glitch. Let's see what they say.

3. is the very slick County Comm SERE compass. Like the Metro Silva, it snapped to North much faster than the button compasses. It comes with a lanyard, but I couldn't resist just sticking it on my keychain. I figured I'd take it off the keychain to do any actual readings. I know this isn't a keychain compass, but I figured if it was tough enough to be included in a "Aircrew Survival Kit" it should be tough enough to live in my front pocket. I was wrong. After a few weeks I realized that the compass dial had effectively become magnetized. The result, and it's hard to see this from the photo, is that compass dial dips down and "sticks" to the base of the compass, rendering its readings useless. D'oh. I've got a note into the good people at County Comm to see what they have to say about this.

4. is my latest attempt. It's a Tac Compass, also by County Comm. This bad boy is tiny. But it does appear to meet my need of being a functional compass. For now, I'm storing the compass in one of the pill containers on my key chain:

Like I said, it's itty bitty! If it can turn out to be reliable, the Tac compass may be the perfect EDC compass. It's almost invisible until you need it, and then can pull it out and be ready to un-lost yourself.

The question, of course, is can this little guy stand up to the punishment of living on my key chain? Time will tell.

Update: Both Silva and County Comm both got back to me within 24 hours and promised to replace / fix the compass for no charge. In the case of Silva, I need to send it back to Sweden, so yeah, we'll see how that goes. But both Silva and County Comm demonstrated quality customer service, which is much appreciated.

Sunday, December 27, 2015

The Other Kind of White Christmas

We had some crazy Christmas weather in DC: 70°F and foggy. Like pea soup foggy. While our neighbor's little ones were no doubt tearing into presents, Shira and I took a surreal walk along the Potomac.

What's truly remarkable was just how fast conditions were changing. The two photos below are taken 2 minutes and 4 seconds apart, yet as you can tell, the visibility drops dramatically. In the first shot, you can partially make out the DC shoreline, in the next, you can't even see the river! That's not photo filter magic; that's actually what was going on.

And then there was National Airport. Gravely Point was as we'd never seen it before. Like the scene above, the fog shifted a number of times in front of us. One minute the airport was plainly visible, the next, it was gone. At one point we watched in awe as an approaching airplane simply disappeared into the fog. I can't imagine what it was like to be that pilot: you're staring at a clear runway and then poof! it's replaced by a wall of white.

And a few more bonus shots: seriously, I felt like we were walking through some exotic fantasy world.

Thursday, December 24, 2015

Review: Star Wars: The Force Awakens

[SPOILER ALERT - SPOILER ALERT - SPOILER ALERT - SPOILER ALERT - SPOILER ALERT]

Two nights ago I watched Star Wars: The Force Awakens, and after mulling it over, I'm ready to weigh in with my two cents.

The movie gets good almost immediately. It doesn't hurt that hearing the open music score brings me back to being 10 years old and sitting in my Aunt and Uncle's house watching Star Wars on Laser Disc. Nearly everything seems spot on: the characters are great, the banter is top notch and the clever references to the previous episodes are brilliant.

I'm loving the Rey character. When she says I know how to run without you holding my hand, she's not just being quippy, she's showing that the writers have been paying attention. We live in the age of the Self Rescuing Princess, and Rey embodies these principles.

And seeing Han and Chewy together? C'mon, who couldn't be moved by that?

I was even OK with the fact the story arc of the movie seemed a pretty near match to Episode IV, the very first Star Wars movie. After the flop of latest set of movies, who could blame the writers for sticking with what works? Besides, the movie was fun. Why shouldn't we get a modern take on classic scenes like the Star Wars Cantina. Heck, they even dressed Rey like the original Luke:

The visuals are amazing, too. To see the various ships interact with snow, sand and water, is really quite remarkable. The killing was also quite a bit more realistic; I don't recall nearly this much gore in the original set of movies. But I suppose that's just a sign of the times.

But—you had to know there was a but coming—at some point in the movie all this recreating of the original Star Wars movie lost its charm for me. The moment: when we get the big reveal of the final mission. What does our band of rebels have to accomplish? Well, destroy the Death Star. Oh wait, they don't call it a Death Star. They call it, and I'm not making this up, a Star Killer. You're telling me that a 200 *million* dollar budget gets you "Star Killer?" And it gets worse from there: what does our team of rebels need to? Well, only exactly what they did in the first Star Wars movie, down to the need to lower the shields and do a trench attack of the one flaw the Death Star Star Killer designer's seemed to have neglected to address (will these engineers never learn!). And with only one snarky comment from Han Solo, that's exactly how the movie proceeds.

At some point imitation stops being the sincerest form of flattery, and just becomes imitation. I mean, was it laziness that caused the writers to bother coming up with anything unique in some of the most climatic scenes in the movie? Or was just fear that they'd mess it up. Better to go with a tried and true plot line than risk a Jar Jar Binks scenario. I'm not sure, but you can tell, it really bothered me. It just made the movie feel a bit tedious at that point, like they were just going through the motions.

OK, so there's my big criticism. Otherwise the movie was rock solid. And for the younger audience who may have never seen the original Star Wars, the whole Star Killer critique won't even mean anything. It's a fun movie and shows that modern day Star Wars films can be created. The big question is this: can Episode 8 be more than just another clone?

Wednesday, December 23, 2015

Inspired by Malcolm Gladwell: 6 Tools to Help Slay the Giant

I really enjoyed Malcolm Gladwell's David and Goliath: Underdogs, Misfits, and the Art of Battling Giants. To help crystallize the points I took away from the book, I've written up a terse list summarizing them. See his book for all the details.

Without further ado I give you: 6 Tools to Help Slay the Giant:

  1. We have a hard time telling what's a strength and what's a weakness. Find yours. Find your giant's.
  2. We assume that a lot of something is good and lacking something is bad, when the opposite can be true. What are you lacking? What does the giant have a lot of?
  3. The underdog need not follow the rules. Giants love the rules and are often optimized to win the game within them. What rules or conventions can you ignore?
  4. Too much of a good thing turns into a bad thing. See #1 and #2.
  5. Don't assume people will act rationally. The giant thinks he knows how you're going to behave. Prove him wrong.
  6. A difficulty can take a person in one of two directions: it can harm them, or it can form a challenge that when overcome makes them even stronger. What difficulties can or did you turn into a strength building exercise?

Tuesday, December 22, 2015

Review: David and Goliath: Underdogs, Misfits, and the Art of Battling Giants

The first time I picked up Malcom Gladwell's David and Goliath: Underdogs, Misfits, and the Art of Battling Giants I promptly put it down. Why read a book that you know you're going to agree with? Consider that the very premise of my day job is that with your idea and my coding skills, we can conquer tech giants everywhere. Or that my blog has a whole section focused on feel-good underdog stories. Even activities like being a foster parent are done with an eye towards showing that one family can make a difference against the colossal problem of child neglect and abuse. So I hardly needed a book telling me that little could beat big; this I knew.

What an idiot I was.

I just finished listening to David and Goliath, and I'm glad to report that it's more than worth your time. Gladwell isn't just interested in recounting underdog stories. Though there is plenty of that, and as usual, he nails it. But he goes further: picking apart the tales to see what makes them tick. As is typical in Gladwell's work, he cleverly weaves together totally disparate threads, from a girl's basketball team to a French town that defies the Nazi's, to make his point.

As if that weren't enough, Gladwell seems to veer into territory that's essentially custom written for me. After a chapter that pretty much explains my college experience, he launches into a chapter on dyslexia, a learning disability I have first hand experience with. His discussion about how being a slow learner in some areas can, in the long run, help you be successful in others wasn't just an interesting theory; it was a description my academic career.

There's no doubt that if you find yourself in an underdog situation, you best get yourself Gladwell's book and start reading in a hurry. He definitely has key insights into what the David's of the world can do to come out on top.

I, however, have been thinking about the Goliath side of the equation of late. Bare with me, as the analogy sort of breaks down. Consider that as I was listening to Gladwell's book, we had both the Paris and San Bernardino attacks happen. In this situation, the US fits the profile of the seemingly invincible Goliath, and ISIS (or is it ISIL or Daesh?) fits the role of the underdog, David.

Goliath appears to hold the advantage: he's huge, well equipped and makes quite the show of force. David, for his part, is opportunistic, using a fighting style that Goliath simply never considered. We know how the story goes.

While I can appreciate why it's tempting to respond to these attacks with draconian polices or outrageous shows of force, I can also see how these can serve to benefit the bad guys. As Gladwell's book points out, it's these sort of tactics that have historically helped the underdog, not defeated it.

I won't claim to have the answers for how to deal with ISIS from a domestic terrorism perspective. But man, it sure would be nice to learn the lessons of history and not fall for into the traps other giants have. And Gladwell's book can absolutely help in this department.

Monday, December 21, 2015

Pirates, Ninjas and Dreidels, Oh My!

I explained to my little buddy Nathan, that traditionally, we played dreidel with M&M's, like our ancestors surely did. But we didn't have any M&M's in the house, so he suggested we play with the Ninja vs. Pirate Army Men I had on hand.

And so we did!

He selected his army of pirates, I an army of ninjas (5 strong, each), his Dad and Sister joined in the fun, and the game began! Sadly, I was defeated in both games we played. That little pisher sure can spin!

Good times!

Friday, December 18, 2015

Smart Phone, Dumb Watch: Implementing a Pebble Pedometer

My Galaxy Note 5 has a built in step counter. However I find that every time I want to check it, I have to bring up the S Health App and dig around until I can find the screen I'm looking for. Further more, I'd love to be able to track steps for a given activity. Think electronic Ranger Beads. S Health will give me a pretty graph of my steps, but not the one number I want. I've tried looking for a lighter weight pedometer app, but every one I've found has been an ad infused disaster.

By now you know where I'm going with this: this is the perfect job for my Pebble. The Pebble classic lacks the step counter that the phone has, but provides the streamlined UI that I'm after. Here's what my Steps 'App' looks like on the Pebble Classic:

There's really not much to it. I select the Steps option on the home menu, and from there, I can see my Steps Since value, as well as the daily total and the previous 4 days. Steps Since is the arbitrary activity counter I mentioned. I can clear it from the watch anytime I want.

Behind the scenes the phone is tracking both the daily and steps since activity in text files. If I ever want to use this data for other purposes, I can.

The above is all written in Tasker and leverages AutoPebble. Most of this little app is pretty obvious, but I did have a few hurdles to get over.

First, it wasn't obvious to me how to gain access to the step counter. One would assume there's a magic Tasker variable, %STEPS you can query. That's not the case. Instead, you need to setup a profile which will be notified when N steps have been taken. Within this profile, I set that global variable I'm after. See:

Profile: Steps Taken Tracker (109)
  Event: Steps Taken [ Number:10 ]
  Enter: Anon (110)
    A1: Variable Add [ Name:%STEPS_DAILY Value:10 Wrap Around:0 ]
    A2: Variable Add [ Name:%STEPS_SINCE Value:10 Wrap Around:0 ] 

I setup this profile to be notified every 10 steps, and as you can see, it updates both the daily and since global variables. I'm not sure what the impact of being notified of every step would be, but it just seems excessive.

To track steps on a daily basis I needed to save and clear out the %STEPS_DAILY value at midnight. That was also an easy profile to write:

 Profile: Steps Daily Reset (116)
  Time: 12:00AM
  Enter: Anon (117)
    A1: Write File [ File:Tasker/steps.txt Text:%DATE: %STEPS_DAILY Append:On Add Newline:On ]
    A2: Variable Set [ Name:%STEPS_DAILY To:0 Do Maths:Off Append:Off ]

Clearing the %STEPS_SINCE is done on demand. In this case I save the start, end dates as well as the step count for the period being cleared. I also send a vibration request to the watch so I get a signal that value has been cleared:

Pebble Steps Clear Since (119)
  A1: Write File [ File:Tasker/steps.since.txt Text:%STEPS_SINCE_STARTED %TIMES %STEPS_SINCE Append:On Add Newline:On ]
  A2: Variable Set [ Name:%STEPS_SINCE_STARTED To:%TIMES Do Maths:Off Append:Off ]
  A3: Variable Set [ Name:%STEPS_SINCE To:0 Do Maths:Off Append:Off ]
  A4: AutoPebble App [ Configuration:Full Screen: false
    Control App: Go Back
    Check Pebble Connected: false
    Other Pebble App: unknown
    No Prefix if Command: false
    Do Not Disturb: false
    Vibration Pattern: 300
    Clear History: false
    Open Phone App: false
    Save Scren: false
    Don't Send Screen: false
    Go Back: false
    Go Back Multi: false Package:com.joaomgcd.autopebble Name:AutoPebble App Timeout (Seconds):20 ]

One final challenge was that I wanted to show the last 4 days worth of step activity on the watch, however, steps.txt contains all activity. To get around this, I wrote an action: Tail File which will grab the last N lines from the file and return them. As you can tell, it's written in JavaScript, which means that the coding is straightforward. However, it's note especially efficient. I find no other choice but to read in the entire file as a string, which will be painful once steps.txt gets huge. But I'll deal with it then. (One solution: setup a Profile to rotate the file every month, and then the file won't grow past 30 lines or so.)

Tail File (132)
  A1: JavaScriptlet [ Code:var file = local("par1");
    var max = local("par2");

    var lines = readFile(file).split("\n");

    if(lines[lines.length-1] == "") {
      lines.pop();
    }

    max = Math.min(max, lines.length);
    while(max != lines.length) {
      lines.shift();
    }

    setLocal("lines", lines.join("\n")); Libraries: Auto Exit:On Timeout (Seconds):45 ]
  A2: Return [ Value:%lines Stop:On ] 

For completeness, here's the actions to show the steps menu and clear the steps since value. That should just about do it for this exercise:

Pebble Steps Menu (114)
  A1: Variable Set [ Name:%newline To:
  Do Maths:Off Append:Off ]
  A2: Perform Task [ Name:Tail File Priority:%priority Parameter 1 (%par1):Tasker/steps.txt Parameter 2 (%par2):5 Return Value Variable:%labels Stop:Off ]
  A3: Variable Split [ Name:%labels Splitter:%newline Delete Base:Off ]
  A4: Array Process [ Variable:%labels Type:Reverse ]
  A5: Array Push [ Name:%labels Position:1 Value:Today: %STEPS_DAILY Fill Spaces:Off ]
  A6: Array Push [ Name:%labels Position:1 Value:Since: %STEPS_SINCE Fill Spaces:Off ]
  A7: AutoPebble List [ Configuration:Full Screen: false
    Header: Steps
    Labels: %labels(:)
    Long Click Actions: steps_clear_since
    Last Line Height Default: false
    Remember Position: false
    No Prefix if Command: false
    Do Not Disturb: false
    Clear History: false
    Open Phone App: false
    Save Scren: false
    Don't Send Screen: false
    Go Back: false
    Go Back Multi: false Package:com.joaomgcd.autopebble Name:AutoPebble List Timeout (Seconds):120 ]


Profile: AutoPebble, Steps Clear Since (118)
  Event: AutoPebble [ Configuration:Command Filter: steps_clear_since
  Case Insensitive: false
  Exact: false
  Case Insensitive: false ]
  Enter: Pebble Steps Clear Since (119)
  A1: Write File [ File:Tasker/steps.since.txt Text:%STEPS_SINCE_STARTED %TIMES %STEPS_SINCE Append:On Add Newline:On ]
  A2: Variable Set [ Name:%STEPS_SINCE_STARTED To:%TIMES Do Maths:Off Append:Off ]
  A3: Variable Set [ Name:%STEPS_SINCE To:0 Do Maths:Off Append:Off ]
  A4: AutoPebble App [ Configuration:Full Screen: false
    Control App: Go Back
    Check Pebble Connected: false
    Other Pebble App: unknown
    No Prefix if Command: false
    Do Not Disturb: false
    Vibration Pattern: 300
    Clear History: false
    Open Phone App: false
    Save Scren: false
    Don't Send Screen: false
    Go Back: false
    Go Back Multi: false Package:com.joaomgcd.autopebble Name:AutoPebble App Timeout (Seconds):20 ]

Wednesday, December 16, 2015

AutoPebble Programming: From Phone to Watch in one click

Before I dive into another AutoPebble programming example, I suppose I should take a step back and explain why I think all this matters.

My Galaxy Note 5 has a great many advantages: amazing screen, gobs of RAM, brilliant camera, handy stylus and more. But compact and always accessible aren't traits on the top of this list. That's where the Pebble appears to come in. With just couple of quick presses on a device that's literally at hand, I can perform tasks on my phone. It's like I get the speed and convenience of an old school flip phone, but the computing power of a tablet. Add to this that AutoPebble allows for quick and easy integration between the phone and watch, and you can start to appreciate just why I'm so loving this setup.

On to the code. Good news, this is a far simpler example than my last hack. Still, I think it makes for a useful Smart Watch feature. Here's a Show Clipboard AutoPebble profile and action:

Profile: AutoPebble, Show Clipboard (86)
Restore: no
State: AutoPebble [ Configuration:Command Filter: show_clipboard ]
Enter: Anon (87)
  A1: AutoPebble Text Screen [ Configuration:Full Screen: false
                               Title: Clipboard
                               Text: %CLIP
                               Vibration Pattern: 200]

The action consists of exactly one command: show a screen on the watch with the text %CLIP. %CLIP is a magic Tasker variable that will always equal the contents of the system clipboard.

But why do you care, right? So you can do this:

Step 1: highlight and copy some text on your phone:

Step 2: select the Clipboard option on the watch and pull in the contents of the clipboard:

Step 3: stroll through the store with confidence picking up the right ingredients with only the occasional glance to your watch.

Random DC: Disabled Veterans, Model Trains and Hallowed Halls

Last night David and I took a random'ish walk through the US Capital area of DC and I was treated to not one, but three new (to me) and remarkable sites.

First up, the American Veterans Disabled for Life Memorial. Apparently, this is the only military memorial in DC that's independent of branch or conflict. This memorial strikes me as a tough one to get right: you don't want to glorify war, nor condemn it. You don't want to trivialize the challenges Veterans with disabilities face, nor turn them into inpsirational props. I think the monument struck this balance well, and most importantly, it gets the conversation started.

Lightening things up from there, we wandered over to the US Botanic Garden. It was past 5pm, so in theory, the garden should have been closed. But they're doing holiday events, so it was open. David and I got to wander through a nearly empty Botanic Garden, and take in the very cool holiday train display. Seriously, if you've got a Thomas obsessed little one, you definitely need to make your way to this exhibit. What the train room lacks in size it makes up for in interesting detail. Oh, and the whole thing is free. Definitely a winner activity.

As if moths drawn to the flame, after the garden we made our way towards the brightly lit US Capitol and its Christmas tree. As has become our tradition, David and I stood by the tree and lamented the fact that we celebrate the holiday season by killing a gorgeous 74 foot tree. The practice of which seems only slightly perverse. (I know, we're literally a bunch of tree huggers.) And from there we found ourselves outside the stately Russell Office Building. David was smart enough to find a visitor entrance, and after a quick security check, in we went.

The big deal behind the Russell Office Building is that it houses the offices of the US Senators. We wandered through the halls and passed office after office of well known Senator. I was such a tourist, peeking my head in wherever I could and snapping tons of photos. It was remarkable to consider that some of the most influential people in the country walk these halls on a daily basis, and we were just roaming the corridors like a bunch of kids cutting math class. The building has that old school ornate quality about it that makes every part of it look interesting (and causes you to repeatedly mutter: man, they sure don't make 'em like they used to). Definitely a fun experience.

For a small city, DC is truly packed with amazing treasures just waiting for you to practically trip over them.

Tuesday, December 15, 2015

I'm a Person. Really, I am.

I finished reading Danny Gregory's blog entry on Zork and was inspired to drop him a quick dude, well written! type comment when I ran into a fairly common snag. Whatever I wrote looked like it was from an automated bot engaging in comment spam. Anything I could think to write (Nice, Well Said!, Keep the great posts coming!) seemed so obviously canned that surely a real human wouldn't write such a thing.

This isn't a new problem. Back in the day, I used to answer live chat requests on my company website. Those chat sessions always made for interesting discussions (note to self: find and install a new live chat platform). One challenge that I'd run into is that some folks wanted me to prove that I wasn't a bot. No matter what information I provided to them, it only tended to support their hunch that they were talking to a machine. I don't have any of those transcripts handy, but here's how I recall them going:

 Me: Howdy! How can I help you?

 Visitor: are you a real person?

 Me: Sure.

 Visitor: prove it.

 Me: Let's see. My name is Ben. It's currently cold outside.
     I'm sitting here in sweatpants.

 Visitor: are you really a person?

 Me: Yes. Really. I promise.

 ...

Just reading the above transcript I barely believe I'm human.

I suppose this all falls into the category of First World Internet Problems. But I find it fascinating that in our race to make computers appear more like humans, we've actually made humans appear more like computers.

There's no doubt that the Turning Test is a tough problem to solve. But who would have thought this sort of reversed Turning Test would be, in some respects, just as tricky?

Was this post autogenerated? Would you know if it was? Would it matter?

AutoPebble Programming: Eyes-Free Time Telling

I've always been fascinated with the challenge of being able to 'read' the current time without looking at a watch. Heck, why stop at the time, I'd love to be able to get all sorts of information from my devices without having to actually look at a physical device. I never did get a chance to buy this sweet braille watch from years ago, but now that I've got a hold of Shira's Pebble, I figured I could finally hack to together a solution.

Using AutoPebble, I'm able to send a vibration pattern to the watch which means that the Pebble can effectively talk Morse Code. At the core of my solution is this JavaScriptlet which maps text to a vibration pattern:

      function textToCode(text) {
        var code      = "";
        var letters   = text.toUpperCase().split("");
        var encoder   = {
          A: '.-',         B: '-...',       C: '-.-.',
          D: '-..',        E: '.',          F: '..-.',
          G: '--.',        H: '....',       I: '..',
          J: '.---',       K: '-.-',        L: '.-..',
          M: '--',         N: '-.',         O: '---',
          P: '.--.',       Q: '--.-',       R: '.-.',
          S: '...',        T: '-',          U: '..-',
          V: '...-',       W: '.--',        X: '-..-',
          Y: '-.--',       Z: '--..'
        };
        // Ben's Own Numeric Mapping
        encoder['1'] = encoder['A'];
        encoder['2'] = encoder['T'];
        encoder['3'] = encoder['H'];
        encoder['4'] = encoder['F'];
        encoder['5'] = encoder['V'];
        encoder['6'] = encoder['X'];
        encoder['7'] = encoder['S'];
        encoder['8'] = encoder['E'];
        encoder['9'] = encoder['N'];
        encoder['0'] = encoder['Z'];

        for(var i = 0; i < letters.length; i ++) {
          var c = letters[i];
          var e = encoder[c];
          if(e) {
            if(code != "") {
              code += " ";
            }
            code += e;
          }
        }
        return code;
      }

      function codeToPattern(code) {
        var code    = code.split('');
        var dot     = 250;
        var pattern = [];

        for(var i = 0; i < code.length; i++) {
          var letter = code[i];
          if(letter == ' ') {
            continue;
          } else if(letter == '.') {
            pattern.push(dot);
           } else if(letter == '-') {
            pattern.push(dot * 3);
          }
          var peek = (i + 1) == code.length ? null : code[i+1];
          if(peek == null) {
            continue;
          } else {
            pattern.push(peek == ' ' ? dot*7 : dot);
          }
        }
        return pattern.join(",");
      }
var text = local("par1");
var code = textToCode(text);
var pattern = codeToPattern(code);

There are a couple of hacks above worth noting. First off, each letter is being treated as its own word. So: Hello World would actually be sent as H E L L O W O R L D. For someone who struggles to read even the most basic Morse Code, this simplification makes sense. Maybe one day I'll graduate to parsing words.

Second of all, you'll notice that I'm not using the proper Morse Code for numbers. Instead, I'm using a mapping I made up. It's sort of logical: A = 1, as it's the first letter in the alphabet, 2 = T, as in Two, 3 = H as in tHree, and so on. I did this for a few reasons: first, Morse Code is optimized for frequently letters. So using A = 1 means that I can send 1 as • —. Had I used the proper Morse Code for 1, I'd have to send • — — — —. Secondly, if I'm going to manage to learn anything through this exercises, I'd prefer it was 10 different letters, rather than the Morse Code numbers.

Regardless, the above does the heavy lifting of converting text into dots and dashes, and from there into a Pebble vibration pattern. I wrap up the above code as an action:

Parse Morse (88)
A1: JavaScriptlet [ 
  Code: .. code from above ...
  Libraries: Auto Exit:On Timeout (Seconds):45 
]
A2: Return [
  Value:%%par2 Stop:On
]

Note that Parse Morse is an example of me figuring out how to make Tasker Actions far more modular. Parse Morse takes in two arguments: the first is the text to parse, and the second is the value to return (either code or pattern).

I then setup the Pebble Morse Time action to listen for requests from AutoPebble, invoke Parse Morse and then present the encoded time on the watch. Here's the code for this action:

Pebble Morse Time (106)
Abort Existing Task
A1: Perform Task [
  Name:Parse Morse
  Priority:%priority
  Parameter 1 (%par1):%TIME
  Parameter 2 (%par2):code
  Return Value Variable:%code
  Stop:Off
]
A2: Perform Task [
  Name:Parse Morse
  Priority:%priority
  Parameter 1 (%par1):%TIME
  Parameter 2 (%par2):pattern
  Return Value
  Variable:%pattern
  Stop:Off
]
A3: Variable Set [
  Name:%newline
  To:

  Do Maths:Off Append:Off
]
A4: Variable Search Replace [
  Variable:%code
  Search:  Ignore Case:Off
  Multi-Line:Off
  One Match Only:Off
  Store Matches In:%code
  Replace Matches:On
  Replace With:%newline
]
A5: AutoPebble Text Screen [
  Configuration:Full Screen: false
  Title: Time
  Text: %code
  Vibration Pattern: %pattern
]

The above action include string handling that turns spaces into newlines. I chose to do thiss via a Variable Search Replace action, though I'm beginning to appreciate that it may have been easier to just do this as a Javascriptlet. The multi-line approach me to render the Morse Code for the time in a large font, with one "letter" per line. Here's how it looks on the watch:

That's T Z Z Z O'Clock, or 20:00 or 8:00pm.

To polish off my no-eyes solution, I've setup two short-cuts. A long press opens up AutoPebble and another long press kicks off the Pebble Morse Time task.

It's a crude solution, but technically, it does work. I can manage to get the time buzzed to me all without ever looking at a physical device.

As for my ability to interpret Morse Code, I've still got a ways to go. For now, I'm both vibrating and showing the Morse Code of the time, and as you can tell above, the current time is included in the header of the watch itself. I find that most of the time I can properly interpret a digit or two from the vibration, and read most of the remaining digits by looking at dots and dashes.

All in all, it's a fun experiment and is just more proof at how cool AutoPebble is. It probably took longer to write up this blog post than did it to code up this solution. Good times.

Monday, December 14, 2015

Holmes Run with Fall Foliage and Spring Weather

I'm always psyched when I discover a new section of biking/walking trail in the area. Yesterday, Shira, Dawn and I did a section of Holmes Run that I was totally unfamiliar with. It seems as though Holmes Run is split into different, perhaps non-connecting sections, so perhaps that's why I I hadn't been on it. Or maybe it's just been completed withing the last couple of years. All I know is that we started at Cameron Station Park and went "right" after crossing the bridge.

It's an excellent section of trail and worth your time to explore. Dawn says it goes all the way to Old Town Alexandria.

The weather was absolutely amazing yesterday (the high was apparently 71°F!) and it was a perfect day to be outside. Here's a few snapshots or the foliage along the trail; I couldn't resist stopping and snapping a handful of photos:

Friday, December 11, 2015

Software Defined Radio Fun: Accessing Real Time Flight Data

Here's another trick a $10 Software Defined Radio dongle can do on Android. You plug in the dongle, and kick off ADSB Receiver, a free Android App. And in a few moments, you'll see something like this:

That's live flight data. But the thing, that's not being pulled off the web. That's being received directly from the airplanes themselves (at least, as I understand it). The whole thing is powered by ADS-B, a standard by which planes broadcast their location data.

I won't claim to understand the arrangement, but I'm still amazed that I can pick up this data using little more than a $10 dongle and smart phone. There's no encryption used in the system, which I find surprising (though like most older protocols, that's not really shocking).

Is this actually useful? Sort of. One of our favorite parks, Gravelley Point, is directly adjacent to National Airport. It's the perfect place to sit back and watch the miracle of flight, as planes take off and land just overhead. Hitting the park with this app open, and also using the radio to listen to Air Traffic Control would be pretty sweet.

I also like the idea of discovering an open protocol that's all around us, yet invisible to most.

Makes me wonder what other data I can pick up with my little receiver...

Thursday, December 10, 2015

AutoPebble: Be a Wearable Tech Programmer in about 15 Minutes

Due to a possible upgrade in Smartwatches (more to come, if it pans out), Shira's letting me play with her classic Pebble. My first thought was to look into Tasker integration, and I was psyched to see that there are a number of options. In doing some research, I decided to focus on AutoPebble (rather, than say, PebbleTasker). AutoPebble is written by the same developer as AutoRemote and follows the same development strategy.

The strategy goes like this: AutoRemote and AutoPebble run on your Android Phone and handle incoming messages. These messages (which main contain a payload) are automatically passed to Tasker, where you can install a handler to respond to them. It's a simple glue layer that turns out to be remarkably powerful.

In the case of handling remote requests, AutoRemote's functionality needs to do little more than what's described above. If you send your phone the message say=:=Hello World, and you've implemented a tasker handler to intercept messages that being with say= you're basically done. In the above case, it's trivial to use the Say tasker action to recite the payload ("Hello World").

AutoPebble does the same thing, but adds another layer. Consider the start screen I put together here:

Using the Up and Down buttons, you can choose which option to invoke. When you press the Middle watch button next to Capture the following screen is shown:

The above screen is implemented by AutoPebble's two main pieces of functionality. The first is that selecting Capture sends the capture_list message, just like in the AutoRemote scheme. I've got a listener setup to handle this incoming request. This listener is implemented as a standard Tasker profile, so it can do anything tasker can do. The second bit of functionality is that AutoPebble allows you to render content on your Pebble. So in response to capture_list, I invoke the AutoPebble List action, which generates a UI list on the watch itself. In this case, capture_list effectively generates a sub menu. From the Capture submenu, I'm able to choose what I'd like to capture. Invoking one of these options sends yet another message to the phone using the AutoRemote style convention.

In the case above, I arrange for specific capture requests to be in the format capture=:=SRC where SRC is defined as one of the following: FrontCamera, BackCamera, Sound. Within Tasker, I invoke tasks that correspond to these different sources, and use the AutoPebble UI capabilities to give an informative message as to what the watch is doing.

Here's another quick app I wrote. Using the Barometric Pressure code I wrote yesterday, I'm able to display this information when asked for it on the watch. Now when Shira feels like she's getting a headache and wonders what the barometric pressure is, I'm only a couple of watch presses away from getting her an answer, as well as seeing the history of data I've seen before. Check it out:

I'm positively amazed how quickly I've been able to write useful apps for the Pebble. Most of the time spent struggling on the above apps was spent figuring out Tasker quirks, more so than anything else. Once you get how AutoPebble does it magic, there's not much to it. Bottom line, AutoPebble is an absolute winner. Yes, there are times when it's a bit slow and I've seen some quirky behavior. But from a programmer's perspective it does all the hard work, so I can just focus on the fun part.

I'm not sure how long this little experiment in wearable tech will last, but so far, it's a programmer's dream. Another device I can program; whoo!

If you'd like to see any of the Tasker code that powers the above screens, let me know, and I'll publish it.

Wednesday, December 09, 2015

Android Tasker: Automatically Storing Local Barometric Pressure Data

One of Shira's headache triggers is the weather, specifically barometric pressure. I was wondering how hard it would be to grab the current barometric pressure and store it all based on the phone's current geolocation.

Turns out, not that hard. One HTTP Request to openweathermap.org is all it takes to get the raw data. And parsing the JSON results turns out to be downright trivial thanks to this awesome Javascriptlet hack. JSON saves the day again!

Running this task appends the location, atmospheric pressure and timestamp to a text file.

Next up: using this text file. Stay tuned for more weather hacking fun.

Here's the Tasker Task described above. It's almost too easy to do!

Store Pressure Data (68)
    A1: Get Location [ Source:GPS Timeout (Seconds):100 Continue Task Immediately:Off Keep Tracking:Off ] 
    A2: Variable Split [ Name:%LOC Splitter:, Delete Base:Off ] 
    A3: HTTP Get [ Server:Port:api.openweathermap.org Path:/data/2.5/weather Attributes:lat=%LOC1
lon=%LOC2
appid=API_KEY Cookies: User Agent: Timeout:10 Mime Type: Output File: Trust Any Certificate:Off ] 
    A4: JavaScriptlet [ Code:var data = JSON.parse(global("HTTPD"));
var wloc = data.name;
var wpressure = data.main.pressure; Libraries: Auto Exit:On Timeout (Seconds):45 ] 
    A5: Write File [ File:Download/pressure.txt Text:%wloc: %wpressure | %DATE %TIME Append:On Add Newline:On ] 

Tuesday, December 08, 2015

Morocco Adventure - Day 8

[Written 12/1/2015]

Our vacation is winding down! We traveled from Marrakesh to Casablanca today to stage our exit from the country, which if all goes well, will happen tomorrow morning. This gave us one day to explore Casablanca and get yet another taste of what Morocco has to offer.

From our hotel (the very impressive Hyatt Regency, made more impressive because they upgraded us to a stunning suite on the 10th floor!), we plotted a path to the massive Hassan II Mosque via the old Medina.

Compared to Marrakesh, the old Medina in Casablanca is tiny. But it had everything one hopes to find in a Medina: a friendly Moroccan who just wants to chat, yet eventually offers to take you to a today-only Berber market (I kid you not, this happened today too), an initial touristy section of town, followed by narrow alleyways that take you to more mundane shopping for the locals (need to buy a live chicken or sardines? We found the place to pick them up). It's all good fun, and we navigated it sans map, which means that we hit a few dead ends. Still, we managed to make it to the other side without an issue.

From there, we made our way to the gigantic Hassan II Mosque (the third largest in the world, according to our guidebook). I asked Shira how'd she describe the Mosque and her answer was: "Ornate but tasteful." That's way better than my answer: "big" and "impressive." It really is a site to see and as beautiful as any Cathedral or Temple as I've ever seen.

We're finally cracking the code behind the various market stalls that serve food. You need to spend a minute or two figuring out what they are actually selling by watching others order. A stall typically only sells one thing, so if you're not in the mood (like I wasn't for the snails that one guy was serving), you can safely walk away. Otherwise, jump in and start pointing. Tonight we had some fresh bread stuffed with cheese and chocolate and it was heavenly. Combine that with some sesame candy we bought for $0.30 and you had one delectable snack. The food hasn't always been perfect here, but we've absolutely found some treats that rival the best we've had anywhere.

Oh, and for the record, we did stop by Rick's Cafe in honor of my In-Laws. Alas, we arrived before they were open, so we couldn't go in. And besides, the location wasn't used in the shooting of the Casablanca movie. But still, I was glad to share this touristy moment in their honor.

Driving in Casablanca is definitely less chaotic than in Marrakesh (mostly because there are mainly cars, versus cars, scooters, mopeds, horses, donkeys and bikes to contend with). But they still have a remarkably laxed view of traffic laws. We saw numerous cars and buses stop at red lights, pause for a few moments, and then pull through. Cause you know, red lights aren't that important to obey.

View Photos

Morocco Adventure - Day 7

[Written 11/30/2015]

Today we took a side trip to Essaouira, a coastal town a few hundred kilometers from Marrakesh. Like all the cities we've visited so far, it contained a medina surrounded by impressive looking ramparts. It also contained a section labeled Mellah. Apparently, anytime you come across a 'Mellah' quarter, you've stumbled onto the old Jewish section of town.

Whether it was in Rabat, Sale or El Jadida, the only indication that you were in a Jewish area was the notation on the map. Most of these cities contained Jewish cemeteries, but we never managed to visit one.

It was in Essaouira, however, that our luck changed. Not only did we find two different shuls we could tour, we managed to find something even more rare: a Moroccan Jew. We met Haim, who has spent the last 4 years restoring one of the shuls in Mellah. He took some time out to share some additional history of the area. You can find the website for the restoration project here.

At its high point, there were 39 shuls in the Medina, and only 3 mosques. All but one of the shul's were part of homes, with the shul Haim was renovating, being the only one that was a dedicated building. The town had a Jewish majority, going back to its creation in the 1700's, where it was established as a world wide trade port. Even in their heyday, the shuls were always modest from the outside, to the point of being almost invisible. Inside however, they could be as extravagant as they wanted.

The rest of Essaouira didn't disappoint. The port was especially picturesque, including impressive ramparts you could tour. In honor of being so close to the sea, I had sardines for lunch. Yum! I could have had any number of sea creatures on display at the market, you simply point to what's laying out and apparently they will cook it up for you.

On our way back to Marrakesh, we stopped at Marjane, a sort of Wal-Mart in Morocco. I've got to say, it's pretty dang impressive. You could buy everything from groceries to electronics, just like you would in the US. Shira and I like to visit grocery stores when traveling in other countries, and this was like hitting the jackpot. It's also quite a contrast shopping in a very Western store, and then getting on the road and dodging donkey carts and such. But that's just how Morocco is.

View Photos

Morocco Adventure - Race Du Soleil (Day 6)

[Written 11/29/2015]

Here's a tip: when your wife makes arrangements with a tour company to run a hike for us, and she asks them to combine their two day hike into one day, be afraid. Be very afraid. That's exactly what my beloved did. And so rather than a leasurely stroll through the mountains, we had a trek against time, trying to pack in the miles before the sun set.

In typical Moroccan fashion, as we were preparing to start our hike, they asked us if we wanted to sit down and have some mint tea. We were already behind schedule and had 7+ hours of hiking ahead of us, and they wanted to know if we wanted tea?! We passed.

The hike ended up being a 10 mile, almost circuit. We slogged up the first pass for a couple of hours, and then descended for a few more, before we had a classic Moroccan meal of tea, salad, veggie tajine and pomegranate seeds. And then it was back on the trail for another massive uphill to a pass, and then back down the other side.

I logged the whole trip using Run Keeper, but apparently the elevation data got totally whacked. According to the GPS, we had a total gain of 12,000 feet, a number which isn't technically possible. Perhaps the GPS was set to a sort of feels-like? Because heck yeah, it *felt* like we climbed 12,000 feet!

I definitely found myself sucking wind while climbing that first monster pass. Our guide walked up it like it was nothing. So typical.

The area doesn't have a whole lot of vegetation or obvious wildlife. We passed through distinctive smelling juniper trees, which was a treat, and saw an awwwwww inducing herd of goats. They were more than happy to eat our orange peels (now that's recycling!). We also saw a number of mules, which are the region's preferred method of hauling materials from point A to B. The views more than made up for any lack of unusual flora or fauna.

We passed through a number of Berber villages, which are apparently very much in use today. The villages appear to subsist on very little: a winter wheat field here; a hammam (bath) there. Each village has its own mosque and imam, and our guide was very clear on the point that all Moroccans practice the exact same form of Islam. From the smallest mosque in a tiny village, to the massive mosques in Marrakesh, everyone is on the same page, if you will.

We received almost the exact same messages from our guide as we did from the young shopkeeper we spoke to in Rabat: they're proud of the security measures the government has put in place to make Morocco safer, and they are acutely aware of the damage that's been done to Islam by the latest attacks in Paris. Our guide make it very clear that in his mind, the terrorists in France absolutely do not represent the religion he and his countrymen practice.

After our epic hike and a hot shower, neither Shira nor I could imagine going out for a fancy sit down dinner. So we stepped outside our hotel, and purchased a few essentials: a persimmon ($1.00), a pomegranate ($0.70), two pita sized pieces of bread ($0.20) and a heaping box of pastries ($6.00) and had a fantastic improvised meal.

It's off to bed, where I'll probably be dreaming of a steep climb that never ends, as that was my reality earlier today.

View Photos

LinkWithin

Related Posts with Thumbnails