From bc1dd2b900b75faf1dda74cd7a2aca8f5aa5cb1f Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Tue, 23 Oct 2018 14:29:21 -0400 Subject: [PATCH] stat functions (#616) * free engine on cleanup * move system queries to c threads (wip) * cpu, temp, disk collected from c thread. done --- lua/menu.lua | 7 +- lua/norns.lua | 9 +++ matron/src/event_types.h | 12 +++- matron/src/events.c | 4 ++ matron/src/hardware/stat.c | 134 +++++++++++++++++++++++++++++++++++++ matron/src/hardware/stat.h | 6 ++ matron/src/main.c | 23 ++----- matron/src/weaver.c | 11 +++ matron/src/weaver.h | 3 + matron/wscript | 1 + 10 files changed, 188 insertions(+), 22 deletions(-) create mode 100644 matron/src/hardware/stat.c create mode 100644 matron/src/hardware/stat.h diff --git a/lua/menu.lua b/lua/menu.lua index 3b8753f19..d67a6b7c6 100644 --- a/lua/menu.lua +++ b/lua/menu.lua @@ -930,7 +930,6 @@ m.sys.pos = 1 m.sys.list = {"AUDIO > ", "DEVICES > ", "WIFI >", "SYNC >", "UPDATE >", "RESET AUDIO"} m.sys.pages = {pAUDIO, pDEVICES, pWIFI, pSYNC, pUPDATE, pRESET} m.sys.input = 0 -m.sys.disk = "" m.key[pSYSTEM] = function(n,z) if n==2 and z==1 then @@ -968,15 +967,17 @@ m.redraw[pSYSTEM] = function() screen.text_right(m.sys.net) screen.move(127,40) - screen.text_right("disk free: "..m.sys.disk) + screen.text_right("disk free: "..norns.disk.."MB") screen.move(127,50) screen.text_right(norns.version.update) + + screen.move(127,60) + screen.text_right(norns.temp .. 'c / ' .. norns.cpu .. '%') screen.update() end m.init[pSYSTEM] = function() - m.sys.disk = util.os_capture("df -hl | grep '/dev/root' | awk '{print $4}'") u.callback = function() m.sysquery() menu.redraw() diff --git a/lua/norns.lua b/lua/norns.lua index 6561d77c2..35cb693b5 100644 --- a/lua/norns.lua +++ b/lua/norns.lua @@ -45,6 +45,15 @@ norns.power = function(present) --print("power: "..present) end +--- stat handler +norns.stat = function(disk, temp, cpu) + --print("stat",disk,temp,cpu) + norns.disk = disk + norns.temp = temp + norns.cpu = cpu +end + + --- key callback (redefined in menu) norns.key = function(n,z) --print ("norns.key "..n.." "..z) diff --git a/matron/src/event_types.h b/matron/src/event_types.h index 4b1926efc..1b9e4190c 100644 --- a/matron/src/event_types.h +++ b/matron/src/event_types.h @@ -19,6 +19,8 @@ typedef enum { EVENT_BATTERY, // power cable present EVENT_POWER, + // stat update (disk, temp, cpu) + EVENT_STAT, // libmonome device added EVENT_MONOME_ADD, // libmonome device removed @@ -166,6 +168,13 @@ struct event_power { uint8_t present; }; // +8 +struct event_stat { + struct event_common common; + uint16_t disk; + uint8_t temp; + uint8_t cpu; +}; + struct event_enc { struct event_common common; uint8_t n; @@ -203,7 +212,7 @@ struct event_startup_ready_ok { }; // + 0 struct event_startup_ready_timeout { - struct event_common common; + struct event_common common; }; // + 0 union event_data { @@ -223,6 +232,7 @@ union event_data { struct event_enc enc; struct event_battery battery; struct event_power power; + struct event_stat stat; struct event_metro metro; struct event_poll_value poll_value; struct event_poll_data poll_data; diff --git a/matron/src/events.c b/matron/src/events.c index 1e540a4ab..04fb3fbbd 100644 --- a/matron/src/events.c +++ b/matron/src/events.c @@ -13,6 +13,7 @@ #include "gpio.h" #include "oracle.h" #include "battery.h" +#include "stat.h" #include "weaver.h" #include "event_types.h" @@ -184,6 +185,9 @@ static void handle_event(union event_data *ev) { case EVENT_POWER: w_handle_power(ev->power.present); break; + case EVENT_STAT: + w_handle_stat(ev->stat.disk, ev->stat.temp, ev->stat.cpu); + break; case EVENT_MONOME_ADD: w_handle_monome_add(ev->monome_add.dev); break; diff --git a/matron/src/hardware/stat.c b/matron/src/hardware/stat.c new file mode 100644 index 000000000..6ff14bc9a --- /dev/null +++ b/matron/src/hardware/stat.c @@ -0,0 +1,134 @@ +/* + * stat.c + * + * hardware status monitoring + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "events.h" + +#define STAT_INTERVAL 2 + +//static int fd[3]; +//static char buf[8]; +static pthread_t p; + +void *stat_check(void *); + +// extern def + +void stat_init() { + if (pthread_create(&p, NULL, stat_check, 0) ) { + fprintf(stderr, "STAT: Error creating thread\n"); + } +} + +void stat_deinit() { + pthread_cancel(p); +} + +void *stat_check(void *x) { + (void)x; + int number = -1; + int disk = 0; + int temp = 0; + int cpu = 0; + int _disk = -1; + int _temp = -1; + int _cpu = -1; + + FILE *fd; + char buf[64]; + char bufsub[8]; + + uint32_t user, nice, system, idle, iowait, irq, softirq, steal; + uint32_t sumidle=0, prevsumidle=0, sumnonidle=0, total=0, prevtotal=0; + int32_t totald, idled; + + while (1) { + number++; + if(number==5) number=0; + + // check disk ever 5 sleeps + if(number==0) { + if ((fd = popen("df -l | grep '/dev/root' | awk '{print $4}'", "r")) == NULL) { + fprintf(stderr,"Error opening pipe: disk free read\n"); + } + else { + while (fgets(buf, 12, fd) != NULL) { + disk = atoi(buf) / 1000; // convert to MB + //fprintf(stderr,"disk free: %d\n", disk); + } + } + pclose(fd); + } + + // check temp + if ((fd = popen("vcgencmd measure_temp", "r")) == NULL) { + fprintf(stderr,"Error opening pipe: temp read\n"); + } + else { + while (fgets(buf, 16, fd) != NULL) { + strncpy(bufsub,buf+5,2); + temp = atoi(bufsub); + //fprintf(stderr,"temp: %d\r\n", temp); + } + } + pclose(fd); + + // check cpu + if ((fd = popen("head -n1 /proc/stat", "r")) == NULL) { + fprintf(stderr,"Error opening pipe: cpu read\n"); + } + else { + while (fgets(buf, 64, fd) != NULL) { + //fprintf(stderr,"%s\n", buf); + strtok(buf," "); + user = atoi(strtok(NULL," ")); + nice = atoi(strtok(NULL," ")); + system = atoi(strtok(NULL," ")); + idle = atoi(strtok(NULL," ")); + iowait = atoi(strtok(NULL," ")); + irq = atoi(strtok(NULL," ")); + softirq = atoi(strtok(NULL," ")); + steal = atoi(strtok(NULL," ")); + + prevsumidle = sumidle; + sumidle = idle + iowait; + sumnonidle = user + nice + system + irq + softirq + steal; + prevtotal = total; + total = sumnonidle + sumidle; + totald = total - prevtotal; + idled = sumidle - prevsumidle; + cpu = 100 * (totald - idled) / totald; + + //fprintf(stderr,"%d\n", cpu); + } + } + pclose(fd); + + + if(_disk != disk || _temp != temp || _cpu != cpu) { + _disk = disk; + _temp = temp; + _cpu = cpu; + + union event_data *ev = event_data_new(EVENT_STAT); + ev->stat.disk = disk; + ev->stat.temp = temp; + ev->stat.cpu = cpu; + event_post(ev); + } + + sleep(STAT_INTERVAL); + } +} diff --git a/matron/src/hardware/stat.h b/matron/src/hardware/stat.h new file mode 100644 index 000000000..6a8c83a8c --- /dev/null +++ b/matron/src/hardware/stat.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +extern void stat_init(void); +extern void stat_deinit(void); diff --git a/matron/src/main.c b/matron/src/main.c index 11796aaff..a4572fef9 100644 --- a/matron/src/main.c +++ b/matron/src/main.c @@ -21,6 +21,7 @@ #include "osc.h" #include "metro.h" #include "screen.h" +#include "stat.h" #include "oracle.h" #include "weaver.h" @@ -36,6 +37,7 @@ void cleanup(void) { i2c_deinit(); screen_deinit(); battery_deinit(); + stat_deinit(); fprintf(stderr, "matron shutdown complete\n"); exit(0); @@ -52,31 +54,16 @@ int main(int argc, char **argv) { metros_init(); gpio_init(); battery_init(); + stat_init(); i2c_init(); osc_init(); - - o_init(); // oracle (audio) - - /* - norns_hello_init(); - - // wait here for a signal from the audio server... - fprintf(stderr, "waiting for crone...\n"); - do { - norns_hello(1); - usleep(5000); - } while(o_ready() != 1); - // fade out - while(norns_hello(0)) { - usleep(5000); - } - */ + o_init(); // oracle (audio) w_init(); // weaver (scripting) dev_list_init(); dev_monitor_init(); - + // now is a good time to set our cleanup atexit(cleanup); // start reading input to interpreter diff --git a/matron/src/weaver.c b/matron/src/weaver.c index 33a8ec26d..8b117e2cc 100644 --- a/matron/src/weaver.c +++ b/matron/src/weaver.c @@ -1611,6 +1611,17 @@ void w_handle_power(const int present) { l_report(lvm, l_docall(lvm, 1, 0)); } +// stat +void w_handle_stat(const uint32_t disk, const uint16_t temp, const uint16_t cpu) { + lua_getglobal(lvm, "norns"); + lua_getfield(lvm, -1, "stat"); + lua_remove(lvm, -2); + lua_pushinteger(lvm, disk); + lua_pushinteger(lvm, temp); + lua_pushinteger(lvm, cpu); + l_report(lvm, l_docall(lvm, 3, 0)); +} + void w_handle_poll_value(int idx, float val) { // fprintf(stderr, "_handle_poll_value: %d, %f\n", idx, val); lua_getglobal(lvm, "norns"); diff --git a/matron/src/weaver.h b/matron/src/weaver.h index 0233c355c..d12d015cf 100644 --- a/matron/src/weaver.h +++ b/matron/src/weaver.h @@ -62,6 +62,9 @@ extern void w_handle_enc(const int n, const int delta); extern void w_handle_battery(const int percent, const int current); extern void w_handle_power(const int present); +//--- system/stat +extern void w_handle_stat(const uint32_t disk, const uint16_t temp, const uint16_t cpu); + //--- metro bang handler extern void w_handle_metro(const int idx, const int stage); diff --git a/matron/wscript b/matron/wscript index ab96a0cc4..8697164c6 100644 --- a/matron/wscript +++ b/matron/wscript @@ -13,6 +13,7 @@ def build(bld): 'src/hardware/gpio.c', 'src/hardware/i2c.c', 'src/hardware/screen.c', + 'src/hardware/stat.c', 'src/args.c', 'src/events.c', 'src/hello.c',