Problem / motivation
I own a Ryzen 5 5600H laptop. While using node-scraper to verify power limits after a BIOS update, I noticed that no existing plugin exposes the PL1 (sustained power limit) from the kernel's powercap interface.
The KernelPlugin reads general OS info; AmdSmiPlugin focuses on discrete GPUs or server hardware. Mobile APUs expose PL1 under /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw – a path currently not collected or validated by any plugin.
This matters for OEMs (Dell, HP, Lenovo) who need to validate that BIOS updates do not accidentally lower PL1 limits, affecting laptop performance. Without automation, this requires manual shell scripts—error‑prone and unscalable.
Proposed solution
I implemented a new plugin AmdMobileApuPlugin following the exact InBandDataPlugin pattern (same as KernelPlugin). It has four standard components:
-
Data Model (AmdMobileApuDataModel):
Pydantic model with pl1_power_limit_mw: int | None and cpu_temp_millidegree: int | None.
-
Collector (AmdMobileApuCollector):
Reads PL1 from /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw (µW → mW) and CPU temp from /sys/class/thermal/thermal_zone0/temp.
Uses try/except for missing files → sets field to None instead of crashing.
-
Analyzer (AmdMobileApuAnalyzer):
If PL1 is None, returns WARN (handles WSL/missing sensors).
If exp_pl1_power_limit_mw is provided, compares actual vs expected (tolerance ±1000 mW) → returns FAIL on deviation, else PASS.
-
Analyzer Args (AmdMobileApuAnalyzerArgs):
Inherits from AnalyzerArgs with one optional field: exp_pl1_power_limit_mw: int | None.
-
Plugin Class (AmdMobileApuPlugin):
Ties the four components together via InBandDataPlugin[DataModel, None, AnalyzerArgs].
Validation:
- Registered in
nodescraper/plugins/__init__.py
- All pre‑commit hooks (
ruff, black, mypy) pass
- Tested on WSL – runs cleanly, returns
WARN (expected, since WSL lacks powercap)
- No tracebacks or crashes
The implementation is ready on my fork. I will open a Pull Request targeting the development branch once this issue is triaged.
Alternatives considered
No response
Scope / impact
No response
Problem / motivation
I own a Ryzen 5 5600H laptop. While using
node-scraperto verify power limits after a BIOS update, I noticed that no existing plugin exposes the PL1 (sustained power limit) from the kernel's powercap interface.The
KernelPluginreads general OS info;AmdSmiPluginfocuses on discrete GPUs or server hardware. Mobile APUs expose PL1 under/sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw– a path currently not collected or validated by any plugin.This matters for OEMs (Dell, HP, Lenovo) who need to validate that BIOS updates do not accidentally lower PL1 limits, affecting laptop performance. Without automation, this requires manual shell scripts—error‑prone and unscalable.
Proposed solution
I implemented a new plugin
AmdMobileApuPluginfollowing the exactInBandDataPluginpattern (same asKernelPlugin). It has four standard components:Data Model (
AmdMobileApuDataModel):Pydantic model with
pl1_power_limit_mw: int | Noneandcpu_temp_millidegree: int | None.Collector (
AmdMobileApuCollector):Reads PL1 from
/sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw(µW → mW) and CPU temp from/sys/class/thermal/thermal_zone0/temp.Uses
try/exceptfor missing files → sets field toNoneinstead of crashing.Analyzer (
AmdMobileApuAnalyzer):If PL1 is
None, returnsWARN(handles WSL/missing sensors).If
exp_pl1_power_limit_mwis provided, compares actual vs expected (tolerance ±1000 mW) → returnsFAILon deviation, elsePASS.Analyzer Args (
AmdMobileApuAnalyzerArgs):Inherits from
AnalyzerArgswith one optional field:exp_pl1_power_limit_mw: int | None.Plugin Class (
AmdMobileApuPlugin):Ties the four components together via
InBandDataPlugin[DataModel, None, AnalyzerArgs].Validation:
nodescraper/plugins/__init__.pyruff,black,mypy) passWARN(expected, since WSL lacks powercap)The implementation is ready on my fork. I will open a Pull Request targeting the
developmentbranch once this issue is triaged.Alternatives considered
No response
Scope / impact
No response