Last active
January 4, 2016 02:59
-
-
Save daniel-j/8559113 to your computer and use it in GitHub Desktop.
A system monitor for PiGlow, uses the PyGlow library, shows CPU usage, memory usage and current CPU temperature. When a value change it transition to it smoothly. There's also a version written in C using the wiringPi library! It should use less CPU, and it's multithreaded, yay!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// PiGlow system monitor by djazz! | |
// Makefile is embedded below | |
// | |
// Configuration | |
float temperature_range[] = {35.0, 65.0}; | |
float led_update_interval = 1000/20.0; | |
float value_update_interval = 1000.0; | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <math.h> | |
#include <wiringPi.h> | |
#include <piGlow.h> | |
#ifndef true | |
# define true (1==1) | |
# define false (!true) | |
#endif | |
const int CHANGE_VALUE = 0; | |
float values[] = {0.0, 0.0, 0.0}; | |
float values_current[] = {0.0, 0.0, 0.0}; | |
// takes a value from 0.0 to 1.0, leg can be 0-2, brightness is max brightness and can be 0-255 | |
void leg_level(float val, int leg, int brightness) { | |
float ratio = 0.0; | |
int i = 0; | |
for (i = 0; i < 6; i++) { | |
ratio = 6*val - i; | |
if (ratio > 1.0) ratio = 1.0; | |
else if (ratio < 0.0) ratio = 0.0; | |
if (i == 0) { | |
ratio /= 3.0; | |
} | |
if (i < 3) { | |
ratio /= 2.0; | |
} | |
piGlow1(leg, 5-i, (int)brightness*ratio); | |
} | |
} | |
PI_THREAD (updateValuesThread) { | |
FILE* fp; | |
FILE* stat; | |
FILE* pfree; | |
int raw = 0.0; | |
float temperature = 0.0; | |
float temp = 0.0; | |
unsigned totalMem, used, free, shared, buffered, cached; | |
float memory = 0.0; | |
unsigned long long lastTotalUser, lastTotalUserLow, lastTotalSys, lastTotalIdle; | |
unsigned long long totalUser, totalUserLow, totalSys, totalIdle, total; | |
float cpu_percent = 0.0; | |
stat = fopen("/proc/stat", "r"); | |
fscanf(stat, "cpu %Ld %Ld %Ld %Ld", &lastTotalUser, &lastTotalUserLow, &lastTotalSys, &lastTotalIdle); | |
fclose(stat); | |
while (true) { | |
fp = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); | |
fscanf(fp, "%d", &raw); | |
fclose(fp); | |
temperature = raw/1000.0; | |
temp = (temperature-temperature_range[0])/(temperature_range[1]-temperature_range[0]); | |
pfree = popen("free | sed -n 2p |awk '{print $2 \" \" $3 \" \" $4 \" \" $5 \" \" $6 \" \" $7}'","r"); | |
fscanf(pfree,"%u %u %u %u %u %u\n", &totalMem, &used, &free, &shared, &buffered, &cached); | |
pclose(pfree); | |
memory = (used - buffered - cached)/(float)totalMem; | |
stat = fopen("/proc/stat", "r"); | |
fscanf(stat, "cpu %Ld %Ld %Ld %Ld", &totalUser, &totalUserLow, &totalSys, &totalIdle); | |
fclose(stat); | |
if (totalUser < lastTotalUser || totalUserLow < lastTotalUserLow || totalSys < lastTotalSys || totalIdle < lastTotalIdle){ | |
//Overflow detection. Just skip this value. | |
//cpu_percent = -1.0; | |
} else { | |
total = (totalUser - lastTotalUser) + (totalUserLow - lastTotalUserLow) + (totalSys - lastTotalSys); | |
cpu_percent = total; | |
total += (totalIdle - lastTotalIdle); | |
cpu_percent /= total; | |
} | |
lastTotalUser = totalUser; | |
lastTotalUserLow = totalUserLow; | |
lastTotalSys = totalSys; | |
lastTotalIdle = totalIdle; | |
piLock(CHANGE_VALUE); | |
values[0] = cpu_percent; | |
values[1] = temp; | |
values[2] = memory; | |
piUnlock(CHANGE_VALUE); | |
delay(value_update_interval); | |
} | |
return 0; | |
} | |
int main(void) { | |
wiringPiSetupSys(); | |
piGlowSetup(true); | |
piThreadCreate(updateValuesThread); | |
while (true) { | |
int i; | |
float diff; | |
for (i = 0; i < 3; i++) { | |
diff = fabs(values_current[i]-values[i]); | |
if (diff > 0.025) diff = 0.025; | |
if (values[i] < values_current[i]) { | |
values_current[i] -= diff; | |
} else if (values[i] > values_current[i]) { | |
values_current[i] += diff; | |
} | |
leg_level(values_current[i], i, 30); | |
} | |
delay(led_update_interval); | |
} | |
return 0; | |
} | |
/* Makefile | |
#DEBUG = -g -O0 | |
DEBUG = -O3 | |
CC = gcc | |
INCLUDE = -I/usr/local/include | |
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | |
LDFLAGS = -L/usr/local/lib | |
LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm | |
# Should not alter anything below this line | |
############################################################################### | |
SRC = cpu.c | |
OBJ = $(SRC:.c=.o) | |
BINS = $(SRC:.c=) | |
all: $(BINS) | |
cpu: cpu.o | |
@echo [link] | |
@$(CC) -o $@ cpu.o $(LDFLAGS) $(LDLIBS) | |
.c.o: | |
@echo [CC] $< | |
@$(CC) -c $(CFLAGS) $< -o $@ | |
clean: | |
@echo "[Clean]" | |
@rm -f $(OBJ) *~ core tags $(BINS) | |
tags: $(SRC) | |
@echo [ctags] | |
@ctags $(SRC) | |
depend: | |
makedepend -Y $(SRC) | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# PiGlow system monitor by djazz! | |
# | |
temperature_range = [35.0, 65.0] | |
cpu_delay = 1.0 # the time it should take to calculate CPU usage | |
other_delay = 5.0 # wait this long between memory and temperature update | |
from pyglow import PyGlow | |
from subprocess import PIPE, Popen | |
from threading import Timer | |
from sys import exit | |
from time import sleep | |
import psutil | |
pyglow = PyGlow() | |
values = [0.0, 0.0, 0.0] | |
values_current = [0.0, 0.0, 0.0] | |
# found this online somewhere.. | |
def get_cpu_temperature(): | |
process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE) | |
output, _error = process.communicate() | |
return float(output[output.index('=') + 1:output.rindex("'")]) | |
# takes a value from 0.0 to 1.0, leg can be 0-2, brightness is max brightness and can be 0-255 | |
def leg_level(val = 0.0, leg = 0, brightness = 100): | |
#print "--" + str(val) | |
for i in range(0,6): | |
ratio = max(0.0, min(1.0, 6*val - i)) | |
#print str(i)+" - "+str(ratio) | |
if i == 0: | |
ratio /= 3.0 | |
if i < 3: | |
ratio /= 2.0 | |
pyglow.set_leds([int(leg*6+(6-i))], int(brightness*ratio)) | |
def update_cpu(): | |
cpu = psutil.cpu_percent(cpu_delay)/100.0 | |
values[0] = cpu | |
timer = Timer(0.0, update_cpu) | |
timer.daemon = True | |
timer.start() | |
def update_other(): | |
memory = psutil.phymem_usage().percent/100.0 | |
values[2] = memory | |
degrees = get_cpu_temperature() | |
temp = (degrees-temperature_range[0])/(temperature_range[1]-temperature_range[0]) | |
values[1] = temp | |
timer = Timer(other_delay, update_other) | |
timer.daemon = True | |
timer.start() | |
pyglow.all(0) | |
update_other() | |
update_cpu() | |
try: | |
while True: | |
for i in range(0,3): | |
diff = min(0.025, abs(values_current[i]-values[i])) | |
if values[i] < values_current[i]: | |
values_current[i]-=diff | |
elif values[i] > values_current[i]: | |
values_current[i]+=diff | |
leg_level(values_current[i], i, 255) | |
pyglow.update_leds() | |
sleep(0.05) | |
except KeyboardInterrupt: | |
pyglow.all(0) | |
exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment