Temp: Display: support better temperature value formatting

Fix #737
This commit is contained in:
李通洲
2024-02-26 10:46:13 +08:00
parent 1c87693867
commit a0c47204bb
10 changed files with 227 additions and 51 deletions
+13
View File
@@ -1,3 +1,16 @@
# 2.8.6
Changes:
* Due to newly introduced configs, JSONC option `{ "temperatureUnit": "C" }` has been changed to `{ "temperature": { "unit": "C" } }`
Bugfixes:
* Fix incorrect GPU name detection for Intel iGPU on Linux (#736, GPU, Linux)
Features:
* Support additional temperature formatting options (#737)
* `{ "temperature": { "ndigits": 1 } }`
* `{ "temperature": { "color": { "green": "green", "yellow": "yellow", "red": "red" } } }`
# 2.8.5
Bugfixes:
+36 -5
View File
@@ -407,11 +407,42 @@
}
}
},
"temperatureUnit": {
"type": "string",
"description": "Set the unit of the temperature",
"enum": ["CELSIUS", "C", "FAHRENHEIT", "F", "KELVIN", "K"],
"default": "C"
"temperature": {
"type": "object",
"description": "Set how a temperature value should be displayed",
"properties": {
"unit": {
"type": "string",
"description": "Set the unit of the temperature",
"enum": ["CELSIUS", "C", "FAHRENHEIT", "F", "KELVIN", "K"],
"default": "C"
},
"ndigits": {
"type": "integer",
"description": "Set the number of digits to keep after the decimal point when formatting temperature values",
"minimum": 0,
"maximum": 9,
"default": 1
},
"color": {
"type": "object",
"description": "Set color used in different states of temperature values",
"properties": {
"green": {
"description": "Color used in green state",
"$ref": "#/$defs/colors"
},
"yellow": {
"description": "Color used in yellow state",
"$ref": "#/$defs/colors"
},
"red": {
"description": "Color used in red state",
"$ref": "#/$defs/colors"
}
}
}
}
},
"bar": {
"type": "object",
+26 -4
View File
@@ -1,5 +1,6 @@
#include "fastfetch.h"
#include "common/parsing.h"
#include "util/textModifier.h"
#include <ctype.h>
#include <inttypes.h>
@@ -98,18 +99,39 @@ void ffParseSize(uint64_t bytes, FFstrbuf* result)
void ffParseTemperature(double celsius, FFstrbuf* buffer)
{
switch (instance.config.display.temperatureUnit)
if (celsius != celsius) // ignores NaN
return;
const FFOptionsDisplay* options = &instance.config.display;
const char* colorGreen = options->temperatureColorGreen.chars;
const char* colorYellow = options->temperatureColorYellow.chars;
const char* colorRed = options->temperatureColorRed.chars;
if (!options->pipe)
{
if (celsius < 50)
ffStrbufAppendF(buffer, "\e[%sm", colorGreen);
else if (celsius < 80)
ffStrbufAppendF(buffer, "\e[%sm", colorYellow);
else
ffStrbufAppendF(buffer, "\e[%sm", colorRed);
}
switch (options->temperatureUnit)
{
case FF_TEMPERATURE_UNIT_CELSIUS:
ffStrbufAppendF(buffer, "%.1f°C", celsius);
ffStrbufAppendF(buffer, "%.*f°C", options->temperatureNdigits, celsius);
break;
case FF_TEMPERATURE_UNIT_FAHRENHEIT:
ffStrbufAppendF(buffer, "%.1f°F", celsius * 1.8 + 32);
ffStrbufAppendF(buffer, "%.*f°F", options->temperatureNdigits, celsius * 1.8 + 32);
break;
case FF_TEMPERATURE_UNIT_KELVIN:
ffStrbufAppendF(buffer, "%.1f K", celsius + 273.15);
ffStrbufAppendF(buffer, "%.*f K", options->temperatureNdigits, celsius + 273.15);
break;
}
if (!options->pipe)
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
}
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4)
+35
View File
@@ -667,6 +667,41 @@
},
"default": "C"
}
},
{
"long": "temperature-ndigits",
"desc": "Set the number of digits to keep after the decimal point when printing temperature",
"arg": {
"type": "num",
"default": 2
}
},
{
"long": "temperature-color-green",
"desc": "Set color used in green state of temperature values",
"remark": "See `-h color` for the list of available colors",
"arg": {
"type": "color",
"default": "green"
}
},
{
"long": "temperature-color-yellow",
"desc": "Set color used in yellow state of temperature values",
"remark": "See `-h color` for the list of available colors",
"arg": {
"type": "color",
"default": "light_yellow"
}
},
{
"long": "temperature-color-red",
"desc": "Set color used in red state of temperature values",
"remark": "See `-h color` for the list of available colors",
"arg": {
"type": "color",
"default": "light_red"
}
}
],
"Library path": [
+4 -2
View File
@@ -58,13 +58,15 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
{
FF_STRBUF_AUTO_DESTROY capacityStr = ffStrbufCreate();
ffPercentAppendNum(&capacityStr, result->capacity, options->percent, false);
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffParseTemperature(result->temperature, &tempStr);
ffPrintFormat(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_BATTERY_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->technology},
{FF_FORMAT_ARG_TYPE_STRBUF, &capacityStr},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->status},
{FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature},
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr},
{FF_FORMAT_ARG_TYPE_UINT, &result->cycleCount},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->serial},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->manufactureDate},
@@ -226,7 +228,7 @@ void ffPrintBatteryHelpFormat(void)
"Battery technology",
"Battery capacity (percentage)",
"Battery status",
"Battery temperature",
"Battery temperature (formatted)",
"Battery cycle count",
"Battery serial number",
"Battery manufactor date",
+4 -2
View File
@@ -60,6 +60,8 @@ void ffPrintCPU(FFCPUOptions* options)
}
else
{
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffParseTemperature(cpu.temperature, &tempStr);
ffPrintFormat(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu.name},
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu.vendor},
@@ -68,7 +70,7 @@ void ffPrintCPU(FFCPUOptions* options)
{FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresOnline},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyMin},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyMax},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.temperature}
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr}
});
}
}
@@ -193,7 +195,7 @@ void ffPrintCPUHelpFormat(void)
"Online core count",
"Min frequency",
"Max frequency",
"Temperature"
"Temperature (formatted)"
});
}
+3 -1
View File
@@ -72,11 +72,13 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
}
else
{
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffParseTemperature(gpu->temperature, &tempStr);
ffPrintFormat(FF_GPU_MODULE_NAME, index, &options->moduleArgs, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor},
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver},
{FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature},
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr},
{FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount},
{FF_FORMAT_ARG_TYPE_STRING, type},
{FF_FORMAT_ARG_TYPE_UINT64, &gpu->dedicated.total},
+4 -2
View File
@@ -102,6 +102,8 @@ void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
}
else
{
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffParseTemperature(dev->temperature, &tempStr);
if (dev->type & FF_PHYSICALDISK_TYPE_READWRITE)
readOnlyType = "Read-write";
ffParseSize(dev->size, &buffer);
@@ -115,7 +117,7 @@ void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
{FF_FORMAT_ARG_TYPE_STRING, removableType},
{FF_FORMAT_ARG_TYPE_STRING, readOnlyType},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->revision},
{FF_FORMAT_ARG_TYPE_DOUBLE, &dev->temperature},
{FF_FORMAT_ARG_TYPE_DOUBLE, &tempStr},
});
}
++index;
@@ -263,7 +265,7 @@ void ffPrintPhysicalDiskHelpFormat(void)
"Device kind (Removable or Fixed)",
"Device kind (Read-only or Read-write)",
"Product revision",
"Device temperature",
"Device temperature (formatted)",
});
}
+98 -35
View File
@@ -94,20 +94,46 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
if (ndigits) options->percentNdigits = (uint8_t) yyjson_get_uint(ndigits);
}
else if (ffStrEqualsIgnCase(key, "temperatureUnit"))
else if (ffStrEqualsIgnCase(key, "temperature"))
{
int value;
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "F", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "KELVIN", FF_TEMPERATURE_UNIT_KELVIN },
{ "K", FF_TEMPERATURE_UNIT_KELVIN },
{},
});
if (error) return error;
options->temperatureUnit = (FFTemperatureUnit) value;
if (!yyjson_is_obj(val))
return "display.temperature must be an object";
yyjson_val* unit = yyjson_obj_get(val, "unit");
if (unit)
{
int value;
const char* error = ffJsonConfigParseEnum(unit, &value, (FFKeyValuePair[]) {
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "F", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "KELVIN", FF_TEMPERATURE_UNIT_KELVIN },
{ "K", FF_TEMPERATURE_UNIT_KELVIN },
{},
});
if (error) return error;
options->temperatureUnit = (FFTemperatureUnit) value;
}
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
if (ndigits) options->temperatureNdigits = (uint8_t) yyjson_get_uint(ndigits);
yyjson_val* color = yyjson_obj_get(val, "color");
if (color)
{
if (!yyjson_is_obj(color))
return "display.temperature.color must be an object";
yyjson_val* green = yyjson_obj_get(color, "green");
if (green) ffOptionParseColor(yyjson_get_str(green), &options->temperatureColorGreen);
yyjson_val* yellow = yyjson_obj_get(color, "yellow");
if (yellow) ffOptionParseColor(yyjson_get_str(yellow), &options->temperatureColorYellow);
yyjson_val* red = yyjson_obj_get(color, "red");
if (red) ffOptionParseColor(yyjson_get_str(red), &options->temperatureColorRed);
}
}
else if (ffStrEqualsIgnCase(key, "percent"))
{
@@ -253,17 +279,31 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
{}
});
}
else if(ffStrEqualsIgnCase(key, "--temperature-unit"))
else if(ffStrStartsWithIgnCase(key, "--temperature-"))
{
options->temperatureUnit = (FFTemperatureUnit) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "F", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "KELVIN", FF_TEMPERATURE_UNIT_KELVIN },
{ "K", FF_TEMPERATURE_UNIT_KELVIN },
{},
});
const char* subkey = key + strlen("--temperature-");
if(ffStrEqualsIgnCase(subkey, "unit"))
{
options->temperatureUnit = (FFTemperatureUnit) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "F", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "KELVIN", FF_TEMPERATURE_UNIT_KELVIN },
{ "K", FF_TEMPERATURE_UNIT_KELVIN },
{},
});
}
else if (ffStrEqualsIgnCase(subkey, "ndigits"))
options->temperatureNdigits = (uint8_t) ffOptionParseUInt32(key, value);
else if(ffStrEqualsIgnCase(subkey, "color-green"))
ffOptionParseColor(value, &options->temperatureColorGreen);
else if(ffStrEqualsIgnCase(subkey, "color-yellow"))
ffOptionParseColor(value, &options->temperatureColorYellow);
else if(ffStrEqualsIgnCase(subkey, "color-red"))
ffOptionParseColor(value, &options->temperatureColorRed);
else
return false;
}
else if(ffStrStartsWithIgnCase(key, "--percent-"))
{
@@ -323,11 +363,16 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options)
options->binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC;
options->sizeNdigits = 2;
options->sizeMaxPrefix = UINT8_MAX;
options->temperatureUnit = FF_TEMPERATURE_UNIT_CELSIUS;
options->stat = false;
options->noBuffer = false;
options->keyWidth = 0;
options->temperatureUnit = FF_TEMPERATURE_UNIT_CELSIUS;
options->temperatureNdigits = 1;
ffStrbufInitStatic(&options->temperatureColorGreen, FF_COLOR_FG_GREEN);
ffStrbufInitStatic(&options->temperatureColorYellow, FF_COLOR_FG_LIGHT_YELLOW);
ffStrbufInitStatic(&options->temperatureColorRed, FF_COLOR_FG_LIGHT_RED);
ffStrbufInitStatic(&options->barCharElapsed, "");
ffStrbufInitStatic(&options->barCharTotal, "-");
options->barWidth = 10;
@@ -430,20 +475,38 @@ void ffOptionsGenerateDisplayJsonConfig(FFOptionsDisplay* options, yyjson_mut_do
yyjson_mut_obj_add_val(doc, obj, "size", size);
}
if (options->temperatureUnit != defaultOptions.temperatureUnit)
{
switch (options->temperatureUnit)
yyjson_mut_val* temperature = yyjson_mut_obj(doc);
if (options->temperatureUnit != defaultOptions.temperatureUnit)
{
case FF_TEMPERATURE_UNIT_CELSIUS:
yyjson_mut_obj_add_str(doc, obj, "temperatureUnit", "C");
break;
case FF_TEMPERATURE_UNIT_FAHRENHEIT:
yyjson_mut_obj_add_str(doc, obj, "temperatureUnit", "F");
break;
case FF_TEMPERATURE_UNIT_KELVIN:
yyjson_mut_obj_add_str(doc, obj, "temperatureUnit", "K");
break;
switch (options->temperatureUnit)
{
case FF_TEMPERATURE_UNIT_CELSIUS:
yyjson_mut_obj_add_str(doc, obj, "unit", "C");
break;
case FF_TEMPERATURE_UNIT_FAHRENHEIT:
yyjson_mut_obj_add_str(doc, obj, "unit", "F");
break;
case FF_TEMPERATURE_UNIT_KELVIN:
yyjson_mut_obj_add_str(doc, obj, "unit", "K");
break;
}
}
if (options->temperatureNdigits != defaultOptions.temperatureNdigits)
yyjson_mut_obj_add_uint(doc, temperature, "ndigits", options->temperatureNdigits);
{
yyjson_mut_val* color = yyjson_mut_obj(doc);
if (!ffStrbufEqual(&options->temperatureColorGreen, &defaultOptions.temperatureColorGreen))
yyjson_mut_obj_add_strbuf(doc, color, "green", &options->temperatureColorGreen);
if (!ffStrbufEqual(&options->temperatureColorYellow, &defaultOptions.temperatureColorYellow))
yyjson_mut_obj_add_strbuf(doc, color, "yellow", &options->temperatureColorYellow);
if (!ffStrbufEqual(&options->temperatureColorRed, &defaultOptions.temperatureColorRed))
yyjson_mut_obj_add_strbuf(doc, color, "red", &options->temperatureColorRed);
if (yyjson_mut_obj_size(color) > 0)
yyjson_mut_obj_add_val(doc, temperature, "color", color);
}
if (yyjson_mut_obj_size(temperature) > 0)
yyjson_mut_obj_add_val(doc, obj, "temperature", temperature);
}
{
+4
View File
@@ -35,6 +35,10 @@ typedef struct FFOptionsDisplay
uint8_t sizeNdigits;
uint8_t sizeMaxPrefix;
FFTemperatureUnit temperatureUnit;
uint8_t temperatureNdigits;
FFstrbuf temperatureColorGreen;
FFstrbuf temperatureColorYellow;
FFstrbuf temperatureColorRed;
FFstrbuf barCharElapsed;
FFstrbuf barCharTotal;
uint8_t barWidth;