hardwaremon 1.2.2__tar.gz → 1.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/PKG-INFO +1 -1
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/hardwaremon.py +123 -152
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon.egg-info/PKG-INFO +1 -1
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/.github/workflows/publish.yml +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/.github/workflows/python-app.yml +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/.gitignore +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/HardwareMon.sh +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/LICENSE +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/README.md +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/Windows/HardwareMon.exe +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/Windows/hardwaremon_win.py +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/assets/demo.gif +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/__init__.py +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/hardwaremon_gui.py +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/icons/board.png +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/icons/cpu.png +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/icons/disk.png +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/icons/gpu.png +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/icons/os.png +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon/icons/ram.png +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon.egg-info/SOURCES.txt +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon.egg-info/dependency_links.txt +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon.egg-info/entry_points.txt +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon.egg-info/requires.txt +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/hardwaremon.egg-info/top_level.txt +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/pyproject.toml +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/requirements.txt +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/setup.cfg +0 -0
- {hardwaremon-1.2.2 → hardwaremon-1.2.3}/test_hardwaremon.py +0 -0
|
@@ -117,65 +117,32 @@ def check_alerts():
|
|
|
117
117
|
return alerts
|
|
118
118
|
|
|
119
119
|
|
|
120
|
-
def gpu_info()
|
|
121
|
-
lines = ["=== GPU
|
|
122
|
-
|
|
120
|
+
def gpu_info():
|
|
121
|
+
lines = ["=== GPU INFORMATION ===", ""]
|
|
123
122
|
try:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
pcie_info = run(f"lspci -s {bus_id} -vv")
|
|
145
|
-
lane_match = re.search(
|
|
146
|
-
r"LnkSta:\s+Speed\s+[^,]+,\s+Width\s+x(\d+).*?LnkCap:\s+Speed\s+[^,]+,\s+Width\s+x(\d+)",
|
|
147
|
-
pcie_info,
|
|
148
|
-
re.S,
|
|
149
|
-
)
|
|
150
|
-
if lane_match:
|
|
151
|
-
current, maximum = lane_match.groups()
|
|
152
|
-
lines.append(f" PCIe: x{current} (max x{maximum})")
|
|
153
|
-
else:
|
|
154
|
-
lines.append(" PCIe: Unknown")
|
|
155
|
-
|
|
156
|
-
# 3. VRAM detection
|
|
157
|
-
if "NVIDIA" in gpu:
|
|
158
|
-
vram = run(
|
|
159
|
-
"nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits"
|
|
160
|
-
)
|
|
161
|
-
lines.append(f" VRAM: {vram} MB" if vram else " VRAM: Unknown")
|
|
162
|
-
|
|
163
|
-
elif "Advanced Micro Devices" in gpu:
|
|
164
|
-
# Try sysfs first (works without Xorg / on Wayland)
|
|
165
|
-
vram_bytes = run(
|
|
166
|
-
f"cat /sys/bus/pci/devices/0000:{bus_id}/mem_info_vram_total 2>/dev/null"
|
|
167
|
-
)
|
|
168
|
-
if vram_bytes and vram_bytes.isdigit():
|
|
169
|
-
vram_mb = int(vram_bytes) // (1024 ** 2)
|
|
170
|
-
lines.append(f" VRAM: {vram_mb} MB")
|
|
171
|
-
else:
|
|
172
|
-
# Fallback: rocm-smi
|
|
173
|
-
vram = run("rocm-smi --showmeminfo vram 2>/dev/null | grep 'Total Memory'")
|
|
174
|
-
lines.append(f" VRAM: {vram}" if vram else " VRAM: Unknown")
|
|
123
|
+
# Try NVIDIA first
|
|
124
|
+
nvidia = subprocess.getoutput("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader")
|
|
125
|
+
if nvidia and "error" not in nvidia.lower() and "not found" not in nvidia.lower():
|
|
126
|
+
for line in nvidia.strip().split("\n"):
|
|
127
|
+
lines.append(line.strip())
|
|
128
|
+
return lines
|
|
129
|
+
|
|
130
|
+
# Try AMD via rocm-smi
|
|
131
|
+
amd = subprocess.getoutput("rocm-smi --showproductname 2>/dev/null")
|
|
132
|
+
if amd and "not found" not in amd.lower() and "error" not in amd.lower():
|
|
133
|
+
for line in amd.strip().split("\n"):
|
|
134
|
+
lines.append(line.strip())
|
|
135
|
+
return lines
|
|
136
|
+
|
|
137
|
+
# Fall back to lspci
|
|
138
|
+
out = subprocess.getoutput("lspci | grep -Ei 'vga|3d|display'")
|
|
139
|
+
if out:
|
|
140
|
+
lines.extend(out.strip().split("\n"))
|
|
141
|
+
else:
|
|
142
|
+
lines.append("GPU info not available")
|
|
175
143
|
|
|
176
144
|
except Exception as e:
|
|
177
|
-
lines.append(f"
|
|
178
|
-
|
|
145
|
+
lines.append(f"GPU info error: {e}")
|
|
179
146
|
return lines
|
|
180
147
|
|
|
181
148
|
# GPU temp (if available)
|
|
@@ -399,74 +366,6 @@ def memory_temperature():
|
|
|
399
366
|
return lines if len(lines) > 1 else ["===No Memory temperature data found==="]
|
|
400
367
|
|
|
401
368
|
|
|
402
|
-
def gpu_info():
|
|
403
|
-
lines = ["=== GPU Information ==="]
|
|
404
|
-
|
|
405
|
-
try:
|
|
406
|
-
if platform.system() != "Linux":
|
|
407
|
-
return ["GPU info not implemented for this OS."]
|
|
408
|
-
|
|
409
|
-
# 1. Find ONLY dedicated AMD / NVIDIA GPUs
|
|
410
|
-
cmd = (
|
|
411
|
-
"lspci | grep -Ei "
|
|
412
|
-
"'(NVIDIA Corporation|Advanced Micro Devices, Inc.)' | "
|
|
413
|
-
"'(VGA|3D)' | "
|
|
414
|
-
"'(APU)' -vi"
|
|
415
|
-
"grep -E '(VGA|3D)' | "
|
|
416
|
-
"grep -vi 'APU'"
|
|
417
|
-
)
|
|
418
|
-
gpus = [l for l in os.popen(cmd).read().splitlines() if l]
|
|
419
|
-
|
|
420
|
-
if not gpus:
|
|
421
|
-
return ["No dedicated AMD or NVIDIA GPU found."]
|
|
422
|
-
|
|
423
|
-
for gpu in gpus:
|
|
424
|
-
lines.append(gpu)
|
|
425
|
-
|
|
426
|
-
# Extract PCI bus ID (e.g. 01:00.0)
|
|
427
|
-
bus_id = gpu.split()[0]
|
|
428
|
-
|
|
429
|
-
# 2. PCIe lane width (current + max)
|
|
430
|
-
pcie_info = os.popen(f"lspci -s {bus_id} -vv").read()
|
|
431
|
-
lane_match = re.search(
|
|
432
|
-
r"LnkSta:\s+Speed\s+[^,]+,\s+Width\s+x(\d+).*?\n.*?LnkCap:\s+Speed\s+[^,]+,\s+Width\s+x(\d+)",
|
|
433
|
-
pcie_info,
|
|
434
|
-
re.S
|
|
435
|
-
)
|
|
436
|
-
|
|
437
|
-
if lane_match:
|
|
438
|
-
current, maximum = lane_match.groups()
|
|
439
|
-
lines.append(f" PCIe: x{current} (max x{maximum})")
|
|
440
|
-
else:
|
|
441
|
-
lines.append(" PCIe: Unknown")
|
|
442
|
-
|
|
443
|
-
# 3. VRAM detection
|
|
444
|
-
if "NVIDIA" in gpu:
|
|
445
|
-
vram = os.popen(
|
|
446
|
-
"nvidia-smi --query-gpu=memory.total "
|
|
447
|
-
"--format=csv,noheader,nounits"
|
|
448
|
-
).read().strip()
|
|
449
|
-
if vram:
|
|
450
|
-
lines.append(f" VRAM: {vram} MB")
|
|
451
|
-
else:
|
|
452
|
-
lines.append(" VRAM: Unknown")
|
|
453
|
-
|
|
454
|
-
elif "Advanced Micro Devices" in gpu:
|
|
455
|
-
vram = os.popen(
|
|
456
|
-
"grep -i 'VRAM' /var/log/Xorg.0.log 2>/dev/null | head -n1"
|
|
457
|
-
).read().strip()
|
|
458
|
-
if vram:
|
|
459
|
-
lines.append(f" VRAM: {vram}")
|
|
460
|
-
else:
|
|
461
|
-
lines.append(" VRAM: Unknown (AMD userspace tools vary)")
|
|
462
|
-
|
|
463
|
-
return lines
|
|
464
|
-
|
|
465
|
-
except Exception as e:
|
|
466
|
-
return [f"GPU info error: {e}"]
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
369
|
|
|
471
370
|
|
|
472
371
|
def intel_gpu_info():
|
|
@@ -588,36 +487,110 @@ def drive_info():
|
|
|
588
487
|
|
|
589
488
|
def gpu_temperature():
|
|
590
489
|
lines = ["=== GPU Temperature ==="]
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
for
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
490
|
+
found = False
|
|
491
|
+
|
|
492
|
+
# NVIDIA
|
|
493
|
+
nvidia = subprocess.getoutput("nvidia-smi --query-gpu=name,temperature.gpu --format=csv,noheader 2>/dev/null")
|
|
494
|
+
if nvidia and "not found" not in nvidia.lower() and "error" not in nvidia.lower() and "failed" not in nvidia.lower():
|
|
495
|
+
for line in nvidia.strip().split("\n"):
|
|
496
|
+
parts = line.split(",")
|
|
497
|
+
if len(parts) == 2:
|
|
498
|
+
name, temp = parts[0].strip(), parts[1].strip()
|
|
499
|
+
lines.append(f"{name}: {temp} °C")
|
|
500
|
+
found = True
|
|
501
|
+
|
|
502
|
+
# AMD via rocm-smi
|
|
503
|
+
amd = subprocess.getoutput("rocm-smi --showtemp 2>/dev/null")
|
|
504
|
+
if amd and "not found" not in amd.lower() and "error" not in amd.lower():
|
|
505
|
+
for line in amd.strip().split("\n"):
|
|
506
|
+
if "temperature" in line.lower() or "°c" in line.lower() or "temp" in line.lower():
|
|
507
|
+
lines.append(line.strip())
|
|
508
|
+
found = True
|
|
509
|
+
|
|
510
|
+
# AMD fallback via hwmon (works without rocm-smi)
|
|
511
|
+
if not found:
|
|
512
|
+
hwmon_base = "/sys/class/hwmon"
|
|
513
|
+
if os.path.exists(hwmon_base):
|
|
514
|
+
for hw in os.listdir(hwmon_base):
|
|
515
|
+
hw_path = os.path.join(hwmon_base, hw)
|
|
516
|
+
name = read_sys(os.path.join(hw_path, "name")) or ""
|
|
517
|
+
if "amdgpu" in name.lower():
|
|
518
|
+
for f in os.listdir(hw_path):
|
|
519
|
+
if f.startswith("temp") and f.endswith("_input"):
|
|
520
|
+
raw = read_sys(os.path.join(hw_path, f))
|
|
521
|
+
label_file = f.replace("_input", "_label")
|
|
522
|
+
label = read_sys(os.path.join(hw_path, label_file)) or f
|
|
523
|
+
if raw and raw.isdigit():
|
|
524
|
+
lines.append(f"AMD ({label}): {int(raw) // 1000} °C")
|
|
525
|
+
found = True
|
|
526
|
+
|
|
527
|
+
return lines if found else ["=== No GPU temperature data found ==="]
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def get_package_manager():
|
|
531
|
+
for pm, cmd in [("apt", "sudo apt install i2c-tools"),
|
|
532
|
+
("dnf", "sudo dnf install i2c-tools"),
|
|
533
|
+
("pacman", "sudo pacman -S i2c-tools"),
|
|
534
|
+
("zypper", "sudo zypper install i2c-tools")]:
|
|
535
|
+
if subprocess.getoutput(f"which {pm} 2>/dev/null").strip():
|
|
536
|
+
return cmd
|
|
537
|
+
return "install i2c-tools via your package manager"
|
|
605
538
|
|
|
606
539
|
def memory_temperature():
|
|
607
540
|
lines = ["=== Memory Temperature ==="]
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
541
|
+
found = False
|
|
542
|
+
|
|
543
|
+
i2c_available = subprocess.getoutput("which decode-dimms 2>/dev/null").strip()
|
|
544
|
+
eeprom_loaded = "eeprom" in subprocess.getoutput("lsmod 2>/dev/null")
|
|
545
|
+
|
|
546
|
+
if not i2c_available or not eeprom_loaded:
|
|
547
|
+
lines.append("DIMM Memory temperature unavailable.")
|
|
548
|
+
lines.append("")
|
|
549
|
+
if not i2c_available:
|
|
550
|
+
lines.append(" → Install i2c-tools:")
|
|
551
|
+
lines.append(f" {get_package_manager()}")
|
|
552
|
+
if not eeprom_loaded:
|
|
553
|
+
lines.append(" → Load the eeprom kernel module:")
|
|
554
|
+
lines.append(" sudo modprobe eeprom")
|
|
555
|
+
lines.append(" (Add 'eeprom' to /etc/modules to persist across reboots)")
|
|
556
|
+
return lines
|
|
619
557
|
|
|
620
|
-
|
|
558
|
+
# Try decode-dimms
|
|
559
|
+
decode = subprocess.getoutput("decode-dimms 2>/dev/null")
|
|
560
|
+
if decode and "not found" not in decode.lower() and "command not found" not in decode.lower():
|
|
561
|
+
for line in decode.split("\n"):
|
|
562
|
+
if "temperature" in line.lower():
|
|
563
|
+
lines.append(line.strip())
|
|
564
|
+
found = True
|
|
565
|
+
|
|
566
|
+
# Try hwmon
|
|
567
|
+
if not found:
|
|
568
|
+
hwmon_base = "/sys/class/hwmon"
|
|
569
|
+
if os.path.exists(hwmon_base):
|
|
570
|
+
for hw in os.listdir(hwmon_base):
|
|
571
|
+
hw_path = os.path.join(hwmon_base, hw)
|
|
572
|
+
name = read_sys(os.path.join(hw_path, "name")) or ""
|
|
573
|
+
if any(k in name.lower() for k in ("dimm", "ddr", "ram", "memory", "spd")):
|
|
574
|
+
for f in os.listdir(hw_path):
|
|
575
|
+
if f.startswith("temp") and f.endswith("_input"):
|
|
576
|
+
raw = read_sys(os.path.join(hw_path, f))
|
|
577
|
+
label_file = f.replace("_input", "_label")
|
|
578
|
+
label = read_sys(os.path.join(hw_path, label_file)) or f
|
|
579
|
+
if raw and raw.isdigit():
|
|
580
|
+
lines.append(f"{name} ({label}): {int(raw) // 1000} °C")
|
|
581
|
+
found = True
|
|
582
|
+
|
|
583
|
+
# psutil fallback
|
|
584
|
+
if not found:
|
|
585
|
+
temps = psutil.sensors_temperatures()
|
|
586
|
+
if temps:
|
|
587
|
+
for name, entries in temps.items():
|
|
588
|
+
for entry in entries:
|
|
589
|
+
if "memory" in entry.label.lower() or "ram" in name.lower() or "dimm" in name.lower():
|
|
590
|
+
lines.append(f"{entry.label or name}: {entry.current} °C")
|
|
591
|
+
found = True
|
|
592
|
+
|
|
593
|
+
return lines if found else ["=== No memory temperature data found ==="]
|
|
621
594
|
|
|
622
595
|
|
|
623
596
|
def cpu_temperature():
|
|
@@ -854,8 +827,6 @@ def system_summary():
|
|
|
854
827
|
|
|
855
828
|
return lines
|
|
856
829
|
|
|
857
|
-
# ---------- Full Sections Placeholder ----------
|
|
858
|
-
# Replace this with your actual SECTIONS list from your app
|
|
859
830
|
SECTIONS = [
|
|
860
831
|
system_info,
|
|
861
832
|
swap_memory,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|