sekazi

kvmd-oled

Jan 14th, 2022 (edited)
609
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.36 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # ========================================================================== #
  3. #                                                                            #
  4. #    KVMD-OLED - Small OLED daemon for Pi-KVM.                               #
  5. #                                                                            #
  6. #    Copyright (C) 2018  Maxim Devaev <[email protected]>                    #
  7. #                                                                            #
  8. #    This program is free software: you can redistribute it and/or modify    #
  9. #    it under the terms of the GNU General Public License as published by    #
  10. #    the Free Software Foundation, either version 3 of the License, or       #
  11. #    (at your option) any later version.                                     #
  12. #                                                                            #
  13. #    This program is distributed in the hope that it will be useful,         #
  14. #    but WITHOUT ANY WARRANTY; without even the implied warranty of          #
  15. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           #
  16. #    GNU General Public License for more details.                            #
  17. #                                                                            #
  18. #    You should have received a copy of the GNU General Public License       #
  19. #    along with this program.  If not, see <https://www.gnu.org/licenses/>.  #
  20. #                                                                            #
  21. # ========================================================================== #
  22.  
  23. # Replaces /usr/bin/kvmd-oled
  24. # Place 'i2c-dev' at the end of /etc/modules-load.d/kvmd.conf
  25. # Place 'dtparam=i2c_arm=on' at the end of /boot/config.txt
  26. # Run 'systemctl enable --now kvmd-oled'
  27. # Reboot
  28.  
  29. import sys
  30. import socket
  31. import logging
  32. import datetime
  33. import time
  34. import os
  35.  
  36. from typing import Tuple
  37.  
  38. import netifaces
  39. import psutil
  40.  
  41. from luma.core import cmdline
  42. from luma.core.render import canvas
  43.  
  44. from PIL import ImageFont
  45.  
  46.  
  47. # =====
  48. _logger = logging.getLogger("oled")
  49.  
  50.  
  51. # =====
  52. def _get_ip() -> Tuple[str, str]:
  53.     try:
  54.         gws = netifaces.gateways()
  55.         if "default" not in gws:
  56.             raise RuntimeError(f"No default gateway: {gws}")
  57.  
  58.         iface = ""
  59.         for proto in [socket.AF_INET, socket.AF_INET6]:
  60.             if proto in gws["default"]:
  61.                 iface = gws["default"][proto][1]
  62.                 break
  63.         else:
  64.             raise RuntimeError(f"No iface for the gateway {gws['default']}")
  65.  
  66.         for addr in netifaces.ifaddresses(iface).get(proto, []):
  67.             return (iface, addr["addr"])
  68.     except Exception:
  69.         # _logger.exception("Can't get iface/IP")
  70.         return ("<no-iface>", "<no-ip>")
  71.  
  72.  
  73. def _get_uptime() -> str:
  74.     uptime = datetime.timedelta(seconds=int(time.time() - psutil.boot_time()))
  75.     pl = {"days": uptime.days}
  76.     (pl["hours"], rem) = divmod(uptime.seconds, 3600)
  77.     (pl["mins"], pl["secs"]) = divmod(rem, 60)
  78.     return "{days}d {hours}h {mins}m".format(**pl)
  79.  
  80.  
  81. # =====
  82. def main() -> None:
  83.     logging.basicConfig(level=logging.INFO, format="%(message)s")
  84.     logging.getLogger("PIL").setLevel(logging.ERROR)
  85.  
  86.     parser = cmdline.create_parser(description="Display FQDN and IP on the OLED")
  87.     parser.add_argument("--font", default="/usr/share/fonts/TTF/ProggyTiny.ttf", help="Font path")
  88.     parser.add_argument("--font-size", default=16, type=int, help="Font size")
  89.     parser.add_argument("--interval", default=5, type=int, help="Screens interval")
  90.     options = parser.parse_args(sys.argv[1:])
  91.     if options.config:
  92.         config = cmdline.load_config(options.config)
  93.         options = parser.parse_args(config + sys.argv[1:])
  94.  
  95.     device = cmdline.create_device(options)
  96.     font = ImageFont.truetype(options.font, options.font_size)
  97.  
  98.     display_types = cmdline.get_display_types()
  99.     if options.display not in cmdline.get_display_types()["emulator"]:
  100.         _logger.info("Iface: %s", options.interface)
  101.     _logger.info("Display: %s", options.display)
  102.     _logger.info("Size: %dx%d", device.width, device.height)
  103.  
  104.     try:
  105.         with canvas(device) as draw:
  106.             text = f"=====================\n  Welcome to Pi-KVM  \n====================="
  107.             draw.multiline_text((0, 0), text, font=font, fill="white")
  108.         time.sleep(options.interval)
  109.         summary = 0
  110.         while True:
  111.             with canvas(device) as draw:
  112.                 summary = summary % 4
  113.                 if summary == 0:
  114.                     var = os.popen(" pistat | grep 'CPU temp' | cut -d ' ' -f 3 | cut -d '.' -f 1 ")
  115.                     ctemp = var.read().replace('\n', '')
  116.                     var = os.popen(" pistat | grep 'GPU temp' | cut -d ' ' -f 3 | cut -d '.' -f 1 ")
  117.                     gtemp = var.read().replace('\n', '')
  118.                     text = f"Hostname: {socket.getfqdn()}\n  Uptime: {_get_uptime().upper()}\nCPU: {ctemp}'C   GPU: {gtemp}'C"
  119.                 elif summary == 1:
  120.                     var = os.popen(" v=$( ip -o a show | grep 'eth0' | grep 'inet ' | cut -d ' ' -f 7 | cut -d '/' -f 1 ); if [[ \"$v\" != \"\" ]]; then printf ' ETH: '$v; count+=1; else echo \'No Ethernet connected\'; fi ")
  121.                     eth = var.read().replace('\n', '')
  122.                     var = os.popen(" v=$( ip -o a show | grep 'wlan0' | grep 'inet ' | cut -d ' ' -f 7 | cut -d '/' -f 1 ); if [[ \"$v\" != \"\" ]]; then printf 'WLAN: '$v; count+=1; else echo \'No Wi-Fi connected\'; fi ")
  123.                     wlan = var.read().replace('\n', '')
  124.                     var = os.popen(" v=$( netctl-auto list | grep '*' | cut -d '-' -f 2 ); if [[ \"$v\" != \"\" ]]; then printf 'SSID: '$v; count+=1; else echo \''; fi ")
  125.                     ssid = var.read().replace('\n', '')
  126.                     text = f"{eth}\n{wlan}\n{ssid}" # Pi 4
  127.                     #text = f"{wlan}\n{ssid}" # Pi Zero
  128.                 elif summary == 2:
  129.                     time.sleep(options.interval)
  130.                     var = os.popen(" pistat | grep Pi | cut -d ' ' -f 2,3,4,6 ") # Pi 4
  131.                     #var = os.popen(" pistat | grep Pi | cut -d ' ' -f 2,3,4,5 ") # Pi Zero
  132.                     rpi = var.read().replace('\n', '')
  133.                     var = os.popen(" pacman -Q | grep 'kvmd ' | cut -d '-' -f 1 ")
  134.                     kvmd = var.read().replace('\n', '').upper()
  135.                     var = os.popen(" pacman -Q | grep kvmd-platform | cut -d '-' -f 3 ")
  136.                     plat = var.read().replace('\n', '').upper()
  137.                     var = os.popen(" pacman -Q | grep kvmd-platform | cut -d '-' -f 4 ")
  138.                     hdmi = var.read().replace('\n', '').upper()
  139.                     var = os.popen(" pistat | grep 'Throttled past' | cut -d ' ' -f 3 ")
  140.                     ovht = var.read().replace('\n', '').upper()
  141.                     var = os.popen(" pistat | grep 'Undervoltage past' | cut -d ' ' -f 3 ")
  142.                     undv = var.read().replace('\n', '').upper()
  143.                     text = f"{rpi}\n{kvmd} {plat} {hdmi}\nOVHT: {ovht:<3}   UNDV: {undv:<3}"
  144.                 else:
  145.                     var = os.popen(" free -h --si | grep 'Mem' | tr -s ' ' | cut -d ' ' -f 2 ")
  146.                     ramtot = var.read().replace('\n', '')
  147.                     var = os.popen(" free -h --si | grep 'Mem' | tr -s ' ' | cut -d ' ' -f 3 ")
  148.                     ramuse = var.read().replace('\n', '')
  149.                     var = os.popen(" free -h --si | grep 'Mem' | tr -s ' ' | cut -d ' ' -f 4 ")
  150.                     ramfre = var.read().replace('\n', '')
  151.                     var = os.popen(" df -h --total | grep 'total' | tr -s ' ' | cut -d ' ' -f 2 ")
  152.                     hddtot = var.read().replace('\n', '')
  153.                     var = os.popen(" df -h --total | grep 'total' | tr -s ' ' | cut -d ' ' -f 3 ")
  154.                     hdduse = var.read().replace('\n', '')
  155.                     var = os.popen(" df -h --total | grep 'total' | tr -s ' ' | cut -d ' ' -f 4 ")
  156.                     hddfre = var.read().replace('\n', '')
  157.                     text = f"        Used    Free \n RAM: {ramuse:>6}  {ramfre:>6} \n HDD: {hdduse:>6}  {hddfre:>6} \n"
  158.                 draw.multiline_text((0, 0), text, font=font, fill="white")
  159.                 summary += 1
  160.                 time.sleep(options.interval)
  161.     except (SystemExit, KeyboardInterrupt):
  162.         pass
  163.  
  164.  
  165. if __name__ == "__main__":
  166.     main()
  167.  
Add Comment
Please, Sign In to add comment