From 27910cf6ecedac547e5ad22150a8518c1d2643ad Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 10 Oct 2024 16:19:11 +0800 Subject: [PATCH] Battery (Linux): calcuate time remaining with current & charge if time_to_empty is unavailable --- src/detection/battery/battery_linux.c | 53 ++++++++++++++++++++++----- src/modules/battery/battery.c | 3 +- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/detection/battery/battery_linux.c b/src/detection/battery/battery_linux.c index 96423b0b0..6ea2f42fe 100644 --- a/src/detection/battery/battery_linux.c +++ b/src/detection/battery/battery_linux.c @@ -24,7 +24,18 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option //type must exist and be "Battery" const char* type = findProperty(buffer, size, "\nPOWER_SUPPLY_TYPE="); - if (!type || !ffStrStartsWith(type, "Battery\n")) return; + if (type) + { + if (!ffStrStartsWith(type, "Battery\n")) return; + } + else if (!ffStrStartsWith(id, "BAT")) + { + char typeBuf[16] = {0}; + ffStrbufSubstrBefore(dir, dir->length - (uint32_t) strlen("uevent")); + ffStrbufAppendS(dir, "type"); + if (ffReadFileData(dir->chars, sizeof(typeBuf), typeBuf) < (ssize_t) strlen("Battery")) return; + if (!ffStrStartsWith(typeBuf, "Battery")) return; + } //scope may not exist or must not be "Device" const char* scope = findProperty(buffer, size, "\nPOWER_SUPPLY_SCOPE="); @@ -50,18 +61,22 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option ffStrbufAppendSUntilC(&result->modelName, findProperty(buffer, size, "\nPOWER_SUPPLY_MODEL_NAME="), '\n'); ffStrbufInit(&result->technology); - ffStrbufAppendSUntilC(&result->technology, findProperty(buffer, size, "\nPOWER_SUPPLY_TECHNOLOGY="), '\n'); + const char* technology = findProperty(buffer, size, "\nPOWER_SUPPLY_TECHNOLOGY="); + if (technology && !ffStrStartsWith(technology, "Unknown")) + ffStrbufAppendSUntilC(&result->technology, technology, '\n'); ffStrbufInit(&result->status); const char* status = findProperty(buffer, size, "\nPOWER_SUPPLY_STATUS="); - - // Unknown, Charging, Discharging, Not charging, Full - if (ffStrStartsWith(status, "Not charging\n") || ffStrStartsWith(status, "Full\n")) - ffStrbufSetStatic(&result->status, "AC Connected"); - else if (ffStrStartsWith(status, "Charging\n")) - ffStrbufSetStatic(&result->status, "AC Connected, Charging"); - else if (ffStrStartsWith(status, "Discharging\n")) - ffStrbufSetStatic(&result->status, "Discharging"); + if (status) + { + // Unknown, Charging, Discharging, Not charging, Full + if (ffStrStartsWith(status, "Not charging\n") || ffStrStartsWith(status, "Full\n")) + ffStrbufSetStatic(&result->status, "AC Connected"); + else if (ffStrStartsWith(status, "Charging\n")) + ffStrbufSetStatic(&result->status, "AC Connected, Charging"); + else if (ffStrStartsWith(status, "Discharging\n")) + ffStrbufSetStatic(&result->status, "Discharging"); + } const char* capacityLevel = findProperty(buffer, size, "\nPOWER_SUPPLY_CAPACITY_LEVEL="); if (capacityLevel && ffStrStartsWith(capacityLevel, "Critical\n")) @@ -101,6 +116,24 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option } } } + else if (ffStrStartsWith(status, "Discharging\n")) + { + const char* chargeNow = findProperty(buffer, size, "\nPOWER_SUPPLY_CHARGE_NOW="); + if (chargeNow) + { + int64_t charge = strtol(chargeNow, NULL, 0); + if (charge > 0) + { + const char* currentNow = findProperty(buffer, size, "\nPOWER_SUPPLY_CURRENT_NOW="); + if (currentNow) + { + int64_t current = strtol(currentNow, NULL, 0); + if (current > 0) + result->timeRemaining = (int32_t) (charge * 3600 / current); + } + } + } + } ffStrbufInit(&result->manufactureDate); const char* myear = findProperty(buffer, size, "\nPOWER_SUPPLY_MANUFACTURE_YEAR="); diff --git a/src/modules/battery/battery.c b/src/modules/battery/battery.c index 25cf8d8cc..f27ff29e7 100644 --- a/src/modules/battery/battery.c +++ b/src/modules/battery/battery.c @@ -250,7 +250,8 @@ void ffGenerateBatteryJsonResult(FFBatteryOptions* options, yyjson_mut_doc* doc, yyjson_mut_obj_add_strbuf(doc, obj, "serial", &battery->serial); yyjson_mut_obj_add_real(doc, obj, "temperature", battery->temperature); yyjson_mut_obj_add_uint(doc, obj, "cycleCount", battery->cycleCount); - yyjson_mut_obj_add_int(doc, obj, "timeRemaining", battery->timeRemaining); + if (battery->timeRemaining > 0) + yyjson_mut_obj_add_int(doc, obj, "timeRemaining", battery->timeRemaining); } FF_LIST_FOR_EACH(FFBatteryResult, battery, results)