So, I avoided the #freakout! The conference talk went well. The one thing that didn’t go well was trying to use Periscope. It turns out that attempting to type, show things via a phone, and deal with the inherent delay of viewing “live” in Periscope was more than I could take on at a time. The moderator came up and showed me that there was a light with some sort of button I could push which would then project whatever was under it. Should I end up getting to talk at OSCON again, I’ll investigate that a bit further. As it was, I ended up just providing color commentary to the audience (“if you could see this up close, it’s blinking!”), rather than attempting to deal with one more thing on the fly.

So, the results… beyond me feeling like it went well, I have a few more data points to suggest, hey, this came off very nicely! First, the qualitative: right after my session, I had to jet to the airport to catch my flight. Not one but two different folks in the same security line mentioned that they had just seen my talk and really enjoyed it. Score! Basking in feelings of minor celebrity there in the security checkpoint line. Second, the quantitative: of likely 60 (!!) folks in the room who came to my talk, 6 have taken the time to evaluate my session and give it a rating. Of a potential 5 point rating, I have 6 folks who’ve given me an average of 4.67 as a rating… Just for the record, I’m not one of the 6… I haven’t, unfortunately, taken the time out to rate anyone else’s schedule, so I’m particularly grateful for those who’ve taken the time to give me a good rating.

I’ll be given a reprise of the talk at a local Golang group on June 23rd… Trying to figure out what to add between now and then – doesn’t feel right to give a duplicate talk, exactly. But do want to take advantage of the work already done and expose it to a local audience….

I’m at OSCON 2016 in Austin. As opposed (ahem) to the last time I did this, I have a slide deck ahead of the day of, as well as working hardware. Realized earlier today, though, that working hardware is only practically useful if the audience can see it… Since the video is trained on the stage, rather than on me, unless I do something, it doesn’t practically matter whether my schtuff works. Problem, particularly given the amount of time I’ve spent making sure schtuff works…

To resolve it, I’m experimenting with live streaming. From my phone, I can send out a Periscope stream, which I can then pull up from my browser to make it visible on the screen to those in the audience. Depending upon lighting, maybe this’ll be valuable and maybe it won’t, but at least it’ll be cool!

Woke up today with a pounding sinus headache. That’ll teach me to think I can walk around outside in the springtime without any allergy meds. After a few hours of sleep, the pain was at least muted enough to function in a quiet environment. So, down to the basement I went to work with Furby.

Luckily for me (???!), Furby was quiet today. Too quiet. As in, couldn’t get it to come on at all quiet. Took a step back and futzed with LEDs again, now tied through the ribbon cable. Uh, finally got the LEDs to come through. But then they stayed on – wouldn’t power on/off at my signal. And then they went out.

That hardware thing: no real configuration management. I guess I could take a picture of my breadboard at a quasi working state, but even then, I’d need to zoom in fairly far to see where the pins practically connected. Several errors today just based on not being able to see where the pins aligned on the breakout board, or whether the pins were in the same row…

So, I retreated and wired in my Furby to a straight 5V + GND alignment. The power wire kept coming undone, so the Furby stayed off. When I finally got her on, none of my sound signals were getting picked up. I’d tried replacing components, completely redoing wiring, … nothing was coming together. At around midnight, I was adding up the problems (non-working power on/off, non-working Furby!), comparing it to the time spent today, and started down the path of ‘oh my gosh, what on earth am I going to say at the front of the room next week??!?! Should I find a way to bail out now?!’

I went to bed. Or tried to for a moment, anyway. And then decided to be stubborn and try to see whether a new set of speakers would send out sound differently – if I could get the Furby to react at all, I’d find another power on/off solution, and maybe I just needed a better set of speakers. Disconnected the ones from the family computer, tried to plug them in down here in my lair. No luck. The set upstairs expected to be powered from a bass which sits underneath the computer. The speakers themselves were big enough they’d be a pain to lug on the plane. No way was I lugging the bass, too…

Defeated. And then an idea.. what if I just needed to make the sound louder from my own speakers? There was no volume control on them, but maybe there was a way to control it programatically. Long story short: there is. And with a louder volume, Furby starts behaving. And the conference session was saved.

I still want to figure out a better power solution. But that’ll mean driving blinking things from GPIOs again, and that wasn’t working so well today. And then adding some sort of NPN (?) solution in the middle to let the GPIO interact with a 5V source, instead of the 3.3 it’s happy with. BUT, as of 3:30, I have a Furby responding, with an LCD display showing info. I _could_ give the talk just based on that… We’ll see!

Attempting to iterate over a map[string]interface{} type in GoLang to retrieve the field key’ed as ‘status’. Known: the interface{} type for the value is _either_ a string OR another map[string]interface{}…

Unsuccessful attempt:


func (paramToCheck string) findKey(keyToCheck string) (string, bool) {
        return keyToCheck, (keyToCheck == paramToCheck)
}

func (paramToCheck map[string]interface{}) findKey(key string) (string, bool) {
        for key, value := range paramToCheck {
                foundValue, found := value.findKey(key)
                if found {
                        return foundValue, true
                }
        }
        return key, false
}

func (val interface{}) findKey(key string) (string, bool) {
        fmt.Println("Unable to find value...")
        return key, false
}

Results of go install:


./parseResult.go:55: invalid receiver type map[string]interface {} (map[string]interface {} is an unnamed type)
./parseResult.go:57: value.findKey undefined (type interface {} is interface with no methods)
./parseResult.go:65: findKey redeclared in this block
previous declaration at ./parseResult.go:55
./parseResult.go:65: invalid receiver type interface {} (interface {} is an unnamed type)
./parseResult.go:78: value.findKey undefined (type interface {} is interface with no methods)

Back to the drawing board… The other day, I also tried a switch statement approach like the below…


switch val := v.(type) {
                case string:
                        fmt.Println(val)
                        checkVal = val
                case map[string]interface{}:
                        fmt.Println("Found interface...")
                        for k, v := range val {
                                switch val := v.(type) {
                                case string:
                                        fmt.Println(val)
                                        checkPhase(k, checkVal)
                                case map[string]interface{}:
                                        fmt.Println("Found ANOTHER interface map...")
                                }
                        }

                }

I ended up realizing I needed something a bit more recursive, since I know there are at least 3 levels of map[string]interface{} gook in my data set.

Looking at what I’ve got, suspect what I need to is blend the function approach with the switch statement approach and duck the attempt to add polymorphic methods to string.. Huh. Why didn’t I see that before starting this blog post?? Good blog audience who hasn’t even seen this. Just attempting to describe this to you may have got me a solution. Saving my draft here and trying it out…

OK… results that did what I want… Bingo!!!


func findKey(key string, value interface{}, checkKey string) (string, bool) {
        fmt.Printf("findKey for %v against checkKey %v\n", key, checkKey)
        switch val := value.(type) {
        case string:
                return val, (key == checkKey)
        case map[string]interface{}:
                for newKey, newValue := range val {
                        foundValue, found := findKey(newKey, newValue, checkKey)
                        if found {
                                return foundValue, found
                        }
                }
        }
        return "", false
}

func ParseJobState(params map[string]interface{}) []JobOutcome {

        // Example: non-compiling code: [1]JobOutcome != []JobOutcome.
        // Size of array is included in its type.  Use slices instead
        //outcomesArray := [...]JobOutcome{firstOutcome}
        //return outcomesArray

        for key, value := range params {
                statusValue, found := findKey(key, value, "status")
                if found {
                        fmt.Printf("Status found: %v\n", statusValue)
                        break
                }
        }

}

[BLOGGER NOTE: Just added the Preserve Code Formatting plugin to WordPress – code blocks like the above work MUCH more nicely now… Thanks to http://blog.templatemonster.com/2011/04/15/wordpress-plugins-code-snippets-displaying/ for helping find a solution…]

+1 for hardware: got my Raspberry Pi using my MacBook’s Wifi connection for its Internet, as well as the Macbook as a DHCP. Outcome: my pi now has an IP address I can grab from the Mac, which means I don’t need a separate monitor and keyboard hooked up to the pi to be able to do things.. I can ssh into the pi and effectively use my laptop as my keyboard and monitor. And my pi can still reach out to the Internet, which will mean it’ll be able to access a remote Jenkins server, even if remote just means hosted off the Mac. These are important things to consider when dealing with a conference where you’ll be working off of an unknown WiFi….

-1 for software… was trying to get a feature done for our sprint demo and just didn’t quite get it there. Number of reasons impacting, some of them a result of other folks’ efforts, but the net is that tomorrow’s demo won’t work end-to-end.

If my +1 and -1 were merge request voting, I’d be done for on my team.. -1 is a reject status, regardless of how many plus ups balance it out. But since this is the realm of humans, I’ll count the day at worst a draw.

Caught a post in my Twitter feed called “Couch Con’ing O’Reilly Fluent Conference 2016”… David couldn’t go to Fluent – web development conference this year, so he listed the sessions he would have gone to and indicated why. It made me think of how I approach conferences. Most of the conferences I want to go to, I can’t go to – there’s not enough time and money loosely available for me to hit up everything I’d like. But I’ll often do what David’s done and survey the session list for a conference… my intent is to see what the general themes are, and see if there’s anything that comes up enough to either have me try to find some replay of that session or go research the topic on my own. Couple of hints on the approach for replaying sessions or otherwise getting access to information a speaker will present:
1) O’Reilly in particular tapes many of its conferences and makes the sessions available to its Safari subscribers. I’ve caught sessions from Strata, Cultivate, OSCON, and Fluent, all through paying one fee per year for unlimited video access. Even for conferences I attend, I can’t hit every session I want – this lets me go back and catch all the topics I manage to find time to fit in.
2) Some conferences (Google I/O, Oculus, Samsung Developer) are kind enough to set up YouTube channels, with videos per presentation.
3) Conference schedules list speakers. Speaker bios list blog pages and Twitter handles. Often speakers will be talking about their topic du jour on their site or Twitter stream… maybe even posting their slides or blog posts talking about their topic. Nothing like paying attention to a speaker’s material before they have to get in front of a crowd of a few hundred folks – helps them fine tune and you get better insights.
4) Some speakers are at conferences at least partly to gain visibility in the tech ecosystem to get their book at the top of your reading list. OK, maybe I can’t hear you in person, but I can skim your book. You, speaker, went out of your way to be approachable at a conference. I, potential book purchaser and person interested in topic, value that putting yourself out there and may buy the book which you’ve basically set up your talk around.

For the record, I’m findable online for MIL-OSS (few OZONE Widget Framework GOSS talks, and one Ignite style session on “It’s the Community, Stupid”) and O’Reilly OSCON (2014: “Arduino + Furby Broken Build Notification – Oh, You’ll Want to Fix it Quick!”). I’ll add to it this year with another OSCON talk: “FURBY: ‘Go’ away!”. So watch my blog and Twitter feed for insights into the new talk as I mutter my way through evenings of code and Furby mumblings.

Doing some researching for my upcoming OSCON talk, ran across the following thread on golang-nuts, a Google Group dedicated to GoLang:

Silly question – why?. As in, why GoLang? A terrific thread for my OSCON talk. Note the originator of the thread: furby themselves. Spooky / scary / affirming / wow that’s amazing coincidence.

(For why that’s spooky / scary / affirming – check out my post describing my intended talk – Furby driven by Gobot, a robotics/IOT framework built upon GoLang.)

Thing just realized… a GitHub gist is its own repository. I’ve treated it as a place to drop notes, mostly, and only edited them via the Github interface. Tonight I tried cloning my gist, and discovered that worked nicely – I had my notes file handily on my local computer. Better, though, I realized I could add more items to my gist… Could set up separate files, all within the same gist context. Each shows up as a separate block containing content.

I next tried to setup a directory, just to see how it’d be conveyed in the interface. Added a directory, added a file within the directory, pushed it up. Went to the interface – nothing changed. Went back and looked: my branch now shows itself as 1 commit ahead of origin/master, and the push of the directory shows that it was rejected by the remote, with a pre-receive hook which indicates that ‘Gist does not support directories’.

Interestingly, gits do support branches. As I listened to my daughters sing some very odd version of Rudolph the Red-nosed Reindeer (who had a very advantageous nose…), I created a ‘weirdChildren’ branch. Git says it pushes up to origin, but the Gists don’t actually show me there’s a branch. I deleted my local branch, and then repulled from remote – got the changes that were unique to that branch.

Now, gists do offer a handy ’embed’ artifact, such as the following: . Whether the gist is secret or not, if that URL is given out, the contents of the Gist can be displayed. However, the URL doesn’t at least directly expose a way to browse the branches of a Gist. In GitHub.com, a branch would be exposed by using username/project/tree/branchName. E.g., colemanserious/gobot/tree/bmp180. That same /tree/branchName suffix doesn’t work on Gist, though: you end up on the GitHub’s well done 404 page. TLDR: if you use a branch for a Gist, you can futz with keeping versions hidden from all view, whether through gist searches or through those who’ve got a copy of your gist’s URL.

Just submitted a topic for OSCON 2016…. now to wait with bated breath to see if my topic is accepted. The topic is Furby related, of course, since that broke the previous logjam of unaccepted submissions – I’m completely superstitious! A/B testing suggests that all previous topics that were not Furby-related, even those submitted in the same year as the Furby submission, were not accepted. Therefore, to optimize chances of acceptance and/or to refute the A/B testing result, submitting a Furby-related proposal. If this one’s accepted, God help me, I may be working with Furbys for the rest of my life… I may need to upgrade to the Chewbacca Furby.

Spent much of this afternoon frustrated at work… Tried to do something “smart” and use a provided virtual machine to run through a tutorial. First time using a virtual machine on that particular box was not pleasant. Completely slowed down my machine, and then the virtual box instance itself was slow to the point of uselessness. The VM would occasionally decide it was done, and would just close. When I finally got something close to working, VM-wise, after the first few steps in the tutorial, an instruction just didn’t work right.

So I’ve spent this evening working to get an environment on my home machine which’ll presumably let me get past the step that got blocked at work. Here’s the life of a computer geek:
* the software I need to run is compiled for a few different operating systems, but not mine.
* there is a link provided to the GitHub repository hosting the source. Good luck: the link goes to a project area that includes 4 pages of potential code repositories. Some of them are marked as no longer supported, but none is conveniently marked with a ‘Start Here’. Even the repository named Documentation is missing a README.md or any sort of file named ‘BuildMe’
* OK, maybe I can use a different operating system distribution by downloading a VirtualBox image of that operating system and getting it set up.
* Hmmm – VirtualBox installed – good. CentOS 64 bit image? Not so much – go find it.
* Now how to get the software RPMs on my CentOS 64 bit image? Need a shared drive. That requires a Guest Additions to be installed in my VM image.
* To install it on Linux requires me to add gcc and kernel-devel. Also prefers something called dkms, which I’ve not heard of before AND which can’t be found from my machine
* Finally got a shared mapped drive, after a few more Googles for missing steps. I’m still missing OpenGL support, I think, but am going to quietly ignore that until it becomes a problem for me.
* By the way, keyboard mappings vary significantly between CentOS and Mac. Meaning, stupid things like finding ‘*’ are a hunt and peck game across my keyboard. I have a README file now shared between the system to help remind me where things are.
* FINALLY have the file I wanted to share in the shared drive, moved over, granted with permissions to the user I want it to. `sudo yum install *.rpm` (after finding *, which is an intuitive Shift-]) complains about some missing libraries. Turns out there are steps listed in the software’s guide for installation of dependencies.

Let’s see – how many bullets above in terms of steps, before I get this software to a potentially runnable state? One has to be particularly bull-headed to continue moving forward. And particularly convinced that she’ll knock the next set of concerns. But sheesh.

OK, software’s installed. First execution – barf. But I know what the next thing is, and will tackle it tomorrow. It does help if one runs an IDE inside something with a windowing system, rather than just a terminal.