Files

192 lines
5.8 KiB
Python
Raw Permalink Normal View History

import sys
import os
import json
import math
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtCore import QObject, Property, Signal, Slot, QTimer
# Try importing w1thermsensor, handle failure for dev environments
try:
from w1thermsensor import W1ThermSensor, Sensor
HAS_W1 = True
except ImportError:
HAS_W1 = False
print("Warning: w1thermsensor not found. Running in simulation mode.")
from PySide6.QtCore import QObject, Property, Signal, Slot, QTimer, QThread
class SensorWorker(QObject):
tempsUpdated = Signal(float, float) # left, right
def __init__(self, config, demo_mode=False):
super().__init__()
self.config = config
self.demo_mode = demo_mode
self.running = False
self.left_sensor = None
self.right_sensor = None
self._sim_step = 0
def init_sensors(self):
if not HAS_W1:
return
print(f"Worker: Loading sensors from {self.config}")
try:
available_sensors = W1ThermSensor.get_available_sensors()
# Left Sensor
left_id = self.config.get("left_sensor_id")
if left_id:
self.left_sensor = next((s for s in available_sensors if s.id == left_id), None)
if not self.left_sensor:
# Fallback
self.left_sensor = W1ThermSensor(sensor_id=left_id)
# Auto-assign Left if missing but sensors exist
if not self.left_sensor and available_sensors:
self.left_sensor = available_sensors[0]
# Right Sensor
right_id = self.config.get("right_sensor_id")
if right_id:
self.right_sensor = W1ThermSensor(sensor_id=right_id)
except Exception as e:
print(f"Worker Error init sensors: {e}")
@Slot()
def start_polling(self):
self.running = True
self.init_sensors()
while self.running:
left_val = 0.0
right_val = 0.0
# --- Left Read ---
if self.left_sensor:
try:
left_val = self.left_sensor.get_temperature()
# print(f"L: {left_val}")
except: pass
elif self.demo_mode:
self._sim_step += 0.1
left_val = 5 + 10 * math.sin(self._sim_step)
# --- Right Read ---
if self.right_sensor:
try:
right_val = self.right_sensor.get_temperature()
except: pass
elif self.demo_mode:
right_val = 10 + 10 * math.cos(self._sim_step)
# Emit result
self.tempsUpdated.emit(left_val, right_val)
# Sleep (30 seconds)
QThread.msleep(30000)
@Slot()
def stop(self):
self.running = False
class Backend(QObject):
leftTempChanged = Signal()
rightTempChanged = Signal()
def __init__(self, demo_mode=False):
super().__init__()
self._left_temp = 0.0
self._right_temp = 0.0
# Load Config
self.config = self.load_config()
# Setup Threading
self.thread = QThread()
self.worker = SensorWorker(self.config, demo_mode)
self.worker.moveToThread(self.thread)
# Connect signals
self.thread.started.connect(self.worker.start_polling)
self.worker.tempsUpdated.connect(self.handle_temps_update)
# Start
self.thread.start()
def handle_temps_update(self, left, right):
# Update Properties (This runs on Main Thread)
if abs(self._left_temp - left) > 0.1:
self._left_temp = left
self.leftTempChanged.emit()
if abs(self._right_temp - right) > 0.1:
self._right_temp = right
self.rightTempChanged.emit()
def load_config(self):
2026-01-14 14:58:30 +01:00
# Determine path based on run mode (Script vs Frozen/Compiled)
if getattr(sys, 'frozen', False):
# If run as a compiled exe, look in the same directory as the executable
application_path = os.path.dirname(sys.executable)
else:
# If run as a script, look in the directory of the script
application_path = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(application_path, "config.json")
if os.path.exists(config_path):
try:
with open(config_path, 'r') as f:
return json.load(f)
except Exception as e:
print(f"Error loading config: {e}")
return {}
# Cleanup
def stop(self):
if self.worker:
self.worker.stop()
self.thread.quit()
self.thread.wait()
@Property(float, notify=leftTempChanged)
def leftTemp(self):
return self._left_temp
@Property(float, notify=rightTempChanged)
def rightTemp(self):
return self._right_temp
def main():
# Redirect output to log.txt
sys.stdout = open("log.txt", "w", buffering=1)
sys.stderr = sys.stdout
print("--- Volvo Display Log ---")
# Check for demo mode
demo_mode = "--demo" in sys.argv
if demo_mode:
print("Starting in DEMO MODE (Simulation Enabled)")
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
backend = Backend(demo_mode=demo_mode)
engine.rootContext().setContextProperty("backend", backend)
# Get absolute path to main.qml
current_dir = os.path.dirname(os.path.abspath(__file__))
qml_file = os.path.join(current_dir, "main.qml")
engine.load(qml_file)
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec())
if __name__ == "__main__":
main()