void battery_update(battery *b) { gchar *gctmp; /* read from sysfs */ b->charge_now = get_gint_from_infofile(b, "charge_now"); b->energy_now = get_gint_from_infofile(b, "energy_now"); b->current_now = get_gint_from_infofile(b, "current_now"); b->power_now = get_gint_from_infofile(b, "power_now"); /* FIXME: Some battery drivers report -1000 when the discharge rate is * unavailable. Others use negative values when discharging. Best we can do * is to treat -1 as an error, and take the absolute value otherwise. * Ideally the kernel would not export the sysfs file when the value is not * available. */ if (b->current_now < -1) b->current_now = - b->current_now; if (b->power_now < -1) b->power_now = - b->power_now; b->charge_full = get_gint_from_infofile(b, "charge_full"); b->energy_full = get_gint_from_infofile(b, "energy_full"); b->charge_full_design = get_gint_from_infofile(b, "charge_full_design"); b->energy_full_design = get_gint_from_infofile(b, "energy_full_design"); b->voltage_now = get_gint_from_infofile(b, "voltage_now"); gctmp = get_gchar_from_infofile(b, "type"); b->type_battery = gctmp ? (strcasecmp(gctmp, "battery") == 0) : TRUE; b->state = get_gchar_from_infofile(b, "status"); if (!b->state) b->state = get_gchar_from_infofile(b, "state"); if (!b->state) { if (b->charge_now != -1 || b->energy_now != -1 || b->charge_full != -1 || b->energy_full != -1) b->state = "available"; else b->state = "unavailable"; } /* convert energy values (in mWh) to charge values (in mAh) if needed and possible */ if (b->energy_full != -1 && b->charge_full == -1) { if (b->voltage_now != -1) { b->charge_full = b->energy_full * 1000 / b->voltage_now; } else { b->charge_full = b->energy_full; b->capacity_unit = "mWh"; } } if (b->energy_full_design != -1 && b->charge_full_design == -1) { if (b->voltage_now != -1) { b->charge_full_design = b->energy_full_design * 1000 / b->voltage_now; } else { b->charge_full_design = b->energy_full_design; b->capacity_unit = "mWh"; } } if (b->energy_now != -1 && b->charge_now == -1) { if (b->voltage_now != -1) { b->charge_now = b->energy_now * 1000 / b->voltage_now; if (b->current_now != -1) b->current_now = b->current_now * 1000 / b->voltage_now; } else { b->charge_now = b->energy_now; } } if (b->power_now != -1 && b->current_now == -1) { if (b->voltage_now != -1 && b->voltage_now != 0) b->current_now = b->power_now * 1000 / b->voltage_now; } if (b->charge_full < MIN_CAPACITY) b->percentage = 0; else { int promille = (b->charge_now * 1000) / b->charge_full; b->percentage = (promille + 5) / 10; /* round properly */ } if (b->percentage > 100) b->percentage = 100; if (b->current_now == -1) { b->poststr = "rate information unavailable"; b->seconds = -1; } else if (!strcasecmp(b->state, "charging")) { if (b->current_now > MIN_PRESENT_RATE) { b->seconds = 3600 * (b->charge_full - b->charge_now) / b->current_now; b->poststr = " until charged"; } else { b->poststr = "charging at zero rate - will never fully charge."; b->seconds = -1; } } else if (!strcasecmp(b->state, "discharging")) { if (b->current_now > MIN_PRESENT_RATE) { b->seconds = 3600 * b->charge_now / b->current_now; b->poststr = " remaining"; } else { b->poststr = "discharging at zero rate - will never fully discharge."; b->seconds = -1; } } else { b->poststr = NULL; b->seconds = -1; } }
battery* battery_update(battery *b) { gchar *gctmp; int promille; if (b == NULL) return NULL; if (!battery_inserted(b->path)) return NULL; /* read from sysfs */ b->charge_now = get_gint_from_infofile(b, "charge_now"); b->energy_now = get_gint_from_infofile(b, "energy_now"); b->current_now = get_gint_from_infofile(b, "current_now"); b->power_now = get_gint_from_infofile(b, "power_now"); /* FIXME: Some battery drivers report -1000 when the discharge rate is * unavailable. Others use negative values when discharging. Best we can do * is to treat -1 as an error, and take the absolute value otherwise. * Ideally the kernel would not export the sysfs file when the value is not * available. */ if (b->current_now < -1) b->current_now = - b->current_now; b->charge_full = get_gint_from_infofile(b, "charge_full"); b->energy_full = get_gint_from_infofile(b, "energy_full"); b->charge_full_design = get_gint_from_infofile(b, "charge_full_design"); b->energy_full_design = get_gint_from_infofile(b, "energy_full_design"); b->voltage_now = get_gint_from_infofile(b, "voltage_now"); gctmp = get_gchar_from_infofile(b, "type"); b->type_battery = gctmp ? (strcasecmp(gctmp, "battery") == 0) : TRUE; g_free(gctmp); g_free(b->state); b->state = get_gchar_from_infofile(b, "status"); if (!b->state) b->state = get_gchar_from_infofile(b, "state"); if (!b->state) { if (b->charge_now != -1 || b->energy_now != -1 || b->charge_full != -1 || b->energy_full != -1) b->state = g_strdup("available"); else b->state = g_strdup("unavailable"); } #if 0 /* those conversions might be good for text prints but are pretty wrong for tooltip and calculations */ /* convert energy values (in mWh) to charge values (in mAh) if needed and possible */ if (b->energy_full != -1 && b->charge_full == -1) { if (b->voltage_now != -1 && b->voltage_now != 0) { b->charge_full = b->energy_full * 1000 / b->voltage_now; } else { b->charge_full = b->energy_full; b->capacity_unit = "mWh"; } } if (b->energy_full_design != -1 && b->charge_full_design == -1) { if (b->voltage_now != -1 && b->voltage_now != 0) { b->charge_full_design = b->energy_full_design * 1000 / b->voltage_now; } else { b->charge_full_design = b->energy_full_design; b->capacity_unit = "mWh"; } } if (b->energy_now != -1 && b->charge_now == -1) { if (b->voltage_now != -1 && b->voltage_now != 0) { b->charge_now = b->energy_now * 1000 / b->voltage_now; if (b->current_now != -1) b->current_now = b->current_now * 1000 / b->voltage_now; } else { b->charge_now = b->energy_now; } } if (b->power_now < -1) b->power_now = - b->power_now; else if (b->power_now == -1 && b->voltage_now != -1 && b->current_now != -1) b->power_now = b->voltage_now * b->current_now / 1000; // P = U*I if (b->power_now != -1 && b->current_now == -1) { if (b->voltage_now != -1 && b->voltage_now != 0) b->current_now = b->power_now * 1000 / b->voltage_now; } #endif if (b->charge_now != -1 && b->charge_full != -1) promille = (b->charge_now * 1000) / b->charge_full; else if (b->energy_full != -1 && b->energy_now != -1) /* no charge data, let try energy instead */ promille = (b->energy_now * 1000) / b->energy_full; else promille = 0; b->percentage = (promille + 5) / 10; /* round properly */ if (b->percentage > 100) b->percentage = 100; if (b->power_now < -1) b->power_now = - b->power_now; if (b->current_now == -1 && b->power_now == -1) { //b->poststr = "rate information unavailable"; b->seconds = -1; } else if (!strcasecmp(b->state, "charging")) { if (b->current_now > MIN_PRESENT_RATE) { b->seconds = 3600 * (b->charge_full - b->charge_now) / b->current_now; //b->poststr = " until charged"; } else if (b->power_now > 0) { b->seconds = 3600 * (b->energy_full - b->energy_now) / b->power_now; } else { //b->poststr = "charging at zero rate - will never fully charge."; b->seconds = -1; } } else if (!strcasecmp(b->state, "discharging")) { if (b->current_now > MIN_PRESENT_RATE) { b->seconds = 3600 * b->charge_now / b->current_now; //b->poststr = " remaining"; } else if (b->power_now > 0) { b->seconds = 3600 * b->energy_now / b->power_now; } else { //b->poststr = "discharging at zero rate - will never fully discharge."; b->seconds = -1; } } else { //b->poststr = NULL; b->seconds = -1; } return b; }