Getting various Linux system information

There are already countless tools and scripts out there to gather and display Linux system information, but there are also numerous reasons why you may want to do this on your own. For example, you don’t like the way it is displayed, the time between the measurements is to short or to long for you, or something that you really need is simply missing or even wrong.

For me, the main reason to do it on my own was, because I want to display the system information together with the data from my weather station, for which I already use RRDtool graphs, and I want all the graphs to have the same appearance.

Below are some little scripts with which you are able to get the most interesting information about your system in a format that allows you to display it, or to store it in a database for further usage.

Overall CPU load of all four cores of the Raspberry Pi:

# Read the current CPU load
CPULOAD=`top -bn 1 | awk 'NR>7{s+=$9} END {print s/4}'`

cpuload

CPU temperature:

# Read the current CPU temperature and format it (e.g.: 59234 to 59.234)
TEMPERATURE=`cat /sys/class/thermal/thermal_zone0/temp`
TEMPERATURE=`echo -n ${TEMPERATURE:0:2}; echo -n .; echo -n ${TEMPERATURE:2}`

cputemp

RAM usage:

# Read the current RAM usage
RAMTOTAL=`free | grep Mem | awk '{print $2}'`
RAMUSED=`free | grep buffers/cache | awk '{print $3}'`
RAM=$(awk "BEGIN {print int($RAMUSED/$RAMTOTAL*100)}")

ramusage

Throughput of the microSD card:

# Read the current values from the diskstats and convert it to kB/s
READ=$(cat /proc/diskstats | grep 'mmcblk0 ' | awk '{print $6}')
READ=$(($READ/2))
READ=`echo $READ`
WRITE=$(cat /proc/diskstats | grep 'mmcblk0 ' | awk '{print $10}')
WRITE=$(($WRITE/2))
WRITE=`echo $WRITE`

card

Network throughput:

# Read the current values from ifconfig and convert it to kB/s
RECEIVED=$(grep wlan0 /proc/net/dev | awk '{print $2}')
RECEIVED=$(($RECEIVED/1024))
RECEIVED=`echo $RECEIVED`
SENT=$(grep wlan0 /proc/net/dev | awk '{print $10}')
SENT=$(($SENT/1024))
SENT=`echo $SENT`

traffic

WI-Fi information:

# Read the current WI-FI information
QUALITY=$(/sbin/iwconfig wlan0 | /bin/sed -n "s/.*Link Quality=\([0-9]*\).*/\1/p")
LEVEL=$(/sbin/iwconfig wlan0 | /bin/sed -n "s/.*Signal level=\([0-9]*\).*/\1/p")

wifiinfo

rtl_433 on a Raspberry Pi made bulletproof

Like I’ve mentioned before, I am using rtl_433 on my Raspberry Pi to receive the outside temperature and humidity from the sensor of my little weather station and store the values in a RRDtool database. Afterwards, I use the gathered data to make some graphs for¬† different periods in the past.

weather_temp2

weather_humi2

In general, this works very well, but every now and then, after one or even after a couple of months, something in the RTL-SDR starts to hang, presumably the USB-controller itself, and you are only able to get it running again by disconnecting and reconnecting the stick physically. Least to say that I was not very happy with this circumstance, especially since I’ve tried different sticks, always with the same disappointing result. But like always, at least someone else was dealing with this kind of problem before and luckily already found a solution for it. The name of the solution is usbreset.c, a small C-program that can be build and used within just a few moments.

I am using a small Bash script to determine where the RTL-USB is located on the bus by using lsusb and to afterwards call the executable of usbreset.

#!/bin/bash
USBNAME=RTL2838
LSUSB=$(lsusb | grep --ignore-case $USBNAME)
DEVICE="/dev/bus/usb/"$(echo $LSUSB | cut --delimiter=' ' --fields='2')"/"$(echo $LSUSB | cut --delimiter=' ' --fields='4' | tr --delete ":")
usbreset $DEVICE 2>&1 >/dev/null

Below is the Python script which I use for calling rtl_433. If everything went fine with the call, I write the received values to the database, otherwise I call the Bash script from above to force an USB reset of the RTL-SDR (instead of a physical reconnect).

#!/usr/bin/python

import sys
import os
import rrdtool

# read the current weather data
process = os.popen('rtl_433 -g 42.1 -f 868250000 -q -R 8 -T 65')
str = process.read()
process.close()

if not str:
	os.system('sudo ./reset_rtlsdr.sh')
	sys.exit(1)

str = str.strip()
str = str.replace('\t', '')
str = str.replace('\n', ' ')
data = str.split(' ')

# check the order of the two messages and act accordingly
if data[6] == 'Temperature:' and data[15] == 'Humidity:':
	update = 'N:' + data[7] + ':' + data[16]
	# insert data into database
	rrdtool.update("%s/weather.rrd" % (os.path.dirname(os.path.abspath(__file__))), update)
elif data[6] == 'Humidity:' and data[15] == 'Temperature:':
	update = 'N:' + data[16] + ':' + data[7]
	# insert data into database
	rrdtool.update("%s/weather.rrd" % (os.path.dirname(os.path.abspath(__file__))), update)

Reading the temperature from FRITZ!DECT devices

If you own a FRITZ!Box router from the German company AVM that has an integrated DECT base station, you are able to connect devices from their FRITZ!DECT accessory line, like switchable power outlets and radiator controller via DECT.

The FRITZ!DECT 200, 210 and 300 are also equipped with a temperature sensor. With a recent firmware for the FRITZ!Box router, AVM now shows you a temperature diagram for the past 24 hours. Unfortunately, it only seems to be for informational purposes and it is not possible to download the temperature data from the router. Also, the data will be lost after you restart your router.

fritztemp

But what is not very well-known is that AVM provides access to the connected devices via their own Home Automation HTTP Interface. Once, you are logging in to the FRITZ!Box, using a Session-ID, you are able to use the mentioned HTTP interface. By using this interface, you are not only able to read the temperature from the FRITZ!DECT devices, you are also able to read a variety of other information and you are able to turn the power of the power outlets on and off and to control the temperature of the radiation controller. So, actually you could design your own personal Home Automation System, using the interface on your Raspberry Pi if you want. Since I am using the MyFRITZ!App provided by AVM to control the devices, I am mainly interested to only read the temperature. With the following Bash script, it is very easy to periodically read out the temperature from a connected FRITZ!DECT device. You just have to fill in the password of your FRITZ!Box and the unique AIN of your device, which is shown in the ‘Smart Home’ menue of the FRITZ!Box.

#!/bin/bash
# -----------
# definitions
# -----------
FBF="http://192.168.178.1/"
USER="root"
PASS="YOURFRITZBOXPASSWORD"
AIN="AINOFYOURFRITZDECTDEVICE"
# ---------------
# fetch challenge
# ---------------
CHALLENGE=$(curl -s "${FBF}/login_sid.lua" | grep -Po '(?<=<Challenge>).*(?=</Challenge>)')
# -----
# login
# -----
MD5=$(echo -n ${CHALLENGE}"-"${PASS} | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}')
RESPONSE="${CHALLENGE}-${MD5}"
SID=$(curl -i -s -k -d "response=${RESPONSE}&username=${USER}" "${FBF}" | grep -Po -m 1 '(?<=sid=)[a-f\d]+')
# -----------------
# fetch temperature
# -----------------
TEMPINT=$(curl -s ${FBF}'/webservices/homeautoswitch.lua?ain='${AIN}'&switchcmd=gettemperature&sid='${SID})
TEMPFLOAT=$(echo $TEMPINT | sed 's/\B[0-9]\{1\}\>/,&/')
# ------------------
# output temperature
# ------------------
echo $TEMPFLOAT

It is also relatively easy to call the script within a python script. Supposed, you have saved the bash script under the name ‘fritztemp.sh’, you can use the following python code as a wrapper which you can include in your own scripts.

#!/usr/bin/python

import sys
import os

# read the temperature from the fritz device
process = os.popen('sudo ./fritztemp.sh')
str = process.read()
process.close()

if not str:
  sys.exit(1)

str = str.replace(',','.')
str = str.replace('\n','')

print str

I use the code shown here to read the temperature from one of my FRITZ!DECT200 devices on the lower floor of my apartment, store it in a RRDtool database and generate a graph, together with the temperature on the upper floor which is measured by a Bosch BMP180 pressure sensor.

insidetemp

You can easily see that the trend of the graph is exactly the same like it is in the diagram showed by the FRITZ!Box router itself.