(New Zealand soap opera)
https://www.tvnz.co.nz/shows/shortland-street/episodes/s2024-e117
https://www.tvnz.co.nz/shows/shortland-street/episodes/s2024-e96
]]>I signed up with an agency (BGT) and have been doing some extra work for fun.
(New Zealand soap opera)
https://www.tvnz.co.nz/shows/shortland-street/episodes/s2024-e117
https://www.tvnz.co.nz/shows/shortland-street/episodes/s2024-e96
https://www.tvnz.co.nz/shows/shortland-street/episodes/s2024-e76
I included this one for the sake of completeness. It was my first "appearance" on TV!
https://www.tvnz.co.nz/shows/taskmaster-nz/episodes/s5-e8
I've had it stuck on a fixed color preset for around a year. (See above.) I still like these colors, but I thought it would be
]]>I have an LED strip behind my desk in my office. It's controlled by an ESP32 running the WLED firmware.
I've had it stuck on a fixed color preset for around a year. (See above.) I still like these colors, but I thought it would be nice to change the colors from time to time.
I also have a Novation Launchpad on my desk. When I'm not using it to make music, I use the lights as a little dashboard. It currently just displays information about my CircleCI builds, and a simplified "floorplan" showing the location of lights that are on in my house. It would be fun to show some more data.
I have a few ideas:
I could also show some of this data on the LED strip behind my desk. But I decided to keep it pretty simple for now. I'm just going to change the color scheme based on the day of the week.
Here's the WLED web UI where you can see some of the available color schemes and effects.
The animations can be a bit distracting when I'm working, so I mainly use solid colors. I do like the Aurora preset though:
I'm going to play the Aurora preset on Sundays.
Here's all the other presets I chose for each day of the week:
Here's the code I used in my Home Assistant automation:
alias: "Set WLED Preset Based on Weekday"
trigger:
- platform: time
at: "00:00:01"
action:
- variables:
preset_options:
- Solid Atlantica
- Solid Sunset
- Solid Ocean
- Solid Toxy Reef
- Solid Analogous
- Solid Splash
- Aurora
- service: select.select_option
target:
entity_id: select.wled_nathans_desk_preset
data:
option: "{{ preset_options[now().weekday()] }}"
]]>I also have their lawnmower, leaf blower, and pressure washer. It's great that we can use the same batteries for everything.
I decided to mount the hand-held power tools on a pegboard in my
]]>I have some Stanley Fatmax power tools:
I also have their lawnmower, leaf blower, and pressure washer. It's great that we can use the same batteries for everything.
I decided to mount the hand-held power tools on a pegboard in my workshop. I found this 3D model called "Drzak naradi Stanley Fatmax V20" on Printables. (Czech for "Stanley Fatmax v20 wall-mounted tool battery holder.")
I wanted to tweak the model and create some variations, so I cloned it in OpenSCAD. I imported the STL into a web-based tool called Meshy to measure the dimensions.
I recreated the model in OpenSCAD. I added 4 screw holes to match the holes in my pegboard (spaced 25mm apart.) I made the holes large enough to fit my screwdriver.
I also cut an angle into the protruding arms to help my tools to slide onto the holder instead of getting stuck.
I printed some wall anchors to attach the mounts to my pegboard. I resized the model to fit the 4.5mm holes in the pegboard.
And here's the tools on the wall:
I'm not sure about the layout, but hopefully it will look a bit better once I've put some more tools on the wall. I need to print something to hold my Bosch router. I'm also planning to buy some more Stanley Fatmax tools. Maybe an angle grinder, multi-material cutting tool, and a work light. Those will all go on the wall as well.
]]>alias: Update Zemismart ZM25 Blind Motor Limit
fields:
entity_id:
required: true
description: Entity ID of your cover entity
example: cover.blinds
selector:
entity:
filter:
domain: cover
]]>If you use Home Assistant and Zigbee2MQTT, you can use the following script to configure the motor limits for your Zemismart Zigbee blinds.
alias: Update Zemismart ZM25 Blind Motor Limit
fields:
entity_id:
required: true
description: Entity ID of your cover entity
example: cover.blinds
selector:
entity:
filter:
domain: cover
limit:
required: true
description: "Type of limit: upper, lower, middle"
default: upper
selector:
select:
options:
- upper
- middle
- lower
action:
required: true
description: Set or unset limit
default: set
selector:
select:
options:
- set
- unset
mode: single
icon: mdi:blinds
sequence:
- service: mqtt.publish
data:
qos: 0
retain: false
topic: >-
zigbee2mqtt/{{ states[entity_id].attributes.friendly_name
}}/set/tuya_data_point_test
payload_template: >-
bool,{{"103" if limit == "upper" else ("105" if limit == "lower" else
"104")}},{{"1" if action == "set" else "0"}}
After you create the script, you can call it from the Developer Tools page:
Or in an automation:
service: script.update_zemismart_zm25_blind_motor_limit
data:
entity_id: cover.blinds
limit: upper
action: set
Here is a script to reverse the direction of the motor if your blinds are going the wrong way.
alias: Configure Zemismart ZM25 Blind Motor Options
fields:
entity_id:
required: true
description: Entity ID of your cover entity
example: cover.blinds
selector:
entity:
filter:
domain: cover
reverse_direction:
required: true
description: If the motor should turn in the opposite direction
default: false
selector:
boolean:
mode: single
icon: mdi:blinds
sequence:
- service: mqtt.publish
data:
qos: 0
retain: false
topic: >-
zigbee2mqtt/{{ states[entity_id].attributes.friendly_name
}}/set
payload_template: >-
{ "options": { "reverse_direction": {{"true" if reverse_direction else "false"}} } }
Note: I originally wrote this on the Home Assistant Community forums. Leave a comment on the forum thread if you have any questions:]]>
I bought a Zigbee motor for some blinds in our living room. I got it on AliExpress. Blind motors can be really expensive from New Zealand suppliers. I got a quote from one supplier for $350 per motor, but you can find motors on AliExpress for less than $100. The only problem is that they didn't fit my 50mm aluminum blind tubes, so I 3D printed some adapters.
The blinds in our living room are quite heavy so I needed to get a 20 Nm motor.
I've been using OpenSCAD to do all of my designs, but I wanted to learn how to use AutoDesk Fusion. (It used to be called "Fusion 360" but they changed the name recently.)
This is the first time that I designed and 3D printed some parts exclusively using Autodesk Fusion. I think I'm finally getting the hang of it, and I'm really enjoying it. I think I like it better than OpenSCAD now.
Here's the motor in action:
This was a successful test, so now I'm going to order a few more motors for the rest of my blinds. It will be cool to close them all automatically when we start a movie during the afternoon, or when we go to bed.
If you want to 3D print your own adapters, here are the STL files:
See this Home Assistant Community Forum thread for some tips on how to set up a Zemismart ZM25 Zigbee blind motor. I also shared some of my scripts here for sending Zigbee commands to set the upper and lower limits.
]]>I wrote a blog post about painting my fence. This got me thinking a lot about colors and how I use them as a web developer.
So I asked myself a question: What's the perceptual difference between two adjacent HTML colors?
There are 16,777,216 possible colors (256 x 256 x 256), since there are only 256 possible values for red, green, and blue. I've been using this Delta-E calculator to calculate the perceptual difference between colors:
I chose a random green/blue color (rgb(50,200,180
) and calculated some differences after adding/subtracting one from each color channel. Here are the results:
Subtracting one from the green channel seems to show the biggest perceptual difference.
Here's the difference when you subtract one from each color for pure white (rgb(255, 255, 255
):
So the green channel shows the biggest difference for both addition and subtraction. The next largest difference is in the blue channel, and red makes a relatively small difference.
Here's the progression from rgb(255, 255, 255)
down to rgb(255, 232, 255)
You can see that it's very hard to tell the difference between any two colors that are right next to each other.
I thought of another question: What are the biggest and smallest perceptual differences between two adjacent HTML colors?
I decided to write a Ruby script to figure this out. I found this color_difference
Ruby gem that uses the CIEDE2000 Color-Difference formula.
Paper: https://hajim.rochester.edu/ece/sites/gsharma/ciede2000/ciede2000noteCRNA.pdf
require 'color_difference'
max_difference = nil
min_difference = nil
max_difference_colors = []
min_difference_colors = []
0.step(255, 1) do |r|
0.step(255, 1) do |g|
0.step(255, 1) do |b|
color = { r: r, g: g, b: b }
puts "Color: #{color.inspect}"
[1, -1].each do |diff|
%i(r g b).each do |channel|
new_color = color.dup
new_color[channel] += diff
new_color[channel] = [0, new_color[channel]].max
new_color[channel] = [255, new_color[channel]].min
next if new_color == color
difference = ColorDifference.cie2000(color, new_color)
if max_difference.nil? || difference > max_difference
max_difference = difference
max_difference_colors = [color, new_color]
end
if min_difference.nil? || difference < min_difference
min_difference = difference
min_difference_colors = [color, new_color]
end
end
end
end
end
end
def format_float(number)
sprintf('%.15f', number).sub(/0+$/, '').sub(/\.$/, '.0')
end
puts "Max difference: #{format_float max_difference}"
puts "Colors: #{max_difference_colors.inspect}"
puts "------------------------------------"
puts "Min difference: #{format_float min_difference}"
puts "Colors: #{min_difference_colors.inspect}"
Max difference: 0.012461248722627
Colors: [{:r=>24, :g=>23, :b=>23}, {:r=>24, :g=>24, :b=>23}]
------------------------------------
Min difference: 0.000064328231603
Colors: [{:r=>0, :g=>255, :b=>255}, {:r=>1, :g=>255, :b=>255}]
I've included the colors below. The large blocks are the two adjacent colors with the biggest/smallest differences. The smaller blocks are what it looks like if I continue adding one to their respective color channels (green for the largest difference, and red for the smallest difference.)
Note: It's easier to see the largest difference against a black background.
Largest perceptual difference:
Smallest perceptual difference:
You can clearly see the top blocks becoming more green, while the bottom blocks all look like the same color. (I had to double-check my HTML code to be sure I hadn't made any mistakes!)
I can't even really tell the difference between rgb(0,255,255)
and rgb(30,255,255)
!
I have to go all the way up to rgb(120,255,255)
before I can really notice the difference.
(I'm not color blind! I did a test!)
So I think we now have enough information to answer the question: Do we need more HTML colors?
No, 256 possible values for each color channel is plenty. It's virtually impossible for a human to tell the difference between any two adjacent color codes.
]]>We're renting an old house that needs a lot of maintenance. The landlords are very easy-going
]]>We're renting an old house that needs a lot of maintenance. The landlords are very easy-going so we're allowed to have a dog and two cats. They also said we can pretty much do whatever we want to the house, so we've installed lots of home automation stuff, put up a garden shed, and hammered nails into the walls to put up pictures. We also take of the lawns and the garden and help to keep the place tidy.
"Tidy up the fence" had been on my todo list for a long time. There's a few marks and rusty nails, and it looks like someone had tried to paint a... smiley face?
I thought it would be nice to touch up the fence with a bit of paint. I guess the proper way to do it is to pressure wash the fence, sand it down, apply a coat of primer, then a coat of paint. I didn't want to do all of that since the fence is old and probably due to be replaced. I just wanted to paint over a few spots, so I needed to find a matching paint color.
I tried taking a small bit of painted wood to the hardware store. They have a computerized paint machine that can scan a color and mix some paint to match the color. Unfortunately this didn't work too well and the resulting paint was too dark. They said that my painted wood chip had a bit too much dirt and grime and it wasn't easy to clean it, so they couldn't get an accurate color.
I went over to the Resene color swatches and held up my paint flake. "Double Thorndon Cream" seemed like it was a good match, so I bought a small test pot. I also brought home a collection of 28 Resene color cards for white and neutral colors, just in case I needed a different color. (They were free!)
I held up the color swatches and double-checked that "Double Thorndon Cream" matched the fence. It seemed pretty close, so I tried it out.
Wait, what? Why is it so light? Maybe there's something wrong with the paint in the test pot. Even if it's a bit brighter when it's wet, I can't see how it will be the right color when it dries.
I took a picture and used the color picker tool in GIMP. I wasn't able to choose a single pixel since the wood has a lot of texture, so I checked the "Sample average" option and took the average color from a 50x50 square.
I also checked the color of the original paint:
I did some Googling and found an online "Delta-E calculator":
This tool can calculate the "perceptual distance" between two colors by using the Cie76 algorithm.
The difference between the original paint and the paint from my test pot is: 8.9811. Apparently that's quite a big difference. Humans can't tell the difference between colors if the difference is less than 1. That might be too hard to find, so I decided to aim for a difference of less than 2.
But how did I get it so wrong? Maybe I didn't mix the paint in the test pot well enough, or maybe it was a lot lighter than the swatch. So I checked the colors in GIMP.
rgb(201, 203, 199)
rgb(198, 203, 201)
The Delta-E difference between these two colors is only 1.5174. They're actually very similar colors.
So the paint does match the swatch. Maybe I shouldn't be relying on my eyes so much.
Anyway, now I know that the color swatch cards can be trusted. If the test paint matches it's corresponding swatch, then maybe I just need to find a swatch that matches the original paint. But I'm not going to rely on my eyes this time. I'm going to use the color picker and look at the Delta-E differences.
I took photos of all 28 swatches against the fence and went through all the colors one-by-one.
I found a color called "Double Parchment" that perfectly matched the paint. It was even the exact RGB value I was looking for: rgb(185, 186, 179)
. There was something very satisfying about finding a perfect match. (Although the color of the fence varies slightly, depending on where I measured it.)
I went back to the store to buy another test pot. Unfortunately they didn't have any small pots available, so I had to buy a slightly bigger one. No problem, I was pretty sure that I got it right this time.
Well that doesn't seem quite right.
You can see that I was getting a bit frustrated so I just went ahead and painted over all the graffiti anyway. But still want to figure this out, because I want to touch up some other parts of the fence and the house. If I manage to figure out the right color then maybe I'll paint over this section again.
I'll compare the new paint with the old paint and calculate percentage difference for each color channel. Then I'll apply that same percentage difference to the color swatch and look for a swatch that matches the darker color.
So I need to find a paint color that's about 91% as bright as Double Parchment.
I finally stumbled onto the Resene website, and realized that I had been doing everything wrong up until this point. Using the GIMP color picker for my swatch photos wasn't a very reliable process.
This looks a lot more promising! Now I can rely on some official RGB values for Resene Double Parchment. I just need to multiply them by around 91%, and hopefully this next color will be the right one.
They even have a search feature, so you can look for paint colors matching some specific RGB values:
I calculated the Delta-E differences for each color to see which one was the closest. Here are the results:
"Double Tea" was the closest match with a difference of only 1.312.
So maybe I'll go back to the hardware store tomorrow and buy another test pot.
I went outside to look at the fence again. The paint had dried. Turns out that "Double Parchment" was pretty close after all.
There's still some room for improvement, but I don't think it will be noticeable after I paint the rest of the boards in this section. The posts spaced every ~2 metres will help to hide the color difference, especially when the sun is hitting them and casting shadows.
If I ever need to color match some paint in the future, I might try using one of these ColorChecker charts:
Maybe I can hold this card against the wall and take a photo. Then I can use the chart to calibrate the photo and get a reliable RGB color for the wall. I could also hold up a ColorChecker chart against some Resene color swatch cards, and then calibrate them against the official RGB values from the Resene website.
I pressure washed the fence and painted a few more spots. I tried taking a timelapse video, but the sun is too bright and you can't really see any difference. Oh well.
It's close, but not really!
I used the color picker on this photo:
rgb(193.8, 195.8, 181.8)
rgb(181.4, 183.4, 171.4)
Differences:
I took the official RGB values for Resene Double Parchment from the website, and multipled the values by this ratio to find a slightly darker color.
Then I searched for this new color: rgb(186, 175, 154)
Akaroa looked promising. I picked up a test pot and tried covering up a few more rusty nails.
The color was perfect! I couldn't see any difference.
... as long as I didn't look at it from the side.
I forgotten to consider the "sheen", or high shiny the paint is.
Resene paints come in a few different gloss levels:
The test pot I tried was "made using Resene Lumbersider low sheen exterior and interior paint." It turns out that I needed a flat / matt paint with zero sheen.
I did some more research and saw that Resene has a "Lumbersider Matt" paint. I couldn't find any matt test pots for sale online, and it looks like Lumbersider Matt might not even be available in New Zealand. But I will go back to the Resene store on Monday and ask them about it.
Otherwise, I might need to start over with a different paint brand. Maybe Dulux or Wattyl.
I wanted to try Resene Lumbersider Matt paint, but they didn't have any test pots. The minimum quantity was a 4L can for ~$130, so I bit the bullet and bought it with the Akaroa color. I painted over the fence again, and it's a perfect match. It looks really good! I'll take a photo tomorrow.
]]>My wife is a counselor who does "play therapy" at a primary school. She has a sand tray and some toys that kids can play with during their sessions. Sometimes she asks me to 3D print things for the kids to play with. For example, I printed this little shovel for the sand tray:
One kid really likes trains, so I was asked to 3D print a toy steam train:
Another kid really likes pretending to make fried rice in the sand, so my wife asked if I could 3D print some plastic ingredients and a toy spatula.
I found a few 3D models:
The wok model was tricky. I used this tool to convert the OBJ to STL:
The resulting STL had some errors, so I used this tool to fix them:
I also added some basic shapes in Bambu Studio (spheres, cylinders, and cubes) to peas, bacon, omelette, and green onions.
Some of these small parts were quite difficult to print. I had to experiement with the support and raft settings, especially for the peas and corn. You can see that I still lost a few.
Here's the finished product:
I had a lot of fun making this. I hope they have fun playing with it!
]]>I bought it from the creator's online store:
The design is also open source and available on GitHub:
]]>I bought this awesome device that sends me notifications whenever we get a new letter or package in our mailbox.
I bought it from the creator's online store:
The design is also open source and available on GitHub:
They included STLs for a 3D printed case. I also designed a custom mailbox flap with embedded magnets. The flap opens whenever a letter is pushed into the mailbox. This triggers a reed switch that turns on the Mailbox Guard and sends a notification to the receiver.
I bought this LILYGO TTGO LoRa32 board to receive messages and send them to Home Assistant via MQTT.
I 3D printed a case for the receiver: TTGO Lora32 T3 Slimline Case on Printables
It turns out that most of our mailbox notifications are flyers and leaflets, and sometimes the wind. I will probably turn off the real-time notifications and just show the status on a dashboard somewhere.
I've noticed that LoRa is more reliable than some of my Zigbee devices, and has a much longer range. I might try designing some of my own LoRa devices in the future.
I would like to add a second reed switch on the main door of the mailbox, so that I can automatically reset the count to zero whenever we take the letters out of the mailbox. But I don't know if this is possible due to the design of the board.
I would also like to add some LoRa transmitters to our cars, so that I can automatically open and close our garage doors. I've already set this up with the Home Assistant mobile app for home presence detection, but sometimes there's a delay, or my wife is driving my car (or vice versa.)
]]>I find a lot of models on Thingiverse, Printables, and MakerWorld. I also design my own parts in Autodesk Fusion and OpenSCAD.
This page is where I log some of the things that I've 3D printed.
You
]]>I bought a Bambu Lab X1-Carbon 3D printer in March 2023.
I find a lot of models on Thingiverse, Printables, and MakerWorld. I also design my own parts in Autodesk Fusion and OpenSCAD.
This page is where I log some of the things that I've 3D printed.
You can find my OpenSCAD designs and STL files in this GitHub repo:
Getting some practice making props for short films, etc.
https://makerworld.com/en/models/610691#profileId-533802
We have a gate to keep our dog out of the kitchen and living room when we're away. She figured out how to push the gate over, so I printed these brackets to screw into the wall and make it much stronger.
Requested by a friend. This ended up taking 3 days since I kept having problems with the filament getting stuck.
I saw a tip on Reddit about using a lighter to tidy up the print, and it worked well for this one. I was able to quickly melt the very fine strands of plastic and smooth out the surface.
I bought a Zigbee motor from AliExpress to automate my blinds. It didn't fit my 50mm blinds tube so I designed my own adapter. This is the first time I designed something in Autodesk Fusion.
My cousin works for a company that supplies generators for events. They lost one of these generator caps and asked me if I could print a new one, since it's quite expensive to buy a replacement. I copied the design in OpenSCAD and printed it using ASA filament for strength and UV resistance.
This took a few attempts because there was significant warping with ASA. You can see the build plate jump up a little bit as the plastic cools and shrinks, but it was able to finish printing without any issues.
This print took 33 hours.
This my new favorite case design. It looks really cool and snaps together nicely.
My first big 3D printing project was to organize all the cables under my desk. I found some of these models on Thingiverse, and I also designed a few of my own things in OpenSCAD.
I printed and spray-painted this David bust to display on a shelf. I paused the print half way and filled it with pebbles to give it some weight.
I printed this duck, Crash Bandicoot, and Pikachu to get some practice with my airbrush. My printer can do multi-color prints using the AMS, but it takes a long time, wastes a lot of plastic, and doesn't always look very good. Another good option is to print all the parts separately and glue them together.
I bought a used Ubiquiti Switch that didn't come with any rack ears. I designed and printed these little brackets so that I could mount it in my server rack. The brackets prevent it from slipping out of the rack, but they are not strong enough to support the switch. It needs to be placed on top of another rack-mounted device for support.
I printed lots of organizers for coin cell batteries, AA, AAA, 9V, etc.
I printed this to try out "Spiral vase" mode, where it prints in one continous line (instead of printing one layer at a time.)
This machine can be used to wind filament onto a new spool.
Bambu Lab P1 / X1 / X1C / X1CC Filament Spool Switcher & Winder on Printables
I ended up using this for airbrushing.
I designed and printed these clips to hold an LED strip grow light.
I printed 8 of these for lights around our house. They look really nice.
I printed these adapters so that an existing light socket would fit into a new spherical glass lampshade.
This dock holder makes it a easier to take out my Nintendo Switch from the TV cabinet.
I use these to quickly reposition or remove a vise from my drill press.
This was designed for a chicken egg, but I scaled it up to fit an ostrich egg. Now my wife can display her ostrich egg on a shelf in her office.
My cousin asked me to fix this thing for his pool vacuum.
I designed some adapters for my shop vac so that I could extend the hose. I also printed adapters for my circular saw and cyclonic separator.
PLA was a bad choice. The tissue box started warping and the color pieces fell off when my wife parked her car in the sun. I might try printing this again using ASA filament (UV resistant.) I might also print the color pieces slightly smaller and super glue them (instead of hammering them in.)
I really like this Raspberry Pi case design.
I've printed lots of these cases for ESP-32s around my house running ESPresense.
QuinLED Dig Uno v3.1 on Printables
I designed this water bottle holder for my car in OpenSCAD.
The "Hello World" of 3D printing!
I haven't been able to write any blog posts since I got an M2 MacBook. I was using an old version of Hugo and got it running in a Docker container, but the Docker container only ran on my old Intel Mac. It was too painful to update my hugo theme to support the latest version, and I couldn't figure out how to get it to run on my new Mac. So I didn't write any blog posts for a while.
I was using Ghost for my company blog and I really loved the editor. It's so much nicer than editing Markdown files in VS Code, especially when it comes to embedding screenshot images and videos. I loved being able to take a screenshot and just drag it into my blog post, instead of messing around with image resizing, file paths, Markdown image syntax, etc. So I decided to set up a Ghost instance on my home Proxmox server.
I found this really helpful post on the Ghost Forum that helped me build an archive of all my old posts and import them into the Ghost database:
See my reply for the JS script that ended up (mostly) working for me. I still had to spend a few hours fixing minor issues, getting syntax highlighting to work, and converting some image slideshows to Ghost galleries.
You can run Ghost in production and use it to serve a blog dynamically, but I didn't want to open up my home server to the public internet. I also didn't want to give up all the benefits of a static site:
Some downsides:
I've turned off Ghost's subscription features and I'm using Disqus for comments.
I found a tool that can generate a static site from a Ghost blog:
I wrote a little script that will fetch all the HTML and assets, make a few changes and add a few things, commit the changes, and push to my GitHub pages repo.
#!/bin/bash
set -e
if ! [ -d "static" ]; then
git clone [email protected]:ndbroadbent/ndbroadbent.github.io.git static
git checkout gh-pages
fi
rm -rf static/*
node src/index.js --domain https://ghost.ndbroadbent.com --productionDomain https://madebynathan.com
# Replace all remaining instances of https://ghost.ndbroadbent.com with https://madebynathan.com in static files
grep -rl "https://ghost.ndbroadbent.com" static | xargs sed -i '' 's/https:\/\/ghost.ndbroadbent.com/https:\/\/madebynathan.com/g'
echo madebynathan.com > static/CNAME
cp pubkey_38E63C0A.txt static/
cp -R sudoblock static/
cd static || exit
git add .
git commit -m "Update static files"
git push origin gh-pages
I always like to use Cloudflare, even though GitHub pages already has a CDN:
Cloudflare provides a little more flexibility, so I can set up custom redirect rules, force SSL, etc. They also have a nice analytics dashboard.
I stopped using Google Analytics a while ago. Now I use Plausible.io for analytics on all of my websites. I use their hosted cloud platform for my blogs and personal sites, and I self-host my company instance on Render.
This blog post is my first real test run on my self-hosted Ghost instance, and I've really enjoyed it! It's such a game changer to have a WYSIWYG editor where I can drag-and-drop images. I love using Ghost as a headless CMS and generating a static site on GitHub pages + Cloudflare. I think it's the best of both worlds.
I'm excited to write some more blog posts about 3D printing, home automation, and all the other stuff I've been up to lately.
]]>You can use this PDF to make your own ring binder:
]]>The template code and generated PDF document are released
I used a ring binder and card sleeves to organize 1,700 through-hole resistors.
You can use this PDF to make your own ring binder:
The template code and generated PDF document are released under the MIT license. You can find a copy of the MIT license at the bottom of this page.
Resistors are a fundamental component in electronics. They are used to limit the current flowing through a circuit. Resistors have colored bands that represent their value. The first two bands represent the first two digits of the resistance, and the third band represents the "multiplier" value, or power of 10. For example, a 10KΩ resistor has a brown band, a black band, and an orange band. The first two bands are brown (1) and black (0), which is 10. The third band is orange (1,000Ω), so the resistance is 10 x 1,000 = 10,000Ω.
The "tolerance" value is the fourth band. This is the maximum deviation from the nominal resistance. For example, a 10KΩ resistor with a 5% tolerance can have a resistance between 9,500Ω and 10,500Ω.
The E24 series is a logarithmic series of 24 values for each power of 10: 1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1.
You can multiply each value in the series by the multiplier (power of 10) to get the 24 resistance values for each order of magnitude. For example, these are the first ten resistor values with a brown multiplier band (10Ω): 100Ω, 110Ω, 120Ω, 130Ω, 150Ω, 160Ω, 180Ω, 200Ω, 220Ω, 240Ω.
I bought a resistor pack that included 1,700 resistors in the E24 series, in sets of 10 (170 different values.) I bought 1/4 W carbon film resistors with a 5% tolerance.
It's very useful to have a wide range of resistors for breadboard circuits and prototype PCBs. It's not so useful when they're all mixed together in a single bag. The resistors I bought didn't have any labels or markings on the paper strips, so I had to read the colored bands or use a multimeter to find the resistance.
For my first attempt at organizing them, I sorted them by the multiplier band (0.1Ω, 1Ω, 10Ω, etc.), and put them in labeled drawers:
This didn't really help at all. I still needed to sort through 24 different values to find the one I was looking for. It got even worse once I started pulling out individual resistors to use in breadboard circuits. Instead of 24 sets of 10, I could have up to 240 individual resistors to sort through.
I had some spare card sleeves, and I realized that I could use these to create a 3x3 grid of pockets on an A4 ring binder sheet.
I used DocSpring to create the layout for all the pages. DocSpring is an API for filling out and generating PDFs. You can upload an existing PDF form, or create your own PDF templates using HTML and CSS. DocSpring's HTML/CSS templates support the Liquid template language, so I wrote some Liquid code to calculate the resistor values and generate all the pages for the E24 series.
(Disclaimer: I'm the founder of DocSpring.)
This template didn't need any fields, so I didn't need to use the DocSpring API. I just downloaded the generated PDF from the Preview tab.
I included a resistor graphic that shows the colored bands for each value. This was invaluable when I was sorting resistors into sleeves.
I used Sleeve Kings 63.5mm X 88mm Card Sleeves for the 3x3 grid of pockets.
I cut them to make them a little shorter, and stuck them onto ring binder sheets using a glue stick. Then I sorted all the resistors into sleeves, which felt like doing a jigsaw puzzle. It was a fun activity for a rainy Sunday afternoon.
I'm pretty happy with how this turned out, and I think my version is even better than the expensive ring binders I found for sale. The PDF and code are MIT licensed, so anyone is more than welcome to use this for personal or commercial purposes.
This ring binder system makes it much easier to see when I need to order more resistors. (I've got some more 330, 360, 1K, and 1.1K ohm resistors on the way!)
After publishing this blog post, I found out that you can buy card binder sheets that already come with 9 pockets.
You can purchase these on Amazon.
I found another option that has some flaps at the top of each pocket.
This would prevent the resistors from falling out if you drop the binder or tip it upside down. I'll probably use this option next time I need to organize electronic components. It would also be very handy for SD cards and USB sticks.
@impulse7 posted a comment on Hacker News where they shared their own solution to this problem. They created PDF labels to organize resistors in Raaco storage drawers. They have shared their PDF generation code on GitHub. This is a great option if you have plenty of space in your workshop.
If you want to skip all the work and just buy a pre-made ring binder, you can buy one from an electronics supplier such as RS Components. This will save a lot of time, but they can be quite expensive.
$504.52 New Zealand dollars = $323.72 USD
I found a few cheaper options but they were still hundreds of dollars. So I thought it would be fun to make my own ring binder.
P.S. Digi-Key's Resistor Color Code Calculator was very useful. It's a great tool for quickly looking up resistor values.
]]>Plex-Cleaner
is a Python script that can clean up your Plex directory by deleting movies and TV shows after you've watched them. This will stop your disk from filling up with lots of old media files over time. You can run this script on your server (or Raspberry]]>Plex-Cleaner
is a Python script that can clean up your Plex directory by deleting movies and TV shows after you've watched them. This will stop your disk from filling up with lots of old media files over time. You can run this script on your server (or Raspberry Pi, or wherever you run Plex Media Server.)
I like to put things in the /opt
directory on my servers.
Run git clone https://github.com/ndbroadbent/Plex-Cleaner.git /opt
Run python3 PlexCleaner.py --dump Cleaner.conf
to create a new configuration file
Configure an authentication token in Cleaner.conf
, under the "Token"
key.
Call python3 PlexCleaner.py
to test it out.
The script will run in test mode and won't delete anything if your Cleaner.conf
contains "test": true
, or if you call python3 PlexCleaner.py --test
.
"test": false
in Cleaner.conf
.You'll probably want to run this script regularly as a cron job. Run crontab -e
to edit your crontab, then add the following line to run the script every day at 4am:
0 4 * * * /usr/bin/python3 /opt/Plex-Cleaner/PlexCleaner.py
I always like to set up monitoring for any scheduled scripts so that I get a notification if when they stop working. healthchecks.io is my favorite monitoring tool and they have a generous free tier. (No affiliation, they're just an awesome service.)
To set up monitoring with healthchecks.io, you can call the run_plex_cleaner.sh
script from my fork. This script will ping healthchecks.io on success or failure. healthchecks.io will also send you a notification if it doesn't receive any ping at the expected time (e.g. if your server has been turned off.)
0 4 * * *
.healthchecksio_id
file in the Plex-Cleaner
directoryCleaner.conf
so that it writes logs to a file:"LogFile": "/opt/Plex-Cleaner/plexcleaner.log",
0 4 * * * /opt/Plex-Cleaner/run_plex_cleaner.sh
Now you'll get an email alert whenever something goes wrong:
plexcleaner.log
log file contains any ERROR
entriesSATA and SAS use very similar connectors, but a SATA connector has a gap in the middle. This means that you can physically plug a SATA drive into a SAS connector, but you can't plug a SAS drive into a SATA controller (because it won't
]]>SATA and SAS use very similar connectors, but a SATA connector has a gap in the middle. This means that you can physically plug a SATA drive into a SAS connector, but you can't plug a SAS drive into a SATA controller (because it won't fit.) SAS controller software can support SATA drives, but SATA controllers don't support SAS drives (even if you have an adapter.)
I was running Home Assistant and Plex Media Server on a Raspberry Pi 4 Model B. I kept adding more and more Home Assistant add-ons (which run in Docker containers), so it started to get a bit slow. It took a long time to restart Home Assistant, and we started to notice some speed and reliability issues.
I already had a server rack in my closet, so I wanted to get a proper server to put in it. I didn't need anything too fancy. It just needed to be a little bit faster than a Raspberry Pi, so I found a 10 year old IBM server for $249 NZD ($160 USD.) I found it on TradeMe, which is similar to eBay in New Zealand.
The new server has been working great, and Home Assistant is noticeably faster. The 10-year-old Intel Xeon E3-1270v2 CPU has a CPU Mark benchmark score of 6429, which is 8x better than the Broadcom BCM2711 processor in a Raspberry Pi 4B (834.)
The only problem is that the server came with a 320GB SAS hard-drive. It was a bit too small, and it made a lot of clicking noises. I wanted to replace it with a 1TB SATA SSD, which would be faster and silent. I just wasn't sure if my old server would be compatible with a modern SATA SSD.
I did a bit of research, and it seemed like it would work, so I bought a new Samsung 870 EVO 1TB SSD. It was the same size and had the same screw holes as the old 2.5" SAS drive, so I was able to swap the drives and use the same drive bracket. I put in the new drive and installed Debian 11 (with LVM), and everything worked great!
Conclusion: The latest Samsung SATA SSDs are still compatible with SAS controllers in servers that were made in 2012.
]]>favicon.ico
file for your website or blog. Things have changed a bit since I wrote that blog post in May 2010.
I've been updating the CSS for my blog recently, and I
]]>It's been a while since I wrote a blog post about creating a favicon.ico
file for your website or blog. Things have changed a bit since I wrote that blog post in May 2010.
I've been updating the CSS for my blog recently, and I wanted to update the favicon. Here's the old green square icon that I was using before:
I wanted something a bit more interesting, so I tried using some of the new text-to-image AI tools that have been getting a lot of attention lately. I used Midjourney and DALL·E 2. (Midjourney uses Stable Diffusion.)
I played around with some different prompts in Midjourney and DALL·E 2, and I iterated on a few different ideas. I enjoy spending time in Midjourney's shared Discord channels (e.g. #general-*
), where you can see what other people are doing and get some inspiration for prompts.
Here's a few examples of the prompts that I was trying:
website favicon logo, circuit board PCB design, vector, SVG, blue purple gradient, hexagon, bolt and tools icon
small favicon logo for a blog website, circuit board pattern, electronics, vector, epic ultra wide aerial shot from atmosphere, cool gradients, ultra high contrast, blue background, psychedelic color, vortex, hyperrealism, intricate details, cinematic lighting
Here's some of the images that I generated using DALL·E 2:
And here's some from Midjourney:
I eventually found some shapes and colors that looked pretty cool, so I generated some variations using the Midjourney Discord Bot.
Eventually I settled on this one. It kind of looks like an abstract "N". I tweaked the colors and contrast a little bit in GIMP.
I used realfavicongenerator.net to generate a favicon package with lots of different sizes and (mostly unnecessary) features.
They provide this HTML to include in my <head>
tag:
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
<meta name="msapplication-TileColor" content="#603cba" />
<meta name="theme-color" content="#ffffff" />
So here's the new favicon:
P.S. Here's one I didn't end up using, in case you want it:
(wetbectolon.com is available!)
]]>