Metadata-Version: 2.5
Name: sysresource-monitor
Version: 0.2.1
Summary: Desktop tray toast + CLI for CPU, RAM and per-drive disk usage
Project-URL: Repository, https://github.com/pandiyarajk/sysresource-monitor
Project-URL: Issues, https://github.com/pandiyarajk/sysresource-monitor/issues
Author-email: Pandiyaraj Karuppasamy <pandiyarajk@live.com>
License: MIT
License-File: LICENSE
Keywords: cpu,disk,memory,monitor,psutil,pyside6,system,toast,tray
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Win32 (MS Windows)
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.11
Requires-Dist: psutil>=5.9
Requires-Dist: pyside6>=6.6
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: twine>=4.0; extra == 'dev'
Description-Content-Type: text/markdown

# sysresource-monitor

[![PyPI version](https://img.shields.io/pypi/v/sysresource-monitor.svg)](https://pypi.org/project/sysresource-monitor/)
[![Python versions](https://img.shields.io/pypi/pyversions/sysresource-monitor.svg)](https://pypi.org/project/sysresource-monitor/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Downloads](https://img.shields.io/pypi/dm/sysresource-monitor.svg)](https://pypi.org/project/sysresource-monitor/)
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-blue.svg)](https://github.com/pandiyarajk/sysresource-monitor)
[![Built with PySide6](https://img.shields.io/badge/GUI-PySide6-41cd52.svg)](https://doc.qt.io/qtforpython/)

CPU, RAM and per-drive disk usage on a small always-on-top toast that parks
itself **just above the system clock** - and slides out of the way the moment
your cursor comes near it.

```
🖥  System Resources                       61%
    CPU   6.2 of 8 cores idle   25°C       23%
          ▁▃▁▂█▁▂▁                             <- one bar per logical core
    RAM   6.7 GB free of 15.9 GB           58%
    CPU↑  python.exe                        7%
    RAM↑  studio64.exe   1.7 GB            11%
    C:    161.0 GB free of 350.9 GB        54%
    D:    62.2 GB free of 125.2 GB         50%
    G:    152.9 GB free of 350.9 GB        56%
    updated 23:23:24   every 5s   3 drives   % = in use
```

No config file, no HTTP server, no background service - a tray icon and a
toast, plus a CLI for when you just want the numbers.

## Install

```bash
pip install sysresource-monitor
```

From a checkout:

```bash
pip install -e .
```

Requires Python 3.11+, [PySide6](https://doc.qt.io/qtforpython/) for the toast
and [psutil](https://github.com/giampaolo/psutil) for the numbers.

## Use

```bash
sysresource-monitor                    # launch the tray toast
sysresource-monitor --interval 2       # ... sampling every 2 seconds
sysresource-monitor --all-mounts       # ... including mounts psutil hides
sysresource-monitor status             # print one sample as a table
sysresource-monitor status --json      # print one sample as JSON
sysresource-monitor status --swap      # include swap usage
sysresource-monitor status --watch     # redraw the table every 5 seconds
sysresource-monitor status --watch 2   # ... every 2 seconds instead
sysresource-monitor status --no-procs  # skip the top-consumer scan
sysresource-monitor status --no-temp   # skip the temperature query
```

Also runs as `python -m sysresource_monitor [...]`, or on Windows via
`run_monitor.bat`, which pins the `py -3.13` launcher so a stray `python` on
PATH can't pick an interpreter without PySide6 installed.

## What it shows

Each row pairs **what is spare** (in words, on the left) with **what is in
use** (the percentage, on the right). Those are opposite quantities, so the
left-hand text always names itself - `idle`, `free` - and the percentage column
is labelled once, in the footer, as `% = in use`.

| Row | left: spare capacity | right: in use |
| --- | --- | --- |
| CPU | `6.2 of 8 cores idle`, plus temperature | current load |
| core strip | one bar per logical core | per-core load |
| RAM | `6.7 GB free of 15.9 GB` | memory in use |
| CPU↑ | the process using the most CPU | its share of the machine |
| RAM↑ | the process using the most RAM, and how much | its share of RAM |
| One row per fixed drive | `161.0 GB free of 350.9 GB` | space in use |

The core strip earns its place on a busy machine: one pegged core reads as 12%
overall on a 8-thread box, which looks calm on the CPU row and obvious on the
strip.

Per-process CPU is normalised by core count, so `CPU↑ 25%` means a quarter of
the whole machine, the way Task Manager counts it - not a quarter of one core.
The terminal view prints both figures.

### About the temperature

There is no portable way to read a CPU temperature, so this is best-effort and
the row simply omits it when nothing will answer:

* **Linux/FreeBSD** - `psutil.sensors_temperatures()`, preferring a real
  package sensor (`coretemp`, `k10temp`, `zenpower`, `cpu_thermal`).
* **Windows** - `psutil` doesn't implement that call at all, and the usual
  substitute, `MSAcpi_ThermalZoneTemperature`, needs an elevated process. The
  fallback is the ACPI thermal-zone performance counter, which any user can
  read. That is a chassis/zone reading rather than the CPU die, so treat it as
  indicative. If you want a true die temperature, run something like
  LibreHardwareMonitor alongside.
* **macOS** - nothing without a signed helper, so the row stays hidden.

The badge in the header is the highest pressure of all of them, and it colours
the whole card: green under 70%, amber from 70%, red from 90%. Each row's own
percentage is coloured on the same scale, so a drive filling up stands out
without you reading the numbers.

## Where it sits, and how it moves

The toast anchors to the bottom-right of the *work area* - the desktop minus
the taskbar - so on a default Windows setup it lands directly above the clock.
Move the taskbar or change its size and the toast follows on the next sample.

The touch-and-go behaviour is the same as
[cursorhub](https://github.com/pandiyarajk/cursorhub)'s: bring the mouse into
the toast's corner and it slides to the opposite side of the screen in a
250 ms ease-out, then slides home once the cursor leaves. It never takes focus
and never eats a click - it just gets out of the way.

## Refresh cadence

Three cadences, because the numbers cost wildly different amounts to read:

| Every | What | Why |
| --- | --- | --- |
| 5s (`--interval`) | CPU, per-core, RAM | free |
| 15s | disks, top consumers | `disk_usage()` can block on a dead network mount; the process scan walks every PID |
| 30s | temperature | on Windows it shells out to PowerShell, about a second each time |

Sampling happens on a worker thread, so a slow mount never freezes the toast,
and a tick is skipped rather than queued if the previous one is still running.
Values from the slower passes stay on screen between them, so no row ever
blanks.

Per-process CPU counters are primed once at the first scan, because
`cpu_percent()` has nothing to diff against on a first call - without that, the
first reading is 0.0 for every process and the "top consumer" is just whichever
process happened to be enumerated first.

Unreadable mounts - empty optical drives, offline shares, mounts you can't stat
- are skipped rather than raised. A monitor that dies because a share went
offline is worse than one missing a row.

## Tray menu

* **Refresh now** - resample immediately, disks included
* **Show toast** / **Hide toast**
* **Quit**

Single-click or double-click the tray icon to bring the toast back.

## Layout

```
sysresource_monitor/
    stats.py       psutil sampling + byte/percent formatting (Qt-free)
    monitor.py     the toast, the tray icon, the refresh timer
    cli.py         `status` table, --json, --watch
    __main__.py    argument dispatch
```

`stats.py` imports nothing from Qt, so `sysresource-monitor status` works over
SSH or in a container where there's no display to put a toast on.

## Licence

MIT - see [LICENSE](LICENSE).
