2013-03-11

Raspberry Pi system monitor embedded on your own site


*** NOTE: ControlMyPi shutting down ***

Above is an embedded ControlMyPi panel showing some system stats from my Raspberry Pi.

If you want to run one of these yourself set up your Raspberry Pi for ControlMyPi by following the instructions on the site and then run the script below (after changing it to use your account and password).

To embed it on your site use an iframe using the instructions on the ControlMyPi FAQ.

If you want this to run automatically every time you boot up just add a line to /etc/rc.local e.g. python /path/to/script/pimonitor.py &

'''
Created on 10 Mar 2013

ControlMyPi Raspberry Pi system monitor. See www.controlmypi.com.

@author: Jeremy Blythe
'''

import subprocess
import logging
import time
from controlmypi import ControlMyPi
        
def get_ip_address(interface):
    "Returns the IP address for the given interface e.g. eth0"
    try:
        s = subprocess.check_output(["ip","addr","show",interface])
        return s.split('\n')[2].strip().split(' ')[1].split('/')[0]
    except:
        return '?.?.?.?'

def get_ram():
    "Returns a tuple (total ram, available ram) in megabytes. See www.linuxatemyram.com"
    try:
        s = subprocess.check_output(["free","-m"])
        lines = s.split('\n')        
        return ( int(lines[1].split()[1]), int(lines[2].split()[3]) )
    except:
        return 0

def get_process_count():
    "Returns the number of processes"
    try:
        s = subprocess.check_output(["ps","-e"])
        return len(s.split('\n'))        
    except:
        return 0

def get_up_stats():
    "Returns a tuple (uptime, 5 min load average)"
    try:
        s = subprocess.check_output(["uptime"])
        load_split = s.split('load average: ')
        load_five = float(load_split[1].split(',')[1])
        up = load_split[0]
        up_pos = up.rfind(',',0,len(up)-4)
        up = up[:up_pos].split('up ')[1]
        return ( up , load_five )        
    except:
        return ( '' , 0 )

def get_connections():
    "Returns the number of network connections"
    try:
        s = subprocess.check_output(["netstat","-tun"])
        return len([x for x in s.split() if x == 'ESTABLISHED'])
    except:
        return 0
    
def get_temperature():
    "Returns the temperature in degrees C"
    try:
        s = subprocess.check_output(["/opt/vc/bin/vcgencmd","measure_temp"])
        return float(s.split('=')[1][:-3])
    except:
        return 0

def on_msg(conn, key, value):
    pass

if __name__ == '__main__':
    logging.basicConfig(level=logging.ERROR)

    total_ram = get_ram()[0]
    
    p = [ 
        [ ['O'] ],
        [ ['L','Up time'],['S','up',''] ],
        [ ['L','Processes'],['S','pcount',''] ],
        [ ['L','Connections'],['S','ncount',''] ],
        [ ['C'] ],
        [ ['O'] ],
        [ ['G','ram','free Mb',0,0,total_ram],['G','load','load',0,0,4],['G','temp',u'\xB0C',0,0,80] ], 
        [ ['C'] ]
        ]

    conn = ControlMyPi('you@yours.com', 'password', 'pimonitor', 'Pi system monitor', p, on_msg)
    if conn.start_control():
        try:
            status = {'ram':0, 'temp':0, 'load':0, 'pcount':0, 'ncount':0, 'up':''}
            while True:
                to_send = {}
                
                to_send['ram'] = get_ram()[1]
                to_send['temp'] = get_temperature()
                up, load = get_up_stats()
                to_send['load'] = load
                to_send['pcount'] = get_process_count()
                to_send['ncount'] = get_connections()
                to_send['up'] = up
                
                for k,v in to_send.items():
                    if status[k] == v:
                        del to_send[k]
                
                if len(to_send) > 0:
                    status.update(to_send)
                    conn.update_status(to_send)
                    
                time.sleep(30)
        finally:
            conn.stop_control()

2 comments:

Anonymous said...

This works great, except I have been through 2 xmpp services which work for a while then stop, as if they have stopped your access. I now am trying google.
Which xmpp service do you use; Im in the UK.

Jeremy Blythe said...

A gmail account works the best. I've also used comm.unicate.me successfully.