The installer asks for the language before the keyboard, and Setup > Language (omarchy language en|zh) switches it later. Under zh_CN the menu reads its labels from omarchy-menu.zh-cn.jsonc, the shell from I18nZh.js through I18n.tr, and notifications are worded by their sender through omarchy-text, which reads the same table. User text is never translated.
159 lines
5.7 KiB
Bash
Executable File
159 lines
5.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# omarchy:summary=Returns a formatted battery status string with percentage and power draw/charge.
|
|
# omarchy:args=[--shell]
|
|
|
|
shell_output=false
|
|
power_supply_path="${OMARCHY_POWER_SUPPLY_PATH:-/sys/class/power_supply}"
|
|
|
|
case "${1:-}" in
|
|
"")
|
|
;;
|
|
--shell)
|
|
shell_output=true
|
|
;;
|
|
*)
|
|
echo "Usage: omarchy-battery-status [--shell]" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
# UPower names the device after the sysfs entry, and only some kernels call
|
|
# that BAT*: Apple Silicon reports battery_macsmc_battery. Match on the class,
|
|
# then take the first one that powers the machine: a wireless mouse or keyboard
|
|
# is a battery_ device too, and UPower marks it "power supply: no".
|
|
battery=""
|
|
battery_info=""
|
|
while read -r candidate; do
|
|
[[ -n $candidate ]] || continue
|
|
candidate_info=$(upower -i "$candidate" 2>/dev/null) || continue
|
|
if grep -qE '^\s*power supply:\s+yes' <<<"$candidate_info"; then
|
|
battery=$candidate
|
|
battery_info=$candidate_info
|
|
break
|
|
fi
|
|
done < <(upower -e 2>/dev/null | grep '/battery_')
|
|
[[ -z $battery ]] && exit 0
|
|
|
|
percentage=$(awk '/percentage/ { print int($2); exit }' <<<"$battery_info")
|
|
capacity=$(awk '/energy-full:/ { printf "%d", $2; exit }' <<<"$battery_info")
|
|
time_remaining=$(awk '/time to (empty|full)/ {
|
|
value = $4
|
|
unit = $5
|
|
if (unit ~ /^minute/) {
|
|
printf "%dm", int(value)
|
|
} else {
|
|
hours = int(value)
|
|
minutes = int((value - hours) * 60)
|
|
if (minutes > 0) {
|
|
printf "%dh %dm", hours, minutes
|
|
} else {
|
|
printf "%dh", hours
|
|
}
|
|
}
|
|
exit
|
|
}' <<<"$battery_info")
|
|
power_rate_raw=$(awk '/energy-rate/ { print $2; exit }' <<<"$battery_info")
|
|
native_path=$(awk '/native-path/ { print $2; exit }' <<<"$battery_info")
|
|
battery_path="$power_supply_path/$native_path"
|
|
|
|
# UPower's energy-rate can lag the kernel telemetry by tens of seconds. Use
|
|
# the instantaneous sysfs reading when available so the open panel stays live.
|
|
if [[ -r $battery_path/power_now ]]; then
|
|
power_rate_raw=$(awk -v microwatts="$(<"$battery_path/power_now")" 'BEGIN { print microwatts / 1000000 }')
|
|
elif [[ -r $battery_path/current_now && -r $battery_path/voltage_now ]]; then
|
|
power_rate_raw=$(awk \
|
|
-v microamps="$(<"$battery_path/current_now")" \
|
|
-v microvolts="$(<"$battery_path/voltage_now")" \
|
|
'BEGIN { print microamps * microvolts / 1000000000000 }')
|
|
fi
|
|
|
|
# Some kernels sign power_now by direction (negative while discharging on
|
|
# Apple Silicon); the state field already says which way it flows.
|
|
power_rate=$(awk -v rate="${power_rate_raw:-0}" 'BEGIN {
|
|
if (rate < 0) rate = -rate
|
|
rounded = sprintf("%.1f", rate)
|
|
sub(/\.0$/, "", rounded)
|
|
print rounded
|
|
}')
|
|
state=$(awk '/state/ { print $2; exit }' <<<"$battery_info")
|
|
threshold_start=$(awk '/charge-start-threshold:/ { gsub(/%/, "", $2); print int($2); exit }' <<<"$battery_info")
|
|
threshold_end=$(awk '/charge-end-threshold:/ { gsub(/%/, "", $2); print int($2); exit }' <<<"$battery_info")
|
|
|
|
# Read the thresholds from the battery UPower resolved rather than a BAT* glob,
|
|
# which misses every battery with another name.
|
|
[[ -n $threshold_end || ! -r $battery_path/charge_control_end_threshold ]] || threshold_end=$(<"$battery_path/charge_control_end_threshold")
|
|
[[ -n $threshold_start || ! -r $battery_path/charge_control_start_threshold ]] || threshold_start=$(<"$battery_path/charge_control_start_threshold")
|
|
[[ -n $threshold_end ]] || threshold_end=$(cat "$power_supply_path"/BAT*/charge_control_end_threshold 2>/dev/null | head -1)
|
|
[[ -n $threshold_start ]] || threshold_start=$(cat "$power_supply_path"/BAT*/charge_control_start_threshold 2>/dev/null | head -1)
|
|
|
|
ac_online=false
|
|
for supply in "$power_supply_path"/*; do
|
|
[[ -r $supply/type ]] || continue
|
|
[[ $(<"$supply/type") == "Mains" ]] || continue
|
|
[[ -r $supply/online ]] || continue
|
|
|
|
if [[ $(<"$supply/online") == "1" ]]; then
|
|
ac_online=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
charge_idle=false
|
|
if awk -v rate="${power_rate_raw:-0}" 'BEGIN { exit !(rate <= 0.2) }'; then
|
|
charge_idle=true
|
|
fi
|
|
|
|
charge_holding=false
|
|
if [[ $ac_online == "true" && -n $threshold_end ]]; then
|
|
if [[ $state == "pending-charge" ]]; then
|
|
charge_holding=true
|
|
elif [[ $state == "fully-charged" ]] && (( percentage < 99 )); then
|
|
charge_holding=true
|
|
elif [[ $state == "charging" && $charge_idle == "true" ]] && (( threshold_end < 99 && percentage >= threshold_end )); then
|
|
charge_holding=true
|
|
fi
|
|
fi
|
|
|
|
if [[ $shell_output == "true" ]]; then
|
|
printf 'percentage\t%s\n' "${percentage}%"
|
|
if [[ $charge_holding == "true" ]]; then
|
|
printf 'state\tholding\n'
|
|
else
|
|
printf 'state\t%s\n' "$state"
|
|
fi
|
|
printf 'rate\t%s\n' "${power_rate}W"
|
|
printf 'size\t%s\n' "${capacity}Wh"
|
|
printf 'time\t%s\n' "$time_remaining"
|
|
|
|
cycles=""
|
|
[[ ! -r $battery_path/cycle_count ]] || cycles=$(<"$battery_path/cycle_count")
|
|
[[ -n $cycles ]] || cycles=$(cat "$power_supply_path"/BAT*/cycle_count 2>/dev/null | head -1)
|
|
|
|
[[ -n $cycles ]] && printf 'cycles\t%s\n' "$cycles"
|
|
|
|
if [[ -n $threshold_end ]]; then
|
|
if [[ -n $threshold_start && $threshold_start != $threshold_end ]]; then
|
|
printf 'threshold\t%s-%s%%\n' "$threshold_start" "$threshold_end"
|
|
else
|
|
printf 'threshold\t%s%%\n' "$threshold_end"
|
|
fi
|
|
fi
|
|
|
|
exit 0
|
|
fi
|
|
|
|
if [[ $charge_holding == "true" ]]; then
|
|
if [[ -n $threshold_start && $threshold_start != $threshold_end ]]; then
|
|
threshold_label="${threshold_start}-${threshold_end}%"
|
|
else
|
|
threshold_label="${threshold_end}%"
|
|
fi
|
|
|
|
omarchy-text "Battery %1% · Holding at %2 · %3W / %4Wh" "$percentage" "$threshold_label" "$power_rate" "$capacity"
|
|
elif [[ $state == "charging" ]]; then
|
|
omarchy-text "Battery %1% · %2 to full · %3W / %4Wh" "$percentage" "$time_remaining" "$power_rate" "$capacity"
|
|
else
|
|
omarchy-text "Battery %1% · %2 left · %3W / %4Wh" "$percentage" "$time_remaining" "$power_rate" "$capacity"
|
|
fi
|