Cargo Counter

Well, this didn’t turn out quite the way I thought it would. Although, in hindsight, I shouldn’t be too surprised.

A couple of years ago, when I was a bit more active in my Rust development efforts, I thought it might be a useful exercise to publish a crate on crates.io. I’d written a small helper function that would temporarily change your filesystem working directory, then change it back when it went out of scope - very much inspired by Python contexts. I dutifully tidied it up a bit, added some doco, and hey presto! chwd was born.

Over the next few days, I’d eagerly look at the crates page to see if anyone had downloaded it. Eventually, someone other than my mum noticed and used it, and it got close to around 100 downloads. I considered this a reasonable success - people were actually using it! Every now and then, I’d go back and look to see what the download level was at. Downloads eventually plateaued at just over 300 downloads.

A couple of months back, I did my periodic check, and my [jaw|eyebrows] hit the [floor|ceiling]. The download count was up to 700! Why the sudden jump? It turns out that a wonderful human being had decided to add chwd to their project kerblam, a project management tool of sorts. This must’ve been what was driving the jump in my own download count! Since then, I’ve been checking every couple of days, eager to see whether I can get to 1000 downloads (TL;DR - getting close!).

Like all good programmers though, it eventually dawned on me that I could find a slightly simpler nerdier way to check the download count. When I next glanced at my Home Assistant dashboard and saw the badge at the top of the screen showing the temperature of the Raspberry Pi it’s running on, the lights went off. In my head I mean, not that the Home Assistant lights integration failed. I could write my own HA sensor to periodically check the download count so I could display it on my dashboard! I would create my own integration!

Or at least, that’s what I thought I’d do. I even spent a couple of hours researching how they were written, what config flows were, and how to develop using devcontainers (very interesting things as it turns out). I started writing this blog post alongside my testing, taking screenshots, making the usual bad programming puns, and dreaming up a suitable MidJourney theme for the post banner.

All of that turned out to be entirely unnecessary. When I was Kagi-ing for an example Home Assistant code snippet to connect to the crates.io rest endpoint for crate details, the first thing that came up was a link to a RESTful sensor, a built-in sensor that did exactly what I wanted. Yet again, Home Assistant has all the bases covered. I just didn’t realise at the time.

RESTful Sensors The Easy Way

It turns out to be as simple as adding this to my configuration.yaml file:

sensors:
  - platform: rest
    name: Chwd Crate Download Count
    resource: https://crates.io/api/v1/crates/chwd
    method: GET
    value_template: "{{ value_json.crate.downloads }}"
    scan_interval: 1800

That is literally all it took. The first config that I tried didn’t work properly as I was trying to use the json_attributes config setting to read the download count. That ends up pulling back the full JSON response and then picks out the response elements that you want, but there’s a limit to the response size that can be handled this way. It ends up that you have to use a value_template instead, which is not really any different anyway.

So the moral of the story is that Home Assistant has now been around long enough that for anything you want to do, there’s probably someone that will have done it already, and there’s even likely a native way to do it. You’re probably just not searching for it right. I’m leaving this small HOWTO post up as a reminder to myself, and a hint to you, dear reader, to not be me.

Addendum: 20240430 - We Made It!

1000 downloads! Woot!