Sunday, 29 August 2021

Switching to git switch

A recent OS upgrade resulted in my Git version being bumped up to 3.x, an interesting feature of which is the new git switch command, which replaces part of the heavily overloaded git checkout functionality with something much clearer.

Now, to switch to branch foo you can just invoke git switch foo

And to create a new branch, instead of git checkout -b newbranch,
it's git switch -c newbranch

These are small changes, to be sure, but worthwhile in bringing more focus to individual commands, and relieving some of the incredibly heavy lifting being done by the flags passed to git checkout, which hopefully now can be my "tool of last resort" as it usually leaves me stranded in "detached head hell" ... my fault, not Git's!

I've also updated my gcm alias/script to use git switch, so accordingly it's now gsm.

Sunday, 25 July 2021

Automating heating vents with openHAB, k8055 and LEGO - Part 1; rationale

It's winter here in Melbourne, and it's a cold one. Combined with the fact that everyone is spending a lot more time at home than before, it's time to start optimising for comfort and efficiency...

I've shared my house's floorplan before on this blog, but this time here it is overlaid with the "schema" of the gas central-heating system, which sends hot air through underfloor ducts into the house through eight vents (or "registers" if you prefer) - shown as red squares:

Now some houses *might* have "zones" implemented, where certain areas of the house are on a physically separated section of ducting and can be addressed and controlled individually. This house is not one of those. I've shown the two *notional* zones we'd probably *like* to have in orange (living spaces) and green (sleeping areas). If you're wondering, we've been advised that for technical reasons related to our heating unit (aka furnace) and available space under the house, a zoned system is not practicable. In any case, it would probably be a bit coarse-grained anyway, as these days I'm working pretty-much 5-days-a-week at home, from the study - the room at the bottom-left of the floorplan.

As such, I would like to be able to control the specific vent in my study, opening and closing it as needed so that it's warm to work in, particularly in the mornings, but also not wasting warm air that is better off being routed to elsewhere in the house in the evenings and on weekends. Also, if the temperature in the study is warm enough, I'd like the vent to shut itself off. It sounds like the height of laziness, but it happens that this vent is located underneath a large couch, so it's actually a major pain to adjust it by hand.

Off-the-shelf "smart vent" solutions have been available for a number of years, from Flair and Keen but they are Not Cheap, don't have any openHAB binding support, don't have stock available and/or don't ship to me in Australia. So it's a roll-your-own situation...

Thursday, 24 June 2021

How do I find all the HTML elements that aren't getting my preferred font?

A quickie script that saved a lot of manually combing through the DOM

Someone noticed that certain elements in our React app were not getting the desired font-face, instead getting plain-old Arial. I wanted to be able to programmatically sniff them out in the browser, so here's what I came up with, mainly thanks to an answer on Stack Overflow for finding all elements on a page, and the MDN documentation for the getComputedStyle function which browsers helpfully expose.

Whack this in your browser's Javascript console and you should be able to hover on any element that is listed to see it on the page:

  // Start where React attaches to the DOM
  const reactRoot = document.getElementById("root"); 
  // Get all elements below that
  const kids = reactRoot.getElementsByTagName("*"); 
  for (var e of kids) { 
    if (window.getComputedStyle(e)["font-family"] === "Arial") { 
      console.log(e); // Allows it to be hovered in console

In case you were wondering, the culprit here was a button that didn't have its font-family set - and Chrome (perhaps others) will use its default (user-agent stylesheet) font style for that in preference to what you have set on the body, which you might be forgiven for assuming gets cascaded down.

Sunday, 30 May 2021

Using the Velleman K8055 USB Experiment board with OpenHAB 3.x

The venerable Velleman K8055 USB Experimenter's Board is a neat way to interface a modern computer with a selection of analog and digital I/O ports. Unfortunately, support for using it within the OpenHAB home-automation framework (where it seems like a natural fit for tinkering) has fallen by the wayside - it had a proper binding in OpenHAB v1, and kinda-sorta still worked in OpenHAB v2, but it's a non-starter in 2021 with OpenHAB v3.x.

If you're running your OpenHAB (and a connected K8055) off a Raspberry Pi however, you're in luck. Simply head over to Github where some outstanding humans have done all the hard work to get your K8055 working again. It's all nicely-documented, so go ahead and give it a try. Come back here when you've got the k8055 command-line program running and making the LEDs go on and off; I'll wait.

Right. Let's get it cooking with OpenHAB, but without going through the hoops of building a new binding. Instead, we'll harness the power of OpenHAB's exec binding, and use OpenHAB's built-in state management to get persistent control of the K8055's outputs. What do I mean by that? Well, the k8055 program is completely stateless; whenever you tell it to set the digital outputs to 147 (i.e. 8, 5, 2 and 1 HIGH), it does just that, ignoring how bits 7, 6, 4 and 3 were set before - they're going to be LOW. It doesn't OR them or mask them with the current state. In fact, it can't even tell you the current state, only what it should be AFTER executing your instructions...

On your Pi, head to ${OPENHAB_CONF}, and add:

Group:Number:SUM gVellemanOutputs "Velleman output sum"
Number VellemanD1 (gVellemanOutputs)
Number VellemanD2 (gVellemanOutputs)
Number VellemanD3 (gVellemanOutputs)
Number VellemanD4 (gVellemanOutputs)
Number VellemanD5 (gVellemanOutputs)
Number VellemanD6 (gVellemanOutputs)
Number VellemanD7 (gVellemanOutputs)
Number VellemanD8 (gVellemanOutputs)

Number VellemanA1
Number VellemanA2

// Arguments to be placed for '%2$s' in command line
String VellemanOutputArgs {channel="exec:command:setoutputs:input"}
Thing exec:command:setoutputs [command="/usr/local/bin/k8055 %2$s", interval=0, autorun=true]
/usr/local/bin/k8055 %2$s
(In OpenHAB 3, for security, you've got to allow-list all the commands that exec can run)

Now we can add a stanza to our sitemap, to get some UI controls:

Frame label="Velleman Outputs" {
  Switch item=VellemanD1 label="Digital 1" mappings=[0="OFF",1="ON"]
  Switch item=VellemanD2 label="Digital 2" mappings=[0="OFF",2="ON"]
  Switch item=VellemanD3 label="Digital 3" mappings=[0="OFF",4="ON"]
  Switch item=VellemanD4 label="Digital 4" mappings=[0="OFF",8="ON"]
  Switch item=VellemanD5 label="Digital 5" mappings=[0="OFF",16="ON"]
  Switch item=VellemanD6 label="Digital 6" mappings=[0="OFF",32="ON"]
  Switch item=VellemanD7 label="Digital 7" mappings=[0="OFF",64="ON"]
  Switch item=VellemanD8 label="Digital 8" mappings=[0="OFF",128="ON"]
  Slider item=VellemanA1 label="Analog 1" minValue=0 maxValue=255
  Slider item=VellemanA2 label="Analog 2" minValue=0 maxValue=255

This gives us all the controls for all of the outputs the Velleman K8055 supports:

Now we're ready to write a rule that ties everything together and makes it work persistently:

rule "Velleman Hardware Sync"
   Item gVellemanDigitals changed or Member of gVellemanAnalogs changed
  val dState = if (gVellemanDigitals.state == NULL) "" else "-d:" + gVellemanDigitals.state
  val a1State = if (VellemanA1.state == NULL) "" else "-a1:" + VellemanA1.state
  val a2State = if (VellemanA2.state == NULL) "" else "-a2:" + VellemanA2.state

    val formattedCommand = dState + " " + a1State + " " + a2State
   // logInfo("velleman.rules", formattedCommand) // Diagnostics if needed

So the neat "tricks" here I think are:

  • Baking the bit-twiddling logic into each Switch - some might object to putting values like 32 or 128 directly into the sitemap. I figure, you're going to have repetitive code up here in the UI, may as well extract some value out of it if it makes the logic in the rules simpler ... and it really does
  • Using the Group:Number:SUM derived group state to generate the final output byte - the other part of the solution that keeps the rule really clean - OpenHAB itself recalculates the sum of all the switch values that belong to the group gVellemanOutputs
  • Using Member of gVellemanAnalogs to reduce repetition in the when clause on the analog outputs - it's only a little thing, but I like it
It's also refreshed my memory on how powerful OpenHAB Item Groups (as opposed to the confusingly-similar Sitemap Groups) can be. When I consider how many lines of rules code my initial attempt was, and how readable the final result is, I think they are a massive win.

Sunday, 25 April 2021

Computers I Have Known - Part 3.11 (For Workgroups)

(This is Part 3 of my Computers I Have Known series)

The 1990s lurched into existence and my Dad again was pivotal in my computing education. As a secondhand bookseller, he had a need to catalog his ever-increasing stock and also write a monthly column for a trade journal. Through school friends I'd become fairly familiar with the PC and Windows 3.0 had finally made it friendly enough that I figured my Dad would be able to point-and-click his way around.

I'd also become acquainted with the Intel 286/386/486 PC landscape through the magic of the Melbourne (Australia) Age newspaper's "Green Guide", ostensibly the TV guide, but more interestingly a hotbed of small computer shops frantically advertising for your beige-box business, dropping prices a handful of dollars week-on-week. Sadly there seems to be virtually no online record available of this weekly bonanza (that probably had equivalents in almost every major city) - but trust me, in an effectively pre-internet era, it was the nearest thing to a Google search for "Clone PC". We ended up with a very solid upper-mid-end choice - a MicroArts 486-DX33 mini-tower, with 4 megabytes of RAM, 1Mb Super-VGA card on its VESA Local Bus, double-speed CD-ROM drive, a whopping (if memory serves correctly) 340Mb Western Digital hard drive, 15" Viewsonic CRT and a superb HP LaserJet 4L desktop laser printer. The only thing better at the time would have been the DX2-66MHz version, which commanded a large premium for its mind-bogglingly fast CPU, but actually talked to everything else at the same speed as the 33MHz brother I'd selected.

I set the machine up to go straight to Windows on boot (the old WIN at the bottom of AUTOEXEC.BAT ... ah memories) and suitably butchered the Windows 3.0 Program Manager to offer my Dad precisely two things to click on - Write (the primitive yet more-than-sufficient-for-his-needs default word processor), and the proprietary book-cataloguing software which was the standard in the trade.

And with that, he was away. That PC had an extraordinary innings of some 15(!) years, gradually gaining a fax/modem, scanner, network card, more RAM, ticking up to Windows 3.11 (surely the most significant operating system point-release in history) and transitioning from "only computer" to "front desk computer" and finally "back office computer". The Internet came along, and my Dad moved his catalogue of books online through increasingly-sophisticated mechanisms, the first of which was a hand-rolled series of templated HTML pages coded by yours truly, which would get "mail merged" with the output of the proprietary book catalog system, and the resulting family of pages FTPed up to his shop website. People would scroll through the listings, which were by-category only (Art, Music, History, etc) and email him with their order. If they were local, they'd come in and pick them up, but he'd box and ship orders internationally on a regular basis. His "secure credit card option" (his words) was getting customers to send him their credit card number in several separate emails; it was ... a simpler time ...

Yep, my Dad, the luddite, was selling books on the web in 1992 - two years before there was an But I digress.

Pictures of my Dad's website, coded by yours truly, from the earliest available Wayback Machine scrape in December 1998. The Wayback Machine and the Internet Archive are an incredible resource - please donate to them if you can!

Every byte of the above (hilariously-primitive) website was honed (on Notepad or Paintbrush) and uploaded (with WS_FTP) from that 486. This machine was the last box I could confidently say I knew like the back of my hand. From its carefully-tuned BIOS settings through its lovingly-crafted CONFIG.SYS and up into Windows from Character Map to Write, I knew this thing inside-out and tended to it like a cherished pet - which was probably how it managed to survive well into the Pentium 4 era before making its way to the great Beige Box in the sky ...

Sunday, 14 March 2021

Fixing internet access failures after upgrading to MacOS 10.14 Mojave

I innocently upgraded my 2012 Macbook Pro to Mojave (10.14) from High Sierra (10.13) purely because HomeBrew was refusing to let me install any new goodies on such an old OS. The upgrade itself was painless and everything seemed to be in good shape until I tried to access the wider Internet (access to my own local network was completely fine).

Now Internet access problems are extra-infuriating, because "Googling for the solution" instantly becomes far more of a palaver. An interesting quirk of this particular issue was that using my iPhone's "Personal Hotspot" worked perfectly with the Mac. Only accessing the internet directly through the home WiFi was problematic, and other devices were of course completely fine.

So to recap the scenario (and hopefully give this post some Google-ju to help anyone else in this situation), here's what we had:

  • Macbook Pro was running OSX High Sierra (10.13) with no prior network problems
  • Network has been carefully set up and tuned for "meshed" operation
  • Local DNS services provided by DNSMasq running on a Raspberry Pi
  • DHCP services provided by DNSMasq, handing out fixed addresses to "known" devices like the Macbook Pro
  • All local network services working fine - e.g. accessing router admin webpages
  • Internet access when tethered to an iPhone works fine (Mac gets assigned, iPhone is
  • Internet access through wired Ethernet (via a Thunderbolt adapter) works fine
  • Internet access on home Wifi completely fails; no DNS, no ping, no browsing

After a frustrating day, I decided to blow through the Mojave upgrade in case it had been fixed in Catalina (10.15) ... it hadn't.

I went through probably a dozen different iterations/versions of the "recreate your network stack"/reboot/reset PRAM and/or SMC cycle; nothing was helping, and I was still mystified by how the wired Ethernet was working immaculately while the WiFi failed to get "out" of the local network.

Comparing settings with my wife's Macbook that had perfect Wifi yielded nothing, so just for the hell of it, I decided to check the gateway router's settings one last time to see if for some reason I had a special route or firewall rule set for the Macbook Pro's Wifi IP address ( only, which would explain why the wired connection ( had no problems. It wouldn't normally be something I'd do, but given the output of traceroute was showing that the hop to the gateway was working in all cases, I had to start suspecting that the MacOS internal routing of packets was not faulty ...

And lo and behold, WHAT IS THIS? On my (ISP-provided) TP-Link router's Security/DoS prevention page, a place I have rarely if ever visited ... My laptop's Wifi IP address has been automatically added to a blocklist for attempted DoSing of my network ... from the inside ?!?!

I removed the blocklist entry and instantly everything worked perfectly. Oh dear. I have no idea when my laptop started absolutely hammering pings/UDP/TCP SYNs but it must have been at some point during or immediately after the upgrade to Mojave, and the router did what it was configured (completely by default) to do when it saw more than 3600 packets/sec coming from my laptop. Wow.

Reading the rather scant documentation for this router feature indicates that it uses up (extremely precious) router CPU so I've turned this feature totally off - internal DoS prevention seems like a waste of time to me.

Addendum: Disabling SPI and DoS detection/prevention has massively sped up using the router's web UI so I can only imagine it's working wonders for the overall performance. So I guess it's been a win ... overall 😕

Monday, 22 February 2021

Computers I Have Known - Part IIe

Next up in my Computers I Have Known "journey" (ugh) is the classic Apple IIe, in this case the final, "Platinum" edition with 128Kb of RAM, numeric keypad, light grey case, matching monitor and 5.25" floppy drive.
By this time, my family and I had migrated from the UK to Australia, and the Electron, although it had come with us, may as well have been made of cheese. Nobody had heard of it, nobody used it, it was a dead end. My Dad, still working off the "buy what they use at school" advice from before, went completely bananas with a full IIe "educational pack" which bundled in a Star NL-10 9-pin dot matrix printer and a ton of "educational software" (most of which was shareware, but had at least been gathered together and well-organised)

Having a printer was Very Exciting, and considerable amounts of ink were consumed with the classic Print Shop banners being the main culprit. I vividly remember the THINKING ... THINKING ... THINKING ... PRINTING screens that Print Shop displayed while you waited 15, 20 or more minutes for a big banner to tractor-feed its way into the world.

The Apple II was already a bit long-in-the-tooth when we got it around 1989 - it had an amazing run for such an "average" 8-bit machine - no doubt helped by Apple's strategy of getting it into schools. It was certainly quite depressing seeing far cheaper Commodore Amigas in department stores running demos of high-resolution bouncing balls, reflective surfaces and relatively high-fidelity music. The 16-bitters were coming and it was impossible not to be impressed by how far the goalposts had moved on. The flipside for me was the popularity of the Apple with my peers (and the ease of copying its disks) made it far easier to expand my software portfolio than I had ever experienced before.

Some more of my favourite software for the Apple: (all screenshots from Moby Games)


A clever example of how great playability can completely offset some pretty ordinary (tiny, horribly-coloured) graphics. You can play it on the Internet Archive here.

California Games

Radical! Tubular! You're wild and crazy! A nice collection of action sports that didn't take itself too seriously. You can play side 1, which includes my favourite, BMX, at the Internet Archive.

Wings of Fury

What an absolute masterpiece of an arcade game. Amazing playability and balance of realism and challenge. You can actually go and play a version of it online and while it's the PC version not the Apple original, I recommend you go and do so immediately. The Internet Archive also holds the true Apple II version but it asks for side 2 of the disk and I can't find a way to feed that in; although the Emularity project that makes this possible are aware of the issue.

As I progressed through high school, the capabilities of the Apple as a word processor became far more important. Many of my peers were still submitting draft essays in longhand, then rewriting the whole thing again after getting the teacher's feedback - a process that seemed incredibly repetitive and wasteful. I took the opportunity (for perhaps the first time in my life) to harness the power of the computer to save me some effort. AppleWorks had been included in our original bundle of shareware, and I used it for a good few years. Being about as non-WYSIWYG as it gets, it was my introduction to marking up text, and thus some of the fundamental ideas of HTML were getting drip-fed to me as I wrapped a sentence in Ctrl-U (or whatever it was) to underline it. The whole printing process was a lot more manual too - choosing a font and its output quality was done with buttons on the printer's front panel, and constant vigilance was required when spanning pages; top- and bottom- margins were highly variable in reality.

A revelation came along when I "obtained" (probably through some disk-copying skulduggery at school) what I think must have been BeagleWrite (although I have no recollection of that name), which was a full WYSIWYG, GUI-and-mouse driven word processor, with white background and black text making it look like a true Mac refugee. I was fairly familiar with the Mac's point-and-click paradigm but actually doing productive work with it (as opposed to just fooling about on someone else's computer) was pretty incredible. I believe we'd call it "discoverability" now, but the ability to just see what commands were available, and of course undo them was mind-blowing. I think it's fair to say that the reason I became "good with computers" was through amazing pieces of software like BeagleWrite where there was no penalty for just trying stuff to see what happens. Apparently this is not that common a trait ...
BeagleWrite screenshot from Vintage Geek - for such an incredibly-good bit of software there is very little evidence of its existence!

And I can't write a post about the Apple II without mentioning my own brush with its legendary creator Woz. Probably the most famous person I will ever have had the pleasure and honour of meeting.