eww-battery-monitor 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env -S awk -f
  2. # -*- mode: awk -*-
  3. function get_icon(charge) {
  4. if (charge <= 10) {
  5. return "󰂃";
  6. } else if (charge <= 20) {
  7. return "󰁻";
  8. } else if (charge <= 30) {
  9. return "󰁼";
  10. } else if (charge <= 40) {
  11. return "󰁽";
  12. } else if (charge <= 50) {
  13. return "󰁾";
  14. } else if (charge <= 60) {
  15. return "󰁿";
  16. } else if (charge <= 70) {
  17. return "󰂀";
  18. } else if (charge <= 80) {
  19. return "󰂁";
  20. } if (charge < 100) {
  21. return "󰂂";
  22. } else {
  23. return "󰁹"
  24. }
  25. }
  26. function notify_send(title, desc, id) {
  27. if (!id) {
  28. cmd="dunstify -t 0 -p \"" title "\" \"" desc "\""
  29. while ((cmd | getline id) > 0) { }
  30. close(cmd)
  31. } else {
  32. system("dunstify -r " id " \"" title "\" \"" desc "\"")
  33. }
  34. return id
  35. }
  36. function close_notify(id) {
  37. system("dunstify -C " id)
  38. }
  39. function warn_if_low() {
  40. percentage = state_info["percentage"]
  41. id = state_info["id"]
  42. notified = state_info["notified"]
  43. if (percentage <= 10) {
  44. if (!notified) {
  45. state_info["id"] = notify_send("Battery Low", percentage "%", id)
  46. state_info["notified"] = 1
  47. }
  48. } else if (notified) {
  49. close_notify(id)
  50. state_info["notified"] = 0
  51. }
  52. }
  53. function print_state() {
  54. percentage = state_info["percentage"]
  55. tooltip = ""
  56. if (state_info["charging"]) {
  57. tooltip = "Until Full: " (percentage == 100 ? "N/A" : state_info["time to full"])
  58. } else {
  59. tooltip = "Until Empty: " state_info["time to empty"]
  60. }
  61. printf "{\"text\":\"%s%s%d%%\",\"tooltip\":\"%s\"}\n",
  62. get_icon(percentage),
  63. state_info["charging"] ? "󱐋" : "",
  64. percentage,
  65. tooltip
  66. fflush()
  67. }
  68. function string_or(str, def) {
  69. return str == "" ? def : str
  70. }
  71. function parse_record(record, exit_on_absent) {
  72. split(record, fields)
  73. for (i in fields) {
  74. match(fields[i], /^ *([^:]+): *(.+)$/, parts)
  75. if (length(parts) >= 3) {
  76. props[parts[1]] = parts[2]
  77. }
  78. }
  79. name = props["native-path"]
  80. if (name == "") {
  81. return 0
  82. } else if ((! BATTERY && props["power supply"] == "yes" && \
  83. props["native-path"] ~ /BAT[0-9]+/) || name == BATTERY) {
  84. state_info["percentage"] = props["percentage"] + 0
  85. state_info["time to full"] = string_or(props["time to full"], "Unknown")
  86. state_info["time to empty"] = string_or(props["time to empty"], "Unknown")
  87. return 1
  88. } else if ((! ADAPTER && props["power supply"] == "yes" && \
  89. props["native-path"] ~ /ADP[0-9]+/) || name == ADAPTER) {
  90. state_info["charging"] = (props["online"] == "yes")
  91. return 1
  92. } else {
  93. return 0
  94. }
  95. }
  96. function print_initial_stats() {
  97. cmd = "upower --dump"
  98. found = 0
  99. while ((cmd | getline record) > 0) {
  100. if (record ~ /Device: \/org\/freedesktop\/UPower\/devices\// \
  101. && parse_record(record)) {
  102. found = 1
  103. }
  104. }
  105. close(cmd)
  106. if (! found) {
  107. # we found no battery adapters
  108. exit 1
  109. }
  110. print_state()
  111. warn_if_low()
  112. }
  113. BEGIN {
  114. RS = ""
  115. FS = "\n"
  116. print_initial_stats()
  117. cmd = "upower --monitor-detail"
  118. while ((cmd | getline record) > 0) {
  119. if (record ~ /device changed/) {
  120. parse_record(record)
  121. print_state()
  122. warn_if_low()
  123. }
  124. }
  125. close(cmd)
  126. }