├── .github └── workflows │ └── release.yaml ├── .gitignore ├── .gitmodules ├── BUILD.md ├── HardwareMonitor ├── Hardware │ ├── CPU │ │ ├── __init__.py │ │ └── __init__.pyi │ ├── Controller │ │ ├── AeroCool │ │ │ ├── __init__.py │ │ │ └── __init__.pyi │ │ ├── AquaComputer │ │ │ ├── __init__.py │ │ │ └── __init__.pyi │ │ └── __init__.py │ ├── Gpu │ │ ├── __init__.py │ │ └── __init__.pyi │ ├── Motherboard │ │ ├── Lpc │ │ │ ├── EC │ │ │ │ ├── __init__.py │ │ │ │ └── __init__.pyi │ │ │ └── __init__.py │ │ ├── __init__.py │ │ └── __init__.pyi │ ├── Psu │ │ ├── Corsair │ │ │ ├── __init__.py │ │ │ └── __init__.pyi │ │ └── __init__.py │ ├── Storage │ │ ├── __init__.py │ │ └── __init__.pyi │ ├── __init__.py │ └── __init__.pyi ├── Interop │ ├── __init__.py │ └── __init__.pyi ├── Software │ ├── __init__.py │ └── __init__.pyi ├── Util.py ├── __init__.py ├── _util │ └── types.pyi └── lib │ ├── HidSharp.dll │ ├── LICENSE │ └── LibreHardwareMonitorLib.dll ├── LICENSE ├── README.md ├── examples └── wsgi_provider.py ├── pyproject.toml ├── scripts ├── generate_all.py ├── generate_namespace_init.py ├── generate_stubs.py ├── generate_types_util.py └── namespace_template.py └── test └── TestHardwareMonitor.py /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "[0-9]+.[0-9]+.[0-9]+" 7 | - "[0-9]+.[0-9]+.[0-9]+a[0-9]+" 8 | - "[0-9]+.[0-9]+.[0-9]+b[0-9]+" 9 | - "[0-9]+.[0-9]+.[0-9]+rc[0-9]+" 10 | 11 | env: 12 | PACKAGE_NAME: "HardwareMonitor" 13 | OWNER: "SimpleNick" 14 | 15 | jobs: 16 | details: 17 | runs-on: ubuntu-latest 18 | outputs: 19 | new_version: ${{ steps.release.outputs.new_version }} 20 | suffix: ${{ steps.release.outputs.suffix }} 21 | tag_name: ${{ steps.release.outputs.tag_name }} 22 | steps: 23 | - uses: actions/checkout@v2 24 | 25 | - name: Extract tag and Details 26 | id: release 27 | run: | 28 | if [ "${{ github.ref_type }}" = "tag" ]; then 29 | TAG_NAME=${GITHUB_REF#refs/tags/} 30 | NEW_VERSION=$(echo $TAG_NAME | awk -F'-' '{print $1}') 31 | SUFFIX=$(echo $TAG_NAME | grep -oP '[a-z]+[0-9]+' || echo "") 32 | echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT" 33 | echo "suffix=$SUFFIX" >> "$GITHUB_OUTPUT" 34 | echo "tag_name=$TAG_NAME" >> "$GITHUB_OUTPUT" 35 | echo "Version is $NEW_VERSION" 36 | echo "Suffix is $SUFFIX" 37 | echo "Tag name is $TAG_NAME" 38 | else 39 | echo "No tag found" 40 | exit 1 41 | fi 42 | 43 | check_pypi: 44 | needs: details 45 | runs-on: ubuntu-latest 46 | steps: 47 | - name: Fetch information from PyPI 48 | run: | 49 | response=$(curl -s https://pypi.org/pypi/${{ env.PACKAGE_NAME }}/json || echo "{}") 50 | latest_previous_version=$(echo $response | grep -oP '"releases":\{"\K[^"]+' | sort -rV | head -n 1) 51 | if [ -z "$latest_previous_version" ]; then 52 | echo "Package not found on PyPI." 53 | latest_previous_version="0.0.0" 54 | fi 55 | echo "Latest version on PyPI: $latest_previous_version" 56 | echo "latest_previous_version=$latest_previous_version" >> $GITHUB_ENV 57 | 58 | - name: Compare versions and exit if not newer 59 | run: | 60 | NEW_VERSION=${{ needs.details.outputs.new_version }} 61 | LATEST_VERSION=$latest_previous_version 62 | if [ "$(printf '%s\n' "$LATEST_VERSION" "$NEW_VERSION" | sort -rV | head -n 1)" != "$NEW_VERSION" ] || [ "$NEW_VERSION" == "$LATEST_VERSION" ]; then 63 | echo "The new version $NEW_VERSION is not greater than the latest version $LATEST_VERSION on PyPI." 64 | exit 1 65 | else 66 | echo "The new version $NEW_VERSION is greater than the latest version $LATEST_VERSION on PyPI." 67 | fi 68 | 69 | setup_and_build: 70 | needs: [details, check_pypi] 71 | runs-on: ubuntu-latest 72 | steps: 73 | - uses: actions/checkout@v4 74 | 75 | - name: Set up Python 76 | uses: actions/setup-python@v5 77 | with: 78 | python-version: "3.12" 79 | 80 | - name: Install pypa/build 81 | run: >- 82 | python -m 83 | pip install 84 | build 85 | --user 86 | 87 | - name: Build source and wheel distribution 88 | run: >- 89 | python -m 90 | build 91 | --sdist 92 | --wheel 93 | --outdir dist 94 | 95 | - name: Upload artifacts 96 | uses: actions/upload-artifact@v3 97 | with: 98 | name: dist 99 | path: dist/ 100 | 101 | pypi_publish: 102 | runs-on: ubuntu-latest 103 | needs: [setup_and_build, details] 104 | 105 | permissions: 106 | # IMPORTANT: this permission is mandatory for trusted publishing 107 | id-token: write 108 | # Dedicated environments with protections for publishing are strongly recommended. 109 | environment: 110 | name: release 111 | 112 | steps: 113 | - name: Retrieve release distributions 114 | uses: actions/download-artifact@v3 115 | with: 116 | name: dist 117 | path: dist/ 118 | 119 | - name: Publish release distributions to PyPI 120 | uses: pypa/gh-action-pypi-publish@release/v1 121 | 122 | github_release: 123 | name: Create GitHub Release 124 | needs: [setup_and_build, details] 125 | runs-on: ubuntu-latest 126 | permissions: 127 | contents: write 128 | steps: 129 | - name: Checkout Code 130 | uses: actions/checkout@v4 131 | with: 132 | fetch-depth: 0 133 | 134 | - name: Download artifacts 135 | uses: actions/download-artifact@v3 136 | with: 137 | name: dist 138 | path: dist/ 139 | 140 | - name: Create GitHub Release 141 | id: create_release 142 | env: 143 | GH_TOKEN: ${{ github.token }} 144 | run: | 145 | gh release create ${{ needs.details.outputs.tag_name }} dist/* --title ${{ needs.details.outputs.tag_name }} --generate-notes 146 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .vscode/ 3 | 4 | *.log 5 | *.zip 6 | *.pyc 7 | *.pyo 8 | *.pkl 9 | 10 | *Release/ 11 | *Debug/ 12 | *.a 13 | *.bak 14 | *.vcxproj.user 15 | *.suo 16 | .vs/ 17 | build/ 18 | 19 | *.egg-info/ 20 | dist/ 21 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/LibreHardwareMonitor"] 2 | path = submodules/LibreHardwareMonitor 3 | url = https://github.com/LibreHardwareMonitor/LibreHardwareMonitor.git 4 | [submodule "submodules/pythonstubs"] 5 | path = submodules/pythonstubs 6 | url = https://github.com/mcneel/pythonstubs.git 7 | -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | # PyHardwareMonitor Build Instructions 2 | 3 | The module is for the most part generated using scripts in the `script` subfolder. 4 | 5 | ## Build Dependencies/Tools 6 | 7 | ### LibreHardwareMonitorLib 8 | Load the [submodules/LibreHardwareMonitor/LibreHardwareMonitor.sln](VisualStudio project) file located at `submodules/LibreHardwareMonitor`. 9 | Build the `LibreHardwareMonitorLib` solution for `Release` configuration and `Any CPU` target. 10 | 11 | ### PyStubbler 12 | Load the [submodules/pythonstubs/builder/PyStubblerNET.sln](VisualStudio project) file located at `submodules/pythonstubs/builder`. 13 | Build the `PyStubblerNET` solution for `Release` configuration and `Any CPU` target. 14 | 15 | 16 | ## Generate Package files 17 | 18 | All the module generator steps can be run in one command 19 | 20 | ```sh 21 | py scripts/generate_all.py 22 | ``` 23 | > Note: It is assumed that python is installed on Windows with the pylauncher option set. 24 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/CPU/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware.Cpu' 2 | 3 | from LibreHardwareMonitor.Hardware.Cpu import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/CPU/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor.Hardware import GroupAffinity, Hardware, ISettings 2 | from HardwareMonitor._util.types import UInt32 3 | from typing import List, Set 4 | 5 | 6 | class CpuId: 7 | @property 8 | def Affinity(self) -> GroupAffinity: ... 9 | @property 10 | def ApicId(self) -> UInt32: ... 11 | @property 12 | def BrandString(self) -> str: ... 13 | @property 14 | def CoreId(self) -> UInt32: ... 15 | @property 16 | def Data(self) -> List[UInt32]: ... 17 | @property 18 | def ExtData(self) -> List[UInt32]: ... 19 | @property 20 | def Family(self) -> UInt32: ... 21 | @property 22 | def Group(self) -> int: ... 23 | @property 24 | def Model(self) -> UInt32: ... 25 | @property 26 | def Name(self) -> str: ... 27 | @property 28 | def PkgType(self) -> UInt32: ... 29 | @property 30 | def ProcessorId(self) -> UInt32: ... 31 | def Get(group: int, thread: int) -> CpuId: ... 32 | @property 33 | def Stepping(self) -> UInt32: ... 34 | @property 35 | def Thread(self) -> int: ... 36 | @property 37 | def ThreadId(self) -> UInt32: ... 38 | @property 39 | def Vendor(self) -> Vendor: ... 40 | 41 | 42 | class GenericCpu(Hardware): 43 | def __init__(self, processorIndex: int, cpuId: Set[Set[CpuId]], settings: ISettings): ... 44 | @property 45 | def CpuId(self) -> Set[Set[CpuId]]: ... 46 | @property 47 | def HardwareType(self) -> HardwareType: ... 48 | @property 49 | def HasModelSpecificRegisters(self) -> bool: ... 50 | @property 51 | def HasTimeStampCounter(self) -> bool: ... 52 | @property 53 | def Index(self) -> int: ... 54 | @property 55 | def TimeStampCounterFrequency(self) -> float: ... 56 | def GetReport(self) -> str: ... 57 | def Update(self) -> None: ... 58 | 59 | 60 | class Vendor: 61 | Unknown = 0 62 | Intel = 1 63 | AMD = 2 64 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Controller/AeroCool/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware.Controller.AeroCool' 2 | 3 | from LibreHardwareMonitor.Hardware.Controller.AeroCool import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Controller/AeroCool/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor.Hardware import ISettings 2 | from HardwareMonitor._util.types import IReadOnlyList 3 | 4 | 5 | class AeroCoolGroup: 6 | def __init__(self, settings: ISettings): ... 7 | def Close(self) -> None: ... 8 | @property 9 | def Hardware(self) -> IReadOnlyList: ... 10 | def GetReport(self) -> str: ... 11 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Controller/AquaComputer/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware.Controller.AquaComputer' 2 | 3 | from LibreHardwareMonitor.Hardware.Controller.AquaComputer import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Controller/AquaComputer/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor.Hardware import ISettings 2 | from HardwareMonitor._util.types import IReadOnlyList 3 | 4 | 5 | class AquaComputerGroup: 6 | def __init__(self, settings: ISettings): ... 7 | def Close(self) -> None: ... 8 | @property 9 | def Hardware(self) -> IReadOnlyList: ... 10 | def GetReport(self) -> str: ... 11 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Controller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snip3rnick/PyHardwareMonitor/5a566ca707cbf373983e15baba32f6b18782e629/HardwareMonitor/Hardware/Controller/__init__.py -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Gpu/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware.Gpu' 2 | 3 | from LibreHardwareMonitor.Hardware.Gpu import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Gpu/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor.Hardware import Hardware 2 | 3 | 4 | class GenericGpu(Hardware): 5 | @property 6 | def DeviceId(self) -> str: ... 7 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Motherboard/Lpc/EC/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware.Motherboard.Lpc.EC' 2 | 3 | from LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Motherboard/Lpc/EC/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor.Hardware import Hardware, ISettings, SensorType 2 | from HardwareMonitor._util.types import AsyncCallback, Byte, IAsyncResult, IntPtr, Object, Single, UInt16 3 | from typing import Iterable, Set 4 | 5 | 6 | class BadConfigurationException: 7 | def __init__(self, message: str): ... 8 | 9 | 10 | class BusMutexLockingFailedException: 11 | def __init__(self): ... 12 | 13 | 14 | class EmbeddedController(Hardware): 15 | @property 16 | def HardwareType(self) -> HardwareType: ... 17 | def GetReport(self) -> str: ... 18 | def Update(self) -> None: ... 19 | 20 | 21 | class EmbeddedControllerReader: 22 | def __init__(self, object: Object, method: IntPtr): ... 23 | def BeginInvoke(self, ecIO: IEmbeddedControllerIO, register: UInt16, callback: AsyncCallback, object: Object) -> IAsyncResult: ... 24 | def EndInvoke(self, result: IAsyncResult) -> Single: ... 25 | def Invoke(self, ecIO: IEmbeddedControllerIO, register: UInt16) -> Single: ... 26 | 27 | 28 | class EmbeddedControllerSource: 29 | def __init__(self, name: str, type: SensorType, register: UInt16, size: Byte, factor: Single, blank: int): ... 30 | @property 31 | def Blank(self) -> int: ... 32 | @property 33 | def Factor(self) -> Single: ... 34 | @property 35 | def Name(self) -> str: ... 36 | @property 37 | def Reader(self) -> EmbeddedControllerReader: ... 38 | @property 39 | def Register(self) -> UInt16: ... 40 | @property 41 | def Size(self) -> Byte: ... 42 | @property 43 | def Type(self) -> SensorType: ... 44 | 45 | 46 | class IEmbeddedControllerIO: 47 | def Read(self, registers: Set[UInt16], data: Set[Byte]) -> None: ... 48 | 49 | 50 | class IOException: 51 | def __init__(self, message: str): ... 52 | 53 | 54 | class MultipleBoardRecordsFoundException: 55 | def __init__(self, model: str): ... 56 | 57 | 58 | class WindowsEmbeddedController(EmbeddedController): 59 | def __init__(self, sources: Iterable[EmbeddedControllerSource], settings: ISettings): ... 60 | 61 | 62 | class WindowsEmbeddedControllerIO: 63 | def __init__(self): ... 64 | def Dispose(self) -> None: ... 65 | def Read(self, registers: Set[UInt16], data: Set[Byte]) -> None: ... 66 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Motherboard/Lpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snip3rnick/PyHardwareMonitor/5a566ca707cbf373983e15baba32f6b18782e629/HardwareMonitor/Hardware/Motherboard/Lpc/__init__.py -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Motherboard/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware.Motherboard' 2 | 3 | from LibreHardwareMonitor.Hardware.Motherboard import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Motherboard/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor.Hardware import IHardware, ISensor, ISettings, IVisitor, SensorEventHandler 2 | from HardwareMonitor._util.types import IDictionary 3 | from typing import Set 4 | 5 | 6 | class Manufacturer: 7 | Abit = 0 8 | Acer = 1 9 | Alienware = 2 10 | AMD = 3 11 | AOpen = 4 12 | Apple = 5 13 | ASRock = 6 14 | ASUS = 7 15 | Biostar = 8 16 | Clevo = 9 17 | Dell = 10 18 | DFI = 11 19 | ECS = 12 20 | EPoX = 13 21 | EVGA = 14 22 | FIC = 15 23 | Foxconn = 16 24 | Fujitsu = 17 25 | Gateway = 18 26 | Gigabyte = 19 27 | HP = 20 28 | IBM = 21 29 | Intel = 22 30 | Jetway = 23 31 | LattePanda = 24 32 | Lenovo = 25 33 | Medion = 26 34 | Microsoft = 27 35 | MSI = 28 36 | NEC = 29 37 | Pegatron = 30 38 | Samsung = 31 39 | Sapphire = 32 40 | Shuttle = 33 41 | Sony = 34 42 | Supermicro = 35 43 | Toshiba = 36 44 | XFX = 37 45 | Zotac = 38 46 | Unknown = 39 47 | 48 | 49 | class Model: 50 | _880GMH_USB3 = 0 51 | A320M_HDV = 1 52 | AB350_Pro4 = 2 53 | AB350M = 3 54 | AB350M_HDV = 4 55 | AB350M_Pro4 = 5 56 | AOD790GX_128M = 6 57 | B450_Pro4 = 7 58 | B450_Steel_Legend = 8 59 | B450M_Pro4 = 9 60 | B450M_Steel_Legend = 10 61 | B85M_DGS = 11 62 | Fatal1ty_AB350_Gaming_K4 = 12 63 | P55_Deluxe = 13 64 | X399_Phantom_Gaming_6 = 14 65 | Z77Pro4M = 15 66 | X570_Pro4 = 16 67 | X570_Taichi = 17 68 | X570_Phantom_Gaming_ITX = 18 69 | Z790_Taichi = 19 70 | CROSSHAIR_III_FORMULA = 20 71 | ROG_CROSSHAIR_VIII_HERO = 21 72 | ROG_CROSSHAIR_VIII_HERO_WIFI = 22 73 | ROG_CROSSHAIR_VIII_DARK_HERO = 23 74 | ROG_CROSSHAIR_VIII_FORMULA = 24 75 | ROG_CROSSHAIR_VIII_IMPACT = 25 76 | ROG_STRIX_X470_I = 26 77 | ROG_CROSSHAIR_X670E_EXTREME = 27 78 | ROG_CROSSHAIR_X670E_HERO = 28 79 | ROG_CROSSHAIR_X670E_GENE = 29 80 | ROG_STRIX_X670E_F_GAMING_WIFI = 30 81 | ROG_STRIX_X570_E_GAMING = 31 82 | ROG_STRIX_X570_F_GAMING = 32 83 | ROG_STRIX_X570_I_GAMING = 33 84 | ROG_STRIX_B550_E_GAMING = 34 85 | ROG_STRIX_B550_F_GAMING_WIFI = 35 86 | ROG_STRIX_B550_I_GAMING = 36 87 | ROG_STRIX_Z390_E_GAMING = 37 88 | ROG_STRIX_Z390_F_GAMING = 38 89 | ROG_STRIX_Z390_I_GAMING = 39 90 | ROG_STRIX_Z690_A_GAMING_WIFI_D4 = 40 91 | ROG_MAXIMUS_XI_FORMULA = 41 92 | ROG_MAXIMUS_X_HERO_WIFI_AC = 42 93 | ROG_MAXIMUS_Z690_FORMULA = 43 94 | ROG_MAXIMUS_Z690_HERO = 44 95 | ROG_MAXIMUS_Z690_EXTREME_GLACIAL = 45 96 | ROG_STRIX_Z790_I_GAMING_WIFI = 46 97 | M2N_SLI_Deluxe = 47 98 | M4A79XTD_EVO = 48 99 | P5W_DH_Deluxe = 49 100 | P6T = 50 101 | P6X58D_E = 51 102 | P8P67 = 52 103 | P8P67_EVO = 53 104 | P8P67_M_PRO = 54 105 | P8P67_PRO = 55 106 | P8Z77_V = 56 107 | P9X79 = 57 108 | PRIME_X370_PRO = 58 109 | PRIME_X470_PRO = 59 110 | PRIME_X570_PRO = 60 111 | PROART_X570_CREATOR_WIFI = 61 112 | PRO_WS_X570_ACE = 62 113 | RAMPAGE_EXTREME = 63 114 | RAMPAGE_II_GENE = 64 115 | ROG_MAXIMUS_X_APEX = 65 116 | ROG_ZENITH_EXTREME = 66 117 | ROG_ZENITH_II_EXTREME = 67 118 | TUF_X470_PLUS_GAMING = 68 119 | Z170_A = 69 120 | TUF_GAMING_B550M_PLUS_WIFI = 70 121 | ROG_MAXIMUS_Z790_HERO = 71 122 | PRIME_Z690_A = 72 123 | B660GTN = 73 124 | X670E_Valkyrie = 74 125 | LP_BI_P45_T2RS_Elite = 75 126 | LP_DK_P55_T3EH9 = 76 127 | A890GXM_A = 77 128 | B350_Gaming_Plus = 78 129 | B360M_PRO_VDH = 79 130 | B450A_PRO = 80 131 | Z270_PC_MATE = 81 132 | Z77_MS7751 = 82 133 | Z68_MS7672 = 83 134 | X570_Gaming_Plus = 84 135 | X58_SLI_Classified = 85 136 | X58_3X_SLI = 86 137 | _965P_S3 = 87 138 | _970A_UD3 = 88 139 | AB350_Gaming_3 = 89 140 | AX370_Gaming_5 = 90 141 | AX370_Gaming_K7 = 91 142 | B360_AORUS_GAMING_3_WIFI_CF = 92 143 | B550_AORUS_PRO = 93 144 | B560M_AORUS_ELITE = 94 145 | B560M_AORUS_PRO = 95 146 | B560M_AORUS_PRO_AX = 96 147 | B660M_DS3H_AX_DDR4 = 97 148 | EP45_DS3R = 98 149 | EP45_UD3R = 99 150 | EX58_EXTREME = 100 151 | EX58_UD3R = 101 152 | G41M_COMBO = 102 153 | G41MT_S2 = 103 154 | G41MT_S2P = 104 155 | H55_USB3 = 105 156 | H55N_USB3 = 106 157 | H61M_DS2_REV_1_2 = 107 158 | H61M_USB3_B3_REV_2_0 = 108 159 | H67A_UD3H_B3 = 109 160 | H67A_USB3_B3 = 110 161 | H81M_HD3 = 111 162 | B75M_D3H = 112 163 | MA770T_UD3 = 113 164 | MA770T_UD3P = 114 165 | MA785GM_US2H = 115 166 | MA785GMT_UD2H = 116 167 | MA78LM_S2H = 117 168 | MA790X_UD3P = 118 169 | P35_DS3 = 119 170 | P35_DS3L = 120 171 | P55_UD4 = 121 172 | P55A_UD3 = 122 173 | P55M_UD4 = 123 174 | P67A_UD3_B3 = 124 175 | P67A_UD3R_B3 = 125 176 | P67A_UD4_B3 = 126 177 | P8Z68_V_PRO = 127 178 | X38_DS5 = 128 179 | X399_AORUS_Gaming_7 = 129 180 | X58A_UD3R = 130 181 | X79_UD3 = 131 182 | Z390_AORUS_ULTRA = 132 183 | Z390_AORUS_PRO = 133 184 | Z390_M_GAMING = 134 185 | Z390_UD = 135 186 | Z68A_D3H_B3 = 136 187 | Z68AP_D3 = 137 188 | Z68X_UD3H_B3 = 138 189 | Z68X_UD7_B3 = 139 190 | Z68XP_UD3R = 140 191 | Z690_AORUS_PRO = 141 192 | Z690_AORUS_ULTRA = 142 193 | Z690_GAMING_X_DDR4 = 143 194 | Z170N_WIFI = 144 195 | X470_AORUS_GAMING_7_WIFI = 145 196 | X570_AORUS_MASTER = 146 197 | X570_GAMING_X = 147 198 | X570_AORUS_ULTRA = 148 199 | FH67 = 149 200 | Unknown = 150 201 | 202 | 203 | class Motherboard: 204 | def __init__(self, smBios: SMBios, settings: ISettings): ... 205 | def Accept(self, visitor: IVisitor) -> None: ... 206 | def add_SensorAdded(self, value: SensorEventHandler) -> None: ... 207 | def add_SensorRemoved(self, value: SensorEventHandler) -> None: ... 208 | def Close(self) -> None: ... 209 | @property 210 | def HardwareType(self) -> HardwareType: ... 211 | @property 212 | def Identifier(self) -> Identifier: ... 213 | @property 214 | def Manufacturer(self) -> Manufacturer: ... 215 | @property 216 | def Model(self) -> Model: ... 217 | @property 218 | def Name(self) -> str: ... 219 | @property 220 | def Parent(self) -> IHardware: ... 221 | @property 222 | def Properties(self) -> IDictionary: ... 223 | @property 224 | def Sensors(self) -> Set[ISensor]: ... 225 | @property 226 | def SMBios(self) -> SMBios: ... 227 | @property 228 | def SubHardware(self) -> Set[IHardware]: ... 229 | def GetReport(self) -> str: ... 230 | def remove_SensorAdded(self, value: SensorEventHandler) -> None: ... 231 | def remove_SensorRemoved(self, value: SensorEventHandler) -> None: ... 232 | @Name.setter 233 | def Name(self, value: str) -> None: ... 234 | def Traverse(self, visitor: IVisitor) -> None: ... 235 | def Update(self) -> None: ... 236 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Psu/Corsair/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware.Psu.Corsair' 2 | 3 | from LibreHardwareMonitor.Hardware.Psu.Corsair import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Psu/Corsair/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor.Hardware import ISettings 2 | from HardwareMonitor._util.types import IReadOnlyList 3 | 4 | 5 | class CommunicationProtocolError: 6 | def __init__(self, device: HidDevice, message: str): ... 7 | 8 | 9 | class CorsairPsuGroup: 10 | def __init__(self, settings: ISettings): ... 11 | def Close(self) -> None: ... 12 | @property 13 | def Hardware(self) -> IReadOnlyList: ... 14 | def GetReport(self) -> str: ... 15 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Psu/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snip3rnick/PyHardwareMonitor/5a566ca707cbf373983e15baba32f6b18782e629/HardwareMonitor/Hardware/Psu/__init__.py -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Storage/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware.Storage' 2 | 3 | from LibreHardwareMonitor.Hardware.Storage import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/Storage/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor.Hardware import Hardware, ISettings, IVisitor, ParameterDescription 2 | from HardwareMonitor._util.types import AsyncCallback, Byte, IAsyncResult, IReadOnlyList, Int16, IntPtr, Nullable, Object, Single, UInt16, UInt32, UInt64 3 | from typing import Set, Tuple, overload 4 | 5 | 6 | class AbstractStorage(Hardware): 7 | def Close(self) -> None: ... 8 | def CreateInstance(deviceId: str, driveNumber: UInt32, diskSize: UInt64, scsiPort: int, settings: ISettings) -> AbstractStorage: ... 9 | @property 10 | def DriveInfos(self) -> Set[DriveInfo]: ... 11 | @property 12 | def FirmwareRevision(self) -> str: ... 13 | @property 14 | def HardwareType(self) -> HardwareType: ... 15 | @property 16 | def Index(self) -> int: ... 17 | def GetReport(self) -> str: ... 18 | def Traverse(self, visitor: IVisitor) -> None: ... 19 | def Update(self) -> None: ... 20 | 21 | 22 | class AtaStorage(AbstractStorage): 23 | def Close(self) -> None: ... 24 | @property 25 | def Smart(self) -> ISmart: ... 26 | @property 27 | def SmartAttributes(self) -> IReadOnlyList: ... 28 | 29 | 30 | class GenericHardDisk(AtaStorage): 31 | pass 32 | 33 | 34 | class ISmart: 35 | def Close(self) -> None: ... 36 | def EnableSmart(self) -> bool: ... 37 | @property 38 | def IsValid(self) -> bool: ... 39 | def ReadNameAndFirmwareRevision(self) -> Tuple[bool, str, str]: ... 40 | def ReadSmartData(self) -> Set[SMART_ATTRIBUTE]: ... 41 | def ReadSmartThresholds(self) -> Set[SMART_THRESHOLD]: ... 42 | 43 | 44 | class NVMeGeneric(AbstractStorage): 45 | def Close(self) -> None: ... 46 | @property 47 | def Smart(self) -> NVMeSmart: ... 48 | 49 | 50 | class NVMeHealthInfo: 51 | @property 52 | def AvailableSpare(self) -> Byte: ... 53 | @property 54 | def AvailableSpareThreshold(self) -> Byte: ... 55 | @property 56 | def ControllerBusyTime(self) -> UInt64: ... 57 | @property 58 | def CriticalCompositeTemperatureTime(self) -> UInt32: ... 59 | @property 60 | def CriticalWarning(self) -> NVME_CRITICAL_WARNING: ... 61 | @property 62 | def DataUnitRead(self) -> UInt64: ... 63 | @property 64 | def DataUnitWritten(self) -> UInt64: ... 65 | @property 66 | def ErrorInfoLogEntryCount(self) -> UInt64: ... 67 | @property 68 | def HostReadCommands(self) -> UInt64: ... 69 | @property 70 | def HostWriteCommands(self) -> UInt64: ... 71 | @property 72 | def MediaErrors(self) -> UInt64: ... 73 | @property 74 | def PercentageUsed(self) -> Byte: ... 75 | @property 76 | def PowerCycle(self) -> UInt64: ... 77 | @property 78 | def PowerOnHours(self) -> UInt64: ... 79 | @property 80 | def Temperature(self) -> Int16: ... 81 | @property 82 | def TemperatureSensors(self) -> Set[Int16]: ... 83 | @property 84 | def UnsafeShutdowns(self) -> UInt64: ... 85 | @property 86 | def WarningCompositeTemperatureTime(self) -> UInt32: ... 87 | 88 | 89 | class NVMeInfo: 90 | @property 91 | def ControllerId(self) -> UInt16: ... 92 | @property 93 | def IEEE(self) -> Set[Byte]: ... 94 | @property 95 | def Index(self) -> int: ... 96 | @property 97 | def Model(self) -> str: ... 98 | @property 99 | def NumberNamespaces(self) -> UInt32: ... 100 | @property 101 | def Revision(self) -> str: ... 102 | @property 103 | def Serial(self) -> str: ... 104 | @property 105 | def SSVID(self) -> UInt16: ... 106 | @property 107 | def TotalCapacity(self) -> UInt64: ... 108 | @property 109 | def UnallocatedCapacity(self) -> UInt64: ... 110 | @property 111 | def VID(self) -> UInt16: ... 112 | 113 | 114 | class NVMeSmart: 115 | def Close(self) -> None: ... 116 | def Dispose(self) -> None: ... 117 | @property 118 | def IsValid(self) -> bool: ... 119 | def GetHealthInfo(self) -> NVMeHealthInfo: ... 120 | def GetInfo(self) -> NVMeInfo: ... 121 | 122 | 123 | class RawValueConversion: 124 | def __init__(self, object: Object, method: IntPtr): ... 125 | def BeginInvoke(self, rawValue: Set[Byte], value: Byte, parameters: IReadOnlyList, callback: AsyncCallback, object: Object) -> IAsyncResult: ... 126 | def EndInvoke(self, result: IAsyncResult) -> Single: ... 127 | def Invoke(self, rawValue: Set[Byte], value: Byte, parameters: IReadOnlyList) -> Single: ... 128 | 129 | 130 | class SmartAttribute: 131 | @overload 132 | def __init__(self, id: Byte, name: str): ... 133 | @overload 134 | def __init__(self, id: Byte, name: str, rawValueConversion: RawValueConversion): ... 135 | @overload 136 | def __init__(self, id: Byte, name: str, rawValueConversion: RawValueConversion, sensorType: Nullable, sensorChannel: int, sensorName: str, defaultHiddenSensor: bool, parameterDescriptions: Set[ParameterDescription]): ... 137 | @property 138 | def DefaultHiddenSensor(self) -> bool: ... 139 | @property 140 | def HasRawValueConversion(self) -> bool: ... 141 | @property 142 | def Id(self) -> Byte: ... 143 | @property 144 | def Name(self) -> str: ... 145 | @property 146 | def ParameterDescriptions(self) -> Set[ParameterDescription]: ... 147 | @property 148 | def SensorChannel(self) -> int: ... 149 | @property 150 | def SensorName(self) -> str: ... 151 | @property 152 | def SensorType(self) -> Nullable: ... 153 | 154 | 155 | class SmartNames: 156 | @property 157 | def AirflowTemperature() -> str: ... 158 | @property 159 | def AlternativeEraseFailCount() -> str: ... 160 | @property 161 | def AlternativeGSenseErrorRate() -> str: ... 162 | @property 163 | def AlternativeProgramFailCount() -> str: ... 164 | @property 165 | def AvailableReservedSpace() -> str: ... 166 | @property 167 | def AverageEraseCount() -> str: ... 168 | @property 169 | def BadBlockFullFlag() -> str: ... 170 | @property 171 | def BitErrors() -> str: ... 172 | @property 173 | def CalibrationRetryCount() -> str: ... 174 | @property 175 | def CommandTimeout() -> str: ... 176 | @property 177 | def ControllerWritesToNand() -> str: ... 178 | @property 179 | def CorrectedErrors() -> str: ... 180 | @property 181 | def CrcErrorCount() -> str: ... 182 | @property 183 | def CurrentPendingSectorCount() -> str: ... 184 | @property 185 | def DataAddressMarkErrors() -> str: ... 186 | @property 187 | def DiskShift() -> str: ... 188 | @property 189 | def DriveTemperature() -> str: ... 190 | @property 191 | def EccRate() -> str: ... 192 | @property 193 | def EmergencyRetractCycleCount() -> str: ... 194 | @property 195 | def EndToEndError() -> str: ... 196 | @property 197 | def EnduranceRemaining() -> str: ... 198 | @property 199 | def EraseFailCount() -> str: ... 200 | @property 201 | def EraseFailCountChip() -> str: ... 202 | @property 203 | def EraseFailCountTotal() -> str: ... 204 | @property 205 | def EraseFailure() -> str: ... 206 | @property 207 | def ErrorCorrectionCount() -> str: ... 208 | @property 209 | def ExceptionModeStatus() -> str: ... 210 | @property 211 | def FactoryBadBlockCount() -> str: ... 212 | @property 213 | def FlyingHeight() -> str: ... 214 | @property 215 | def FreeFallProtection() -> str: ... 216 | @property 217 | def FTLProgramNANDPagesCount() -> str: ... 218 | @property 219 | def GmrHeadAmplitude() -> str: ... 220 | @property 221 | def GSenseErrorRate() -> str: ... 222 | @property 223 | def HardwareEccRecovered() -> str: ... 224 | @property 225 | def HeadFlyingHours() -> str: ... 226 | @property 227 | def HeadStability() -> str: ... 228 | @property 229 | def HighFlyWrites() -> str: ... 230 | @property 231 | def HostProgramNANDPagesCount() -> str: ... 232 | @property 233 | def HostReads() -> str: ... 234 | @property 235 | def HostWrites() -> str: ... 236 | @property 237 | def HostWritesToController() -> str: ... 238 | @property 239 | def InducedOpVibrationDetection() -> str: ... 240 | @property 241 | def InitialBadBlockCount() -> str: ... 242 | @property 243 | def LoadCycleCount() -> str: ... 244 | @property 245 | def LoadedHours() -> str: ... 246 | @property 247 | def LoadFriction() -> str: ... 248 | @property 249 | def LoadInTime() -> str: ... 250 | @property 251 | def LoadUnloadCycleCount() -> str: ... 252 | @property 253 | def LoadUnloadCycleCountFujitsu() -> str: ... 254 | @property 255 | def LoadUnloadRetryCount() -> str: ... 256 | @property 257 | def MaxCellCycles() -> str: ... 258 | @property 259 | def MaxErase() -> str: ... 260 | @property 261 | def MediaWearOutIndicator() -> str: ... 262 | @property 263 | def MinErase() -> str: ... 264 | @property 265 | def MultiZoneErrorRate() -> str: ... 266 | @property 267 | def NewFailingBlockCount() -> str: ... 268 | @property 269 | def Non4KAlignedAccess() -> str: ... 270 | @property 271 | def OfflineSeekPerformance() -> str: ... 272 | @property 273 | def OffLineUncorrectableErrorCount() -> str: ... 274 | @property 275 | def PowerCycleCount() -> str: ... 276 | @property 277 | def PowerOffRetractCycle() -> str: ... 278 | @property 279 | def PowerOnHours() -> str: ... 280 | @property 281 | def PowerRecoveryCount() -> str: ... 282 | @property 283 | def ProgramFailCount() -> str: ... 284 | @property 285 | def ProgramFailCountChip() -> str: ... 286 | @property 287 | def ProgramFailCountTotal() -> str: ... 288 | @property 289 | def ProgramFailure() -> str: ... 290 | @property 291 | def RawReadErrorRate() -> str: ... 292 | @property 293 | def ReadChannelMargin() -> str: ... 294 | @property 295 | def ReadCommands() -> str: ... 296 | @property 297 | def ReadErrorRate() -> str: ... 298 | @property 299 | def ReadErrorRetryRate() -> str: ... 300 | @property 301 | def ReadFailure() -> str: ... 302 | @property 303 | def ReallocatedNANDBlockCount() -> str: ... 304 | @property 305 | def ReallocatedSectorsCount() -> str: ... 306 | @property 307 | def ReallocationEventCount() -> str: ... 308 | @property 309 | def RecalibrationRetries() -> str: ... 310 | @property 311 | def RemainingLife() -> str: ... 312 | @property 313 | def ReportedUncorrectableErrors() -> str: ... 314 | @property 315 | def RetiredBlockCount() -> str: ... 316 | @property 317 | def RunOutCancel() -> str: ... 318 | @property 319 | def RuntimeBadBlockTotal() -> str: ... 320 | @property 321 | def SataDownshiftErrorCount() -> str: ... 322 | @property 323 | def SataErrorCountCrc() -> str: ... 324 | @property 325 | def SataErrorCountHandshake() -> str: ... 326 | @property 327 | def SectorsRead() -> str: ... 328 | @property 329 | def SectorsWritten() -> str: ... 330 | @property 331 | def SeekErrorRate() -> str: ... 332 | @property 333 | def SeekTimePerformance() -> str: ... 334 | @property 335 | def ShockDuringWrite() -> str: ... 336 | @property 337 | def SoftEccCorrection() -> str: ... 338 | @property 339 | def SoftReadErrorRate() -> str: ... 340 | @property 341 | def SpinBuzz() -> str: ... 342 | @property 343 | def SpinHighCurrent() -> str: ... 344 | @property 345 | def SpinRetryCount() -> str: ... 346 | @property 347 | def SpinUpTime() -> str: ... 348 | @property 349 | def StartStopCount() -> str: ... 350 | @property 351 | def SuccessfulRAINRecoveryCount() -> str: ... 352 | @property 353 | def SupercapStatus() -> str: ... 354 | @property 355 | def TaCounterDetected() -> str: ... 356 | @property 357 | def Temperature() -> str: ... 358 | @property 359 | def TemperatureDifferenceFrom100() -> str: ... 360 | @property 361 | def TemperatureExceedCount() -> str: ... 362 | @property 363 | def ThermalAsperityRate() -> str: ... 364 | @property 365 | def ThroughputPerformance() -> str: ... 366 | @property 367 | def TorqueAmplificationCount() -> str: ... 368 | @property 369 | def TotalLbasRead() -> str: ... 370 | @property 371 | def TotalLbasWritten() -> str: ... 372 | @property 373 | def TransferErrorRate() -> str: ... 374 | @property 375 | def UltraDmaCrcErrorCount() -> str: ... 376 | @property 377 | def UncorrectableErrorCount() -> str: ... 378 | @property 379 | def UncorrectableSectorCount() -> str: ... 380 | @property 381 | def UnexpectedPowerLossCount() -> str: ... 382 | @property 383 | def Unknown() -> str: ... 384 | @property 385 | def UnknownUnique() -> str: ... 386 | @property 387 | def UnrecoverableEcc() -> str: ... 388 | @property 389 | def UnsafeShutdownCount() -> str: ... 390 | @property 391 | def UnusedReserveNANDBlocks() -> str: ... 392 | @property 393 | def UsedReservedBlockCountChip() -> str: ... 394 | @property 395 | def UsedReservedBlockCountTotal() -> str: ... 396 | @property 397 | def VibrationDuringWrite() -> str: ... 398 | @property 399 | def WearLevelingCount() -> str: ... 400 | @property 401 | def WearRangeDelta() -> str: ... 402 | @property 403 | def WriteCommands() -> str: ... 404 | @property 405 | def WriteErrorRate() -> str: ... 406 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Hardware' 2 | 3 | from LibreHardwareMonitor.Hardware import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Hardware/__init__.pyi: -------------------------------------------------------------------------------- 1 | from HardwareMonitor._util.types import AsyncCallback, Byte, DateTime, IAsyncResult, IDictionary, IReadOnlyList, IntPtr, Nullable, Object, Single, TimeSpan, UInt16, UInt64 2 | __all__ = ['Cpu','Gpu','Motherboard','Storage'] 3 | from typing import Iterable, List, Set, overload 4 | 5 | 6 | class BaseBoardInformation(InformationBase): 7 | @property 8 | def ManufacturerName(self) -> str: ... 9 | @property 10 | def ProductName(self) -> str: ... 11 | @property 12 | def SerialNumber(self) -> str: ... 13 | @property 14 | def Version(self) -> str: ... 15 | 16 | 17 | class BiosInformation(InformationBase): 18 | @property 19 | def Date(self) -> Nullable: ... 20 | @property 21 | def Size(self) -> Nullable: ... 22 | @property 23 | def Vendor(self) -> str: ... 24 | @property 25 | def Version(self) -> str: ... 26 | 27 | 28 | class CacheAssociativity: 29 | Other = 1 30 | Unknown = 2 31 | DirectMapped = 3 32 | _2Way = 4 33 | _4Way = 5 34 | FullyAssociative = 6 35 | _8Way = 7 36 | _16Way = 8 37 | _12Way = 9 38 | _24Way = 10 39 | _32Way = 11 40 | _48Way = 12 41 | _64Way = 13 42 | _20Way = 14 43 | 44 | 45 | class CacheDesignation: 46 | Other = 0 47 | L1 = 1 48 | L2 = 2 49 | L3 = 3 50 | 51 | 52 | class CacheInformation(InformationBase): 53 | @property 54 | def Associativity(self) -> CacheAssociativity: ... 55 | @property 56 | def Designation(self) -> CacheDesignation: ... 57 | @property 58 | def Handle(self) -> UInt16: ... 59 | @property 60 | def Size(self) -> UInt16: ... 61 | 62 | 63 | class Computer: 64 | @overload 65 | def __init__(self): ... 66 | @overload 67 | def __init__(self, settings: ISettings): ... 68 | def Accept(self, visitor: IVisitor) -> None: ... 69 | def add_HardwareAdded(self, value: HardwareEventHandler) -> None: ... 70 | def add_HardwareRemoved(self, value: HardwareEventHandler) -> None: ... 71 | def Close(self) -> None: ... 72 | @property 73 | def Hardware(self) -> List[IHardware]: ... 74 | @property 75 | def IsBatteryEnabled(self) -> bool: ... 76 | @property 77 | def IsControllerEnabled(self) -> bool: ... 78 | @property 79 | def IsCpuEnabled(self) -> bool: ... 80 | @property 81 | def IsGpuEnabled(self) -> bool: ... 82 | @property 83 | def IsMemoryEnabled(self) -> bool: ... 84 | @property 85 | def IsMotherboardEnabled(self) -> bool: ... 86 | @property 87 | def IsNetworkEnabled(self) -> bool: ... 88 | @property 89 | def IsPsuEnabled(self) -> bool: ... 90 | @property 91 | def IsStorageEnabled(self) -> bool: ... 92 | @property 93 | def SMBios(self) -> SMBios: ... 94 | def GetReport(self) -> str: ... 95 | def Open(self) -> None: ... 96 | def remove_HardwareAdded(self, value: HardwareEventHandler) -> None: ... 97 | def remove_HardwareRemoved(self, value: HardwareEventHandler) -> None: ... 98 | def Reset(self) -> None: ... 99 | @IsBatteryEnabled.setter 100 | def IsBatteryEnabled(self, value: bool) -> None: ... 101 | @IsControllerEnabled.setter 102 | def IsControllerEnabled(self, value: bool) -> None: ... 103 | @IsCpuEnabled.setter 104 | def IsCpuEnabled(self, value: bool) -> None: ... 105 | @IsGpuEnabled.setter 106 | def IsGpuEnabled(self, value: bool) -> None: ... 107 | @IsMemoryEnabled.setter 108 | def IsMemoryEnabled(self, value: bool) -> None: ... 109 | @IsMotherboardEnabled.setter 110 | def IsMotherboardEnabled(self, value: bool) -> None: ... 111 | @IsNetworkEnabled.setter 112 | def IsNetworkEnabled(self, value: bool) -> None: ... 113 | @IsPsuEnabled.setter 114 | def IsPsuEnabled(self, value: bool) -> None: ... 115 | @IsStorageEnabled.setter 116 | def IsStorageEnabled(self, value: bool) -> None: ... 117 | def Traverse(self, visitor: IVisitor) -> None: ... 118 | 119 | 120 | class ControlMode: 121 | Undefined = 0 122 | Software = 1 123 | Default = 2 124 | 125 | 126 | class GroupAffinity: 127 | def __init__(self, group: UInt16, mask: UInt64): ... 128 | def Equals(self, o: Object) -> bool: ... 129 | @property 130 | def Group(self) -> UInt16: ... 131 | @property 132 | def Mask(self) -> UInt64: ... 133 | def GetHashCode(self) -> int: ... 134 | def op_Equality(a1: GroupAffinity, a2: GroupAffinity) -> bool: ... 135 | def op_Inequality(a1: GroupAffinity, a2: GroupAffinity) -> bool: ... 136 | def Single(group: UInt16, index: int) -> GroupAffinity: ... 137 | 138 | 139 | class Hardware: 140 | def Accept(self, visitor: IVisitor) -> None: ... 141 | def add_Closing(self, value: HardwareEventHandler) -> None: ... 142 | def add_SensorAdded(self, value: SensorEventHandler) -> None: ... 143 | def add_SensorRemoved(self, value: SensorEventHandler) -> None: ... 144 | def Close(self) -> None: ... 145 | @property 146 | def HardwareType(self) -> HardwareType: ... 147 | @property 148 | def Identifier(self) -> Identifier: ... 149 | @property 150 | def Name(self) -> str: ... 151 | @property 152 | def Parent(self) -> IHardware: ... 153 | @property 154 | def Properties(self) -> IDictionary: ... 155 | @property 156 | def Sensors(self) -> Set[ISensor]: ... 157 | @property 158 | def SubHardware(self) -> Set[IHardware]: ... 159 | def GetReport(self) -> str: ... 160 | def remove_Closing(self, value: HardwareEventHandler) -> None: ... 161 | def remove_SensorAdded(self, value: SensorEventHandler) -> None: ... 162 | def remove_SensorRemoved(self, value: SensorEventHandler) -> None: ... 163 | @Name.setter 164 | def Name(self, value: str) -> None: ... 165 | def Traverse(self, visitor: IVisitor) -> None: ... 166 | def Update(self) -> None: ... 167 | 168 | 169 | class HardwareEventHandler: 170 | def __init__(self, object: Object, method: IntPtr): ... 171 | def BeginInvoke(self, hardware: IHardware, callback: AsyncCallback, object: Object) -> IAsyncResult: ... 172 | def EndInvoke(self, result: IAsyncResult) -> None: ... 173 | def Invoke(self, hardware: IHardware) -> None: ... 174 | 175 | 176 | class HardwareType: 177 | Motherboard = 0 178 | SuperIO = 1 179 | Cpu = 2 180 | Memory = 3 181 | GpuNvidia = 4 182 | GpuAmd = 5 183 | GpuIntel = 6 184 | Storage = 7 185 | Network = 8 186 | Cooler = 9 187 | EmbeddedController = 10 188 | Psu = 11 189 | Battery = 12 190 | 191 | 192 | class IComputer: 193 | def add_HardwareAdded(self, value: HardwareEventHandler) -> None: ... 194 | def add_HardwareRemoved(self, value: HardwareEventHandler) -> None: ... 195 | @property 196 | def Hardware(self) -> List[IHardware]: ... 197 | @property 198 | def IsBatteryEnabled(self) -> bool: ... 199 | @property 200 | def IsControllerEnabled(self) -> bool: ... 201 | @property 202 | def IsCpuEnabled(self) -> bool: ... 203 | @property 204 | def IsGpuEnabled(self) -> bool: ... 205 | @property 206 | def IsMemoryEnabled(self) -> bool: ... 207 | @property 208 | def IsMotherboardEnabled(self) -> bool: ... 209 | @property 210 | def IsNetworkEnabled(self) -> bool: ... 211 | @property 212 | def IsPsuEnabled(self) -> bool: ... 213 | @property 214 | def IsStorageEnabled(self) -> bool: ... 215 | def GetReport(self) -> str: ... 216 | def remove_HardwareAdded(self, value: HardwareEventHandler) -> None: ... 217 | def remove_HardwareRemoved(self, value: HardwareEventHandler) -> None: ... 218 | 219 | 220 | class IControl: 221 | @property 222 | def ControlMode(self) -> ControlMode: ... 223 | @property 224 | def Identifier(self) -> Identifier: ... 225 | @property 226 | def MaxSoftwareValue(self) -> Single: ... 227 | @property 228 | def MinSoftwareValue(self) -> Single: ... 229 | @property 230 | def Sensor(self) -> ISensor: ... 231 | @property 232 | def SoftwareValue(self) -> Single: ... 233 | def SetDefault(self) -> None: ... 234 | def SetSoftware(self, value: Single) -> None: ... 235 | 236 | 237 | class ICriticalSensorLimits: 238 | @property 239 | def CriticalHighLimit(self) -> Nullable: ... 240 | @property 241 | def CriticalLowLimit(self) -> Nullable: ... 242 | 243 | 244 | class Identifier: 245 | @overload 246 | def __init__(self, identifiers: Set[str]): ... 247 | @overload 248 | def __init__(self, identifier: Identifier, extensions: Set[str]): ... 249 | def CompareTo(self, other: Identifier) -> int: ... 250 | def Equals(self, obj: Object) -> bool: ... 251 | def GetHashCode(self) -> int: ... 252 | def op_Equality(id1: Identifier, id2: Identifier) -> bool: ... 253 | def op_GreaterThan(id1: Identifier, id2: Identifier) -> bool: ... 254 | def op_Inequality(id1: Identifier, id2: Identifier) -> bool: ... 255 | def op_LessThan(id1: Identifier, id2: Identifier) -> bool: ... 256 | def ToString(self) -> str: ... 257 | 258 | 259 | class IElement: 260 | def Accept(self, visitor: IVisitor) -> None: ... 261 | def Traverse(self, visitor: IVisitor) -> None: ... 262 | 263 | 264 | class IHardware: 265 | def add_SensorAdded(self, value: SensorEventHandler) -> None: ... 266 | def add_SensorRemoved(self, value: SensorEventHandler) -> None: ... 267 | @property 268 | def HardwareType(self) -> HardwareType: ... 269 | @property 270 | def Identifier(self) -> Identifier: ... 271 | @property 272 | def Name(self) -> str: ... 273 | @property 274 | def Parent(self) -> IHardware: ... 275 | @property 276 | def Properties(self) -> IDictionary: ... 277 | @property 278 | def Sensors(self) -> Set[ISensor]: ... 279 | @property 280 | def SubHardware(self) -> Set[IHardware]: ... 281 | def GetReport(self) -> str: ... 282 | def remove_SensorAdded(self, value: SensorEventHandler) -> None: ... 283 | def remove_SensorRemoved(self, value: SensorEventHandler) -> None: ... 284 | @Name.setter 285 | def Name(self, value: str) -> None: ... 286 | def Update(self) -> None: ... 287 | 288 | 289 | class InformationBase: 290 | pass 291 | 292 | 293 | class IParameter: 294 | @property 295 | def DefaultValue(self) -> Single: ... 296 | @property 297 | def Description(self) -> str: ... 298 | @property 299 | def Identifier(self) -> Identifier: ... 300 | @property 301 | def IsDefault(self) -> bool: ... 302 | @property 303 | def Name(self) -> str: ... 304 | @property 305 | def Sensor(self) -> ISensor: ... 306 | @property 307 | def Value(self) -> Single: ... 308 | @IsDefault.setter 309 | def IsDefault(self, value: bool) -> None: ... 310 | @Value.setter 311 | def Value(self, value: Single) -> None: ... 312 | 313 | 314 | class ISensor: 315 | def ClearValues(self) -> None: ... 316 | @property 317 | def Control(self) -> IControl: ... 318 | @property 319 | def Hardware(self) -> IHardware: ... 320 | @property 321 | def Identifier(self) -> Identifier: ... 322 | @property 323 | def Index(self) -> int: ... 324 | @property 325 | def IsDefaultHidden(self) -> bool: ... 326 | @property 327 | def Max(self) -> Nullable: ... 328 | @property 329 | def Min(self) -> Nullable: ... 330 | @property 331 | def Name(self) -> str: ... 332 | @property 333 | def Parameters(self) -> IReadOnlyList: ... 334 | @property 335 | def SensorType(self) -> SensorType: ... 336 | @property 337 | def Value(self) -> Nullable: ... 338 | @property 339 | def Values(self) -> Iterable[SensorValue]: ... 340 | @property 341 | def ValuesTimeWindow(self) -> TimeSpan: ... 342 | def ResetMax(self) -> None: ... 343 | def ResetMin(self) -> None: ... 344 | @Name.setter 345 | def Name(self, value: str) -> None: ... 346 | @ValuesTimeWindow.setter 347 | def ValuesTimeWindow(self, value: TimeSpan) -> None: ... 348 | 349 | 350 | class ISensorLimits: 351 | @property 352 | def HighLimit(self) -> Nullable: ... 353 | @property 354 | def LowLimit(self) -> Nullable: ... 355 | 356 | 357 | class ISettings: 358 | def Contains(self, name: str) -> bool: ... 359 | def GetValue(self, name: str, value: str) -> str: ... 360 | def Remove(self, name: str) -> None: ... 361 | def SetValue(self, name: str, value: str) -> None: ... 362 | 363 | 364 | class IVisitor: 365 | def VisitComputer(self, computer: IComputer) -> None: ... 366 | def VisitHardware(self, hardware: IHardware) -> None: ... 367 | def VisitParameter(self, parameter: IParameter) -> None: ... 368 | def VisitSensor(self, sensor: ISensor) -> None: ... 369 | 370 | 371 | class MemoryDevice(InformationBase): 372 | @property 373 | def BankLocator(self) -> str: ... 374 | @property 375 | def ConfiguredSpeed(self) -> UInt16: ... 376 | @property 377 | def ConfiguredVoltage(self) -> UInt16: ... 378 | @property 379 | def DeviceLocator(self) -> str: ... 380 | @property 381 | def ManufacturerName(self) -> str: ... 382 | @property 383 | def PartNumber(self) -> str: ... 384 | @property 385 | def SerialNumber(self) -> str: ... 386 | @property 387 | def Size(self) -> UInt16: ... 388 | @property 389 | def Speed(self) -> UInt16: ... 390 | @property 391 | def Type(self) -> MemoryType: ... 392 | 393 | 394 | class MemoryType: 395 | Other = 1 396 | Unknown = 2 397 | DRAM = 3 398 | EDRAM = 4 399 | VRAM = 5 400 | SRAM = 6 401 | RAM = 7 402 | ROM = 8 403 | FLASH = 9 404 | EEPROM = 10 405 | FEPROM = 11 406 | EPROM = 12 407 | CDRAM = 13 408 | _3DRAM = 14 409 | SDRAM = 15 410 | SGRAM = 16 411 | RDRAM = 17 412 | DDR = 18 413 | DDR2 = 19 414 | DDR2_FBDIMM = 20 415 | DDR3 = 24 416 | FBD2 = 25 417 | DDR4 = 26 418 | LPDDR = 27 419 | LPDDR2 = 28 420 | LPDDR3 = 29 421 | LPDDR4 = 30 422 | LogicalNonVolatileDevice = 31 423 | HBM = 32 424 | HBM2 = 33 425 | DDR5 = 34 426 | LPDDR5 = 35 427 | 428 | 429 | class ParameterDescription: 430 | def __init__(self, name: str, description: str, defaultValue: Single): ... 431 | @property 432 | def DefaultValue(self) -> Single: ... 433 | @property 434 | def Description(self) -> str: ... 435 | @property 436 | def Name(self) -> str: ... 437 | 438 | 439 | class ProcessorCharacteristics: 440 | #None = 0 441 | _64BitCapable = 1 442 | MultiCore = 2 443 | HardwareThread = 4 444 | ExecuteProtection = 8 445 | EnhancedVirtualization = 16 446 | PowerPerformanceControl = 32 447 | _128BitCapable = 64 448 | 449 | 450 | class ProcessorFamily: 451 | Other = 1 452 | Intel8086 = 3 453 | Intel80286 = 4 454 | Intel386 = 5 455 | Intel486 = 6 456 | Intel8087 = 7 457 | Intel80287 = 8 458 | Intel80387 = 9 459 | Intel80487 = 10 460 | IntelPentium = 11 461 | IntelPentiumPro = 12 462 | IntelPentiumII = 13 463 | IntelPentiumMMX = 14 464 | IntelCeleron = 15 465 | IntelPentiumIIXeon = 16 466 | IntelPentiumIII = 17 467 | M1 = 18 468 | M2 = 19 469 | IntelCeleronM = 20 470 | IntelPentium4HT = 21 471 | AmdDuron = 24 472 | AmdK5 = 25 473 | AmdK6 = 26 474 | AmdK62 = 27 475 | AmdK63 = 28 476 | AmdAthlon = 29 477 | Amd2900 = 30 478 | AmdK62Plus = 31 479 | PowerPc = 32 480 | PowerPc601 = 33 481 | PowerPc603 = 34 482 | PowerPc603Plus = 35 483 | PowerPc604 = 36 484 | PowerPc620 = 37 485 | PowerPcx704 = 38 486 | PowerPc750 = 39 487 | IntelCoreDuo = 40 488 | IntelCoreDuoMobile = 41 489 | IntelCoreSoloMobile = 42 490 | IntelAtom = 43 491 | IntelCoreM = 44 492 | IntelCoreM3 = 45 493 | IntelCoreM5 = 46 494 | IntelCoreM7 = 47 495 | Alpha = 48 496 | Alpha21064 = 49 497 | Alpha21066 = 50 498 | Alpha21164 = 51 499 | Alpha21164Pc = 52 500 | Alpha21164a = 53 501 | Alpha21264 = 54 502 | Alpha21364 = 55 503 | AmdTurionIIUltraDualCoreMobileM = 56 504 | AmdTurionDualCoreMobileM = 57 505 | AmdAthlonIIDualCoreM = 58 506 | AmdOpteron6100Series = 59 507 | AmdOpteron4100Series = 60 508 | AmdOpteron6200Series = 61 509 | AmdOpteron4200Series = 62 510 | AmdFxSeries = 63 511 | Mips = 64 512 | MipsR4000 = 65 513 | MipsR4200 = 66 514 | MipsR4400 = 67 515 | MipsR4600 = 68 516 | MipsR10000 = 69 517 | AmdCSeries = 70 518 | AmdESeries = 71 519 | AmdASeries = 72 520 | AmdGSeries = 73 521 | AmdZSeries = 74 522 | AmdRSeries = 75 523 | AmdOpteron4300Series = 76 524 | AmdOpteron6300Series = 77 525 | AmdOpteron3300Series = 78 526 | AmdFireProSeries = 79 527 | Sparc = 80 528 | SuperSparc = 81 529 | MicroSparcII = 82 530 | MicroSparcIIep = 83 531 | UltraSparc = 84 532 | UltraSparcII = 85 533 | UltraSparcIIi = 86 534 | UltraSparcIII = 87 535 | UltraSparcIIIi = 88 536 | Motorola68040 = 96 537 | Motorola68xxx = 97 538 | Motorola68000 = 98 539 | Motorola68010 = 99 540 | Motorola68020 = 100 541 | Motorola68030 = 101 542 | AmdAthlonX4QuadCore = 102 543 | AmdOpteronX1000Series = 103 544 | AmdOpteronX2000Series = 104 545 | AmdOpteronASeries = 105 546 | AmdOpteronX3000Series = 106 547 | AmdZen = 107 548 | Hobbit = 112 549 | CrusoeTm5000 = 120 550 | CrusoeTm3000 = 121 551 | EfficeonTm8000 = 122 552 | Weitek = 128 553 | IntelItanium = 130 554 | AmdAthlon64 = 131 555 | AmdOpteron = 132 556 | AmdSempron = 133 557 | AmdTurio64Mobile = 134 558 | AmdOpteronDualCore = 135 559 | AmdAthlon64X2DualCore = 136 560 | AmdTurion64X2Mobile = 137 561 | AmdOpteronQuadCore = 138 562 | AmdOpteronThirdGen = 139 563 | AmdPhenomFXQuadCore = 140 564 | AmdPhenomX4QuadCore = 141 565 | AmdPhenomX2DualCore = 142 566 | AmdAthlonX2DualCore = 143 567 | PaRisc = 144 568 | PaRisc8500 = 145 569 | PaRisc8000 = 146 570 | PaRisc7300LC = 147 571 | PaRisc7200 = 148 572 | PaRisc7100LC = 149 573 | PaRisc7100 = 150 574 | V30 = 160 575 | IntelXeon3200QuadCoreSeries = 161 576 | IntelXeon3000DualCoreSeries = 162 577 | IntelXeon5300QuadCoreSeries = 163 578 | IntelXeon5100DualCoreSeries = 164 579 | IntelXeon5000DualCoreSeries = 165 580 | IntelXeonLVDualCore = 166 581 | IntelXeonULVDualCore = 167 582 | IntelXeon7100Series = 168 583 | IntelXeon5400Series = 169 584 | IntelXeonQuadCore = 170 585 | IntelXeon5200DualCoreSeries = 171 586 | IntelXeon7200DualCoreSeries = 172 587 | IntelXeon7300QuadCoreSeries = 173 588 | IntelXeon7400QuadCoreSeries = 174 589 | IntelXeon7400MultiCoreSeries = 175 590 | IntelPentiumIIIXeon = 176 591 | IntelPentiumIIISpeedStep = 177 592 | IntelPentium4 = 178 593 | IntelXeon = 179 594 | As400 = 180 595 | IntelXeonMP = 181 596 | AmdAthlonXP = 182 597 | AmdAthlonMP = 183 598 | IntelItanium2 = 184 599 | IntelPentiumM = 185 600 | IntelCeleronD = 186 601 | IntelPentiumD = 187 602 | IntelPentiumExtreme = 188 603 | IntelCoreSolo = 189 604 | IntelCore2Duo = 191 605 | IntelCore2Solo = 192 606 | IntelCore2Extreme = 193 607 | IntelCore2Quad = 194 608 | IntelCore2ExtremeMobile = 195 609 | IntelCore2DuoMobile = 196 610 | IntelCore2SoloMobile = 197 611 | IntelCoreI7 = 198 612 | IntelCeleronDualCore = 199 613 | Ibm390 = 200 614 | PowerPcG4 = 201 615 | PowerPcG5 = 202 616 | Esa390G6 = 203 617 | ZArchitecture = 204 618 | IntelCoreI5 = 205 619 | IntelCoreI3 = 206 620 | IntelCoreI9 = 207 621 | ViaC7M = 210 622 | ViaC7D = 211 623 | ViaC7 = 212 624 | ViaEden = 213 625 | IntelXeonMultiCore = 214 626 | IntelXeon3xxxDualCoreSeries = 215 627 | IntelXeon3xxxQuadCoreSeries = 216 628 | ViaNano = 217 629 | IntelXeon5xxxDualCoreSeries = 218 630 | IntelXeon5xxxQuadCoreSeries = 219 631 | IntelXeon7xxxDualCoreSeries = 221 632 | IntelXeon7xxxQuadCoreSeries = 222 633 | IntelXeon7xxxMultiCoreSeries = 223 634 | IntelXeon3400MultiCoreSeries = 224 635 | AmdOpteron3000Series = 228 636 | AmdSempronII = 229 637 | AmdOpteronQuadCoreEmbedded = 230 638 | AmdPhenomTripleCore = 231 639 | AmdTurionUltraDualCoreMobile = 232 640 | AmdTurionDualCoreMobile = 233 641 | AmdTurionDualCore = 234 642 | AmdAthlonDualCore = 235 643 | AmdSempronSI = 236 644 | AmdPhenomII = 237 645 | AmdAthlonII = 238 646 | AmdOpteronSixCore = 239 647 | AmdSempronM = 240 648 | IntelI860 = 250 649 | IntelI960 = 251 650 | ArmV7 = 256 651 | ArmV8 = 257 652 | HitachiSh3 = 258 653 | HitachiSh4 = 259 654 | Arm = 260 655 | StrongArm = 261 656 | _686 = 262 657 | MediaGX = 263 658 | MII = 264 659 | WinChip = 265 660 | Dsp = 266 661 | VideoProcessor = 267 662 | 663 | 664 | class ProcessorInformation(InformationBase): 665 | @property 666 | def Characteristics(self) -> ProcessorCharacteristics: ... 667 | @property 668 | def CoreCount(self) -> UInt16: ... 669 | @property 670 | def CoreEnabled(self) -> UInt16: ... 671 | @property 672 | def CurrentSpeed(self) -> UInt16: ... 673 | @property 674 | def ExternalClock(self) -> UInt16: ... 675 | @property 676 | def Family(self) -> ProcessorFamily: ... 677 | @property 678 | def Handle(self) -> UInt16: ... 679 | @property 680 | def Id(self) -> UInt64: ... 681 | @property 682 | def L1CacheHandle(self) -> UInt16: ... 683 | @property 684 | def L2CacheHandle(self) -> UInt16: ... 685 | @property 686 | def L3CacheHandle(self) -> UInt16: ... 687 | @property 688 | def ManufacturerName(self) -> str: ... 689 | @property 690 | def MaxSpeed(self) -> UInt16: ... 691 | @property 692 | def ProcessorType(self) -> ProcessorType: ... 693 | @property 694 | def Serial(self) -> str: ... 695 | @property 696 | def Socket(self) -> ProcessorSocket: ... 697 | @property 698 | def SocketDesignation(self) -> str: ... 699 | @property 700 | def ThreadCount(self) -> UInt16: ... 701 | @property 702 | def Version(self) -> str: ... 703 | 704 | 705 | class ProcessorSocket: 706 | Other = 1 707 | Unknown = 2 708 | DaughterBoard = 3 709 | ZifSocket = 4 710 | PiggyBack = 5 711 | #None = 6 712 | LifSocket = 7 713 | Zif423 = 13 714 | A = 14 715 | Zif478 = 15 716 | Zif754 = 16 717 | Zif940 = 17 718 | Zif939 = 18 719 | MPga604 = 19 720 | Lga771 = 20 721 | Lga775 = 21 722 | S1 = 22 723 | AM2 = 23 724 | F = 24 725 | Lga1366 = 25 726 | G34 = 26 727 | AM3 = 27 728 | C32 = 28 729 | Lga1156 = 29 730 | Lga1567 = 30 731 | Pga988A = 31 732 | Bga1288 = 32 733 | RPga088B = 33 734 | Bga1023 = 34 735 | Bga1224 = 35 736 | Lga1155 = 36 737 | Lga1356 = 37 738 | Lga2011 = 38 739 | FS1 = 39 740 | FS2 = 40 741 | FM1 = 41 742 | FM2 = 42 743 | Lga20113 = 43 744 | Lga13563 = 44 745 | Lga1150 = 45 746 | Bga1168 = 46 747 | Bga1234 = 47 748 | Bga1364 = 48 749 | AM4 = 49 750 | Lga1151 = 50 751 | Bga1356 = 51 752 | Bga1440 = 52 753 | Bga1515 = 53 754 | Lga36471 = 54 755 | SP3 = 55 756 | SP3R2 = 56 757 | Lga2066 = 57 758 | Bga1510 = 58 759 | Bga1528 = 59 760 | Lga4189 = 60 761 | 762 | 763 | class ProcessorType: 764 | Other = 1 765 | Unknown = 2 766 | CentralProcessor = 3 767 | MathProcessor = 4 768 | DspProcessor = 5 769 | VideoProcessor = 6 770 | 771 | 772 | class SensorEventHandler: 773 | def __init__(self, object: Object, method: IntPtr): ... 774 | def BeginInvoke(self, sensor: ISensor, callback: AsyncCallback, object: Object) -> IAsyncResult: ... 775 | def EndInvoke(self, result: IAsyncResult) -> None: ... 776 | def Invoke(self, sensor: ISensor) -> None: ... 777 | 778 | 779 | class SensorType: 780 | Voltage = 0 781 | Current = 1 782 | Power = 2 783 | Clock = 3 784 | Temperature = 4 785 | Load = 5 786 | Frequency = 6 787 | Fan = 7 788 | Flow = 8 789 | Control = 9 790 | Level = 10 791 | Factor = 11 792 | Data = 12 793 | SmallData = 13 794 | Throughput = 14 795 | TimeSpan = 15 796 | Energy = 16 797 | Noise = 17 798 | 799 | 800 | class SensorValue: 801 | def __init__(self, value: Single, time: DateTime): ... 802 | @property 803 | def Time(self) -> DateTime: ... 804 | @property 805 | def Value(self) -> Single: ... 806 | 807 | 808 | class SensorVisitor: 809 | def __init__(self, handler: SensorEventHandler): ... 810 | def VisitComputer(self, computer: IComputer) -> None: ... 811 | def VisitHardware(self, hardware: IHardware) -> None: ... 812 | def VisitParameter(self, parameter: IParameter) -> None: ... 813 | def VisitSensor(self, sensor: ISensor) -> None: ... 814 | 815 | 816 | class SMBios: 817 | def __init__(self): ... 818 | @property 819 | def Bios(self) -> BiosInformation: ... 820 | @property 821 | def Board(self) -> BaseBoardInformation: ... 822 | @property 823 | def MemoryDevices(self) -> Set[MemoryDevice]: ... 824 | @property 825 | def ProcessorCaches(self) -> Set[CacheInformation]: ... 826 | @property 827 | def Processors(self) -> Set[ProcessorInformation]: ... 828 | @property 829 | def System(self) -> SystemInformation: ... 830 | @property 831 | def SystemEnclosure(self) -> SystemEnclosure: ... 832 | def GetReport(self) -> str: ... 833 | 834 | 835 | class SystemEnclosure(InformationBase): 836 | @property 837 | def AssetTag(self) -> str: ... 838 | @property 839 | def BootUpState(self) -> SystemEnclosureState: ... 840 | @property 841 | def LockDetected(self) -> bool: ... 842 | @property 843 | def ManufacturerName(self) -> str: ... 844 | @property 845 | def PowerCords(self) -> Byte: ... 846 | @property 847 | def PowerSupplyState(self) -> SystemEnclosureState: ... 848 | @property 849 | def RackHeight(self) -> Byte: ... 850 | @property 851 | def SecurityStatus(self) -> SystemEnclosureSecurityStatus: ... 852 | @property 853 | def SerialNumber(self) -> str: ... 854 | @property 855 | def SKU(self) -> str: ... 856 | @property 857 | def ThermalState(self) -> SystemEnclosureState: ... 858 | @property 859 | def Type(self) -> SystemEnclosureType: ... 860 | @property 861 | def Version(self) -> str: ... 862 | @LockDetected.setter 863 | def LockDetected(self, value: bool) -> None: ... 864 | @SecurityStatus.setter 865 | def SecurityStatus(self, value: SystemEnclosureSecurityStatus) -> None: ... 866 | 867 | 868 | class SystemEnclosureSecurityStatus: 869 | Other = 1 870 | Unknown = 2 871 | #None = 3 872 | ExternalInterfaceLockedOut = 4 873 | ExternalInterfaceEnabled = 5 874 | 875 | 876 | class SystemEnclosureState: 877 | Other = 1 878 | Unknown = 2 879 | Safe = 3 880 | Warning = 4 881 | Critical = 5 882 | NonRecoverable = 6 883 | 884 | 885 | class SystemEnclosureType: 886 | Other = 1 887 | Unknown = 2 888 | Desktop = 3 889 | LowProfileDesktop = 4 890 | PizzaBox = 5 891 | MiniTower = 6 892 | Tower = 7 893 | Portable = 8 894 | Laptop = 9 895 | Notebook = 10 896 | HandHeld = 11 897 | DockingStation = 12 898 | AllInOne = 13 899 | SubNotebook = 14 900 | SpaceSaving = 15 901 | LunchBox = 16 902 | MainServerChassis = 17 903 | ExpansionChassis = 18 904 | SubChassis = 19 905 | BusExpansionChassis = 20 906 | PeripheralChassis = 21 907 | RaidChassis = 22 908 | RackMountChassis = 23 909 | SealedCasePc = 24 910 | MultiSystemChassis = 25 911 | CompactPci = 26 912 | AdvancedTca = 27 913 | Blade = 28 914 | BladeEnclosure = 29 915 | Tablet = 30 916 | Convertible = 31 917 | Detachable = 32 918 | IoTGateway = 33 919 | EmbeddedPc = 34 920 | MiniPc = 35 921 | StickPc = 36 922 | 923 | 924 | class SystemInformation(InformationBase): 925 | @property 926 | def Family(self) -> str: ... 927 | @property 928 | def ManufacturerName(self) -> str: ... 929 | @property 930 | def ProductName(self) -> str: ... 931 | @property 932 | def SerialNumber(self) -> str: ... 933 | @property 934 | def Version(self) -> str: ... 935 | @property 936 | def WakeUp(self) -> SystemWakeUp: ... 937 | 938 | 939 | class SystemWakeUp: 940 | Reserved = 0 941 | Other = 1 942 | Unknown = 2 943 | ApmTimer = 3 944 | ModemRing = 4 945 | LanRemote = 5 946 | PowerSwitch = 6 947 | PciPme = 7 948 | AcPowerRestored = 8 949 | -------------------------------------------------------------------------------- /HardwareMonitor/Interop/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Interop' 2 | 3 | from LibreHardwareMonitor.Interop import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Interop/__init__.pyi: -------------------------------------------------------------------------------- 1 | 2 | 3 | class DISK_PERFORMANCE: 4 | pass 5 | 6 | 7 | class GROUP_AFFINITY: 8 | pass 9 | 10 | 11 | class Kernel32: 12 | def __init__(self): ... 13 | 14 | 15 | class NVME_CRITICAL_WARNING: 16 | #None = 0 17 | AvailableSpaceLow = 1 18 | TemperatureThreshold = 2 19 | ReliabilityDegraded = 4 20 | ReadOnly = 8 21 | VolatileMemoryBackupDeviceFailed = 16 22 | 23 | 24 | class SMART_ATTRIBUTE: 25 | pass 26 | 27 | 28 | class SMART_THRESHOLD: 29 | pass 30 | -------------------------------------------------------------------------------- /HardwareMonitor/Software/__init__.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.Software' 2 | 3 | from LibreHardwareMonitor.Software import * 4 | -------------------------------------------------------------------------------- /HardwareMonitor/Software/__init__.pyi: -------------------------------------------------------------------------------- 1 | 2 | 3 | class OperatingSystem: 4 | @property 5 | def Is64Bit() -> bool: ... 6 | @property 7 | def IsUnix() -> bool: ... 8 | @property 9 | def IsWindows8OrGreater() -> bool: ... 10 | -------------------------------------------------------------------------------- /HardwareMonitor/Util.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | import logging 3 | from typing import Dict, Iterable, List 4 | 5 | import HardwareMonitor 6 | from HardwareMonitor.Hardware import Computer, IVisitor, IComputer, IHardware, IParameter, ISensor, HardwareType, SensorType 7 | from System.Collections.Generic import IList, IDictionary 8 | 9 | logger = logging.getLogger("PyHardwareMonitor") 10 | 11 | # ------------------------------------------------------------------------------ 12 | def _get_name_to_type(obj): 13 | def object_getattr(attr): 14 | try: return getattr(obj, attr) 15 | except: pass 16 | result = {} 17 | for (a, v) in zip(dir(obj), map(object_getattr, dir(obj))): 18 | if type(v) in (int, obj): 19 | result[v] = result[int(v)] = a 20 | return result 21 | 22 | HardwareTypeString: Dict[HardwareType|int, str] = _get_name_to_type(HardwareType) 23 | SensorTypeString: Dict[SensorType |int, str] = _get_name_to_type(SensorType) 24 | 25 | SensorTypeUnitFormatter = { 26 | SensorType.Voltage: "{:.3f} V", 27 | SensorType.Current: "{:.3f} A", 28 | SensorType.Clock: "{:.1f} MHz", 29 | SensorType.Load: "{:.1f} %", 30 | SensorType.Temperature: "{:.1f} °C", 31 | SensorType.Fan: "{:.0f} RPM", 32 | SensorType.Flow: "{:.1f} L/h", 33 | SensorType.Control: "{:.1f} %", 34 | SensorType.Level: "{:.1f} %", 35 | SensorType.Power: "{:.1f} W", 36 | SensorType.Data: "{:.1f} GB", 37 | SensorType.SmallData: "{:.1f} MB", 38 | SensorType.Factor: "{:.3f}", 39 | SensorType.Frequency: "{:.1f} Hz", 40 | SensorType.Throughput: "{:.1f} B/s", 41 | SensorType.TimeSpan: "{}", 42 | SensorType.Energy: "{:.0f} mWh", 43 | } 44 | 45 | def SensorValueToString(value: float, type: SensorType) -> str: 46 | return SensorTypeUnitFormatter.get(type, "{}").format(value or 0) 47 | 48 | 49 | def GroupSensorsByType(sensors: Iterable[ISensor]) -> List[List[ISensor]]: 50 | groups = {} 51 | for sensor in sensors: 52 | group = groups[sensor.SensorType] = groups.get(sensor.SensorType, []) 53 | group.append(sensor) 54 | return list(groups.values()) 55 | 56 | 57 | # ------------------------------------------------------------------------------ 58 | _generic_type_cache = {} 59 | 60 | 61 | def IsInstanceOfInterface(obj, interface): 62 | if not hasattr(obj, "GetType"): 63 | return False 64 | try: 65 | obj_type = obj.GetType() 66 | if obj_type in _generic_type_cache: 67 | return any(cmp == interface for cmp in _generic_type_cache[obj_type]) 68 | ifaces = list(i for i in obj.GetType().GetInterfaces() if i.IsGenericType) 69 | cache = _generic_type_cache[obj_type] = set() 70 | for iface in ifaces: 71 | cache.add(iface.GetGenericTypeDefinition()) 72 | return any(cmp == interface for cmp in cache) 73 | except: 74 | pass 75 | return False 76 | 77 | 78 | # ------------------------------------------------------------------------------ 79 | _UPDATE_WARNING_CACHE = set() 80 | def UpdateHardwareSafe(hardware: IHardware): 81 | try: 82 | hardware.Update() 83 | except: 84 | if hardware.Identifier not in _UPDATE_WARNING_CACHE: 85 | logger.warning(f"Unable to update HardwareMonitor sensors for {hardware.Identifier} ('{hardware.Name}')") 86 | _UPDATE_WARNING_CACHE.add(hardware.Identifier) 87 | 88 | 89 | # ------------------------------------------------------------------------------ 90 | class UpdateVisitor(IVisitor): 91 | __namespace__ = "HardwareMonitor.Util" 92 | def __init__(self, time_window=1.0): 93 | super().__init__() 94 | self.time_window = time_window 95 | 96 | def VisitComputer(self, computer: IComputer): 97 | computer.Traverse(self); 98 | 99 | def VisitHardware(self, hardware: IHardware): 100 | UpdateHardwareSafe(hardware) 101 | for subHardware in hardware.SubHardware: 102 | UpdateHardwareSafe(subHardware) 103 | 104 | def VisitParameter(self, parameter: IParameter): 105 | pass 106 | 107 | def VisitSensor(self, sensor: ISensor): 108 | sensor.ValuesTimeWindow = self.time_window 109 | 110 | 111 | # ------------------------------------------------------------------------------ 112 | class PyComputer(Computer): 113 | def __init__(self, time_window=1.0, **settings): 114 | super().__init__() 115 | attr_filter = lambda attr: attr.startswith("Is") and attr.endswith("Enabled") 116 | for attr in filter(attr_filter, dir(self)): 117 | key = attr[2:-7].lower() 118 | setattr(self, attr, bool(settings.get(key, settings.get("all", False)))) 119 | self._visitor = UpdateVisitor(time_window) 120 | 121 | def Update(self): 122 | self.Open() 123 | self.Accept(self._visitor) 124 | return self 125 | 126 | def __enter__(self): 127 | self.Open() 128 | self.Accept(self._visitor) 129 | return self 130 | 131 | def __exit__(self, *args): 132 | self.Close() 133 | 134 | def __del__(self): 135 | try: self.Close() 136 | except: pass 137 | 138 | 139 | # ------------------------------------------------------------------------------ 140 | def OpenComputer(**settings) -> PyComputer: 141 | computer = PyComputer(**settings) 142 | return computer.Update() 143 | 144 | 145 | # ------------------------------------------------------------------------------ 146 | def ToBuiltinTypes(obj, exclude=["Parameters", "Values"]): 147 | def process_object(obj): 148 | # Return 'primitive' python types as such 149 | if type(obj) in (str, bytes, bool, int, float): 150 | return obj 151 | elif type(obj) in (list, tuple, set): 152 | return list(map(process_object, obj)) 153 | elif type(obj) in (dict,): 154 | return dict((k, process_object(v)) for k,v in obj.items()) 155 | # Handle .NET objects 156 | if hasattr(obj, "GetType"): 157 | # Return enums as the string representation of the value 158 | if obj.GetType().IsEnum: 159 | return obj.ToString() 160 | # Prevent recursion within HardwareMonitor objects 161 | if obj in visited: 162 | return None 163 | visited.add(obj) 164 | # Convert lists and dictionaries to python objects 165 | if obj.GetType().IsArray or IsInstanceOfInterface(obj, IList): 166 | return list(map(process_object, obj)) 167 | if IsInstanceOfInterface(obj, IDictionary): 168 | return dict((k, process_object(obj.get_Item(k))) for k in list(obj)) 169 | # Handle objects from the 'HardwareMonitor.Hardware' namespace 170 | if obj.__class__.__module__.startswith(HardwareMonitor.ASSEMBLY_NAME): 171 | cls_name = obj.__class__.__name__ 172 | if cls_name[:2].isupper() and cls_name[0] == "I": 173 | cls_name = cls_name[1:] 174 | obj_dict = {} 175 | # Iterate over all "public" members of the object 176 | for attr in [a for a in dir(obj) if not a.startswith("_")]: 177 | if attr in exclude or attr.startswith("IsDefault"): 178 | continue 179 | val = getattr(obj, attr) 180 | val_reduced = process_object(val) 181 | if val_reduced is None or val_reduced == [None]: 182 | continue 183 | elif val_reduced or type(val_reduced) is not dict: 184 | obj_dict[attr] = val_reduced 185 | if not obj_dict: 186 | return None 187 | # Add the class name to allow for easy filtering 188 | result = {"Type": cls_name} 189 | result.update(obj_dict) 190 | return result 191 | return None 192 | visited = set() 193 | return process_object(obj) 194 | -------------------------------------------------------------------------------- /HardwareMonitor/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | import clr 4 | import ctypes 5 | import logging 6 | from pathlib import Path 7 | 8 | 9 | logger = logging.getLogger("PyHardwareMonitor") 10 | 11 | 12 | if not ctypes.windll.shell32.IsUserAnAdmin(): 13 | logger.warning("Admin privileges are required for 'HardwareMonitor' to work properly") 14 | 15 | ASSEMBLY_NAME = "LibreHardwareMonitor" 16 | 17 | _LIB_PATH = Path(__file__).parent.joinpath("lib").absolute() 18 | sys.path.insert(0, str(_LIB_PATH)) 19 | __reference__ = clr.AddReference(str(_LIB_PATH / (ASSEMBLY_NAME + "Lib.dll"))) 20 | 21 | __import__(ASSEMBLY_NAME) 22 | -------------------------------------------------------------------------------- /HardwareMonitor/_util/types.pyi: -------------------------------------------------------------------------------- 1 | # Generated stub file for some types from the CLR 2 | 3 | # Symbols from 'System' namespace 4 | class _AppDomain: ... 5 | class AccessViolationException: ... 6 | class Action: ... 7 | class ActivationContext: ... 8 | class Activator: ... 9 | class AggregateException: ... 10 | class AppContext: ... 11 | class AppDomain: ... 12 | class AppDomainInitializer: ... 13 | class AppDomainManager: ... 14 | class AppDomainManagerInitializationOptions: ... 15 | class AppDomainSetup: ... 16 | class AppDomainUnloadedException: ... 17 | class ApplicationException: ... 18 | class ApplicationId: ... 19 | class ApplicationIdentity: ... 20 | class ArgIterator: ... 21 | class ArgumentException: ... 22 | class ArgumentNullException: ... 23 | class ArgumentOutOfRangeException: ... 24 | class ArithmeticException: ... 25 | class Array: ... 26 | class ArraySegment: ... 27 | class ArrayTypeMismatchException: ... 28 | class AssemblyLoadEventArgs: ... 29 | class AssemblyLoadEventHandler: ... 30 | class AsyncCallback: ... 31 | class Attribute: ... 32 | class AttributeTargets: ... 33 | class AttributeUsageAttribute: ... 34 | class BadImageFormatException: ... 35 | class Base64FormattingOptions: ... 36 | class BitConverter: ... 37 | class Boolean: ... 38 | class Buffer: ... 39 | class Byte: ... 40 | class CannotUnloadAppDomainException: ... 41 | class Char: ... 42 | class CharEnumerator: ... 43 | class CLSCompliantAttribute: ... 44 | class Comparison: ... 45 | class Console: ... 46 | class ConsoleCancelEventArgs: ... 47 | class ConsoleCancelEventHandler: ... 48 | class ConsoleColor: ... 49 | class ConsoleKey: ... 50 | class ConsoleKeyInfo: ... 51 | class ConsoleModifiers: ... 52 | class ConsoleSpecialKey: ... 53 | class ContextBoundObject: ... 54 | class ContextMarshalException: ... 55 | class ContextStaticAttribute: ... 56 | class Convert: ... 57 | class Converter: ... 58 | class CrossAppDomainDelegate: ... 59 | class DataMisalignedException: ... 60 | class DateTime: ... 61 | class DateTimeKind: ... 62 | class DateTimeOffset: ... 63 | class DayOfWeek: ... 64 | class DBNull: ... 65 | class Decimal: ... 66 | class Delegate: ... 67 | class DivideByZeroException: ... 68 | class DllNotFoundException: ... 69 | class Double: ... 70 | class DuplicateWaitObjectException: ... 71 | class EntryPointNotFoundException: ... 72 | class Enum: ... 73 | class Environment: ... 74 | class EnvironmentVariableTarget: ... 75 | class EventArgs: ... 76 | class EventHandler: ... 77 | class Exception: ... 78 | class ExecutionEngineException: ... 79 | class FieldAccessException: ... 80 | class FileStyleUriParser: ... 81 | class FlagsAttribute: ... 82 | class FormatException: ... 83 | class FormattableString: ... 84 | class FtpStyleUriParser: ... 85 | class Func: ... 86 | class GC: ... 87 | class GCCollectionMode: ... 88 | class GCNotificationStatus: ... 89 | class GenericUriParser: ... 90 | class GenericUriParserOptions: ... 91 | class GopherStyleUriParser: ... 92 | class Guid: ... 93 | class HttpStyleUriParser: ... 94 | class IAppDomainSetup: ... 95 | class IAsyncResult: ... 96 | class ICloneable: ... 97 | class IComparable: ... 98 | class IConvertible: ... 99 | class ICustomFormatter: ... 100 | class IDisposable: ... 101 | class IEquatable: ... 102 | class IFormatProvider: ... 103 | class IFormattable: ... 104 | class IndexOutOfRangeException: ... 105 | class InsufficientExecutionStackException: ... 106 | class InsufficientMemoryException: ... 107 | class Int16: ... 108 | class Int32: ... 109 | class Int64: ... 110 | class IntPtr: ... 111 | class InvalidCastException: ... 112 | class InvalidOperationException: ... 113 | class InvalidProgramException: ... 114 | class InvalidTimeZoneException: ... 115 | class IObservable: ... 116 | class IObserver: ... 117 | class IProgress: ... 118 | class IServiceProvider: ... 119 | class Lazy: ... 120 | class LdapStyleUriParser: ... 121 | class LoaderOptimization: ... 122 | class LoaderOptimizationAttribute: ... 123 | class LocalDataStoreSlot: ... 124 | class MarshalByRefObject: ... 125 | class Math: ... 126 | class MemberAccessException: ... 127 | class MethodAccessException: ... 128 | class MidpointRounding: ... 129 | class MissingFieldException: ... 130 | class MissingMemberException: ... 131 | class MissingMethodException: ... 132 | class ModuleHandle: ... 133 | class MTAThreadAttribute: ... 134 | class MulticastDelegate: ... 135 | class MulticastNotSupportedException: ... 136 | class NetPipeStyleUriParser: ... 137 | class NetTcpStyleUriParser: ... 138 | class NewsStyleUriParser: ... 139 | class NonSerializedAttribute: ... 140 | class NotFiniteNumberException: ... 141 | class NotImplementedException: ... 142 | class NotSupportedException: ... 143 | class Nullable: ... 144 | class NullReferenceException: ... 145 | class Object: ... 146 | class ObjectDisposedException: ... 147 | class ObsoleteAttribute: ... 148 | class OperatingSystem: ... 149 | class OperationCanceledException: ... 150 | class OutOfMemoryException: ... 151 | class OverflowException: ... 152 | class ParamArrayAttribute: ... 153 | class PlatformID: ... 154 | class PlatformNotSupportedException: ... 155 | class Predicate: ... 156 | class Progress: ... 157 | class Random: ... 158 | class RankException: ... 159 | class ResolveEventArgs: ... 160 | class ResolveEventHandler: ... 161 | class RuntimeArgumentHandle: ... 162 | class RuntimeFieldHandle: ... 163 | class RuntimeMethodHandle: ... 164 | class RuntimeTypeHandle: ... 165 | class SByte: ... 166 | class SerializableAttribute: ... 167 | class Single: ... 168 | class StackOverflowException: ... 169 | class STAThreadAttribute: ... 170 | class String: ... 171 | class StringComparer: ... 172 | class StringComparison: ... 173 | class StringNormalizationExtensions: ... 174 | class StringSplitOptions: ... 175 | class SystemException: ... 176 | class ThreadStaticAttribute: ... 177 | class TimeoutException: ... 178 | class TimeSpan: ... 179 | class TimeZone: ... 180 | class TimeZoneInfo: ... 181 | class TimeZoneNotFoundException: ... 182 | class TupleExtensions: ... 183 | class Type: ... 184 | class TypeAccessException: ... 185 | class TypeCode: ... 186 | class TypedReference: ... 187 | class TypeInitializationException: ... 188 | class TypeLoadException: ... 189 | class TypeUnloadedException: ... 190 | class UInt16: ... 191 | class UInt32: ... 192 | class UInt64: ... 193 | class UIntPtr: ... 194 | class UnauthorizedAccessException: ... 195 | class UnhandledExceptionEventArgs: ... 196 | class UnhandledExceptionEventHandler: ... 197 | class Uri: ... 198 | class UriBuilder: ... 199 | class UriComponents: ... 200 | class UriFormat: ... 201 | class UriFormatException: ... 202 | class UriHostNameType: ... 203 | class UriIdnScope: ... 204 | class UriKind: ... 205 | class UriParser: ... 206 | class UriPartial: ... 207 | class UriTypeConverter: ... 208 | class ValueTuple: ... 209 | class ValueType: ... 210 | class Version: ... 211 | class Void: ... 212 | class WeakReference: ... 213 | 214 | # Symbols from 'System.Collections.Generic' namespace 215 | class Comparer: ... 216 | class Dictionary: ... 217 | class EqualityComparer: ... 218 | class HashSet: ... 219 | class ICollection: ... 220 | class IComparer: ... 221 | class IDictionary: ... 222 | class IEnumerable: ... 223 | class IEnumerator: ... 224 | class IEqualityComparer: ... 225 | class IList: ... 226 | class IReadOnlyCollection: ... 227 | class IReadOnlyDictionary: ... 228 | class IReadOnlyList: ... 229 | class ISet: ... 230 | class KeyNotFoundException: ... 231 | class KeyValuePair: ... 232 | class LinkedList: ... 233 | class LinkedListNode: ... 234 | class Queue: ... 235 | class SortedDictionary: ... 236 | class SortedList: ... 237 | class SortedSet: ... 238 | class Stack: ... 239 | 240 | -------------------------------------------------------------------------------- /HardwareMonitor/lib/HidSharp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snip3rnick/PyHardwareMonitor/5a566ca707cbf373983e15baba32f6b18782e629/HardwareMonitor/lib/HidSharp.dll -------------------------------------------------------------------------------- /HardwareMonitor/lib/LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /HardwareMonitor/lib/LibreHardwareMonitorLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snip3rnick/PyHardwareMonitor/5a566ca707cbf373983e15baba32f6b18782e629/HardwareMonitor/lib/LibreHardwareMonitorLib.dll -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Nicholas Feix 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyHardwareMonitor 2 | 3 | Python Harware Monitor is a thin package layer for [`LibreHardwareMonitorLib`](https://github.com/LibreHardwareMonitor/LibreHardwareMonitor) using [`pythonnet`](https://github.com/pythonnet/pythonnet). 4 | Libre Hardware Monitor, a fork of Open Hardware Monitor, is free software that can monitor the temperature sensors, fan speeds, voltages, load and clock speeds of your computer. 5 | This package is mostly auto generated using the [`pythonstubs`](https://github.com/mcneel/pythonstubs) generator tool for .NET libraries. 6 | Scripts for generating, altering and extending package resources are located in the [scripts folder](https://github.com/snip3rnick/PyHardwareMonitor/tree/main/scripts). 7 | 8 | The purpose of this layer is the ability to provide extensive typing information and additional utilities around the LibreHardwareMonitorLib. 9 | 10 | > **Note:** Python must have **admin privileges** for `HardwareMonitor` to be able to access all available sensors properly! 11 | 12 | 13 | ## Prerequisites 14 | - Python 3.6+ 15 | - pythonnet 16 | - .NET 4.7 17 | 18 | 19 | ## Installation 20 | 21 | Install from PyPi directly 22 | ``` 23 | pip3 install HardwareMonitor 24 | ``` 25 | 26 | or install locally from source 27 | 28 | ``` 29 | git clone https://github.com/snip3rnick/PyHardwareMonitor 30 | cd PyHardwareMonitor 31 | pip3 install . 32 | ``` 33 | 34 | 35 | ## Basic Usage 36 | 37 | This simple example is a python adaptation of the [**C#** example of the LibreHardwareMonitor repository](https://github.com/LibreHardwareMonitor/LibreHardwareMonitor#whats-the-easiest-way-to-start). 38 | 39 | ```python 40 | from HardwareMonitor.Hardware import * # equivalent to 'using LibreHardwareMonitor.Hardware;' 41 | 42 | class UpdateVisitor(IVisitor): 43 | __namespace__ = "TestHardwareMonitor" # must be unique among implementations of the IVisitor interface 44 | def VisitComputer(self, computer: IComputer): 45 | computer.Traverse(self); 46 | 47 | def VisitHardware(self, hardware: IHardware): 48 | hardware.Update() 49 | for subHardware in hardware.SubHardware: 50 | subHardware.Update() 51 | 52 | def VisitParameter(self, parameter: IParameter): pass 53 | 54 | def VisitSensor(self, sensor: ISensor): pass 55 | 56 | 57 | computer = Computer() # settings can not be passed as constructor argument (following below) 58 | computer.IsMotherboardEnabled = True 59 | computer.IsControllerEnabled = True 60 | computer.IsCpuEnabled = True 61 | computer.IsGpuEnabled = True 62 | computer.IsBatteryEnabled = True 63 | computer.IsMemoryEnabled = True 64 | computer.IsNetworkEnabled = True 65 | computer.IsStorageEnabled = True 66 | 67 | computer.Open() 68 | computer.Accept(UpdateVisitor()) 69 | 70 | for hardware in computer.Hardware: 71 | print(f"Hardware: {hardware.Name}") 72 | for subhardware in hardware.SubHardware: 73 | print(f"\tSubhardware: {subhardware.Name}") 74 | for sensor in subhardware.Sensors: 75 | print(f"\t\tSensor: {sensor.Name}, value: {sensor.Value}") 76 | for sensor in hardware.Sensors: 77 | print(f"\tSensor: {sensor.Name}, value: {sensor.Value}") 78 | 79 | computer.Close() 80 | ``` 81 | 82 | --- 83 | 84 | ## Utilities 85 | 86 | Utilities are located in the `HardwareMonitor.Util` module. 87 | 88 | ### Function `OpenComputer` 89 | 90 | The `OpenComputer` function provides a shorthand for creating the `HardwareMonitor.Hardware.Computer` instance including the settings and update visitor. 91 | Settings are given as keyword arguments, the following example enables just the `cpu` and `motherboard` component. 92 | 93 | ```python 94 | computer = OpenComputer(cpu=True, motherboard=True) # use 'all=True' to enable every component 95 | # Access sensors 96 | ... 97 | computer.Update() # Updates all sensors 98 | ... 99 | computer.Close() 100 | ``` 101 | 102 | ### Function `ToBuiltinTypes` 103 | 104 | Instances from the `HardwareMonitor` module can be reduced to primitive python types instead of `HardwareMonitor` object instances with the `ToBuiltinTypes` function. 105 | Objects are recursively converted to Python builtin types (`dict`, `list`, ...). 106 | This can be useful for applications that serialized the data (e.g. with json). 107 | 108 | ```python 109 | computer = OpenComputer(cpu=True) 110 | 111 | data = ToBuiltinTypes(computer.Hardware) 112 | # [{'Type': 'Hardware', 'HardwareType': 'Cpu', 'Name': 'Intel Core i5-8265U', 'Sensors': [...], 'SubHardware': [...]}] 113 | ``` 114 | 115 | ### Function `GroupSensorsByType` 116 | 117 | Sensors of an instance of `HardwareMonitor.Harware.Hardware` are held in a flat list. 118 | The helper function `GroupSensorsByType` converts the sensor list into a list of lists grouping sensors by type. 119 | 120 | ```python 121 | GroupSensorsByType(sensors: Iterable[ISensor]) -> List[List[ISensor]] 122 | ``` 123 | 124 | ### Function `SensorValueToString` 125 | 126 | The helper function `SensorValueToString` converts sensor values to strings appending with the appropriate unit. 127 | 128 | ```python 129 | SensorValueToString(value: float, type: SensorType) -> str 130 | # returns "3100.0 MHz" for value=3100.0 with type=SensorType.Clock 131 | ``` 132 | 133 | ### Dictionary `HardwareTypeString` and `SensorTypeString` 134 | 135 | These two mappings convert values for `HardwareType` (or `SensorType`) to a string. 136 | Both the integer value for the enum or the instances of the enum value (e.g. `HardwareType.Cpu`) are present as keys. 137 | 138 | > In some environments the type fields were set to integers in others to the corresponding type instance. 139 | -------------------------------------------------------------------------------- /examples/wsgi_provider.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | import json 4 | import time 5 | import socket 6 | from threading import Timer, Lock 7 | from typing import List 8 | from wsgiref import simple_server 9 | from HardwareMonitor.Util import OpenComputer, HardwareTypeString, SensorTypeString, SensorValueToString, GroupSensorsByType 10 | from HardwareMonitor.Hardware import SensorType, IComputer, IHardware, ISensor 11 | 12 | 13 | # ------------------------------------------------------------------------------ 14 | SensorTypeStringPlurals = { 15 | SensorType.Voltage: "Voltages", 16 | SensorType.Current: "Currents", 17 | SensorType.Clock: "Clocks", 18 | SensorType.Load: "Loads", 19 | SensorType.Temperature: "Temperatures", 20 | SensorType.Fan: "Fans", 21 | SensorType.Level: "Levels", 22 | SensorType.Power: "Powers", 23 | SensorType.Frequency: "Frequencies", 24 | } 25 | 26 | 27 | # ------------------------------------------------------------------------------ 28 | class NodeFormatter(): 29 | _counter = 0 30 | def getId(self): 31 | node_id = self._counter 32 | self._counter += 1 33 | return node_id 34 | 35 | def _makeNode(self, Text, Min="", Value="", Max="", ImageURL="", **kwargs): 36 | return dict(id=self.getId(), Text=Text, Min=Min, Value=Value, Max=Max, 37 | ImageURL=ImageURL, Children=[], **kwargs) 38 | 39 | def makeSensorGroupNode(self, sensors: List[ISensor]): 40 | sensor_type = sensors[0].SensorType 41 | type_str = SensorTypeString[sensor_type] 42 | def makeSensorNode(sensor: ISensor): 43 | min_str = SensorValueToString(sensor.Min, sensor_type) 44 | val_str = SensorValueToString(sensor.Value, sensor_type) 45 | max_str = SensorValueToString(sensor.Max, sensor_type) 46 | return self._makeNode(sensor.Name, Min=min_str, Value=val_str, Max=max_str, Type=type_str, 47 | SensorId=sensor.Identifier.ToString()) 48 | 49 | group_node = self._makeNode(SensorTypeStringPlurals.get(sensor_type, type_str)) 50 | group_node["Children"].extend(map(makeSensorNode, sensors)) 51 | return group_node 52 | 53 | def makeHardwareNode(self, hardware: IHardware): 54 | sensors_grouped = GroupSensorsByType(hardware.Sensors) 55 | hardware_type = HardwareTypeString[hardware.HardwareType] 56 | hardware_node = self._makeNode(hardware.Name, Type=hardware_type) 57 | hardware_node["Children"].extend(map(self.makeSensorGroupNode, sensors_grouped)) 58 | hardware_node["Children"].extend(map(self.makeHardwareNode, hardware.SubHardware)) 59 | return hardware_node 60 | 61 | def buildNodeTree(self, computer: IComputer): 62 | self._counter = 0 63 | root_node = self._makeNode("Sensor") 64 | computer_node = self._makeNode(socket.gethostname()) 65 | 66 | root_node["Children"].append(computer_node) 67 | computer_node["Children"].extend(map(self.makeHardwareNode, computer.Hardware)) 68 | return root_node 69 | 70 | 71 | 72 | # ------------------------------------------------------------------------------ 73 | class IndefiniteTimer(Timer): 74 | def start(self): 75 | self.daemon = True 76 | super().start() 77 | return self 78 | 79 | def run(self): 80 | delay = self.interval 81 | while not self.finished.wait(delay): 82 | start_time = time.perf_counter() 83 | self.function(*self.args, **self.kwargs) 84 | delay = max(0, self.interval - (time.perf_counter() - start_time)) 85 | 86 | 87 | # ------------------------------------------------------------------------------ 88 | class SensorApp(): 89 | def __init__(self, port=8085, interval=1.0): 90 | self.interval = interval 91 | self.mutex = Lock() 92 | self.computer = OpenComputer(all=True, time_window=interval) 93 | self.timer = IndefiniteTimer(interval, self.update).start() 94 | self.http = simple_server.make_server('', port, self.handler) 95 | 96 | @property 97 | def port(self): 98 | return self.http.server_port 99 | 100 | def update(self): 101 | with self.mutex: 102 | self.computer.Update() 103 | 104 | def getSensors(self): 105 | with self.mutex: 106 | return NodeFormatter().buildNodeTree(self.computer) 107 | 108 | def serve(self): 109 | self.http.serve_forever() 110 | 111 | def close(self): 112 | self.timer.cancel() 113 | self.http.shutdown() 114 | 115 | def handler(self, environ, respond): 116 | if environ['PATH_INFO'].lower() == "/data.json": 117 | json_str = json.dumps(self.getSensors(), ensure_ascii=False) 118 | respond('200 OK', [('Content-Type', 'application/json')]) 119 | return [json_str.encode("utf-8")] 120 | else: 121 | respond('404 Not Found', [('Content-Type', 'application/json')]) 122 | return [b'not found'] 123 | 124 | 125 | # ------------------------------------------------------------------------------ 126 | def main(): 127 | print(f"Loading devices and sensors...") 128 | app = SensorApp() 129 | print(f"Serving on 'http://localhost:{app.port}/data.json', press 'ctrl + C' to stop") 130 | try: 131 | app.serve() 132 | except KeyboardInterrupt: 133 | app.close() 134 | 135 | if __name__ == "__main__": 136 | main() 137 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "setuptools_scm[toml]"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "HardwareMonitor" 7 | authors = [{ name = "Nicholas Feix", email = "nf@fconsoft.com" }] 8 | description = "Python import layer for the LibreHardwareMonitorLib assembly." 9 | readme = "README.md" 10 | keywords = ["monitoring", "sensors", "LibreHardwareMonitor"] 11 | requires-python = ">=3.6" 12 | license = { file = "LICENSE" } 13 | classifiers = [ 14 | "License :: Other/Proprietary License", 15 | "Intended Audience :: Developers", 16 | "Environment :: Win32 (MS Windows)", 17 | "Programming Language :: Python", 18 | "Programming Language :: Python :: 3", 19 | "Topic :: System :: Monitoring", 20 | ] 21 | dependencies = [ 22 | "pythonnet" 23 | ] 24 | dynamic = ["version"] 25 | 26 | [project.urls] 27 | Repository = "https://github.com/snip3rnick/PyHardwareMonitor" 28 | 29 | [tool.setuptools] 30 | include-package-data = true 31 | packages = ["HardwareMonitor"] 32 | 33 | [tool.build-system] 34 | exclude = [ 35 | ".github/*", 36 | "examples/*", 37 | "scripts/*", 38 | "submodules/*", 39 | "tests/*", 40 | ] 41 | 42 | [tool.setuptools.package-data] 43 | "HardwareMonitor" = ["lib/*"] 44 | 45 | [tool.setuptools_scm] 46 | -------------------------------------------------------------------------------- /scripts/generate_all.py: -------------------------------------------------------------------------------- 1 | from generate_stubs import collectAssembly, removeExistingStubs, generateStubs 2 | from generate_types_util import generateTypesUtilStub 3 | from generate_namespace_init import processAllNamespaces 4 | 5 | 6 | collectAssembly() 7 | removeExistingStubs() 8 | generateStubs() 9 | generateTypesUtilStub() 10 | processAllNamespaces() 11 | -------------------------------------------------------------------------------- /scripts/generate_namespace_init.py: -------------------------------------------------------------------------------- 1 | import re 2 | from pathlib import Path 3 | 4 | from generate_types_util import NAMESPACES, getExported 5 | 6 | SYSTEM_SYMBOLS = set(sum(map(list, map(getExported, NAMESPACES)), start=[])) 7 | HARDWARE_SYMBOLS = set() 8 | 9 | 10 | BASE_PATH = Path(__file__).parent.absolute() 11 | MODULE_PATH = BASE_PATH / ".." / "HardwareMonitor" 12 | NAMESPACE_INIT = BASE_PATH / "namespace_template.py" 13 | IMPORT_BASE = "LibreHardwareMonitor" 14 | 15 | EXCLUDE_SYMBOLS = ("Type", "Version", "OperatingSystem") 16 | OVERRIDE_SYMBOLS = ("Single", ) 17 | EXTRA_TYPING = ("overload", ) 18 | 19 | 20 | # ------------------------------------------------------------------------------ 21 | def findClosingParenthesis(data: str, symbols="()"): 22 | sym_open, sym_close = symbols 23 | lindex = rindex = lcount = rcount = 0 24 | while rindex > -1: 25 | rindex = data.find(sym_close, rindex) + 1 26 | lcount += data.count(sym_open, lindex, rindex) 27 | if lcount == rcount: 28 | break 29 | rcount += 1 30 | lindex = rindex 31 | return rindex - 1 32 | 33 | 34 | # ------------------------------------------------------------------------------ 35 | def _replaceSetBracesRecursive(data: str, pattern: re.Pattern): 36 | blocks = [] 37 | pos = 0 38 | while 42: 39 | match = pattern.search(data, pos) 40 | if not match: 41 | break 42 | _, mend = match.regs[0] 43 | blocks.append(data[pos:mend-1]) 44 | blocks.append("[") 45 | remainder = data[mend:] 46 | rpos = findClosingParenthesis(remainder) 47 | blocks.extend(_replaceSetBracesRecursive(remainder[:rpos], pattern)) 48 | blocks.append("]") 49 | pos = mend + rpos + 1 50 | if pos < (len(data) - 1): 51 | blocks.append(data[pos:]) 52 | return blocks 53 | 54 | 55 | # ------------------------------------------------------------------------------ 56 | def repairSetAnnotation(stub_data: str): 57 | regex = re.compile(r"(\A|\W)Set\(") 58 | return ''.join(_replaceSetBracesRecursive(stub_data, regex)) 59 | 60 | 61 | # ------------------------------------------------------------------------------ 62 | def repairArrayAnnotation(stub_data: str): 63 | return re.sub(r"(\s)([^\s\[]+)\[\,\]", r"\1List[\2]", stub_data) 64 | 65 | 66 | # ------------------------------------------------------------------------------ 67 | def repairTypingImport(stub_data: str): 68 | prefix = "from typing import " 69 | start_pos = stub_data.find(prefix) 70 | if start_pos == -1: 71 | return stub_data 72 | end_pos = stub_data.find("\n", start_pos) + 1 73 | symbols_used = set() 74 | stub_data_aft = stub_data[end_pos:] 75 | all_symbols = [*EXTRA_TYPING, *map(str.strip, stub_data[start_pos + len(prefix):end_pos].split(","))] 76 | for symbol in all_symbols: 77 | if re.search(f"\\W{symbol}\\W", stub_data_aft): 78 | symbols_used.add(symbol) 79 | if not symbols_used: 80 | return stub_data[:start_pos] + stub_data_aft 81 | import_statement = "from typing import " + ", ".join(sorted(symbols_used)) + "\n" 82 | return stub_data[:start_pos] + import_statement + stub_data_aft 83 | 84 | 85 | # ------------------------------------------------------------------------------ 86 | def _addSymbolImport(stub_data: str, symbols: set[str], namespace: str): 87 | symbols_used = set() 88 | exists_pos = stub_data.find(f"from {namespace} import ") 89 | if exists_pos >= 0: 90 | keep_index = stub_data.find("\n", exists_pos) + 1 91 | else: 92 | keep_index = exists_pos = 0 93 | stub_data_aft = stub_data[keep_index:] 94 | for symbol in symbols: 95 | if re.search(f"\\W{symbol}\\W", stub_data_aft): 96 | if symbol in OVERRIDE_SYMBOLS or not re.search(f"\\s*(class|def)\\s+{symbol}\\W", stub_data_aft): 97 | symbols_used.add(symbol) 98 | symbols_used = symbols_used.difference(EXCLUDE_SYMBOLS) 99 | if not symbols_used: 100 | return stub_data 101 | symbols_str = ", ".join(sorted(symbols_used)) 102 | import_statement = f"from {namespace} import {symbols_str}\n" 103 | return stub_data[:exists_pos] + import_statement + stub_data_aft 104 | 105 | 106 | # ------------------------------------------------------------------------------ 107 | def addSystemSymbolImport(stub_data: str): 108 | return _addSymbolImport(stub_data, SYSTEM_SYMBOLS, "HardwareMonitor._util.types") 109 | 110 | 111 | # ------------------------------------------------------------------------------ 112 | def addHardwareSymbolImport(stub_data: str): 113 | if not HARDWARE_SYMBOLS: 114 | stub_path = MODULE_PATH / "Hardware" / "__init__.pyi" 115 | with stub_path.open("r") as fobj: 116 | for symbol in re.findall("class (\w+)\\W", fobj.read()): 117 | HARDWARE_SYMBOLS.add(symbol) 118 | return _addSymbolImport(stub_data, HARDWARE_SYMBOLS, "HardwareMonitor.Hardware") 119 | 120 | 121 | # ------------------------------------------------------------------------------ 122 | def repairStub(stub_path: Path): 123 | repair_steps = [ 124 | repairSetAnnotation, 125 | repairArrayAnnotation, 126 | repairTypingImport, 127 | addSystemSymbolImport, 128 | addHardwareSymbolImport, 129 | ] 130 | with stub_path.open("r") as fobj: 131 | stub_data = fobj.read() 132 | # Apply repair functions to the data 133 | for func in repair_steps: 134 | stub_data = func(stub_data) 135 | with stub_path.open("w") as fobj: 136 | fobj.write(stub_data) 137 | print("repaired", repr(str(stub_path.relative_to(BASE_PATH)))) 138 | 139 | 140 | # ------------------------------------------------------------------------------ 141 | def processNamespaceDir(namespace_dir: Path): 142 | has_subdirs = False 143 | init_py = namespace_dir / "__init__.py" 144 | options = { 145 | "namespace_root": IMPORT_BASE, 146 | "submodule_name": namespace_dir.relative_to(MODULE_PATH).as_posix().replace("/", "."), 147 | } 148 | for path in namespace_dir.iterdir(): 149 | if path.is_dir(): 150 | processNamespaceDir(path) 151 | has_subdirs = True 152 | if path.name == "__init__.pyi": 153 | with open(NAMESPACE_INIT, "r") as fin: 154 | with open(init_py, "w") as fout: 155 | fout.write(fin.read().format(**options)) 156 | print("updated ", repr(str(init_py.relative_to(BASE_PATH)))) 157 | repairStub(path) 158 | 159 | if has_subdirs: 160 | init_py.touch(exist_ok=True) 161 | print("touched ", repr(str(init_py.relative_to(BASE_PATH)))) 162 | 163 | 164 | # ------------------------------------------------------------------------------ 165 | def processAllNamespaces(): 166 | for path in MODULE_PATH.iterdir(): 167 | if path.is_dir(): 168 | processNamespaceDir(path) 169 | 170 | 171 | if __name__ == "__main__": 172 | processAllNamespaces() 173 | -------------------------------------------------------------------------------- /scripts/generate_stubs.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import shutil 3 | import subprocess as sp 4 | from pathlib import Path 5 | 6 | BASE_PATH = Path(__file__).parent.absolute() 7 | MODULE_PATH = BASE_PATH / ".." / "HardwareMonitor" 8 | MODULE_LIB_PATH = MODULE_PATH / "lib" 9 | SUBMODULE_PATH = BASE_PATH / ".." / "submodules" 10 | 11 | STUBBLER_PATH = SUBMODULE_PATH / "pythonstubs" / "builder" / "bin" / "PyStubbler.exe" 12 | ASSEMBLY_PATH = SUBMODULE_PATH / "LibreHardwareMonitor" / "bin" / "Release" / "net4*" 13 | 14 | ASSEMBLY_NAMES = ("LibreHardwareMonitorLib.dll", "HidSharp.dll") 15 | 16 | 17 | def collectAssembly(): 18 | for assembly_name in ASSEMBLY_NAMES: 19 | for lib in map(Path, glob.glob(str(ASSEMBLY_PATH / assembly_name))): 20 | shutil.copyfile(lib, MODULE_LIB_PATH / lib.name) 21 | 22 | def removeExistingStubs(): 23 | for stub in MODULE_PATH.rglob("__init__.pyi"): 24 | stub.unlink() 25 | 26 | def generateStubs(): 27 | assembly_path = list(MODULE_LIB_PATH.glob("*HardwareMonitorLib.dll"))[0] 28 | return sp.call([str(STUBBLER_PATH), "--dest-is-root", "--dest", str(MODULE_PATH), str(assembly_path)]) 29 | 30 | 31 | if __name__ == "__main__": 32 | collectAssembly() 33 | removeExistingStubs() 34 | generateStubs() 35 | -------------------------------------------------------------------------------- /scripts/generate_types_util.py: -------------------------------------------------------------------------------- 1 | 2 | import clr # noqa: F401 3 | from pathlib import Path 4 | 5 | 6 | BASE_PATH = Path(__file__).parent.absolute() 7 | MODULE_PATH = BASE_PATH / ".." / "HardwareMonitor" 8 | TYPES_STUB = MODULE_PATH / "_util" / "types.pyi" 9 | 10 | NAMESPACES = ( 11 | "System", "System.Collections.Generic", 12 | ) 13 | 14 | EXCLUDE_SYMBOLS = set(["Tuple", "Set", "Iterable", "List"]) 15 | 16 | 17 | # ------------------------------------------------------------------------------ 18 | def getExported(namespace): 19 | split = namespace.split(".", 1) 20 | fromlist = () 21 | if len(split) == 2: 22 | fromlist = (split[0],) 23 | module = __import__(namespace, fromlist=fromlist) 24 | return set([attr for attr in module.__all__ if "`" not in attr]) - EXCLUDE_SYMBOLS 25 | 26 | 27 | # ------------------------------------------------------------------------------ 28 | def generateTypesUtilStub(): 29 | lines = ["# Generated stub file for some types from the CLR\n", "\n"] 30 | for namespace in NAMESPACES: 31 | lines.append(f"# Symbols from '{namespace}' namespace\n") 32 | for symbol in sorted(getExported(namespace), key=str.lower): 33 | lines.append(f"class {symbol}: ...\n") 34 | lines.append("\n") 35 | with open(TYPES_STUB, "w") as fobj: 36 | fobj.writelines(lines) 37 | print("generated typing utility") 38 | 39 | 40 | if __name__ == "__main__": 41 | generateTypesUtilStub() 42 | -------------------------------------------------------------------------------- /scripts/namespace_template.py: -------------------------------------------------------------------------------- 1 | # Generated namespace __init__.py file for 'HardwareMonitor.{submodule_name}' 2 | 3 | from {namespace_root}.{submodule_name} import * 4 | -------------------------------------------------------------------------------- /test/TestHardwareMonitor.py: -------------------------------------------------------------------------------- 1 | # Test script enumerating all hardware components and listing available sensors 2 | 3 | import sys, os 4 | sys.path.insert(0, os.path.abspath(__file__ + "/../..")) 5 | 6 | 7 | from HardwareMonitor.Hardware import Computer, IVisitor, IComputer, IHardware, IParameter, ISensor 8 | from HardwareMonitor.Util import SensorValueToString 9 | 10 | 11 | class UpdateVisitor(IVisitor): 12 | __namespace__ = "TestHardwareMonitor" 13 | def VisitComputer(self, computer: IComputer): 14 | computer.Traverse(self); 15 | 16 | def VisitHardware(self, hardware: IHardware): 17 | hardware.Update() 18 | for subHardware in hardware.SubHardware: 19 | subHardware.Update() 20 | 21 | def VisitParameter(self, parameter: IParameter): 22 | pass 23 | 24 | def VisitSensor(self, sensor: ISensor): 25 | pass 26 | 27 | 28 | computer = Computer() 29 | computer.IsMotherboardEnabled = True 30 | computer.IsControllerEnabled = True 31 | computer.IsCpuEnabled = True 32 | computer.IsGpuEnabled = True 33 | computer.IsBatteryEnabled = True 34 | computer.IsMemoryEnabled = True 35 | computer.IsNetworkEnabled = True 36 | computer.IsStorageEnabled = True 37 | 38 | computer.Open() 39 | computer.Accept(UpdateVisitor()) 40 | 41 | for hardware in computer.Hardware: 42 | print(f"Hardware: {hardware.Name}") 43 | for subhardware in hardware.SubHardware: 44 | print(f"\tSubhardware: {subhardware.Name}") 45 | for sensor in subhardware.Sensors: 46 | print(f"\t\tSensor: {sensor.Name}, value: {SensorValueToString(sensor.Value, sensor.SensorType)}") 47 | for sensor in hardware.Sensors: 48 | print(f"\tSensor: {sensor.Name}, value: {SensorValueToString(sensor.Value, sensor.SensorType)}") 49 | 50 | computer.Close() 51 | --------------------------------------------------------------------------------