HN user

maxmunzel

438 karma

maxmunzel@me.com

Posts2
Comments61
View on HN

Not yet, but I used VLMs to read out water meters with mixed results. It is definitely the easiest approach to prototype. For my balcony, all vision based approaches are limited by viewing angles that don’t expose any neighbors.

But even with an llm backbone you’d still need some setup to detect when to query the llm. And then you already have a low-false-negative pigeon detector that may be sufficient for your use case.

Cool! Do you have the STLs of the turret online somewhere?

My setup also had its occasional false positives but that’s not a problem if all you do is spray a bit of water around. I also looked into yolo, but I couldn’t find any good datasets of pigeons. Nowadays that’s no problem anymore as you can just use models like meta’s segment anything that do zero-shot bounding boxes… if you have the GPU to run it.

Hey, author here — thanks for posting it again!

As of 2025 the pigeons are back and version 2 with aiming and a microphone array for target acquisition is still work-in-progress. I’m heading to bed now, but I’ll happily answer any questions tomorrow.

Hi mbreeze!

this seems to just be a SQLite database with values in fields?

Sqlite is used as a storage format ("SQLite competes with fopen()"). The key-value pairs are stored as a modified Append-Only CRDT. The LUB-Operation (to merge to states while syncing) is implemented here: https://github.com/maxmunzel/kvass/blob/e32fdabdc86b039f716c...

anyone with access to the file would be able to see all data stored?

Yes, attackers with access to your fs are not part of my attacker model. I rely on disk encryption for that matter.

Do the clients cache data locally? It looks like you're basically syncing from the server for every request. You're already making a round trip to the server for a request anyway, so why not keep state only on the server? I can understand an offline-only mode, but this would require a significantly more robust sync mechanism. If this was the goal, I'd love to see this discussed more in the README too.

The sync mechanism is actually pretty solid, as its based on CRDTs. One of the applications of kvass is central management of config files, so automatic syncing and offline fallback are important.

What is the purpose of the ProcessID?

The Counter Variable implements a rudimentary implementation of Lamport clocks. To get a total order from Lamport clocks, you need ordered, distinct process ids. The process id's don't really need to mean anything and the Lamport clock is itself just a fallback for the case that the wall-clock timestamps collide (see the Max() function), so it's practical to just draw them randomly.

I didn't see any authn/authz in the requests. You're also unmarshalling random data from the request w/o confirming that it is valid first. This seems risky to me and could potentially crash the server if I were to send it random data.

Authentication is provided by the GCM mode of AES. As I decrypt (and thereby verify) early, I can assume to work on trustworthy payloads. GCM is also non-malleable unlike for example CBC or CTR.

As suggested by losfair, I'll switch to PSK TLS as soon as it's available or just put HTTPS in front of the end-points. But that's not high-priority right now.

SQLite allows me to keep multiple versions of the same entry, which is convenient for state merging. Half the sync logic is actually implemented in SQL. Other than that, I’m already familiar with it and the storage backend is not very performance critical for the intended use case.

Redis is in-memory so it's prohibitive for big files. Also kvass still works if its disconnected from the server. This is important, if you want to use it for config files.

On the other hand, using redis (/skate) for storing files was the inspiration for creating kvass.

Mainly self-hosting and generating share-able urls. If your key's end in ".html" the mime type is even set accordingly and you can use it for toy-websites ;)

This is by no means meant to replace the backend of your app. It's more of an alternative to usb-sticks and google drive.

I think it's fair to say that skate is the more mature tool. Kvass on the other hand is more focused and simpler.

Especially self-hosting kvass is even simpler than skate, and I had issues linking/syncing skate in the past.

It would probably be a nice weekend project to port the url/qr features to skate.

Thanks for the critique! I wanted to use symmetric crypto as its trivial to use without domains and certificates. The possibility of replays is a non-issue, as the key-value store is implemented as a CRDT and therefore all operations are idempotent.

On the other hand, I didn't anticipate replay attacks in the design and thanks to your comment, I'll keep them in mind should I ever find myself in a scenario where they are undesirable...

The primary use case is for shuffling around files or clipboards between different computers. I also regularly use the url-sharing capability.

Prior, I had to deal with ephemeral http servers, which I didn't like from an ergonomic perspective.

Ergonomically, I find redis nice. The problem is, that it is in-memory and that encryption is cumbersome. Also, kvass is able to be used offline, as the kv-store is implemented as a CRDT.

Interesting question! The geometry of my balcony kind of restricts the number of places that observe the pigeons without spying on my neighbors. Therefore I’m not sure where else I could put another camera.

I’m thinking about a auto-aiming gun for the next iteration, though.

After a quick burst of manic energy during exam phase, I decided to solve the pigeon problem on my balcony once and for all (and in a humane way).

So I bought a cheap electric water gun from Amazon, built in WiFi using an ESP8266 and a relay shield; 3D printed a window mount for my old iPhone (running a webcam app) and hacked together some openCV code in python.

After all this was working on my desk, I had the pleasure to discover that the PCB Antenna of the ESP is to weak to receive WiFi on my balcony so I connected the ESP to my (current) iPhone hotspot and wrote a small go relay for my server so that my laptop can send the shooting commands to the water gun ~~over the internet~~. Oh and while I was at it, I added a Siri Shortcut, so it’s voice controllable, too. (They are surprisingly hacker-friendly)

The surprising thing is, that this Ruben Goldberg machine actually works really well and without much fiddling.

For my bachelor thesis, I used Postgres on a compressed btrfs partition. For my text-heavy dataset, this gave excellent results without compromising on ergonomics.

As the implementation is block-based it is also faster than the naive approach of just zipping your data files.

In some countries it is allowed to vote, but your employer or landlord may request you to prove to you that you voted for the „right“ guy by sending them a picture of your filled out ballot.

A feature like this (properly implemented) could actually be great for those countries.

The slippery slope argument still applies of course.