-todo
+/* todo
power vs current
Full
old way of doing alarm
+*/
/*
* display outputs, per line:
};
/*---------- structure of and results from /sys/class/power/... ----------*/
-/* variables thisbat_... are the results from readbattery();
+/* variables this_... are the results from readbattery();
* if readbattery() succeeds the appropriate ones are all valid
* and not VAL_NOTFOUND
*/
const char *enumarray[10];
} batinfo_field;
-#define UEVENT_QUANTITY_FIELDS(f) \
- f(design_capacity, BATTERY, CHARGE_FULL_DESIGN ) /* uAh */ \
- f(last_full_capacity, BATTERY, CHARGE_FULL ) /* uAh */ \
- f(present_rate, BATTERY, CURRENT_NOW ) /* uA */ \
- f(remaining_capacity, BATTERY, CHARGE_NOW ) /* uAh */ \
- f(present, BATTERY, PRESENT ) /* boolean */ \
- f(online, MAINS, ONLINE ) /* boolean */
+#define BAT_QTYS(_) \
+ _(design_capacity, ENERGY, CHARGE, FULL_DESIGN ) \
+ _(last_full_capacity, ENERGY, CHARGE, FULL ) \
+ _(remaining_capacity, ENERGY, CHARGE, NOW ) \
+ _(present_rate, POWER, CURRENT, NOW )
+ /* ENERGY [mWh]; POWER [mW]; CHARGE [uAh]; CURRENT [uA] */
-#define UEVENT_ENUM_FIELDS(f) \
- f(state, BATTERY, STATUS, "Discharging","Charging","Charged","Unknown" ) \
- f(type, BOTH, TYPE, "Mains", "Battery" )
+#define UEVENT_QTY_CHARGE(f,lle,llc,lr) \
+ _(f##_energy, BATTERY, lle##_##lr ) \
+ _(f##_charge, BATTERY, llc##_##lr )
-#define CHGST_DISCHARGING 0 /* Reflects order in f(state,...) above */
+#define UEVENT_QUANTITY_FIELDS(_) \
+ BAT_QTYS(UEVENT_QTY_CHARGE) \
+ _(present, BATTERY, PRESENT ) /* boolean */ \
+ _(online, MAINS, ONLINE ) /* boolean */
+
+#define UEVENT_ENUM_FIELDS(_) \
+ _(state, BATTERY, STATUS, "Discharging","Charging","Full","Unknown" ) \
+ _(type, BOTH, TYPE, "Mains", "Battery" )
+
+#define CHGST_DISCHARGING 0 /* Reflects order in _(state,...) above */
#define CHGST_CHARGING 1 /* Also, much code assumes exactly */
#define CHGST_CHARGED 2 /* these three possible states. */
#define CHGST_UNKNOWN 3 /* these three possible states. */
#define CHGST_ERROR 8 /* Except that this one is an extra bit. */
-#define TYPE_MAINS 0 /* Reflects order in f(type,...) above */
+#define TYPE_MAINS 0 /* Reflects order in _(type,...) above */
#define TYPE_BATTERY 1 /* Also, much code assumes exactly these two */
#define TYPE_BOTH 100 /* Except this is a magic invalid value. */
-#define SEPARATE_QUANTITY_FIELDS(f) \
- f(alarm, BATTERY, "alarm", "0", "1")
+#define SEPARATE_QUANTITY_FIELDS(_) \
+ _(alarm, BATTERY, "alarm", "0", "1")
-#define ALL_FIELDS(f) \
- UEVENT_QUANTITY_FIELDS(f) \
- UEVENT_ENUM_FIELDS(f) \
- SEPARATE_QUANTITY_FIELDS(f)
+#define ALL_FIELDS(_) \
+ UEVENT_QUANTITY_FIELDS(_) \
+ UEVENT_ENUM_FIELDS(_) \
+ SEPARATE_QUANTITY_FIELDS(_)
-#define ALL_QUANTITY_FIELDS(f) \
- UEVENT_QUANTITY_FIELDS(f) \
- SEPARATE_QUANTITY_FIELDS(f)
+#define ALL_QUANTITY_FIELDS(_) \
+ UEVENT_QUANTITY_FIELDS(_) \
+ SEPARATE_QUANTITY_FIELDS(_)
+
+#define ALL_VARS(_) \
+ ALL_FIELDS(_) \
+ BAT_QTYS(_)
#define F_VAR(f,...) \
-static value thisbat_##f;
-ALL_FIELDS(F_VAR)
+static value this_##f;
+ALL_VARS(F_VAR)
-#define Q_FLD(f,t,l) { "POWER_SUPPLY_" #l, &thisbat_##f },
-#define E_FLD(f,t,l,vl...) { "POWER_SUPPLY_" #l, &thisbat_##f, { vl } },
+#define Q_FLD(f,t,l) { "POWER_SUPPLY_" #l, &this_##f },
+#define E_FLD(f,t,l,vl...) { "POWER_SUPPLY_" #l, &this_##f, { vl } },
static const batinfo_field uevent_fields[]= {
UEVENT_QUANTITY_FIELDS(Q_FLD)
};
#define S_FLD(f,t,fn,vl...) \
-static const batinfo_field bif_##f = { 0, &thisbat_##f, { vl } };
+static const batinfo_field bif_##f = { 0, &this_##f, { vl } };
SEPARATE_QUANTITY_FIELDS(S_FLD)
#define S_FILE(f,t,fn,vl...) { fn, parse_separate, &bif_##f },
return -1;
}
+static int batfailc(const char *why) {
+ fprintf(stderr,"%s/%s: %s\n",
+ batdirname,batfilename, why);
+ return -1;
+}
+
static int batfaile(const char *syscall, const char *target) {
fprintf(stderr,"%s: failed to %s %s: %s\n",
batdirname ? batdirname : "*", syscall, target, strerror(errno));
if (r) return batfaile("chdir",batdirname);
#define V_NOTFOUND(f,...) \
- thisbat_##f = VAL_NOTFOUND;
-ALL_FIELDS(V_NOTFOUND)
+ this_##f = VAL_NOTFOUND;
+ALL_VARS(V_NOTFOUND)
for (cfile=files;
(batfilename= cfile->filename);
batfile= 0;
}
- int needsfields_MAINS = thisbat_type == TYPE_MAINS;
- int needsfields_BATTERY = thisbat_type == TYPE_BATTERY;
+ int needsfields_MAINS = this_type == TYPE_MAINS;
+ int needsfields_BATTERY = this_type == TYPE_BATTERY;
int needsfields_BOTH = 1;
int missing = 0;
#define V_NEEDED(f,t,...) \
- if (needsfields_##t && thisbat_##f == VAL_NOTFOUND) { \
+ if (needsfields_##t && this_##f == VAL_NOTFOUND) { \
fprintf(stderr,"%s: %s: not found\n", \
batdirname, #f); \
missing++; \
break;
}
- if (thisbat_type == TYPE_BATTERY) {
- if (!thisbat_present)
+ if (this_type == TYPE_BATTERY) {
+ if (!this_present)
continue;
- charging_mask |= 1u << thisbat_state;
+ charging_mask |= 1u << this_state;
- if (thisbat_state == CHGST_DISCHARGING)
+ if (this_state == CHGST_DISCHARGING)
/* negate it */
total_present_rate -= 2.0 * thisbat_present_rate;
+
+#define QTY_ENERGY_SUPPLIED(f,...) this_##f##_energy != V_NOTFOUND &&
+#define QTY_ENERGY_USE(f,...) this_##f = this_##f##_energy;
+#define QTY_CHARGE_SUPPLIED(f,...) this_##f##_charge != V_NOTFOUND &&
+#define QTY_CHARGE_USE(f,...) this_##f = this_##f##_charge;
+
+ if (BAT_QTYS(QTY_ENERGY_SUPPLIED) 1) {
+ BAT_QTYS(QTY_ENERGY_USE);
+ } else if (BAT_QTYS(QTY_CHARGE_SUPPLIED) 1) {
+ BAT_QTYS(QTY_CHARGE_USE);
+ } else {
+ return batfailc("neither complete set of energy nor charge");
+ }
}
#define Q_TOTALISE(f,t,...) \