class ConditionalRunner: def __init__(self, template): template_str = "".join(template) self._template = env.from_string(template_str) self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests def get_simvar_value(self, name: str): value = self._aq.get(name) return value def set_simvar_value(self, name: str, value): self._aq.set(name, value) def trigger_event(self, name: str, value): self._ae.find(name)(int(value)) @staticmethod def trigger_encoder_alternate(index: int, value: bool): GlobalStorage().encoders[index - 1].on_alternate(value) def execute(self): self._template.render(data=self) def __call__(self, *args, **kwargs): self.execute()
def __init__(self, template, file=None): self._template_str = "".join(template) if file: with open(f"Configurations/{file}", 'r') as file: self._template_str = file.read() self._template = env.from_string(self._template_str) self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests
class ConditionalRunner: def __init__(self, template): self._template_str = "".join(template) self._template = env.from_string(self._template_str) self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests def get_simvar_value(self, name: str): value = self._aq.get(name) return value def set_simvar_value(self, name: str, value): self._aq.set(name, value) def trigger_event(self, name: str, value): self._ae.find(name)(int(value)) @staticmethod def trigger_encoder_alternate(index: int, value: bool): GlobalStorage().encoders[index - 1].on_alternate(value) @staticmethod def set_global_variable(key: str, value): GlobalStorage().set_global_variable(key, value) @staticmethod def get_global_variable(key: str): return GlobalStorage().get_global_variable(key) @staticmethod def print(data): print(data) @staticmethod def set_button_led(index: int, on: bool, blink=False): GlobalStorage().buttons[index - 1].set_led_on_off(on, blink) @staticmethod def set_encoder_led(index: int, on: bool, blink=False): GlobalStorage().encoders[index - 1].set_led_ring_on_off(on, blink) @staticmethod def set_encoder_led_value(index: int, value: int, blink=False): GlobalStorage().encoders[index - 1].set_led_ring_value( int(value), blink) def execute(self): try: self._template.render(data=self) except Exception as e: print('Exception during execution of template:', e) print('For template:', self._template_str) def __call__(self, *args, **kwargs): self.execute()
class Initialization: def __init__(self, json_data): self._global_storage = GlobalStorage() if json_data: self._global_variables(json_data.get('global_variables', None)) def _global_variables(self, json_data): if not json_data: return for elem in json_data: self._global_storage.set_global_variable(elem['name'], elem['value'])
def __init__(self, event_name, event_type="auto", value=0): self._event_name = event_name self._event_type = event_type self._value = value self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests self._event = None if event_type == "manual": self._event = Event(event_name.encode(), self._ae.sm) # manual event with forced value elif event_type == "condition": self._event = ConditionalRunner(event_name) else: self._event = self._ae.find(event_name) # auto find event
class SingleEvent: def __init__(self, event_name, event_type="auto", value=0): self._event_name = event_name self._event_type = event_type self._value = value self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests self._event = None if event_type == "manual": self._event = Event(event_name.encode(), self._ae.sm) # manual event with forced value elif event_type == "condition": self._event = ConditionalRunner(event_name) elif event_type == "condition-file": self._event = ConditionalRunner("", event_name) else: self._event = self._ae.find(event_name) # auto find event if self._event is None: print( f"WARNING: Event {event_name}, was not found in simconnect list. Using a manual binding" ) self._event = Event(event_name.encode(), self._ae.sm) def __call__(self, value=0): if self._event_type == "manual": self._event(self._value) else: self._event(value)
def __init__(self, aircraft): self._encoders = GlobalStorage().encoders self._buttons = GlobalStorage().buttons self._faders = GlobalStorage().faders self._triggers = GlobalStorage().triggers self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests self._aircraft = aircraft
def configure(self): with open('Configurations/config.json') as base_json_file: base_data = json.load(base_json_file) config_file = base_data['default'] for elem in base_data['aircraft']: aircraft_contains = elem['aircraft_contains'] file = elem['file'] 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) with open(config_file) as json_file: data = json.load(json_file) self._configure_encoders(data['encoders']) self._configure_buttons(data['buttons']) self._configure_faders(data['faders']) self._configure_triggers(data['triggers']) Initialization(data.get('initialization', None))
def trigger_encoder_alternate(index: int, value: bool): GlobalStorage().encoders[index - 1].on_alternate(value)
class ConfigFile: def __init__(self, aircraft): self._encoders = GlobalStorage().encoders self._buttons = GlobalStorage().buttons self._faders = GlobalStorage().faders self._triggers = GlobalStorage().triggers self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests self._aircraft = aircraft def configure(self): with open('Configurations/config.json') as base_json_file: base_data = json.load(base_json_file) config_file = base_data['default'] for elem in base_data['aircraft']: aircraft_contains = elem['aircraft_contains'] file = elem['file'] if aircraft_contains in str(self._aircraft): config_file = file config_file = 'Configurations/' + config_file # Add folder prefix print("Loading config file:", config_file) with open(config_file) as json_file: data = json.load(json_file) self._configure_encoders(data['encoders']) self._configure_buttons(data['buttons']) self._configure_faders(data['faders']) self._configure_triggers(data['triggers']) @property def triggers(self): return self._triggers def _create_binding(self, obj, events): # Support multiple events for one binding event_queue = EventQueue() # Check for multiple events by checking for a list if isinstance(events, list): for event in events: event_queue.add(self._create_single_binding(obj, event)) else: event_queue.add(self._create_single_binding(obj, events)) return event_queue @staticmethod def _create_single_binding(obj, event): if isinstance( event, str): # if event is single STRING in JSON: "AP_ALT_VAR_INC" if event == "{alternate}": return obj.on_alternate_toggle return SingleEvent(event) event_name = event.get('event') event_type = event.get('type') event_value = event.get('value', None) return SingleEvent(event_name, event_type, event_value) def _configure_encoders(self, data): for elem in data: # print(elem) index = elem['index'] event_up = elem.get('event_up') event_down = elem.get('event_down') alternate_event_up = elem.get('alternate_event_up') alternate_event_down = elem.get('alternate_event_down') event_press = elem.get('event_press') event_short_press = elem.get('event_short_press') event_long_press = elem.get('event_long_press') encoder = self._encoders[index - 1] if event_up and event_down: encoder.bind_to_event( self._create_binding(encoder, event_up), self._create_binding(encoder, event_down)) if alternate_event_up and alternate_event_down: encoder.bind_to_alternate_event( self._create_binding(encoder, alternate_event_up), self._create_binding(encoder, alternate_event_down)) if event_press: encoder.bind_press(self._create_binding(encoder, event_press)) if event_short_press: encoder.bind_short_press( self._create_binding(encoder, event_short_press)) if event_long_press: encoder.bind_long_press( self._create_binding(encoder, event_long_press)) def _configure_buttons(self, data): for elem in data: # print(elem) index = elem['index'] event_press = elem.get('event_press') event_short_press = elem.get('event_short_press') event_long_press = elem.get('event_long_press') simvar_led = elem.get('simvar_led') button = self._buttons[index - 1] if event_press: button.bind_press(self._create_binding(button, event_press)) if event_short_press: button.bind_short_press( self._create_binding(button, event_short_press)) if event_long_press: button.bind_long_press( self._create_binding(button, event_long_press)) if simvar_led: button.bind_led_to_simvar(simvar_led) def _configure_faders(self, data): for elem in data: # print(elem) index = elem['index'] event_change = elem['event_change'] min_value = elem['min_value'] max_value = elem['max_value'] fader = self._faders[index - 1] fader.bind_to_event(self._create_binding(fader, event_change), min_value, max_value) def _configure_triggers(self, data): for elem in data: # print(elem) simvar = elem.get('simvar') trigger_type = elem.get('trigger_type', None) trigger_index = elem.get('trigger_index', None) condition = elem.get('condition', None) object_to_trigger = None trigger = Trigger() trigger.bind_to_simvar(simvar) if condition: trigger.bind_to_event(ConditionalRunner(condition)) else: if trigger_type == "encoder": object_to_trigger = self._encoders[trigger_index - 1] elif trigger_type == "button": object_to_trigger = self._buttons[trigger_index - 1] else: raise ValueError(f"Unknown trigger type: {trigger_type}") trigger.bind_to_event(object_to_trigger.on_alternate) self._triggers.append(trigger)
def __init__(self, template): self._template_str = "".join(template) self._template = env.from_string(self._template_str) self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests
def set_encoder_led(index: int, on: bool, blink=False): GlobalStorage().encoders[index - 1].set_led_ring_on_off(on, blink)
def set_encoder_led_value(index: int, value: int, blink=False): GlobalStorage().encoders[index - 1].set_led_ring_value( int(value), blink)
def get_global_variable(key: str): return GlobalStorage().get_global_variable(key)
def set_button_led(index: int, on: bool, blink=False): GlobalStorage().buttons[index - 1].set_led_on_off(on, blink)
def set_global_variable(key: str, value): GlobalStorage().set_global_variable(key, value)
class ConfigFile: def __init__(self, aircraft): self._encoders = GlobalStorage().encoders self._buttons = GlobalStorage().buttons self._faders = GlobalStorage().faders self._triggers = GlobalStorage().triggers self._ae = GlobalStorage().aircraft_events self._aq = GlobalStorage().aircraft_requests self._aircraft = aircraft def configure(self): with open('Configurations/config.json') as base_json_file: base_data = json.load(base_json_file) config_file = base_data['default'] for elem in base_data['aircraft']: aircraft_contains = elem['aircraft_contains'] file = elem['file'] 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) with open(config_file) as json_file: data = json.load(json_file) self._configure_encoders(data['encoders']) self._configure_buttons(data['buttons']) self._configure_faders(data['faders']) self._configure_triggers(data['triggers']) Initialization(data.get('initialization', None)) @staticmethod def get_midi_input() -> str: with open('Configurations/config.json') as base_json_file: base_data = json.load(base_json_file) return base_data.get('midi_input_device', 'X-TOUCH MINI 0') @staticmethod def get_midi_output() -> str: with open('Configurations/config.json') as base_json_file: base_data = json.load(base_json_file) return base_data.get('midi_output_device', 'X-TOUCH MINI 1') @property def triggers(self): return self._triggers def _create_binding(self, obj, events): # Support multiple events for one binding event_queue = EventQueue() # Check for multiple events by checking for a list if isinstance(events, list): for event in events: event_queue.add(self._create_single_binding(obj, event)) else: event_queue.add(self._create_single_binding(obj, events)) return event_queue @staticmethod def _create_single_binding(obj, event): if isinstance( event, str): # if event is single STRING in JSON: "AP_ALT_VAR_INC" if event == "{alternate}": return obj.on_alternate_toggle return SingleEvent(event) event_name = event.get('event') event_type = event.get('type') event_value = event.get('value', None) return SingleEvent(event_name, event_type, event_value) def _configure_encoders(self, data): for enc in self._encoders: enc.reset_configuration() for elem in data: # print(elem) index = elem['index'] event_up = elem.get('event_up') event_down = elem.get('event_down') alternate_event_up = elem.get('alternate_event_up') alternate_event_down = elem.get('alternate_event_down') event_press = elem.get('event_press') event_short_press = elem.get('event_short_press') event_long_press = elem.get('event_long_press') encoder = self._encoders[index - 1] if event_up and event_down: encoder.bind_to_event( self._create_binding(encoder, event_up), self._create_binding(encoder, event_down)) if alternate_event_up and alternate_event_down: encoder.bind_to_alternate_event( self._create_binding(encoder, alternate_event_up), self._create_binding(encoder, alternate_event_down)) if event_press: encoder.bind_press(self._create_binding(encoder, event_press)) if event_short_press: encoder.bind_short_press( self._create_binding(encoder, event_short_press)) if event_long_press: encoder.bind_long_press( self._create_binding(encoder, event_long_press)) def _configure_buttons(self, data): for btn in self._buttons: btn.reset_configuration() for elem in data: # print(elem) index = elem['index'] event_press = elem.get('event_press') event_short_press = elem.get('event_short_press') event_long_press = elem.get('event_long_press') simvar_led = elem.get('simvar_led') mobiflightsimvar_led = elem.get('mobiflightsimvar_led') button = self._buttons[index - 1] if event_press: button.bind_press(self._create_binding(button, event_press)) if event_short_press: button.bind_short_press( self._create_binding(button, event_short_press)) if event_long_press: button.bind_long_press( self._create_binding(button, event_long_press)) if simvar_led: button.bind_led_to_simvar(simvar_led) if mobiflightsimvar_led: button.bind_led_to_mobiflightsimvar(mobiflightsimvar_led) def _configure_faders(self, data): for fad in self._faders: fad.reset_configuration() for elem in data: # print(elem) index = elem['index'] event_change = elem['event_change'] min_value = elem['min_value'] max_value = elem['max_value'] fader = self._faders[index - 1] fader.bind_to_event(self._create_binding(fader, event_change), min_value, max_value) def _configure_triggers(self, data): for trig in self._triggers: trig.reset_configuration() self._triggers.clear() for elem in data: # print(elem) simvar = elem.get('simvar') trigger_type = elem.get('trigger_type', None) trigger_index = elem.get('trigger_index', None) condition = elem.get('condition', None) object_to_trigger = None trigger = Trigger() trigger.bind_to_simvar(simvar) if trigger_type == "encoder": object_to_trigger = self._encoders[trigger_index - 1] trigger.bind_to_event(object_to_trigger.on_alternate) elif trigger_type == "button": object_to_trigger = self._buttons[trigger_index - 1] elif trigger_type == "condition": trigger.bind_to_event(ConditionalRunner(condition)) elif trigger_type == "condition-file": trigger.bind_to_event(ConditionalRunner("", condition)) else: raise ValueError(f"Unknown trigger type: {trigger_type}") self._triggers.append(trigger) def _configure_additional_simvars(self, data): if 'additional_simvars' in data: helper = RequestList.RequestHelper(self._aq.sm) helper.list = {} for elem in data['additional_simvars']: writable = 'N' if elem['writable']: writable = 'y' simvar_elem = [ elem['description'], elem['simvar'].encode(), elem['type'].encode(), writable ] helper.list[elem['name']] = simvar_elem if helper not in self._aq.list: self._aq.list.append(helper)
def get_mobiflight_value(self, name: str): #Add MobiFlight value = GlobalStorage().get_mobiflight_variable(name) #print(name,value) return value
def main_app(offline: bool): global_storage = GlobalStorage() sm = None aq = None ae = None if not offline: sm = SimConnect() aq = AircraftRequests(sm, _time=200) ae = AircraftEvents(sm) global_storage.set_aircraft_events(ae) global_storage.set_aircraft_requests(aq) else: global_storage.set_aircraft_events(MockAircraftEvents()) global_storage.set_aircraft_requests(MockAircraftRequests()) aircraft = aq.get('TITLE') print("Current aircraft:", aircraft) outport = mido.open_output('X-TOUCH MINI 1') # pylint: disable=no-member control_change_dict = {} note_dict = {} def handle_message(msg: mido.Message): # print(msg) if msg.type == 'control_change': if msg.control in control_change_dict: control_change_dict[msg.control].on_cc_data(msg.value) elif msg.type == 'note_on': if msg.note in note_dict: note_dict[msg.note].on_note_data(True) elif msg.type == 'note_off': if msg.note in note_dict: note_dict[msg.note].on_note_data(False) inport = mido.open_input('X-TOUCH MINI 0', callback=handle_message) # pylint: disable=no-member for e in range(1, 17): encoder = RotaryEncoder(e, outport) global_storage.add_encoder(encoder) for b in range(1, 33): btn = PushButton(b, outport) global_storage.add_button(btn) for f in range(1, 3): fader = Fader(f) global_storage.add_fader(fader) c = ConfigFile(aircraft) c.configure() triggers = c.triggers for encoder in GlobalStorage().encoders: control_change_dict[encoder.rotary_control_channel] = encoder note_dict[encoder.button_note] = encoder for btn in GlobalStorage().buttons: note_dict[btn.button_note] = btn for f in GlobalStorage().faders: control_change_dict[f.control_channel] = f triggers[0].on_simvar_data(1.0) while True: for obj in GlobalStorage().all_elements: if obj.bound_simvar and aq: sv = aq.get(obj.bound_simvar) obj.on_simvar_data(sv) current_aircraft = aq.get('TITLE') if current_aircraft and aircraft != current_aircraft: print("Aircraft changed from", aircraft, "to", current_aircraft) break time.sleep(0.05) global_storage.clear() inport.close() outport.close()
def __init__(self, json_data): self._global_storage = GlobalStorage() if json_data: self._global_variables(json_data.get('global_variables', None))