diff --git a/resources/qml/PixelDash.qml b/resources/qml/PixelDash.qml index 178a72d..2788635 100644 --- a/resources/qml/PixelDash.qml +++ b/resources/qml/PixelDash.qml @@ -82,7 +82,7 @@ ApplicationWindow { anchors.margins: 25 width: Math.floor((lightsController.width + 75) / 2) - 25 - sensor: (app != null) ? app.sensors.RPI : null + sensor: (app != null) ? app.sensors.RPITelemetry : null } SensorBlock { diff --git a/src/emitter_manager.py b/src/emitter_manager.py index 5a6d9eb..7dcdacf 100644 --- a/src/emitter_manager.py +++ b/src/emitter_manager.py @@ -1,41 +1,55 @@ import logging +import sys +import types -from PySide2.QtCore import QObject, Property +from PySide2.QtQml import QQmlPropertyMap -from .emitters.lights_emitter import LightsEmitter -from .emitters.gpio_emitter import GPIOEmitter -from .emitters.vcgencmd_emitter import VCGenCmdEmitter +from .emitters import * -class EmitterManager(QObject): +class EmitterManager(QQmlPropertyMap): def __init__(self): - QObject.__init__(self) - self._emitters = {} + QQmlPropertyMap.__init__(self) + + # get a list of imported emitter modules + module_dict = sys.modules["src.emitters"].__dict__ + emitter_modules = [ + module_obj + for _, module_obj in module_dict.items() + if ( + isinstance(module_obj, types.ModuleType) + and module_obj.__name__.startswith("src.emitters") + ) + ] + + for emitter_module in emitter_modules: + # get the classes defined in the module + classes = [ + emitter_obj + for (_, emitter_obj) in emitter_module.__dict__.items() + if ( + isinstance(emitter_obj, type) + and emitter_obj.__module__ == emitter_module.__name__ + ) + ] + if not classes: + continue + emitter_class = classes[0] + + # filter out super classes that should not be used on their own + class_name = emitter_class.__name__[:-7] + if class_name in [""]: + continue - def stop(self): - for name, emitter_class in self._emitters.items(): - logging.info("Closing %s emitter", name) - emitter_class.stop() - - def getSensor(self, cls): - class_name = cls.__name__ - if class_name not in self._emitters: logging.info("Creating %s emitter", class_name) - self._emitters[class_name] = cls() - self._emitters[class_name].start() - return self._emitters[class_name] - - def Lights(self) -> LightsEmitter: - return self.getSensor(LightsEmitter) - - Lights = Property(QObject, fget=Lights, constant=True) + emitter_instance = emitter_class() + emitter_instance.start() - def GPIO(self) -> GPIOEmitter: - return self.getSensor(GPIOEmitter) + self.insert(class_name, emitter_instance) - GPIO = Property(QObject, fget=GPIO, constant=True) - - def VCGenCmd(self) -> VCGenCmdEmitter: - return self.getSensor(VCGenCmdEmitter) - - VCGenCmd = Property(QObject, fget=VCGenCmd, constant=True) + def stop(self): + for key in self.keys(): + logging.info("Closing %s emitter", key) + print(self.value(key)) + self.value(key).stop() + self.clear(key) diff --git a/src/emitters/__init__.py b/src/emitters/__init__.py index e69de29..12e6da8 100644 --- a/src/emitters/__init__.py +++ b/src/emitters/__init__.py @@ -0,0 +1,5 @@ +from os.path import dirname, basename, isfile, join +import glob + +modules = glob.glob(join(dirname(__file__), "*.py")) +__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')] \ No newline at end of file diff --git a/src/sensor_manager.py b/src/sensor_manager.py index e9a74ea..d190dd2 100644 --- a/src/sensor_manager.py +++ b/src/sensor_manager.py @@ -1,65 +1,57 @@ import logging +import sys +import types -from PySide2.QtCore import QObject, Property +from PySide2.QtQml import QQmlPropertyMap -from .sensors.spacestate_sensor import SpaceStateSensor -from .sensors.weather_sensor import WeatherSensor -from .sensors.ikea_sensor import IKEASensor -from .sensors.tasmota2_sensor import Tasmota2Sensor -from .sensors.jim_sensor import JimSensor -from .sensors.pim_sensor import PimSensor -from .sensors.rpi_telemetry_sensor import RPITelemetrySensor +from .sensors import * -class SensorManager(QObject): +class SensorManager(QQmlPropertyMap): def __init__(self): - QObject.__init__(self) - self._sensors = {} + QQmlPropertyMap.__init__(self) + + # get a list of imported sensor modules + module_dict = sys.modules["src.sensors"].__dict__ + sensor_modules = [ + module_obj + for _, module_obj in module_dict.items() + if ( + isinstance(module_obj, types.ModuleType) + and module_obj.__name__.startswith("src.sensors") + ) + ] + + for sensor_module in sensor_modules: + # get the classes defined in the module + classes = [ + sensor_obj + for (_, sensor_obj) in sensor_module.__dict__.items() + if ( + isinstance(sensor_obj, type) + and sensor_obj.__module__ == sensor_module.__name__ + ) + ] + if not classes: + continue + sensor_class = classes[0] + + # filter out super classes that should not be used on their own + class_name = sensor_class.__name__[:-6] + if class_name in ["", "REST", "CommandLine"]: + continue + + logging.info("Creating %s sensor", class_name) + sensor_instance = sensor_class() + sensor_instance.start() + + self.insert(class_name, sensor_instance) def stop(self): - for name, sensor_class in self._sensors.items(): - logging.info("Closing %s sensor", name) - sensor_class.stop() - - def getSensor(self, cls): - name = cls.__name__ - if name not in self._sensors: - logging.info("Creating %s sensor", name) - self._sensors[name] = cls() - self._sensors[name].start() - return self._sensors[name] - - def SpaceState(self) -> SpaceStateSensor: - return self.getSensor(SpaceStateSensor) - - SpaceState = Property(QObject, fget=SpaceState, constant=True) - - def Weather(self) -> WeatherSensor: - return self.getSensor(WeatherSensor) - - Weather = Property(QObject, fget=Weather, constant=True) - - def IKEA(self) -> IKEASensor: - return self.getSensor(IKEASensor) - - IKEA = Property(QObject, fget=IKEA, constant=True) - - def Tasmota2(self) -> Tasmota2Sensor: - return self.getSensor(Tasmota2Sensor) - - Tasmota2 = Property(QObject, fget=Tasmota2, constant=True) - - def Jim(self) -> JimSensor: - return self.getSensor(JimSensor) - - Jim = Property(QObject, fget=Jim, constant=True) - - def Pim(self) -> PimSensor: - return self.getSensor(PimSensor) - - Pim = Property(QObject, fget=Pim, constant=True) - - def RPI(self) -> RPITelemetrySensor: - return self.getSensor(RPITelemetrySensor) - - RPI = Property(QObject, fget=RPI, constant=True) + for key in self.keys(): + logging.info("Closing %s sensor", key) + try: + self.value(key).stop() + except AttributeError: + pass + self.clear(key) diff --git a/src/sensors/__init__.py b/src/sensors/__init__.py index e69de29..12e6da8 100644 --- a/src/sensors/__init__.py +++ b/src/sensors/__init__.py @@ -0,0 +1,5 @@ +from os.path import dirname, basename, isfile, join +import glob + +modules = glob.glob(join(dirname(__file__), "*.py")) +__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')] \ No newline at end of file