You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arch Linux命令行电池信息工具中电池剩余运行时长与充满时长计算方案问询

Arch Linux命令行电池信息工具中电池剩余运行时长与充满时长计算方案问询

嘿,针对你在Arch Linux命令行项目里遇到的电池时长计算问题,我来分享几个原生、可靠的方案——毕竟Linux的sysfs文件系统已经把这些底层数据直接暴露给我们了,完全不用依赖第三方工具,适配性还强。

一、计算放电时的剩余运行时长

Linux系统会把电池的实时数据放在/sys/class/power_supply/BAT0/目录下(如果你的笔记本有多个电池,可能是BAT1、BAT2,可自行调整),核心用到这几个文件:

  • status:判断当前电池状态(Discharging/Charging/Full等)
  • energy_now:当前剩余电量(单位:微瓦时,μWh)
  • power_now:当前实时功耗(单位:微瓦,μW)

计算逻辑

当电池处于Discharging状态时,剩余运行时长 = 剩余电量 / 当前功耗,结果直接是小时数,你可以再转成小时+分钟的格式。

Bash示例代码

# 定义电池路径,可根据实际情况调整为BAT1等
BAT_PATH="/sys/class/power_supply/BAT0"

# 获取当前电池状态
STATUS=$(cat "$BAT_PATH/status")

if [ "$STATUS" = "Discharging" ]; then
    ENERGY_NOW=$(cat "$BAT_PATH/energy_now")
    POWER_NOW=$(cat "$BAT_PATH/power_now")

    # 处理功耗为0的特殊情况(比如待机)
    if [ "$POWER_NOW" -eq 0 ]; then
        echo "当前功耗为0,无法计算剩余运行时长"
        exit 1
    fi

    # 计算时长,保留两位小数
    RUNTIME_HOURS=$(echo "scale=2; $ENERGY_NOW / $POWER_NOW" | bc)
    # 拆分小时和分钟
    HOURS=$(echo "$RUNTIME_HOURS" | cut -d. -f1)
    MINUTES=$(echo "scale=0; ($RUNTIME_HOURS - $HOURS) * 60" | bc)

    echo "预计剩余运行时长:$HOURS 小时 $MINUTES 分钟"
else
    echo "电池未处于放电状态,无法计算剩余运行时长"
fi

注意事项

  • 部分老款电池可能用charge_now(安时)和current_now(安培)来计量,计算逻辑是一样的:charge_now / current_now得到小时数。
  • 如果要做更精准的计算,可以每隔2-3秒读取一次power_now,取平均值,避免瞬时功耗波动导致结果偏差。

二、计算充电时的充满时长

同样依赖sysfs的文件,额外需要energy_full(满电总电量,单位:μWh)。

计算逻辑

当电池处于Charging状态时,充满所需时长 = (满电总电量 - 当前剩余电量) / 当前充电功率,结果为小时数。

Bash示例代码

BAT_PATH="/sys/class/power_supply/BAT0"
STATUS=$(cat "$BAT_PATH/status")

if [ "$STATUS" = "Charging" ]; then
    ENERGY_FULL=$(cat "$BAT_PATH/energy_full")
    ENERGY_NOW=$(cat "$BAT_PATH/energy_now")
    POWER_NOW=$(cat "$BAT_PATH/power_now")

    if [ "$POWER_NOW" -eq 0 ]; then
        echo "当前充电功率为0,无法计算充满时长"
        exit 1
    fi

    # 计算剩余需充入电量
    CHARGE_REMAIN=$((ENERGY_FULL - ENERGY_NOW))
    # 计算充电时长
    CHARGE_TIME_HOURS=$(echo "scale=2; $CHARGE_REMAIN / $POWER_NOW" | bc)
    HOURS=$(echo "$CHARGE_TIME_HOURS" | cut -d. -f1)
    MINUTES=$(echo "scale=0; ($CHARGE_TIME_HOURS - $HOURS) * 60" | bc)

    echo "预计充满时长:$HOURS 小时 $MINUTES 分钟"
else
    echo "电池未处于充电状态,无法计算充满时长"
fi

注意事项

  • 当电池接近满电时,大部分笔记本会自动降低充电功率来保护电池,所以这个计算是基于当前实时功率的估计值,实际充满时间可能会略长。
  • 可以加入循环读取功率的逻辑,动态更新预计时长,让结果更准确。

如果你用C/C++开发命令行工具

这里给个简单的C语言片段,直接读取sysfs文件并计算:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BAT_BASE_PATH "/sys/class/power_supply/BAT0/"

// 读取sysfs中的数值型文件
long long read_sysfs_value(const char *filename) {
    char full_path[100];
    snprintf(full_path, sizeof(full_path), "%s%s", BAT_BASE_PATH, filename);
    
    FILE *file = fopen(full_path, "r");
    if (!file) {
        perror("无法打开文件");
        return -1;
    }
    
    long long value;
    fscanf(file, "%lld", &value);
    fclose(file);
    return value;
}

int main() {
    // 读取电池状态
    char status[20];
    FILE *status_file = fopen(BAT_BASE_PATH "status", "r");
    if (!status_file) {
        perror("无法读取电池状态");
        return 1;
    }
    fscanf(status_file, "%s", status);
    fclose(status_file);

    if (strcmp(status, "Discharging") == 0) {
        long long energy_now = read_sysfs_value("energy_now");
        long long power_now = read_sysfs_value("power_now");
        
        if (energy_now == -1 || power_now == -1 || power_now == 0) {
            printf("无法计算剩余运行时长:数据无效\n");
            return 1;
        }

        double runtime = (double)energy_now / power_now;
        int hours = (int)runtime;
        int minutes = (int)((runtime - hours) * 60);
        printf("预计剩余运行时长:%d小时%d分钟\n", hours, minutes);
    } else if (strcmp(status, "Charging") == 0) {
        long long energy_full = read_sysfs_value("energy_full");
        long long energy_now = read_sysfs_value("energy_now");
        long long power_now = read_sysfs_value("power_now");
        
        if (energy_full == -1 || energy_now == -1 || power_now == -1 || power_now == 0) {
            printf("无法计算充满时长:数据无效\n");
            return 1;
        }

        double charge_time = (double)(energy_full - energy_now) / power_now;
        int hours = (int)charge_time;
        int minutes = (int)((charge_time - hours) * 60);
        printf("预计充满时长:%d小时%d分钟\n", hours, minutes);
    } else {
        printf("电池当前处于%s状态,无法计算目标时长\n", status);
    }

    return 0;
}

最后补充

Arch Linux默认启用sysfs的power_supply接口,不需要安装任何额外包,这个方案是最轻量化、最可靠的。如果要兼容不同笔记本,可以遍历/sys/class/power_supply/目录下的所有子目录,筛选出以BAT开头的路径,自动适配多电池场景。

备注:内容来源于stack exchange,提问作者Ashish Kushwaha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 12:47:58