Category: Uncategorized

  • Kitchenaid kDTM404ESS3 diverter diagnostics

    How to test the diverter motor (no disassembly yet). The diverter’s job is to switch water flow between:

    • Lower spray arm
    • Middle arm
    • Upper arm
    • Sometimes a dedicated zone

    If the lower arm never moves, the diverter is the prime suspect.

    You can confirm it without removing anything.


    Test 1: Door-open rotation check (most important)

    Goal: See if the diverter ever sends water to the lower arm.

    1. Start a normal wash cycle with dishes removed.
    2. Let it run 3 minutes.
    3. Open the door quickly (don’t wait for pump to ramp down).
    4. Look at the position of the lower spray arm.
    5. Close the door and let it run another 4 minutes.
    6. Open again and check the arm position.

    Interpretation:

    • If arm never changes position at ANY time: Diverter is stuck in one zone (typically upper arm).
    • If arm moves at least once: Diverter is functioning at least partially. Fault may be pump, filter, or pressure related.
    • If movement is random but weak: Diverter may be slipping internally (gear partially stripped).

    For a definite diverter failure, you’ll see upper arm spraying strongly, lower arm not at all, and static lower arm across multiple checks.


    Test 2: Listen for diverter rotation

    The diverter motor “indexes” at set intervals. You can hear it.

    What to do:

    1. Start a cycle.
    2. Stand in front of the dishwasher during the first 10 minutes.
    3. You should hear a faint:
      • click-click
      • whirr
      • short hum for 3 seconds

    If you hear nothing — especially no periodic hum — the diverter motor is not being driven or is mechanically jammed.

    If you hear repetitive ticking, the diverter is trying and the internal gear is stripped (common for this generation).


    Test 3: Real water-pressure test (tells you 100 percent if the diverter is indexing)

    Do this with a cup or small glass.

    1. Start a cycle.
    2. After 3 minutes, open the door.
    3. Observe which spray arm is wet and dripping:
      • If upper arm only is wet: diverter is stuck in upper zone.
      • If lower arm never gets wet after multiple openings: diverter jammed.
      • If sometimes middle arm gets wet, sometimes upper, but never lower: partial indexing failure.

    How it actually went down:

    My KitchenAid dishwasher has been a solid, quiet, low-maintenance unit for about eight years, but this is now the second major part to fail.

    The first failure was four years ago when the self-cleaning pump mesh tore apart. The extended warranty covered everything, and I definitely got my money’s worth.

    This time the diverter assembly died. The diverter controls where the water goes. Top, middle, or bottom spray arms.

    I ran the symptoms through ChatGPT, followed its diagnostic checklist, and it pointed straight at the diverter motor.

    Steps:

    • Power off at the breaker
    • Remove racks and spray arms
    • Disconnect supply line
    • Pull out dishwasher
    • Replace diverter assembly
    • Reassemble everything

    After putting it back together I spotted a slow drip on the old supply line. It was eight years old anyway, so I grabbed a new one from Home Depot.

    Back home, I pulled the dishwasher out again, swapped the line, levelled it, and started reassembling. Then I dropped the tiny washer from the supply line underneath the unit. Metal coat hanger to the rescue. Fished it out, reattached the line, and verified no leaks.

    Breaker on. Test cycle running. Open after two minutes. Lower spray arm not moving. Wait a few more minutes, open again. It moved. Problem solved.

    Levelled the unit one last time and put the trim back in place.

    The garbage pile is now one dead diverter assembly and one old supply line.

    Total cost was about two hundred twenty five dollars plus tax for parts. A technician would have likely charged two hours of labour on top.

  • Revisiting My Home Backup Strategy (2025 Edition)

    After tax season wrapped up, I found myself revisiting my home backup strategy. Years ago, I came across the classic 3-2-1 backup rule:

    • 3 copies of your data
    • 2 different types of media
    • 1 stored offsite

    It’s a solid rule of thumb—simple, memorable, and effective against data loss due to drive failure, theft, ransomware, or natural disaster.

    What I’ve Been Using

    Until recently, my setup looked something like this:

    • Apple Time Machine backing up my MacBook Pro to a local network volume (a Raspberry Pi with a 12TB external HDD).
    • iCloud syncing photos and files from all our iOS devices.

    This setup technically gets me close to 3-2-1:

    • Local copy (Mac)
    • Local backup (Time Machine)
    • Offsite-ish (iCloud)

    But it’s not perfect. I don’t control the iCloud ecosystem. It’s convenient, but it’s not self-owned. And I want more automation, more control, and long-term durability—especially for things like tax files, client work, and personal documents.

    The New Workflow

    I’m keeping Time Machine and iCloud because they’re seamless. But I’ve added a parallel system that gives me full control:

    1. Syncthing

    All my devices (Windows, Linux, macOS) run Syncthing, a decentralized, open-source peer-to-peer file synchronization system. My Documents folders stay automatically in sync—real-time mirroring across platforms.

    2. BorgBackup

    My Raspberry Pi runs Borg to back up synced documents (and other important data). Borg is efficient:

    • Deduplication: Reuses unchanged data blocks
    • Compression: Saves space
    • Encryption: Keeps it secure at rest

    Borg creates snapshot-style backups—each backup is a full view of your files at that point in time, but under the hood, only new or changed data is stored. This makes it incredibly efficient for both disk space and bandwidth.

    3. AWS Glacier Deep Archive

    Once a week, the RPi rsyncs the latest Borg backups to AWS S3 Glacier Deep Archive. The cost?

    Roughly $1/TB/month, so even backing up multiple GBs of documents and compressed photos comes to $12/year. That gives me true offsite, low-cost cold storage.

    Result

    • ✅ Windows, Linux, macOS files are all synced and backed up locally and offsite
    • ✅ iOS photos are synced to iCloud and back down to my MBP, which flows into Syncthing → Borg → Glacier
    • ✅ My documents are versioned, deduplicated, encrypted, and geo-redundant

    Comparing Backup Types

    Let’s clarify backup semantics:

    • Traditional backup: Full copies or incremental changes. Often slow and storage-hungry.
    • Time Machine: Apple’s versioned backup. Great for end-users but opaque and not portable.
    • Borg: Snapshot-based, deduplicating, efficient. Transparent, portable, scriptable.
    • Syncthing: Real-time syncing, not a backup per se—but fantastic for redundancy and protection against single-node loss.

    This setup gives me full ownership, control, and visibility—without giving up the convenience of Apple’s ecosystem. Best of both worlds.

  • Self-Hosting Headscale + Tailscale: Secure Access to Your Home Network via EC2

    Most developers and homelab enthusiasts want secure, zero-config access to their home network from anywhere—without exposing ports or struggling with dynamic DNS. Tailscale offers this using WireGuard and NAT traversal, but for privacy, control, or cost reasons, you might prefer to self-host your coordination server.

    This post walks through:

    1. Deploying Headscale (the open-source Tailscale coordination server) in Docker on AWS EC2
    2. Connecting devices (Mac, Windows, iOS, Raspberry Pi, etc.)
    3. Accessing your home LAN securely by advertising and enabling subnet routes

    Why Tailscale?

    Tailscale creates a secure, encrypted mesh network between your devices. Each device gets a unique IP in the 100.x.y.z range and can directly communicate with others, bypassing NAT, firewalls, and even CG-NAT. Key benefits:

    • Zero port forwarding
    • Single sign-on and ACLs
    • Cross-platform clients
    • MagicDNS for easy name resolution
    • Optional exit nodes and subnet routes

    However, using Tailscale.com means trusting a third-party control plane. That’s where Headscale comes in.


    (1) Docker-Based Headscale on EC2

    Assuming you’re comfortable with SSH, Docker, and DNS:

    Prerequisites

    • EC2 instance (Ubuntu 22.04 or 24.04 preferred)
    • Domain/subdomain pointing to your instance (e.g., headscale.example.com)
    • Docker and Docker Compose
    • Basic UFW firewall rules allowing ports 80, 443, 3478/udp, and 41641/udp

    Docker Compose Example

    services:
      headscale:
        image: headscale/headscale:latest
        container_name: headscale
        restart: always
        ports:
          - "8080:8080"         # Headscale web API
        volumes:
          - ./config:/etc/headscale
          - ./data:/var/lib/headscale
        command: headscale serve

    Above, also assumes you know how to reverse proxy tailscale. Such as caddy.

    Initialize Headscale:

    docker exec headscale headscale users create <user>
    docker exec headscale headscale preauthkeys create --reusable --expiration 24h

    <user> is the user you’re creating.

    Use the output URL (or tailscale up –login-server) to connect clients.


    (2) Installing Clients on Devices

    macOS / Linux / Windows

    Install the official Tailscale client, then run:

    tailscale up --login-server https://headscale.example.com

    iOS / Android

    Install the app, then visit the /register URL from Headscale to authenticate. You can also generate a reusable key with –ephemeral for IoT-style devices.

    Raspberry Pi

    Install via:

    curl -fsSL https://tailscale.com/install.sh | sh
    sudo tailscale up --login-server https://headscale.example.com \
      --advertise-routes=192.168.0.0/24 \
      --accept-routes

    This advertises your home subnet to the Tailscale network.


    (3) Enabling Subnet Routes to Your LAN

    After advertising the subnet, you’ll need to enable it manually via Headscale:

    docker exec headscale headscale routes list
    # Note the ID for the route, e.g., 1
    
    docker exec headscale headscale routes enable --route 1

    Now all devices on your Tailscale network can access your local network (e.g., 192.168.0.x) via your Pi.

    Make sure IP forwarding is enabled and iptables/nftables allows routing:

    echo 1 > /proc/sys/net/ipv4/ip_forward

    Use a systemd script or rc.local to persist this change across reboots.


    Final Thoughts

    Using Tailscale with Headscale gives you:

    • Private WireGuard-based networking
    • Access to all your devices, including those behind CG-NAT
    • Control over coordination with no third-party dependency
    • Subnet routing, acting like a VPN into your LAN

    You maintain complete control of authentication, ACLs, and key expiration—ideal for those who want privacy and flexibility.

    Whether you’re backing up photos from your phone to your NAS, administering a Docker swarm, or checking on a security cam, this is one of the cleanest ways to securely bridge multiple networks.

  • Tax Season, Procrastination, and the AI That Saved My Sanity

    It’s tax season… and even though I’ve technically been “paperless” for a while, my actual document management? Yeah—let’s just say it hasn’t kept up. 😅

    While procrastinating (YouTube rabbit hole, naturally), I stumbled across a video about Paperless-ngx—a document management system that supposedly auto-tags your docs based on heuristics (aka smart guesses). Intrigued, I gave it a spin on about 150-200 documents.

    Verdict? Cool idea, but… not quite smart enough.

    So, I did what I do best—asked ChatGPT what was missing. Turns out, there’s a powerful little sidekick: Paperless-AI. It plugs into Paperless-ngx and uses local AI to handle the actual smarts.

    Fast-forward: I spun it all up using Docker and Ollama (a self-hosted LLaMA 3.2 AI model). And now? It’s chewing through my documents like a beast.

    The setup?

    • Drop documents into a watch folder (or pull them from my email).
    • They get OCR’d, parsed, and passed through local AI.
    • Paperless-AI auto-generates context, titles, tags, keywords, and even figures out the sender (correspondents).
    • Everything gets backed up to the cloud, too.

    Honestly… this is the doc management system I’ve always wanted. Private, automated, organized, and blazing fast.

    What more could I ask for?

  • Kickstarting Your IoT Project with ESP8266 or ESP32: A Step-by-Step Guide

    The ESP8266 and ESP32 are among the most popular microcontrollers for Internet of Things (IoT) projects. Their robust Wi-Fi capabilities, versatility, and affordability make them perfect for creating smart home devices that can integrate seamlessly with platforms like Home Assistant and Alexa. This post walks you through starting a project to develop a smart IR remote using one of these devices, with the potential to expand functionality down the line.

    Project Overview

    Your project’s goal is to create a device capable of:

    1. Receiving IR signals for recording—to learn commands from existing remotes.
    2. Emitting IR signals—to control devices like TVs, air conditioners, or media players.
    3. Integration with Home Assistant and Alexa—to make the remote voice controllable and part of your smart home ecosystem.

    Stretch Goals:

    • Add MQTT for lightweight messaging.
    • Support macros for complex sequences (e.g., changing TV input reliably from any state).
    • Implement HTTPS for secure local communication.
    • Design and 3D print a custom case for your device.

    Let’s dive into the details.


    Step 1: Gather Your Tools and Components

    Here’s what you’ll need to start:

    • ESP8266 or ESP32 module (e.g., NodeMCU, Wemos D1 Mini, or ESP32 DevKit).
    • IR receiver module (e.g., VS1838B or TSOP38238).
    • IR LED for sending signals.
    • Resistors (220Ω or as specified for your IR LED).
    • Breadboard and jumper wires for prototyping.
    • USB cable for programming the ESP board.
    • 3D printer (optional, for the case).

    You’ll also need a computer with the Arduino IDE installed or another ESP-compatible programming environment like PlatformIO.


    Step 2: Set Up the Development Environment

    1. Install Arduino IDE: Download and install the Arduino IDE from Arduino’s website.
    2. Add ESP8266/ESP32 Board Support: Open the Arduino IDE, go to File > Preferences, and add the appropriate board URL:
      • ESP8266: http://arduino.esp8266.com/stable/package_esp8266com_index.json
      • ESP32: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
      Then, go to Tools > Board > Boards Manager and install the necessary board package.
    3. Install Required Libraries: Install libraries like IRremoteESP8266, ESPAsyncWebServer (for web interfaces), and ArduinoJSON (for Home Assistant integration).

    Step 3: Build the Circuit

    1. Connect the IR Receiver:
      • Connect the IR receiver’s data pin to a GPIO pin on the ESP board (e.g., D2 on ESP8266 or GPIO22 on ESP32).
      • Connect the VCC and GND pins to 3.3V and GND, respectively.
    2. Connect the IR LED:
      • Connect the anode (+) of the IR LED to a GPIO pin via a 220Ω resistor.
      • Connect the cathode (-) to GND.
    3. Power the Circuit: Use a USB cable to connect the ESP board to your computer or a power source.

    Step 4: Program the Device

    1. Record IR Signals: Use the IRrecv functionality from the IRremoteESP8266 library to decode and record signals from existing remotes. Example code snippet: #include <IRrecv.h> #include <IRutils.h> const uint16_t kRecvPin = D2; IRrecv irrecv(kRecvPin); decode_results results; void setup() { Serial.begin(115200); irrecv.enableIRIn(); // Start the receiver } void loop() { if (irrecv.decode(&results)) { Serial.println(resultToHumanReadableBasic(&results)); irrecv.resume(); // Receive the next value } }
    2. Send IR Signals: Use the IRsend functionality to emit signals. Example snippet: #include <IRsend.h> const uint16_t kIrLedPin = D1; IRsend irsend(kIrLedPin); void setup() { irsend.begin(); } void loop() { irsend.sendNEC(0x20DF10EF, 32); // Example NEC signal delay(5000); // Wait 5 seconds before sending again }
    3. Integrate with Home Assistant: Use an HTTP server or MQTT to communicate with Home Assistant. Define services in Home Assistant to map IR commands to specific actions.

    Step 5: Test and Debug

    • Verify the IR receiver correctly records signals by checking the serial output.
    • Test the IR LED by sending commands to your device.
    • Integrate the device with Home Assistant or Alexa to ensure seamless control.

    Stretch Goals Implementation

    1. Add MQTT: Use the PubSubClient library to add MQTT communication for a lightweight, reliable messaging system.
    2. Program Macros: Write code that executes a sequence of IR commands with delays and conditions.
    3. Enable HTTPS Support: Use the WiFiClientSecure library to secure local web communication.
    4. 3D Printed Case: Design a case using software like Tinkercad or Fusion 360 and print it using a 3D printer. Make cutouts for the IR LED, receiver, and power cable.

    Final Thoughts

    Building a smart IR remote with the ESP8266 or ESP32 is a rewarding project that brings convenience and customization to your smart home setup. You can create a polished, multifunctional device by starting with a minimal viable product (MVP) and iterating toward your stretch goals. Dive in, experiment, and enjoy the process of building your own IoT gadget!

  • Step-by-Step Guide to Enabling IPv6 on Your Network with Cogeco ISP and UniFi

    In today’s rapidly expanding digital landscape, IPv6 is becoming increasingly critical for ensuring efficient and secure internet connectivity. Whether you’re managing a small home network or administering the infrastructure for a small business, making the transition to IPv6 can significantly improve your network’s scalability and performance. For Cogeco ISP users with UniFi networking equipment, enabling IPv6 is a straightforward process. Here’s a step-by-step guide to get you started.

    Step 1: Access WAN Settings to Enable DHCPv6

    Your first step involves accessing the WAN (Wide Area Network) settings within your UniFi Controller. This is where you’ll enable DHCPv6, which is crucial for your network to communicate over IPv6.

    1. Login to UniFi Controller: Open your browser and enter the IP address of your UniFi Controller. Log in with your credentials.
    2. Navigate to Settings: Once logged in, look for the ‘Settings’ option in the left-hand menu and click on it.
    3. Access WAN Settings: Inside the Settings menu, find the ‘Networks’ section and select the WAN network you wish to configure.
    4. Enable DHCPv6: In the WAN network settings, look for the IPv6 Configuration section. Here, you’ll find an option to enable DHCPv6. Make sure to select it.

    Step 2: Set the Delegation Size to 56

    Setting the correct delegation size is essential for the proper distribution of IPv6 addresses within your network.

    1. Find the IPv6 Configuration: Still within the WAN settings, locate the IPv6 Configuration section if you’re not already there.
    2. Adjust the Delegation Size: You should see an option for ‘Delegation Size’. Set this to 56. This size is typically recommended for most home and small business networks, allowing for a large number of subnets without overcomplicating your network structure.

    Step 3: Configure LAN Network with IPv6 Prefix Delegation

    The final step involves setting up your LAN (Local Area Network) to utilize the IPv6 prefix delegation effectively, ensuring devices on your network can obtain IPv6 addresses.

    1. Navigate to LAN Settings: Go back to the ‘Networks’ section in your UniFi Controller settings, but this time, select your LAN network.
    2. Enable IPv6: Look for an option to configure IPv6. Ensure it’s enabled.
    3. Set Prefix Delegation: Within the IPv6 configuration for your LAN, you should see an option for ‘Prefix Delegation’. Enter the IPv6 prefix that was delegated to your WAN. This step is crucial as it tells your network how to distribute IPv6 addresses to connected devices.

    Conclusion

    By following these steps, you’ve successfully configured your network to support IPv6, leveraging the capabilities of both Cogeco ISP and UniFi networking equipment. This setup not only prepares your network for the future of internet connectivity but also enhances its security and efficiency.

    IPv6 is the backbone of the next-generation internet, enabling countless devices to connect seamlessly and securely. As the world continues to move towards this newer protocol, ensuring your network is IPv6-ready is more important than ever. With this guide, you’re well on your way to making the most out of your internet connection, embracing the vast possibilities of IPv6.

  • Repurposing an Old Apple 1A/5V Charger for the Ratgdo 2.51i: A Reliable Power Solution

    Are you looking for an efficient way to power your Ratgdo 2.51i? Well, I’ve discovered a handy trick that not only works reliably but also gives a new lease of life to an old gadget lying around in your drawer.

    Recently, I ventured into uncharted territory with my Ratgdo 2.51i. I was in search of a power solution that was both efficient and readily available. Surprisingly, I didn’t find much information online, but through some experimentation, I stumbled upon a fantastic solution.

    I realized that an old Apple 1A/5V phone charger, which was collecting dust in my tech drawer, could be repurposed to power the Ratgdo 2.51i. To my delight, this setup has proven to be not just a makeshift arrangement but a reliable and consistent power source for the device.

    This discovery is particularly exciting for a couple of reasons. First, it’s a great way to recycle those ‘wall warts’ – you know, those old chargers that you no longer use because you’ve upgraded your phone. Second, it’s a cost-effective solution, saving you the trouble and expense of purchasing a new power adapter specifically for the Ratgdo 2.51i.

    Moreover, this approach aligns perfectly with the growing trend of repurposing and recycling electronic components. It’s a small step, but it contributes to reducing e-waste and promotes a more sustainable approach to our ever-growing collection of tech gadgets.

    So, if you have an old Apple 1A/5V charger lying around and a Ratgdo 2.51i that needs powering, give this method a try. It’s simple, efficient, and a smart way to reuse and repurpose what you already have.

    Remember, innovations in tech don’t always have to be about the latest and greatest. Sometimes, it’s the small hacks and creative uses of what we already own that can make a significant impact. Keep experimenting and finding new ways to make the most out of your tech gadgets!
  • Automation tasks MAC

    I’m old school. I love the scheduling service crontab.

    0 4 * * * /opt/homebrew/bin/brew update > /dev/null 2>&1
    0 4 * * * /opt/homebrew/bin/brew autoremove > /dev/null 2>&1

    meaning, I run $> brew update every day at 4am, as well as $> brew autoremove, to prune anything Brew feels is not needed. — Have yet to have an issue.

    I am not going to $> brew autoupdate, but at least I’ll be primed and ready to update, if needed.

  • Ubiquiti migration from USG Pro v4 to UDM SE

    Requirements:

    • Ethernet connection to your UDM

    Fresh install instructions:

    1. Connect your new UDM SE Port Wan 1 to a port on USG (Lan side).
    2. Let UDM SE boot up.
    3. From your original USG Pro V4 Drop/forget all Ubiqiuti devices (switches/AP/etc). This will allow you to adopt them
    4. Unplug Ubiquiti devices and plug into UDM SE
    5. Connect your computer/laptop to UDM via ethernet
    6. Adopt old devices
    7. Setup you wifi

    If you don’t forget/drop the original devices, you’re going to need to do a factory reset. Reset button for 10 seconds. On APs, wait for the LED to flash. May want to unplug and plug back in the POE ethernet.

    Switches, just hold down for 10 seconds.

    Remember your old wifi names and passwords. Very simple adoption/setup.

  • phpstorm unable to establish connection with xdebug

    I recently reinstalled PHP, and noticed that xdebug would not work from within phpstorm.

    Getting the message “Connection was not establish”.

    Connection was not established. Cannot start debugger session with ‘Xdebug 3.2.0’

    The way to fix that, was just to ensure that we’re using the proper port.

    Xdebug 3.x, uses port 9003. Where as Xdebug 2.x used 9000.

    To fix this, change your phpStorm preferences for the listening port to 9003.

    PhpStorm -> Settings -> PHP -> debug -> port and set to 9003.

    Debug port: 9003