36 Commits

Author SHA1 Message Date
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
13393ed44d LiquidGUI [1.1.1.0]
- Added button to reset min/max values.
2024-07-13 21:57:08 +01:00
b483cdeb0e Removed Linux Changes 2024-07-13 21:34:21 +01:00
fbf594926c Added PyCharm .ignore file 2024-07-13 21:31:15 +01:00
11b812cd37 LiquidGUI [1.1.0.1]
- Added support for minimum and maximum temperatures.
- Corrected typo in Calibri font name.
- UI tweaks.
2024-07-13 21:30:28 +01:00
852186587c Removed DEV label from app. 2024-07-09 22:01:26 +01:00
65456aa5c6 LiquidGUI [1.1.0.0] Dev
- Code cleanup & refactoring.
- Platform specific code.
2024-07-09 22:00:56 +01:00
aed37b7fae LiquidGUI [1.1.0.0] Dev
- Added build script for Linux.
2024-07-08 23:25:29 +01:00
495de03e39 LiquidGUI [1.1.0.0] Dev
- Initial Linux support.
2024-07-07 16:41:50 +01:00
5fab490885 LiquidGUI
- Added support for EXE version data.
2024-07-02 00:01:38 +01:00
03ff5f1f66 Merged corrected build & requirements for 1.0.0.x 2024-06-30 15:30:48 +01:00
a9e807ceaf Merge branch '1.0.0.x'
# Conflicts:
#	requirements.txt
2024-06-30 15:21:29 +01:00
7723df2ea4 Fixed requirements.txt for 1.0.0.x 2024-06-30 15:18:54 +01:00
99259f877c Build script now sources venv 2024-06-30 15:18:54 +01:00
eda2fbeb71 LiquidGUI [1.0.3.2] Release
- Refactored some code.
- Corrected fonts and updated styles.
2024-06-30 14:57:29 +01:00
069b6f650c LiquidGUI [1.0.3.0] Release
- Updated PySide package version.
- GUI improvements with emoji.
2024-06-30 00:29:52 +01:00
ce98de60e6 Merge branch 'master' of https://go.hypn.synology.me/dunestorm/LiquidGUI
# Conflicts:
#	LiquidCTL_Helper.py
#	main.pyw
2024-03-10 20:37:39 +00:00
63fbeb430b LiquidGUI [1.0.2.0] Release
- Updated requirements with pip installer.
- Updated resources file after most recent local build.
2024-03-10 20:33:34 +00:00
c8ca1e881d LiquidGUI [1.0.1.3] Bugfix Release
- Moved device init into dedicated function to prevent unwanted
device re-init.
- Library renaming.
2024-03-10 20:28:00 +00:00
52b6f45c60 LiquidGUI [1.1.0.0] DEV
- Allow window to minimize.
2024-03-10 20:23:18 +00:00
c4f30ca156 LiquidGUI [1.0.1.3] Bugfix
- Added try block around device enumeration to catch unhandled
exception.
2024-03-03 17:13:08 +00:00
51ccdbcaa5 LiquidGUI [1.0.1.3] Bugfix Release
- Moved device init into dedicated function to prevent unwanted
device re-init.
- Library renaming.
2023-10-16 20:27:36 +01:00
080e19ae20 LiquidGUI [1.1.0.0] DEV
- Updated icon.
2023-09-02 23:18:48 +01:00
050ed12e43 LiquidGUI [1.1.0.0] DEV
- Corrected calling of static MessageHandler class.
- Apply theme only on main app to make QMessageBox button text legible.
2023-08-20 12:48:52 +01:00
5d4c09fc99 Corrected MessageHandler file name case 2023-08-20 11:40:07 +00:00
160a52db66 LiquidGUI [1.1.0.0] DEV
- Code refactoring.
- Created main method on main file.
- Made MessageHander static
2023-08-20 12:38:17 +01:00
5487a689a6 LiquidGUI [1.0.1.3] Bugfix Release
- Moved device init into dedicated function to prevent unwanted
device re-init.
- Library renaming.
2023-08-19 19:50:26 +01:00
a3ee61bff1 LiquidGUI [1.1.0.0] DEV
- Moved device init into dedicated function to prevent unwanted
device re-init.
- Library renaming.
2023-08-19 19:39:03 +01:00
ba1d19cc0b LiquidGUI [1.1.0.0] DEV
- Implemented the ability to change fan speed.
- Placeholder GUI button to max out fan speed.
2023-08-19 18:04:38 +01:00
7b32a214df LiquidGUI [1.0.1.2]
- Error handling and app termination for no compatible coolers.
- Minor code refactoring.
2023-08-18 21:37:59 +01:00
23 changed files with 8300 additions and 2372 deletions
Vendored
+1
View File
@@ -3,3 +3,4 @@ dist
build
.venv
LiquidGUI.spec
.idea
+32
View File
@@ -0,0 +1,32 @@
import subprocess
import re
class LiquidCTL_Helper():
device_name = None
device_temp = 0
device_fanSpeed = 0
device_pumpSpeed = 0
device_fwVers = None
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
+49
View File
@@ -0,0 +1,49 @@
from liquidctl import find_liquidctl_devices, cli
class LiquidCTL_Helper():
device_name = None
device_temp = 0
device_fanSpeed = 0
device_pumpSpeed = 0
device_fwVers = None
devices = find_liquidctl_devices()
try:
for dev in devices:
with dev.connect():
#print(f'{dev.description}')
device_name = dev.description
device_fwVers = ''.join(map(str, dev.firmware_version))
except:
pass
def ForceInit(self):
init_status = self.dev.initialize()
if init_status:
for key, value, unit in init_status:
#print(f'- {key}: {value} {unit}')
device_fwVers = value
def TestConnectionState(self):
if self.device_name != None:
return False
else:
return True
def Update(self):
with self.dev.connect():
status = self.dev.get_status()
for key, value, unit in status:
#print(f'- {key}: {value} {unit}')
if key == "Liquid temperature":
self.device_temp = value
elif key == "Fan speed":
self.device_fanSpeed = value
elif key == "Pump speed":
self.device_pumpSpeed = value
def SetFanSpeed(self, speed):
with self.dev.connect():
cli._device_set_speed(self.dev, args={"<temperature>": [],
"<channel>": "fan",
"<percentage>": [str(speed)]})
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 40 KiB

+11
View File
@@ -0,0 +1,11 @@
from PySide6.QtWidgets import QMessageBox
@staticmethod
class MessageHandler():
def ShowNoDevicesFoundError(self):
msg = QMessageBox()
msg.setWindowTitle("LiquidGUI Error")
msg.setText("No suitable devices could be detected. Please ensure you have a cooler \
compatible with LiquidCTL, and connected to the system.")
msg.setIcon(QMessageBox.Icon.Warning)
msg.exec()
+2 -1
View File
@@ -1,3 +1,4 @@
@echo off
call .venv\Scripts\activate.bat
pyside6-rcc.exe resources.qrc -o resources.py
pyinstaller.exe main.pyw --onefile --paths .venv\Lib\site-packages --icon resources\LiquidGUI.ico --name LiquidGUI
pyinstaller.exe main.pyw --onefile --paths .venv\Lib\site-packages --icon resources\LiquidGUI.ico --name LiquidGUI --version-file file_version_info.txt
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
+22
View File
@@ -0,0 +1,22 @@
class MinMaxCurrent:
def __init__(self):
self.min = 0
self.max = 0
self.cur = 0
def builder(self, _cur: int, _unit: str):
self.cur = _cur
if 0 in [self.max, self.min]:
self.max = _cur
self.min = _cur
if self.cur > self.max:
self.max = _cur
if self.cur < self.min:
self.min = _cur
return (f"🟢 Current: {self.cur}{_unit}\n"
f"Min: {self.min}{_unit} / "
f"Max: {self.max}{_unit}")
+44
View File
@@ -0,0 +1,44 @@
# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
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,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.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x40004,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'040904B0',
[StringStruct(u'CompanyName', u'Fil Sapia'),
StringStruct(u'FileDescription', u'LiquidGUI'),
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.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"
-32
View File
@@ -1,32 +0,0 @@
from liquidctl import find_liquidctl_devices
class LiquidCTL_Init():
device_name = None
device_temp = 0
device_fanSpeed = 0
device_pumpSpeed = 0
device_fwVers = 0
devices = find_liquidctl_devices()
for dev in devices:
with dev.connect():
#print(f'{dev.description}')
device_name = dev.description
init_status = dev.initialize()
if init_status:
for key, value, unit in init_status:
#print(f'- {key}: {value} {unit}')
device_fwVers = value
def Update(self):
with self.dev.connect():
status = self.dev.get_status()
for key, value, unit in status:
#print(f'- {key}: {value} {unit}')
if key == "Liquid temperature":
self.device_temp = value
elif key == "Fan speed":
self.device_fanSpeed = value
elif key == "Pump speed":
self.device_pumpSpeed = value
+121 -48
View File
@@ -1,83 +1,156 @@
# External Dependencies v####################################
import sys
import qdarktheme
import win32mica
import liquidctl_worker
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
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QProgressBar, QGroupBox
from PySide6.QtCore import Qt, QTimer, QThreadPool
from PySide6.QtGui import QFont, QIcon
import common
from MessageHandler import MessageHandler
## Platform Imports #########################################
import globals
if globals.os == "Windows":
from LiquidCTL_Helper_Windows import LiquidCTL_Helper
from styles import Labels_Windows as Labels
import win32mica
import darkdetect
elif globals.os == "Linux":
from LiquidCTL_Helper_Linux import LiquidCTL_Helper
from styles import Labels_Linux as Labels
from pathlib import Path
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("LiquidGUI (v.1.0.0.1)")
self.setFixedSize(450, 300)
self.setWindowFlags(Qt.WindowType.Dialog)
widget = QWidget(self)
""" Main application window. """
font_style = QFont("Calibri", 16, weight=QFont.Weight.Bold)
self.lbl_device_name = QLabel()
self.lbl_device_name.setFont(font_style)
self.lbl_temp = QLabel("Liquid Temperature:")
self.prg_temp = QProgressBar(format="%v°C",
def __init__(self, lctl):
super(MainWindow, self).__init__()
self.setWindowTitle("LiquidGUI (v.1.2.0.0)")
self.setFixedSize(450, 500)
self.lctl = lctl
# Widgets ##########################################
self.lbl_device_name = Labels.MainLabel()
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_fanSpeed = QLabel("Fan Speed:")
self.prg_fanSpeed = QProgressBar(format="%v rpm",
self.lbl_value_prg_temp = Labels.SubLabelValue()
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_pumpSpeed = QLabel("Pump Speed:")
self.prg_pumpSpeed = QProgressBar(format="%v rpm",
self.lbl_value_prg_fanspeed = Labels.SubLabelValue()
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_fwVers = QLabel()
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 = Labels.SubLabelValue()
# Layout ##########################################
widget = QWidget(self)
layout = QVBoxLayout(widget)
layout.addWidget(self.lbl_device_name)
layout.addWidget(self.lbl_temp)
layout.addWidget(self.prg_temp)
layout.addWidget(self.lbl_fanSpeed)
layout.addWidget(self.prg_fanSpeed)
layout.addWidget(self.lbl_pumpSpeed)
layout.addWidget(self.prg_pumpSpeed)
layout.addWidget(self.lbl_fwVers)
layout.addWidget(self.lbl_value_prg_temp)
layout.addWidget(self.lbl_fanspeed)
layout.addWidget(self.prg_fanspeed)
layout.addWidget(self.lbl_value_prg_fanspeed)
layout.addWidget(self.lbl_pumpspeed)
layout.addWidget(self.prg_pumpspeed)
layout.addWidget(self.lbl_value_prg_pumpspeed)
layout.addWidget(self.lbl_fwvers)
layout.addWidget(self.btn_reset_min_max)
layout.setSpacing(10)
self.setLayout(layout)
self.setCentralWidget(widget)
self.setContentsMargins(40, 20, 40, 20)
self.setContentsMargins(20, 20, 20, 20)
# Threading #######################################
self.thread_manager = QThreadPool()
self.timer = QTimer()
self.timer.setInterval(1000)
self.timer.timeout.connect(lambda: self.thread_manager.start(lctl_worker.Update))
self.timer.timeout.connect(lambda: self.thread_manager.start(self.lctl.Update))
self.timer.timeout.connect(self.update_widgets)
self.timer.start()
def on_reset_min_max(self):
""" Pauses the timer and creates new instances of MinMaxCurrent """
self.timer.stop()
self.min_max_cur_temp = common.MinMaxCurrent()
self.min_max_cur_fanspeed = common.MinMaxCurrent()
self.min_max_cur_pumpspeed = common.MinMaxCurrent()
self.timer.start()
def update_widgets(self):
self.lbl_device_name.setText(lctl_worker.device_name)
self.prg_temp.setValue(lctl_worker.device_temp)
self.prg_fanSpeed.setValue(lctl_worker.device_fanSpeed)
self.prg_pumpSpeed.setValue(lctl_worker.device_pumpSpeed)
if lctl_worker.device_fwVers != 0 or None:
self.lbl_fwVers.setText(f"Firmware: v{lctl_worker.device_fwVers}")
app = QApplication(sys.argv)
""" Update widgets using LiquidCTL library."""
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.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.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}")
icon = QIcon(":/icons/LiquidGUI.ico")
app.setWindowIcon(icon)
lctl_worker = liquidctl_worker.LiquidCTL_Init()
def main():
""" Initialize application and setup window parameters. """
app = QApplication(sys.argv)
window = MainWindow(LiquidCTL_Helper())
window = MainWindow()
window.setWindowIcon(icon)
window.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
if globals.os == "Windows":
window.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
icon = QIcon(":/icons/LiquidGUI.ico")
qdarktheme.setup_theme("dark", custom_colors={"background": "#00000000"})
win32mica.ApplyMica(window.winId(), win32mica.MICAMODE.DARK)
if darkdetect.isDark():
win32mica.ApplyMica(window.winId(), win32mica.MICAMODE.DARK)
elif darkdetect.isLight():
win32mica.ApplyMica(window.winId(), win32mica.MICAMODE.LIGHT)
window.show()
app.exec()
elif globals.os == "Linux":
app.setDesktopFileName("LiquidGUI")
icon = QIcon(":/icons/LiquidGUI.png")
app.setWindowIcon(icon)
# Show error and quit app if no devices are found
if window.lctl.TestConnectionState():
MessageHandler().ShowNoDevicesFoundError()
sys.exit(1)
else:
window.show()
app.exec()
if __name__ == "__main__":
main()
+12
View File
@@ -0,0 +1,12 @@
Version: 1.1.0.1
CompanyName: Fil Sapia
FileDescription: LiquidGUI
InternalName: LiquidGUI
LegalCopyright: © Fil Sapia. All rights reserved.
OriginalFilename: LiquidGUI.exe
ProductName: LiquidGUI
Translation:
- langID: 0
charsetID: 1200
- langID: 1033
charsetID: 1252
BIN
View File
Binary file not shown.
+5295 -2291
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>
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

+2633
View File
File diff suppressed because it is too large Load Diff
+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=''
)
+27
View File
@@ -0,0 +1,27 @@
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QFont
from PySide6.QtCore import Qt
class MainLabel(QLabel):
def __init__(self):
super().__init__()
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.setFont(QFont("Noto Sans",
16,
weight=QFont.Weight.ExtraBold))
class SubLabel(QLabel):
""" Formatting for sub-labels. """
def __init__(self, value):
super().__init__()
self.setFont(QFont("Noto Sans", 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("Noto Sans Mono", 8))
+27
View File
@@ -0,0 +1,27 @@
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QFont
from PySide6.QtCore import Qt
class MainLabel(QLabel):
def __init__(self):
super().__init__()
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.setFont(QFont("Calibri",
14.5,
weight=QFont.Weight.ExtraBold))
class SubLabel(QLabel):
""" Formatting for sub-labels. """
def __init__(self, value):
super().__init__()
self.setFont(QFont("Calibri", 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("Cascadia Code", 8))