API returns the simple device history with the 'notify' command
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
diff --git a/README b/README
index 2999368..0aaf211 100644
--- a/README
+++ b/README
@@ -723,7 +723,7 @@ The list of requests - a (*) means it requires privileged access - and replies a
stating the results of setting GPU N clock to V MHz
gpufan|N,V (*)
- none There is no reply section just the STATUS section
+ none There is no reply section just the STATUS section
stating the results of setting GPU N fan speed to V%
gpuvddc|N,V (*)
@@ -738,6 +738,9 @@ The list of requests - a (*) means it requires privileged access - and replies a
quit (*) none There is no status section but just a single "BYE|"
reply before cgminer quits
+ notify NOTIFY The last status and history count of each devices problem
+ e.g. NOTIFY=0,Name=GPU,ID=0,Last Well=1332432290,...|
+
privileged (*)
none There is no reply section just the STATUS section
stating an error if you do not have privileged access
diff --git a/api.c b/api.c
index 8991c15..a3582cf 100644
--- a/api.c
+++ b/api.c
@@ -222,6 +222,7 @@ static const char *OSINFO =
#define _GPUS "GPUS"
#define _PGAS "PGAS"
#define _CPUS "CPUS"
+#define _NOTIFY "NOTIFY"
#define _BYE "BYE"
static const char ISJSON = '{';
@@ -251,6 +252,7 @@ static const char ISJSON = '{';
#define JSON_GPUS JSON1 _GPUS JSON2
#define JSON_PGAS JSON1 _PGAS JSON2
#define JSON_CPUS JSON1 _CPUS JSON2
+#define JSON_NOTIFY JSON1 _NOTIFY JSON2
#define JSON_BYE JSON1 _BYE JSON1
#define JSON_CLOSE JSON3
#define JSON_END JSON4
@@ -325,6 +327,7 @@ static const char *JSON_PARAMETER = "parameter";
#endif
#define MSG_NUMPGA 59
+#define MSG_NOTIFY 60
enum code_severity {
SEVERITY_ERR,
@@ -440,6 +443,7 @@ struct CODES {
{ SEVERITY_ERR, MSG_INVPDP, PARAM_STR, "Invalid addpool details '%s'" },
{ SEVERITY_ERR, MSG_TOOMANYP,PARAM_NONE, "Reached maximum number of pools (%d)" },
{ SEVERITY_SUCC, MSG_ADDPOOL, PARAM_STR, "Added pool '%s'" },
+ { SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" },
{ SEVERITY_FAIL, 0, 0, NULL }
};
@@ -1596,6 +1600,97 @@ void privileged(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool is
strcpy(io_buffer, message(MSG_ACCOK, 0, NULL, isjson));
}
+void notifystatus(int device, struct cgpu_info *cgpu, bool isjson)
+{
+ char buf[BUFSIZ];
+ char *reason;
+
+ if (cgpu->device_last_not_well == 0)
+ reason = REASON_NONE;
+ else
+ switch(cgpu->device_not_well_reason) {
+ case REASON_THREAD_FAIL_INIT:
+ reason = REASON_THREAD_FAIL_INIT_STR;
+ break;
+ case REASON_THREAD_ZERO_HASH:
+ reason = REASON_THREAD_ZERO_HASH_STR;
+ break;
+ case REASON_THREAD_FAIL_QUEUE:
+ reason = REASON_THREAD_FAIL_QUEUE_STR;
+ break;
+ case REASON_DEV_SICK_IDLE_60:
+ reason = REASON_DEV_SICK_IDLE_60_STR;
+ break;
+ case REASON_DEV_DEAD_IDLE_600:
+ reason = REASON_DEV_DEAD_IDLE_600_STR;
+ break;
+ case REASON_DEV_NOSTART:
+ reason = REASON_DEV_NOSTART_STR;
+ break;
+ case REASON_DEV_OVER_HEAT:
+ reason = REASON_DEV_OVER_HEAT_STR;
+ break;
+ case REASON_DEV_THERMAL_CUTOFF:
+ reason = REASON_DEV_THERMAL_CUTOFF_STR;
+ break;
+ default:
+ reason = REASON_UNKNOWN_STR;
+ break;
+ }
+
+ 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);
+
+ strcat(io_buffer, buf);
+}
+
+static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
+{
+ int devcount = 0;
+ int i;
+
+ for (i = 0; i < total_devices; i++) {
+ if (devices[i]->deven == DEV_ENABLED) {
+ devcount++;
+ break;
+ }
+ }
+
+ if (devcount == 0) {
+ strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson));
+ return;
+ }
+
+ strcpy(io_buffer, message(MSG_NOTIFY, 0, NULL, isjson));
+
+ if (isjson) {
+ strcat(io_buffer, COMMA);
+ strcat(io_buffer, JSON_NOTIFY);
+ }
+
+ devcount = 0;
+ for (i = 0; i < total_devices; i++)
+ if (devices[i]->deven == DEV_ENABLED)
+ notifystatus(devcount++, devices[i], isjson);
+
+ if (isjson)
+ strcat(io_buffer, JSON_CLOSE);
+}
+
void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
{
FILE *fcfg;
@@ -1652,6 +1747,7 @@ struct CMDS {
{ "save", dosave, true },
{ "quit", doquit, true },
{ "privileged", privileged, true },
+ { "notify", notify, false },
{ NULL, NULL, false }
};
diff --git a/miner.h b/miner.h
index 5c04cfa..f244e81 100644
--- a/miner.h
+++ b/miner.h
@@ -232,6 +232,17 @@ enum dev_reason {
REASON_DEV_THERMAL_CUTOFF,
};
+#define REASON_NONE "None"
+#define REASON_THREAD_FAIL_INIT_STR "Thread failed to init"
+#define REASON_THREAD_ZERO_HASH_STR "Thread got zero hashes"
+#define REASON_THREAD_FAIL_QUEUE_STR "Thread failed to queue work"
+#define REASON_DEV_SICK_IDLE_60_STR "Device idle for 60s"
+#define REASON_DEV_DEAD_IDLE_600_STR "Device dead - idle for 600s"
+#define REASON_DEV_NOSTART_STR "Device failed to start"
+#define REASON_DEV_OVER_HEAT_STR "Device over heated"
+#define REASON_DEV_THERMAL_CUTOFF_STR "Device reached thermal cutoff"
+#define REASON_UNKNOWN_STR "Unknown reason - code bug"
+
struct cgpu_info {
int cgminer_id;
struct device_api *api;