164 lines
5.2 KiB
Python
164 lines
5.2 KiB
Python
#
|
|
# Copyright (C) John Solntsev <johnsol@internet.ru> (2024)
|
|
#
|
|
# This file is part of hwmon-checker.
|
|
#
|
|
# hwmon-checker is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# hwmon-checker is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with hwmon-checker. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
import re
|
|
import json
|
|
|
|
import os
|
|
|
|
TEMP_REGEX = re.compile(r"temp\d+_")
|
|
TEMP_LABEL_REGEX = re.compile(r"temp\d+_label")
|
|
TEMP_INPUT_REGEX = re.compile(r"temp\d+_input")
|
|
|
|
CURRENT_REGEX = re.compile(r"curr\d+_")
|
|
CURRENT_INPUT_REGEX = re.compile(r"curr\d+_input")
|
|
|
|
VOLTAGE_REGEX = re.compile(r"in\d+_")
|
|
VOLTAGE_INPUT_REGEX = re.compile(r"in\d+_input")
|
|
|
|
class HardwareNoneNameError(Exception):
|
|
pass
|
|
|
|
|
|
class MonitorParseValue:
|
|
def __init__(self, hwmon_base, hw_item_path, name, item):
|
|
self.__hwmon_base = hwmon_base
|
|
self.hw_item_path = os.path.join(hw_item_path, item)
|
|
self.name = name
|
|
self.item = item
|
|
self.item_first_name = item
|
|
|
|
if self.item.find("_") >= 0:
|
|
self.item_first_name = self.item[0:item.find("_")]
|
|
|
|
self._check_temperature()
|
|
self._check_current()
|
|
self._check_voltage()
|
|
|
|
def __create_element_store(self):
|
|
if not self.item_first_name in self.__hwmon_base[self.name]:
|
|
self.__hwmon_base[self.name][self.item_first_name] = {}
|
|
|
|
def __update_base(self, key, value):
|
|
self.__hwmon_base[self.name][self.item_first_name][key] = value
|
|
|
|
@staticmethod
|
|
def __get_text_value(from_file):
|
|
text_val = ""
|
|
|
|
with open(from_file, "r") as fd_item:
|
|
text_val = fd_item.read().replace("\n", "")
|
|
|
|
return text_val
|
|
|
|
@staticmethod
|
|
def __get_num_value(from_file):
|
|
num_val = 0
|
|
|
|
with open(from_file, "r") as fd_item:
|
|
raw_val = fd_item.read().replace("\n", "")
|
|
|
|
if raw_val.isdigit():
|
|
num_val = int(raw_val)
|
|
|
|
return num_val
|
|
|
|
def _check_temperature(self):
|
|
"""
|
|
Write to base value if is temperature
|
|
"""
|
|
if TEMP_REGEX.match(self.item):
|
|
self.__create_element_store()
|
|
self.__update_base("type", "temperature")
|
|
self.__update_base("rate", "°C")
|
|
|
|
if TEMP_LABEL_REGEX.match(self.item):
|
|
label = self.__get_text_value(self.hw_item_path)
|
|
self.__update_base("name", label)
|
|
|
|
elif TEMP_INPUT_REGEX.match(self.item):
|
|
temperature = self.__get_num_value(self.hw_item_path)
|
|
self.__update_base("value", temperature / 1000)
|
|
|
|
def _check_current(self):
|
|
"""
|
|
Write to base value if is current
|
|
"""
|
|
if CURRENT_REGEX.match(self.item):
|
|
self.__create_element_store()
|
|
self.__update_base("type", "current")
|
|
self.__update_base("rate", "A")
|
|
|
|
if CURRENT_INPUT_REGEX.match(self.item):
|
|
current = self.__get_num_value(self.hw_item_path)
|
|
self.__update_base("value", current)
|
|
|
|
def _check_voltage(self):
|
|
"""
|
|
Write to base value if is voltage
|
|
"""
|
|
if VOLTAGE_REGEX.match(self.item):
|
|
self.__create_element_store()
|
|
self.__update_base("type", "voltage")
|
|
self.__update_base("rate", "V")
|
|
|
|
if VOLTAGE_INPUT_REGEX.match(self.item):
|
|
voltage = self.__get_num_value(self.hw_item_path)
|
|
self.__update_base("value", voltage)
|
|
|
|
|
|
class HardwareMonitor:
|
|
def __init__(self, hwmon_path="/sys/class/hwmon"):
|
|
self.__hwmon_path = hwmon_path
|
|
self.__hwmon_base = {}
|
|
|
|
self.__create_base()
|
|
|
|
def __create_base(self):
|
|
for hw_item in os.listdir(self.__hwmon_path):
|
|
hw_item_path = os.path.join(self.__hwmon_path, hw_item)
|
|
|
|
with open(os.path.join(hw_item_path, "name"), "r") as fd_name:
|
|
name = fd_name.readline().replace("\n", "")
|
|
self.__hwmon_base.update({name: {}})
|
|
|
|
def __check_one_item(self, name):
|
|
if name is None:
|
|
raise HardwareNoneNameError
|
|
|
|
for hw_item in os.listdir(self.__hwmon_path):
|
|
hw_item_path = os.path.join(self.__hwmon_path, hw_item)
|
|
|
|
with open(os.path.join(hw_item_path, "name")) as fd_name:
|
|
name = fd_name.read().replace("\n", "")
|
|
|
|
for item in os.listdir(hw_item_path):
|
|
mb = MonitorParseValue(self.__hwmon_base, hw_item_path, name, item)
|
|
|
|
def check_all(self):
|
|
for hwmon_elem in os.listdir(self.__hwmon_path):
|
|
self.__check_one_item(hwmon_elem)
|
|
|
|
def get_json(self, human_readable=False):
|
|
if human_readable:
|
|
return json.dumps(self.__hwmon_base, indent=4)
|
|
|
|
return json.dumps(self.__hwmon_base)
|
|
|
|
def get(self):
|
|
return self.__hwmon_base
|