I am no stranger to working from home. Having had my first experience of the internet in the late 90's with a dial-up modem, and then in the early 00's with the advent of cable modems in the United Kingdom, it was early on that I jumped into Voice over Internet Protocol (VOIP) and doing internet calls, while gaming on ID Software's Quake 3: Arena and Bioware's Neverwinter Nights using Ventrilo, Skype and Roger Wilco. It is almost second nature to me now, fortunately, that when asked to use software such as Discord, Microsoft Teams, Zoom or equivalent I turn on my webcam, pick up my headset and get going while typing away on an article such as this one, or an e-mail.
Although I'm capable of working from home, in the United Kingdom that isn't the norm, and it certainly isn't for a lot of people who are now forced to with the COVID-19 coronavirus outbreak. So in steps the UK Government with 'Claim tax relief for your job expenses' and one of those is working from home.
So you're now working from home, and you obviously have some concerns. You're required to have home internet access, if you're lucky you may already have broadband internet, if you're less lucky you've been using your mobile phone, or your IT department are providing some form of cellular network USB dongle for your work laptop or desktop. Either way, you may be suffering from broadband internet caps. While some Internet Service Providers (ISPs) are removing these caps while you're working from home, you may be one of the few who have had to get broadband internet purely for the purpose of working from home (that can particularly be claimed from the UK government as well) or you may just be interested in how much data your work computer is using to resolve that argument with your children, or partner as to why they can't stream Netflix while you're on a conference call.
Internet use isn't the only cost when working from home, you have just setup and installed computer hardware, and sometimes that is not necessarily cheap. If your work involves heavy duty processing, your computer's not going to be the most energy efficient hardware available when it's using up over 60 watts of electricity to render a video for that marketing campaign or social media promotion (not everyone has access to a render farm) or maybe you're actually joining in with the Folding@Home project going on. Either way, adding computer hardware to your home is going to increase the electricity bill, and if it is anything like mine - that will have been increasing year upon year. Now you may not be spending as much money each week on public transport or fuelling up your car travelling to and from work, there's still going to be a transposed expenses with being asked to work from home instead.
Over Engineering the Solution
I decided that I want to monitor the situation. I have a spare Raspberry Pi 4 here, and my original goal was to use it along with custom hardware to watch the electricity usage of my work laptop. I would also use some form of computer network pass-through to keep an eye on bandwidth use. In this scenario, we have to assume that the work laptop is a 'black box' that we don't have access to or control over, as most people who work for any company typically do not have administrative rights to their work machine, or they're not allowed to install software, change hardware, etc. At the very least, they can connect to wireless networks and wired networks, and perhaps a virtual private network (vpn) connection.
I decided against the custom hardware solution to monitor the electricity usage, sure I could setup something custom and work with 240 volts, or perhaps find some way to monitor it via inductance, but I'm not a certified electrician and I do not want to cut my teeth on getting my first electric shock with such a thing, electricity is the wrong kind of fizzy sherbet to lick - even once.
No, my plan turned somewhat differently.
Keeping an Eye on Electricity Usage
A lot of us are aware that Internet of Things devices are not necessarily secure. In fact, there's a very popular Twitter account dedicated to mocking such things, and questions just why you'd want devices to be accessible to the internet. Sometimes this insecurity can work in our favour, so long as your computer network is setup such that no-one can easily get connected to it (ensure your WiFi has sufficient encryption of at least WPA2) and your Ethernet ports aren't exposed (Ethernet over power adaptors can sometimes leak the connection to neighbours) and you're not forwarding your ports to the global internet on your router or gateway from vulnerable hardware or machines, then behind a NAT (Network Address Translation) network then you're typically fine and safe (not always..).
In this project, we're focusing on the TP-Link HS110 which is an IoT, WiFi connected power socket. With this device we find that we can get the information that we want and need out of it, without having to do too much additional work.
This device is perfectly hack-able in more than one sense, in one way it's hack-able in the Maker, Hacker, Inventor and Hobbyist sense, and in another because its local security and encryption is terrible. There are good articles that explain how it has been reverse engineered. The way in which the HS110 is intended that you control and manage its data is by using Kasa, TP-Link's IoT platform. TP-Link have integrations with various different systems, such as Google Home, Amazon Alexa, IFTTT and SmartThings APIs, though I didn't look too hard there wasn't a very evident way of officially interrogating the device. They also have IOS and Android apps.
If node.js is more your coding environment there are plenty of ways to communicate with the TP-Link API to control the socket, however there are other implementations on github, or if you have a home automation setup already you might be looking at Domoticz or OpenHAB.
Inside the HS110 is basically a small, micro-controller based computer. Its hardware isn't too far away from some portable WiFi Access Points or Routers that're also made by TP-Link. This means you can flash custom firmware to the hardware, there's also a build of OpenWRT. This also means if we don't want the hardware phoning home to TP-Link, or we want to secure it in the future, we have the possibility of doing so (though doing so may be no small feat in itself).
So thanks to this interim socket connecting to your local WiFi, and allowing you to remotely control whether or not the power socket itself is turned on or off, and further to that, it keeping a log of real-time, daily and monthly power usage which is then sent to its cloud service and stored locally, we have a good basis for retrieving the information that we need. Thanks to a python library, which also functions as a standalone tool, pyHS100 lets us import code into Python to discover what sockets we have on the network, and their 'emeter' readings.
You can install the library by running
pip install pyHS100
And then you can start writing python to interrogate the devices on the network, you can have it automatically discover the devices, or if you know the IP addresses, pass them or hard-code them into the file yourself.
Example discovery code:
from pyHS100 import Discover
for dev in Discover.discover().values():
print(dev)
Example hard-coded code:
from pyHS100 import SmartPlug, SmartBulb
from pprint import pformat as pf
plug = SmartPlug("192.168.XXX.XXX")
print("Hardware: %s" % pf(plug.hw_info))
print("Full sysinfo: %s" % pf(plug.get_sysinfo())) # this prints lots of information about the device
More information can be discovered about the library at the github site, but I also discovered that I had to manually find out what modules/functions were accessible in the code. It was not obvious from the github site at all, and so running the following commands gave me more information:
$python3
>>> import pyHS100
>>>help(pyHS100)
Also you can find out more information by using:
>>>dir(pyHS100)
If you want to look up sub modules, then you can type something similar to:
>>>dir(pyHS100.Discover)
or
>>>help(pyHS100.Discover)
I didn't realise before that Python could do this, and it's helped a lot. My syntax may not exactly be correct here as I don't have the terminal in front of me.
What if I Can't Code (yet) ?
There is also a really nice, and easy way to plot and show all of the information we're interested in, thanks to James Barnett on github. The 'TPLink Energy Monitoring dashboard' has been written in node.js and is installed using npm, and while it doesn't let you directly control the socket, it will gladly discover the sockets you have on your network, and show you the status of them. It also logs the readings to local files.
The charts created from this are really fascinating to watch, here we can see a dip where I turned off (and back on) the computer monitor attached to the laptop (and in line with it on a multi-socket connected to the TP-Link) which then has a curious power bounce:
And then there's a subtle dip when I close the laptop lid, thus turning off the built-in LCD display screen:
Which also highlights that the use of an LCD display makes the power usage very variable as it fluctuates when it's active, but pretty static when the screen is off.
To have this up and running you'll have to install npm on your system:
$ sudo apt-get install npm
And then you run the following commands:
$ git clone https://github.com/jamesbarnett91/tplink-energy-monitor && cd tplink-energy-monitor
$ npm install
$ npm start
If your install is anything like mine, npm, after you install it, or when you run 'npm install' will complain that there are security vulnerabilities. It'll advise that you run commands to fix this. Do so, do all of it. Even the 'dangerous' advice it gives to fix these vulnerabilities didn't break my tp-link energy monitor dashboard install, so you should be good to go.
Once installed, you can go to the IP address of your Raspberry Pi, and you should now see the dashboard. By default it runs on port 3000, so for example:
http://192.168.0.3:3000
To find out the ip address of your interface, you'll want to run the following command at your terminal:
$ ifconfig
Now to have this running as a system service, and potentially automatically on startup.
Edit the following file, or one like it:
sudo vim /etc/systemd/system/tlink.service
Now type into it the following, assuming that you've got the files in your /home/pi folder:
[Service]
WorkingDirectory=/home/pi/propanel
ExecStart=/usr/local/bin/node --expose-gc /home/pi/propanel/server.js
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=propanel
User=root
Group=root
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
Now run
sudo systemctl enable tplink
And you should be able to control the service with systemd!
sudo systemctl start tplink
If you want to know the status of the script, you can run the following:
cat /var/log/syslog
or
tail -f /var/log/syslog
or
less /varlog/syslog
Which may or may not have to be run as sudo. You may have a problem with the script in that it really needs to wait for the Raspberry Pi to have a network IP before it runs, and it won't re-scan for devices if it doesn't have one yet. I'll let you work out how to solve that one, and if you do, add it in the comments below!
Monitoring the Network Activity
I have an academic background in network technology, which is why I am fortunate in having the hardware to hand to set this one up. I appreciate not everyone will, and not everyone may fully understand what is happening with this setup. The goal here, is to monitor and track all computer network traffic coming out of the 'black box' which is the laptop, or frankly this could be any device that's plugged into an Ethernet adaptor connected to the Raspberry Pi.
With this part of the project, I use functionality called 'bridging'. Usually when your Raspberry Pi connects to a network, any computer communication traffic on that network goes only to the device that is directly connected. Whether it is the Wireless LAN, or the on-board Ethernet socket. Bridging the connection allows communications to pass through that device to another on the Raspberry Pi, otherwise the two never really know about each other.
To do this, in Raspbian (Debian Linux) we create another network device, one that is in software and not physical (this is called br0 typically) that allows all of the network traffic pass through two devices connected to the Raspberry Pi (or more if you really want), and we can then monitor/watch/observe the data and communications going through those devices. So This could be setup in any of the following configurations:
- From the on-board Ethernet through to the on-board Wireless LAN, or
- It can be on-board Ethernet to USB Ethernet, or
- On-board Wireless LAN to USB Wireless LAN, or
- USB WiFi to USB Ethernet.
In our case, we're going to use a USB Ethernet adaptor which will route the computer communications on the network back and forth through the on-board Ethernet. So that we do not interfere with this information being passed along, we will not include the on-board Wireless LAN in the bridge. We have to be careful when using USB Ethernet, If you have read any of my blogs where I benchmark the network connectivity on the Raspberry Pi (A Comprehensive Raspberry Pi 3 Model B Plus Benchmark or Benchmarking the Raspberry Pi 4 Model B ) you may be familiar that using Ethernet connected to USB can slow down the network connection, and in some cases, be faster than the on-board Ethernet. This is because USB is rated at a different speed to Ethernet. USB 2.0 is at most 54 megabits per second, with the Raspberry Pi 4 we are working with Gigabit Ethernet, to ensure that the Raspberry Pi doesn't slow down the network connection to the laptop in this case, we want to go from Gigabit Ethernet to Gigabit Ethernet, USB 3.0 is rated at 5 gigabits per second which means a USB 3 Gigabit Ethernet adaptor should be fine.
The USB 3 Gigabit adapter I am using is the TRENDnet TU3-ETG/EUNL v1.0R, this will identify itself as 'eth1' when connected to the Raspberry Pi 4, the on-board Ethernet will identify itself as eth0.
The Raspberry Pi 4 case I'm using here is a slightly modified version from this blog post: Raspberry Pi temperature and cooling testing Part 1 initial tests. which also has an attached 5 volt small fan attached to the GPIO pins (I haven't connected the third pin for speed control/monitoring yet..), perfect for keeping it cool. I'm using alleged 'diamond' heatsinks and thermal paste to help keep the Pi 4 cool.
Bridging Connections
We will be using the on-board Wireless LAN to monitor and setup the Raspberry Pi 4, this identifies itself as 'wlan0' by default in Raspbian. The Ethernet adaptors will be eth0 and eth1. We will also go with the default bridge virtual interface identifier as 'br0'. Here's a diagram that might help you to visualise what's going on:
In Linux it is pretty straightforward to setup a bridge, but it's a bit trickier to set one up that just acts as a 'pass through' for network activity, and to ensure it sets itself up whenever we start up the Raspberry Pi 4. What if I told you, that your network connection doesn't need an IP address for it to work? You are probably used to connecting to your Raspberry Pi by using an IP address such as '192.168.1.15' or something similar? Well, there's a mode called 'promiscuous mode' which lets your network connection accept all traffic and to pass it through, and this is how eth0 and eth1 will run, but it means to prevent confusion for the laptop or computer connected to the Raspberry Pi, we need to make sure that eth0 and eth1 do not receive an IP address. wlan0 can continue to receive an IP address, it needs to so that we can talk to it.
In this setup we're assuming that you've already setup your Raspberry Pi so that your Wireless LAN is connected to the network, and we're connected to the terminal on your Raspberry Pi, either physically with a keyboard, mouse and monitor. Or you've found out the IP address of wlan0 (by running ifconfig wlan0 on the Pi) and you've connected via SSH.
If you're trying to set this up while connected over SSH to your on-board Ethernet, you're going to have problems. Make sure you don't have any cables plugged into the Ethernet ports. It's also worth noting that for eth0 to your laptop/computer you may need to use a crossover cable, and each Ethernet cable needs to be at least Cat5e so that it is rated for Gigabit transmission and reception.
Step by Step
Once connected, first we should disable the ability for the on-board ethernet adapters from getting an IP address (confirm what name these interfaces are called by running 'ifconfig') I personally use vim text editor, you can use nano, or emacs. Whatever you're familiar with:
$ sudo vim /etc/dhcpcd.conf
At the end of the file, add the following line, in vim you press 'i' which allows you to 'insert' text:
denyinterfaces eth0 eth1
Then save the file and quit the text editor, in vim you press 'Esc' then type ':x' or ':wq'. Now we need to setup the network bridge by typing the following commands:
$ sudo ifconfig eth0 down
$ sudo ifconfig eth1 down
$ sudo brctl addbr br0
$ sudo brctl addif br0 eth0
$ sudo brctl addif br0 eth1
$ sudo ifconfig eth0 up
$ sudo ifconfig eth0 up
This will not setup the network bridge every time we start the Raspberry Pi. To do so, we need to edit another file, run:
$ sudo vim /etc/network/interfaces
Now alter the file so it looks like this:
auto lo br0
iface eth0 inet manual
iface eth1 inet manual
iface br0 inet manual
bridge_ports eth0 eth1
bridge_stp off
bridge_waitport 0
bridge_fd 0
If you have the line 'iface lo inet loopback' you can leave that in there. For the sake of simplicity, restart the Raspberry Pi with:
$ sudo reboot
Though you can probably restart the dhcpcd and network services if you're comfortable doing so.
Now, you can plug in your Ethernet cable to the USB3 Ethernet adaptor, and your computer/laptop into the on-board Ethernet adaptor. Your laptop/computer should now be able to get an IP address. If you have any problems, run the following commands:
$ sudo ifconfig eth0 down
$ sudo ifconfig eth1 down
$ sudo ifconfig br0 down
$ sudo ifconfig br0 up
$ sudo ifconfig eth1 up
$ sudo ifconfig eth0 up
This prompts the connections to renegotiate and reconnect. Now that we have the network traffic going through the Raspberry Pi, we need to monitor it.
Keeping an Eye on the Network
There are many different ways that we can now keep an eye on the network connection going through the Raspberry Pi. In fact, if you're interested in 'infosec' or 'information security' this is also a good way to increase your knowledge in 'man in the middle attacks' - but I won't go into detail about that here. We are only interested in how much data is going through this connection. While it is not going to be an entirely 'clean' way of monitoring the network connection, it is a good enough best effort. You see, we are looking at all network traffic, not just connection to the internet with this method. There are of course ways to isolate what we're looking at, to ensure that it's only the laptop connecting to the external internet, but we aren't going to go into that here, so what we observe will include information on our local network, and also the internet connection to the laptop/computer.
VNStat
I stumbled upon this software and it's great, mainly because it is free, but it is great none the less. vnstat allows you to monitor all of the network connections on your device and it will tell you the real-time usage, and it will also give you information broken down by day and by month. There are also additional tools which we can setup to allow us to view it on a web browser.
You can pull this down from the Raspbian repository by running the following command:
$ sudo apt-get install vnstat
Then by default, type the following:
$ vnstat
And you will get an output similar to this:
You will notice that the amount received (rx) and amount transmitted (tx) will be different for each interface. Our bridge (br0) has aggregated/combined together how much data has gone through eth0 and eth1, so this is not a very accurate measurement of how much information has transferred across the connection. Where as eth0 and eth1 are actually similar, there will be some increase on eth1 in this case, as that is directly connected to the local network and there will be some amount of traffic filtering going on with the Raspberry Pi bridge that's preventing it going directly through to the laptop/computer.
However for the least confusion here, you could take the rx and tx numbers from eth1 and present those as how much data is used by the laptop/computer.
vnstat can be customised further, for example if you don't see a list of interfaces like I do here, you can add them, you can also 'clear' the database that's being stored, and you can remove interfaces. You can find more information about the commands on the vnstat man page:
However we want a pretty graph, we have two options for this. One is a package called 'vnstati' which can produce a one-off graphic (unless you automate it), or there's 'ntopng', and these can also be installed with 'apt-get' (ntopng will clash with the TP-Link Energy Monitor unless you change the port it defaults to). Or we can use the vnstat dashboard:
I encountered a number of problems getting the vnstat dashboard to install and work. Mainly because of permissions when setting up the Raspberry Pi as a web server. So here I present to you the steps I took to get this setup and running, feel free to add comments below if you encounter problems (since you can use this for monitoring the network of a Raspberry Pi anyway, it doesn't have to be for this project). If you're already running a web server on your Raspberry Pi, then change the folder structure to what you need so that it doesn't conflict.
$ sudo apt-get install apache2 php php-gd wget unzip
$ sudo service apache2 restart
$ cd /tmp
$ wget https://github.com/alexandermarston/vnstat-dashboard/archive/master.zip
$ unzip master.zip
$ sudo cp -a /tmp/vnstat-dashboard-master/ /var/www/html/
$ sudo rm /var/www/html/index.html
By default vnstat dashboard will look at all the interfaces. If you want to change that then you'll have to edit the following file:
$ sudo vim /var/www/html/includes/config.php
And now we change the following lines to read as follows:
vnstat_bin_dir = '/usr/bin/vnstat';
// Set to true to set your own interfaces
$use_predefined_interfaces = true;
if ($use_predefined_interfaces == true) {
$interface_list = array("eth0", "eth1");
Other lines can be left as they are. Now you can save and quit your text editor.
Your VnStat Dashboard should now be accessible on the IP address of the wlan0 interface of your Raspberry Pi, for example:
http://192.168.0.3
I had an issue with the permissions, I was getting an error whenever I tried to access the website (error 500) and this was related to the permissions on the files. To fix this I had to run the following commands:
$ sudo chgrp -R www-data /var/www/html
$ sudo find /var/www/html -type d -exec chmod g+rx {} +
$ sudo find /var/www/html -type f -exec chmod g+r {} +
If you want to install this via other means, such as Docker/Locally, you can read more on the github site for VnStat Dashboard.
If you're still having problems, you need to check your apache2 error log to see where the problem lies, sometimes it'll say it can't access a folder, or that it's having trouble with permissions, you can check the log by typing the following:
$ more /var/log/apache2/error.log
Then you can try to work around them, for example if it's missing the following folders you can do:
$ sudo mkdir /var/www/html/templates_c
$ sudo mkdir /var/www/html/cache
$ sudo chmod 770 /var/www/html/templates_c
$ sudo chmod 770 /var/www/html/cache
$ sudo chown pi:www-data /var/www/html/templates_c
$ sudo chown pi:www-data /var/www/html/cache
If you're still having problems... (can you tell I had some debugging to do with this?) then there's the 'Locally' setup instructions on the VnStats Dashboard github which basically say to do something like this:
$ sudo apt-get install smarty composer
$ sudo cp -a /var/www/html/app /var/www/html
$ cd /var/www/html
$ composer install
There are other tools you can use to monitor the network activity on your Raspberry Pi.
ntopng
One such tool is 'ntop' or 'ntopng'. Now, you're on your own with setting up and configuring this one, see if you can work it out. It can clash with the install of the TP-Link Dashboard because it tries to run on the same port. It gives you a lot more information about the network traffic that's going through your Raspberry Pi interfaces:
You can install this via 'apt-get ntopng', however this tool is a little more out of scope for this blog post, but I figured I'd mention it just to get your interest!
A Week's Worth of Data
I thought you might appreciate an update where it's been about a week of monitoring the bandwidth and power usage:
I'm really glad that my ISP doesn't cap my internet usage per month, I think I'd really struggle to work from home with this amount of data usage!
How's that?
Hope you've enjoyed this little guide to monitoring your network and electricity use for your hardware. Consider this a 'starter' to getting the full benefit of logging and information onto your Raspberry Pi and IoT hardware in the home.
Top Comments