docs: def add_input_data_port(self, name, data_type=None, default_value=None, data_port_id=None):
          """Add a new input data port to the state.
  
          :param str name: the name of the new input data port
          :param data_type: the type of the new output data port considered of class :class:`type` or
                            :class:`str` which has to be convertible to :class:`type`
          :param default_value: the default value of the data port
          :param int data_port_id: the data_port_id of the new data port
          :return: data_port_id of new input data port
          :rtype: int
          :raises exceptions.ValueError: if name of the input port is not unique
          """
          if data_port_id is None:
              # All data port ids have to passed to the id generation as the data port id has to be unique inside a state
              data_port_id = generate_data_port_id(self.get_data_port_ids())
          self._input_data_ports[data_port_id] = InputDataPort(name, data_type, default_value, data_port_id, self)
  
          # Check for name uniqueness
          valid, message = self._check_data_port_name(self._input_data_ports[data_port_id])
          if not valid:
              self._input_data_ports[data_port_id].parent = None
              del self._input_data_ports[data_port_id]
              raise ValueError(message)
  
          return data_port_id