Commit f5aad8f52a9ba814360b3af57b1126563db40036

kanoi 2014-03-12T16:18:19

Merge pull request #560 from kanoi/master API - add edevs and estats - to only show enabled devices

diff --git a/API-README b/API-README
index c60f2c9..5643e80 100644
--- a/API-README
+++ b/API-README
@@ -178,6 +178,16 @@ The list of requests - a (*) means it requires privileged access - and replies:
                               Will not report PGAs if PGA mining is disabled
                               Will not report ASCs if ASC mining is disabled
 
+ edevs[|old]   DEVS           The same as devs, except it ignores blacklisted
+                              devices and zombie devices
+                              If you specify the optional 'old' parameter, then
+                              the output will include zombie devices that became
+                              zombies less than 'old' seconds ago
+                              A value of zero for 'old', which is the default,
+                              means ignore all zombies
+                              It will return an empty list of devices if all
+                              devices are blacklisted or zombies
+
  pga|N         PGA            The details of a single PGA number N in the same
                               format and details as for DEVS
                               This is only available if PGA mining is enabled
@@ -293,6 +303,16 @@ The list of requests - a (*) means it requires privileged access - and replies:
                               Device drivers are also able to add stats to the
                               end of the details returned
 
+ estats[|old]  STATS          The same as stats, except it ignores blacklisted
+                              devices, zombie devices and pools
+                              If you specify the optional 'old' parameter, then
+                              the output will include zombie devices that became
+                              zombies less than 'old' seconds ago
+                              A value of zero for 'old', which is the default,
+                              means ignore all zombies
+                              It will return an empty list of devices if all
+                              devices are blacklisted or zombies
+
  check|cmd     COMMAND        Exists=Y/N, <- 'cmd' exists in this version
                               Access=Y/N| <- you have access to use 'cmd'
 
@@ -483,6 +503,14 @@ miner.php - an example web page to access the API
 Feature Changelog for external applications using the API:
 
 
+API V3.3 (cgminer v4.1.1)
+
+Added API commands:
+ 'edevs' - Only enabled devices, for 'devs'
+ 'estats' - Only enabled devices, for 'stats'
+
+---------
+
 API V3.2 (cgminer v4.1.0)
 
 Fix for:
diff --git a/api.c b/api.c
index 3a9891b..3511312 100644
--- a/api.c
+++ b/api.c
@@ -132,7 +132,7 @@ static const char SEPARATOR = '|';
 #define JOIN_CMD "CMD="
 #define BETWEEN_JOIN SEPSTR
 
-static const char *APIVERSION = "3.2";
+static const char *APIVERSION = "3.3";
 static const char *DEAD = "Dead";
 static const char *SICK = "Sick";
 static const char *NOSTART = "NoStart";
@@ -2202,6 +2202,95 @@ static void pgadev(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *p
 		io_close(io_data);
 }
 
+static void edevstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
+{
+	bool io_open = false;
+	int devcount = 0;
+	int numasc = 0;
+	int numpga = 0;
+	int i;
+	time_t howoldsec = 0;
+
+#ifdef HAVE_AN_ASIC
+	numasc = numascs();
+#endif
+
+#ifdef HAVE_AN_FPGA
+	numpga = numpgas();
+#endif
+
+	if (numpga == 0 && numasc == 0) {
+		message(io_data, MSG_NODEVS, 0, NULL, isjson);
+		return;
+	}
+
+	if (param && *param)
+		howoldsec = (time_t)atoi(param);
+
+	message(io_data, MSG_DEVS, 0, NULL, isjson);
+	if (isjson)
+		io_open = io_add(io_data, COMSTR JSON_DEVS);
+
+#ifdef HAVE_AN_ASIC
+	if (numasc > 0) {
+		for (i = 0; i < numasc; i++) {
+#ifdef USE_USBUTILS
+			int dev = ascdevice(i);
+			if (dev < 0) // Should never happen
+				continue;
+
+			struct cgpu_info *cgpu = get_devices(dev);
+			if (!cgpu)
+				continue;
+			if (cgpu->blacklisted)
+				continue;
+			if (cgpu->usbinfo.nodev) {
+				if (howoldsec <= 0)
+					continue;
+				if ((when - cgpu->usbinfo.last_nodev.tv_sec) >= howoldsec)
+					continue;
+			}
+#endif
+
+			ascstatus(io_data, i, isjson, isjson && devcount > 0);
+
+			devcount++;
+		}
+	}
+#endif
+
+#ifdef HAVE_AN_FPGA
+	if (numpga > 0) {
+		for (i = 0; i < numpga; i++) {
+#ifdef USE_USBUTILS
+			int dev = pgadevice(i);
+			if (dev < 0) // Should never happen
+				continue;
+
+			struct cgpu_info *cgpu = get_devices(dev);
+			if (!cgpu)
+				continue;
+			if (cgpu->blacklisted)
+				continue;
+			if (cgpu->usbinfo.nodev) {
+				if (howoldsec <= 0)
+					continue;
+				if ((when - cgpu->usbinfo.last_nodev.tv_sec) >= howoldsec)
+					continue;
+			}
+#endif
+
+			pgastatus(io_data, i, isjson, isjson && devcount > 0);
+
+			devcount++;
+		}
+	}
+#endif
+
+	if (isjson && io_open)
+		io_close(io_data);
+}
+
 static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
 {
 	struct cgpu_info *cgpu;
@@ -3201,6 +3290,52 @@ static void minerstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
 		io_close(io_data);
 }
 
+static void minerestats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
+{
+	struct cgpu_info *cgpu;
+	bool io_open = false;
+	struct api_data *extra;
+	char id[20];
+	int i, j;
+	time_t howoldsec = 0;
+
+	if (param && *param)
+		howoldsec = (time_t)atoi(param);
+
+	message(io_data, MSG_MINESTATS, 0, NULL, isjson);
+	if (isjson)
+		io_open = io_add(io_data, COMSTR JSON_MINESTATS);
+
+	i = 0;
+	for (j = 0; j < total_devices; j++) {
+		cgpu = get_devices(j);
+		if (!cgpu)
+			continue;
+#ifdef USE_USBUTILS
+		if (cgpu->blacklisted)
+			continue;
+		if (cgpu->usbinfo.nodev) {
+			if (howoldsec <= 0)
+				continue;
+			if ((when - cgpu->usbinfo.last_nodev.tv_sec) >= howoldsec)
+				continue;
+		}
+#endif
+		if (cgpu->drv) {
+			if (cgpu->drv->get_api_stats)
+				extra = cgpu->drv->get_api_stats(cgpu);
+			else
+				extra = NULL;
+
+			sprintf(id, "%s%d", cgpu->drv->name, cgpu->device_id);
+			i = itemstats(io_data, i, id, &(cgpu->cgminer_stats), NULL, extra, cgpu, isjson);
+		}
+	}
+
+	if (isjson && io_open)
+		io_close(io_data);
+}
+
 static void failoveronly(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
 {
 	if (param == NULL || *param == '\0') {
@@ -3809,6 +3944,7 @@ struct CMDS {
 	{ "version",		apiversion,	false,	true },
 	{ "config",		minerconfig,	false,	true },
 	{ "devs",		devstatus,	false,	true },
+	{ "edevs",		edevstatus,	false,	true },
 	{ "pools",		poolstatus,	false,	true },
 	{ "summary",		summary,	false,	true },
 #ifdef HAVE_AN_FPGA
@@ -3832,6 +3968,7 @@ struct CMDS {
 	{ "devdetails",		devdetails,	false,	true },
 	{ "restart",		dorestart,	true,	false },
 	{ "stats",		minerstats,	false,	true },
+	{ "estats",		minerestats,	false,	true },
 	{ "check",		checkcommand,	false,	false },
 	{ "failover-only",	failoveronly,	true,	false },
 	{ "coin",		minecoin,	false,	true },