From 6f467f31a191ca26135b89c171e51c886c59c008 Mon Sep 17 00:00:00 2001 From: Maarten Tamboer <1395437+maartentamboer@users.noreply.github.com> Date: Fri, 2 Apr 2021 15:01:42 +0200 Subject: [PATCH] Add support for automatic layer revert --- Configurations/config.json | 3 +- activelayer.py | 6 ++++ activelayerchanger.py | 70 ++++++++++++++++++++++++++++++++++++++ configfile.py | 2 ++ globalstorage.py | 10 ++++++ main.py | 5 +++ 6 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 activelayerchanger.py diff --git a/Configurations/config.json b/Configurations/config.json index bea3f33..9b187c5 100644 --- a/Configurations/config.json +++ b/Configurations/config.json @@ -20,5 +20,6 @@ "type": "Bool", "writable": false } - ] + ], + "automatic_layer_revert": 3.0 } \ No newline at end of file diff --git a/activelayer.py b/activelayer.py index b80f634..524e540 100644 --- a/activelayer.py +++ b/activelayer.py @@ -12,6 +12,7 @@ class ActiveLayer(metaclass=Singleton): def __init__(self): self._active_layer = ActiveLayerIdentifier.A self._layer_change_events = [] + self._activity_events = [] @property def active_layer(self): @@ -19,6 +20,8 @@ def active_layer(self): @active_layer.setter def active_layer(self, value: ActiveLayerIdentifier): + for x in self._activity_events: + x(value) if value != self._active_layer: print("Layer Change to", value) for x in self._layer_change_events: @@ -27,3 +30,6 @@ def active_layer(self, value: ActiveLayerIdentifier): def subscribe_to_layer_change(self, callback): self._layer_change_events.append(callback) + + def subscribe_to_activity(self, callback): + self._activity_events.append(callback) diff --git a/activelayerchanger.py b/activelayerchanger.py new file mode 100644 index 0000000..b376a61 --- /dev/null +++ b/activelayerchanger.py @@ -0,0 +1,70 @@ +from threading import Timer +import mido +import time + +from singleton import Singleton +from activelayer import ActiveLayer, ActiveLayerIdentifier + + +class RepeatedTimer(object): + def __init__(self, interval, function, *args, **kwargs): + self._timer = None + self.interval = interval + self.function = function + self.args = args + self.kwargs = kwargs + self.is_running = False + + def _run(self): + self.is_running = False + self.start() + self.function(*self.args, **self.kwargs) + + def start(self): + if not self.is_running: + self._timer = Timer(self.interval, self._run) + self._timer.start() + self.is_running = True + + def stop(self): + self._timer.cancel() + self.is_running = False + + +class ActiveLayerChanger: + def __init__(self, outport: mido.ports.BaseOutput): + self._timer = None + self._layer_revert_interval = 0.0 + self._outport = outport + self._time_of_last_activity = time.time() + ActiveLayer().subscribe_to_layer_change(self._on_layer_change) + ActiveLayer().subscribe_to_activity(self._on_activity) + + def set_active_layer(self, newlayer: ActiveLayerIdentifier): + if newlayer == ActiveLayerIdentifier.A: + msg = mido.Message('program_change', program=0) + else: + msg = mido.Message('program_change', program=1) + self._outport.send(msg) + ActiveLayer().active_layer = newlayer + + def enable_layer_revert_timer(self, interval: float): + self._time_of_last_activity = time.time() + self._timer = RepeatedTimer(0.1, self._layer_revert_timer_event) + self._layer_revert_interval = interval + + def _on_layer_change(self, newlayer): + if self._timer: + if newlayer == ActiveLayerIdentifier.B: + self._timer.start() + else: + self._timer.stop() + + def _on_activity(self, layer): + self._time_of_last_activity = time.time() + + def _layer_revert_timer_event(self): + current_time = time.time() + if current_time - self._time_of_last_activity > self._layer_revert_interval: + print("Automatic change to layer A") + self.set_active_layer(ActiveLayerIdentifier.A) diff --git a/configfile.py b/configfile.py index 55c3a6f..aa04d0b 100644 --- a/configfile.py +++ b/configfile.py @@ -27,6 +27,8 @@ def configure(self): if aircraft_contains in str(self._aircraft): config_file = file self._configure_additional_simvars(base_data) + if 'automatic_layer_revert' in base_data: + GlobalStorage().active_layer_changer.enable_layer_revert_timer(base_data['automatic_layer_revert']) config_file = 'Configurations/' + config_file # Add folder prefix print("Loading config file:", config_file) diff --git a/globalstorage.py b/globalstorage.py index e0b22f8..fd79c40 100644 --- a/globalstorage.py +++ b/globalstorage.py @@ -7,6 +7,7 @@ from pushbutton import PushButton from trigger import Trigger from fader import Fader +from activelayerchanger import ActiveLayerChanger class GlobalStorage(metaclass=Singleton): @@ -18,12 +19,14 @@ def __init__(self): self._ae = None self._aq = None self._global_variables = {} + self._active_layer_changer = None # type: ActiveLayerChanger def clear(self): self._buttons = [] self._encoders = [] self._faders = [] self._triggers = [] + self._active_layer_changer = None def add_encoder(self, encoder: RotaryEncoder): self._encoders.append(encoder) @@ -49,6 +52,9 @@ def set_global_variable(self, key: str, value): def get_global_variable(self, key: str): return self._global_variables.get(key, None) + def set_active_layer_changer(self, ac: ActiveLayerChanger): + self._active_layer_changer = ac + @property def encoders(self) -> List[RotaryEncoder]: return self._encoders @@ -76,3 +82,7 @@ def aircraft_events(self) -> AircraftEvents: @property def aircraft_requests(self) -> AircraftRequests: return self._aq + + @property + def active_layer_changer(self) -> ActiveLayerChanger: + return self._active_layer_changer diff --git a/main.py b/main.py index 6f31648..ee86676 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,7 @@ from configfile import ConfigFile from globalstorage import GlobalStorage from mocksimconnect import MockAircraftEvents, MockAircraftRequests +from activelayerchanger import ActiveLayerChanger def main_app(offline: bool): @@ -23,6 +24,8 @@ def main_app(offline: bool): global_storage.set_aircraft_events(ae) global_storage.set_aircraft_requests(aq) else: + aq = MockAircraftRequests() + ae = MockAircraftEvents() global_storage.set_aircraft_events(MockAircraftEvents()) global_storage.set_aircraft_requests(MockAircraftRequests()) @@ -66,6 +69,8 @@ def handle_message(msg: mido.Message): fader = Fader(f) global_storage.add_fader(fader) + GlobalStorage().set_active_layer_changer(ActiveLayerChanger(outport)) + c = ConfigFile(aircraft) c.configure() triggers = c.triggers