def __init__(self,
                 storage_type,
                 configdict,
                 data_source,
                 loop_interval=5000,
                 ui_pipe=None):
        """
        Intializes the class
        --------------------
        @Params: storage_type   (string)            Type of the selected storage
                                                    method. Must be one of the
                                                    implemented types.
                 configdict     (dict)              Key value pair based settings
                                                    according to the needs of the
                                                    selected storing engine.
                 data_source    (PipeConnection)    The pipe where source data
                                                    come from.
                 loop_interval  (int)               Time in milliseconds between
                                                    cycles.
                 ui_pipe        (PipeConnection)    Pipe to send data to the UI
                                                    flow.
        @Throws: MGPError                           When storage type is not
                                                    implemented or doesn't exist.
                                                    When data source is not
                                                    instance of PipeConnection.
        """

        if not isinstance(DataArea.engine, DataArea.__DataAreaEngine):
            if storage_type in DataArea.__STORAGE_TYPES:
                if storage_type == 'DoF':
                    DataArea.engine = DataArea.__DataAreaEngine(
                        DataArea.__EngineDof(configdict))
                elif storage_type == 'CSV':
                    DataArea.engine = DataArea.__DataAreaEngine(
                        DataArea.__EngineCSV(configdict))
                elif storage_type == 'SQL':
                    DataArea.engine = DataArea.__DataAreaEngine(
                        DataArea.__EngineSQL(configdict))
            else:
                self.showimplemented()
                raise MGPError(
                    'DataArea: Storage "{}" is not valid or not implemented.'.
                    format(storage_type))
            if data_source.__class__.__name__ == 'PipeConnection':
                self.__data_source = data_source
            else:
                raise MGPError(
                    'DataArea: Pipe for data source must be instance of PipeConnection but is "{}".'
                    .format(data_source.__class__.__name__))
            self.__loop_interval = loop_interval / 1000
            if ui_pipe is not None:
                self.__to_ui = ui_pipe
            else:
                self.__to_ui = NullPipe()
            self.__do_loop = False
    def __init__(self, flow_source, processor_function, loop_interval=100,
                 flow_pipe=None, data_pipe=None, ui_pipe=None):
        """
        Intializes the class
        --------------------
        @Params: flow_source        (PipeConnection)    The pipe where source
                                                        data come from.
                 processor_function (callable)          Callable function to
                                                        process input data.
                                                        Every data gets processed
                                                        with the same function.
                                                    data gating.
                 loop_interval      (int)               [optional] Time in
                                                        milliseconds between
                                                        cycles.
                 flow_pipe          (PipeConnection)    [optional] Pipe to send
                                                        data to the main flow.
                 data_pipe          (PipeConnection)    [optional] Pipe to send
                                                        data to the data flow.
                 ui_pipe            (PipeConnection)    [optional] Pipe to send
                                                        data to the UI flow.
        @Throws: MGPError                               When flow_source is not
                                                        instance of PipeConnection.
                                                        When processor_function
                                                        is not callable.
        """

        if flow_source.__class__.__name__ == 'PipeConnection':
            self.__flow_source = flow_source
        else:
            raise MGPError('ProcessArea: Pipe for main workflow must be instance of PipeConnection but is "{}".'.format(flow_source.__class__.__name__))
        if callable(processor_function):
            self.__processor_function = processor_function
        else:
            raise MGPError('ProcessArea: Parameter for processor function must be at least callable.')
        self.__loop_interval = loop_interval / 1000
        if flow_pipe is not None:
            self.__to_flow = flow_pipe
        else:
            self.__to_flow = NullPipe()
        if data_pipe is not None:
            self.__to_data = data_pipe
        else:
            self.__to_data = NullPipe()
        if ui_pipe is not None:
            self.__to_ui = ui_pipe
        else:
            self.__to_ui = NullPipe()
        self.__do_loop = False
    def unregister(self, handler_name):
        """
        Unregisters a handler
        ---------------------
        @Params: handler_name   (string)    The identifier to delete.
        @Throws: MGPError                   If the identifier doesn't exist.
        """

        if handler_name in self.__actions:
            del self.__actions[handler_name]
        else:
            raise MGPError('OutputArea.unregister(): Tried to unregister non-existing name "{}".'
                           .format(handler_name))
    def act(self, handler_name, data):
        """
        Translates gate action to data for actuator
        -------------------------------------------
        @Params: handler_name   (string)    The identifier of the handler.
                 data           (MGPData)   The data to be sent to the handler.
        @Throws: MGPError                   When non-existing handler is called.
                                            When data is not instance of MGPData.
        """

        if handler_name in self.__events:
            if isinstance(data, MGPDataRowL2):
                finaldata = self.__actions[handler_name].handle(data)
                if finaldata.todata() is not None:
                    self.__to_data.send(finaldata.todata())
                if finaldata.toui() is not None:
                    self.__to_ui.send(finaldata.toui())
            else:
                raise MGPError('OutputArea.act(): Action data must be instance of MGPData but is "{}".'
                               .format(data.__class__.__name__))
        else:
            raise MGPError('OutputArea.act(): Tried to read for non-existing name "{}".'
                           .format(handler_name))
    def register(self, handler_name, handler_type, handler_function,
                 filter_function=None):
        """
        Registers a handler to an identifier
        ------------------------------------
        @Params: handler_name       (string)    Identifier to register.
                 handler_type       (string)    Type of the handler.
                 handler_function   (callable)  The handler function.
                 filter_function    (callable)  [optional]  The filter function.
        @Throws: MGPError                       When tired to register a new
                                                entry to an existing identifier.
        """

        if handler_name not in self.__actions:
            self.__actions[handler_name] = OutputArea.OutputHandler(handler_type,
                                                                    handler_function,
                                                                    filter_function)
        else:
            raise MGPError('OutputArea.register(): Tried to register existing name "{}".'
                           .format(handler_name))
    def read(self, handler_name, rawdata):
        """
        Translates raw data to processable data
        ---------------------------------------
        @Params: handler_name   (string)    The identifier of the handler.
                 rawdata        (object)    The data to be sent to the handler.
        @Throws: MGPError                   When non-existing handler is called.
        """

        if handler_name in self.__events:
            data = self.__events[handler_name].handle(rawdata)
            if data.toflow() is not None:
                self.__to_flow.send(data.toflow())
            if data.todata() is not None:
                self.__to_data.send(data.todata())
            if data.toui() is not None:
                self.__to_ui.send(data.toui())
        else:
            raise MGPError(
                'InputArea.read(): Tried to read for non-existing name "{}".'.
                format(handler_name))