Cloudflare Workers and Backblaze’s S3 API

I use CF Worker to deliver the static copy of my old blogs. Files are stored in Backblaze’ B2. Here is how this works:

import { AwsClient } from 'aws4fetch'

// Those come from Workers secrets

const aws = new AwsClient({
    "accessKeyId": ACCESSKEYID,
    "secretAccessKey": SECRETACCESSKEY

// Hosting static web files on BackBlaze's B2
// Bucket: blog
// Directory inside bucket: static/

const B2BaseUrl = '';

addEventListener('fetch', event => {

async function handleRequest(request) {
  let response;

  if (request.method !== 'GET') {
    response = new Response('Expect only GET requests', { status: 400 })
  } else {
    let b2Url = request.url.split('/').slice(3).join('/');
    if (b2Url == "" || b2Url == "/") {
	    b2Url = "index.html";
    b2Url = B2BaseUrl + b2Url;

    let signedRequest = await aws.sign(b2Url);

    response = await fetch(signedRequest);
    // Make the headers mutable by re-constructing the Response.
    response = new Response(response.body, response);
    response.headers.set('Cache-Control', 'max-age=7200')
  return response;

To set up the 2 secrets (repeat with SECRETACCESSKEY):

❯ wrangler secret put ACCESSKEYID
Enter the secret text you'd like assigned to the variable ACCESSKEYID on the script named blog-static:

I used the native B2 API before, but there’s no way (I found) to not constantly refresh the download key as the max lifetime for such a key was 1 week. The S3 API is much easier as it’s fixed (inside the secrets).

Effect on CPU Temperature by Air Temperature

It’s obvious that a lower room temperature should lower the CPU temperature. But how much does is it? Here’s the answer for a HP t620. Fanless, CPU usage 5-10%. The temperature was measured at 2 different heights: air temperature was measured about 1m above the floor, while the t620 sits about 10cm above the floor.

My Bicycle

Long time ago, around 2007, I bought a bike: Specialized Crossrider XC Sport. Maintenance free except a dab of oil for the gears and chain. I recently replaced the wheel’s tire recently. And the inner tubes have been replaced I think a total of 3 times.

And with “maintenance free” I mean: not maintained.

Last weekend a small plastic piece (bottom bracket cable guide) broke and it rendered the gear mechanism useless. With no tension on that cable anymore, it changed to the 8th gear. I was able to use Velcro to change to 3rd gear, but it’s effectively a single speed bicycle now.

That needs to be fixed.

Turns out that I know next to nothing about this bicycle. Or bicycles in general. Bottom bracket didn’t mean anything to me 3 days ago. And I had no idea that you can have 12 gears now in the back and it’s very smooth to change.

Time for an update!

But first I had to know what I had at my hands. Only now I found the specs of my bicycle (from here):

定価(税込) \71,400
カラー ルートビア
サイズ 49、52、55
フレーム A1プレミアムアルミ
フォーク SPECIALIZED TCR-043D、63mm
リアショック NA
ヘッドセット 1-1/8″ Threadless、フルインテグレート、
ハンドルバー A1アルミ、フラット、600mm幅
ステム 3D 鍛造アルミ、15゜ライズ
グリップ BG Comfort、トリプルデンシティ
ブレーキ Vブレーキ
ブレーキレバー SHIMANO Alivio
フロントディレーラー SHIMANO Nexave、31.8クランプ、ボトムプル
リアディレーラー SHIMANO Deore、ロングケージ
シフター SHIMANO Alivio ラピッドファイアー
フリー SHIMANO HG40、8スピード、11-32T
チェーン SHIMANO HG53(違う?) 114リンク
クランクセット Sugino RD Comp
チェーンリング 48A/38S/28S
ボトムブラッケト SHIMANO UN25、68×113mm
ペダル アロイ
リム Alex DH-19、700c、ダブルウォール
フロントハブ SPECIALIZED、鍛造、32H、QR
リアハブ SHIMANO Paralax、鍛造、32H、QR
スポーク 2.0mm(#14)、ステンレス、真鍮ニップル、293mm(291でも可能だった)
フロントタイヤ 700×38c、アラミドビード
リアタイヤ 700×38c、SPECIALIZED クロスロード
チューブ SPECIALIZED シュレッダーバルブ
サドル BG Indie
シートポスト 鍛造6061 アロイ、27.2φ×350mm
ウェイト 12.7Kg

What I was looking for were the gears for the gear ratio (most popular for me is about 1:1.7) and the bottom bracket bearing type and size as I think I need a replacement. There’s enough rust there to indicate old age.

Update: According to this common single speed gear ratio are:

  • 700c off-road: 1.75:1
  • 700c on road: 2.3:1

Firebase Real Time Updates

Firebase Cloud Firestore has the nice feature of being able to tell you about changes to its data. Here’s how this looks like using Node.js:


A Firebase Cloud Firestore DB, named ‘messages’. Has 2 entries per document: sender and text, both being strings.

The sample Firebase Cloud Firestore DB

Service Account Key

Get your service account secret from

Service account: Generate your private key

Get your private key in JSON format.

Watching the DB

const admin = require('firebase-admin');

const serviceAccount = require('./chat-53a8e-firebase.json');

  credential: admin.credential.cert(serviceAccount),
  databaseURL: ""

const db = admin.firestore();

async function dumpDB() {
  const dbRef = db.collection('messages');
  const doc = await dbRef.get();
  if (doc.exists) {
  } else {
    doc.forEach(doc => {
      console.log(`${} -> ${}, ${}`);

async function watchDB() {
  // const observer = db.collection('messages').where('sender', '==', '')
  // .onSnapshot(querySnapshot => {
  const observer = db.collection('messages')
    .onSnapshot(querySnapshot => {
      querySnapshot.docChanges().forEach(change => {
        if (change.type === 'added') {
          console.log('Added ',;
        if (change.type === 'modified') {
          console.log('Modified ',;
        if (change.type === 'removed') {
          console.log('Removed ',;


When changing entries (via any application incl. the Firebase DB UI), you’ll get entries like

Updates coming in!

Update 2020-07-11: Tested on my Orange Pi Zero (256MB RAM version) with Armbian and Node.js 14.5.0, and not only does it work fine (as expected), it used only about 16MB RAM while running and listening for events from the Firebase Cloud Firestore. For comparison: Linux itself uses about 100MB.

vmware Horizon Client on Ubuntu with Firefox

Sometimes things “just” work on Linux, and sometimes it’s a bit more fiddling. It’s the latter when running vmware Horizon client with Firefox. But as so often, there’s a fix here.

Copy&pasted the answer here:

  1. Download the client from the VMWare Horizon Client for 64-bit Linux
  2. In Firefox, open about:config and click through the warning.
  3. Add a new boolean entry called network.protocol-handler.expose.vmware-view and set the value to false
  4. Create a file called ‘test.html’ somewhere on your computer and put the following in it:
    <html><a href=’vmware-view://’>test</a></html>
  5. Open the file in Firefox and click on the link, which should prompt you for a path to open the link.
  6. Select /usr/bin/vmware-view and it should work for future uses!

Crosh and Web Fonts

Crosh, the Crostini shell, uses CSS to render the terminal. Gives you nice capabilities, but it’s also not compatible how normal Linux is configured.

Zsh and in particular the PowerLevel10k theme uses Unicode characters quite a bit.

So step 1 is using a font which works:

  1. Open the crosh terminal
  2. Control-Shift-P
  3. In the Text Font Family field, enter:
    “DejaVu Sans Mono”, monospace
  4. In the Custom CSS URI field, enter:

Instead of DejaVu Sans Mono, use another one in the list from the CSS file. Like Hack or Source Code Pro.

Fixing a Nintendo Pro Controller – Part 2

While I ordered a replacement joystick potentiometer slider (see my post from last week), I thought that you could also simply move one slider from a less used joystick axis to the one used most (left joystick, up-down direction). Much less used is the right joystick up-down). So I open the joystick again, bent off the housing of the those and swapped the up-down potentiometer sliders of the 2 joysticks. And while it was a bit fiddly with moderate amount of force needed to open and close those plastic housings of the slider, it worked fine and it completely fixed the intermittent failures to move forward via the left joystick!

Without re-calibration there was a tiny drift up (sometimes I walked very slowly forward). After re-calibration it’s rock-solid and works perfectly.

Reminded me of Tire Rotation in a car. In 2020 you rotate potentiometer sliders instead.

ESP8266’s smaller brother: ESP8285

ESP8285 on Wemos D1 Mini Lite

I forgot I bought one of those a while ago! To flash Espruino software on it: --port /dev/ttyUSB1 --baud 115200 write_flash \
  --flash_freq 80m --flash_mode dout --flash_size 1MB --verify \
  0x0000 "boot_v1.6.bin" 0x1000 espruino_esp8266_user1.bin \
  0xFC000 esp_init_data_default.bin 0xFE000 blank.bin

Files from Source: although that speaks of 40MHz. I have not seen any issues with 80MHz.

Needless to say, it works fine:

ESP8285 with WS2812B LED (via D2)
Create your website at
Get started