newspaint

Documenting Problems That Were Difficult To Find The Answer To

Using Perl to Make Signed Requests to Public Transport Victoria Timetable API

So you want to create an application to access the Public Transport Victoria (PTV) Timetable API.

You’ve followed the instructions and e-mailed a request for a developer ID and an access key; and you’ve received both in an e-mail that contained text similar to the following:

Thank you for your interest in the PTV Timetable API.

Your email address has now been registered and your user Id and API key are
below.

User Id: 2912345

API Key: 4cc12345-ff11-2222-a00a-dd1297cd04aa

Now you want to create a signed request using Perl to access the API.

The following function will take a URL and return a signed URL that can be used to access that URL:

#!/usr/bin/perl -w

use Digest::HMAC;
use Digest::SHA;

use strict;

my $devid = "2912345";
my $apikey = "4cc12345-ff11-2222-a00a-dd1297cd04aa";

sub sign_url {
  my ( $url ) = @_;

  # add ?devid=$devid or &devid=$devid to URL
  $url .= ( index($url, "?") < $[ ) ? "?" : "&";
  $url .= "devid=$devid";

  # strip out base URL from part used in signing
  my $request = $url;
  $request =~ s{^(([a-z]+)://+)?[^/]+}{};

  # calculate signature using API key and URL without base
  #   e.g. sign over a string like "/v3/routes?devid=2912345"
  my $signature = Digest::HMAC::hmac_hex(
      $request,
      $apikey,
      \&Digest::SHA::sha1
  );

  $url .= "&signature=" . $signature;
  return $url;
}

print sign_url( "http://timetableapi.ptv.vic.gov.au/v3/routes" );

This should output the following:

$ perl -w signtest.pl
http://timetableapi.ptv.vic.gov.au/v3/routes?devid=2912345&signature=b7ee928f05499a0016746daef5013dba35224d8e

The example is using an invalid signature and devid, so this example URL will not actually return a page; you will have to provide the access key and devid you received in your e-mail.

Note: it is absolutely essential that you do not change the capitalisation of the access key in this script. While it looks like a hex string it is actually treated as case-sensitive text.

Bash Script to Run Apt-Get Upgrades on All LXC Running Containers

If you have several LXC containers on your system that you want to upgrade in a loop you could use a sensible infrastructure management platform like Ansible.

Here, however, is a simple BASH script for logging into each running LXC host one at a time and letting you answer yes or no to the apt-get upgrade taking place:

#!/bin/bash

# declare an array variable
declare -a LINES

# store each line about running LXC containers into array
LINENUM=0
while IFS= read -r line; do
  echo "  processing LINENUM=$LINENUM, $line"
  LINES[$LINENUM]="$line"
  LINENUM=$((LINENUM + 1))
done <<< "$(sudo lxc-ls -f)"

# iterate through each line in the array
INDEX=0
while [[ $INDEX -lt $LINENUM ]]; do
  # squash up the spaces and delete commas from line
  CLEANLINE=`echo "${LINES[$INDEX]}" |tr -s ' ' |tr -d ,`

  # extract the hostname and ipaddress fields
  HNAME=`echo "$CLEANLINE" |cut '-d ' -f1`
  IPADDR=`echo "$CLEANLINE" |cut '-d ' -f5`

  # ssh into host if a valid IP address is present
  if [ `echo "$IPADDR" |grep -E '^([0-9]+[.]){3}([0-9]+)$'` ]; then
    echo "== $HNAME ($IPADDR) =="
    ssh -t ubuntu@$IPADDR 'echo "== $(hostname) =="; sudo apt-get update; echo "== $(hostname) =="; sudo apt-get upgrade;'
  else
    :
  fi

  INDEX=$((INDEX + 1))
done

This script makes use of BASH arrays. In addition it was discovered that attempting to change variables inside a read loop that was piped was fruitless because the pipe was run inside its own shell and thus the variable changes were lost.

Rust/Cargo Outputting Dollar Angle Bracket Symbols

So you’re compiling source using Cargo/Rust and you see output similar to the following:

error[E0046]$<2>: not all trait items implemented, missing: `decode`, `encode`$<2>
  $<2>--> $<2>src/main.rs:7:1$<2>
   $<2>|$<2>
7$<2>  $<2>| $<2>impl tokio_core::io::Codec for LineCodec {$<2>
   $<2>| $<2>^$<2> missing `decode`, `encode` in implementation$<2>

error$: aborting due to previous error$

This is full of dollar, angle bracket, number, angle bracket characters.

The fix is to change your terminal, e.g.:

TERM=xterm

On doing this I had the output in full colour without the mysterious symbols.

Conditionally adding a directory to PATH if not already in PATH

In BASH it is possible to check that a directory is not already in the PATH environment variable before adding it.

The basic string-in-string search function was adopted from this forum post.

stringContains() { [ -z "${1##*$2*}" ]; }
stringBegins()   { [ -z "${1##$2*}"  ]; }
stringEnds()     { [ -z "${1##*$2}"  ]; }

# call as inPath "$PATH" "/my/new/path"
inPath() {
  if stringBegins   "$1" "$2:";  then return 0; fi
  if stringEnds     "$1" ":$2";  then return 0; fi
  if stringContains "$1" ":$2:"; then return 0; fi
  if [ "$1" == "$2" ];           then return 0; fi
  return 1;
}

If you wanted to, say, add “/home/myuser/bin” if it didn’t already exist, you could add the above functions and the following:

if inPath "$PATH" "/home/myuser/bin"; then
  : # do nothing
else
  PATH="$PATH:/home/myuser/bin"
fi

Setting the Time on the Clock for the Blanco BSO422W Oven

Press and hold the 2nd button from the left.

Press and hold the 2nd button from the left

Press and hold the 2nd button from the left

Continue holding the 2nd button down.

Press and hold the 3rd button from the left.

Press and hold the 3rd button from the left while the 2nd button is still held down

Press and hold the 3rd button from the left while the 2nd button is still held down

Continue holding the 2nd and 3rd buttons from the left down.

Twist the knob left and right to set the time you want.

Twist the knob to set the time while holding the 2nd and 3rd buttons from the left

Twist the knob to set the time while holding the 2nd and 3rd buttons from the left

Now you can release the two buttons you’ve been holding down.

Hyundai Sonata Won’t Start In Drive, Locks Up

I blew my (mental) gasket today in a tense situation in peak hour traffic when I stopped my car (intentionally) but couldn’t get it to start again.

When you turn the engine off while in Drive (D) you can’t actually turn the keys all the way to the “lock” position to remove them. In this situation:

  • the transmission is in D (drive) and can only be moved into N (neutral)
  • you cannot move the transmission into P (park) even with the foot brake applied
  • the keys cannot be removed from the ignition
  • the keys can be twisted into the “start” position but the car won’t start while the transmission is in D (drive)
  • the car will only start again with the transmission in N (neutral)

It is only when the car is running, and the foot is on the brake, that you can put the car in P (park) and switch the car completely off removing the keys.

Believe me, this is so frustrating.

I don’t know if my car has a fault, or if Hyundai want to just put unsuspecting drivers in impossible situations in heavy traffic.

Windows 10 TCP/Internet Slow With Chrome and OpenWRT Router

So I was having issues getting a Windows 10 laptop running Google Chrome connected via wifi to a router running OpenWRT Chaos Calmer 15.05.1.

The Windows 10 laptop would take a long time to establish a connection and then a long time for any data to transfer at an incredibly slow rate.

At first I thought it was Google Chrome but downloaded Firefox and was still having the same issues.

There are many proposed solutions but the commands that appeared to make a magical difference and instantly speed things up were:

netsh interface tcp show global
netsh interface tcp set global autotuning=disabled

At this stage things did not magically get better.

Then I tried:

netsh interface tcp show heuristics
netsh interface tcp set heuristics enabled

Now the Internet suddenly got quicker.

To undo these changes (if they don’t work for you):

netsh interface tcp set global autotuning=normal
netsh interface tcp set heuristics disabled

Also, because I messed around with the MTU on the WiFi interface I had to run the following to restore things to a relatively normal default:

netsh interface ipv4 set subinterface “WiFi” mtu=1458 store=persistent

Adding Huawei E160E To OpenWRT

I wanted to add a Huawei E160E USB 3G modem to OpenWRT but had some trouble getting it to work.

I used documentation from three places:

In this case I used a latest snapshot from the LEDE project. It turns out the router would simply lose networking, I’d be unable to SSH or access it via the web, after several minutes. Perhaps this was because I was forcing kmod’s with a slightly incompatible kernel. In the end I went back to Chaos Calmer 15.05.1 from OpenWRT which seemed to be more stable for me.

It turned out that I needed to add some more packages, specifically:

  • usbutils – to run “lsusb” to see when my USB devices had been detected
  • kmod-usb-uhci – ultimately I needed a kmod to see the USB controller in order to detect attached devices
  • kmod-usb2 – just in case the UHCI controller module above didn’t work

Note that when adding kmods then opkg might reject it with a LEDE build if package slightly out of sync with the kernel build, in which case use –force-depends (don’t do this, it might result in an unstable router):

opkg install --force-depends kmod-usb-uhci

Now, also ensure that the /etc/modules.d/usb-serial has the following line:

usbserial vendor=0x12d1 product=0x140c maxSize=4096

The vendor and product values are taken from the output of lsusb:

# lsusb
Bus 001 Device 002: ID 12d1:140c Huawei Technologies Co., Ltd. E180v

Once connected the signal strength can be obtained on the command line by running:

# comgt -d /dev/ttyUSB3
SIM ready
Waiting for Registration..(120 sec max)
Registered on Home network: "50502",2
Signal Quality: 13,99

The result can be looked up in the table at this link:

Value RSSI dBm Condition
2 -109 Marginal
3 -107 Marginal
4 -105 Marginal
5 -103 Marginal
6 -101 Marginal
7 -99 Marginal
8 -97 Marginal
9 -95 Marginal
10-93OK
11-91OK
12-89OK
13-87OK
14-85OK
15 -83 Good
16 -81 Good
17 -79 Good
18 -77 Good
19 -75 Good
20 -73 Excellent
21 -71 Excellent
22 -69 Excellent
23 -67 Excellent
24 -65 Excellent
25 -63 Excellent
26 -61 Excellent
27 -59 Excellent
28 -57 Excellent
29 -55 Excellent
30 -53 Excellent

How Do I Add A Medicare Service To MyGov With A Linking Code?

So you’ve logged into your MyGov website and you’re attempting to add a Medicare service using a linking code that Medicare has provided you.

You’re confronted with a webpage like this:

  Enter your linking code:

  Select one of the online services you want to link:

  Enter your agency reference number for this online service (no spaces):

Your linking code is straightforward. It is what you were provided with (e.g. G12345678).

The online service you want to link is “Medicare”.

The agency reference number, however, is tricky. It is your 10 digit Medicare card number and your individual reference number without a gap. But what does this mean?

Your Medicare card number is the 10 digits along the top of the card. The individual reference number is the single digit next to your name underneath.

Use the 10 digits from the top plus the single digit next to your name

Use the 10 digits from the top plus the single digit next to your name

So the filled out form will look something like (for this example card):

Entering linking information for MyGov and Medicare

Entering linking information for MyGov and Medicare

Good luck! And if you have a problem you’ll have to call Medicare (not MyGov) on 132011, it took my 19 minutes to get through to an operator.

Turning Off DHCP Server on Netgear Wireless Cable Gateway CGD24N

The Netgear Wireless Cable Gateway model CGD24N supplied by Bigpond in Australia can spend a second life as a simple Ethernet switch. However it assigns DHCP addresses out of the box which can really upset a home network if you’re not expecting it.

Your wireless router might be assigning addresses from one range but you keep finding guest devices assigned something from the 192.168.100.0/24 range.

It’s not that straightforward to find the DHCP on/off switch. The steps to find it are thus:

1. Log in to gateway admin interface, select NAT from menu

Select NAT from menu on left-hand side

Select NAT from menu on left-hand side

2. Turn NAT on, click apply

Select NAT on checkbox, click apply

Select NAT on checkbox, click apply

3. Select LAN IP from left hand menu

Select LAN IP from left hand menu

Select LAN IP from left hand menu

4. Select DHCP no radio button, click apply

Select DHCP no radio button, click apply

Select DHCP no radio button, click apply