diff --git a/README b/README index ec926c76..c9c6eb4c 100644 --- a/README +++ b/README @@ -55,6 +55,7 @@ CGMiner specific configuration options: --disable-adl Override detection and disable building with adl --enable-bitforce Compile support for BitForce FPGAs(default disabled) --enable-icarus Compile support for Icarus Board(default disabled) + --enable-ztex Compile support for Ztex Board(default disabled) Basic *nix build instructions: To build with GPU mining support: @@ -193,7 +194,7 @@ GPU only options: --worksize|-w Override detected optimal worksize - one value or comma separated list -FPGA mining boards(BitForce, Icarus) only options: +FPGA mining boards(BitForce, Icarus, Ztex) only options: --scan-serial|-S Serial port to probe for FPGA mining device @@ -612,7 +613,7 @@ An example request in both formats to set GPU 0 fan to 80%: The format of each reply (unless stated otherwise) is a STATUS section followed by an optional detail section -From API verion 1.7 onwards, reply strings in JSON and Text have the +From API version 1.7 onwards, reply strings in JSON and Text have the necessary escaping as required to avoid ambiguity - they didn't before 1.7 For JSON the 2 characters '"' and '\' are escaped with a '\' before them For Text the 4 characters '|' ',' '=' and '\' are escaped the same way @@ -647,7 +648,7 @@ The STATUS section is: This defaults to the cgminer version but is the value of --api-description if it was specified at runtime. -For API version 1.7: +For API version 1.8: The list of requests - a (*) means it requires privileged access - and replies are: @@ -772,6 +773,8 @@ The list of requests - a (*) means it requires privileged access - and replies a reply before cgminer quits notify NOTIFY The last status and history count of each devices problem + This lists all devices including those not supported + by the 'devs' command e.g. NOTIFY=0,Name=GPU,ID=0,Last Well=1332432290,...| privileged (*) @@ -791,6 +794,11 @@ The list of requests - a (*) means it requires privileged access - and replies a stating the results of the disable request This is only available if PGA mining is enabled + devdetails DEVDETAILS Each device with a list of their static details + This lists all devices including those not supported + by the 'devs' command + e.g. DEVDETAILS=0,Name=GPU,ID=0,Driver=opencl,...| + When you enable, disable or restart a GPU or PGA, you will also get Thread messages in the cgminer status window @@ -1052,7 +1060,7 @@ working in the logs? A: http://us.php.net/manual/en/sockets.installation.php Q: What is a PGA? -A: At the moment, cgminer supports 2 FPGA's: Icarus and BitForce. +A: At the moment, cgminer supports 3 FPGA's: Icarus, Ztex and BitForce. They are Field-Programmable Gate Arrays that have been programmed to do Bitcoin mining. Since the acronym needs to be only 3 characters, the "Field-" part has been skipped. diff --git a/api.c b/api.c index 3879686d..81e8313c 100644 --- a/api.c +++ b/api.c @@ -152,12 +152,13 @@ static SOCKETTYPE sock = INVSOCK; static const char *UNAVAILABLE = " - API will not be available"; -//static const char *BLANK = ""; +static const char *BLANK = ""; static const char *COMMA = ","; static const char SEPARATOR = '|'; +#define SEPSTR "|" static const char GPUSEP = ','; -static const char *APIVERSION = "1.7"; +static const char *APIVERSION = "1.8"; static const char *DEAD = "Dead"; static const char *SICK = "Sick"; static const char *NOSTART = "NoStart"; @@ -179,6 +180,9 @@ static const char *DEVICECODE = "" #ifdef USE_ICARUS "ICA " #endif +#ifdef USE_ZTEX + "ZTX " +#endif #ifdef WANT_CPUMINE "CPU " #endif @@ -211,7 +215,7 @@ static const char *OSINFO = #define _MINECON "CONFIG" #define _GPU "GPU" -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) #define _PGA "PGA" #endif @@ -223,6 +227,7 @@ static const char *OSINFO = #define _PGAS "PGAS" #define _CPUS "CPUS" #define _NOTIFY "NOTIFY" +#define _DEVDETAILS "DEVDETAILS" #define _BYE "BYE" static const char ISJSON = '{'; @@ -241,7 +246,7 @@ static const char ISJSON = '{'; #define JSON_MINECON JSON1 _MINECON JSON2 #define JSON_GPU JSON1 _GPU JSON2 -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) #define JSON_PGA JSON1 _PGA JSON2 #endif @@ -253,6 +258,7 @@ static const char ISJSON = '{'; #define JSON_PGAS JSON1 _PGAS JSON2 #define JSON_CPUS JSON1 _CPUS JSON2 #define JSON_NOTIFY JSON1 _NOTIFY JSON2 +#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2 #define JSON_BYE JSON1 _BYE JSON1 #define JSON_CLOSE JSON3 #define JSON_END JSON4 @@ -320,7 +326,7 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_TOOMANYP 54 #define MSG_ADDPOOL 55 -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) #define MSG_PGANON 56 #define MSG_PGADEV 57 #define MSG_INVPGA 58 @@ -329,7 +335,7 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_NUMPGA 59 #define MSG_NOTIFY 60 -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) #define MSG_PGALRENA 61 #define MSG_PGALRDIS 62 #define MSG_PGAENA 63 @@ -340,6 +346,7 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_REMLASTP 66 #define MSG_ACTPOOL 67 #define MSG_REMPOOL 68 +#define MSG_DEVDETAILS 69 enum code_severity { SEVERITY_ERR, @@ -385,7 +392,7 @@ struct CODES { { SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" }, { SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, "%d GPU(s)" -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) " - %d PGA(s)" #endif #ifdef WANT_CPUMINE @@ -394,7 +401,7 @@ struct CODES { }, { SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs" -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) "/PGAs" #endif #ifdef WANT_CPUMINE @@ -408,7 +415,7 @@ struct CODES { { SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" }, { SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" }, { SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" }, -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) { SEVERITY_ERR, MSG_PGANON, PARAM_NONE, "No PGAs" }, { SEVERITY_SUCC, MSG_PGADEV, PARAM_PGA, "PGA%d" }, { SEVERITY_ERR, MSG_INVPGA, PARAM_PGAMAX, "Invalid PGA id %d - range is 0 - %d" }, @@ -464,6 +471,7 @@ struct CODES { { SEVERITY_ERR, MSG_ACTPOOL, PARAM_POOL, "Cannot remove active pool %d:'%s'" }, { SEVERITY_SUCC, MSG_REMPOOL, PARAM_BOTH, "Removed pool %d:'%s'" }, { SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" }, + { SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" }, { SEVERITY_FAIL, 0, 0, NULL } }; @@ -490,6 +498,10 @@ extern struct device_api bitforce_api; extern struct device_api icarus_api; #endif +#ifdef USE_ZTEX +extern struct device_api ztex_api; +#endif + // This is only called when expected to be needed (rarely) // i.e. strings outside of the codes control (input from the user) static char *escape_string(char *str, bool isjson) @@ -552,7 +564,7 @@ static char *escape_string(char *str, bool isjson) return buf; } -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) static int numpgas() { int count = 0; @@ -566,6 +578,10 @@ static int numpgas() #ifdef USE_ICARUS if (devices[i]->api == &icarus_api) count++; +#endif +#ifdef USE_ZTEX + if (devices[i]->api == &ztex_api) + count++; #endif } return count; @@ -584,6 +600,10 @@ static int pgadevice(int pgaid) #ifdef USE_ICARUS if (devices[i]->api == &icarus_api) count++; +#endif +#ifdef USE_ZTEX + if (devices[i]->api == &ztex_api) + count++; #endif if (count == (pgaid + 1)) return i; @@ -599,7 +619,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) { char severity; char *ptr; -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) int pga; #endif #ifdef WANT_CPUMINE @@ -625,10 +645,10 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) break; } - if (isjson) - sprintf(msg_buffer, JSON_START JSON_STATUS "{\"" _STATUS "\":\"%c\",\"When\":%lu,\"Code\":%d,\"Msg\":\"", severity, (unsigned long)when, messageid); - else - sprintf(msg_buffer, _STATUS "=%c,When=%lu,Code=%d,Msg=", severity, (unsigned long)when, messageid); + sprintf(msg_buffer, isjson + ? JSON_START JSON_STATUS "{\"" _STATUS "\":\"%c\",\"When\":%lu,\"Code\":%d,\"Msg\":\"" + : _STATUS "=%c,When=%lu,Code=%d,Msg=", + severity, (unsigned long)when, messageid); ptr = msg_buffer + strlen(msg_buffer); @@ -644,7 +664,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) case PARAM_GPUMAX: sprintf(ptr, codes[i].description, paramid, nDevs - 1); break; -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) case PARAM_PGAMAX: pga = numpgas(); sprintf(ptr, codes[i].description, paramid, pga - 1); @@ -666,7 +686,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) sprintf(ptr, codes[i].description, paramid, total_pools - 1); break; case PARAM_DMAX: -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) pga = numpgas(); #endif #ifdef WANT_CPUMINE @@ -677,7 +697,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) #endif sprintf(ptr, codes[i].description, nDevs -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) , pga #endif #ifdef WANT_CPUMINE @@ -701,35 +721,30 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) ptr = msg_buffer + strlen(msg_buffer); - if (isjson) - sprintf(ptr, "\",\"Description\":\"%s\"}" JSON_CLOSE, opt_api_description); - else - sprintf(ptr, ",Description=%s%c", opt_api_description, SEPARATOR); + sprintf(ptr, isjson + ? "\",\"Description\":\"%s\"}" JSON_CLOSE + : ",Description=%s" SEPSTR, + opt_api_description); return msg_buffer; } } - if (isjson) - sprintf(msg_buffer, JSON_START JSON_STATUS "{\"" _STATUS "\":\"F\",\"When\":%lu,\"Code\":-1,\"Msg\":\"%d\",\"Description\":\"%s\"}" JSON_CLOSE, - (unsigned long)when, messageid, opt_api_description); - else - sprintf(msg_buffer, _STATUS "=F,When=%lu,Code=-1,Msg=%d,Description=%s%c", - (unsigned long)when, messageid, opt_api_description, SEPARATOR); + sprintf(msg_buffer, isjson + ? JSON_START JSON_STATUS "{\"" _STATUS "\":\"F\",\"When\":%lu,\"Code\":-1,\"Msg\":\"%d\",\"Description\":\"%s\"}" JSON_CLOSE + : _STATUS "=F,When=%lu,Code=-1,Msg=%d,Description=%s" SEPSTR, + (unsigned long)when, messageid, opt_api_description); return msg_buffer; } static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) { - if (isjson) - sprintf(io_buffer, "%s," JSON_VERSION "{\"CGMiner\":\"%s\",\"API\":\"%s\"}" JSON_CLOSE, - message(MSG_VERSION, 0, NULL, isjson), - VERSION, APIVERSION); - else - sprintf(io_buffer, "%s" _VERSION ",CGMiner=%s,API=%s%c", - message(MSG_VERSION, 0, NULL, isjson), - VERSION, APIVERSION, SEPARATOR); + sprintf(io_buffer, isjson + ? "%s," JSON_VERSION "{\"CGMiner\":\"%s\",\"API\":\"%s\"}" JSON_CLOSE + : "%s" _VERSION ",CGMiner=%s,API=%s" SEPSTR, + message(MSG_VERSION, 0, NULL, isjson), + VERSION, APIVERSION); } static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) @@ -752,7 +767,7 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, const char *adl = NO; #endif -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) pgacount = numpgas(); #endif @@ -762,10 +777,12 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, strcpy(io_buffer, message(MSG_MINECON, 0, NULL, isjson)); - if (isjson) - sprintf(buf, "," JSON_MINECON "{\"GPU Count\":%d,\"PGA Count\":%d,\"CPU Count\":%d,\"Pool Count\":%d,\"ADL\":\"%s\",\"ADL in use\":\"%s\",\"Strategy\":\"%s\",\"Log Interval\":%d,\"Device Code\":\"%s\",\"OS\":\"%s\"}" JSON_CLOSE, nDevs, pgacount, cpucount, total_pools, adl, adlinuse, strategies[pool_strategy].s, opt_log_interval, DEVICECODE, OSINFO); - else - sprintf(buf, _MINECON ",GPU Count=%d,PGA Count=%d,CPU Count=%d,Pool Count=%d,ADL=%s,ADL in use=%s,Strategy=%s,Log Interval=%d,Device Code=%s,OS=%s%c", nDevs, pgacount, cpucount, total_pools, adl, adlinuse, strategies[pool_strategy].s, opt_log_interval, DEVICECODE, OSINFO, SEPARATOR); + sprintf(buf, isjson + ? "," JSON_MINECON "{\"GPU Count\":%d,\"PGA Count\":%d,\"CPU Count\":%d,\"Pool Count\":%d,\"ADL\":\"%s\",\"ADL in use\":\"%s\",\"Strategy\":\"%s\",\"Log Interval\":%d,\"Device Code\":\"%s\",\"OS\":\"%s\"}" JSON_CLOSE + : _MINECON ",GPU Count=%d,PGA Count=%d,CPU Count=%d,Pool Count=%d,ADL=%s,ADL in use=%s,Strategy=%s,Log Interval=%d,Device Code=%s,OS=%s" SEPSTR, + + nDevs, pgacount, cpucount, total_pools, adl, adlinuse, + strategies[pool_strategy].s, opt_log_interval, DEVICECODE, OSINFO); strcat(io_buffer, buf); } @@ -808,28 +825,21 @@ static void gpustatus(int gpu, bool isjson) else sprintf(intensity, "%d", cgpu->intensity); - if (isjson) - sprintf(buf, "{\"GPU\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"Fan Speed\":%d,\"Fan Percent\":%d,\"GPU Clock\":%d,\"Memory Clock\":%d,\"GPU Voltage\":%.3f,\"GPU Activity\":%d,\"Powertune\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Intensity\":\"%s\",\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}", - gpu, enabled, status, gt, gf, gp, gc, gm, gv, ga, pt, - cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, - cgpu->accepted, cgpu->rejected, cgpu->hw_errors, - cgpu->utility, intensity, - ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, - (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); - else - sprintf(buf, "GPU=%d,Enabled=%s,Status=%s,Temperature=%.2f,Fan Speed=%d,Fan Percent=%d,GPU Clock=%d,Memory Clock=%d,GPU Voltage=%.3f,GPU Activity=%d,Powertune=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Intensity=%s,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c", - gpu, enabled, status, gt, gf, gp, gc, gm, gv, ga, pt, - cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, - cgpu->accepted, cgpu->rejected, cgpu->hw_errors, - cgpu->utility, intensity, - ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, - (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR); + sprintf(buf, isjson + ? "{\"GPU\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"Fan Speed\":%d,\"Fan Percent\":%d,\"GPU Clock\":%d,\"Memory Clock\":%d,\"GPU Voltage\":%.3f,\"GPU Activity\":%d,\"Powertune\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Intensity\":\"%s\",\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}" + : "GPU=%d,Enabled=%s,Status=%s,Temperature=%.2f,Fan Speed=%d,Fan Percent=%d,GPU Clock=%d,Memory Clock=%d,GPU Voltage=%.3f,GPU Activity=%d,Powertune=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Intensity=%s,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f" SEPSTR, + gpu, enabled, status, gt, gf, gp, gc, gm, gv, ga, pt, + cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, + cgpu->accepted, cgpu->rejected, cgpu->hw_errors, + cgpu->utility, intensity, + ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, + (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); strcat(io_buffer, buf); } } -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) static void pgastatus(int pga, bool isjson) { char buf[BUFSIZ]; @@ -843,6 +853,12 @@ static void pgastatus(int pga, bool isjson) return; struct cgpu_info *cgpu = devices[dev]; + double frequency = 0; + +#ifdef USE_ZTEX + if (cgpu->api == &ztex_api && cgpu->device_ztex) + frequency = cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1); +#endif cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; @@ -860,22 +876,15 @@ static void pgastatus(int pga, bool isjson) else status = (char *)ALIVE; - if (isjson) - sprintf(buf, "{\"PGA\":%d,\"Name\":\"%s\",\"ID\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}", - pga, cgpu->api->name, cgpu->device_id, - enabled, status, cgpu->temp, - cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, - cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility, - ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, - (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); - else - sprintf(buf, "PGA=%d,Name=%s,ID=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c", - pga, cgpu->api->name, cgpu->device_id, - enabled, status, cgpu->temp, - cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, - cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility, - ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, - (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR); + sprintf(buf, isjson + ? "{\"PGA\":%d,\"Name\":\"%s\",\"ID\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f,\"Frequency\":%.2f}" + : "PGA=%d,Name=%s,ID=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f,Frequency=%.2f" SEPSTR, + pga, cgpu->api->name, cgpu->device_id, + enabled, status, cgpu->temp, + cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, + cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility, + ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, + (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, frequency); strcat(io_buffer, buf); } @@ -892,22 +901,15 @@ static void cpustatus(int cpu, bool isjson) cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; - if (isjson) - sprintf(buf, "{\"CPU\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}", - cpu, cgpu->total_mhashes / total_secs, - opt_log_interval, cgpu->rolling, - cgpu->accepted, cgpu->rejected, - cgpu->utility, - ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, - (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); - else - sprintf(buf, "CPU=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c", - cpu, cgpu->total_mhashes / total_secs, - opt_log_interval, cgpu->rolling, - cgpu->accepted, cgpu->rejected, - cgpu->utility, - ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, - (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR); + sprintf(buf, isjson + ? "{\"CPU\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}" + : "CPU=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f" SEPSTR, + cpu, cgpu->total_mhashes / total_secs, + opt_log_interval, cgpu->rolling, + cgpu->accepted, cgpu->rejected, + cgpu->utility, + ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, + (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); strcat(io_buffer, buf); } @@ -917,9 +919,14 @@ static void cpustatus(int cpu, bool isjson) static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) { int devcount = 0; + int numpga = 0; int i; - if (nDevs == 0 && opt_n_threads == 0) { +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) + numpga = numpgas(); +#endif + + if (nDevs == 0 && opt_n_threads == 0 && numpga == 0) { strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson)); return; } @@ -940,9 +947,7 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b devcount++; } -#if defined(USE_BITFORCE) || defined(USE_ICARUS) - int numpga = numpgas(); - +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) if (numpga > 0) for (i = 0; i < numpga; i++) { if (isjson && devcount > 0) @@ -1003,7 +1008,7 @@ static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson) strcat(io_buffer, JSON_CLOSE); } -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson) { int numpga = numpgas(); @@ -1207,27 +1212,18 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, rpc_url = escape_string(pool->rpc_url, isjson); rpc_user = escape_string(pool->rpc_user, isjson); - if (isjson) - sprintf(buf, "%s{\"POOL\":%d,\"URL\":\"%s\",\"Status\":\"%s\",\"Priority\":%d,\"Long Poll\":\"%s\",\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Remote Failures\":%d,\"User\":\"%s\"}", - (i > 0) ? COMMA : "", - i, rpc_url, status, pool->prio, lp, - pool->getwork_requested, - pool->accepted, pool->rejected, - pool->discarded_work, - pool->stale_shares, - pool->getfail_occasions, - pool->remotefail_occasions, - rpc_user); - else - sprintf(buf, "POOL=%d,URL=%s,Status=%s,Priority=%d,Long Poll=%s,Getworks=%d,Accepted=%d,Rejected=%d,Discarded=%d,Stale=%d,Get Failures=%d,Remote Failures=%d,User=%s%c", - i, rpc_url, status, pool->prio, lp, - pool->getwork_requested, - pool->accepted, pool->rejected, - pool->discarded_work, - pool->stale_shares, - pool->getfail_occasions, - pool->remotefail_occasions, - rpc_user, SEPARATOR); + sprintf(buf, isjson + ? "%s{\"POOL\":%d,\"URL\":\"%s\",\"Status\":\"%s\",\"Priority\":%d,\"Long Poll\":\"%s\",\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Remote Failures\":%d,\"User\":\"%s\"}" + : "%sPOOL=%d,URL=%s,Status=%s,Priority=%d,Long Poll=%s,Getworks=%d,Accepted=%d,Rejected=%d,Discarded=%d,Stale=%d,Get Failures=%d,Remote Failures=%d,User=%s" SEPSTR, + (isjson && (i > 0)) ? COMMA : BLANK, + i, rpc_url, status, pool->prio, lp, + pool->getwork_requested, + pool->accepted, pool->rejected, + pool->discarded_work, + pool->stale_shares, + pool->getfail_occasions, + pool->remotefail_occasions, + rpc_user); strcat(io_buffer, buf); @@ -1258,35 +1254,23 @@ static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, boo mhs = total_mhashes_done / total_secs; #ifdef WANT_CPUMINE - if (isjson) - sprintf(io_buffer, "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"Algorithm\":\"%s\",\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE, - message(MSG_SUMM, 0, NULL, isjson), - total_secs, algo, mhs, found_blocks, - total_getworks, total_accepted, total_rejected, - hw_errors, utility, total_discarded, total_stale, - total_go, local_work, total_ro, new_blocks, total_mhashes_done); - else - sprintf(io_buffer, "%s" _SUMMARY ",Elapsed=%.0f,Algorithm=%s,MHS av=%.2f,Found Blocks=%d,Getworks=%d,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Discarded=%d,Stale=%d,Get Failures=%d,Local Work=%u,Remote Failures=%u,Network Blocks=%u,Total MH=%.4f%c", - message(MSG_SUMM, 0, NULL, isjson), - total_secs, algo, mhs, found_blocks, - total_getworks, total_accepted, total_rejected, - hw_errors, utility, total_discarded, total_stale, - total_go, local_work, total_ro, new_blocks, total_mhashes_done, SEPARATOR); + sprintf(io_buffer, isjson + ? "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"Algorithm\":\"%s\",\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE + : "%s" _SUMMARY ",Elapsed=%.0f,Algorithm=%s,MHS av=%.2f,Found Blocks=%d,Getworks=%d,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Discarded=%d,Stale=%d,Get Failures=%d,Local Work=%u,Remote Failures=%u,Network Blocks=%u,Total MH=%.4f" SEPSTR, + message(MSG_SUMM, 0, NULL, isjson), + total_secs, algo, mhs, found_blocks, + total_getworks, total_accepted, total_rejected, + hw_errors, utility, total_discarded, total_stale, + total_go, local_work, total_ro, new_blocks, total_mhashes_done); #else - if (isjson) - sprintf(io_buffer, "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE, - message(MSG_SUMM, 0, NULL, isjson), - total_secs, mhs, found_blocks, - total_getworks, total_accepted, total_rejected, - hw_errors, utility, total_discarded, total_stale, - total_go, local_work, total_ro, new_blocks, total_mhashes_done); - else - sprintf(io_buffer, "%s" _SUMMARY ",Elapsed=%.0f,MHS av=%.2f,Found Blocks=%d,Getworks=%d,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Discarded=%d,Stale=%d,Get Failures=%d,Local Work=%u,Remote Failures=%u,Network Blocks=%u,Total MH=%.4f%c", - message(MSG_SUMM, 0, NULL, isjson), - total_secs, mhs, found_blocks, - total_getworks, total_accepted, total_rejected, - hw_errors, utility, total_discarded, total_stale, - total_go, local_work, total_ro, new_blocks, total_mhashes_done, SEPARATOR); + sprintf(io_buffer, isjson + ? "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE + : "%s" _SUMMARY ",Elapsed=%.0f,MHS av=%.2f,Found Blocks=%d,Getworks=%d,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Discarded=%d,Stale=%d,Get Failures=%d,Local Work=%u,Remote Failures=%u,Network Blocks=%u,Total MH=%.4f" SEPSTR, + message(MSG_SUMM, 0, NULL, isjson), + total_secs, mhs, found_blocks, + total_getworks, total_accepted, total_rejected, + hw_errors, utility, total_discarded, total_stale, + total_go, local_work, total_ro, new_blocks, total_mhashes_done); #endif } @@ -1397,10 +1381,10 @@ static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo strcpy(io_buffer, message(MSG_NUMGPU, 0, NULL, isjson)); - if (isjson) - sprintf(buf, "," JSON_GPUS "{\"Count\":%d}" JSON_CLOSE, nDevs); - else - sprintf(buf, _GPUS ",Count=%d%c", nDevs, SEPARATOR); + sprintf(buf, isjson + ? "," JSON_GPUS "{\"Count\":%d}" JSON_CLOSE + : _GPUS ",Count=%d" SEPSTR, + nDevs); strcat(io_buffer, buf); } @@ -1410,16 +1394,16 @@ static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo char buf[BUFSIZ]; int count = 0; -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) count = numpgas(); #endif strcpy(io_buffer, message(MSG_NUMPGA, 0, NULL, isjson)); - if (isjson) - sprintf(buf, "," JSON_PGAS "{\"Count\":%d}" JSON_CLOSE, count); - else - sprintf(buf, _PGAS ",Count=%d%c", count, SEPARATOR); + sprintf(buf, isjson + ? "," JSON_PGAS "{\"Count\":%d}" JSON_CLOSE + : _PGAS ",Count=%d" SEPSTR, + count); strcat(io_buffer, buf); } @@ -1435,10 +1419,10 @@ static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo strcpy(io_buffer, message(MSG_NUMCPU, 0, NULL, isjson)); - if (isjson) - sprintf(buf, "," JSON_CPUS "{\"Count\":%d}" JSON_CLOSE, count); - else - sprintf(buf, _CPUS ",Count=%d%c", count, SEPARATOR); + sprintf(buf, isjson + ? "," JSON_CPUS "{\"Count\":%d}" JSON_CLOSE + : _CPUS ",Count=%d" SEPSTR, + count); strcat(io_buffer, buf); } @@ -1890,22 +1874,16 @@ void notifystatus(int device, struct cgpu_info *cgpu, bool isjson) // ALL counters (and only counters) must start the name with a '*' // Simplifies future external support for adding new counters - if (isjson) - sprintf(buf, "%s{\"NOTIFY\":%d,\"Name\":\"%s\",\"ID\":%d,\"Last Well\":%lu,\"Last Not Well\":%lu,\"Reason Not Well\":\"%s\",\"*Thread Fail Init\":%d,\"*Thread Zero Hash\":%d,\"*Thread Fail Queue\":%d,\"*Dev Sick Idle 60s\":%d,\"*Dev Dead Idle 600s\":%d,\"*Dev Nostart\":%d,\"*Dev Over Heat\":%d,\"*Dev Thermal Cutoff\":%d}" JSON_CLOSE, - device > 0 ? "," : "", device, cgpu->api->name, cgpu->device_id, - cgpu->device_last_well, cgpu->device_last_not_well, reason, - cgpu->thread_fail_init_count, cgpu->thread_zero_hash_count, - cgpu->thread_fail_queue_count, cgpu->dev_sick_idle_60_count, - cgpu->dev_dead_idle_600_count, cgpu->dev_nostart_count, - cgpu->dev_over_heat_count, cgpu->dev_thermal_cutoff_count); - else - sprintf(buf, "NOTIFY=%d,Name=%s,ID=%d,Last Well=%lu,Last Not Well=%lu,Reason Not Well=%s,*Thread Fail Init=%d,*Thread Zero Hash=%d,*Thread Fail Queue=%d,*Dev Sick Idle 60s=%d,*Dev Dead Idle 600s=%d,*Dev Nostart=%d,*Dev Over Heat=%d,*Dev Thermal Cutoff=%d%c", - device, cgpu->api->name, cgpu->device_id, - cgpu->device_last_well, cgpu->device_last_not_well, reason, - cgpu->thread_fail_init_count, cgpu->thread_zero_hash_count, - cgpu->thread_fail_queue_count, cgpu->dev_sick_idle_60_count, - cgpu->dev_dead_idle_600_count, cgpu->dev_nostart_count, - cgpu->dev_over_heat_count, cgpu->dev_thermal_cutoff_count, SEPARATOR); + sprintf(buf, isjson + ? "%s{\"NOTIFY\":%d,\"Name\":\"%s\",\"ID\":%d,\"Last Well\":%lu,\"Last Not Well\":%lu,\"Reason Not Well\":\"%s\",\"*Thread Fail Init\":%d,\"*Thread Zero Hash\":%d,\"*Thread Fail Queue\":%d,\"*Dev Sick Idle 60s\":%d,\"*Dev Dead Idle 600s\":%d,\"*Dev Nostart\":%d,\"*Dev Over Heat\":%d,\"*Dev Thermal Cutoff\":%d}" JSON_CLOSE + : "%sNOTIFY=%d,Name=%s,ID=%d,Last Well=%lu,Last Not Well=%lu,Reason Not Well=%s,*Thread Fail Init=%d,*Thread Zero Hash=%d,*Thread Fail Queue=%d,*Dev Sick Idle 60s=%d,*Dev Dead Idle 600s=%d,*Dev Nostart=%d,*Dev Over Heat=%d,*Dev Thermal Cutoff=%d" SEPSTR, + (isjson && (device > 0)) ? COMMA : BLANK, + device, cgpu->api->name, cgpu->device_id, + cgpu->device_last_well, cgpu->device_last_not_well, reason, + cgpu->thread_fail_init_count, cgpu->thread_zero_hash_count, + cgpu->thread_fail_queue_count, cgpu->dev_sick_idle_60_count, + cgpu->dev_dead_idle_600_count, cgpu->dev_nostart_count, + cgpu->dev_over_heat_count, cgpu->dev_thermal_cutoff_count); strcat(io_buffer, buf); } @@ -1933,6 +1911,42 @@ static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool strcat(io_buffer, JSON_CLOSE); } +static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) +{ + char buf[BUFSIZ]; + struct cgpu_info *cgpu; + int i; + + if (total_devices == 0) { + strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson)); + return; + } + + strcpy(io_buffer, message(MSG_DEVDETAILS, 0, NULL, isjson)); + + if (isjson) { + strcat(io_buffer, COMMA); + strcat(io_buffer, JSON_DEVDETAILS); + } + + for (i = 0; i < total_devices; i++) { + cgpu = devices[i]; + + sprintf(buf, isjson + ? "%s{\"DEVDETAILS\":%d,\"Name\":\"%s\",\"ID\":%d,\"Driver\":\"%s\",\"Kernel\":\"%s\",\"Model\":\"%s\",\"Device Path\":\"%s\"}" + : "%sDEVDETAILS=%d,Name=%s,ID=%d,Driver=%s,Kernel=%s,Model=%s,Device Path=%s" SEPSTR, + (isjson && (i > 0)) ? COMMA : BLANK, + i, cgpu->api->name, cgpu->device_id, + cgpu->api->dname, cgpu->kname ? : BLANK, + cgpu->name ? : BLANK, cgpu->device_path ? : BLANK); + + strcat(io_buffer, buf); + } + + if (isjson) + strcat(io_buffer, JSON_CLOSE); +} + void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson) { FILE *fcfg; @@ -1977,7 +1991,7 @@ struct CMDS { { "gpudisable", gpudisable, true }, { "gpurestart", gpurestart, true }, { "gpu", gpudev, false }, -#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) { "pga", pgadev, false }, { "pgaenable", pgaenable, true }, { "pgadisable", pgadisable, true }, @@ -2002,6 +2016,7 @@ struct CMDS { { "quit", doquit, true }, { "privileged", privileged, true }, { "notify", notify, false }, + { "devdetails", devdetails, false }, { NULL, NULL, false } }; @@ -2015,7 +2030,7 @@ static void send_result(SOCKETTYPE c, bool isjson) len = strlen(io_buffer); - applog(LOG_DEBUG, "API: send reply: (%d) '%.10s%s'", len+1, io_buffer, len > 10 ? "..." : ""); + applog(LOG_DEBUG, "API: send reply: (%d) '%.10s%s'", len+1, io_buffer, len > 10 ? "..." : BLANK); // ignore failure - it's closed immediately anyway n = send(c, io_buffer, len+1, 0); diff --git a/cgminer.c b/cgminer.c index 5fce8aa3..d358a520 100644 --- a/cgminer.c +++ b/cgminer.c @@ -324,10 +324,10 @@ static void applog_and_exit(const char *fmt, ...) } static pthread_mutex_t sharelog_lock; -FILE *sharelog_file = NULL; +static FILE *sharelog_file = NULL; -static void -sharelog(const char*disposition, const struct work*work) { +static void sharelog(const char*disposition, const struct work*work) +{ if (!sharelog_file) return; @@ -361,7 +361,7 @@ sharelog(const char*disposition, const struct work*work) { free(target); free(hash); free(data); - if (rv >= sizeof(s)) + if (rv >= (int)(sizeof(s))) s[sizeof(s) - 1] = '\0'; else if (rv < 0) { diff --git a/miner.php b/miner.php index a8832e40..2441cad8 100644 --- a/miner.php +++ b/miner.php @@ -1,7 +1,7 @@ '; $tableend = '
'; $warnfont = ''; $warnoff = ''; - +$dfmt = 'H:i:s j-M-Y \U\T\CP'; +# +# Ensure it is only ever shown once +global $showndate; +$showndate = false; +# +# For summary page to stop retrying failed rigs +global $rigerror; +$rigerror = array(); # function htmlhead($checkapi) { @@ -80,7 +96,7 @@ $error = null; # function getsock($addr, $port) { - global $error; + global $error, $socktimeoutsec; $socket = null; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); @@ -92,6 +108,11 @@ function getsock($addr, $port) return null; } + // Ignore if this fails since the socket connect may work anyway + // and nothing is gained by aborting if the option cannot be set + // since we don't know in advance if it can connect + socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => $socktimeoutsec, 'usec' => 0)); + $res = socket_connect($socket, $addr, $port); if ($res === false) { @@ -203,6 +224,8 @@ function getparam($name, $both = false) # function fmt($section, $name, $value) { + global $dfmt; + $errorclass = ' class=err'; $warnclass = ' class=warn'; $b = ' '; @@ -325,6 +348,9 @@ function fmt($section, $name, $value) if ($value != 'Y') $class = $warnclass; break; + case 'STATUS.When': + $ret = date($dfmt, $value); + break; } if ($section == 'NOTIFY' && substr($name, 0, 1) == '*' && $value != '0') @@ -346,7 +372,7 @@ function showhead($cmd, $item, $values) foreach ($values as $name => $value) { - if ($name == '0') + if ($name == '0' or $name == '') $name = ' '; echo "$name"; } @@ -360,18 +386,22 @@ function showhead($cmd, $item, $values) # function details($cmd, $list, $rig) { - global $tablebegin, $tableend; + global $tablebegin, $tableend, $dfmt; global $poolcmd, $readonly; - - $dfmt = 'H:i:s j-M-Y \U\T\CP'; + global $showndate; $stas = array('S' => 'Success', 'W' => 'Warning', 'I' => 'Informational', 'E' => 'Error', 'F' => 'Fatal'); echo $tablebegin; - echo 'Date: '.date($dfmt).''; + if ($showndate === false) + { + echo 'Date: '.date($dfmt).''; - echo $tableend.$tablebegin; + echo $tableend.$tablebegin; + + $showndate = true; + } if (isset($list['STATUS'])) { @@ -550,18 +580,23 @@ function process($cmds, $rig) } # # $head is a hack but this is just a demo anyway :) -function doforeach($cmd, $des, $sum, $head) +function doforeach($cmd, $des, $sum, $head, $datetime) { global $miner, $port; global $error, $readonly, $notify, $rigs; - global $tablebegin, $tableend, $warnfont, $warnoff; + global $tablebegin, $tableend, $warnfont, $warnoff, $dfmt; + global $rigerror; $header = $head; $anss = array(); $count = 0; + $preverr = count($rigerror); foreach ($rigs as $rig) { + if (isset($rigerror[$rig])) + continue; + $parts = explode(':', $rig, 2); if (count($parts) == 2) { @@ -574,6 +609,7 @@ function doforeach($cmd, $des, $sum, $head) { echo "Error on rig $count getting $des: "; echo $warnfont.$error.$warnoff.''; + $rigerror[$rig] = $error; $error = null; } else @@ -584,10 +620,56 @@ function doforeach($cmd, $des, $sum, $head) if (count($anss) == 0) { - echo "Failed to access any rigs successfully"; + echo 'Failed to access any rigs successfully'; + if ($preverr > 0) + echo ' (or rigs had previous errors)'; + echo ''; return; } + if ($datetime) + { + echo 'Date: '.date($dfmt).''; + + echo $tableend.$tablebegin; + + $dthead = array('' => 1, 'STATUS' => 1, 'Description' => 1, 'When' => 1); + showhead('', null, $dthead); + + foreach ($anss as $rig => $ans) + { + echo ''; + + foreach ($ans as $item => $row) + { + if ($item != 'STATUS') + continue; + + foreach ($dthead as $name => $x) + { + if ($name == '') + echo ""; + else + { + if (isset($row[$name])) + list($showvalue, $class) = fmt('STATUS', $name, $row[$name]); + else + { + $class = ''; + $showvalue = ' '; + } + echo "$showvalue"; + } + } + } + + echo ''; + } + echo $tableend; + echo '

'; + echo $tablebegin; + } + $total = array(); foreach ($anss as $rig => $ans) @@ -795,15 +877,15 @@ function display() echo $tablebegin; $sum = array('MHS av', 'Getworks', 'Found Blocks', 'Accepted', 'Rejected', 'Discarded', 'Stale', 'Utility', 'Local Work', 'Total MH'); - doforeach('summary', 'summary information', $sum, array()); + doforeach('summary', 'summary information', $sum, array(), true); echo $tableend; echo '

'; echo $tablebegin; - doforeach('devs', 'device list', $sum, array(''=>'','ID'=>'','Name'=>'')); + doforeach('devs', 'device list', $sum, array(''=>'','ID'=>'','Name'=>''), false); echo $tableend; echo '

'; echo $tablebegin; - doforeach('pools', 'pool list', $sum, array(''=>'')); + doforeach('pools', 'pool list', $sum, array(''=>''), false); echo $tableend; } #