Ejemplo n.º 1
0
 def __init__(self):  # "nie"konstruktor, inicjalizator obiektu usługi
     super(MasterService, self).__init__(
     )  # wywołanie metody inicjalizatora klasy nadrzędnej
     self.service_lock = threading.RLock(
     )  # obiekt pozwalający na blokadę wątku
     self.service_params = ServicesParameters(
     )  # obiekt do pobierania nazw serwisów, które podłączone są do serwisu master i ich konektorów
Ejemplo n.º 2
0
    def __init__(self):			#"nie"konstruktor, inicjalizator obiektu usługi
        super(InputService, self).__init__() #wywołanie metody inicjalizatora klasy nadrzędnej

        self.service_params = ServicesParameters()
        self.webCam = cv2.VideoCapture(0) # strumien z kamery wideo
        self.service_lock = threading.RLock() #obiekt pozwalający na blokadę wątku

        self.app = Application()
Ejemplo n.º 3
0
    def __init__(self): # "nie"konstruktor, inicjalizator obiektu usługi
        super(MasterService, self).__init__() # wywołanie metody inicjalizatora klasy nadrzędnej
        self.service_lock = threading.RLock() # obiekt pozwalający na blokadę wątku
        self.service_params = ServicesParameters() # obiekt do pobierania nazw serwisów, które podłączone są do serwisu master i ich konektorów
        self.next_services = {} # słownik, którego elementy maja następujący format: { nazwa_serwisu_1 : nazwa_serwisu_2 }, gdzie nazwa_serwisu_2 jest stringiem określającym serwis, do którego zostaje przesłany obraz po powrocie do mastera z serwisu określonego jako nazwa_serwisu_1. Zmienna ta bezpośrednio określa kolejność wykonywania poszczególnych serwisów.
        self.video_frames = {}  # słownik z elementami formatu: { nazwa_serwisu : obraz_z_kamery } - zawiera zrzuty z ekranu, które mają być przesyłane do poszczególnych serwisów określonych jako string nazwa_serwisu
        self.settings = {}  # słownik z elementami formatu: { nazwa_serwisu : słownik_z_ustawieniami } - zawiera ustawienia, które mają być przesłane do kolejnych serwisów określonych jako nazwa_serwisu

        self.__prepare_instance()   # przygotowanie zmiennych self.next_services, self.video_frames i self.settings - należy dodać odpowiednie klucze (nazwy serwisów) w słownikach
Ejemplo n.º 4
0
    def __init__(self):  #"nie"konstruktor, inicjalizator obiektu usługi
        super(
            InputService,
            self).__init__()  #wywołanie metody inicjalizatora klasy nadrzędnej

        self.service_params = ServicesParameters()
        self.webCam = cv2.VideoCapture(0)  # strumien z kamery wideo
        self.service_lock = threading.RLock(
        )  #obiekt pozwalający na blokadę wątku

        # pola do określania, które serwisy zostały wybrane (domyślnie wyłączone)
        self.preprocessing_service = 1  # preprocessing service ma byc wykonywany zawsze
        self.resize_service = 0
        self.filter_gray_service = 0

        # parametry dla poszczególnych serwisów
        self.resize_coeff = 1  # wspołczynnik skalowania (resize service)

        self.app = Application()
Ejemplo n.º 5
0
class MasterService(Service):
    def __init__(self):  # "nie"konstruktor, inicjalizator obiektu usługi
        super(MasterService, self).__init__(
        )  # wywołanie metody inicjalizatora klasy nadrzędnej
        self.service_lock = threading.RLock(
        )  # obiekt pozwalający na blokadę wątku
        self.service_params = ServicesParameters(
        )  # obiekt do pobierania nazw serwisów, które podłączone są do serwisu master i ich konektorów

    def declare_outputs(self):  # deklaracja wyjść
        service_names = self.service_params.getAllServiceNames(
        )  # pobieram nazwy wszystkich serwisów, jakie będą podłączone do serwisu master (na ich podstawie są pobierane nazy konektorów)
        for service in service_names:
            connector_name = self.service_params.getOutputVideoConnectorName(
                service
            )  # pobieram nazwę konektora wyjściowego dla obrazu video
            self.declare_output(
                connector_name,
                OutputMessageConnector(self))  # deklaracja konektora
            if service != self.service_params.MASTER_SERVICE:  # wszystkie serwisy oprócz samego serwisu master mają konektor wyjściowy z ustawieniami
                connector_name = self.service_params.getOutputSettingsConnectorName(
                    service
                )  # pobieram nazwę konektora wyjściowego dla ustawień przetwarzania
                self.declare_output(
                    connector_name,
                    OutputObjectConnector(self))  # deklaracja konektora

    def declare_inputs(self):  #deklaracja wejść
        service_names = self.service_params.getAllServiceNames(
        )  # pobieram nazwy wszystkich serwisów, jakie będą podłączone do serwisu master (na ich podstawie są pobierane nazy konektorów)
        for service in service_names:
            connector_name = self.service_params.getInputVideoConnectorName(
                service
            )  # pobieram nazwę konektora wejściowego dla obrazu video
            self.declare_input(
                connector_name,
                InputMessageConnector(self))  # deklaracja konektora
            connector_name = self.service_params.getInputSettingsConnectorName(
                service
            )  # pobieram nazwę konektora wejściowego dla ustawień przetwarzania
            self.declare_input(
                connector_name,
                InputObjectConnector(self))  # deklaracja konektora

    def watch_services(
        self, str_settingsInput, str_videoInput
    ):  # metoda obsługująca wejścia i wyjścia poszczególnych serwisów podrzędnych, które podłączone są do mastera
        # Bezpośrednio deklaruje tylko interfejsy wejściowe, bo to jaki będzie inerefejs wyjściowy (czyli jaki serwis podrzędny przetwarzający obraz będzie wykonwany jako kolejny) zależy od przesłanych ustawień. Więc program musi sam wybrać, gdzie dalej przesłać obraz i dalsze ustawienia
        settings_input = self.get_input(
            str_settingsInput)  # obiekt interfejsu wejściowego
        video_input = self.get_input(str_videoInput)

        while self.running():  #główna pętla wątku

            try:
                settings = settings_input.read(
                )  #odczyt danych z interfejsu wejściowego
            except:
                # jeśli nie da się odczytać danych to prawdopodobnie połączenie na sockecie zostało przerwane, więc je zamykam. Połączenie zostaje odtworzone przy kolejnej próbie odczytu danych (wynika z implementacji konektorów
                settings_input.close()

            current_services = settings.get(
                'servicesApplied', {}
            )  # lista serwisów, które należy wykorzystać. Zawiera numery ID, które określone są w klasie ServiceParameters, zmiennej SERVICES_ID

            if current_services:  # jeśli lista serwisów nie jest pusta, to trzeba przekazac dane do kolejnego serwisu
                service_value = current_services.pop(
                    0
                )  # biorę pierwszy element z listy serwisow - ta usługa będzie aktualnie zastosowana
                settings[
                    'servicesApplied'] = current_services  # aktualizuję ogólne ustawienia z usuniętym pierwszym elementem

                service_name = self.service_params.getServiceName(
                    service_value
                )  # pobieram nazwę serwisu, jaki ma być teraz wykonany
                output_settings_connector = self.service_params.getOutputSettingsConnectorName(
                    service_name
                )  # pobieram nazwę konektora wyjściowego dla ustawień przetwarzania
                settings_output = self.get_output(
                    output_settings_connector
                )  # pobieram obiekt interfejsu wyjściowego dla ustawień
                try:
                    settings_output.send(
                        settings
                    )  # przesłanie danych za pomocą interfejsu wyjściowego
                except:
                    settings_output.close(
                    )  # zamknięcie socketa - będzie odtworzone w kolejnej próbie (jak wyżej)
            else:  # jeśli lista serwisów jest pusta, to znaczy ze wszystkie operacje przetwarzania obrazu zostały wykonane i można przesłac obraz na wyjście, więc aktualnym konektorem wyjściowym będzie konektor mastera
                service_name = self.service_params.MASTER_SERVICE

            try:
                frame_obj = video_input.read(
                )  # odebranie danych z interfejsu wejściowego dla obrazu
            except:
                video_input.close(
                )  # zamknięcie socketa - będzie odtworzone w kolejnej próbie (jak wyżej)

            frame = np.loads(frame_obj)  # załadowanie ramki do obiektu NumPy
            output_video_connector = self.service_params.getOutputVideoConnectorName(
                service_name
            )  # pobieram nazwę konektora wyjściowego dla obrazu
            video_output = self.get_output(
                output_video_connector
            )  # pobieram obiekt interfejsu wyjściowego dla obrazu
            try:
                video_output.send(frame.dumps(
                ))  # przesłanie danych za pomocą interfejsu wyjściowego
            except:
                video_output.close(
                )  # zamknięcie socketa - będzie odtworzone w kolejnej próbie (jak wyżej)

    def run(self):  # główna metoda usługi
        # Uruchamiam w odzielnych wątkach metody obsługujące wejścia i wyjścia serwisów podrzędnych, które podłączone są do mastera
        for service_name in self.service_params.getAllServiceNames():
            input_settings_connector = self.service_params.getInputSettingsConnectorName(
                service_name
            )  # pobieram nazwę konektora wejściowego serwisu podrzędnego (wejście ustawień)
            input_video_connector = self.service_params.getInputVideoConnectorName(
                service_name
            )  # pobieram nazwę konektora wejściowego serwisu podrzędnego (wejście obrazu)
            threading.Thread(target=lambda: self.watch_services(
                input_settings_connector, input_video_connector
            )).start(
            )  #uruchomienie wątku obsługującego wejścia i wyjścia dla serwisu podrzędnego

        while self.running():
            None
Ejemplo n.º 6
0
class InputService(Service): #klasa usługi musi dziedziczyć po ComssServiceDevelopment.service.Service
    def __init__(self):			#"nie"konstruktor, inicjalizator obiektu usługi
        super(InputService, self).__init__() #wywołanie metody inicjalizatora klasy nadrzędnej

        self.service_params = ServicesParameters()
        self.webCam = cv2.VideoCapture(0) # strumien z kamery wideo
        self.service_lock = threading.RLock() #obiekt pozwalający na blokadę wątku

        self.app = Application()

    def declare_outputs(self):	#deklaracja wyjść
        self.declare_output("videoOutput", OutputMessageClientConnector(self))
        self.declare_output("settingsOutput", OutputObjectClientConnector(self))

    def declare_inputs(self): #deklaracja wejść
        pass

    def run_app_gui(self):
        self.app.master.title('Input settings')
        self.app.mainloop()
        os.kill(os.getpid(),signal.SIGTERM)

    def send_settings(self):
        settings_output = self.get_output("settingsOutput") # obiekt interfejsu wyjściowego dla ustawień

        while self.running():
            with self.service_lock:     #blokada wątku
                # pobieram wartości widgetów z interfejsu graficznego
                resize_service = self.app.var_checkbox_resize.get()
                filter_gray_service = self.app.var_checkbox_filterGray.get()
                resize_coeff = self.app.var_scale_resize.get()

            # Określam, które serwisy trzeba zastosować - dodaje do kolekcji numery ID poszczególnych serwisów, które należy wykonać
            services_applied = set()
            services_applied.add(self.service_params.getServiceValue(self.service_params.PREPROCESSING_SERVICE)) # serwis preprocessingu wykonywany jest zawsze
            if resize_service:
                services_applied.add(self.service_params.getServiceValue(self.service_params.RESIZE_SERVICE))
            if filter_gray_service:
                services_applied.add(self.service_params.getServiceValue(self.service_params.FILTER_GRAY_SERVICE))

            # Tworzę słownik z ustawieniami, który będzie przesłany do serwisu master
            settings = {'servicesApplied': list(services_applied),
                        'resizeCoeff': resize_coeff}

            settings_output.send(settings) # wysłanie ustawień do serwisu master
            #print "ustawienia wysłane:", settings

            time.sleep(0.05)

    def send_video(self):
        video_output = self.get_output("videoOutput") # obiekt interfejsu wyjściowego dla obrazu

        while self.running():

            _, frame = self.webCam.read() # odczyt obrazu z kamery
            frame_dump = frame.dumps() # zrzut ramki wideo do postaci ciągu bajtow

            video_output.send(frame_dump) # przesłanie ramki video do serwisu master
            #print "ramka wysłana"
            time.sleep(0.05)

    def run(self):	#główna metoda usługi
        threading.Thread(target=self.run_app_gui).start() # W oddzielnym wątku uruchamiam aplikację z iterfejsem graficzynym
        threading.Thread(target=self.send_settings).start()
        threading.Thread(target=self.send_video).start()

        while self.running():   # pętla główna usługi
            pass
Ejemplo n.º 7
0
class MasterService(Service):
    def __init__(self): # "nie"konstruktor, inicjalizator obiektu usługi
        super(MasterService, self).__init__() # wywołanie metody inicjalizatora klasy nadrzędnej
        self.service_lock = threading.RLock() # obiekt pozwalający na blokadę wątku
        self.service_params = ServicesParameters() # obiekt do pobierania nazw serwisów, które podłączone są do serwisu master i ich konektorów
        self.next_services = {} # słownik, którego elementy maja następujący format: { nazwa_serwisu_1 : nazwa_serwisu_2 }, gdzie nazwa_serwisu_2 jest stringiem określającym serwis, do którego zostaje przesłany obraz po powrocie do mastera z serwisu określonego jako nazwa_serwisu_1. Zmienna ta bezpośrednio określa kolejność wykonywania poszczególnych serwisów.
        self.video_frames = {}  # słownik z elementami formatu: { nazwa_serwisu : obraz_z_kamery } - zawiera zrzuty z ekranu, które mają być przesyłane do poszczególnych serwisów określonych jako string nazwa_serwisu
        self.settings = {}  # słownik z elementami formatu: { nazwa_serwisu : słownik_z_ustawieniami } - zawiera ustawienia, które mają być przesłane do kolejnych serwisów określonych jako nazwa_serwisu

        self.__prepare_instance()   # przygotowanie zmiennych self.next_services, self.video_frames i self.settings - należy dodać odpowiednie klucze (nazwy serwisów) w słownikach

    def __prepare_instance(self):
        services_names = self.service_params.getAllServiceNames() # pobranie nazw wszsytkich serwisów podpiętych do mastera
        for service in services_names:
            self.next_services[service] = None
            self.video_frames[service] = None
            self.settings[service] = None

    def declare_outputs(self):	# deklaracja wyjść
        service_names = self.service_params.getAllServiceNames() # pobieram nazwy wszystkich serwisów, jakie będą podłączone do serwisu master (na ich podstawie są pobierane nazy konektorów)
        for service in service_names:
            connector_name = self.service_params.getOutputVideoConnectorName(service) # pobieram nazwę konektora wyjściowego dla obrazu video
            self.declare_output(connector_name, OutputMessageServerConnector(self)) # deklaracja konektora
            connector_name = self.service_params.getOutputSettingsConnectorName(service) # pobieram nazwę konektora wyjściowego dla ustawień przetwarzania
            self.declare_output(connector_name, OutputObjectServerConnector(self)) # deklaracja konektora

    def declare_inputs(self): #deklaracja wejść
        service_names = self.service_params.getAllServiceNames() # pobieram nazwy wszystkich serwisów, jakie będą podłączone do serwisu master (na ich podstawie są pobierane nazy konektorów)
        for service in service_names:
            connector_name = self.service_params.getInputVideoConnectorName(service) # pobieram nazwę konektora wejściowego dla obrazu video
            self.declare_input(connector_name, InputMessageServerConnector(self)) # deklaracja konektora
            connector_name = self.service_params.getInputSettingsConnectorName(service) # pobieram nazwę konektora wejściowego dla ustawień przetwarzania
            self.declare_input(connector_name, InputObjectServerConnector(self)) # deklaracja konektora

    def read_settings(self, service_name, str_settingsInput):
        settings_input = self.get_input(str_settingsInput) # obiekt interfejsu wejściowego

        while self.running():

            settings = settings_input.read() #odczyt danych z interfejsu wejściowego
            #print service_name, ": odebrano ustwienia:", settings
            services_to_apply = settings['servicesApplied'] # lista serwisów, które należy wykorzystać. Zawiera numery ID, które określone są w klasie ServiceParameters, zmiennej SERVICES_ID

            if services_to_apply: # jeśli lista serwisów nie jest pusta, to trzeba przekazac dane do kolejnego serwisu
                next_service_value = services_to_apply.pop(0) # biorę pierwszy element z listy serwisow - ta usługa będzie aktualnie zastosowana
            else: # jeśli lista serwisów jest pusta, to trzeba przekazać obraz na wyjście mastera
                next_service_value = self.service_params.getServiceValue(self.service_params.MASTER_SERVICE)

            next_service_name = self.service_params.getServiceName(next_service_value)
            settings['servicesApplied'] = services_to_apply # aktualizuję ogólne ustawienia z usuniętym pierwszym elementem

            with self.service_lock:
                self.settings[next_service_name] = settings
                self.next_services[service_name] = next_service_name

    def send_settings(self, service_name, str_settingsOutput):
        settings_output = self.get_output(str_settingsOutput)

        while self.running():
            if not self.settings[service_name] is None:
                settings_output.send(self.settings[service_name])
                #print service_name, ": ustawienia wysłane"
                with self.service_lock:
                    self.settings[service_name] = None

    def read_video(self, service_name, str_videoInput):
        video_input = self.get_input(str_videoInput)

        while self.running():
            frame_obj = video_input.read()  # odebranie danych z interfejsu wejściowego dla obrazu
            #print service_name, ": odebrano ramkę"
            frame = np.loads(frame_obj) # załadowanie ramki do obiektu NumPy
            frame = frame.dumps()

            with self.service_lock:
                next_service_name = self.next_services[service_name]
                self.video_frames[next_service_name] = frame

    def send_video(self, service_name, str_videoInput):
        video_output = self.get_output(str_videoInput)

        while self.running():
            if not self.video_frames[service_name] is None:
                video_output.send(self.video_frames[service_name]) #przesłanie ramki za pomocą interfejsu wyjściowego
                #print service_name, ": ramka wysłana"
                with self.service_lock:
                    self.video_frames[service_name] = None


    def run(self):	# główna metoda usługi
        # Uruchamiam w odzielnych wątkach metody obsługujące wejścia i wyjścia serwisów podrzędnych, które podłączone są do mastera
        for service_name in self.service_params.getAllServiceNames():
            input_settings_connector = self.service_params.getInputSettingsConnectorName(service_name) # pobieram nazwę konektora wejściowego serwisu podrzędnego (wejście ustawień)
            threading.Thread(target=lambda: self.read_settings(service_name, input_settings_connector)).start()

            input_video_connector = self.service_params.getInputVideoConnectorName(service_name) # pobieram nazwę konektora wejściowego serwisu podrzędnego (wejście obrazu)
            threading.Thread(target=lambda: self.read_video(service_name, input_video_connector)).start() #uruchomienie wątku obsługującego wejścia i wyjścia dla serwisu podrzędnego

            output_settings_connector = self.service_params.getOutputSettingsConnectorName(service_name)
            threading.Thread(target=lambda: self.send_settings(service_name, output_settings_connector)).start()

            output_video_connector = self.service_params.getOutputVideoConnectorName(service_name)
            threading.Thread(target=lambda: self.send_video(service_name, output_video_connector)).start()

        while self.running():
            pass
Ejemplo n.º 8
0
 def __init__(self): # "nie"konstruktor, inicjalizator obiektu usługi
     super(MasterService, self).__init__() # wywołanie metody inicjalizatora klasy nadrzędnej
     self.service_lock = threading.RLock() # obiekt pozwalający na blokadę wątku
     self.service_params = ServicesParameters() # obiekt do pobierania nazw serwisów, które podłączone są do serwisu master i ich konektorów
Ejemplo n.º 9
0
class MasterService(Service):
    def __init__(self): # "nie"konstruktor, inicjalizator obiektu usługi
        super(MasterService, self).__init__() # wywołanie metody inicjalizatora klasy nadrzędnej
        self.service_lock = threading.RLock() # obiekt pozwalający na blokadę wątku
        self.service_params = ServicesParameters() # obiekt do pobierania nazw serwisów, które podłączone są do serwisu master i ich konektorów

    def declare_outputs(self):	# deklaracja wyjść
        service_names = self.service_params.getAllServiceNames() # pobieram nazwy wszystkich serwisów, jakie będą podłączone do serwisu master (na ich podstawie są pobierane nazy konektorów)
        for service in service_names:
            connector_name = self.service_params.getOutputVideoConnectorName(service) # pobieram nazwę konektora wyjściowego dla obrazu video
            self.declare_output(connector_name, OutputMessageConnector(self)) # deklaracja konektora
            if service != self.service_params.MASTER_SERVICE: # wszystkie serwisy oprócz samego serwisu master mają konektor wyjściowy z ustawieniami
                connector_name = self.service_params.getOutputSettingsConnectorName(service) # pobieram nazwę konektora wyjściowego dla ustawień przetwarzania
                self.declare_output(connector_name, OutputObjectConnector(self)) # deklaracja konektora

    def declare_inputs(self): #deklaracja wejść
        service_names = self.service_params.getAllServiceNames() # pobieram nazwy wszystkich serwisów, jakie będą podłączone do serwisu master (na ich podstawie są pobierane nazy konektorów)
        for service in service_names:
            connector_name = self.service_params.getInputVideoConnectorName(service) # pobieram nazwę konektora wejściowego dla obrazu video
            self.declare_input(connector_name, InputMessageConnector(self)) # deklaracja konektora
            connector_name = self.service_params.getInputSettingsConnectorName(service) # pobieram nazwę konektora wejściowego dla ustawień przetwarzania
            self.declare_input(connector_name, InputObjectConnector(self)) # deklaracja konektora

    def watch_services(self, str_settingsInput, str_videoInput): # metoda obsługująca wejścia i wyjścia poszczególnych serwisów podrzędnych, które podłączone są do mastera
        # Bezpośrednio deklaruje tylko interfejsy wejściowe, bo to jaki będzie inerefejs wyjściowy (czyli jaki serwis podrzędny przetwarzający obraz będzie wykonwany jako kolejny) zależy od przesłanych ustawień. Więc program musi sam wybrać, gdzie dalej przesłać obraz i dalsze ustawienia
        settings_input = self.get_input(str_settingsInput) # obiekt interfejsu wejściowego
        video_input = self.get_input(str_videoInput)

        while self.running(): #główna pętla wątku

            try:
                settings = settings_input.read() #odczyt danych z interfejsu wejściowego
            except:
                # jeśli nie da się odczytać danych to prawdopodobnie połączenie na sockecie zostało przerwane, więc je zamykam. Połączenie zostaje odtworzone przy kolejnej próbie odczytu danych (wynika z implementacji konektorów
                settings_input.close()

            current_services = settings.get('servicesApplied',{}) # lista serwisów, które należy wykorzystać. Zawiera numery ID, które określone są w klasie ServiceParameters, zmiennej SERVICES_ID

            if current_services: # jeśli lista serwisów nie jest pusta, to trzeba przekazac dane do kolejnego serwisu
                service_value = current_services.pop(0) # biorę pierwszy element z listy serwisow - ta usługa będzie aktualnie zastosowana
                settings['servicesApplied'] = current_services # aktualizuję ogólne ustawienia z usuniętym pierwszym elementem

                service_name = self.service_params.getServiceName(service_value) # pobieram nazwę serwisu, jaki ma być teraz wykonany
                output_settings_connector = self.service_params.getOutputSettingsConnectorName(service_name) # pobieram nazwę konektora wyjściowego dla ustawień przetwarzania
                settings_output = self.get_output(output_settings_connector) # pobieram obiekt interfejsu wyjściowego dla ustawień
                try:
                    settings_output.send(settings) # przesłanie danych za pomocą interfejsu wyjściowego
                except:
                    settings_output.close() # zamknięcie socketa - będzie odtworzone w kolejnej próbie (jak wyżej)
            else: # jeśli lista serwisów jest pusta, to znaczy ze wszystkie operacje przetwarzania obrazu zostały wykonane i można przesłac obraz na wyjście, więc aktualnym konektorem wyjściowym będzie konektor mastera
                service_name = self.service_params.MASTER_SERVICE

            try:
                frame_obj = video_input.read()  # odebranie danych z interfejsu wejściowego dla obrazu
            except:
                video_input.close() # zamknięcie socketa - będzie odtworzone w kolejnej próbie (jak wyżej)

            frame = np.loads(frame_obj) # załadowanie ramki do obiektu NumPy
            output_video_connector = self.service_params.getOutputVideoConnectorName(service_name) # pobieram nazwę konektora wyjściowego dla obrazu
            video_output = self.get_output(output_video_connector) # pobieram obiekt interfejsu wyjściowego dla obrazu
            try:
                video_output.send(frame.dumps()) # przesłanie danych za pomocą interfejsu wyjściowego
            except:
                video_output.close() # zamknięcie socketa - będzie odtworzone w kolejnej próbie (jak wyżej)


    def run(self):	# główna metoda usługi
        # Uruchamiam w odzielnych wątkach metody obsługujące wejścia i wyjścia serwisów podrzędnych, które podłączone są do mastera
        for service_name in self.service_params.getAllServiceNames():
            input_settings_connector = self.service_params.getInputSettingsConnectorName(service_name) # pobieram nazwę konektora wejściowego serwisu podrzędnego (wejście ustawień)
            input_video_connector = self.service_params.getInputVideoConnectorName(service_name) # pobieram nazwę konektora wejściowego serwisu podrzędnego (wejście obrazu)
            threading.Thread(target=lambda: self.watch_services(input_settings_connector,input_video_connector)).start() #uruchomienie wątku obsługującego wejścia i wyjścia dla serwisu podrzędnego

        while self.running():
            None