Integrate Obsidian with the site and track its settings
9
content/.obsidian/app.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"spellcheck": true,
|
||||
"autoPairBrackets": false,
|
||||
"autoPairMarkdown": false,
|
||||
"vimMode": true,
|
||||
"useMarkdownLinks": false,
|
||||
"attachmentFolderPath": "media",
|
||||
"alwaysUpdateLinks": true
|
||||
}
|
4
content/.obsidian/appearance.json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"theme": "moonstone",
|
||||
"baseFontSize": 16
|
||||
}
|
16
content/.obsidian/core-plugins.json
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
[
|
||||
"file-explorer",
|
||||
"global-search",
|
||||
"switcher",
|
||||
"graph",
|
||||
"backlink",
|
||||
"page-preview",
|
||||
"note-composer",
|
||||
"command-palette",
|
||||
"editor-status",
|
||||
"markdown-importer",
|
||||
"outline",
|
||||
"word-count",
|
||||
"open-with-default-app",
|
||||
"file-recovery"
|
||||
]
|
1
content/.obsidian/hotkeys.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
112
content/.obsidian/workspace
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"main": {
|
||||
"id": "69e9da393623ab60",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "642564a28e60933d",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "Protospace.md",
|
||||
"mode": "source"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"direction": "vertical"
|
||||
},
|
||||
"left": {
|
||||
"id": "3885f82c1ab72e1b",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "0e37795504669957",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "e5f5df16367f5f9a",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "file-explorer",
|
||||
"state": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "15b64333baa0fbc2",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300
|
||||
},
|
||||
"right": {
|
||||
"id": "260bba8f76f307a9",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "21c556d6660f839b",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "528c8f9657044ea2",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "Protospace.md",
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
"showSearch": false,
|
||||
"searchQuery": "",
|
||||
"backlinkCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "79f3ff4100fe3ae6",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "Protospace.md"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"currentTab": 1
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300
|
||||
},
|
||||
"active": "642564a28e60933d",
|
||||
"lastOpenFiles": [
|
||||
"Protospace.md",
|
||||
"Plant Waterer.md",
|
||||
"media/protospace2.png",
|
||||
"media/protospace1.png",
|
||||
"Solar Car.md",
|
||||
"Acousting Panels.md",
|
||||
"Backup Strategy.md",
|
||||
"Bypassing Ports.md",
|
||||
"Garage Door Opener.md",
|
||||
"Painting.md"
|
||||
]
|
||||
}
|
25
content/Acousting Panels.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
Title: Theatre Acoustic Panels
|
||||
Date: 2021-10-21
|
||||
Category: Creations
|
||||
Summary: Panels for acoustic treatment in my home theatre.
|
||||
Short: 3
|
||||
|
||||
Acoustic treatment is one of the most overlooked aspects of home audio. There's no point in spending money on premium speakers if the room they are playing in has poor acoustics.
|
||||
|
||||
The primary purpose of acoustic panels is to reduce the reverberations caused by sound reflecting off the smooth walls of the theatre. The path of the reflected sound is a longer distance to your ear compared to the sound coming directly from the speaker. This causes the reflected sound to be delayed by the time it reaches your ear. The delayed signal interferes with itself, causing comb filtering which distorts the signal.
|
||||
|
||||
Acoustic panels are placed geometrically where the sound from the speakers would reflect off the wall to reach the listener's ears. The insulation inside the panels absorbs energy from the soundwave which reduces its volume and interference.
|
||||
|
||||
![[ panel1.jpg | twelve L-shaped corners of the panels stacked together leaning on a table saw in a wood shop]]
|
||||
|
||||
I made six frames in the wood shop of my local makerspace, Protospace. After cutting the 1x4" pine boards to length, I made a jig so I could quickly join them together with screws.
|
||||
|
||||
![[ panel2.jpg | a panel with insulation inside on the ground about to be wrapped with black fabric]]
|
||||
|
||||
I added 4" batts of Rockwool insulation into each frame after it was assembled. I then wrapped the frame with black speaker fabric and stabled it in place while trying to pull it taut.
|
||||
|
||||
I sat in my theatre while a friend slid a handheld mirror along the wall until I could see the middle of the speaker in its reflection. This told me the centre point of where to mount each panel because the reflected sound would take the same path to my ear.
|
||||
|
||||
<span class="aside">Four in the front, two in the back</span>
|
||||
|
||||
![[panel3.jpg | four black acoustic panels mounted on the walls in my home theatre]]
|
|
@ -7,49 +7,33 @@ Short: 1
|
|||
|
||||
[TOC]
|
||||
|
||||
Regularly backing up all the data I care about is very important to me. This
|
||||
article outlines my strategy to make sure I never lose essential data.
|
||||
Regularly backing up all the data I care about is very important to me. This article outlines my strategy to make sure I never lose essential data.
|
||||
|
||||
## Motivation
|
||||
|
||||
Backups should be as automatic as possible. This ensures laziness and
|
||||
forgetfulness won't interfere with the regularity.
|
||||
Backups should be as automatic as possible. This ensures laziness and forgetfulness won't interfere with the regularity.
|
||||
|
||||
All software used to create and store the backups should be free and open source
|
||||
so I'm not depending on the survival of a company.
|
||||
All software used to create and store the backups should be free and open source so I'm not depending on the survival of a company.
|
||||
|
||||
Backups need to be tested to ensure they are correct and happening regularly.
|
||||
Multiple copies of the backups should exist, including at least one offsite to
|
||||
protect against my building burning down.
|
||||
Backups need to be tested to ensure they are correct and happening regularly. Multiple copies of the backups should exist, including at least one offsite to protect against my building burning down.
|
||||
|
||||
Backups should also be incremental when possible (rather than mirror copies) so
|
||||
an accidental deletion isn't propagated into the backups, making the file
|
||||
irrecoverable.
|
||||
Backups should also be incremental when possible (rather than mirror copies) so an accidental deletion isn't propagated into the backups, making the file irrecoverable.
|
||||
|
||||
## Strategy
|
||||
|
||||
I have one backup folder `/mnt/backup` on my media server at home that serves as
|
||||
the destination for all my backup sources. All scheduled automatic backups write
|
||||
to their own subfolder inside of it.
|
||||
I have one backup folder `/mnt/backup` on my media server at home that serves as the destination for all my backup sources. All scheduled automatic backups write to their own subfolder inside of it.
|
||||
|
||||
This backup folder is then synced to encrypted 2.5" 1 TB hard drives which I
|
||||
rotate between my bag, offsite, and my parents' house.
|
||||
This backup folder is then synced to encrypted 2.5" 1 TB hard drives which I rotate between my bag, offsite, and my parents' house.
|
||||
|
||||
## Backup Sources
|
||||
|
||||
I use the tool `rdiff-backup` extensively because it allows me to take
|
||||
incremental backups locally or over SSH. It acts very similar to `rsync` and has
|
||||
no configuration.
|
||||
I use the tool `rdiff-backup` extensively because it allows me to take incremental backups locally or over SSH. It acts very similar to `rsync` and has no configuration.
|
||||
|
||||
### Email
|
||||
|
||||
I have every email since 2010 backed up continuously in case my email provider
|
||||
disappears.
|
||||
I have every email since 2010 backed up continuously in case my email provider disappears.
|
||||
|
||||
I use `offlineimap` to sync my mail to the directory `~/email` on my media
|
||||
server as a Maildir. Since offlineimap is only a syncing tool, the emails need
|
||||
to be copied elsewhere to be backed up. I run `rdiff-backup` from a weekly cron
|
||||
job:
|
||||
I use `offlineimap` to sync my mail to the directory `~/email` on my media server as a Maildir. Since offlineimap is only a syncing tool, the emails need to be copied elsewhere to be backed up. I run `rdiff-backup` from a weekly cron job:
|
||||
|
||||
<span class="aside">I'll explain what backup_check.txt does below</span>
|
||||
|
||||
|
@ -84,8 +68,7 @@ sslcacertfile = /etc/ssl/certs/ca-certificates.crt
|
|||
|
||||
### Notes
|
||||
|
||||
I use Standard Notes to take notes and wrote the tool [standardnotes-fs](https://github.com/tannercollin/standardnotes-fs)
|
||||
to mount my notes as a file system to view and edit them as plain text files.
|
||||
I use Standard Notes to take notes and wrote the tool [standardnotes-fs](https://github.com/tannercollin/standardnotes-fs) to mount my notes as a file system to view and edit them as plain text files.
|
||||
|
||||
I take weekly backups of the mounted file system on my media server with cron:
|
||||
|
||||
|
@ -96,9 +79,7 @@ I take weekly backups of the mounted file system on my media server with cron:
|
|||
|
||||
### Nextcloud
|
||||
|
||||
I self-host a Nextcloud instance to store all my personal documents (non-code
|
||||
projects, tax forms, spreadsheets, etc.). Since it's only a syncing software,
|
||||
the files need to be copied elsewhere to be backed up.
|
||||
I self-host a Nextcloud instance to store all my personal documents (non-code projects, tax forms, spreadsheets, etc.). Since it's only a syncing software, the files need to be copied elsewhere to be backed up.
|
||||
|
||||
I take weekly backups of the Nextcloud data folder with cron:
|
||||
|
||||
|
@ -109,9 +90,7 @@ I take weekly backups of the Nextcloud data folder with cron:
|
|||
|
||||
### Gitea
|
||||
|
||||
I self-host a Gitea instance to store all my git repositories for code-based
|
||||
projects. My home folder is also a git repo so I can easily sync my config files
|
||||
and password database between servers and machines.
|
||||
I self-host a Gitea instance to store all my git repositories for code-based projects. My home folder is also a git repo so I can easily sync my config files and password database between servers and machines.
|
||||
|
||||
I take weekly backups of the Gitea data folder with cron:
|
||||
|
||||
|
@ -123,30 +102,23 @@ I take weekly backups of the Gitea data folder with cron:
|
|||
|
||||
### Telegram
|
||||
|
||||
Telegram Messenger is my main app for communication. My parents, most of my
|
||||
friends, and friend groups are on there so I don't want to lose those messages
|
||||
in case Telegram disappears or my account gets banned.
|
||||
Telegram Messenger is my main app for communication. My parents, most of my friends, and friend groups are on there so I don't want to lose those messages in case Telegram disappears or my account gets banned.
|
||||
|
||||
<span class="aside">Saves the messages to a sqlite db</span>
|
||||
|
||||
Telegram includes a data export feature, but it can't be automated. Instead I
|
||||
run the deprecated software [telegram-export](https://github.com/expectocode/telegram-export) hourly with cron:
|
||||
Telegram includes a data export feature, but it can't be automated. Instead I run the deprecated software [telegram-export](https://github.com/expectocode/telegram-export) hourly with cron:
|
||||
|
||||
```
|
||||
0 * * * * bash -c 'timeout 50m /home/tanner/opt/telegram-export/env/bin/python -m telegram_export' > /var/log/telegramexport.log 2>&1
|
||||
```
|
||||
|
||||
It likes to hang, so `timeout` kills it if it's still running after 50 minutes.
|
||||
Hasn't corrupted the database yet.
|
||||
It likes to hang, so `timeout` kills it if it's still running after 50 minutes. Hasn't corrupted the database yet.
|
||||
|
||||
### Phone
|
||||
|
||||
[Signal Messenger](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms&hl=en_CA&gl=US) automatically exports a copy of my text messages database, and
|
||||
[Aegis](https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis&hl=en_CA&gl=US) allows me to export an encrypted JSON file of my two-factor authentication
|
||||
codes.
|
||||
[Signal Messenger](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms&hl=en_CA&gl=US) automatically exports a copy of my text messages database, and [Aegis](https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis&hl=en_CA&gl=US) allows me to export an encrypted JSON file of my two-factor authentication codes.
|
||||
|
||||
I mount my phone's internal storage as a file system on my desktop using
|
||||
[adbfs-rootless](https://github.com/spion/adbfs-rootless). I then rsync the files over to my media server:
|
||||
I mount my phone's internal storage as a file system on my desktop using [adbfs-rootless](https://github.com/spion/adbfs-rootless). I then rsync the files over to my media server:
|
||||
|
||||
```
|
||||
$ ./adbfs ~/mntphone
|
||||
|
@ -160,22 +132,17 @@ $ time rsync -Wav \
|
|||
localmediaserver:/mnt/backup/files/phone/
|
||||
```
|
||||
|
||||
Unfortunately this is a manual process because I need to plug my phone in each
|
||||
time. Ideally it would happen automatically while I'm asleep and the phone is
|
||||
charging.
|
||||
Unfortunately this is a manual process because I need to plug my phone in each time. Ideally it would happen automatically while I'm asleep and the phone is charging.
|
||||
|
||||
### Miscellaneous Files
|
||||
|
||||
The directory `/backup/files` is a repository for any kind of files I want to
|
||||
keep forever. My phone data, old archives, computer files, Minecraft worlds,
|
||||
files from previous jobs, and so on.
|
||||
The directory `/backup/files` is a repository for any kind of files I want to keep forever. My phone data, old archives, computer files, Minecraft worlds, files from previous jobs, and so on.
|
||||
|
||||
All the files will be included in the 1 TB hard drive backup rotations.
|
||||
|
||||
### Web Services
|
||||
|
||||
Web services that I run like [txt.t0.vc](https://txt.t0.vc) and [QotNews](https://news.t0.vc) are backed up daily, weekly,
|
||||
and monthly depending on how frequently the data changes.
|
||||
Web services that I run like [txt.t0.vc](https://txt.t0.vc) and [QotNews](https://news.t0.vc) are backed up daily, weekly, and monthly depending on how frequently the data changes.
|
||||
|
||||
I run `rdiff-backup` on the remote server with cron:
|
||||
|
||||
|
@ -192,9 +159,7 @@ I run `rdiff-backup` on the remote server with cron:
|
|||
55 14 1 * * rdiff-backup --remove-older-than 12B --force tbotbak@remotebackup::/mnt/backup/remote/tbotbak/monthly/t0txt/
|
||||
```
|
||||
|
||||
The `tbotbak` user has write access to the `/mnt/backup/remote/tbotbak`
|
||||
directory only. It has its own passwordless SSH key that's only permitted to run
|
||||
the `rdiff-backup --server` command for security.
|
||||
The `tbotbak` user has write access to the `/mnt/backup/remote/tbotbak` directory only. It has its own passwordless SSH key that's only permitted to run the `rdiff-backup --server` command for security.
|
||||
|
||||
### Protospace
|
||||
|
||||
|
@ -258,8 +223,7 @@ My backup folder `/mnt/backup` now looks like this:
|
|||
└── telebak
|
||||
```
|
||||
|
||||
This directory tree is the master backup and I make a copy of the entire tree
|
||||
every Saturday to a hard drive.
|
||||
This directory tree is the master backup and I make a copy of the entire tree every Saturday to a hard drive.
|
||||
|
||||
The directory is copied over with the following script:
|
||||
|
||||
|
@ -279,29 +243,17 @@ umount /mnt/external
|
|||
cryptsetup luksClose external
|
||||
```
|
||||
|
||||
I wrote a Python script `checkbackup.py` that goes through each backup and
|
||||
compares the timestamp in `backup_check.txt` files to the current time. This
|
||||
makes sure that the cron ran, backups were taken, and transferred over
|
||||
correctly.
|
||||
I wrote a Python script `checkbackup.py` that goes through each backup and compares the timestamp in `backup_check.txt` files to the current time. This makes sure that the cron ran, backups were taken, and transferred over correctly.
|
||||
|
||||
## Rotating Hard Drives
|
||||
|
||||
I rotate through 2.5" 1 TB hard drives each Saturday when I do a backup. They
|
||||
are quite cheap at [$65 CAD](https://www.memoryexpress.com/Products/MX65194) each so I can have a bunch floating around.
|
||||
I rotate through 2.5" 1 TB hard drives each Saturday when I do a backup. They are quite cheap at [$65 CAD](https://www.memoryexpress.com/Products/MX65194) each so I can have a bunch floating around.
|
||||
|
||||
I keep one connected to the server, one in my bag, one offsite, one at my
|
||||
mother's house, and one at my dad's house. Every Saturday I run the script above
|
||||
to take a copy and then swap the drive with the one in my bag. It then gets <span class="aside">I go back home about twice per year</span>
|
||||
swapped when I visit my offsite location. Same for when I visit my parents. This
|
||||
means that all hard drives eventually get rotated through with new data and
|
||||
don't sit too long unpowered.
|
||||
I keep one connected to the server, one in my bag, one offsite, one at my mother's house, and one at my dad's house. Every Saturday I run the script above to take a copy and then swap the drive with the one in my bag. It then gets <span class="aside">I go back home about twice per year</span> swapped when I visit my offsite location. Same for when I visit my parents. This means that all hard drives eventually get rotated through with new data and don't sit too long unpowered.
|
||||
|
||||
The drives are all encrypted with full-disk LUKS encryption using a password I'm
|
||||
unlikely to forget.
|
||||
The drives are all encrypted with full-disk LUKS encryption using a password I'm unlikely to forget.
|
||||
|
||||
I run the check-summing `btrfs` file system on them in RAID-1 to protect against
|
||||
bitrot. This means I can only use 0.5 TB of storage for my backups, but the data
|
||||
is stored redundantly.
|
||||
I run the check-summing `btrfs` file system on them in RAID-1 to protect against bitrot. This means I can only use 0.5 TB of storage for my backups, but the data is stored redundantly.
|
||||
|
||||
Here's how I set up new hard drives to do this:
|
||||
|
||||
|
@ -317,12 +269,8 @@ $ sudo cryptsetup luksClose external
|
|||
|
||||
## Future Improvements
|
||||
|
||||
I'm working on a system to automatically back up all my home directories to my
|
||||
media server. I need this to grab Bash histories and code that's
|
||||
work-in-progress. I've been burned by not having this once when a server died.
|
||||
I'm working on a system to automatically back up all my home directories to my media server. I need this to grab Bash histories and code that's work-in-progress. I've been burned by not having this once when a server died.
|
||||
|
||||
I'd like to automate backing up my phone by connecting it to a Raspberry Pi when
|
||||
I go to sleep.
|
||||
I'd like to automate backing up my phone by connecting it to a Raspberry Pi when I go to sleep.
|
||||
|
||||
I need to get better at fully testing my backups by restoring them on a blank
|
||||
machine.
|
||||
I need to get better at fully testing my backups by restoring them on a blank machine.
|
|
@ -7,29 +7,21 @@ Short: 2
|
|||
|
||||
[TOC]
|
||||
|
||||
My residential ISP blocks inbound traffic to common ports like 22, 80, and 443.
|
||||
I use an OpenVPN tunnel to forward these ports so that I can self-host a
|
||||
public media server. It does __not__ require users to be on the VPN.
|
||||
My residential ISP blocks inbound traffic to common ports like 22, 80, and 443. I use an OpenVPN tunnel to forward these ports so that I can self-host a public media server. It does __not__ require users to be on the VPN.
|
||||
|
||||
This article explains how I set it up and is targeted towards Linux sysadmins.
|
||||
|
||||
## Overview
|
||||
|
||||
I have a cheap $5 per month virtual server with [Digital Ocean](https://digitalocean.com) that runs
|
||||
Debian GNU/Linux 10. An OpenVPN server is running on this virtual server.
|
||||
I have a cheap $5 per month virtual server with [Digital Ocean](https://digitalocean.com) that runs Debian GNU/Linux 10. An OpenVPN server is running on this virtual server.
|
||||
|
||||
My media server at home has an OpenVPN client connected to the server and is
|
||||
assigned a static IP on the VPN network.
|
||||
My media server at home has an OpenVPN client connected to the server and is assigned a static IP on the VPN network.
|
||||
|
||||
The virtual server has routing enabled and forwards inbound traffic __from the
|
||||
internet__ to my media server at home. This allows me to have external HTTP and
|
||||
SSH access.
|
||||
The virtual server has routing enabled and forwards inbound traffic __from the internet__ to my media server at home. This allows me to have external HTTP and SSH access.
|
||||
|
||||
## Server Setup
|
||||
|
||||
Spin up a Debian 10 virtual server on your favourite hosting provider and set
|
||||
your user up as you would normally. You should probably harden this server.
|
||||
Assign a subdomain to it like `vpn.example.com`.
|
||||
Spin up a Debian 10 virtual server on your favourite hosting provider and set your user up as you would normally. You should probably harden this server. Assign a subdomain to it like `vpn.example.com`.
|
||||
|
||||
Install the following requirements:
|
||||
|
||||
|
@ -62,8 +54,7 @@ $ head /dev/urandom > pki/.rnd
|
|||
$ ./easyrsa build-ca
|
||||
```
|
||||
|
||||
Enter a password you won't forget in case you want to add another client later.
|
||||
The Common Name you choose is not important.
|
||||
Enter a password you won't forget in case you want to add another client later. The Common Name you choose is not important.
|
||||
|
||||
Generate Diffie–Hellman params:
|
||||
|
||||
|
@ -83,19 +74,15 @@ Generate a client cert:
|
|||
$ ./easyrsa build-client-full mediaserver nopass
|
||||
```
|
||||
|
||||
We make a `mediaserver` client because we want to assign a static IP to it. You
|
||||
need to make a different one for each client you want with a static IP.
|
||||
We make a `mediaserver` client because we want to assign a static IP to it. You need to make a different one for each client you want with a static IP.
|
||||
|
||||
Also, if you want generic clients that all get dynamic IPs for use on your
|
||||
laptop, phone, etc. to protect you from public WiFi (like a normal VPN), create
|
||||
only a single extra one:
|
||||
Also, if you want generic clients that all get dynamic IPs for use on your laptop, phone, etc. to protect you from public WiFi (like a normal VPN), create only a single extra one:
|
||||
|
||||
```
|
||||
$ ./easyrsa build-client-full client nopass # optional
|
||||
```
|
||||
|
||||
Leave off `nopass` if you want to password protect the config file keys when you
|
||||
set up a new client.
|
||||
Leave off `nopass` if you want to password protect the config file keys when you set up a new client.
|
||||
|
||||
Create the server config file `/etc/openvpn/server.conf`:
|
||||
|
||||
|
@ -135,8 +122,7 @@ $ sudo mkdir ccd
|
|||
$ sudo touch ccd/mediaserver
|
||||
```
|
||||
|
||||
Replace `mediaserver` with whatever client name you used above. Edit it like
|
||||
so:
|
||||
Replace `mediaserver` with whatever client name you used above. Edit it like so:
|
||||
|
||||
<span class="aside">Your home server will be `10.8.0.100`</span>
|
||||
|
||||
|
@ -182,8 +168,7 @@ $ ip addr
|
|||
|
||||
### Port Forwarding
|
||||
|
||||
I use `ufw` to handle the iptables rules because I use it anyway as a firewall
|
||||
when I harden my servers.
|
||||
I use `ufw` to handle the iptables rules because I use it anyway as a firewall when I harden my servers.
|
||||
|
||||
Enable routing:
|
||||
|
||||
|
@ -218,14 +203,11 @@ Add this to the top of `/etc/ufw/before.rules`:
|
|||
COMMIT
|
||||
```
|
||||
|
||||
Replace `123.123.123.123` with your VPN server's external IP address and `eth0`
|
||||
with the external interface.
|
||||
Replace `123.123.123.123` with your VPN server's external IP address and `eth0` with the external interface.
|
||||
|
||||
This will forward TCP traffic on port 2222 to your home server. If you want to
|
||||
use port 22, then you need to set the VPN SSH server to something else.
|
||||
This will forward TCP traffic on port 2222 to your home server. If you want to use port 22, then you need to set the VPN SSH server to something else.
|
||||
|
||||
A full example of `/etc/ufw/before.rules` with other ports included can be
|
||||
found here:
|
||||
A full example of `/etc/ufw/before.rules` with other ports included can be found here:
|
||||
|
||||
[https://txt.t0.vc/URUG](https://txt.t0.vc/URUG)
|
||||
|
||||
|
@ -248,8 +230,7 @@ $ sudo apt install openvpn
|
|||
|
||||
### Client Configs
|
||||
|
||||
For static IP clients (like your home server), create the config file
|
||||
`/etc/openvpn/client.conf`:
|
||||
For static IP clients (like your home server), create the config file `/etc/openvpn/client.conf`:
|
||||
|
||||
```
|
||||
client
|
||||
|
@ -279,8 +260,7 @@ key-direction 1
|
|||
</tls-auth>
|
||||
```
|
||||
|
||||
Replace the `[server ...]` lines with the contents of that file on the __VPN
|
||||
server__, for example:
|
||||
Replace the `[server ...]` lines with the contents of that file on the __VPN server__, for example:
|
||||
|
||||
```
|
||||
$ sudo cat /etc/openvpn/easy-rsa/pki/ca.crt
|
||||
|
@ -289,8 +269,7 @@ $ sudo cat /etc/openvpn/easy-rsa/pki/ca.crt
|
|||
|
||||
Also replace `vpn.example.com` with the subdomain you assigned earlier.
|
||||
|
||||
For device clients (like your laptop and phone), create the config file
|
||||
`client.ovpn`:
|
||||
For device clients (like your laptop and phone), create the config file `client.ovpn`:
|
||||
|
||||
<span class="aside">`redirect-gateway def1` forces traffic over the VPN</span>
|
||||
|
||||
|
@ -367,22 +346,17 @@ $ sudo service openvpn restart
|
|||
|
||||
### Client Apps
|
||||
|
||||
On Android I use "OpenVPN for Android" and on Linux I use the
|
||||
`network-manager-openvpn-gnome` Debian package.
|
||||
On Android I use "OpenVPN for Android" and on Linux I use the `network-manager-openvpn-gnome` Debian package.
|
||||
|
||||
To add your VPN on Gnome, open VPN settings, import file, and select
|
||||
`client.ovpn`. If the private key is missing, select it from
|
||||
`~/.cert/nm-openvpn/`.
|
||||
To add your VPN on Gnome, open VPN settings, import file, and select `client.ovpn`. If the private key is missing, select it from `~/.cert/nm-openvpn/`.
|
||||
|
||||
## Closing Thoughts
|
||||
|
||||
You should now be fine to access your home server from over the internet.
|
||||
|
||||
To forward additional ports, just edit the `/etc/ufw/before.rules` file like
|
||||
above and apply the changes to `ufw`.
|
||||
To forward additional ports, just edit the `/etc/ufw/before.rules` file like above and apply the changes to `ufw`.
|
||||
|
||||
You can now point a domain to your virtual server's IP and use that to connect
|
||||
to your home server. Use a CNAME to make it easy to change later:
|
||||
You can now point a domain to your virtual server's IP and use that to connect to your home server. Use a CNAME to make it easy to change later:
|
||||
|
||||
```
|
||||
NAME TYPE VALUE
|
||||
|
@ -391,5 +365,4 @@ vpn.example.com. A 123.123.123.123
|
|||
myserver.example.com. CNAME vpn.example.com.
|
||||
```
|
||||
|
||||
Finally, make sure any server programs are listening / bound to `10.8.0.100` or
|
||||
`0.0.0.0` so that they can get traffic from that interface.
|
||||
Finally, make sure any server programs are listening / bound to `10.8.0.100` or `0.0.0.0` so that they can get traffic from that interface.
|
23
content/Garage Door Opener.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
Title: Garage Door Opener Hack
|
||||
Date: 2021-12-26
|
||||
Category: Creations
|
||||
Summary: Hacking my garage door opener to work over Wifi.
|
||||
Short: 5
|
||||
|
||||
In the quest to automate as much of my house as possible, I thought it would be useful to be able to remotely control my garage door from my home automation system. If I suspected that I forgot to close it while leaving, I could check in my security cameras and then close it from anywhere. It's nice having this peace of mind, even if it almost never happens.
|
||||
|
||||
Instead of reverse engineering the wireless protocol, cracking the encryption, and sending my own commands, I figured it would be much easier to hack the hardware. I cracked open a spare remote to find that it contained a basic PCB with simple tactile switches.
|
||||
|
||||
![[garage1.jpg | the six parts of the spare remote on my desk: metal clip, plastic buttons, battery, PCB, and two halves of the case]]
|
||||
|
||||
My plan was to solder an Arduino controlled relay in parallel with the button that toggled the garage door. I would also power the remote from the 3 V pin. I soldered four wires on to the appropriate pins.
|
||||
|
||||
![[garage2.jpg | a closeup of the green PCB with two wires soldered to the battery terminals and two to the button pins]]
|
||||
|
||||
I drilled a hole in the plastic case and routed the wires through it while reassembling the remote. It's connected to an Adafruit ESP8266 Arduino with a relay module shield.
|
||||
|
||||
The Arduino joins my isolated home automation Wifi network and connects over MQTT, a simple messaging protocol, to my automation server. When it receives a command over MQTT it toggles the relay on for a quarter of a second and then off, simulating a button press.
|
||||
|
||||
![[garage3.jpg | the completed system: an arduino with a white relay and wires leading to the reassembled garage door remote]]
|
||||
|
||||
Update: this system has been flawless for two months now. It's worked every time I've tried to toggle the door and has never opened by mistake.
|
19
content/Hand of Ozymandias.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
Title: Hand of Ozymandias
|
||||
Date: 2012-03-23
|
||||
Category: Creations
|
||||
Summary: A withered hand I welded out of scrap metal.
|
||||
Short: hand
|
||||
|
||||
I was visiting my cousins in Radium, BC and decided to learn stick welding at their shop. I wanted to create a sculpture, so with pieces of scrap metal I welded together this hand. The beads are far from perfect. Working with small pieces of rusted metal made it difficult.
|
||||
|
||||
![[hand1.jpg | a rusted hand welded together out of scrap square stock metal tubing]]
|
||||
|
||||
## The Name
|
||||
|
||||
One of my favourite poems is [Ozymandias](https://en.wikipedia.org/wiki/Ozymandias) by Percy Bysshe Shelley. It's about the inevitable complete decline of all rulers and the empires they build, however mighty in their time. This is the hand of Ozymandias sticking out from the sand, grasping for life after he has been reduced to dust.
|
||||
|
||||
## Construction
|
||||
|
||||
I eyeballed the joint angles and my cousin cut them to spec with an angle grinder. It was made in a machine shop with no real planning done ahead of time. In between welds, I used my own hand as a reference. Below is a picture of me adding a bead to it.
|
||||
|
||||
![[hand2.jpg | me welding the hand causing a very bright white light that washes out the photo]]
|
22
content/LED Dress.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
Title: LED Dress
|
||||
Date: 2016-03-18
|
||||
Category: Creations
|
||||
Summary: A dress made out of LEDs that twinkle like stars.
|
||||
Short: 4
|
||||
|
||||
A friend of mine was attending a stars and constellations themed ball. She wanted to wear a dress that was lit up with LEDs acting as twinkling stars. Seven of the 28 stars are aligned to resemble the Big Dipper constellation and twinkle differently than the rest, which twinkle in a random pattern.
|
||||
|
||||
![[dress1.jpg | a girl wearing a blue dress with a number of LEDs shining through the fabric]]
|
||||
|
||||
## Construction
|
||||
|
||||
The LEDs came from that strip that was cut up and soldered together with very small wires. Each of the LEDs can be controlled individually.
|
||||
|
||||
![[dress2.jpg | the controller circuit board, and the string of soldered together LEDs]]
|
||||
|
||||
Twenty-one of the stars are light magenta in color and twinkle by fading randomly. The seven LEDs that form the Big Dipper continually scroll through a gradient of three colors. Instead of calculating the values of each color in the gradient as the program runs, a lookup table is used.
|
||||
|
||||
<video autoplay muted loop style="display:block; margin: 0 auto;">
|
||||
<source src="{static}/media/dress3.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
23
content/Light Switch.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
Title: Remote Control Light Switch
|
||||
Date: 2014-10-09
|
||||
Category: Creations
|
||||
Summary: A device to toggle my lights remotely.
|
||||
Short: remote
|
||||
|
||||
I wanted the ability to toggle my bedroom light remotely for convenience. I designed a circuit that allows me to control my light with any device that can load a webpage.
|
||||
|
||||
I still wanted to be able to control the light manually, so I bought a metallic face-plate and turned it into a capacitive touch sensor. The slightest touch anywhere on the plate is enough to toggle the light. I had to electrically isolate the metal screws from it because they screw into a grounded switch box.
|
||||
|
||||
![[light1.jpg | my custom light switch, a Raspberry Pi computer, and an old iPhone]]
|
||||
|
||||
## Function
|
||||
|
||||
I have a Raspberry Pi ($35 computer) on my home network that runs a web server. When you connect to it in your web browser, a page loads with buttons to turn the light on or off. When you press a button, the server executes a command that sends a message over Bluetooth to the light switch. The Bluetooth module in the wall receives this message and forwards it to the microcontroller, which processes it and toggles the relay. The whole circuit is also powered from mains by an AC-DC converter.
|
||||
|
||||
This entire process happens quicker than half a second, so it feels instant.
|
||||
|
||||
![[light2.jpg | the front side which has several electrical components]]
|
||||
|
||||
<span class="aside">Black stuff's liquid electrical tape</span>
|
||||
|
||||
![[light3.jpg | the back side which has wires soldered to connect all the components]]
|
74
content/Linux Flavour.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
Title: Choosing a Linux Flavour
|
||||
Date: 2020-10-31
|
||||
Category: Writing
|
||||
Summary: A recommendation on which flavour of Linux to run.
|
||||
Wide: true
|
||||
Short: 6
|
||||
|
||||
[TOC]
|
||||
|
||||
People often ask me which flavour of Linux they should install. In summary, choose Ubuntu if it's your first time. Once you are comfortable, install Debian the next time you need to install Linux.
|
||||
|
||||
I run Debian on my computers and servers.
|
||||
|
||||
## Linux Distributions
|
||||
|
||||
<span class="aside">Interjection: it's technically called GNU/Linux</span>
|
||||
|
||||
When people refer to the "flavour of Linux" they are talking about a Linux distribution (distro). It mostly describes what software is distributed in its software repository.
|
||||
|
||||
"A typical Linux distribution comprises a Linux kernel, GNU tools and libraries, additional software, documentation, a window system, a window manager, and a desktop environment." [Wikipedia]
|
||||
|
||||
The major Linux distros are practically all the same. If you master one it's easy to pick up the others. The main differences you'll run into are which tools you use to install new software, and the desktop environment, which is what all the windows and buttons look like.
|
||||
|
||||
I recommend two Linux distros, Debian and Ubuntu. Ubuntu is based off of Debian, so they are very similar.
|
||||
|
||||
## Pros of Debian
|
||||
|
||||
Debian is one of the oldest distros and many other distros are based off it. You can see a timeline visualization of all its derivatives here:
|
||||
|
||||
<https://upload.wikimedia.org/wikipedia/commons/1/1b/Linux_Distribution_Timeline.svg>
|
||||
|
||||
This image is what originally convinced me to use Debian. Scroll down until you see it and zoom out so you grasp how many derivatives it has.
|
||||
|
||||
Debian is also non-commercial and requires that all software in its main repository is free and open source. This is important because that grants you the right to study, change, and distribute the software and source code to anyone and for any purpose. They also follow a strong social contract you can see here:
|
||||
|
||||
<https://www.debian.org/social_contract>
|
||||
|
||||
It's also a very stable Linux distro since they freeze all software features on each release. This makes it great for servers because nothing will break when it updates.
|
||||
|
||||
The main Raspberry Pi distro is nearly identical to Debian, so you'll also gain familiarity with it.
|
||||
|
||||
## Cons of Debian
|
||||
|
||||
Since Debian requires all its software to be free and open source, proprietary hardware drivers aren't included in its main repo. This can make installing Debian difficult if your hardware requires proprietary drivers. You'll need to use an installation image found here:
|
||||
|
||||
<https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/>
|
||||
|
||||
The fact that Debian freezes software features can also mean that your software gets old until the next Debian release. If you want versions that are bleeding edge, you'll need to use Debian Unstable as described here:
|
||||
|
||||
<https://wiki.debian.org/DebianUnstable#Installation>
|
||||
|
||||
Don't be fooled by the name "unstable". I use it for my personal computers and it runs fine.
|
||||
|
||||
## Pros of Ubuntu
|
||||
|
||||
Ubuntu is incredibly easy to install. You can also try it out before deciding to install it. The distro pretty much just works on what ever hardware you have.
|
||||
|
||||
It's very beginner friendly because it's so popular. Any problem you search for will reveal dozens of threads with people solving the same problem.
|
||||
|
||||
## Cons of Ubuntu
|
||||
|
||||
Unfortunately Ubuntu is developed by a commercial company, Canonical. The company's interests come first, before the users' and they have a track record of betraying their users' trust and privacy.
|
||||
|
||||
Years ago Ubuntu had a feature enabled by default that would send your desktop searches to Amazon so they could suggest products for you to buy:
|
||||
|
||||
<https://www.pcworld.com/article/2840401/ubuntus-unity-8-desktop-removes-the-amazon-search-spyware.html>
|
||||
|
||||
Currently whenever you remote login to your Ubuntu machine, it phones home to Canonical and they collect info about your system:
|
||||
|
||||
<https://ubuntu.com/legal/motd>
|
||||
|
||||
While these reasons are fairly minor, they are quite frowned upon in the Linux community and are reason enough to switch to Debian once you are comfortable with using Linux.
|
||||
|
||||
[Wikipedia]: https://en.wikipedia.org/wiki/Linux_distribution
|
30
content/Painting.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
Title: Man's Reach Exceeds His Grasp
|
||||
Date: 2012-04-11
|
||||
Category: Creations
|
||||
Summary: My first attempt at painting with acrylic.
|
||||
Short: 7
|
||||
|
||||
The painting is called “Man’s Reach Exceeds His Grasp”. I've always wanted to try painting and thought I had a good idea, so after a couple of drawings I attempted to paint it. I eventually got it framed at Michaels. Many thanks to my friend Laura for the opportunity to do this, I couldn't have done it without her help.
|
||||
|
||||
![[painting1.jpg | a painting of water pouring out of a vase and into a hand, then turning to sand]]
|
||||
|
||||
## The Meaning
|
||||
|
||||
It’s hard to see in the photo, but the moment the water touches his hand it turns into sand and is taken by the slight breeze. The title is a quote from Andrea del Sarto, a poem by Robert Browning. It is also said by Nikola Tesla’s character in my favourite movie, [The Prestige](https://www.imdb.com/title/tt0482571/).
|
||||
|
||||
“I, painting from myself and to myself,
|
||||
Know what I do, am unmoved by men’s blame
|
||||
Or their praise either. Somebody remarks
|
||||
Morello's outline there is wrongly traced,
|
||||
His hue mistaken; what of that? or else,
|
||||
Rightly traced and well ordered; what of that?
|
||||
Speak as they please, what does the mountain care?
|
||||
Ah, but a man’s reach should exceed his grasp,
|
||||
Or what’s a heaven for?”
|
||||
– Robert Browning from *Andrea del Sarto*
|
||||
|
||||
## Creation
|
||||
|
||||
I started with the background, trying to make it blurry and out of focus, then slowly progressed to the foreground. The hands were drawn in pencil and painted in. It was quite difficult to get the blending and shadows perfect, but I had Laura to tell me when things didn't look right. Below I am trying to figure out what a hand looks like in a mirror.
|
||||
|
||||
![[painting2.jpg | me looking at my own hand in the mirror as a guide]]
|
29
content/Plant Waterer.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
Title: Automatic Plant Waterer
|
||||
Date: 2014-06-05
|
||||
Category: Creations
|
||||
Summary: A device that automatically waters plants.
|
||||
short: 8
|
||||
|
||||
One day I decided watering my one plant was too much work, so I automated it. It's also great for when I'm on vacation. The plant is a year old now and doesn't look as good as it used to (kinda like you). So this machine is like its life support.
|
||||
|
||||
<span class="aside">Update: this plant died long ago</span>
|
||||
|
||||
![[waterer1.jpg | the device and pump on a 2L pop bottle with a tube running to a flowerpot]]
|
||||
|
||||
## First Attempt
|
||||
|
||||
The design was very simple and soldered together on perf board. A microcontroller turns the pump on for 20 seconds, then waits 24 hours and restarts. The pump ran way too fast so it was slowed down to 10% power.
|
||||
|
||||
This design suffered from a fatal problem. After running, there was a chance that the tube would stay full of fluid. If the water level in the pop bottle was too high, it could siphon out. I woke up with a flower pot overflowing with water a couple of times.
|
||||
|
||||
![[waterer2.jpg | a new version feeding into a different plant]]
|
||||
|
||||
## Second Attempt
|
||||
|
||||
I liked the idea so much that I made a second iteration. This one used a custom printed circuit board with a lot more features. The pumping duration could be adjusted with a screwdriver. This was useful as the plant (now a [Ming aralia](https://en.wikipedia.org/wiki/Polyscias_fruticosa)) grew.
|
||||
|
||||
Another feature was the ability to run the pump backwards. This completely eliminated the siphoning problem from before. After pumping for a set duration, it would run backwards until the tube was cleared of water.
|
||||
|
||||
<span class="aside">Also dead :(</span>
|
||||
|
||||
![[waterer3.jpg | the new version beside a big Ming aralia plant with bushy drooping leaves and skinny stems]]
|
15
content/Solar Car.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
Title: Solar Car
|
||||
Date: 2013-04-27
|
||||
Category: Creations
|
||||
Summary: About my time volunteering with the University of Calgary Solar Car Team, where I designed a maximum power point tracker.
|
||||
Short: 9
|
||||
|
||||
I joined the University of Calgary Solar Car Team in my first semester for a chance to learn things, gain practical experience, and meet people that share my interests. The car was the top Canadian team in a 3000 km race from Darwin to Adelaide, Australia in 2011. We met up at a shop on campus every Saturday morning to work on the new Generation IV of the solar car.
|
||||
|
||||
![[solar1.jpg | the MPPT device, a printed circuit board with bulky round electrical components held in my hand]]
|
||||
|
||||
## The Helianthus MPPT
|
||||
|
||||
I was in charge of designing and assembling the MPPTs (maximum power point trackers) for the new generation solar car. An MPPT extracts as much power out of the solar cells as possible. The solar array operates less efficiently without them. The Generation IV car, Schulich Delta (pictured below) uses seven of them: one per section of solar cells with similar lighting conditions. Andrei and I designed the MPPT above.
|
||||
|
||||
![[solar2.jpg | the solar car from an angle with a driver inside]]
|
19
content/Wine Crate Coffee Table.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
Title: Wine Crate Coffee Table
|
||||
Date: 2018-09-12
|
||||
Category: Creations
|
||||
Summary: A coffee table made out of wooden wine creates.
|
||||
Short: 0
|
||||
|
||||
My close friend Odai saw a simple coffee table design online that was built out of four wooden wine crates. They are quite cheap and available at any hardware store. We each wanted to make one so went and bought eight crates and some plywood to use as a base.
|
||||
|
||||
We went to my local makerspace, Protospace, to build them in the wood shop. We thought it would be a quick job only taking a few hours, but it turned out to be a twelve hour job over a couple of days. At least we were in good company!
|
||||
|
||||
![[wine1.jpg | the table before staining. four box-like wine crates are on their sides and joined together in a spiral. a messy wood shop is in the background]]
|
||||
|
||||
![[wine2.jpg | the two tables after staining. one face is centred and the contrast between the dark stain and light wood grain shows.]]
|
||||
|
||||
The wine crates were glued and then brad-nailed together. Extra wood was added under the thin top strips for support. After the glue dried, the brad nails were painstakingly removed because the ones we used were too long and stuck out.
|
||||
|
||||
After being attached to the base, the entire table was sanded and then stained. We let it dry overnight and returned the following day to add a quick layer of varnish.
|
||||
|
||||
![[wine3.jpg | the table in my living room with blankets inside the wine crates and a plant pot in the centre growing a bonsai tree and a succulent]]
|
|
@ -1,41 +0,0 @@
|
|||
Title: Theatre Acoustic Panels
|
||||
Date: 2021-10-21
|
||||
Category: Creations
|
||||
Summary: Panels for acoustic treatment in my home theatre.
|
||||
Short: 3
|
||||
|
||||
Acoustic treatment is one of the most overlooked aspects of home audio. There's
|
||||
no point in spending money on premium speakers if the room they are playing in
|
||||
has poor acoustics.
|
||||
|
||||
The primary purpose of acoustic panels is to reduce the reverberations caused by
|
||||
sound reflecting off the smooth walls of the theatre. The path of the reflected
|
||||
sound is a longer distance to your ear compared to the sound coming directly
|
||||
from the speaker. This causes the reflected sound to be delayed by the time it
|
||||
reaches your ear. The delayed signal interferes with itself, causing comb
|
||||
filtering which distorts the signal.
|
||||
|
||||
Acoustic panels are placed geometrically where the sound from the speakers would
|
||||
reflect off the wall to reach the listener's ears. The insulation inside the
|
||||
panels absorbs energy from the soundwave which reduces its volume and
|
||||
interference.
|
||||
|
||||
![twelve L-shaped corners of the panels stacked together leaning on a table saw in a wood shop]({static}/images/panel/panel1.jpg)
|
||||
|
||||
I made six frames in the wood shop of my local makerspace, Protospace. After
|
||||
cutting the 1x4" pine boards to length, I made a jig so I could quickly join
|
||||
them together with screws.
|
||||
|
||||
![a panel with insulation inside on the ground about to be wrapped with black fabric]({static}/images/panel/panel2.jpg)
|
||||
|
||||
I added 4" batts of Rockwool insulation into each frame after it was assembled.
|
||||
I then wrapped the frame with black speaker fabric and stabled it in place while
|
||||
trying to pull it taut.
|
||||
|
||||
I sat in my theatre while a friend slid a handheld mirror along the wall until I
|
||||
could see the middle of the speaker in its reflection. This told me the centre
|
||||
point of where to mount each panel because the reflected sound would take the
|
||||
same path to my ear.
|
||||
|
||||
<span class="aside">Four in the front, two in the back</span>
|
||||
![four black acoustic panels mounted on the walls in my home theatre]({static}/images/panel/panel3.jpg)
|
|
@ -1,38 +0,0 @@
|
|||
Title: Garage Door Opener Hack
|
||||
Date: 2021-12-26
|
||||
Category: Creations
|
||||
Summary: Hacking my garage door opener to work over Wifi.
|
||||
Short: 5
|
||||
|
||||
In the quest to automate as much of my house as possible, I thought it would be
|
||||
useful to be able to remotely control my garage door from my home automation
|
||||
system. If I suspected that I forgot to close it while leaving, I could check in
|
||||
my security cameras and then close it from anywhere. It's nice having this peace
|
||||
of mind, even if it almost never happens.
|
||||
|
||||
Instead of reverse engineering the wireless protocol, cracking the encryption,
|
||||
and sending my own commands, I figured it would be much easier to hack the
|
||||
hardware. I cracked open a spare remote to find that it contained a basic PCB
|
||||
with simple tactile switches.
|
||||
|
||||
![the six parts of the spare remote on my desk: metal clip, plastic buttons, battery, PCB, and two halves of the case]({static}/images/garage/garage1.jpg)
|
||||
|
||||
My plan was to solder an Arduino controlled relay in parallel with the button
|
||||
that toggled the garage door. I would also power the remote from the 3 V pin. I
|
||||
soldered four wires on to the appropriate pins.
|
||||
|
||||
![a closeup of the green PCB with two wires soldered to the battery terminals and two to the button pins]({static}/images/garage/garage2.jpg)
|
||||
|
||||
I drilled a hole in the plastic case and routed the wires through it while
|
||||
reassembling the remote. It's connected to an Adafruit ESP8266 Arduino with a
|
||||
relay module shield.
|
||||
|
||||
The Arduino joins my isolated home automation Wifi network and connects over
|
||||
MQTT, a simple messaging protocol, to my automation server. When it receives a
|
||||
command over MQTT it toggles the relay on for a quarter of a second and then
|
||||
off, simulating a button press.
|
||||
|
||||
![the completed system: an arduino with a white relay and wires leading to the reassembled garage door remote]({static}/images/garage/garage3.jpg)
|
||||
|
||||
Update: this system has been flawless for two months now. It's worked every time
|
||||
I've tried to toggle the door and has never opened by mistake.
|
|
@ -1,29 +0,0 @@
|
|||
Title: Hand of Ozymandias
|
||||
Date: 2012-03-23
|
||||
Category: Creations
|
||||
Summary: A withered hand I welded out of scrap metal.
|
||||
Short: hand
|
||||
|
||||
I was visiting my cousins in Radium, BC and decided to learn stick welding at
|
||||
their shop. I wanted to create a sculpture, so with pieces of scrap metal I
|
||||
welded together this hand. The beads are far from perfect. Working with small
|
||||
pieces of rusted metal made it difficult.
|
||||
|
||||
![a rusted hand welded together out of scrap square stock metal tubing]({static}/images/hand-of-ozymandias/hand1.jpg)
|
||||
|
||||
## The Name
|
||||
|
||||
One of my favourite poems is [Ozymandias](https://en.wikipedia.org/wiki/Ozymandias)
|
||||
by Percy Bysshe Shelley. It's about the inevitable complete decline of all
|
||||
rulers and the empires they build, however mighty in their time. This is the
|
||||
hand of Ozymandias sticking out from the sand, grasping for life after he has
|
||||
been reduced to dust.
|
||||
|
||||
## Construction
|
||||
|
||||
I eyeballed the joint angles and my cousin cut them to spec with an angle
|
||||
grinder. It was made in a machine shop with no real planning done ahead of time.
|
||||
In between welds, I used my own hand as a reference. Below is a picture of me
|
||||
adding a bead to it.
|
||||
|
||||
![me welding the hand causing a very bright white light that washes out the photo]({static}/images/hand-of-ozymandias/hand2.jpg)
|
|
@ -1,29 +0,0 @@
|
|||
Title: LED Dress
|
||||
Date: 2016-03-18
|
||||
Category: Creations
|
||||
Summary: A dress made out of LEDs that twinkle like stars.
|
||||
Short: 4
|
||||
|
||||
A friend of mine was attending a stars and constellations themed ball. She
|
||||
wanted to wear a dress that was lit up with LEDs acting as twinkling stars.
|
||||
Seven of the 28 stars are aligned to resemble the Big Dipper constellation and
|
||||
twinkle differently than the rest, which twinkle in a random pattern.
|
||||
|
||||
![a girl wearing a blue dress with a number of LEDs shining through the fabric]({static}/images/dress/dress1.jpg)
|
||||
|
||||
## Construction
|
||||
|
||||
The LEDs came from that strip that was cut up and soldered together with very
|
||||
small wires. Each of the LEDs can be controlled individually.
|
||||
|
||||
![the controller circuit board, and the string of soldered together LEDs]({static}/images/dress/dress2.jpg)
|
||||
|
||||
21 of the stars are light magenta in color and twinkle by fading randomly. The
|
||||
seven LEDs that form the Big Dipper continually scroll through a gradient of
|
||||
three colors. Instead of calculating the values of each color in the gradient as
|
||||
the program runs, a lookup table is used.
|
||||
|
||||
<video autoplay muted loop style="display:block; margin: 0 auto;">
|
||||
<source src="{static}/videos/dress/dress3.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
|
@ -1,34 +0,0 @@
|
|||
Title: Remote Control Light Switch
|
||||
Date: 2014-10-09
|
||||
Category: Creations
|
||||
Summary: A device to toggle my lights remotely.
|
||||
Short: remote
|
||||
|
||||
I wanted the ability to toggle my bedroom light remotely for convenience. I
|
||||
designed a circuit that allows me to control my light with any
|
||||
device that can load a webpage.
|
||||
|
||||
I still wanted to be able to control the light manually, so I bought a metallic
|
||||
face-plate and turned it into a capacitive touch sensor. The slightest touch
|
||||
anywhere on the plate is enough to toggle the light. I had to electrically
|
||||
isolate the metal screws from it because they screw into a grounded switch box.
|
||||
|
||||
![my custom light switch, a Raspberry Pi computer, and an old iPhone]({static}/images/light-switch/light1.jpg)
|
||||
|
||||
## Function
|
||||
|
||||
I have a Raspberry Pi ($35 computer) on my home network that runs a web server.
|
||||
When you connect to it in your web browser, a page loads with buttons to turn
|
||||
the light on or off. When you press a button, the server executes a command that
|
||||
sends a message over Bluetooth to the light switch. The Bluetooth module in the
|
||||
wall receives this message and forwards it to the microcontroller, which
|
||||
processes it and toggles the relay. The whole circuit is also powered from mains
|
||||
by an AC-DC converter.
|
||||
|
||||
This entire process happens quicker than half a second, so it feels instant.
|
||||
|
||||
![the front side which has several electrical components]({static}/images/light-switch/light2.jpg)
|
||||
|
||||
<span class="aside">Black stuff's liquid electrical tape</span>
|
||||
|
||||
![the back side which has wires soldered to connect all the components]({static}/images/light-switch/light3.jpg)
|
|
@ -1,107 +0,0 @@
|
|||
Title: Choosing a Linux Flavour
|
||||
Date: 2020-10-31
|
||||
Category: Writing
|
||||
Summary: A recommendation on which flavour of Linux to run.
|
||||
Wide: true
|
||||
Short: 6
|
||||
|
||||
[TOC]
|
||||
|
||||
People often ask me which flavour of Linux they should install. In summary,
|
||||
choose Ubuntu if it's your first time. Once you are comfortable, install Debian
|
||||
the next time you need to install Linux.
|
||||
|
||||
I run Debian on my computers and servers.
|
||||
|
||||
## Linux Distributions
|
||||
|
||||
When people refer to the "flavour of Linux" they are talking about a Linux
|
||||
<span class="aside">Interjection: it's technically called GNU/Linux</span>
|
||||
distribution (distro). It mostly describes what software is distributed in its
|
||||
software repository.
|
||||
|
||||
"A typical Linux distribution comprises a Linux kernel, GNU tools and
|
||||
libraries, additional software, documentation, a window system, a window
|
||||
manager, and a desktop environment." [Wikipedia]
|
||||
|
||||
The major Linux distros are practically all the same. If you master one it's
|
||||
easy to pick up the others. The main differences you'll run into are which
|
||||
tools you use to install new software, and the desktop environment, which is
|
||||
what all the windows and buttons look like.
|
||||
|
||||
I recommend two Linux distros, Debian and Ubuntu. Ubuntu is based off of
|
||||
Debian, so they are very similar.
|
||||
|
||||
## Pros of Debian
|
||||
|
||||
Debian is one of the oldest distros and many other distros are based off it.
|
||||
You can see a timeline visualization of all its derivatives here:
|
||||
|
||||
<https://upload.wikimedia.org/wikipedia/commons/1/1b/Linux_Distribution_Timeline.svg>
|
||||
|
||||
This image is what originally convinced me to use Debian. Scroll down until you
|
||||
see it and zoom out so you grasp how many derivatives it has.
|
||||
|
||||
Debian is also non-commercial and requires that all software in its main
|
||||
repository is free and open source. This is important because that grants you
|
||||
the right to study, change, and distribute the software and source code to
|
||||
anyone and for any purpose. They also follow a strong social contract you can
|
||||
see here:
|
||||
|
||||
<https://www.debian.org/social_contract>
|
||||
|
||||
It's also a very stable Linux distro since they freeze all software features on
|
||||
each release. This makes it great for servers because nothing will break when
|
||||
it updates.
|
||||
|
||||
The main Raspberry Pi distro is nearly identical to Debian, so you'll also gain
|
||||
familiarity with it.
|
||||
|
||||
## Cons of Debian
|
||||
|
||||
Since Debian requires all its software to be free and open source, proprietary
|
||||
hardware drivers aren't included in its main repo. This can make installing
|
||||
Debian difficult if your hardware requires proprietary drivers. You'll need to use
|
||||
an installation image found here:
|
||||
|
||||
<https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/>
|
||||
|
||||
The fact that Debian freezes software features can also mean that your software
|
||||
gets old until the next Debian release. If you want versions that are bleeding
|
||||
edge, you'll need to use Debian Unstable as described here:
|
||||
|
||||
<https://wiki.debian.org/DebianUnstable#Installation>
|
||||
|
||||
Don't be fooled by the name "unstable". I use it for my personal computers and
|
||||
it runs fine.
|
||||
|
||||
## Pros of Ubuntu
|
||||
|
||||
Ubuntu is incredibly easy to install. You can also try it out before deciding
|
||||
to install it. The distro pretty much just works on what ever hardware you
|
||||
have.
|
||||
|
||||
It's very beginner friendly because it's so popular. Any problem you search for
|
||||
will reveal dozens of threads with people solving the same problem.
|
||||
|
||||
## Cons of Ubuntu
|
||||
|
||||
Unfortunately Ubuntu is developed by a commercial company, Canonical. The
|
||||
company's interests come first, before the users' and they have a track record
|
||||
of betraying their users' trust and privacy.
|
||||
|
||||
Years ago Ubuntu had a feature enabled by default that would send your desktop
|
||||
searches to Amazon so they could suggest products for you to buy:
|
||||
|
||||
<https://www.pcworld.com/article/2840401/ubuntus-unity-8-desktop-removes-the-amazon-search-spyware.html>
|
||||
|
||||
Currently whenever you remote login to your Ubuntu machine, it phones home to
|
||||
Canonical and they collect info about your system:
|
||||
|
||||
<https://ubuntu.com/legal/motd>
|
||||
|
||||
While these reasons are fairly minor, they are quite frowned upon in the Linux
|
||||
community and are reason enough to switch to Debian once you are comfortable
|
||||
with using Linux.
|
||||
|
||||
[Wikipedia]: https://en.wikipedia.org/wiki/Linux_distribution
|
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 239 KiB After Width: | Height: | Size: 239 KiB |
Before Width: | Height: | Size: 247 KiB After Width: | Height: | Size: 247 KiB |
Before Width: | Height: | Size: 293 KiB After Width: | Height: | Size: 293 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 154 KiB |
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 350 KiB After Width: | Height: | Size: 350 KiB |
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 286 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 163 KiB |
Before Width: | Height: | Size: 295 KiB After Width: | Height: | Size: 295 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
|
@ -1,41 +0,0 @@
|
|||
Title: Man's Reach Exceeds His Grasp
|
||||
Date: 2012-04-11
|
||||
Category: Creations
|
||||
Summary: My first attempt at painting with acrylic.
|
||||
Short: 7
|
||||
|
||||
The painting is called “Man’s Reach Exceeds His Grasp”. I've always wanted to
|
||||
try painting and thought I had a good idea, so after a couple of drawings I
|
||||
attempted to paint it. I eventually got it framed at Michaels. Many thanks to my
|
||||
friend Laura for the opportunity to do this, I couldn't have done it without her
|
||||
help.
|
||||
|
||||
![a painting of water pouring out of a vase and into a hand, then turning to sand]({static}/images/painting/painting1.jpg)
|
||||
|
||||
## The Meaning
|
||||
|
||||
It’s hard to see in the photo, but the moment the water touches his hand it
|
||||
turns into sand and is taken by the slight breeze. The title is a quote from
|
||||
Andrea del Sarto, a poem by Robert Browning. It is also said by Nikola Tesla’s
|
||||
character in my favourite movie, [The Prestige](https://www.imdb.com/title/tt0482571/).
|
||||
|
||||
“I, painting from myself and to myself,
|
||||
Know what I do, am unmoved by men’s blame
|
||||
Or their praise either. Somebody remarks
|
||||
Morello's outline there is wrongly traced,
|
||||
His hue mistaken; what of that? or else,
|
||||
Rightly traced and well ordered; what of that?
|
||||
Speak as they please, what does the mountain care?
|
||||
Ah, but a man’s reach should exceed his grasp,
|
||||
Or what’s a heaven for?”
|
||||
– Robert Browning from *Andrea del Sarto*
|
||||
|
||||
## Creation
|
||||
|
||||
I started with the background, trying to make it blurry and out of focus, then
|
||||
slowly progressed to the foreground. The hands were drawn in pencil and painted
|
||||
in. It was quite difficult to get the blending and shadows perfect, but I had
|
||||
Laura to tell me when things didn't look right. Below I am trying to figure out
|
||||
what a hand looks like in a mirror.
|
||||
|
||||
![me looking at my own hand in the mirror as a guide]({static}/images/painting/painting2.jpg)
|
|
@ -1,42 +0,0 @@
|
|||
Title: Automatic Plant Waterer
|
||||
Date: 2014-06-05
|
||||
Category: Creations
|
||||
Summary: A device that automatically waters plants.
|
||||
short: 8
|
||||
|
||||
One day I decided watering my one plant was too much work, so I automated it.
|
||||
It's also great for when I'm on vacation. The plant is a year old now and
|
||||
doesn't look as good as it used to (kinda like you). So this machine is like its
|
||||
life support.
|
||||
|
||||
<span class="aside">Update: this plant died long ago</span>
|
||||
|
||||
![the device and pump on a 2L pop bottle with a tube running to a flowerpot]({static}/images/plant-waterer/waterer1.jpg)
|
||||
|
||||
## First Attempt
|
||||
|
||||
The design was very simple and soldered together on perf board. A
|
||||
microcontroller turns the pump on for 20 seconds, then waits 24 hours and
|
||||
restarts. The pump ran way too fast so it was slowed down to 10% power.
|
||||
|
||||
This design suffered from a fatal problem. After running, there was a chance
|
||||
that the tube would stay full of fluid. If the water level in the pop bottle was
|
||||
too high, it could siphon out. I woke up with a flower pot overflowing with
|
||||
water a couple of times.
|
||||
|
||||
![a new version feeding into a different plant]({static}/images/plant-waterer/waterer2.jpg)
|
||||
|
||||
## Second Attempt
|
||||
|
||||
I liked the idea so much that I made a second iteration. This one used a custom
|
||||
printed circuit board with a lot more features. The pumping duration could be
|
||||
adjusted with a screwdriver. This was useful as the plant (now a
|
||||
[Ming aralia](https://en.wikipedia.org/wiki/Polyscias_fruticosa)) grew.
|
||||
|
||||
Another feature was the ability to run the pump backwards. This completely
|
||||
eliminated the siphoning problem from before. After pumping for a set duration,
|
||||
it would run backwards until the tube was cleared of water.
|
||||
|
||||
<span class="aside">Also dead :(</span>
|
||||
|
||||
![the new version beside a big Ming aralia plant with bushy drooping leaves and skinny stems]({static}/images/plant-waterer/waterer3.jpg)
|
|
@ -1,24 +0,0 @@
|
|||
Title: Solar Car
|
||||
Date: 2013-04-27
|
||||
Category: Creations
|
||||
Summary: About my time volunteering with the University of Calgary Solar Car Team, where I designed a maximum power point tracker.
|
||||
Short: 9
|
||||
|
||||
I joined the University of Calgary Solar Car Team in my first semester for a
|
||||
chance to learn things, gain practical experience, and meet people that share my
|
||||
interests. The car was the top Canadian team in a 3000 km race from Darwin to
|
||||
Adelaide, Australia in 2011. We met up at a shop on campus every Saturday
|
||||
morning to work on the new Generation IV of the solar car.
|
||||
|
||||
![the MPPT device, a printed circuit board with bulky round electrical components held in my hand]({static}/images/solar-car/solar1.jpg)
|
||||
|
||||
## The Helianthus MPPT
|
||||
|
||||
I was in charge of designing and assembling the MPPTs (maximum power point
|
||||
trackers) for the new generation solar car. An MPPT extracts as much power out
|
||||
of the solar cells as possible. The solar array operates less efficiently
|
||||
without them. The Generation IV car, Schulich Delta (pictured below) uses seven
|
||||
of them: one per section of solar cells with similar lighting conditions. Andrei
|
||||
and I designed the MPPT above.
|
||||
|
||||
![the solar car from an angle with a driver inside]({static}/images/solar-car/solar2.jpg)
|
|
@ -1,28 +0,0 @@
|
|||
Title: Wine Crate Coffee Table
|
||||
Date: 2018-09-12
|
||||
Category: Creations
|
||||
Summary: A coffee table made out of wooden wine creates.
|
||||
Short: 0
|
||||
|
||||
My close friend Odai saw a simple coffee table design online that was built out
|
||||
of four wooden wine crates. They are quite cheap and available at any hardware
|
||||
store. We each wanted to make one so went and bought eight crates and some
|
||||
plywood to use as a base.
|
||||
|
||||
We went to my local makerspace, Protospace, to build them in the wood shop. We
|
||||
thought it would be a quick job only taking a few hours, but it turned out to be
|
||||
a twelve hour job over a couple of days. At least we were in good company!
|
||||
|
||||
![the table before staining. four box-like wine crates are on their sides and joined together in a spiral. a messy wood shop is in the background]({static}/images/wine/wine1.jpg)
|
||||
|
||||
![the two tables after staining. one face is centred and the contrast between the dark stain and light wood grain shows.]({static}/images/wine/wine2.jpg)
|
||||
|
||||
The wine crates were glued and then brad-nailed together. Extra wood was added
|
||||
under the thin top strips for support. After the glue dried, the brad nails were
|
||||
painstakingly removed because the ones we used were too long and stuck out.
|
||||
|
||||
After being attached to the base, the entire table was sanded and then stained.
|
||||
We let it dry overnight and returned the following day to add a quick layer of
|
||||
varnish.
|
||||
|
||||
![the table in my living room with blankets inside the wine crates and a plant pot in the centre growing a bonsai tree and a succulent]({static}/images/wine/wine3.jpg)
|
|
@ -34,7 +34,11 @@ MARKDOWN = {
|
|||
'output_format': 'html5',
|
||||
}
|
||||
|
||||
STATIC_PATHS = ['images', 'extra']
|
||||
PLUGINS = [
|
||||
'obsidian',
|
||||
]
|
||||
|
||||
STATIC_PATHS = ['media', 'extra']
|
||||
|
||||
EXTRA_PATH_METADATA = {
|
||||
'extra/favicon.svg': {'path': 'favicon.svg'},
|
||||
|
|
15
requirements.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
blinker==1.4
|
||||
commonmark==0.9.1
|
||||
docutils==0.18.1
|
||||
feedgenerator==2.0.0
|
||||
Jinja2==3.1.2
|
||||
Markdown==3.3.6
|
||||
MarkupSafe==2.1.1
|
||||
pelican==4.7.2
|
||||
pelican-obsidian @ git+https://git.tannercollin.com/tanner/pelican-obsidian.git@41dd1d649127ae2833f5a4b1c3b6b6cb571117d8
|
||||
Pygments==2.12.0
|
||||
python-dateutil==2.8.2
|
||||
pytz==2022.1
|
||||
rich==12.3.0
|
||||
six==1.16.0
|
||||
Unidecode==1.3.4
|