Exemple #1
0
    def get(self, block=True, timeout=None):
        """
        Returns the first element of the queue if there is some
        element ready before timeout expires, in case of the timeout is not
        ``None``.

        If timeout is ``None``, this method is non-blocking. In this case, if there
        isn't any element available, it returns ``None``, otherwise it returns
        an :class:`.XBeeAPIPacket`.

        Args:
            block (Boolean): ``True`` to block during ``timeout`` waiting for a packet, ``False`` to not block.
            timeout (Integer, optional): timeout in seconds.

        Returns:
            :class:`.XBeeAPIPacket`: a packet if there is any packet available before ``timeout`` expires.
                If ``timeout`` is ``None``, the returned value may be ``None``.

        Raises:
            TimeoutException: if ``timeout`` is not ``None`` and there isn't any packet available
                before the timeout expires.
        """
        if timeout is None:
            try:
                xbee_packet = Queue.get(self, block=False)
            except (Empty, ValueError):
                xbee_packet = None
            return xbee_packet
        else:
            try:
                return Queue.get(self, True, timeout)
            except Empty:
                raise TimeoutException()
Exemple #2
0
    def send(self):
        """
        Sends the packet and waits for its corresponding response.

        Returns:
            :class:`.XBeePacket`: Received response packet.

        Raises:
            InvalidOperatingModeException: If the XBee device's operating mode
                is not API or ESCAPED API. This method only checks the cached
                value of the operating mode.
            TimeoutException: If the response is not received in the configured
                timeout.
            XBeeException: If the XBee device's communication interface is closed.

        .. seealso::
           | :class:`.XBeePacket`
        """
        # Add the packet received callback.
        if self._packet.needs_id():
            self._xbee.add_packet_received_callback(self._packet_received_cb)

        try:
            # Send the packet.
            self._xbee.send_packet(self._packet, sync=False)

            if not self._packet.needs_id():
                return None

            # Wait for response or timeout.
            self._lock.acquire()
            if self._timeout == -1:
                self._lock.wait()
            else:
                self._lock.wait(self._timeout)
            self._lock.release()
            # After waiting check if we received any response, if not throw a
            # timeout exception.
            if not self._response_list:
                raise TimeoutException(
                    message="Response not received in the configured timeout.")
            # Return the received packet.
            return self._response_list[0]
        finally:
            # Always remove the packet listener from the list.
            if self._packet.needs_id():
                self._xbee.del_packet_received_callback(
                    self._packet_received_cb)
Exemple #3
0
    def get_by_remote(self, remote_xbee_device, timeout=None):
        """
        Returns the first element of the queue that had been sent
        by ``remote_xbee_device``, if there is some in the specified timeout.

        If timeout is ``None``, this method is non-blocking. In this case, if there isn't
        any packet sent by ``remote_xbee_device`` in the queue, it returns ``None``,
        otherwise it returns an :class:`.XBeeAPIPacket`.

        Args:
            remote_xbee_device (:class:`.RemoteXBeeDevice`): the remote XBee device to get its firs element from queue.
            timeout (Integer, optional): timeout in seconds.

        Returns:
            :class:`.XBeeAPIPacket`: if there is any packet available before the timeout expires. If timeout is
                ``None``, the returned value may be ``None``.

        Raises:
            TimeoutException: if timeout is not ``None`` and there isn't any packet available that has
                been sent by ``remote_xbee_device`` before the timeout expires.
        """
        if timeout is None:
            with self.mutex:
                for xbee_packet in self.queue:
                    if self.__remote_device_match(xbee_packet,
                                                  remote_xbee_device):
                        self.queue.remove(xbee_packet)
                        return xbee_packet
            return None
        else:
            xbee_packet = self.get_by_remote(remote_xbee_device, None)
            dead_line = time.time() + timeout
            while xbee_packet is None and dead_line > time.time():
                time.sleep(0.1)
                xbee_packet = self.get_by_remote(remote_xbee_device, None)
            if xbee_packet is None:
                raise TimeoutException()
            return xbee_packet
Exemple #4
0
    def get_by_id(self, frame_id, timeout=None):
        """
        Returns the first packet from the queue whose frame ID
        matches the provided one.

        If timeout is ``None``, this method is non-blocking. In this case, if there isn't
        any received packet with the provided frame ID in the queue, it returns ``None``,
        otherwise it returns an :class:`.XBeeAPIPacket`.

        Args:
            frame_id (Integer): The frame ID to look for in the list of packets.
            timeout (Integer, optional): Timeout in seconds.

        Returns:
            :class:`.XBeeAPIPacket`: if there is any packet available before the timeout expires. If timeout is
                ``None``, the returned value may be ``None``.

        Raises:
            TimeoutException: if timeout is not ``None`` and there isn't any packet available that matches
            the provided frame ID before the timeout expires.
        """
        if timeout is None:
            with self.mutex:
                for xbee_packet in self.queue:
                    if xbee_packet.needs_id(
                    ) and xbee_packet.frame_id == frame_id:
                        self.queue.remove(xbee_packet)
                        return xbee_packet
            return None
        else:
            xbee_packet = self.get_by_id(frame_id, None)
            dead_line = time.time() + timeout
            while xbee_packet is None and dead_line > time.time():
                time.sleep(0.1)
                xbee_packet = self.get_by_id(frame_id, None)
            if xbee_packet is None:
                raise TimeoutException()
            return xbee_packet
Exemple #5
0
    def get_by_ip(self, ip_addr, timeout=None):
        """
        Returns the first IP data packet from the queue whose IP address
        matches the provided address.

        If timeout is ``None``, this method is non-blocking. In this case, if there isn't
        any packet sent by ``remote_xbee_device`` in the queue, it returns ``None``,
        otherwise it returns an :class:`.XBeeAPIPacket`.

        Args:
            ip_addr (:class:`ipaddress.IPv4Address`): The IP address to look for in the list of packets.
            timeout (Integer, optional): Timeout in seconds.

        Returns:
            :class:`.XBeeAPIPacket`: if there is any packet available before the timeout expires. If timeout is
                ``None``, the returned value may be ``None``.

        Raises:
            TimeoutException: if timeout is not ``None`` and there isn't any packet available that has
                been sent by ``remote_xbee_device`` before the timeout expires.
        """
        if timeout is None:
            with self.mutex:
                for xbee_packet in self.queue:
                    if self.__ip_addr_match(xbee_packet, ip_addr):
                        self.queue.remove(xbee_packet)
                        return xbee_packet
            return None
        else:
            xbee_packet = self.get_by_ip(ip_addr, None)
            dead_line = time.time() + timeout
            while xbee_packet is None and dead_line > time.time():
                time.sleep(0.1)
                xbee_packet = self.get_by_ip(ip_addr, None)
            if xbee_packet is None:
                raise TimeoutException()
            return xbee_packet
    def connect(self, address):
        """
        Connects to a remote socket at the given address.

        Args:
            address (Tuple): A pair ``(host, port)`` where ``host`` is the domain name or string representation of an
                IPv4 and ``port`` is the numeric port value.

        Raises:
            TimeoutException: if the connect response is not received in the configured timeout.
            ValueError: if ``address`` is ``None`` or not a pair ``(host, port)``.
            ValueError: if ``port`` is less than 1 or greater than 65535.
            XBeeException: if the connection with the XBee device is not open.
            XBeeSocketException: if the connect status is not ``SUCCESS``.
        """
        # Check address and its contents.
        if address is None or len(address) != 2:
            raise ValueError(
                "Invalid address, it must be a pair (host, port).")

        host = address[0]
        port = address[1]
        if isinstance(host, IPv4Address):
            host = str(host)
        if port < 1 or port > 65535:
            raise ValueError("Port number must be between 1 and 65535.")

        # If the socket is not created, create it first.
        if self.__socket_id is None:
            self.__create_socket()

        lock = threading.Condition()
        received_state = list()

        # Define the socket state received callback.
        def socket_state_received_callback(socket_id, state):
            # Check the socket ID.
            if socket_id != self.__socket_id:
                return

            # Add the state to the list and notify the lock.
            received_state.append(state)
            lock.acquire()
            lock.notify()
            lock.release()

        # Add the socket state received callback.
        self.__xbee_device.add_socket_state_received_callback(
            socket_state_received_callback)

        try:
            # Create, send and check the socket connect packet.
            connect_packet = SocketConnectPacket(
                self.__xbee_device.get_next_frame_id(), self.__socket_id, port,
                SocketConnectPacket.DEST_ADDRESS_STRING, host)
            response_packet = self.__xbee_device.send_packet_sync_and_get_response(
                connect_packet, timeout=self.__get_timeout())
            self.__check_response(response_packet)

            # Wait until the socket state frame is received confirming the connection.
            if not received_state:
                lock.acquire()
                lock.wait(self.__timeout)
                lock.release()

            # Check if the socket state has been received.
            if not received_state:
                raise TimeoutException(
                    "Timeout waiting for the socket connection")

            # Check if the socket is connected successfully.
            if received_state[0] != SocketState.CONNECTED:
                raise XBeeSocketException(status=received_state[0])

            self.__connected = True

            # Register internal socket state and data reception callbacks.
            self.__register_state_callback()
            self.__register_data_received_callback()
        finally:
            # Always remove the socket state callback.
            self.__xbee_device.del_socket_state_received_callback(
                socket_state_received_callback)