desktop notifications with mqtt and my mqn tool

Ever heard of mqtt? Ever wanted to be able to send your desktop machines notifications just as easily as all those services like pushover do for your phone or tablet?

My answer to both of those questions was 'yes', but of course I didn't immediately come up with the solution (and the little program that implements it) right off the bat.

If your interested in the little bit you've read or figured out, by all means keep reading...

My problem

I'm slooowly getting into the world of home automation (some of that hardware is expensive), and one of the first things I wanted after setting up home assistant was to be notified when something happens. Seems like a reasonable request right? In a situation like this, you've probably bought one or two (or more) devices your about to place around (and sometimes literally in) your home, so your computer can track the state of those devices, and make decisions based on that data (as well as things like the weather, where you or other people are, etc). It can then use this data (along with rules defined by you) to identify when, say, no-one should be home, -- and why are the indoor motion detectors going off and why is the back window open when no-one is home?

A big part of a system like this (at least, in my opinion) is it's ability to inform you about things that are important, as they happen (as I hope is self-evident in the example above). There are plenty of ways to do this in homeassistant, there's a notification platform for exactly this reason, and in fact at the time of this writing there are 46 different specific notification "components"... But... With options ranging from pushover, instapush, pushbullet, mailgun, , kodi, facebook (one of these is not like the others)... there wasn't one for basic desktop notifications. You know, the system tray on windows, notification center on Mac OS, and... Whatever the latest linux desktop environment uses.

That's what I really wanted: a simple way to push notifications to all my machines when important things happen.

I'm not counting html5 push notifications because (while it is a way to get notifications on the desktop), it requires a browser to be open all the time. It also requires extra work to be used with chrome (work I didn't want to do), your notifications go through mozilla or google, and it requires your home assistant instance to be open to the big bad world wide web (and exposing a server that has lots of information about you and your home, -- even possible live video feeds-- to the internet is always something you should seriously think twice about).

While individually those things might not have been a deal breaker, , with all of them put together I figured I'd look for a better way than html5 push notifications.

So maybe I should update the list of what I wanted:

  • Desktop notifications that can be sent automatically.
  • Preferably without requiring me to open homeassistant up to the web.
  • Doesn't rely on other applications (that I may close because they normally don't have anything to do with notifications).
  • Doesn't require much work on my end.

My first thought was to implement this myself, and while it did go against the last item on the list, if I couldn't find anything better it's what I was planning on doing.

Oddly enough, when (in the middle of doing something else) I started trying to come up with things I would want this little notification client / server to be able to do, I came up with this list:

  • Authentication (username and password)
  • Encryption (ssl)?
  • Different endpoints (so this will be useful to more than one situation, instead of just being for homeassistant)
  • Access control (unlikely that I'd implement, basic auth and tls would probably have been good enough for my use)
  • Clients can be interested in more than one endpoint.

This started to sound like the publish / subscribe pattern; just replace 'endpoint' with 'topic'.

While it was neat to realize the similarities, seeing the pub/sub pattern also made me remember mqtt.

It had been a while since I'd really looked at doing anything with mqtt, so to make sure I remembered things correctly, I skimmed the mqtt specification. It turns out:

  • Mqtt is basically a distributed pub / sub model - clients can subscribe to topics they're interested in as well as publish to any topic (as long as the broker allows this).
  • it's actually designed for machine-to-machine communication and the "internet of things" - for what that's worth.
  • Mqtt is designed to minimize bandwidth (always a plus).
  • It has basic authentication - the standard username and password pairs.
  • It has access controls - depending on the broker used, extra access controls can be applied (certain users can only subscribe or publish to certain topics).
  • Servers and libraries (at least the ones I found) support ssl out-of-the-box.
  • Topics can be specified with wildcards, so clients can, for example, choose to subscribe to every topic after home, without having to list them all.
  • There are also different qos (quality of service) levels - a message can be marked as qos 0, which means it just gets flung down a tcp socket with no acknowledgment needed, up to qos 2 ("did you get that?" "Yeah, I got it." "You sure?" "Yes..." "Are you really really sure?").
  • mqtt doesn't specify any specific payload format - it can be a json string, bytes, "on", "off, whatever, up to a limit of about 256 mb.

It was basically perfect for what I wanted - as little work for me as possible (mqtt client libraries and servers exist, so no reinventing the wheel), auth and access controls...

Even better... As I had noticed when looking through homeassistant's components, there was an easy way to hook mqtt up to homeassistant, so the publish service (which allows other things like automations or scripts to use a particular feature of another component) would be available for me to use in anything that I wanted to cause a notification.

There's also an mqtt eventstream component, so instead of manually sending notifications in individual automations (ok, bad rimes but it's late when I'm writing this), I could just send each event on the homeassistant event bus over mqtt. This component is intended to be used to bridge home assistant instances - so your main instance has access to all of the information your vacation house instance does (or whatever your second instance is). It's "intended" purpose doesn't really matter though, because it does just what it says on the tin and directs everything to an mqtt topic of your choice. So a desktop app could subscribe and notify only on ones I'm interested in.

Yeah... About that... (the solution)

So this is where my "just use mqtt, you dummy - don't do extra work" plan sort of hit a wall of... Well... Work. The mqtt protocol is nice and all, and there are client libraries, but they're just that: libraries. So I wrote my own little tool called mqn. I still havent decided what that stands for. 'my quick notifier' was suggested to me by a friend, and I like that as much as 'mqtt notifier', or any of the other totally not creative things I've come up with.

My horrible attempts at naming and indecision aside, all this app does is load a config file, connect to the specified mqtt server with the given options, subscribe to any topics that are mentioned in the config file and sit and wait. When it receives a message on any of the listed topics that is a parsable json string, and it has a type of 'notification', a title and a message, it pops up a balloon with that title and message near the system tray.

The only downside to this is that wx (the UI toolkit I'm using) says that the notifications only work on windows. Though I could swear it used to work for other platforms, this is fine for me, for now.

hooking it all up

So mqn worked out just as I'd hoped, after installing mosquitto (what a funny name) on my server, some fiddling with mosquitto-auth-plug and mysql, writing a script to manage it all (I'll probably put that up on git hub soon) I have... Fully working desktop notifications, to as many computers as I need, without sending the notifications through [insert big company name here] (or so I think...).

Now anything that can speak mqtt (or can run a command, which is pretty much everything) can send notifications to my desktops.

I only just pushed this to git hub, and I already have a few ideas I want to add to this, such as making mqn keep track of user activity on a machine and only displaying notifications if that last time of activity is under a certain threshold, machine-named topics (so notifications can be specifically directed), a submenu in the tray icon's pop-up menu to individually mute notifications from certain topics, etc.

What I have now works for me though, and I finally get notifications when someone leaves the damn door open, which is all I really wanted :p.

If you have an issue or (even better) an idea for a pull request with a feature or bugfix, feel free to open either on it's git hub page which is linked above.

Quick torrent downloading from commandline

Whenever I actually sit down to write a post here, the first thing I can come up with to write is how long it's been since I've posted last, so without further adue:

Wow it's been a while!
This isn't going to be a full post, just a quick tip; I have a lot of these "tips" I've been meaning to write, so I'm starting here.
On a day-to-day basis, I wget a lot of files. [For non-unix gurus, wget is a commandline http/s ftp/s client.] It's now second nature for me to wget whatever tarball or file I need to get on a linux machine, but it's not so easy to do with torrents. This has annoyed me for a while now; it seems every time I actually need to get a torrent on a linux machine I have to go install something like transmission, then configure it, then test it because I'll invariably get that one weird bug that no-one knows about. While this isn't really a big deal in the long run, it's inconvenient to go through this process for just one torrent. I needed something that was as quick as wget or curl. Something that I could run in a tmux window and check later. There are, of course, ways to do this with transmission, mainly transmission-cli; I'm sure there are similar solutions for other linux torrent clients. This assumes, of course, that you already have transmission installed, configured and running, which made it a non-solution for me. Nice and quick if you've got a client you usually use and that is always running. Not so nice if you want wget-like functionality (run once, maybe seed to ratio 1.0 and then go away, as well as writing in current directory).

My solution

I tossed the idea of creating something to do this around for a while, there are after all libraries like libtorrent-rasterbar and it's asociated python bindings. In the end, I did the smart thing and actually looked for existing solutions. One of the answers on this stackoverflow question mentions lftp.
At first, I was skeptical. With a name like lftp... Well... Yeah. But after sudo apt-get install lftp and lftp -c torrent "my magnet link", it worked like a charm.

So there you have it; wget-like torrent downloading, just 2 commands away from any reasonably up-to-date modern system.

A few things that I've noticed so far: It downloads the torrent to your current directory by default, so make sure you are where you want it to go before running lftp. The person on stack overflow who wrote about this did mention that -c will background the process after the torrent is finished; the background process will seed. I'm not sure to what limit, if any at all, though I'm assuming 1.0.

I hope this helps if you just need to quickly get one torrent and don't feel like installing and setting up a persistent bit torrent daemon.

How much difference does a little difference make?

In a departure from my normal technology related posts, this one will be about something far more personal; if you aren't interested, feel free to stop reading here. This will most likely just be me pondering and getting nowhere while asking questions of myself along the way.

What follows is a description of my eye condition and a recent development (I say development because it sounds better than "what the fuck just happened!")

Read more… (Total estimated reading time, 6 minutes)

Easy, one-time and secure file transfer with the magic wormhole!

Ah, it's been a while...

Hello readers who probably believed this blog to be abandoned. While I haven't written anything here in a few months, I think I have a few upcoming posts (I just got a raspberry pi, so if I can think up any interesting projects /uses for it I'll certainly post them here). Now, though, I'd like to share a nice little tool I just came across.

So I regularly browse what's trending on Git Hub to see what's getting the attention of the open source community, in hopes to find any nifty tools / libraries / awesome lists I don't already know about. There's always something new and usually something interesting; today was no different. Only... I found a particularly useful tool. It's called magic-wormhole, and it's so simple your average point-and-click, semi-computer literate monkey can use it. Assuming, that is, that they can find their command prompt / terminal. Sorry if you are such an aforementioned clickmonkey; no-one blames you. Well. Ok... I don't. :P Any how, one of the more interesting things about this application is exactly how it's used. There isn't a server where you upload your files, no automagically updating folder like dropbox... Not even any configuration of devices and folders like Syncthing requires. You just give it a piece of text or a file, and it gives you a few codewords you give to the person who you want to receive your stuff. It is like Syncthing in the fact that it's peer to peer, which means you send your data streight to the person who's receiving it, although it might go through a relay if you can't directly connect to them. This thing isn't meant for your average file sharing... It's meant for when people are talking to each other (face to face, over the phone, chatting, what have you), but their computers are not. This is what I mean by "one-time". You run a command, provide a file or some text, get your codewords, tell someone the codewords, they run their client, get the file, and then it's done. They have the file, your client closes. Mission accomplished. Rather than upload your file to dropbox and give the other person it's link, you can just send it to them directly. It's also encrypted, unlike most other easy methods of transfering files, has no space restriction, and is only limited by your upload speed. Oh yeah... And you can also upload directories. Personally, I have had to upload a file to my webserver so many times just so one person could get it, because my dropbox links were suspended, because I was low on space, because I didn't want to make a shared folder with them for one little file, etc... So much work... I have to log in with filezilla or something similar and upload the file. Granted, that's not much work really, but I almost always have a terminal open and I'm super lazy... Much easier to just "wormhole send my.file". While the linux readers might be muttering to themselves about things like scp, ssh and rsync, remember that most people haven't been enlightened yet and windows obviously doesn't come with them by default (thanks, git for windows, now where's rsync!)

Another aspect I like about this program is that you can host the server that handles matching codewords to connection info, as well as the relay server that will send TCP packets through to a receiver if their firewall isn't allowing a direct conection. [Yay, self hostable!]

The more experienced readers (aka linux nerds) might think to ask why there's a need for this tool at all. After all, we have gpg with email, ssh and scp... All of which require previous arrangements in the form of keys or email addresses exchanged. For a quick file transfar to someone you have no prior key for, this works great as a commandline tool for me. For more on why you might want to use this project over other alternatives, see the motivation section of the README.

To install this, you'll need python 2.7 (python 3 support doesn't fully work yet, as I understand) and pip. There are instructions to fix some missing dependencies you might run into on Debian / Ubuntu in the README for the repository; check there if your having issues. If you have python and pip (go you), just:

pip install magic-wormhole

For those who don't have python and really don't feel like installing it, I'll most likely be posting an executable of the tool here later (either using pyinstaller or py2exe).

If this sounds like something you and others you know would use, check it out. Heh heh... See what I did there? Check it out..... Yeah nevermind...

If you found this useful or you have other awesome projects you'd like to share, feel free to comment below.

Until next time...

Self-hosted comments with Nikola

If you've been reading any of the previous tech related posts, you no doubt have noticed by now that I love anything self-hostable. Dropbox, Google Drive, and others are what most people think of for cloud storage, and are good examples of services you can get similar (and often better) functionality by using self-hosted alternatives for. But what about comment systems?

Read more… (Total estimated reading time, 6 minutes)

What world do you live in?

This isn't a metaphorical or rhetorical question, I honestly want to know - what world do you live in? Read this post, think about it, and if you feel like sharing mention me on Twitter. (And no, the irony is not lost on me - you'll get it after reading).

This is a post I've been contemplating for a while now (it was one of those posts I told myself I would write once I got a blog again), and I've finally sat down and thought about it. Read on for my musings on entertainment, socializing, the average teenager, and where I think technology is heading.

Read more… (Total estimated reading time, 5 minutes)

Every programmer is just a plummer with motivation

Just wanted to post a thought I've had for a while now, as well as mention my latest project.

so almost a month ago, some friends and I decided we would develop an application that would phasilitate quick access to information, by pressing a hotkey, choosing an API from a list and searching for information. This has already been done in different ways with JAWS for Windows' Research it, and more recently with Accessible apps' QSeek. Both of whitch are paid, as well as closed source. Our project, Queriet (the quick ubiquitous extensible research interface enhancement tool), aims to provide an extensible core that anyone with python knowledge can easily write plugins for.

Read more… (Total estimated reading time, 2 minutes)

Backup, sync, and security - my thoughts on how we store our online lives

In the course of looking for large amounts of online disk access for my own backup needs, I've scene a lot of blog posts and articles with names like "The 10 best backup solutions", "Best backup and sync solutions", and "Best free backup tools". While I don't intend this article to serve as my take on "the best...", I do want to express my thoughts on backup and sync solutions, as well as my thoughts on the two in general and their security.

Read more… (Total estimated reading time, 6 minutes)