hwmonitor/hwmon-service/hwmon.py

165 lines
5.2 KiB
Python
Raw Normal View History

2024-10-18 22:51:22 +03:00
#
# 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