Beispiel #1
0
    async def _listen_for_incoming_websocket_data(self, incoming_parser):
        """Creates a websocket connection, listens for incoming data and
        uses the incoming parser to parse the incoming data.
        """
        try:
            for i in range(self._restCallRequestCounter):
                try:
                    await self._connect_to_websocket()
                    break
                except (asyncio.TimeoutError, aiohttp.ClientConnectionError):
                    logger.warning(
                        'websocket connection timed-out. or other connection error occurred.'
                    )
                    await asyncio.sleep(self._restCallTimout)
            else:
                # exit while loop without break. Raising error which
                # should be handled by user.
                raise HmipConnectionError(
                    "Problem connecting to hmip websocket connection")

            logger.info('Connected to HMIP websocket.')

            while True:
                try:
                    # It doesn't seem to be possible to observe an unexpected
                    # internet disconnect. To keep the connection persistent
                    # the connection is wrapped in a timeout after which a
                    # reconnect attempt is made.

                    with async_timeout.timeout(self.reconnect_timeout,
                                               loop=self._loop):
                        async for msg in self.socket_connection:
                            logger.debug(msg)
                            if msg.tp == aiohttp.WSMsgType.BINARY:
                                message = str(msg.data, 'utf-8')
                                incoming_parser(None, message)
                            elif msg.tp in [
                                    aiohttp.WSMsgType.CLOSE,
                                    aiohttp.WSMsgType.CLOSED,
                                    aiohttp.WSMsgType.ERROR
                            ]:
                                # Server has closed the connection.
                                # Raising error which should be handled by
                                # user.
                                raise HmipConnectionError(
                                    "Server closed websocket connection")
                except asyncio.TimeoutError:
                    #await self.socket_connection.close()
                    logger.debug(
                        'controlled stopping of websocket. Reconnecting')
        except CancelledError:
            logger.debug('stopping websocket incoming listener')
Beispiel #2
0
 async def _connect_to_websocket(self):
     try:
         self.socket_connection = await asyncio.wait_for(
             websockets.connect(self._urlWebSocket,
                                extra_headers={
                                    ATTR_AUTH_TOKEN: self._auth_token,
                                    ATTR_CLIENT_AUTH: self._clientauth_token
                                }),
             timeout=self.connect_timeout)
     except asyncio.TimeoutError:
         raise HmipConnectionError(
             "Connecting to hmip ws socket timed out.")
     except Exception as err:
         logger.exception(err)
         raise HmipConnectionError()
Beispiel #3
0
    async def api_call(self, path, body=None, full_url=False):
        """Make the actual call to the HMIP server.

        Throws `HmipWrongHttpStatusError` or `HmipConnectionError` if connection has failed or
        response is not correct."""
        result = None
        if not full_url:
            path = self.full_url(path)
        for i in range(self._restCallRequestCounter):
            try:
                with async_timeout.timeout(self._restCallTimout,
                                           loop=self._loop):
                    result = await self._websession.post(path,
                                                         data=body,
                                                         headers=self.headers)
                    if result.status == 200:
                        if result.content_type == 'application/json':
                            ret = await result.json()
                        else:
                            ret = True
                        return ret
                    else:
                        raise HmipWrongHttpStatusError
            except (asyncio.TimeoutError, aiohttp.ClientConnectionError):
                # Both exceptions occur when connecting to the server does
                # somehow not work.
                logger.debug(
                    "Connection timed out or another error occurred %s" % path)
            except JSONDecodeError as err:
                logger.exception(err)
            finally:
                if result is not None:
                    await result.release()
        raise HmipConnectionError("Failed to connect to HomeMaticIp server")
    async def _ws_loop(self, on_message, on_error):
        try:
            while True:
                msg = await self.socket_connection.recv()
                logger.debug("incoming hmip message")
                on_message(msg.decode())
        except TypeError:
            logger.error("Problem converting incoming bytes %s", msg)
        except ConnectionClosed:
            logger.debug("Connection closed by server")
        except CancelledError:
            logger.info("Reading task is cancelled.")
        except Exception as err:
            logger.debug("WS Reader task stop.")
            logger.exception(err)
        finally:
            await self.close_websocket_connection(source_is_reading_loop=True)
            await self._closing_task

            raise HmipConnectionError()