7
votes
What programming/technical projects have you been working on?
This is a recurring post to discuss programming or other technical projects that we've been working on. Tell us about one of your recent projects, either at work or personal projects. What's interesting about it? Are you having trouble with anything?
Foot Pedal
(This is more a basic electronics project than a software development one)
Problem
I'd been thinking about getting a foot pedal to use with my PC for a couple months, but I wasn't particularly enthused by the selection I saw for purchase:
Requirements
Plan
My idea was to approach this like building a mechanical keyboard:
This approach reduces the hard part of the project to "How do I connect a pedal to a mechanical keyboard?". My insight was that pedals for digital pianos and mechanical keyboard switches work exactly the same way: it's a basic electrical switch. So I just needed to get a keyboard switch, remove the stem and the spring, and then solder a connection from the metal leaf inside the switch to a female TS jack . This would give me a "Keyboard Switch to Female TS Jack" connector that lets me connect any digital piano pedal to any mechanical keyboard.
I expected the solder joint to be a weak point, so I hoped that filling the keyboard switch with epoxy afterwards would reinforce the solder joint.
Materials
Epoxy(Never ended up using)Challenges
Improvements for next time
Miscellaneous Notes
I've been working on a set of related websites, each deployed using Astro for static site generation and deployed with Cloudflare pages. There was a rush to set each of them up, so right now I have three separate git repositories with slightly different versions of the Astro template customization / basic components because I've been refining them as I go.
I want to set up a monorepo with a separate package for the components and a package for each website deployment. That way I can have a common template and keep the look and feel in sync between them.
I was able to make this example work, but no matter what I do, I can't get the intellisense in vscode to resolve the imports from the other package. Not the end of the world, but pretty annoying.
When I started porting my own code into the monorepo structure, I broke something else so I get some kind of error about not having a rendered for the type.
I'm pretty sure this is the "right" way to do it, but it has been super frustrating to try to set up. I'm on the verge of just putting the common components into one of the sites and symlinking the directories into the other folders. I'd have to test that that works in the Cloudflare deploy, and it feels barbaric, but I'm almost at my wit's end.
If anyone has any insights or suggestions to share, I'm open to suggestions. I'm fairly new to Typescript and JavaScript, so maybe I am missing something.
I've been experimenting with smart-home setups these past couple of month- we have a range of Ikea Zigbee compatible bulbs and remotes, a Raspberry Pi 5 with Sonoff Zigbee controller, and a number of other Sonoff smart sensors and such that we're trying out. The majority of the Zigbee communication is being bridged to the controller through Zigbee2MQTT, which has been almost flawless so far. Apart from a few issues when it comes to binding remotes that like to enter deep-sleep modes, the bridge has worked very well, it's HomeAssistant where the problems lie. It never keeps sync with the network state, it's overly convoluted and for all of the extra nonsense it has, the configurability is still poor. It doesn't help that Zigbee devices often have limitations when it comes to modifying parameters (brightness, colour temperature) when they're toggled off (but still powered!).
As a result, I'm writing my own Python-based automation system, with minimal dependencies, and I'm really enjoying it a lot more than I ever did HomeAssistant. I'm enjoying the simplicity of it. It's called "hab", and it mostly handles customisable bindings for switches, sensors, remotes, and lights- with more conditionals. The flexibility of the resulting system should be much better than that of purely using native Zigbee bindings, without being a behemoth of unnecessary code. The big problem that I am trying to solve is in sunrise / sunset re-configuring of lights and scenes. The solution appears to be to write automations which only change the parameters of devices which are currently toggled on, then catch any future remote / switch actions and adjust the target device / scene as necessary. With the use of smart switches like the Sonoff ZBMINIR2, the system will still be able to fail-dumb if the controller is ever knocked out, which is quite important to me.
This week on repeatTest, I finished up the work I was doing on tables. A table is an array type that’s restricted to storing objects (also called rows), and can restrict some of the row properties to be unique keys. Up until now, rows could only have a single shape, but I added support for having multiple shapes by making the row a tagged union. The property for a unique key needs to be defined the same way in each shape.
You can see them in use in this schema, where each node has a name property, and the names need to be unique.
Still need to do a release.
I found myself needing customizable output from tests in JS (TS), and the test framework I normally use doesn't support it. I looked at the Node builtin test runner and some other popular ones, and wasn't happy with the APIs and capabilities, so I starting writing a new test framework for myself because it sounds like a fun diversion with some concrete benefits to my workflow, and implementing one isn't that difficult.
It's not open source yet but it will be soon, I have a few major blockers remaining. I'm naming it Zest I think.
I had the first iteration working and fairly well-tested using itself, but now I'm changing the API to support nested groups - this meant rewriting a lot of the internals. I'm at 1600 LOC of tests, trying to be as thorough as I can because bugs in a test framework seem extra bad.
The first iteration of the API was mostly inspired by uvu:
Creates:
And I'm changing it to also support nested groups:
Creates:
Basically like Deno's BDD maybe with some specific choices and inspiration from uvu. The visual weight of
test(
andtest.group(
feel good to me.Each test module is implicitly in a group with the name of the relative path to its file. This gives us a really simple hierarchical data structure of tests and nestable groups, where tests must be leaf nodes.
I think the main idea that I haven't seen in other frameworks (I didn't look very hard, I could be way wrong and this is common, thoughts/references welcome) is that I'm separating the execution of test files into two distinct phases:
test.group()
calls are executed synchronously during module import and once the module exits, you cannot add new groups or tests through the normal APIs.So a plan is created when modules import, and with top-level
await
and async group callbacks, you can construct plans with arbitrary code at startup. A plan can be run multiple times in a long-running process, and its data is exposed in full fidelity at runtime or output to JSON without running any tests. I think I could streamline refreshing plans with a reused worker thread and really nudge users to doing setup in hooks (which are skipped when just reading the registry, so e.g. you wouldn't need to wait on a db connection just to get the test structure), but tests themselves will probably run with full process isolation at the granularity of groups/tests that you can configure.Code can restructure or modify plans as desired. I think this will work well when adding opt-in parallelization.
There's a lot of implications to this design that I'm still thinking through. One tradeoff is that you cannot create tests or groups after the module has been imported. Trying will throw an error, but maybe that could be relaxed and you just have some caveats for the capabilities around dynamic tests.
I think this is more complicated to deal with e.g. file changes and plan refreshing, but possibly more powerful in that it abstracts away the filesystem and makes the framework's internals a nice exposed API. (rule of least power) I'm ignorant of how most test frameworks work, but e.g. Jest doesn't have good reporting of registered tests, and I browsed some popular frameworks without seeing what I was looking for.
With the restrictions and complexity come some nice benefits, because you know tests and groups won't be created on the fly, so you can treat it like data, even reactively. It's easier to do things with the test metadata, like making a UI with fine-grained handles on it - I have an early prototype, this probably excites me the most.
There's a programmatic API available so you can make your own "test root" objects like
test
above. It's perhaps strange to havetest
be so magical but I liked the convenience of a single import. I'm trying to make it as modular as I can, and most behavior should be pluggable.It has a plugin architecture with hooks for all of the events, so it's easy to add multiple custom reporters or other integrations. Right now I just use them for outputting data - in one case logging event/summary info to stdout, and the other outputting JSON to stdout for the plans and results. All outputs are implemented as plugins so the core stays minimal. I'm thinking about maybe adding control flow mechanisms like error handling capabilities to the plugin hooks. (e.g. result mapping like enhancing errors, stopping/changing events, I think I want to give the hooks as much control as possible and let userland deal with the mess)
It's been a lot of fun to make, and I'm still open to rethinking the API to get it as nice/flexible as possible, input welcome!
I've been reading a lot about LTO archival. So far I've learned that:
I only have a couple hundred TBs and I'm pretty content now--I'm not looking to extend into the >600 TB range right now so my conclusion is that a tape drive probably doesn't make sense for me right now. But if someone wants to pay me to sign up to USENET and just download stuff then I would invest in a tape library first.
Other than that I've been researching parallel/cluster compute platforms like HTCondor, Nomad, Triton DataCenter, and other tools listed here: https://github.com/dstdev/awesome-hpc. This week I've started writing something lightweight for spinning up systemd services across PCs (a bit like telefork, Outrun, or Exodus) taking into account (simple polling) resource allocations like %iowait, cpu_idle, available memory and excess network capacity.