D-Bus error management

This commit is contained in:
Daniele Verducci 2024-04-26 09:20:05 +02:00
parent 7936aaf147
commit 1b3760a508
3 changed files with 59 additions and 11 deletions

View File

@ -1,5 +1,6 @@
from gi.repository import Gio, GLib
from threading import Timer
from enum import Enum
# window.py
#
@ -20,7 +21,6 @@ from threading import Timer
#
# SPDX-License-Identifier: GPL-3.0-or-later
# A timer for polling the light sensor via DBus.
# Checks the sensor at a specific interval and runs a callback only when an update is detected.
#
@ -28,17 +28,30 @@ from threading import Timer
# Instantiate it, then call run(interval_in_seconds, callback_function)
# To stop it, call cancel()
class SensorsPollingTimer(Timer):
def run(self):
# Setup
bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
self.proxy = Gio.DBusProxy.new_sync(bus,Gio.DBusProxyFlags.NONE,None,'net.hadess.SensorProxy','/net/hadess/SensorProxy','org.freedesktop.DBus.Properties', None)
self.oldValue = None
try:
bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
self.proxy = Gio.DBusProxy.new_sync(bus,Gio.DBusProxyFlags.NONE,None,'net.hadess.SensorProxy','/net/hadess/SensorProxy','org.freedesktop.DBus.Properties', None)
# Loop
while not self.finished.wait(self.interval):
value = self.proxy.Get('(ss)', 'net.hadess.SensorProxy', 'LightLevel')
if (self.oldValue != value):
self.oldValue = value
unit = self.proxy.Get('(ss)', 'net.hadess.SensorProxy', 'LightLevelUnit')
self.function(value, unit) # Invoke callback
self.oldValue = None
# Loop
while not self.finished.wait(self.interval):
value = self.proxy.Get('(ss)', 'net.hadess.SensorProxy', 'LightLevel')
if (self.oldValue != value):
self.oldValue = value
unit = self.proxy.Get('(ss)', 'net.hadess.SensorProxy', 'LightLevelUnit')
self.function(value, unit) # Invoke callback
except Exception as e:
if not self.onError:
print("SensorsPollingTimer: error occurred, but no onError callback defined")
return
self.onError(e)
def setOnErrorListener(onError):
self.onError = onError

View File

@ -25,17 +25,22 @@ from .ev_calculator import EVCalculator
class LumosWindow(Adw.ApplicationWindow):
__gtype_name__ = 'LumosWindow'
# Labels
lux_label = Gtk.Template.Child()
ev_label = Gtk.Template.Child()
error_banner = Gtk.Template.Child()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.lastError = None
# Register for window lifecycle events
self.connect("close-request", self.__on_close_request)
# Start polling sensors
self.sensorsPollingTimer = SensorsPollingTimer(0.1, self.onSensorRead)
self.sensorsPollingTimer.onError = self.onError
self.sensorsPollingTimer.start()
def __on_close_request(self, _obj: GObject.Object) -> None:
@ -52,3 +57,24 @@ class LumosWindow(Adw.ApplicationWindow):
if self.ev_label:
self.ev_label.set_label("{:.1f} EV".format(ev))
def onError(self, e: Exception):
self.lastError = e
self.error_banner.set_revealed(True)
@Gtk.Template.Callback()
def showErrorDetails(self, _button: Gtk.Button) -> None:
# Called by error_banner button click signal
if "ServiceUnknown" in self.lastError.message or "UnknownMethod" in self.lastError.message:
dialogTitle = "No light sensor found"
else:
dialogTitle = "Unable to access D-Bus"
dialog = Adw.AlertDialog(
heading = dialogTitle,
body = self.lastError,
close_response="close",
)
dialog.add_response("close", "Close")
dialog.choose(self, None, None)

View File

@ -43,6 +43,15 @@
<object class="GtkBox">
<property name="orientation">1</property>
<!-- Errors banner -->
<child>
<object class="AdwBanner" id="error_banner">
<property name="title" translatable="true">Unable to access light sensor</property>
<property name="button-label" translatable="true">Details</property>
<signal name="button-clicked" handler="showErrorDetails"/>"
</object>
</child>
<!-- Pages Stack -->
<child>
<object class="AdwViewStack" id="stack">