Battery: detect manufacturer date

This commit is contained in:
李通洲
2024-01-09 22:58:32 +08:00
parent 61af59fc00
commit 7926b74917
7 changed files with 111 additions and 9 deletions
+1
View File
@@ -7,6 +7,7 @@
typedef struct FFBatteryResult
{
FFstrbuf manufacturer;
FFstrbuf manufacturerDate;
FFstrbuf modelName;
FFstrbuf technology;
FFstrbuf status;
+1
View File
@@ -40,6 +40,7 @@ static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results)
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->manufacturerDate);
battery->capacity = yyjson_get_num(yyjson_obj_get(root, "percentage"));
ffStrbufAppendS(&battery->status, yyjson_get_str(yyjson_obj_get(root, "status")));
+1
View File
@@ -29,6 +29,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->status);
ffStrbufInit(&battery->manufacturerDate);
battery->capacity = 0.0/0.0;
int currentCapacity, maxCapacity;
+1
View File
@@ -40,6 +40,7 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufacturerDate);
battery->capacity = battio.battinfo.cap;
if(battio.battinfo.state == ACPI_BATT_STAT_INVALID)
+2
View File
@@ -83,6 +83,8 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option
result->cycleCount = cycleCount < 0 || cycleCount > UINT32_MAX ? 0 : (uint32_t) cycleCount;
}
ffStrbufInit(&result->manufacturerDate);
result->temperature = FF_BATTERY_TEMP_UNSET;
if (options->temp)
{
+99 -9
View File
@@ -1,6 +1,7 @@
#include "battery.h"
#include "util/windows/unicode.h"
#include "util/mallocHelper.h"
#include "util/smbiosHelper.h"
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -75,19 +76,19 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
if(memcmp(bi.Chemistry, "PbAc", 4) == 0)
ffStrbufInitS(&battery->technology, "Lead Acid");
ffStrbufInitStatic(&battery->technology, "Lead Acid");
else if(memcmp(bi.Chemistry, "LION", 4) == 0 || memcmp(bi.Chemistry, "Li-I", 4) == 0)
ffStrbufInitS(&battery->technology, "Lithium Ion");
ffStrbufInitStatic(&battery->technology, "Lithium Ion");
else if(memcmp(bi.Chemistry, "NiCd", 4) == 0)
ffStrbufInitS(&battery->technology, "Nickel Cadmium");
ffStrbufInitStatic(&battery->technology, "Nickel Cadmium");
else if(memcmp(bi.Chemistry, "NiMH", 4) == 0)
ffStrbufInitS(&battery->technology, "Nickel Metal Hydride");
ffStrbufInitStatic(&battery->technology, "Nickel Metal Hydride");
else if(memcmp(bi.Chemistry, "NiZn", 4) == 0)
ffStrbufInitS(&battery->technology, "Nickel Zinc");
ffStrbufInitStatic(&battery->technology, "Nickel Zinc");
else if(memcmp(bi.Chemistry, "RAM\0", 4) == 0)
ffStrbufInitS(&battery->technology, "Rechargeable Alkaline-Manganese");
ffStrbufInitStatic(&battery->technology, "Rechargeable Alkaline-Manganese");
else
ffStrbufInitS(&battery->technology, "Unknown");
ffStrbufInitStatic(&battery->technology, "Unknown");
{
ffStrbufInit(&battery->modelName);
@@ -105,6 +106,14 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
ffStrbufSetWS(&battery->manufacturer, name);
}
{
ffStrbufInit(&battery->manufacturerDate);
bqi.InformationLevel = BatteryManufactureDate;
BATTERY_MANUFACTURE_DATE date;
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &date, sizeof(date), &dwOut, NULL))
ffStrbufSetF(&battery->manufacturerDate, "%.4d-%.2d-%.2d", date.Year + 1900, date.Month, date.Day);
}
{
ffStrbufInit(&battery->serial);
bqi.InformationLevel = BatterySerialNumber;
@@ -121,7 +130,7 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
bqi.InformationLevel = BatteryTemperature;
ULONG temp;
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &temp, sizeof(temp), &dwOut, NULL))
battery->temperature = temp;
battery->temperature = temp / 10.0 - 273.15;
}
{
@@ -148,6 +157,83 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
return NULL;
}
typedef struct FFSmbiosPortableBattery
{
FFSmbiosHeader Header;
// 2.1+
uint8_t Location; // string
uint8_t Manufacturer; // string
uint8_t ManufactureDate; // string
uint8_t SerialNumber; // string
uint8_t DeviceName; // string
uint8_t DeviceChemistry; // enum
uint16_t DesignCapacity; // varies
uint16_t DesignVoltage; // varies
uint8_t SbdsVersionNumber; // string
uint8_t MaximumErrorInBatteryData; // varies
// 2.2+
uint16_t SbdsSerialNumber; // varies
uint16_t SbdsManufactureDate; // varies
uint8_t SbdsDeviceChemistry; // string
uint8_t DesignCapacityMultiplier; // varies
uint16_t OEMSpecific; // varies
} FFSmbiosPortableBattery;
const char* detectBySmbios(FFBatteryResult* battery)
{
const FFSmbiosPortableBattery* data = (const FFSmbiosPortableBattery*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_PORTABLE_BATTERY];
if (!data)
return "Portable battery section is not found in SMBIOS data";
const char* strings = (const char*) data + data->Header.Length;
ffStrbufSetStatic(&battery->modelName, ffSmbiosLocateString(strings, data->DeviceName));
ffCleanUpSmbiosValue(&battery->modelName);
ffStrbufSetStatic(&battery->manufacturer, ffSmbiosLocateString(strings, data->Manufacturer));
ffCleanUpSmbiosValue(&battery->manufacturer);
if (data->ManufactureDate)
{
ffStrbufSetStatic(&battery->manufacturerDate, ffSmbiosLocateString(strings, data->ManufactureDate));
ffCleanUpSmbiosValue(&battery->manufacturerDate);
}
else if (data->Header.Length > offsetof(FFSmbiosPortableBattery, SbdsManufactureDate))
{
uint16_t day = data->SbdsManufactureDate & 0b11111;
uint16_t month = (data->SbdsManufactureDate >> 5) & 0b1111;
uint16_t year = (data->SbdsManufactureDate >> 9) + 1800;
ffStrbufSetF(&battery->manufacturerDate, "%.4d-%.2d-%.2d", year, month, day);
}
switch (data->DeviceChemistry)
{
case 0x01: ffStrbufSetStatic(&battery->technology, "Other"); break;
case 0x02: ffStrbufSetStatic(&battery->technology, "Unknown"); break;
case 0x03: ffStrbufSetStatic(&battery->technology, "Lead Acid"); break;
case 0x04: ffStrbufSetStatic(&battery->technology, "Nickel Cadmium"); break;
case 0x05: ffStrbufSetStatic(&battery->technology, "Nickel metal hydride"); break;
case 0x06: ffStrbufSetStatic(&battery->technology, "Lithium-ion"); break;
case 0x07: ffStrbufSetStatic(&battery->technology, "Zinc air"); break;
case 0x08: ffStrbufSetStatic(&battery->technology, "Lithium Polymer"); break;
}
if (data->SerialNumber)
{
ffStrbufSetStatic(&battery->serial, ffSmbiosLocateString(strings, data->SerialNumber));
ffCleanUpSmbiosValue(&battery->serial);
}
else if (data->Header.Length > offsetof(FFSmbiosPortableBattery, SbdsSerialNumber))
{
ffStrbufSetF(&battery->serial, "%4X", data->SbdsSerialNumber);
}
return NULL;
}
static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
{
SYSTEM_BATTERY_STATE info;
@@ -156,6 +242,7 @@ static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FF
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->manufacturerDate);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->status);
ffStrbufInit(&battery->serial);
@@ -171,6 +258,9 @@ static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FF
}
else if(info.Discharging)
ffStrbufAppendS(&battery->status, "Discharging");
detectBySmbios(battery);
return NULL;
}
return "NtPowerInformation(SystemBatteryState) failed";
@@ -178,7 +268,7 @@ static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FF
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
{
return true
return options->useSetupApi
? detectWithSetupApi(options, results)
: detectWithNtApi(options, results);
}
+6
View File
@@ -72,6 +72,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
{FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature},
{FF_FORMAT_ARG_TYPE_UINT, &result->cycleCount},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->serial},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturerDate},
});
}
}
@@ -97,6 +98,8 @@ void ffPrintBattery(FFBatteryOptions* options)
ffStrbufDestroy(&result->modelName);
ffStrbufDestroy(&result->technology);
ffStrbufDestroy(&result->status);
ffStrbufDestroy(&result->serial);
ffStrbufDestroy(&result->manufacturerDate);
}
if(results.length == 0)
ffPrintError(FF_BATTERY_MODULE_NAME, 0, &options->moduleArgs, "No batteries found");
@@ -192,6 +195,7 @@ void ffGenerateBatteryJsonResult(FFBatteryOptions* options, yyjson_mut_doc* doc,
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_real(doc, obj, "capacity", battery->capacity);
yyjson_mut_obj_add_strbuf(doc, obj, "manufacturer", &battery->manufacturer);
yyjson_mut_obj_add_strbuf(doc, obj, "manufacturerDate", &battery->manufacturerDate);
yyjson_mut_obj_add_strbuf(doc, obj, "modelName", &battery->modelName);
yyjson_mut_obj_add_strbuf(doc, obj, "status", &battery->status);
yyjson_mut_obj_add_strbuf(doc, obj, "technology", &battery->technology);
@@ -203,6 +207,7 @@ void ffGenerateBatteryJsonResult(FFBatteryOptions* options, yyjson_mut_doc* doc,
FF_LIST_FOR_EACH(FFBatteryResult, battery, results)
{
ffStrbufDestroy(&battery->manufacturer);
ffStrbufDestroy(&battery->manufacturerDate);
ffStrbufDestroy(&battery->modelName);
ffStrbufDestroy(&battery->technology);
ffStrbufDestroy(&battery->status);
@@ -221,6 +226,7 @@ void ffPrintBatteryHelpFormat(void)
"Battery temperature",
"Battery cycle count",
"Battery serial number",
"Battery manufactorDate",
});
}