Indiegogo, SARS and a GPD 2 Pocket Computer

Yeah, Indiegogo is a bit dodgy; a closer look at their recent MATE X e-bike campaign revealed that the people behind the campaign have failed to deliver products from their previous campaign – but that hasn’t stopped Indiegogo from promoting them.

and it goes on and on… so the lesson is don’t trust Indiegogo, even if the campaign in question looks legit, because Indiegogo don’t give a flying fuck.

The actual story: my main laptop is getting a bit old and its batteries have started to do the sudden-death dance. Unfortunately they’re also near-impossible to replace, so I figured the GPD 2 could be a nice replacement; it wouldn’t break the bank, it’s reasonably powerful, tiny… perfect.

I ordered one off Indiegogo, the vendor (GPD HK) decided to ship all their US orders first – a bit cheeky, but no worries. Eventually they did ship my unit (amazing that someone actually shipped their product) but GPD went and under-declared the item’s value by 3.4 times, nice. The South African Revenue Service’s Customs/Border Control thought $180 was a bit on the low-side for a laptop and stopped the parcel. I exchanged e-mails with a customs officer through a DHL agent over the course of two weeks, during which I was completely honest and upfront with everyone concerned. I had to badger them, they never spontaneously e-mailed me.

The gist of it is that SARS requested evidence of the value of the item, which I provided in the form of the Indiegogo order confirmation e-mail. I should point out that it is trivial to fake this, and many people do.

In response, the SARS agent produced a comedic nugget : “provide an explanation from the importer as to why the goods in this consignment was under declared for US$180.00 when it has an actual value of US$609.00.” – seriously ? because everyone routinely engages in mind-reading.

My response : “I do not have an explanation for the discrepancy; I paid for the item some time ago and only recently got a notification that the item had shipped, beyond that I haven’t had any communication with the vendor. I did not request that the vendor under-declare the value of the parcel”

The customs official : “ask the importer to get an explanation from the Vendor as to why they under valuated the goods.”

Which I did lol, and GPD responded : “in order to avoid high tariffs, we declare the device as a laptop,and the price is  $180, shipping cost is  $15, for a total of $195.” GPD’s response just goes to show how, to them, under-declaring an item’s value is completely normal and by extension there’s nothing wrong with that practice.

Fast forward two weeks, ~20 e-mails later and SARS has done what I expected: they’ve put so many duties and penalties on the item that there is no equity in the item and therefore the only logical action to take is to abandon the package.

A love letter from SARS which can be summed up as “pay us a crapton of money or the precious gets it!”
The important part of Section 84 of the Customs and Excise Act of Apartheid South Africa 1964

Of course, DHL also wants their cut; so taxes, administrative charges, penalties (which are also taxes) and the neighbour’s dog food costs for this item now sit at R 7070.68 . Someone has to pay for all those luxury cars.

Reading the act, the part that scares me is the “who makes use for the purposes of this Act of a declaration or document containing any such (false) statement shall, unless he proves that he was ignorant of the falsity of such statement and that such ignorance was not due to negligence on his part, be guilty of an offence and liable on conviction to a fine not exceeding R40 000… treble the value of the goods… imprisonment for … ten years” – Scary, which is what you’d expect from an apartheid-era law.

I didn’t know that GPD had under-declared the value of the item, but by initially paying the customs duty DHL advised me to pay, was I “making use of a document containing false statements” ? Assuming I was ignorant, was I also negligent ? Does DHL have a duty to make me confirm the customs value of items I import ? I’ve gone and checked and DHL did not provide me with the value of the item during their initial request for a customs duty payment and I’m not sure it’s reasonable to expect a member of the public to know and understand SARS’s complex duties calculation to the extent of being able to reverse engineer an amount calculated with it – so short of requesting the declared value from DHL, there was no way of knowing what the parcel’s declared amount was.

Well, I won’t pay and here’s hoping that’ll be the end of it from my side. I’ll abandon the package and then GPD, because you misdeclared the item, the ball is in your court; you can either refund me or send me a replacement, but correctly declared this time 😉 and if you don’t, I’ll do a chargeback.

The question is, who’s winning here ?

GPD don’t care because I’m probably 0.01% of their customer base. If this happens too often they’ll just stop shipping to South Africa. So they’re not losing, they’re winning.

I lose because of the inconvenience of, yet again, GOVERNMENT doing everything they can to (1) squeeze more money out of me and (2) make business difficult – because that’s what makes for a successful country. It’s really important to protect the local ultra-netbook industry (mostly owned by the Guptas btw). I also lost out on the initial customs duty payment.

DHL wins the most because they retain their fee for shipping the parcel and the initial amount I paid for customs duty (this amount almost certainly won’t go to SARS).

SARS loses in every way; they won’t get any customs duty on the parcel, a staff member has had to spend time dealing with this case, writing multiple e-mails and at least one official document. The government will -eventually- auction off the package in 6-9 months, by which time it’ll be worth radically less than it is now (and of course those auction sales are dodgy in-and-of themselves). SARS/the ZA government has wasted time and money dealing with this situation and in the process has helped create an illicit trade, increased incentives for providing false/fraudulent documents and stifled business.

with love, SARS


Header image acquired from Wikipedia under the Creative Commons Attribution 2.0 Generic license.

Humon Hex Bluetooth Protocol

AKA Reverse Engineering the Humon Hex Muscle Oxygenation Sensor’s Bluetooth Protocol

Athletes (or I suppose more generally mammals) have muscles. Muscles consume oxygen when they do work and output carbon dioxide into the host system’s blood. If insufficient oxygen is present, the muscle starts consuming glycogen, which is a somewhat finite resource and results in lactate as a byproduct of the consumption. Work done through the consumption of oxygen is aerobic work and work done with reduced oxygen is anaerobic work.

The transition between these two states is caused by a balance between a muscle’s ability to consume oxygen and the host system’s ability to supply oxygen to that muscle. Generally heart rate is the most-easily acquired indicator of whether or not the host system is struggling to supply enough oxygen to its peripherals, but heart rate has high hysteresis and varies per person, amongst other issues. As a result, Muscle Oxygenation “moxy” sensors are useful because they’re precise, provide absolute readings and they’re fast. They are analogous to reading a car’s engine RPM directly vs trying to figure out the RPM by looking at the water temperature.

Unfortunately, moxy sensors have historically been very pricey with units like the Moxy and BSX Insight in the range of several hundred dollars. A coach told me recently that athletes generally go to a lab to be measured (?!). A new company on the block, called Humon, has released a product called the Hex and the Hex does moxy. The Hex is less than half the price of its competitors. It’s also small and modern, with wireless charging. It’s generally a very very cool device.

A Humon Hex
The underside of a Humon Hex

The Hex transmits data on both ANT+ and Bluetooth Low Energy (BLE/Smart). The ANT+ variant of the data is standardised and easy to acquire if you have the correct radio to do it. The BLE variant of the data unfortunately is not standardised and Humon declined my request for the protocol specification… this guide is both to help others and a reminder to myself how the device works and more generally how to access BLE sensors on Linux.

I want a small logging device for my bicycle 😉 but I don’t want something that has a display because I don’t want to be distracted. I just want the data for later review, so the logging device should ideally be small enough to be tucked away in or under the bicycle’s seat. In order to achieve this I figured I’d build a logging device out of THE AMAZING Raspberry Pi Zero W. The Zero W has a built-in wifi and bluetooth radio but said radio doesn’t support ANT+ and adding ANT+ would increase the size of the device, look crap and use more battery power. Bluetooth Low Energy is therefore the best option.

Everything that follows should work on any device running Linux with BLE support and running a recent version of Bluez (5.40 up).

Start by putting the Hex on you, press the power button once to start it up. The LED will rapidly fly through some colours and then go red. Double-push the button, the LED will go blue and after a while, it’ll go green. Green seems to mean the device is both calibrated and transmitting.

Get yourself a screen/byobu session : screen
Run bluetoothctl
In the interactive console :
power on – this powers on the BLE radio
scan on – this begins scanning for hardware
Wait for the device to show up as a detected device.

The hex will show up as “Hex XXXX”. This next step may not entirely be necessary :
In the terminal enter :
scan off – to stop the scan, we know what devices are present now
agent on – this is to enable pairing authentication
default-agent – this exchanges some keys but doesn’t ask for input
pair 00:00:00:00:00 – replace the zeroes with the mac address of your Hex

The device should now be paired.
connect 00:00:00:00:00 – connects to the device
info – if you want some cool info:
Name: Hex A2C6 Alias: Hex A2C6 Paired: yes Trusted: no Blocked: no Connected: yes LegacyPairing: no UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb) UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb) UUID: Device Information (0000180a-0000-1000-8000-00805f9b34fb) UUID: Battery Service (0000180f-0000-1000-8000-00805f9b34fb) UUID: Vendor specific (0000f00d-1212-efde-1523-785fef13d123)

This next part requires a “characteristc”. I’m going to demonstrate the 0000deef-1212-efde-1523-785fef13d123 characteristic, but the others I’ve looked at are listed at the bottom of this page. the deef characteristic is listed in the Humon Hex APK source code as HUMON_CALCULATED_DATA_CHARACTERISTIC.

In the terminal : select-attribute /org/bluez/hci0/dev_F5_63_A2_C6_8D_8D/service001a/char0024
and then read. The result will look like this :

And yes, I gave some thought to whether or now I should leave the MAC addresses in… it’s a moxy sensor 😀

The resulting values count as 16 bytes in total, which seems like… a float maybe ? I couldn’t figure it out easily, so I grabbed a copy of the Humon Hex Android APK and decompiled it. It took a lot of digging as the app is a React Native application with most of the logic minified into a horrible blob of Javascript… BUT grep exists, so yay. After much grep’ping I came across this :

apk/assets/shell-app.bundle:__d(function(E,R,_,A,T){Object.defineProperty(A,"__esModule",{value:!0});var C='0000-1000-8000-00805f9b34fb';A.BleUuid={DFU_SERVICE:"0000FE59-"+C,HUMON_DEVICE_INFORMATION_SERVICE:"0000180a-"+C,HUMON_MODEL_CHARACTERISTIC:"00002a24-"+C,HUMON_SERIAL_CHARACTERISTIC:"00002a25-"+C,HUMON_FIRMWARE_VERSION_CHARACTERISTIC:"00002a26-"+C,HUMON_HARDWARE_VERSION_CHARACTERISTIC:"00002a27-"+C,HUMON_SOFTWARE_VERSION_CHARACTERISTIC:"00002a28-"+C,HUMON_MANUFACTURER_CHARACTERISTIC:"00002a29-"+C,HUMON_DATA_SERVICE:"0000f00d-1212-efde-1523-785fef13d123",HUMON_RAW_DATA_CHARACTERISTIC:"0000beef-1212-efde-1523-785fef13d123",HUMON_CALCULATED_DATA_CHARACTERISTIC:"0000deef-1212-efde-1523-785fef13d123",HUMON_COMMAND_CHARACTERISTIC:"0000abcd-1212-efde-1523-785fef13d123",HUMON_STATE_CHARACTERISTIC:"0000abc0-1212-efde-1523-785fef13d123",HUMON_BATTERY_SERVICE:"0000180f-"+C,HUMON_BATTERY_CHARACTERISTIC:"00002a19-"+C,HEART_RATE_SERVICE:"0000180d-

This told me what the characteristics on the device do. EVEN MOARRRRRR grep’ping later I found some of the code the app uses to reconstruct the data from the device. This is the cleaned up version :

groupNBytes = function(bytesArray, sizeOfGroup) { var n = Object.keys(bytesArray).map(function(sizeOfGroup) { return bytesArray[sizeOfGroup] }); return n.reduce(function(bytesArray, t, a) { return a % sizeOfGroup == 0 && bytesArray.push(n.slice(a, a + sizeOfGroup)), bytesArray }, []) }

byteArrayToFloat = function(r) { var e = r[3] << 24 | r[2] << 16 | r[1] << 8 | r[0], n = new ArrayBuffer(4); return new Int32Array(n)[0] = e, new Float32Array(n)[0] }

Take the values from the terminal, build an array with them and then curry them together to get something cool :
[0] 37.44892501831055
[1] 68.58602905273438
[2] 0.6468204259872437
[3] 3

In this case [2] very closely matches the value my Wahoo ElMENT Bolt showed when I executed the read command in the terminal (multiplied by 100x).

You can stream these values by entering notify on once the attribute has been selected.

That’s about it for now, the next step is building a logger.

P.S. The battery level can be found on this characteristic :
select-attribute /org/bluez/hci0/dev_F5_63_A2_C6_8D_8D/service000b/char000c

Ratanga Junction: Then

Back in October 2012 I figured that at some point, in the then near future, that the Ratanga Junction theme park (located near Cape Town and built using funds from the global financial crisis of 2001) would probably be closed and demolished. The theme park had just lost two of its major attractions to land that had been carved out and handed off to office-block developers. It couldn’t be much longer I thought, so I decided to pay a visit to the wounded park and take a few photos for posterity.

In reality the bleeding theme park continued running for another six years and only now has proper disassembly of the park begun. I’ll eventually go back and try and recreate some of these images with whatever comes to replace Ratanga Junction, but for now here are a few titbits :

Welcome to Ratanga Junction – October 2012
COME TO RATANGA JUNCT – December 2006 – thank you Arnold van der Walt

The Ratanga Junction sign boards/map boards summed up the state of Ratanga Junction at the time: sweating the asset. Monetary input was so tight the administrators didn’t have money to update the map boards by printing new boards when details changed, and more importantly, entire subsections of the park disappeared. Here the board is metal with a plastic/vinyl covering on which the salient information has been printed. The missing section of the map was physically cut out of the vinyl. Additional references to the ill-fated rides, in the bottom right corner, have been blacked out with insulation tape.

What happens when new things made-to-look old get old ? A Hippo from Hippo’s Hollow in surprisingly good condition for a 12-year old ornament.
New old-things getting old…
The Congo Queen ride.

Ratanga Junction was designed to be an immersive experience; entering the park was supposed to be like being whisked away to a foreign land. This approach relied on one suspending one’s sense of disbelief and to aid that the park prevented patrons seeing anything outside of the park’s boundaries…

A sign of things to come – a different view of the Congo Queen ride.

Of course, when the park’s limbs started getting chopped off, the illusion of a foreign land died very quickly – and ironically those visions were replaced with images of things to come.

“Exciting hospitality offerings” are coming soon… (look how happy their mascots are)
Remnants of an unknown ride and The Diamond Devil Run.
Better times: part of the building in the lower-centre is present in my photo above on the right.
Spooky Voodoo Bridge – leading to a newly-constructed car park.
Spooky Voodoo Bridge back when it did go somewhere.
Entrance to The Cobra roller coaster – renamed to “The Cape Cobras” in support of corporate sponsorship (from a company that no longer exists).
The original, un-sponsored entrance (2006).
The disused railway, now overgrown.
Maggie’s Park (female primary mascot) looking over disused railway line and new car park.
The Ratanga Junction Arena
A “lobby” area. 4×4 CRT public displays were obsolete, even in 2012.
A “window” on the disused cinema building.
Patrons enjoying Monkey Falls

SlingStudio Learnings

I run a business on the side that does corporate video/advertising/training media. In order to keep clients happy and the business current I’m always on the lookout for new ways of doing things. New ways that are better, stronger, faster and more efficient than what we’ve done in the past. Efficiency ultimately translates into cost savings and cost savings keep clients happy.

Live streaming content has become a hot topic service in the last few years but despite the passage of time not much has changed changed on the tech-side.

A small portion of the equipment necessary to make a reasonably-decent show work.

We normally achieve live streaming in one of two main ways; but they both start with big heavy cameras, expensive coaxial cables, a big bulky video mixer, some LCD monitors, loads of converters, frame rate and resolution “scalers” and then an output step. The output step involves either a dedicated video streaming device, like the Teradek Vidiu or a laptop running a USB3 capture card and the amazing OBS. Systems that run on 30p (NTSC) frame rates tends to *just work* but we operate in a PAL country (South Africa) and this greatly complicates things as most IT equipment is NTSC native.

Even more equipment.

These setups are unfortunately huge and by extension very expensive (as they require a lot of expensive equipment, space, cabling, setup time, crew, etc).

A client recently started asking about ways in which they could do smaller, “lighter-weight” multi-camera streams for the purposes of internal marketing and staff training. One of this client’s staff members had found an advert for a system, called the “SlingStudio”.

The SlingStudio Hub

Now, “SlingStudio” is a very poorly thought-out name, because the word “Sling” often means a type of support equipment that may not be “safe for work”. My client’s staff member mentioned this device, the SlingStudio that is, and asked if it could work for their purposes. I looked into it and I must admit it seemed too good to be true… and it is, sort of. They’ve taken a leaf out of Blackmagic Design’s book, in that it isn’t a bug-free product and it certainly isn’t plain-sailing to operate.

An NTSC HDMI-equipped camera attached to a SlingStudio CameraLink

The SlingStudio is tiny compared to the setup we normally use. The switcher and video encoder/streaming module are contained in one device the size of a fancy wifi router – and ironically the device is also a wifi router, albeit a very limited one. The system has some notable limitations, that mostly extend out of its core design:

  • All video sources, bar one, are wirelessly streamed to the device over 5GHz 802.11ac wifi using proprietary equipment or a smartphone application (which uses the phone’s camera).
  • The device is 30p only. 60p is available as an option with another set of limitations.

Have lots of batteries ready…

In order to use the machine in practice you need the following :

  • HDMI-equipped cameras all operating on NTSC.
  • For each camera you need a wireless transmitter.
  • If you’re operating for longer than ~1.5 hours you’ll need USB power banks for each of the transmitters.
  • Tripods (optional!).
  • The SlingStudio “hub”.
  • The hub’s battery “base” or a power supply.
  • An iPad.
  • An internet connection.

The SlingStudio’s iPad console operating with three wireless video sources.

The above makes for a very compact setup compared to traditional configurations. In South Africa, almost all of our “ENG”-style cameras operate on PAL (25p/50i) frame rates, which makes them incompatible with most projectors. This means that you need a frame rate converter to connect a normal mixer and camera setup to a projector system – but the SlingStudio is an American product and it only supports NTSC (specifically 30p, 60p* and 60i). As a result of this frame rate selection all venue projectors are happy to deal with the signal the SlingStudio outputs. The SlingStudio can output video to the internet via RTMP or to Youtube and Facebook directly. It can even create events on those platforms using the iPad console interface. In parallel it can also record your output stream (program), your video sources individually, your line-in audio source and output a limited set of streams via HDMI. Really impressive stuff. All this is at an extremely attractive price point that’s a fraction of the cost of a traditional setup. So what’s the catch ?

There are several catches, but it is possible to work around them if you understand them in the context of your brief. Here are some limitations, some of them are South Africa-specific :

  • The SlingStudio is an NTSC/30p/60p/60i product and as such will only work with equipment that supports these framerates. Many cameras in South Africa are locked to PAL frame rates and are therefore incompatible with this system. This is especially true of cheaper “handycam”-type camcorders.
  • The company that makes the SlingStudio (DISH) are hell-bent on preventing the SlingStudio being used by non-US customers; you need an iPad with a US iTunes account to download their control application. US retailers will not ship the SlingStudio to South Africa (or anywhere outside of the US and Canada). Warranty support is, naturally, unavailable.
  • The SlingStudio -only- works with a Macbook or an iPad, no Android folks.
  • The SlingStudio uses 802.11ac wifi on 5GHz to transport camera video streams and as a result you are subject to all of the complexities that come with that, including interference and general frequency congestion (which can be erratic and severe).
  • Full HD video at 30 fps is roughly 1.5 Gbits/second, but the SlingStudio transmits video data over wifi at anywhere between 2mbit/sec and 10 mbit/sec. It manages to do that by heavily compressing the footage and that comes with the price tag of notable latency. This isn’t an issue if you’re only recording and streaming to the web but it is a problem if you’re planning on going out to a projector in the location in which you’re filming. The SlingStudio does have a low-latency mode which sacrifices quality for latency.
  • The system is cutting-edge and as a result sometimes suffers a software glitch here and there. You have to keep your technical wits about you to navigate these issues.

The SlingStudio’s wifi quality checker interface.

In practice the system has been pretty amazing so far. I performed extensive testing (in excess of several days of streaming) before actually using the device on a real shoot. In a real-world environment the system unfortunately has failed once so far, but after some investigation I came to the conclusion that the fault was caused by a ground-loop between an HDMI input and the machine’s line-in audio input (the ground-loop was created by an audio desk’s dodgy power supply). The solution was to put as much of the system on battery as possible and air-gap everything else (we moved the audio onto a wirelessly-connected camera). This resolved further issues. The lesson here is don’t “electrically” trust the voltages of third-party equipment.

So, if you find that your SlingStudio’s wifi occasionally abruptly disappears but the device continues operating normally otherwise, you’re probably experiencing a ground-loop related issue. Galvanically isolate the crap out of everything.

The SlingStudio’s Quad View output

The SlingStudio can send a “quad view” output, program output or HDMI pass-through to the HDMI output. Switching between these modes is seemless, so it’s possible to use it as a rudimentary auxiliary output.

The real SlingStudio treat is in the edit…

For all the SlingStudio’s limitations, issues and reliability concerns the feature that really stands out is the edit – it’s possible to import SlingStudio recorded projects/footage into Adobe Premiere Pro and Apple Final Cut Pro. The resulting timeline includes all of your cuts and transitions. It’s an absolute treat and makes fixing things easy. This is the biggest sell for the SlingStudio for me against other competing solutions.

All-in-all the SlingStudio is an amazing piece of equipment at an almost unbelievable price-point ($1000 without the transmitters and iPad) but it does have very specific limitations and can be finicky. A traditional system is a lot more effort to set up but it is much more reliable and provides lower-latency and better quality feeds.


It appears that the SlingStudio runs Linux; the company publishes open source licences for the system (but not the source) and the licences mention both Linux and SSH, amongst other things. I’ve also noticed that drives formatted in Debian that are unlabelled get assigned “sda” as a drive name on the SlingStudio… which seems familiar. If only someone would open their hub up and take some photos. I’m tempted…


A few months, a few more live streaming jobs and a website update later and the SlingStudio is performing well. After adopting a policy of galvanically isolating the hub (running from batteries, not using the audio input on the hub, not using the HDMI input/output on the hub, etc.) the system has performed admirably and hasn’t crashed/rebooted/failed once, despite being used on several high profile shoots, often with 5 video sources, high bitrates and lots of graphics.