15 Commits

Author SHA1 Message Date
112ca3e276 LiquidGUI [1.3.0.0]
- Linux fixes.
2025-02-11 23:31:37 +00:00
0f45cbf272 LiquidGUI [1.3.0.0]
- Continued refactoring.
2025-02-10 20:15:05 +00:00
89129fc6e5 LiquidGUI [1.3.0.0]
- Continued refactoring.
2025-02-10 20:13:22 +00:00
c05e8da224 LiquidGUI [1.3.0.0]
- Lots of refactoring.
2025-02-08 23:26:03 +00:00
ce4b1ec24c LiquidGUI [1.3.0.0]
- Moved CPU widget to top position.
2025-01-29 21:17:22 +00:00
aedd54b6a9 LiquidGUI [1.3.0.0]
- Unified Labels class to handle Linux and Windows.
2025-01-29 21:13:16 +00:00
3cf0709dd8 LiquidGUI [1.3.0.0]
- Round psutil result by 2 decimal places.
2025-01-27 00:24:57 +00:00
2226ebbe69 LiquidGUI [1.3.0.0]
- Initial psutil support for system vitals.
2025-01-27 00:17:44 +00:00
f9e01cfd8e LiquidGUI [1.2.0.0]
- Linux Support.
2024-12-30 14:38:47 +00:00
4d91e54e65 LiquidGUI [1.2.0.0]
- Linux Support
2024-12-30 14:08:06 +00:00
3cc53d0c81 LiquidGUI [1.2.0.0]
- Linux Support
2024-12-26 12:34:07 +00:00
03fca21675 LiquidGUI [1.2.0.0]
- Linux Support
2024-12-26 12:32:51 +00:00
040fff0677 LiquidGUI [1.2.0.0]
- Linux Support
2024-12-26 00:43:39 +00:00
ca036a5576 LiquidGUI [1.1.3.0]
- Added emoji to value text.
- Refactored label styling.
2024-07-14 15:24:26 +01:00
39c8fe48c8 LiquidGUI [1.1.2.0]
- Support for light mode.
2024-07-14 00:22:27 +01:00
19 changed files with 3014 additions and 79 deletions
+9 -1
View File
@@ -4,9 +4,17 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: LiquidCTL",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/main.pyw",
"console": "integratedTerminal",
"justMyCode": true
},
{
"name": "Python: Current File",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
+1 -1
View File
@@ -6,6 +6,6 @@ class MessageHandler():
msg = QMessageBox()
msg.setWindowTitle("LiquidGUI Error")
msg.setText("No suitable devices could be detected. Please ensure you have a cooler \
both compatible with LiquidCTL, and connected to the system.")
compatible with LiquidCTL, and connected to the system.")
msg.setIcon(QMessageBox.Icon.Warning)
msg.exec()
Binary file not shown.
Executable
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
pyside6-rcc resources.qrc -o resources.py
pyinstaller main.pyw --onefile --icon resources/LiquidGUI.png --name LiquidGUI
+3 -1
View File
@@ -17,4 +17,6 @@ class MinMaxCurrent:
if self.cur < self.min:
self.min = _cur
return f"Current: {self.cur}{_unit}\n(Min: {self.min}{_unit} / Max: {self.max}{_unit})"
return (f"🟢 Current: {self.cur}{_unit}\n"
f"Min: {self.min}{_unit} / "
f"Max: {self.max}{_unit}")
+4 -4
View File
@@ -7,8 +7,8 @@ VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0. Must always contain 4 elements.
filevers=(1,1,1,0),
prodvers=(1,1,1,0),
filevers=(1,1,3,0),
prodvers=(1,1,3,0),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
@@ -32,12 +32,12 @@ VSVersionInfo(
u'040904B0',
[StringStruct(u'CompanyName', u'Fil Sapia'),
StringStruct(u'FileDescription', u'LiquidGUI'),
StringStruct(u'FileVersion', u'1.1.1.0'),
StringStruct(u'FileVersion', u'1.1.3.0'),
StringStruct(u'InternalName', u'LiquidGUI'),
StringStruct(u'LegalCopyright', u'© Fil Sapia. All rights reserved.'),
StringStruct(u'OriginalFilename', u'LiquidGUI.exe'),
StringStruct(u'ProductName', u'LiquidGUI'),
StringStruct(u'ProductVersion', u'1.1.1.0')])
StringStruct(u'ProductVersion', u'1.1.3.0')])
]),
VarFileInfo([VarStruct(u'Translation', [0, 1200, 1033, 1252])])
]
+8
View File
@@ -0,0 +1,8 @@
import platform
os = None
_platform = platform.platform()
if _platform.startswith("Linux"):
os = "Linux"
elif _platform.startswith("Windows"):
os = "Windows"
+33
View File
@@ -0,0 +1,33 @@
from interfaces.liquidctl_helper_interface import LiquidCTL_Helper_Interface
import subprocess
import re
class LiquidCTL_Helper(LiquidCTL_Helper_Interface):
device_name = str()
device_temp = 0
device_fanSpeed = 0
device_pumpSpeed = 0
device_fwVers = str()
devices = None
def ForceInit(self):
NotImplemented
def TestConnectionState(self):
output = subprocess.run(["liquidctl", "status"], stdout=subprocess.PIPE, universal_newlines=True)
if len(output.stdout) > 0:
return False
else:
return True
def Update(self):
output = subprocess.run(["liquidctl", "status"], stdout=subprocess.PIPE, universal_newlines=True)
self.device_name = str(re.search(r'^[^\n]*', output.stdout).group(0))
self.device_temp = float(re.search(r'Liquid temperature\s+(\d+\.?\d*)', output.stdout).group(1))
self.device_fanSpeed = int(re.search(r'Fan speed\s+(\d+)', output.stdout).group(1))
self.device_pumpSpeed = int(re.search(r'Pump speed\s+(\d+)', output.stdout).group(1))
def SetFanSpeed(self, speed):
NotImplemented
@@ -1,11 +1,12 @@
from liquidctl import find_liquidctl_devices, cli
from interfaces.liquidctl_helper_interface import LiquidCTL_Helper_Interface
from liquidctl import find_liquidctl_devices, cli # type: ignore
class LiquidCTL_Helper():
device_name = None
class LiquidCTL_Helper(LiquidCTL_Helper_Interface):
device_name = str()
device_temp = 0
device_fanSpeed = 0
device_pumpSpeed = 0
device_fwVers = None
device_fwVers = str()
devices = find_liquidctl_devices()
try:
+28
View File
@@ -0,0 +1,28 @@
from interfaces.vitals_helper_interface import VitalsHelperInterface
from enum import Enum
import psutil
class VitalsHelperLinux(VitalsHelperInterface):
class HWSensor(Enum):
lin_cpu_amd = ("k10temp", "Tctl")
lin_gpu_amd = ("amdgpu", "edge")
lin_mobo_asus = ("asus_wmi_sensors", "Motherboard Temperature")
def get_temps(self, _hw_sensor: HWSensor):
temps = psutil.sensors_temperatures()
if _hw_sensor.value[0] in temps:
for entry in temps[_hw_sensor.value[0]]:
if entry.label == _hw_sensor.value[1]:
return round(entry.current, 2)
class VitalsHelperWindows(VitalsHelperInterface):
def __init__(self):
print(f"{self.__class__.__name__} is not Implemented")
class HWSensor(Enum):
pass
def get_temps(self, _hw_sensor: HWSensor):
return 0
+48
View File
@@ -0,0 +1,48 @@
from abc import ABC, abstractmethod, abstractproperty
class LiquidCTL_Helper_Interface(ABC):
@property
@abstractmethod
def device_name(self) -> str:
pass
@property
@abstractmethod
def device_temp(self) -> float:
pass
@property
@abstractmethod
def device_fanSpeed(self) -> float:
pass
@property
@abstractmethod
def device_pumpSpeed(self) -> float:
pass
@property
@abstractmethod
def device_fwVers(self) -> str:
pass
@property
@abstractmethod
def devices(self) -> None:
pass
@abstractmethod
def ForceInit(self) -> None:
pass
@abstractmethod
def TestConnectionState(self) -> None:
pass
@abstractmethod
def Update(self) -> None:
pass
@abstractmethod
def SetFanSpeed(self, speed) -> None:
pass
+8
View File
@@ -0,0 +1,8 @@
from abc import ABC, abstractmethod
class VitalsHelperInterface(ABC):
@abstractmethod
def get_temps(self, HWSensor):
""" Return Temperatures """
pass
+101 -43
View File
@@ -1,16 +1,30 @@
# External Dependencies
# External Dependencies v####################################
import sys
import win32mica
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QProgressBar, QPushButton
from PySide6.QtCore import Qt, QTimer, QThreadPool
from PySide6.QtGui import QFont, QIcon
# Internal Imports
from LiquidCTL_Helper import LiquidCTL_Helper
from MessageHandler import MessageHandler
from styles.SubLabel import SubLabel
from styles.SubLabelValue import SubLabelValue
from PySide6.QtWidgets import (QApplication,
QMainWindow,
QWidget,
QVBoxLayout,
QProgressBar,
QPushButton)
from PySide6.QtCore import (Qt,
QTimer,
QThreadPool)
from PySide6.QtGui import QIcon
## Internal Imports #########################################
import resources
import common
import resources, pkg_resources.extern
from MessageHandler import MessageHandler
## Platform Imports #########################################
import globals
from styles import Labels
if globals.os == "Windows":
from helpers.liquidctl_helper_windows import LiquidCTL_Helper
from helpers.vitals_helper import VitalsHelperWindows as VitalsHelper
import win32mica # type: ignore
import darkdetect # type: ignore
elif globals.os == "Linux":
from helpers.liquidctl_helper_linux import LiquidCTL_Helper
from helpers.vitals_helper import VitalsHelperLinux as VitalsHelper
class MainWindow(QMainWindow):
@@ -18,46 +32,55 @@ class MainWindow(QMainWindow):
def __init__(self, lctl):
super(MainWindow, self).__init__()
self.setWindowTitle("LiquidGUI (v.1.1.1.0)")
self.setFixedSize(450, 450)
self.setWindowTitle("LiquidGUI (v.1.3.0.0) DEV")
self.setFixedSize(450, 700)
self.lctl = lctl
self._lctl = lctl
self.__vitals_helper = VitalsHelper()
# Widgets ##########################################
self.lbl_device_name = QLabel(font=QFont("Calibri",
18,
weight=QFont.Weight.Bold),
alignment=Qt.AlignmentFlag.AlignCenter)
self.lbl_device_name = Labels.MainLabel()
self.lbl_temp = SubLabel(value="💧 Liquid Temperature:")
self.lbl_cpu_temp = Labels.SubLabel(value="💻 CPU Temp:")
self.min_max_cur_cpu_temp = common.MinMaxCurrent()
self.prg_cpu_temp = QProgressBar(textVisible=False,
minimum=0,
maximum=105)
self.lbl_value_prg_cpu_temp = Labels.SubLabelValue()
self.lbl_temp = Labels.SubLabel(value="💧 Liquid Temperature:")
self.min_max_cur_temp = common.MinMaxCurrent()
self.prg_temp = QProgressBar(textVisible=False,
minimum=0,
maximum=50)
self.lbl_value_prg_temp = SubLabelValue()
self.lbl_value_prg_temp = Labels.SubLabelValue()
self.lbl_fanspeed = SubLabel(value="🍃 Fan Speed:")
self.lbl_fanspeed = Labels.SubLabel(value="🍃 Fan Speed:")
self.min_max_cur_fanspeed = common.MinMaxCurrent()
self.prg_fanspeed = QProgressBar(textVisible=False,
minimum=520,
maximum=1700)
self.lbl_value_prg_fanspeed = SubLabelValue()
self.lbl_value_prg_fanspeed = Labels.SubLabelValue()
self.lbl_pumpspeed = SubLabel(value="⛽ Pump Speed:")
self.lbl_pumpspeed = Labels.SubLabel(value="⛽ Pump Speed:")
self.min_max_cur_pumpspeed = common.MinMaxCurrent()
self.prg_pumpspeed = QProgressBar(textVisible=False,
minimum=1900,
maximum=2700)
self.lbl_value_prg_pumpspeed = SubLabelValue()
self.lbl_value_prg_pumpspeed = Labels.SubLabelValue()
self.btn_reset_min_max = QPushButton("Reset Min/Max")
self.btn_reset_min_max.clicked.connect(self.on_reset_min_max)
self.lbl_fwvers = SubLabelValue()
self.lbl_fwvers = Labels.SubLabelValue()
# Layout ##########################################
widget = QWidget(self)
layout = QVBoxLayout(widget)
layout.addWidget(self.lbl_device_name)
layout.addWidget(self.lbl_cpu_temp)
layout.addWidget(self.prg_cpu_temp)
layout.addWidget(self.lbl_value_prg_cpu_temp)
layout.addWidget(self.lbl_temp)
layout.addWidget(self.prg_temp)
layout.addWidget(self.lbl_value_prg_temp)
@@ -76,12 +99,12 @@ class MainWindow(QMainWindow):
self.setCentralWidget(widget)
self.setContentsMargins(20, 20, 20, 20)
# Threading #######################################
# Threading #######################################################################
self.thread_manager = QThreadPool()
self.timer = QTimer()
self.timer.setInterval(1000)
self.timer.timeout.connect(lambda: self.thread_manager.start(self.lctl.Update))
self.timer.timeout.connect(lambda: self.thread_manager.start(self._lctl.Update))
self.timer.timeout.connect(self.update_widgets)
self.timer.start()
@@ -91,44 +114,79 @@ class MainWindow(QMainWindow):
self.min_max_cur_temp = common.MinMaxCurrent()
self.min_max_cur_fanspeed = common.MinMaxCurrent()
self.min_max_cur_pumpspeed = common.MinMaxCurrent()
self.min_max_cur_cpu_temp = common.MinMaxCurrent()
self.timer.start()
def update_widgets(self):
""" Update widgets using LiquidCTL library."""
self.lbl_device_name.setText(self.lctl.device_name)
self.prg_temp.setValue(self.lctl.device_temp)
# Platform Specific Widgets #######################################################
if globals.os == "Windows":
self.__vitals_helper()
elif globals.os == "Linux":
self.lbl_value_prg_cpu_temp.setText(
self.min_max_cur_cpu_temp.builder(
self.__vitals_helper.get_temps(
self.__vitals_helper.HWSensor.lin_cpu_amd), "°C"))
self.prg_cpu_temp.setValue(
self.__vitals_helper.get_temps(
self.__vitals_helper.HWSensor.lin_cpu_amd))
# Cross Platform Widgets ##########################################################
self.lbl_device_name.setText(
self._lctl.device_name)
self.prg_temp.setValue(
self._lctl.device_temp)
self.lbl_value_prg_temp.setText(
self.min_max_cur_temp.builder(
self.lctl.device_temp, "°C"))
self.prg_fanspeed.setValue(self.lctl.device_fanSpeed)
self._lctl.device_temp, "°C"))
self.prg_fanspeed.setValue(
self._lctl.device_fanSpeed)
self.lbl_value_prg_fanspeed.setText(
self.min_max_cur_fanspeed.builder(
self.lctl.device_fanSpeed, " rpm"))
self.prg_pumpspeed.setValue(self.lctl.device_pumpSpeed)
self._lctl.device_fanSpeed, " rpm"))
self.prg_pumpspeed.setValue(
self._lctl.device_pumpSpeed)
self.lbl_value_prg_pumpspeed.setText(
self.min_max_cur_pumpspeed.builder(
self.lctl.device_pumpSpeed, " rpm"))
if self.lctl.device_fwVers is not None:
self.lbl_fwvers.setText(f"Firmware: v{self.lctl.device_fwVers}")
self._lctl.device_pumpSpeed, " rpm"))
if len(self._lctl.device_fwVers) > 0:
self.lbl_fwvers.setText(f"Firmware: v{self._lctl.device_fwVers}")
def main():
""" Initialize application and setup window parameters. """
app = QApplication(sys.argv)
window = MainWindow(LiquidCTL_Helper())
if globals.os == "Windows":
window.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
icon = QIcon(":/icons/LiquidGUI.ico")
if darkdetect.isDark():
win32mica.ApplyMica(window.winId(), win32mica.MicaTheme.DARK)
elif darkdetect.isLight():
win32mica.ApplyMica(window.winId(), win32mica.MicaTheme.LIGHT)
elif globals.os == "Linux":
app.setDesktopFileName("LiquidGUI")
icon = QIcon(":/icons/LiquidGUI.png")
app.setWindowIcon(icon)
window = MainWindow(LiquidCTL_Helper())
window.setWindowIcon(icon)
window.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
# Show error and quit app if no devices are found
if window.lctl.TestConnectionState():
if window._lctl.TestConnectionState():
MessageHandler().ShowNoDevicesFoundError()
sys.exit(1)
else:
win32mica.ApplyMica(window.winId(), win32mica.MICAMODE.DARK)
window.show()
app.exec()
+2703 -3
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -2,5 +2,6 @@
<RCC version="1.0">
<qresource prefix="icons">
<file alias="LiquidGUI.ico">resources/LiquidGUI.ico</file>
<file alias="LiquidGUI.png">resources/LiquidGUI.png</file>
</qresource>
</RCC>
+12
View File
@@ -0,0 +1,12 @@
from setuptools import setup
setup(
name='LiquidGUI',
version='1.1.3.0',
packages=[''],
url='',
license='',
author='Fil Sapia',
author_email='filippo333@gmail.com',
description=''
)
+46
View File
@@ -0,0 +1,46 @@
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QFont
from PySide6.QtCore import Qt
import globals
def _set_os_family_font(ClassName: str):
_font = None
if globals.os == "Linux":
if ClassName == MainLabel.__name__ or SubLabel.__name__:
_font = "Noto Sans"
elif ClassName == SubLabelValue.__name__:
_font = "Noto Sans Mono"
elif globals.os == "Windows":
if ClassName == MainLabel.__name__ or SubLabel.__name__:
_font = "Calibri"
elif ClassName == SubLabelValue.__name__:
_font = "Cascadia Code"
return _font
class MainLabel(QLabel):
def __init__(self):
super().__init__()
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.setFont(QFont(_set_os_family_font(__class__.__name__),
16,
weight=QFont.Weight.ExtraBold))
class SubLabel(QLabel):
""" Formatting for sub-labels. """
def __init__(self, value):
super().__init__()
self.setFont(QFont(_set_os_family_font(__class__.__name__),
12,
weight=QFont.Weight.Thin))
self.setText(value)
class SubLabelValue(QLabel):
""" Formatting for values. """
def __init__(self):
super().__init__()
self.setAlignment(Qt.AlignmentFlag.AlignRight)
self.setFont(QFont(_set_os_family_font(__class__.__name__), 8))
-11
View File
@@ -1,11 +0,0 @@
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QFont
class SubLabel(QLabel):
""" Formatting for sub-labels. """
def __init__(self, value):
super().__init__()
self.setFont(QFont("Calibri", 12, weight=QFont.Weight.Bold))
self.setText(value)
-10
View File
@@ -1,10 +0,0 @@
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QFont
from PySide6.QtCore import Qt
class SubLabelValue(QLabel):
""" Formatting for values. """
def __init__(self):
super().__init__()
self.setAlignment(Qt.AlignmentFlag.AlignRight)
self.setFont(QFont("Cascadia Code", 8))