예제 #1
0
파일: battery.c 프로젝트: Civil/collectd
static int read_sysfs_callback (char const *dir, /* {{{ */
		char const *power_supply,
		void *user_data)
{
	int *battery_index = user_data;

	char const *plugin_instance;
	char buffer[32];
	gauge_t v = NAN;
	_Bool discharging = 0;
	int status;

	/* Ignore non-battery directories, such as AC power. */
	status = sysfs_file_to_buffer (dir, power_supply, "type", buffer, sizeof (buffer));
	if (status != 0)
		return (0);
	if (strcasecmp ("Battery", buffer) != 0)
		return (0);

	(void) sysfs_file_to_buffer (dir, power_supply, "status", buffer, sizeof (buffer));
	if (strcasecmp ("Discharging", buffer) == 0)
		discharging = 1;

	/* FIXME: This is a dirty hack for backwards compatibility: The battery
	 * plugin, for a very long time, has had the plugin_instance
	 * hard-coded to "0". So, to keep backwards compatibility, we'll use
	 * "0" for the first battery we find and the power_supply name for all
	 * following. This should be reverted in a future major version. */
	plugin_instance = (*battery_index == 0) ? "0" : power_supply;
	(*battery_index)++;

	if (sysfs_file_to_gauge (dir, power_supply, "energy_now", &v) == 0)
		battery_submit (plugin_instance, "charge", v / 1000000.0);
	if (sysfs_file_to_gauge (dir, power_supply, "power_now", &v) == 0)
	{
		if (discharging)
			battery_submit (plugin_instance, "power", v / -1000000.0);
		else
			battery_submit (plugin_instance, "power", v / 1000000.0);
	}
	if (sysfs_file_to_gauge (dir, power_supply, "voltage_now", &v) == 0)
		battery_submit (plugin_instance, "voltage", v / 1000000.0);
#if 0
	if (sysfs_file_to_gauge (dir, power_supply, "energy_full_design", &v) == 0)
		battery_submit (plugin_instance, "charge", v / 1000000.0);
	if (sysfs_file_to_gauge (dir, power_supply, "energy_full", &v) == 0)
		battery_submit (plugin_instance, "charge", v / 1000000.0);
	if (sysfs_file_to_gauge (dir, power_supply, "voltage_min_design", &v) == 0)
		battery_submit (plugin_instance, "voltage", v / 1000000.0);
#endif

	return (0);
} /* }}} int read_sysfs_callback */
예제 #2
0
파일: battery.c 프로젝트: Whissi/collectd
static void submit_capacity (char const *plugin_instance, /* {{{ */
		gauge_t capacity_charged,
		gauge_t capacity_full,
		gauge_t capacity_design)
{
	if (report_percent && (capacity_charged > capacity_full))
		return;
	if (report_degraded && (capacity_full > capacity_design))
		return;

	if (report_percent)
	{
		gauge_t capacity_max;

		if (report_degraded)
			capacity_max = capacity_design;
		else
			capacity_max = capacity_full;

		battery_submit2 (plugin_instance, "percent", "charged",
				100.0 * capacity_charged / capacity_max);
		battery_submit2 (plugin_instance, "percent", "discharged",
				100.0 * (capacity_full - capacity_charged) / capacity_max);

		if (report_degraded)
			battery_submit2 (plugin_instance, "percent", "degraded",
					100.0 * (capacity_design - capacity_full) / capacity_max);
	}
	else if (report_degraded) /* && !report_percent */
	{
		battery_submit2 (plugin_instance, "capacity", "charged",
				capacity_charged);
		battery_submit2 (plugin_instance, "capacity", "discharged",
				(capacity_full - capacity_charged));
		battery_submit2 (plugin_instance, "capacity", "degraded",
				(capacity_design - capacity_full));
	}
	else /* !report_percent && !report_degraded */
	{
		battery_submit (plugin_instance, "capacity", capacity_charged);
	}
} /* }}} void submit_capacity */
예제 #3
0
파일: battery.c 프로젝트: Civil/collectd
static int read_pmu (void) /* {{{ */
{
	int i;

	/* The upper limit here is just a safeguard. If there is a system with
	 * more than 100 batteries, this can easily be increased. */
	for (i = 0; i < 100; i++)
	{
		FILE *fh;

		char buffer[1024];
		char filename[PATH_MAX];
		char plugin_instance[DATA_MAX_NAME_LEN];

		gauge_t current = NAN;
		gauge_t voltage = NAN;
		gauge_t charge  = NAN;

		ssnprintf (filename, sizeof (filename), PROC_PMU_PATH_FORMAT, i);
		if (access (filename, R_OK) != 0)
			break;

		ssnprintf (plugin_instance, sizeof (plugin_instance), "%i", i);

		fh = fopen (filename, "r");
		if (fh == NULL)
		{
			if (errno == ENOENT)
				break;
			else if ((errno == EAGAIN) || (errno == EINTR))
				continue;
			else
				return (errno);
		}

		while (fgets (buffer, sizeof (buffer), fh) != NULL)
		{
			char *fields[8];
			int numfields;

			numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
			if (numfields < 3)
				continue;

			if (strcmp ("current", fields[0]) == 0)
				strtogauge (fields[2], &current);
			else if (strcmp ("voltage", fields[0]) == 0)
				strtogauge (fields[2], &voltage);
			else if (strcmp ("charge", fields[0]) == 0)
				strtogauge (fields[2], &charge);
		}

		fclose (fh);
		fh = NULL;

		battery_submit (plugin_instance, "charge", charge / 1000.0);
		battery_submit (plugin_instance, "current", current / 1000.0);
		battery_submit (plugin_instance, "voltage", voltage / 1000.0);
	}

	if (i == 0)
		return (ENOENT);
	return (0);
} /* }}} int read_pmu */
예제 #4
0
파일: battery.c 프로젝트: Civil/collectd
static int read_acpi_callback (char const *dir, /* {{{ */
		char const *power_supply,
		void *user_data)
{
	int *battery_index = user_data;

	gauge_t current = NAN;
	gauge_t voltage = NAN;
	gauge_t charge  = NAN;
	_Bool charging = 0;

	char const *plugin_instance;
	char filename[PATH_MAX];
	char buffer[1024];

	FILE *fh;

	ssnprintf (filename, sizeof (filename), "%s/%s/state", dir, power_supply);
	fh = fopen (filename, "r");
	if ((fh = fopen (filename, "r")) == NULL)
	{
		if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT))
			return (0);
		else
			return (errno);
	}

	/*
	 * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state
	 * [11:00] <@tokkee> present:                 yes
	 * [11:00] <@tokkee> capacity state:          ok
	 * [11:00] <@tokkee> charging state:          charging
	 * [11:00] <@tokkee> present rate:            1724 mA
	 * [11:00] <@tokkee> remaining capacity:      4136 mAh
	 * [11:00] <@tokkee> present voltage:         12428 mV
	 */
	while (fgets (buffer, sizeof (buffer), fh) != NULL)
	{
		char *fields[8];
		int numfields;

		numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
		if (numfields < 3)
			continue;

		if ((strcmp (fields[0], "charging") == 0)
				&& (strcmp (fields[1], "state:") == 0))
		{
			if (strcmp (fields[2], "charging") == 0)
				charging = 1;
			else
				charging = 0;
			continue;
		}

		/* FIXME: The unit of "present rate" depends on the battery.
		 * Modern batteries export watts, not amperes, i.e. it's not a
		 * current anymore. We should check if the fourth column
		 * contains "mA" and only use a current then. Otherwise, export
		 * a power. */
		if ((strcmp (fields[0], "present") == 0)
				&& (strcmp (fields[1], "rate:") == 0))
			strtogauge (fields[2], &current);
		else if ((strcmp (fields[0], "remaining") == 0)
				&& (strcmp (fields[1], "capacity:") == 0))
			strtogauge (fields[2], &charge);
		else if ((strcmp (fields[0], "present") == 0)
				&& (strcmp (fields[1], "voltage:") == 0))
			strtogauge (fields[2], &voltage);
	} /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */

	fclose (fh);

	if (!charging)
		current *= -1.0;

	/* FIXME: This is a dirty hack for backwards compatibility: The battery
	 * plugin, for a very long time, has had the plugin_instance
	 * hard-coded to "0". So, to keep backwards compatibility, we'll use
	 * "0" for the first battery we find and the power_supply name for all
	 * following. This should be reverted in a future major version. */
	plugin_instance = (*battery_index == 0) ? "0" : power_supply;
	(*battery_index)++;

	battery_submit (plugin_instance, "charge", charge / 1000.0);
	battery_submit (plugin_instance, "current", current / 1000.0);
	battery_submit (plugin_instance, "voltage", voltage / 1000.0);

	return 0;
} /* }}} int read_acpi_callback */
예제 #5
0
파일: battery.c 프로젝트: ajdiaz/collectd
static int read_acpi_callback(char const *dir, /* {{{ */
                              char const *power_supply, void *user_data) {
  int *battery_index = user_data;

  gauge_t power = NAN;
  gauge_t voltage = NAN;
  gauge_t capacity_charged = NAN;
  gauge_t capacity_full = NAN;
  gauge_t capacity_design = NAN;
  _Bool charging = 0;
  _Bool is_current = 0;

  char const *plugin_instance;
  char filename[PATH_MAX];
  char buffer[1024];

  FILE *fh;

  ssnprintf(filename, sizeof(filename), "%s/%s/state", dir, power_supply);
  fh = fopen(filename, "r");
  if (fh == NULL) {
    if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT))
      return (0);
    else
      return (errno);
  }

  /*
   * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state
   * [11:00] <@tokkee> present:                 yes
   * [11:00] <@tokkee> capacity state:          ok
   * [11:00] <@tokkee> charging state:          charging
   * [11:00] <@tokkee> present rate:            1724 mA
   * [11:00] <@tokkee> remaining capacity:      4136 mAh
   * [11:00] <@tokkee> present voltage:         12428 mV
   */
  while (fgets(buffer, sizeof(buffer), fh) != NULL) {
    char *fields[8];
    int numfields;

    numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields));
    if (numfields < 3)
      continue;

    if ((strcmp(fields[0], "charging") == 0) &&
        (strcmp(fields[1], "state:") == 0)) {
      if (strcmp(fields[2], "charging") == 0)
        charging = 1;
      else
        charging = 0;
      continue;
    }

    /* The unit of "present rate" depends on the battery. Modern
     * batteries export power (watts), older batteries (used to)
     * export current (amperes). We check the fourth column and try
     * to find old batteries this way. */
    if ((strcmp(fields[0], "present") == 0) &&
        (strcmp(fields[1], "rate:") == 0)) {
      strtogauge(fields[2], &power);

      if ((numfields >= 4) && (strcmp("mA", fields[3]) == 0))
        is_current = 1;
    } else if ((strcmp(fields[0], "remaining") == 0) &&
               (strcmp(fields[1], "capacity:") == 0))
      strtogauge(fields[2], &capacity_charged);
    else if ((strcmp(fields[0], "present") == 0) &&
             (strcmp(fields[1], "voltage:") == 0))
      strtogauge(fields[2], &voltage);
  } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */

  fclose(fh);

  if (!charging)
    power *= -1.0;

  /* FIXME: This is a dirty hack for backwards compatibility: The battery
   * plugin, for a very long time, has had the plugin_instance
   * hard-coded to "0". So, to keep backwards compatibility, we'll use
   * "0" for the first battery we find and the power_supply name for all
   * following. This should be reverted in a future major version. */
  plugin_instance = (*battery_index == 0) ? "0" : power_supply;
  (*battery_index)++;

  read_acpi_full_capacity(dir, power_supply, &capacity_full, &capacity_design);

  submit_capacity(plugin_instance, capacity_charged * PROC_ACPI_FACTOR,
                  capacity_full * PROC_ACPI_FACTOR,
                  capacity_design * PROC_ACPI_FACTOR);

  battery_submit(plugin_instance, is_current ? "current" : "power",
                 power * PROC_ACPI_FACTOR);
  battery_submit(plugin_instance, "voltage", voltage * PROC_ACPI_FACTOR);

  return 0;
} /* }}} int read_acpi_callback */