Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into dev/advanced-radials
Browse files Browse the repository at this point in the history
  • Loading branch information
mathoudebine committed Dec 22, 2024
2 parents 790941e + e686767 commit ad2bc4b
Show file tree
Hide file tree
Showing 51 changed files with 3,850 additions and 272 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/simple-program-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/simple-program-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/simple-program-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/system-monitor-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
theme: [ "3.5inchTheme2" ]

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/system-monitor-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
theme: [ "3.5inchTheme2" ]

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/system-monitor-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
theme: [ "3.5inchTheme2" ]

steps:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/themes-screenshot-on-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ jobs:

steps:
- uses: actions/checkout@v4
- name: Set up Python 3.10
- name: Set up Python 3.x
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.13"

- name: Install dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/themes-screenshot-on-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:

steps:
- uses: actions/checkout@v4
- name: Set up Python 3.10
- name: Set up Python 3.x
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.13"

- name: Install dependencies
run: |
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ dmypy.json
# Pyre type checker
.pyre/

# PyCharm
# Editors / IDEs
.idea/
.vscode/

# Git mergetool backup
*.orig
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This project is an open-source alternative software, NOT the original software p
* for other smart screens, contact your reseller
---

![Linux](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black) ![Windows](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white) ![macOS](https://img.shields.io/badge/mac%20os-000000?style=for-the-badge&logo=apple&logoColor=white) ![Raspberry Pi](https://img.shields.io/badge/Raspberry%20Pi-A22846?style=for-the-badge&logo=Raspberry%20Pi&logoColor=white) ![Python](https://img.shields.io/badge/Python-3.8/3.12-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54) [![Licence](https://img.shields.io/github/license/mathoudebine/turing-smart-screen-python?style=for-the-badge)](./LICENSE)
![Linux](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black) ![Windows](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white) ![macOS](https://img.shields.io/badge/mac%20os-000000?style=for-the-badge&logo=apple&logoColor=white) ![Raspberry Pi](https://img.shields.io/badge/Raspberry%20Pi-A22846?style=for-the-badge&logo=Raspberry%20Pi&logoColor=white) ![Python](https://img.shields.io/badge/Python-3.8/3.13-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54) [![Licence](https://img.shields.io/github/license/mathoudebine/turing-smart-screen-python?style=for-the-badge)](./LICENSE)


A Python system monitor program and an abstraction library for **small IPS USB-C (UART) displays.**
Expand Down
22 changes: 22 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,28 @@ config:
ETH: "" # Ethernet Card
WLO: "" # Wi-Fi Card

# CPU fan
# For Linux/MacOS platforms, the CPU fan is amongst all fan sensors gathered from the motherboard chipset
# If value is AUTO the system monitor will try to auto-select the CPU fan
# If auto-detection fails, it might be necessary to manually indicate which fan is the CPU fan
# Value must be 'controller/fan' e.g. 'nct6798/fan2'. Use configuration wizard for help in selection
CPU_FAN: AUTO

# Address used for ping sensor. Can be internal/external IP (e.g. 8.8.8.8 or 192.168.0.1) or hostname (google.com)
PING: 8.8.8.8

# Weather data with OpenWeatherMap API. Only useful if you want to use a theme that displays it
# Location from which to display the weather. Use for example https://www.latlong.net/ to get latitude/longitude
WEATHER_LATITUDE: 45.75
WEATHER_LONGITUDE: 4.85
# OpenWeatherMap API KEY. Can be obtained by creating a free account on https://home.openweathermap.org/users/sign_up.
# You need to subscribe to the 3.0 OneCallAPI that has 1000 free daily calls
WEATHER_API_KEY: ""
# Units used to display temperatures (metric - °C, imperial - °F, standard - °K)
WEATHER_UNITS: metric
# Language is used by the API. Find more here https://openweathermap.org/api/one-call-3#multi
WEATHER_LANGUAGE: en

display:
# Display revision:
# - A for Turing 3.5" and UsbPCMonitor 3.5"/5"
Expand Down
95 changes: 74 additions & 21 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,24 @@
import tkinter.ttk as ttk
from tkinter import *
from PIL import ImageTk
except:
print(
"[ERROR] Tkinter dependency not installed. Please follow troubleshooting page: https://github.com/mathoudebine/turing-smart-screen-python/wiki/Troubleshooting#all-os-tkinter-dependency-not-installed")
try:
sys.exit(0)
except:
os._exit(0)

try:
import psutil
import ruamel.yaml
import sv_ttk
from PIL import Image
from serial.tools.list_ports import comports
except:
print(
"[ERROR] Python dependencies not installed. Please follow start guide: https://github.com/mathoudebine/turing-smart-screen-python/wiki/System-monitor-:-how-to-start")
from tktooltip import ToolTip
except Exception as e:
print("""Import error: %s
Please follow start guide to install required packages: https://github.com/mathoudebine/turing-smart-screen-python/wiki/System-monitor-:-how-to-start
Or the troubleshooting page: https://github.com/mathoudebine/turing-smart-screen-python/wiki/Troubleshooting#all-os-tkinter-dependency-not-installed""" % str(
e))
try:
sys.exit(0)
except:
os._exit(0)

from library.sensors.sensors_python import sensors_fans, is_cpu_fan

TURING_MODEL = "Turing Smart Screen"
USBPCMONITOR_MODEL = "UsbPCMonitor"
XUANFANG_MODEL = "XuanFang rev. B & flagship"
Expand Down Expand Up @@ -141,14 +137,28 @@ def get_net_if():
return if_list


def get_fans():
fan_list = list()
auto_detected_cpu_fan = "None"
for name, entries in sensors_fans().items():
for entry in entries:
fan_list.append("%s/%s (%d%% - %d RPM)" % (name, entry.label, entry.percent, entry.current))
if (is_cpu_fan(entry.label) or is_cpu_fan(name)) and auto_detected_cpu_fan == "None":
auto_detected_cpu_fan = "Auto-detected: %s/%s" % (name, entry.label)

fan_list.insert(0, auto_detected_cpu_fan) # Add manual entry on top if auto-detection succeeded
return fan_list


class TuringConfigWindow:
def __init__(self):
self.window = Tk()
self.window.title('Turing System Monitor configuration')
self.window.geometry("770x550")
self.window.geometry("770x570")
self.window.iconphoto(True, PhotoImage(file="res/icons/monitor-icon-17865/64.png"))
# When window gets focus again, reload theme preview in case it has been updated by theme editor
self.window.bind("<FocusIn>", self.on_theme_change)
self.window.after(0, self.on_fan_speed_update)

# Make TK look better with Sun Valley ttk theme
sv_ttk.set_theme("light")
Expand Down Expand Up @@ -224,18 +234,29 @@ def __init__(self):
self.wl_cb = ttk.Combobox(self.window, values=get_net_if(), state='readonly')
self.wl_cb.place(x=500, y=415, width=250)

# For Windows platform only
self.lhm_admin_warning = ttk.Label(self.window,
text="❌ Restart as admin. or select another Hardware monitoring",
foreground='#f00')
# For platform != Windows
self.cpu_fan_label = ttk.Label(self.window, text='CPU fan (?)')
self.cpu_fan_label.config(foreground="#a3a3ff", cursor="hand2")
self.cpu_fan_cb = ttk.Combobox(self.window, values=get_fans(), state='readonly')

self.tooltip = ToolTip(self.cpu_fan_label,
msg="If \"None\" is selected, CPU fan was not auto-detected.\n"
"Manually select your CPU fan from the list.\n\n"
"Fans missing from the list? Install lm-sensors package\n"
"and run 'sudo sensors-detect' command, then reboot.")

self.edit_theme_btn = ttk.Button(self.window, text="Edit theme", command=lambda: self.on_theme_editor_click())
self.edit_theme_btn.place(x=310, y=490, height=50, width=130)
self.edit_theme_btn.place(x=310, y=510, height=50, width=130)

self.save_btn = ttk.Button(self.window, text="Save settings", command=lambda: self.on_save_click())
self.save_btn.place(x=450, y=490, height=50, width=130)
self.save_btn.place(x=450, y=510, height=50, width=130)

self.save_run_btn = ttk.Button(self.window, text="Save and run", command=lambda: self.on_saverun_click())
self.save_run_btn.place(x=590, y=490, height=50, width=130)
self.save_run_btn.place(x=590, y=510, height=50, width=130)

self.config = None
self.load_config_values()
Expand All @@ -261,7 +282,8 @@ def load_theme_preview(self):
self.theme_author.config(text="Author: " + author_name)
if author_name.startswith("@"):
self.theme_author.config(foreground="#a3a3ff", cursor="hand2")
self.theme_author.bind("<Button-1>", lambda e: webbrowser.open_new_tab("https://github.com/" + author_name[1:]))
self.theme_author.bind("<Button-1>",
lambda e: webbrowser.open_new_tab("https://github.com/" + author_name[1:]))
else:
self.theme_author.config(foreground="#a3a3a3", cursor="")
self.theme_author.unbind("<Button-1>")
Expand All @@ -271,11 +293,16 @@ def load_config_values(self):
with open("config.yaml", "rt", encoding='utf8') as stream:
self.config, ind, bsi = ruamel.yaml.util.load_yaml_guess_indent(stream)

# Check if theme is valid
if get_theme_data(self.config['config']['THEME']) is None:
# Theme from config.yaml is not valid: use first theme available default size 3.5"
self.config['config']['THEME'] = get_themes(SIZE_3_5_INCH)[0]

try:
self.theme_cb.set(self.config['config']['THEME'])
except:
self.theme_cb.current(0)
# self.load_theme_size()
self.theme_cb.set("")

self.load_theme_preview()

try:
Expand Down Expand Up @@ -331,6 +358,14 @@ def load_config_values(self):
except:
self.brightness_slider.set(50)

try:
if self.config['config']['CPU_FAN'] == "AUTO":
self.cpu_fan_cb.current(0)
else:
self.cpu_fan_cb.set(self.config['config']['CPU_FAN'])
except:
self.cpu_fan_cb.current(0)

# Reload content on screen
self.on_model_change()
self.on_size_change()
Expand All @@ -353,6 +388,10 @@ def save_config_values(self):
self.config['config']['COM_PORT'] = "AUTO"
else:
self.config['config']['COM_PORT'] = self.com_cb.get()
if self.cpu_fan_cb.current() == 0:
self.config['config']['CPU_FAN'] = "AUTO"
else:
self.config['config']['CPU_FAN'] = self.cpu_fan_cb.get().split(' ')[0]
self.config['display']['REVISION'] = model_and_size_to_revision_map[(self.model_cb.get(), self.size_cb.get())]
self.config['display']['DISPLAY_REVERSE'] = [k for k, v in reverse_map.items() if v == self.orient_cb.get()][0]
self.config['display']['BRIGHTNESS'] = int(self.brightness_slider.get())
Expand All @@ -361,7 +400,6 @@ def save_config_values(self):
ruamel.yaml.YAML().dump(self.config, file)

def on_theme_change(self, e=None):
# self.load_theme_size()
self.load_theme_preview()

def on_theme_editor_click(self):
Expand Down Expand Up @@ -417,11 +455,18 @@ def on_hwlib_change(self, e=None):
import ctypes
is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0
if (hwlib == "LHM" or hwlib == "AUTO") and not is_admin:
self.lhm_admin_warning.place(x=320, y=455)
self.lhm_admin_warning.place(x=320, y=460)
self.save_run_btn.state(["disabled"])
else:
self.lhm_admin_warning.place_forget()
self.save_run_btn.state(["!disabled"])
else:
if hwlib == "PYTHON" or hwlib == "AUTO":
self.cpu_fan_label.place(x=320, y=460)
self.cpu_fan_cb.place(x=500, y=455, width=250)
else:
self.cpu_fan_label.place_forget()
self.cpu_fan_cb.place_forget()

def show_hide_brightness_warning(self, e=None):
if int(self.brightness_slider.get()) > 50 and self.model_cb.get() == TURING_MODEL and self.size_cb.get() == SIZE_3_5_INCH:
Expand All @@ -430,6 +475,14 @@ def show_hide_brightness_warning(self, e=None):
else:
self.brightness_warning_label.place_forget()

def on_fan_speed_update(self):
# Update fan speed periodically
prev_value = self.cpu_fan_cb.current() # Save currently selected index
self.cpu_fan_cb.config(values=get_fans())
if prev_value != -1:
self.cpu_fan_cb.current(prev_value) # Force select same index to refresh displayed value
self.window.after(500, self.on_fan_speed_update)


if __name__ == "__main__":
configurator = TuringConfigWindow()
Expand Down
5 changes: 4 additions & 1 deletion library/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,17 @@ def display_static_text(self):
text=config.THEME_DATA['static_text'][text].get("TEXT"),
x=config.THEME_DATA['static_text'][text].get("X", 0),
y=config.THEME_DATA['static_text'][text].get("Y", 0),
width=config.THEME_DATA['static_text'][text].get("WIDTH", 0),
height=config.THEME_DATA['static_text'][text].get("HEIGHT", 0),
font=config.THEME_DATA['static_text'][text].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=config.THEME_DATA['static_text'][text].get("FONT_SIZE", 10),
font_color=config.THEME_DATA['static_text'][text].get("FONT_COLOR", (0, 0, 0)),
background_color=config.THEME_DATA['static_text'][text].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=_get_full_path(config.THEME_DATA['PATH'],
config.THEME_DATA['static_text'][text].get("BACKGROUND_IMAGE",
None)),
anchor="lt"
align=config.THEME_DATA['static_text'][text].get("ALIGN", "left"),
anchor=config.THEME_DATA['static_text'][text].get("ANCHOR", "lt"),
)


Expand Down
Loading

0 comments on commit ad2bc4b

Please sign in to comment.