How I Get Notified When Wi-Fi & Network Devices Go Offline
My living room set-up has a BIG problem: there are two identical looking plug switches. Turning the bottom one off just turns my TV (and TV equipment) on and off – which is no big deal.
BUT turning the top switch off will disable my downstairs Eero point, along with a network switch that ultimately supplies internet (and Wi-Fi) to my detached garage via some direct burial CAT7 cables that I have run through my backyard. It also knocks offline two CCTV cameras that I have set-up (these stream to my Synology NAS 24/7).
So I wanted to build a simple home network monitoring solution that will notify me if the wrong switch is turned off downstairs. I evaluated a few options here including PRTG, Nagios, a third party Eero API, Node-RED and more.
Eventually I coded up my own Python script which is available on Github. I discuss exactly how this script works (and how you can configure and run it yourself) in this video. I also use MailerSend to send out any notification emails, which I explore in this video too.
If you prefer text over video, please read on for the guide/transcript version of this video.
Video Transcript And Guide
Hey everyone, I have an issue. Well, MANY issues in-fact but in THIS case I have a tech issue. These two switches look innocuous enough: the bottom one turns our TV equipment off. But the top one turns off this Eero and THIS network switch. And because these supply internet to my garage through some direct burial CAT7 cables, I THEN loose internet access in my backyard, driveway and garage. Plus two of my CCTV Power over Ethernet cameras get knocked offline in the process.
Luckily though I built a simple software solution that anyone can run, and basically what happens is that if a crucial network device gets knocked offline, it’ll send me an email:
It works really well, let’s have a look at how you do this.
PRTG
Before I discuss why I coded up my own solution, I wanted to look at some of the other options I tested out first. Essentially we’re looking for networking monitoring software, and on Windows the most popular option is probably PRTG (there’s also Nagios, although that doesn’t run natively on Windows which I’ll discuss a little later). PRTG is actually a set of infrastructure monitoring tools although we’re mainly interested in their network monitor here.
The website shows that it has LOTS of features including the ability to generate lots of pretty graphs but more crucially, it has automatic network discovery. What that means is that PRTG can scan your entire local network (for example) and see exactly what devices are connected:
It can then automatically create notification alerts (called sensors) that so that you get notified when certain network devices go offline. That’s pretty much perfect for what I’m looking to do and while PRTG is MAINLY a paid-for tool, the free tier supports up to 100 sensors which would also have been fine for me.
So, why did I decide against PRTG? Well it kinda’ boils down to me being a fairly pragmatic, “KISS” (keep it simple) type person who doesn’t like overly complex tools. PRTG is clearly a great software tool, especially for professional companies, but I don’t really need this level of features just to get notified it a couple of CCTV cameras go offline. I also found that despite scanning my local network for many minutes, it only found a handful of network devices. Even if it was struggling to scan devices on a different subnet (in other words, those supplied by my other Eero devices), my desktop PC connects to an IoT Hub and a PoE switch that ultimately powers four security cameras.
So it SHOULD have been able to pick these up at the very least, in my opinion. I did try manually adding a device on a different subnet (one of the garage Power over Ethernet cameras) but it kept complaining that it couldn’t see it or create sensors for it, which was a bit odd.
Now this IS clearly something that *I’m* doing wrong because PRTG is a well known bit of software, but it generally doesn’t seem like the right fit for me. I get the feeling that I would have spent more time configuring and maintaining PRTG than anything else, to be honest.
Eero API FTW?
Since I have an Eero mesh Wi-Fi system, the next thing I explored was whether Eero has an API or not. After all, if they have a simple API then I could just use this to regularly query which network devices are connected – and if a required device goes offline, I could sent an alert out. While Eero doesn’t have a well established, open API, 343max on Github HAS created an unofficial API for Eero that provides everything I needed – such as devices connected to my network. Great. So I started to explore this option, and my initial tests worked fairly well:
The first time you run the script, it authenticates you by firstly asking for your login information, then asking for a two factor auth code sent to my email. After this is complete, I can run the script again and see all my connected devices – sweet. Unfortunately you might have worked out the problem here: I want a simple, automated solution here, but this Eero client can’t bypass Eero’s login mechanisms and so it needs to ask me for my two factor auth token, for example.
This means that I either weaken my Eero account security by trying to disable two factor auth, or I keep it but then I can’t easily this Eero API automatically. You might be thinking “big deal, just log into your email within your script” – but this adds an extra layer of complexity and starts getting a bit over the top for this use case, in my opinion. So it’s frustrating because this IS a useful library but back to the drawing board.
Other Alternatives
I then scoped out a few alternatives to PRTG and there ARE quite a few, including Nagios, domotz, zabbix and emco. I’m not sure if I pronounced those all correctly. Some of these are paid-for solutions, while some have a free tier. emco looked particularly good to me because it looks fairly easy to set up and it’s not PURELY marketed as an “enterprise software solution”. I was an enterprise software developer for over a decade, and the words “enterprise software” still sends a shiver down my spine.
NMAP
HOWEVER at this point I started to wonder whether it would be simpler to just code my own solution – I didn’t want to fall into the trap of spending loads of time configuring a fancy monitoring solution, all for a couple of CCTV cameras. Y’know, I’m not trying to monitor hundreds of mission critical distributed servers for a Fortune 500 company.
So I thought back to my legal hacking days, and I remembered nmap, the “swiss army knife” of networking. Nmap has loads of different functions, but it’s particularly good at scanning over an IP or range of IPs and seeing whether any IPs have open ports.
You can THEN use this knowledge for… nothing. Nothing at all. The awesome thing with nmap is that you can give it a local IP range, and within seconds or will return any IP addresses which “appear” to be online. Now it’s never QUITE as easy as saying “yes this IP address is online” because some IPs won’t respond to pings, and others won’t show any open TCP ports – because they are hosting UDP services INSTEAD. However in general, nmap can still be a great tool so I wanted to go down this route.
Node-RED
I had a few options. I could code my own shell script which calls nmap natively and then sends an email if required, although this could get clunky fairly quickly. Another option would be to use Node-RED which is a Javascript based development tool that allows for visually hooking together different “bits” of code and scripts, essentially.
So I could have installed Node-RED and added an inject node to run an nmap script that returns which local network devices are online. Or I could have used a ping node (or similar) to ping an IP every so often, such as once a minute. You would then have a function node to check if it returns false, and then add an email node (for example) to send an email.
My Own Python Script
This solution WOULD work really well and there’s no real flaws with it, other than the fact that I’m personally more comfortable with writing scripts in Python – so that’s the route I went down. But Node-red would work just fine here and if the script I discuss next doesn’t seem right for you, I’ll put some links in the description to get you started with receiving offline notifications in Node-red.
So I got started with writing some Python to ping a range of IP addresses, and cross reference the results with a few IP addresses that “must” be online – in other words, the ones that would get knocked offline if someone turns the wrong switch off in my living room. I’ve put the script on Github and I’ll link to it in the description too, but essentially this is a Python 3 based script with minimal dependencies – it mainly expects that nmap is installed on your system.
I also use MailerSend to send out notification emails, but you could swap this out with a custom version if you preferred. I won’t get into the detail too much here, especially because the code is fairly self explanatory and the README goes into detail on how to get this script up and running. But essentially, this script uses a Python nmap wrapper to run a basic ARP discovery check over the range of IP addresses specified in the config.ini file. This will then give a list of all active IP addresses, meaning I can then work out whether any of the required IP addresses are missing. If so, this is a concern – of course.
However I did notice that sometimes the nmap ARP check was missing certain IP addresses out, in other words it was saying that certain IPs were offline – even when they weren’t. So I added a quick ‘failsafe’ check that pings the required IP addresses one final time, just to see if they really are offline or not. Any results will then be sent over email.
MailerSend Setup
In this case I am using MailerSend’s API to send out the email because it was MUCH easier than worrying about configuring local email servers and deliverability rules. It’s also free unless you’re sending thousands of emails. You can create an account for free and then you just need to add the domain that you’re planning to email to, which was “tristanperry.com” in my case. MailerSend then gives you certain DNS records that you will need to change to validate this domain for anti-spam purposes. If you have any doubts at this point, just contact your host or domain name registrar and they should be able to help you out. Once the domain is validated, you’re pretty much good to go.
The final thing to do is get a MailerSend API key, and this is then specified as a command line option (well, it’s actually a local environment variable) because it’s not really ideal to save this in a config file.
You then just need to tweak the IP addresses in the config file. If you only have a single router, and all your devices are on 192.168.1
(for example) then you can just put a single range here. But if you have a mesh Wi-Fi system, look through some of your connected devices in your router’s admin panel or app to see all of the IP subnet ranges that your devices can connect to. List these in the IpRangesToScan
field, and finally specify any mandatory Wi-Fi devices under the RequiredIps
field. It helps if you assign these IPs as static devices within your router’s admin panel or app because otherwise the IP can change if the device restarts.
Phew. That sounds like a lot of information (sorry) – it’s actually a fairly straightforward script but I wanted to cover everything you need to know. You can then run the script in the usual way, either as a one-off command line option or by scheduling it into the system’s crontab or whatever.
Final Notes
If one of your crucial network devices then goes offline, you’ll receive an email. Noice. It’s really that simple. UNLESS you struggled to get this script running (of course) in which case, please drop me a comment here or on Github and I’ll see if I can make the instructions clearer.
The final thing I wanted to point out is that I developed and ran this script on Ubuntu because that’s what I prefer to develop in, but this should run fine on Windows too because I used cross-compatible code and wrappers. Just make sure that nmap is available on the path when running the Python script.