Skip to content

Commit

Permalink
Merge pull request #30 from BlackSound1/gpu-testing
Browse files Browse the repository at this point in the history
Added GPU functionality
  • Loading branch information
BlackSound1 authored Apr 19, 2024
2 parents 54b3d8f + 3b57de2 commit 066249a
Show file tree
Hide file tree
Showing 22 changed files with 418 additions and 94 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/system-monitor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ permissions:

jobs:
build:
runs-on: ubuntu-latest
runs-on: windows-latest

steps:
- name: Checkout repo
Expand Down
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ name = "pypi"
textual = "*"
psutil = "*"
idna = "*"
wmi = "*"

[dev-packages]
flake8 = "*"
Expand Down
202 changes: 115 additions & 87 deletions Pipfile.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ The right-hand side shows various system stats.
- **Memory Usage**: Shows the current status of the system's memory.
- **CPU Usage**: Shows the current load of each of the systems cores, as well as overall CPU load.
- **Network Info**: Shows the status of each connected network interface.
- **GPU Info**: Shows the status of the GPU.

# Assumptions

Expand Down Expand Up @@ -148,7 +149,7 @@ own remote branch (because you forked it). Create a pull request from your forke
- [x] Add CPU load info to Processes and sort by highest load
- [ ] Make certain panels searchable as necessary
- [x] Make panels clickable to open a new screen showing more info
- [ ] Add GPU info
- [x] Add GPU info
- [ ] Add temperature info
- [x] Improve colors, so dark mode toggling looks better
- [x] Lay out information in a nicer, less cluttered way
Expand Down
2 changes: 2 additions & 0 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .screens.cpu_screen import CPU_Screen
from .screens.drive_screen import DriveScreen
from .screens.mem_screen import MemoryScreen
from .screens.gpu_screen import GPU_Screen


class Monitor(App[str]):
Expand All @@ -21,6 +22,7 @@ class Monitor(App[str]):
"cpu": CPU_Screen,
"drive": DriveScreen,
"mem": MemoryScreen,
"gpu": GPU_Screen,
}

def on_mount(self) -> None:
Expand Down
71 changes: 69 additions & 2 deletions src/panes/gpu.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,75 @@
from textual.app import ComposeResult
from textual.containers import VerticalScroll
from textual.css.query import NoMatches
from textual.reactive import reactive
from textual.widgets import Static

from src.utilities import get_gpu_data, RARE_INTERVAL


class GPU_Usage(Static):
BORDER_TITLE = "GPU Usage"
BORDER_TITLE = "GPU Info"
BORDER_SUBTITLE = f"Updated every {RARE_INTERVAL} seconds"

gpu_data = reactive(get_gpu_data())

def update_gpu_data(self) -> None:
"""
Update GPU data
:return: None
"""
self.gpu_data = get_gpu_data()

def watch_gpu_data(self, gpu_data: list) -> None:
"""
Watch `gpu_data` and update the Static Widget with the new information
:param gpu_data: The list of new GPU data
:return: None
"""

# First, grab the Static Widget
try:
static = self.query_one("#gpu-static", Static)
except NoMatches:
return

static_content = ""

# Then, for each video controller, update the Static Widget with its new information
for gpu in gpu_data:
static_content += (
f"[green]GPU[/]: {gpu['gpu']}\n"
f"[green]Driver Version[/]: {gpu['driver_version']}\n"
f"[green]Resolution[/]: {gpu['resolution']}\n"
f"[green]Adapter RAM[/]: {gpu['adapter_ram']}\n"
f"[green]Availability[/]: {gpu['availability']}\n"
f"[green]Refresh[/]: {gpu['refresh']} Hz\n"
f"[green]Status[/]: {gpu['status']}\n"
)

static.update(static_content)

def on_mount(self) -> None:
self.update("This will display current GPU usage")
"""
Set interval to update the memory information.
:return: None
"""
self.update_gpu_data = self.set_interval(RARE_INTERVAL, self.update_gpu_data)

def on_click(self) -> None:
"""
When this pane is clicked, switch to the GPU screen
:return: None
"""
self.app.switch_mode("gpu")

def compose(self) -> ComposeResult:
"""
Generate a ComposeResult by yielding a vertically-scrolling Static widget with the GPU information.
:return: The ComposeResult
"""

with VerticalScroll():
yield Static(id="gpu-static")
1 change: 1 addition & 0 deletions src/panes/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

class NetInfo(Static):
BORDER_TITLE = "Network Info"
BORDER_SUBTITLE = f"Updated every {NET_INTERVAL} seconds"

io = reactive(get_network_stats())

Expand Down
3 changes: 2 additions & 1 deletion src/panes/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from .cpu import CPU_Usage
from .drives import DriveUsage
from .gpu import GPU_Usage
from .memory import MemUsage
from .network import NetInfo

Expand All @@ -20,4 +21,4 @@ def compose(self) -> ComposeResult:
yield MemUsage(id="mem")
yield CPU_Usage(id="cpu")
yield NetInfo(id='network')
# yield GPU_Usage(id="gpu")
yield GPU_Usage(id="gpu")
1 change: 1 addition & 0 deletions src/screens/cpu_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class CPU_Screen(Screen):
("n", "switch_mode('network')", "Network"),
("d", "switch_mode('drive')", "Drives"),
("m", "switch_mode('mem')", "Memory"),
("v", "switch_mode('gpu')", "GPU"),
]

cpu_data = reactive(get_cpu_data())
Expand Down
1 change: 1 addition & 0 deletions src/screens/drive_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class DriveScreen(Screen):
("n", "switch_mode('network')", "Network"),
("d", "switch_mode('main')", "Main Screen"),
("m", "switch_mode('mem')", "Memory"),
("v", "switch_mode('gpu')", "GPU"),
]

# Set the default disks value to an initial call to the function
Expand Down
93 changes: 93 additions & 0 deletions src/screens/gpu_screen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from textual.app import ComposeResult
from textual.containers import Container, VerticalScroll
from textual.css.query import NoMatches
from textual.reactive import reactive
from textual.screen import Screen
from textual.widgets import Header, Footer, DataTable

from src.utilities import RARE_INTERVAL, get_gpu_data


class GPU_Screen(Screen):
BORDER_TITLE = "GPU Info"
BORDER_SUBTITLE = f"Updated every {RARE_INTERVAL} seconds"
CSS_PATH = "../styles/gpu_css.tcss"
BINDINGS = [
("q", "quit", "Quit"),
("t", "toggle_dark", "Toggle dark mode"),
("p", "switch_mode('processes')", "Processes"),
("c", "switch_mode('cpu')", "CPU"),
("n", "switch_mode('network')", "Network"),
("d", "switch_mode('drive')", "Drives"),
("m", "switch_mode('mem')", "Memory"),
("v", "switch_mode('main')", "Main Screen"),
]

gpu_data = reactive(get_gpu_data())

def update_gpu_data(self) -> None:
"""
Update GPU data
:return: None
"""
self.gpu_data = get_gpu_data()

def watch_gpu_data(self, gpu_data: list) -> None:
"""
Watch `gpu_data` and update the Static Widget with the new information
:param gpu_data: The list of new GPU data
:return: None
"""

# First, grab the Static Widget
try:
table = self.query_one("#gpu-screen-table", expect_type=DataTable)
except NoMatches:
return

# Clear the table and add the columns
table.clear(columns=True)
table.add_columns("GPU", "Driver Version", "Resolution", "Adapter RAM",
"Availability", "Refresh", "Status")

# Then, for each video controller, update the Static Widget with its new information
for gpu in gpu_data:
name = gpu['gpu']
version = gpu['driver_version']
resolution = gpu['resolution']
ram = gpu['adapter_ram']
availability = gpu['availability']
refresh = gpu['refresh']
status = gpu['status']

table.add_row(name, version, resolution, ram, availability, refresh, status)

def on_mount(self) -> None:
"""
Perform initial setup for the GPU Screen
:return: None
"""

self.update_gpu_data = self.set_interval(RARE_INTERVAL, self.update_gpu_data)

try:
container = self.query_one("#gpu-container", expect_type=Container)
except NoMatches:
return

container.border_title = self.BORDER_TITLE
container.border_subtitle = self.BORDER_SUBTITLE

def compose(self) -> ComposeResult:
"""
Display the structure of the GPU Screen
:return: The ComposeResult featuring the structure of the GPU Screen
"""

yield Header(show_clock=True)
with Container(id="gpu-container"):
with VerticalScroll():
yield DataTable(id="gpu-screen-table", show_cursor=False, zebra_stripes=True)
yield Footer()
12 changes: 12 additions & 0 deletions src/screens/guide_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
\t- Memory Usage
\t- CPU Usage
\t- Network Information
\t- GPU Information
\t- More coming soon?
- Dark and Light modes
Expand All @@ -39,6 +40,7 @@
"mem_color": {"dark": "#FFFF00", "light": "#F3CD00"},
"cpu_color": {"dark": "#ADD8E6", "light": "#7272f6"},
"net_color": {"dark": "#90EE90", "light": "#008000"},
"gpu_color": {"dark": "#FFC0CB", "light": "#FF1493"},
}

MONITORING_STRING = """
Expand Down Expand Up @@ -78,6 +80,15 @@
[{net_color}]Network Info[/]: An updated list of network interfaces. Each interface has info on:
- Download amount and speed
- Upload amount and speed
[{gpu_color}]GPU Info[/]: Updated GPU info about:
- GPU name: The name of the GPU
- Driver version: The version of the GPU driver
- Resolution: The resolution of the GPU
- Adapter RAM: How much RAM is allocated to the GPU
- Availability: The availability of the GPU. Can have one of several different statuses
- Refresh: The refresh rate of the GPU
- Status: The current status of the GPU
"""


Expand All @@ -103,6 +114,7 @@ class GuideScreen(Screen):
('n', "", ''),
('d', "", ''),
('m', "", ''),
('v', "", ''),
('g', "switch_mode('main')", 'Main Screen'),
]

Expand Down
1 change: 1 addition & 0 deletions src/screens/main_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class MainScreen(Screen):
("n", "switch_mode('network')", "Network"),
("d", "switch_mode('drive')", "Drives"),
("m", "switch_mode('mem')", "Memory"),
("v", "switch_mode('gpu')", "GPU"),
('g', "switch_mode('guide')", 'Guide')
]

Expand Down
1 change: 1 addition & 0 deletions src/screens/mem_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class MemoryScreen(Screen):
("n", "switch_mode('network')", "Network"),
("d", "switch_mode('drive')", "Drives"),
("m", "switch_mode('main')", "Main Screen"),
("v", "switch_mode('gpu')", "GPU"),
]

mem_data = reactive(get_mem_data())
Expand Down
1 change: 1 addition & 0 deletions src/screens/network_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class NetworkScreen(Screen):
("n", "switch_mode('main')", "Main Screen"),
("d", "switch_mode('drive')", "Drives"),
("m", "switch_mode('mem')", "Memory"),
("v", "switch_mode('gpu')", "GPU"),
]

io = reactive(get_network_stats())
Expand Down
1 change: 1 addition & 0 deletions src/screens/processes_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ProcessesScreen(Screen):
("n", "switch_mode('network')", "Network"),
("d", "switch_mode('drive')", "Drives"),
("m", "switch_mode('mem')", "Memory"),
("v", "switch_mode('gpu')", "GPU"),
]

initial = True
Expand Down
13 changes: 13 additions & 0 deletions src/styles/gpu_css.tcss
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#gpu-container {
background: $panel;
border: pink;
border-title-color: $text;
border-title-align: center;
border-subtitle-color: $text;
border-subtitle-align: center;
}

#gpu-container:light {
border: deeppink;
background: $boost-darken-1;
}
13 changes: 13 additions & 0 deletions src/styles/main_css.tcss
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@
border: green;
}

#gpu {
background: $panel;
border: pink;
border-title-color: $text;
border-title-align: center;
border-subtitle-color: $text;
border-subtitle-align: center;
}

#gpu:light {
border: deeppink;
}

.proc {
margin: 0 0 1 0;
}
2 changes: 2 additions & 0 deletions src/styles/network_css.tcss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
border: lightgreen;
border-title-color: $text;
border-title-align: center;
border-subtitle-color: $text;
border-subtitle-align: center;
}

#network-container:light {
Expand Down
Loading

0 comments on commit 066249a

Please sign in to comment.