Esempio n. 1
0
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;
}