I made a quick demonstration video and added some example scripts to the project!
I spent some time cleaning up the package.json and implementing some bug fixes like adding reads and subscriptions to a queue (since before it would send them at the same time and crash the brush occasionally). Some newer brushes also require an “unlock code” to use the Bluetooth API, so I implemented that too!
The first version is now live on npm.js!
I’ve finally finished working on the documentation! I also added a commands table in the README.md which lists all of the current commands and a link to their designated Markdown page.
I’m preparing to publish it to npm.js now!
I finished adding some more commands: deviceState which tells you what “state” the brush is in (running, idle, charging, etc), buttonState which allows you to subscribe to button events and notifies you when the power or mode button was pressed, and brushingTime which allows you to view the live stopwatch as you brush your teeth.
I built a simple demo script to give you all a visual example of how these can be used!
Been a while! Most of this 7 hours was spent digging through the source code of the Oral-B codebase again, but I finished implementing a Bluetooth command transport layer and added a command handler for easy additions. I also implemented protocol versioning, which each brush specifies in its manufacturer data so the host knows what commands/values are available for the brush. In most cases, the newer the brush model (especially in the iO series of brushes), the higher the protocol, resulting in more available commands / data values to read from.
I’ve also added the first incoming command: batteryLevel! This method requests battery data from the brush, and depending on the protocol version of your brush, you’ll be able to view info like the battery percentage, estimated runtime, and even the technical specifications of the battery (like voltage, current, temperature, etc).
From here on, all I’ll be doing is adding more support for commands!
It’s been a while but I’m back!
I made huge changes to the overall layout of the library, and decided that…
Brush objects are the devices themselves, and will allow you to connect, disconnect, view its state, send/receive BLE commands, etc.OralBClient will only act as a “discovery layer”, which lets you search for new Brush objects and keep track of your connections (like a “management” layer I guess you could call it???)I finished building the connect/disconnect commands with an optional timeout option for connections, and I moved rssi and macAddress into getters so they’re read directly from the peripheral and update automatically. Had to switch to the @stoprocent/noble fork because the previous one caused issues with discovery in Fedora.
In OralBClient, I added a way to track the brushes and store the connected ones in a Map (so users don’t have to keep track of the Brush objects elsewhere). I also added the option to stop discovery early, and an adapter state check before it starts discovering (so it waits for the Bluetooth adapter to power on first!)
I spent a while testing out all the functionality on my website (including on mobile devices) and made a variety of minor page fixes!
I also improved the old 404 page to use my new page design.
I created a project card component and added a featured projects section on the home screen! I also moved all database query functions into dedicated projects.ts and blog.ts modules so they can be reused across the codebase.
I noticed that as I’ve been adding more pages, the navbar on mobile is becoming more and more crammed, so I created a simple hamburger navigation menu for smaller screens!
Besides that, I added 5-minute caching for projects and blog posts (since database reads are a lil’ slow) using Next.js’ unstable_cache function, and cleaned up the rest of the SVGs across the codebase to their own icon file in components/icons.
Almost ready to ship :D just gonna add a “featured projects” section on the homepage!
I finished adding a projects page and created a Payload collection so I don’t need to hard code them! I also added Payload email functionality for password resets, cleaned up the environment variable setup, and upgraded all dependencies.
Payload has lacked official support for Next.js v16 for quite some time now, but it’s finally here!!
Made some big organizational changes! I moved all of the icons in Skills.tsx and constants.tsx (contact links, footer links, etc.) into designated tsx files for reusability.
I also DRY’d out the skills data by assigning it in constants.tsx and mapping over it! Besides that, I just made a couple bug fixes and ran prettier.
Making the projects page next!
I added a nice fade animation when switching between skill tabs! I also added a favicon by pointing the source to my GitHub profile picture URL, and fixed a few more bugs.
I finished updating both the music player and the printer modal to use our new color scheme!
I ditched @tailwindcss/typography and completely transformed the styling of blog posts! Spent the past 2 hours designing custom CSS to pair with Payload’s RichText output.
Super happy with the results. Codeblocks look amazing now! Next step will be fixing the music player and printer modal to have them use our new color scheme.
I’ve been thinking about the website for a while, and figured there’s just so much wrong with it. The color scheme is incredibly generic and boring, and it seems more like a product landing page than a personal website.
So after a little over 2 hours of experimenting with different hues, and creating custom Tailwind classes to use across the website, I made some big changes! The website looks much more cozy now and features a nice navy blue design with a new font. I also scrapped the old grid background since it’s pretty generic. I’m incredibly happy about the new font and I think it makes the website much more inviting (I found it here)!
Next step will be fixing blog posts since they’re really messy with Tailwind Typography.
I added a printer section on my website and a modal to enter in the message! I also added filtering to block any inappropriate content using obscenity, rate limiting with Redis to limit each IP address to 1 successful request per 24 hours, and implemented VPN/Proxy checks with proxycheck.io.
Generally I’m strictly against VPN blocking, but unfortunately in my case I think it’s the only effective way to prevent abuse (I want to be able to sleep at night
).
Besides those changes, I also installed and ran prettier in the repo, and added basic Vercel analytics to see how many page visits I’m getting!
Finished implementing a printer module in the client to facilitate message printing! It uses Redis to store the messages as well, and the client polls every 30 seconds to pop the values and print them out.
I also made some major Redis command optimizations by using Lua execution for the printer module and a Hash structure for the status. I was able to drastically minimize the amount of commands necessary to sync the status and fetch new printer messages, which is definitely a huge plus considering there’s a monthly command limit on the free plan.
Time to build a messages input box on the website!