Categories
Engineering Software

Sale Monitor

I got tired of manually checking prices on things I was watching. Price tracking services exist, but they’re limited to specific retailers, don’t let you define your own alert rules, and you have no control over your data. I wanted something self-hosted that could monitor any product on any site, track history, and notify me across multiple channels when a deal hits.

What started as a simple script to scrape prices and send an email turned into a full application with a web dashboard, multi-currency support, product grouping for cross-retailer comparison, and purchase tracking to quantify actual savings.

Dashboard page

How It Works

The core loop is straightforward: a background process checks product pages on a schedule, extracts the price using either a user-defined CSS selector or auto-detection (60+ built-in selectors for major retailers), converts to a base currency, and stores the result in SQLite. When a price triggers an alert rule, notifications go out over email, Discord, or Slack.

The web dashboard is where most of the interaction happens. Products are displayed in a sortable table or card grid with live price data, trend indicators, and quick actions. Each product has a detail page with an interactive price history chart and statistics. Products selling the same item across different retailers are automatically grouped using identifiers extracted from the page (MPN, SKU, GTIN), so you can compare pricing across vendors at a glance.

Product detail page

Alert Rules

There are five configurable alert types per product, which can be combined:

  • Target price – triggers when the price drops to or below a set amount
  • Discount threshold – triggers on a percentage drop from the last known price
  • Price drop – any decrease from the previous check
  • Below average – price falls under the 30-day rolling average
  • Any change – notifies on any price movement, up or down

Each product has its own notification cooldown to prevent spam, and can override the default notification channels.

Features

  • Dark-themed responsive dashboard with table and card views
  • Interactive price history charts with selectable time ranges (7d to all-time)
  • Auto-detection of prices on 60+ retailer platforms (Amazon, Best Buy, Shopify, WooCommerce, etc.)
  • Multi-currency support with automatic conversion and cached exchange rates
  • Product grouping and cross-retailer price comparison
  • Purchase tracking with savings calculation
  • Failure diagnostics page with per-product extraction health metrics
  • Bulk CSV import/export
  • Browser bookmarklet for identifying price selectors on any page
  • Optional API key authentication and rate limiting

Tech Stack

  • Backend: Python, Flask, Gunicorn
  • Storage: SQLite with WAL mode for concurrent reads/writes
  • Frontend: Jinja2 templates, Tailwind CSS, Chart.js
  • Notifications: SMTP (with retry), Discord webhooks, Slack webhooks
  • Deployment: Docker with supervisord managing the web server and monitor process
  • Hosting: Self-hosted

The price extraction runs in a thread pool (4 workers) for parallel checks. SQLite’s WAL mode lets the web dashboard serve reads while the background monitor writes new data without locking. Schema changes are handled through versioned migrations.

What I Learned

Building the auto-detection was the most interesting challenge. Every retailer structures their pricing differently, and even sites on the same platform (Shopify, WooCommerce) have variations. The approach I settled on is a priority chain: try the user’s custom selector first, then platform-specific selectors, then generic fallbacks. Currency detection follows a similar pattern – JSON-LD first, meta tags, platform-specific data attributes, then fall back to configured defaults.

Product grouping was another area that required more thought than expected. Matching products across retailers by name is unreliable, but standardized identifiers (MPN, GTIN) extracted from structured data on the page work well. The system uses a three-tier matching strategy: explicit user-defined groups take priority, then manually assigned keys, then auto-detected identifiers.

Categories
Engineering Software

Computer Vision Based Object Detection

This project was a machine-vision proof of concept delivered to a large multinational commodity distribution company in Western Canada. The company had recently implemented an automated railcar unloading system, and this POC aimed to demonstrate how a machine-learning–based object detection solution could augment the existing system by accurately identifying, localising and determining the orientation of capstan sockets on incoming train cars.

Traditional vision-based automation struggled due to the variability in railcar geometry, capstan designs, lighting conditions, debris and other environmental factors. The goal of the POC was to show that a well-trained machine learning model could outperform these legacy methods – delivering high accuracy, low latency and a clean, structured data stream suitable for real-time integration into the existing control system.

The existing system had acquisition times exceeding 1 second and a success rate below 80%. For the POC, still images and video of multiple capstan types were captured, labelled and used to train a custom model. The resulting model successfully detected capstans on 100% of the validation set with confidence levels consistently above 85% and was able to infer both location and rotation. When evaluated on live video, it achieved acquisition times under 25 ms with zero false positives on surrounding train structures.

Categories
Engineering Software

Garmin Wearable Cold Plunge App

I frequent a local cold plunge therapy venue with my girlfriend and wanted a way to effectively time each phase of the process. The solutions on the market didn’t fit my requirements, nor did using a basing timer, or no timer, so I decided to make my own.

I thought it’d be a nice weekend project, but I was quick to learn that it was going to involve learning a new platform, language and a very finicky UI design to be effective across multiple devices/resolutions, etc. Garmin uses their own language “Monkey C”, which is an object-oriented language, most similar to JavaScript. It ended up taking a couple months to get together, including testing.

The initial design consists of 3 timers, one for each phase – hot, cold and rest. Each is customisable for your desired duration and level of suffering. The app also tracks the users heart rate, temperature and saves the activity for later review in Garmin Connect.

There are additoinal features to be added to the app over time, given user feedback and from my own experience using the app. So far, it is exactly what I would’ve wanted in a cold plunge app, but let’s see what the community says.

Link to Garmin IQ Store – Cold Plunge App

Categories
Engineering Mechanical design

Trainer Table V2

After selling on Etsy for a while (tables have been selling like hot-cakes!) I had received some good feedback from customers, friends and from my own use. I have since integrated several modifications to improve the table and released a new version.

The table is now 22% larger and features a phone holding slot. See below for pics! I also now offer the table with different configurations including a power outlet on the left and no power outlet at all, for a slightly lower cost.

Now available on my store at aptdesign.io.

Categories
Engineering Mechanical design

Bike Trainer Table

I was on the search for a table to use when training indoors, but found that all tables on the market weren’t only expensive, but also didn’t meet all my requirements.

I wanted something that could support either iPad or laptop, would be able charge either device, featured a towel and drink holder.

Given this, I decided to design and manufacture my own!

The table is made from 3D printed PLA and the legs from birch. The table is fully modular and features tool-less assembly.

Categories
Engineering

Concealed Bike AirTag holder

I recently needed to travel internationally with my bike to an Ironman event and figured it’d be a good idea to fit by bike with an AirTag so that I could track it, in case there was any logistics issues and for a little bit of added security.

I designed and 3D printed a holder to fit within the seat post of the bike, which slides into the bike seat tube and remains concealed. There was an option of fixing the tag to the inside of the frame using an adhesive, however the tag requires its batteries to be replaced every ~12 months, so the requirement to be able to remove (easily enough) had to be inherent in the design.

There are a number of commercially available AirTag holders that fit below the seat, or under bottle cages, but given my bike geometry and decreased security, I decided to design my own. The AirTag is still able to tx/rx through the carbon frame and works well!

Categories
Engineering Le clock of clocks

June ’23 Update

Since my last post, I had decided to sign up to compete in an Ironman. Training is coming along well and I’ll be racing in Penticton, B.C. this August. This is obviously taking most of my time, however there has been some progress on the clocks since the last update.

Late last year I had the PCBs fabricated and I assembled the first rev of the ‘main’ and ‘slave’ boards. There were a couple minor issues identified, which will need to be rectified in the next revision. There has been further software development and testing of the system. Below is a video of the first board executing the homing procedure from random starting positions.

All the clocks are drivable in either direction to any position and all updates from the main board are sent to the slave board via can. Both ends of the system are running a RTOS, which each clock having a dedicated thread to ensure a clean and low-jitter pulse stream to the stepper drivers.

Clock homing procedure – Chattering in the video is from a faulty driver causing one of the arms to oscillate as it rotates

Categories
Engineering Le clock of clocks

October ’22 Update

I had been busy training for a bunch of triathlons over the last year, however since triathlon season is now complete, I’ve been able to put a whole lot more time into the clock project.

As it stands today, the electronics and mech design is at 95% completion. Starting the fun process of procurement and assembly.

Regarding software, the base code of both sets of microcontrollers (master + slave) are programmed and RTOS running. CAN comms between MCU’s operating and master MCU sending motion commands to slaves. Slave control of each clock functional.

Slave PCB Layout
3D Design – Clock frame rear
Slave PCB 3D model
Time to clean up this mess
Categories
Engineering Le clock of clocks

Le Clock of Clocks

I was inspired to undertake this project from my graduate boss who performed a similar project that mimicked the “Million Times Clock” by Humans Since 1982.

Initially I started playing with a couple old microcontrollers to get an idea of scale and necessary components, then set out to develop a simulator in Python. An example of the simulator can be seen in the YouTube video below.