async def test_multiple_channels(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) ch1 = 'test-where-now-asyncio-ch1' ch2 = 'test-where-now-asyncio-ch2' uuid = 'test-where-now-asyncio-uuid' pubnub.config.uuid = uuid callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels([ch1, ch2]).execute() await callback.wait_for_connect() await sleeper(7) env = await pubnub.where_now() \ .uuid(uuid) \ .future() channels = env.result.channels assert len(channels) == 2 assert ch1 in channels assert ch2 in channels pubnub.unsubscribe().channels([ch1, ch2]).execute() await callback.wait_for_disconnect() await pubnub.stop()
async def test_timeout_event_on_broken_heartbeat(event_loop): ch = helper.gen_channel("heartbeat-test") pubnub = PubNubAsyncio(messenger_config, custom_event_loop=event_loop) pubnub_listener = PubNubAsyncio(listener_config, custom_event_loop=event_loop) pubnub.config.uuid = helper.gen_channel("messenger") pubnub_listener.config.uuid = helper.gen_channel("listener") # - connect to :ch-pnpres callback_presence = SubscribeListener() pubnub_listener.add_listener(callback_presence) pubnub_listener.subscribe().channels(ch).with_presence().execute() await callback_presence.wait_for_connect() envelope = await callback_presence.wait_for_presence_on(ch) assert ch == envelope.channel assert 'join' == envelope.event assert pubnub_listener.uuid == envelope.uuid # - connect to :ch callback_messages = SubscribeListener() pubnub.add_listener(callback_messages) pubnub.subscribe().channels(ch).execute() useless_connect_future = callback_messages.wait_for_connect() presence_future = asyncio.ensure_future( callback_presence.wait_for_presence_on(ch)) # - assert join event await asyncio.wait([useless_connect_future, presence_future]) prs_envelope = presence_future.result() assert ch == prs_envelope.channel assert 'join' == prs_envelope.event assert pubnub.uuid == prs_envelope.uuid # wait for one heartbeat call await asyncio.sleep(8) # - break messenger heartbeat loop pubnub._subscription_manager._stop_heartbeat_timer() # - assert for timeout envelope = await callback_presence.wait_for_presence_on(ch) assert ch == envelope.channel assert 'timeout' == envelope.event assert pubnub.uuid == envelope.uuid pubnub.unsubscribe().channels(ch).execute() await callback_messages.wait_for_disconnect() # - disconnect from :ch-pnpres pubnub_listener.unsubscribe().channels(ch).execute() await callback_presence.wait_for_disconnect() await pubnub.stop() await pubnub_listener.stop()
async def test_cg_subscribe_unsubscribe(event_loop, sleeper=asyncio.sleep): ch = "test-subscribe-asyncio-channel" gr = "test-subscribe-asyncio-group" pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) envelope = await pubnub.add_channel_to_channel_group().channel_group( gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 await sleeper(3) callback_messages = SubscribeListener() pubnub.add_listener(callback_messages) pubnub.subscribe().channel_groups(gr).execute() await callback_messages.wait_for_connect() pubnub.unsubscribe().channel_groups(gr).execute() await callback_messages.wait_for_disconnect() envelope = await pubnub.remove_channel_from_channel_group().channel_group( gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 await pubnub.stop()
def test_multiple_channels(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) ch1 = 'test-where-now-asyncio-ch1' ch2 = 'test-where-now-asyncio-ch2' uuid = 'test-where-now-asyncio-uuid' pubnub.config.uuid = uuid callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels([ch1, ch2]).execute() yield from callback.wait_for_connect() yield from sleeper(7) env = yield from pubnub.where_now() \ .uuid(uuid) \ .future() channels = env.result.channels assert len(channels) == 2 assert ch1 in channels assert ch2 in channels pubnub.unsubscribe().channels([ch1, ch2]).execute() yield from callback.wait_for_disconnect() pubnub.stop()
async def test_subscribe_unsubscribe(event_loop): channel = "test-subscribe-asyncio-ch" pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) callback = SubscribeListener() pubnub.add_listener(callback) pubnub.subscribe().channels(channel).execute() assert channel in pubnub.get_subscribed_channels() assert len(pubnub.get_subscribed_channels()) == 1 await callback.wait_for_connect() assert channel in pubnub.get_subscribed_channels() assert len(pubnub.get_subscribed_channels()) == 1 pubnub.unsubscribe().channels(channel).execute() assert channel not in pubnub.get_subscribed_channels() assert len(pubnub.get_subscribed_channels()) == 0 # await callback.wait_for_disconnect() assert channel not in pubnub.get_subscribed_channels() assert len(pubnub.get_subscribed_channels()) == 0 await pubnub.stop()
def test_single_channel_with_subscription(event_loop, sleeper=asyncio.sleep): pnconf = pnconf_sub_copy() pnconf.set_presence_timeout(12) pubnub = PubNubAsyncio(pnconf, custom_event_loop=event_loop) ch = 'test-state-asyncio-ch' pubnub.config.uuid = 'test-state-asyncio-uuid' state = {"name": "Alex", "count": 5} callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels(ch).execute() yield from callback.wait_for_connect() yield from sleeper(20) env = yield from pubnub.set_state() \ .channels(ch) \ .state(state) \ .future() assert env.result.state['name'] == "Alex" assert env.result.state['count'] == 5 env = yield from pubnub.get_state() \ .channels(ch) \ .future() assert env.result.channels[ch]['name'] == "Alex" assert env.result.channels[ch]['count'] == 5 pubnub.unsubscribe().channels(ch).execute() yield from callback.wait_for_disconnect() pubnub.stop()
def test_single_channel_with_subscription(event_loop, sleeper=asyncio.sleep): pnconf = pnconf_sub_copy() pnconf.set_presence_timeout(12) pubnub = PubNubAsyncio(pnconf, custom_event_loop=event_loop) ch = "test-state-asyncio-ch" pubnub.config.uuid = "test-state-asyncio-uuid" state = {"name": "Alex", "count": 5} callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels(ch).execute() yield from callback.wait_for_connect() yield from sleeper(20) env = yield from pubnub.set_state().channels(ch).state(state).future() assert env.result.state["name"] == "Alex" assert env.result.state["count"] == 5 env = yield from pubnub.get_state().channels(ch).future() assert env.result.channels[ch]["name"] == "Alex" assert env.result.channels[ch]["count"] == 5 pubnub.unsubscribe().channels(ch).execute() yield from callback.wait_for_disconnect() pubnub.stop()
def test_subscribe_unsubscribe(event_loop): channel = "test-subscribe-asyncio-ch" pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) callback = SubscribeListener() pubnub.add_listener(callback) pubnub.subscribe().channels(channel).execute() assert channel in pubnub.get_subscribed_channels() assert len(pubnub.get_subscribed_channels()) == 1 yield from callback.wait_for_connect() assert channel in pubnub.get_subscribed_channels() assert len(pubnub.get_subscribed_channels()) == 1 pubnub.unsubscribe().channels(channel).execute() assert channel not in pubnub.get_subscribed_channels() assert len(pubnub.get_subscribed_channels()) == 0 yield from callback.wait_for_disconnect() assert channel not in pubnub.get_subscribed_channels() assert len(pubnub.get_subscribed_channels()) == 0 pubnub.stop()
def test_single_channel(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) ch = 'test-where-now-asyncio-ch' uuid = 'test-where-now-asyncio-uuid' pubnub.config.uuid = uuid callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels(ch).execute() yield from callback.wait_for_connect() yield from sleeper(2) env = yield from pubnub.where_now() \ .uuid(uuid) \ .future() channels = env.result.channels assert len(channels) == 1 assert channels[0] == ch pubnub.unsubscribe().channels(ch).execute() yield from callback.wait_for_disconnect() pubnub.stop()
def test_timeout_event_on_broken_heartbeat(event_loop): ch = helper.gen_channel("heartbeat-test") pubnub = PubNubAsyncio(messenger_config, custom_event_loop=event_loop) pubnub_listener = PubNubAsyncio(listener_config, custom_event_loop=event_loop) pubnub.config.uuid = helper.gen_channel("messenger") pubnub_listener.config.uuid = helper.gen_channel("listener") # - connect to :ch-pnpres callback_presence = SubscribeListener() pubnub_listener.add_listener(callback_presence) pubnub_listener.subscribe().channels(ch).with_presence().execute() yield from callback_presence.wait_for_connect() envelope = yield from callback_presence.wait_for_presence_on(ch) assert ch == envelope.channel assert 'join' == envelope.event assert pubnub_listener.uuid == envelope.uuid # - connect to :ch callback_messages = SubscribeListener() pubnub.add_listener(callback_messages) pubnub.subscribe().channels(ch).execute() useless_connect_future = callback_messages.wait_for_connect() presence_future = asyncio.ensure_future(callback_presence.wait_for_presence_on(ch)) # - assert join event yield from asyncio.wait([useless_connect_future, presence_future]) prs_envelope = presence_future.result() assert ch == prs_envelope.channel assert 'join' == prs_envelope.event assert pubnub.uuid == prs_envelope.uuid # wait for one heartbeat call yield from asyncio.sleep(8) # - break messenger heartbeat loop pubnub._subscription_manager._stop_heartbeat_timer() # - assert for timeout envelope = yield from callback_presence.wait_for_presence_on(ch) assert ch == envelope.channel assert 'timeout' == envelope.event assert pubnub.uuid == envelope.uuid pubnub.unsubscribe().channels(ch).execute() yield from callback_messages.wait_for_disconnect() # - disconnect from :ch-pnpres pubnub_listener.unsubscribe().channels(ch).execute() yield from callback_presence.wait_for_disconnect() pubnub.stop() pubnub_listener.stop()
def async_create_pubnub(user_uuid, subscriptions): """Create a pubnub subscription.""" pnconfig = PNConfiguration() pnconfig.subscribe_key = AUGUST_CHANNEL pnconfig.uuid = f"pn-{str(user_uuid).upper()}" pubnub = PubNubAsyncio(pnconfig) pubnub.add_listener(subscriptions) pubnub.subscribe().channels(subscriptions.channels).execute() def _unsub(): pubnub.unsubscribe().channels(subscriptions.channels).execute() return _unsub
async def test_join_leave(event_loop): channel = "test-subscribe-asyncio-join-leave-ch" pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub_listener = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) patch_pubnub(pubnub) patch_pubnub(pubnub_listener) pubnub.config.uuid = "test-subscribe-asyncio-messenger" pubnub_listener.config.uuid = "test-subscribe-asyncio-listener" callback_presence = VCR599Listener(1) callback_messages = VCR599Listener(1) pubnub_listener.add_listener(callback_presence) pubnub_listener.subscribe().channels(channel).with_presence().execute() await callback_presence.wait_for_connect() envelope = await callback_presence.wait_for_presence_on(channel) assert envelope.channel == channel assert envelope.event == 'join' assert envelope.uuid == pubnub_listener.uuid pubnub.add_listener(callback_messages) pubnub.subscribe().channels(channel).execute() await callback_messages.wait_for_connect() envelope = await callback_presence.wait_for_presence_on(channel) assert envelope.channel == channel assert envelope.event == 'join' assert envelope.uuid == pubnub.uuid pubnub.unsubscribe().channels(channel).execute() await callback_messages.wait_for_disconnect() envelope = await callback_presence.wait_for_presence_on(channel) assert envelope.channel == channel assert envelope.event == 'leave' assert envelope.uuid == pubnub.uuid pubnub_listener.unsubscribe().channels(channel).execute() await callback_presence.wait_for_disconnect() await pubnub.stop() pubnub_listener.stop()
def test_access_denied_unsubscribe_operation(event_loop): channel = "not-permitted-channel" pnconf = pnconf_pam_copy() pnconf.secret_key = None pnconf.enable_subscribe = True pubnub = PubNubAsyncio(pnconf, custom_event_loop=event_loop) callback = AccessDeniedListener() pubnub.add_listener(callback) pubnub.subscribe().channels(channel).execute() yield from callback.access_denied_event.wait() pubnub.stop()
def test_access_denied_unsubscribe_operation(event_loop): channel = "not-permitted-channel" pnconf = pnconf_pam_copy() pnconf.secret_key = None pnconf.enable_subscribe = True pubnub = PubNubAsyncio(pnconf, custom_event_loop=event_loop) callback = AccessDeniedListener() pubnub.add_listener(callback) pubnub.subscribe().channels(channel).execute() yield from callback.access_denied_event.wait() pubnub.stop()
def test_join_leave(event_loop): channel = "test-subscribe-asyncio-join-leave-ch" pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub_listener = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) patch_pubnub(pubnub) patch_pubnub(pubnub_listener) pubnub.config.uuid = "test-subscribe-asyncio-messenger" pubnub_listener.config.uuid = "test-subscribe-asyncio-listener" callback_presence = VCR599Listener(1) callback_messages = VCR599Listener(1) pubnub_listener.add_listener(callback_presence) pubnub_listener.subscribe().channels(channel).with_presence().execute() yield from callback_presence.wait_for_connect() envelope = yield from callback_presence.wait_for_presence_on(channel) assert envelope.channel == channel assert envelope.event == 'join' assert envelope.uuid == pubnub_listener.uuid pubnub.add_listener(callback_messages) pubnub.subscribe().channels(channel).execute() yield from callback_messages.wait_for_connect() envelope = yield from callback_presence.wait_for_presence_on(channel) assert envelope.channel == channel assert envelope.event == 'join' assert envelope.uuid == pubnub.uuid pubnub.unsubscribe().channels(channel).execute() yield from callback_messages.wait_for_disconnect() envelope = yield from callback_presence.wait_for_presence_on(channel) assert envelope.channel == channel assert envelope.event == 'leave' assert envelope.uuid == pubnub.uuid pubnub_listener.unsubscribe().channels(channel).execute() yield from callback_presence.wait_for_disconnect() pubnub.stop() pubnub_listener.stop()
async def test_unsubscribe_all(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = "test-subscribe-asyncio-messenger" ch = "test-subscribe-asyncio-unsubscribe-all-ch" ch1 = "test-subscribe-asyncio-unsubscribe-all-ch1" ch2 = "test-subscribe-asyncio-unsubscribe-all-ch2" ch3 = "test-subscribe-asyncio-unsubscribe-all-ch3" gr1 = "test-subscribe-asyncio-unsubscribe-all-gr1" gr2 = "test-subscribe-asyncio-unsubscribe-all-gr2" envelope = await pubnub.add_channel_to_channel_group().channel_group( gr1).channels(ch).future() assert envelope.status.original_response['status'] == 200 envelope = await pubnub.add_channel_to_channel_group().channel_group( gr2).channels(ch).future() assert envelope.status.original_response['status'] == 200 await sleeper(1) callback_messages = VCR599Listener(1) pubnub.add_listener(callback_messages) pubnub.subscribe().channels([ch1, ch2, ch3]).channel_groups([gr1, gr2]).execute() await callback_messages.wait_for_connect() assert len(pubnub.get_subscribed_channels()) == 3 assert len(pubnub.get_subscribed_channel_groups()) == 2 pubnub.unsubscribe_all() await callback_messages.wait_for_disconnect() assert len(pubnub.get_subscribed_channels()) == 0 assert len(pubnub.get_subscribed_channel_groups()) == 0 envelope = await pubnub.remove_channel_from_channel_group().channel_group( gr1).channels(ch).future() assert envelope.status.original_response['status'] == 200 envelope = await pubnub.remove_channel_from_channel_group().channel_group( gr2).channels(ch).future() assert envelope.status.original_response['status'] == 200 await pubnub.stop()
def test_subscribe_publish_unsubscribe(event_loop): pubnub_sub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub_pub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) patch_pubnub(pubnub_sub) patch_pubnub(pubnub_pub) pubnub_sub.config.uuid = 'test-subscribe-asyncio-uuid-sub' pubnub_pub.config.uuid = 'test-subscribe-asyncio-uuid-pub' callback = VCR599Listener(1) channel = "test-subscribe-asyncio-ch" message = "hey" pubnub_sub.add_listener(callback) pubnub_sub.subscribe().channels(channel).execute() yield from callback.wait_for_connect() publish_future = asyncio.ensure_future(pubnub_pub.publish().channel(channel).message(message).future()) subscribe_message_future = asyncio.ensure_future(callback.wait_for_message_on(channel)) yield from asyncio.wait([ publish_future, subscribe_message_future ]) publish_envelope = publish_future.result() subscribe_envelope = subscribe_message_future.result() assert isinstance(subscribe_envelope, PNMessageResult) assert subscribe_envelope.channel == channel assert subscribe_envelope.subscription is None assert subscribe_envelope.message == message assert subscribe_envelope.timetoken > 0 assert isinstance(publish_envelope, AsyncioEnvelope) assert publish_envelope.result.timetoken > 0 assert publish_envelope.status.original_response[0] == 1 pubnub_sub.unsubscribe().channels(channel).execute() yield from callback.wait_for_disconnect() pubnub_pub.stop() pubnub_sub.stop()
async def test_subscribe_publish_unsubscribe(event_loop): pubnub_sub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub_pub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) patch_pubnub(pubnub_sub) patch_pubnub(pubnub_pub) pubnub_sub.config.uuid = 'test-subscribe-asyncio-uuid-sub' pubnub_pub.config.uuid = 'test-subscribe-asyncio-uuid-pub' callback = VCR599Listener(1) channel = "test-subscribe-asyncio-ch" message = "hey" pubnub_sub.add_listener(callback) pubnub_sub.subscribe().channels(channel).execute() await callback.wait_for_connect() publish_future = asyncio.ensure_future( pubnub_pub.publish().channel(channel).message(message).future()) subscribe_message_future = asyncio.ensure_future( callback.wait_for_message_on(channel)) await asyncio.wait([publish_future, subscribe_message_future]) publish_envelope = publish_future.result() subscribe_envelope = subscribe_message_future.result() assert isinstance(subscribe_envelope, PNMessageResult) assert subscribe_envelope.channel == channel assert subscribe_envelope.subscription is None assert subscribe_envelope.message == message assert subscribe_envelope.timetoken > 0 assert isinstance(publish_envelope, AsyncioEnvelope) assert publish_envelope.result.timetoken > 0 assert publish_envelope.status.original_response[0] == 1 pubnub_sub.unsubscribe().channels(channel).execute() # await callback.wait_for_disconnect() pubnub_pub.stop() pubnub_sub.stop()
async def test_cg_subscribe_publish_unsubscribe(event_loop, sleeper=asyncio.sleep): ch = "test-subscribe-asyncio-channel" gr = "test-subscribe-asyncio-group" message = "hey" pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) envelope = await pubnub.add_channel_to_channel_group().channel_group( gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 await sleeper(1) callback_messages = VCR599Listener(1) pubnub.add_listener(callback_messages) pubnub.subscribe().channel_groups(gr).execute() await callback_messages.wait_for_connect() subscribe_future = asyncio.ensure_future( callback_messages.wait_for_message_on(ch)) publish_future = asyncio.ensure_future( pubnub.publish().channel(ch).message(message).future()) await asyncio.wait([subscribe_future, publish_future]) sub_envelope = subscribe_future.result() pub_envelope = publish_future.result() assert pub_envelope.status.original_response[0] == 1 assert pub_envelope.status.original_response[1] == 'Sent' assert sub_envelope.channel == ch assert sub_envelope.subscription == gr assert sub_envelope.message == message pubnub.unsubscribe().channel_groups(gr).execute() await callback_messages.wait_for_disconnect() envelope = await pubnub.remove_channel_from_channel_group().channel_group( gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 await pubnub.stop()
def test_unsubscribe_all(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = "test-subscribe-asyncio-messenger" ch = "test-subscribe-asyncio-unsubscribe-all-ch" ch1 = "test-subscribe-asyncio-unsubscribe-all-ch1" ch2 = "test-subscribe-asyncio-unsubscribe-all-ch2" ch3 = "test-subscribe-asyncio-unsubscribe-all-ch3" gr1 = "test-subscribe-asyncio-unsubscribe-all-gr1" gr2 = "test-subscribe-asyncio-unsubscribe-all-gr2" envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr1).channels(ch).future() assert envelope.status.original_response['status'] == 200 envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr2).channels(ch).future() assert envelope.status.original_response['status'] == 200 yield from sleeper(1) callback_messages = VCR599Listener(1) pubnub.add_listener(callback_messages) pubnub.subscribe().channels([ch1, ch2, ch3]).channel_groups([gr1, gr2]).execute() yield from callback_messages.wait_for_connect() assert len(pubnub.get_subscribed_channels()) == 3 assert len(pubnub.get_subscribed_channel_groups()) == 2 pubnub.unsubscribe_all() yield from callback_messages.wait_for_disconnect() assert len(pubnub.get_subscribed_channels()) == 0 assert len(pubnub.get_subscribed_channel_groups()) == 0 envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr1).channels(ch).future() assert envelope.status.original_response['status'] == 200 envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr2).channels(ch).future() assert envelope.status.original_response['status'] == 200 pubnub.stop()
def test_blah(): pnconf = pnconf_sub_copy() assert isinstance(pnconf, PNConfiguration) pnconf.reconnect_policy = PNReconnectionPolicy.EXPONENTIAL pubnub = PubNubAsyncio(pnconf) time_until_open_again = 8 @asyncio.coroutine def close_soon(): yield from asyncio.sleep(2) pubnub._connector.close() print(">>> connection is broken") @asyncio.coroutine def open_again(): yield from asyncio.sleep(time_until_open_again) pubnub.set_connector(aiohttp.TCPConnector(conn_timeout=pubnub.config.connect_timeout, verify_ssl=True)) print(">>> connection is open again") @asyncio.coroutine def countdown(): asyncio.sleep(2) opened = False count = time_until_open_again while not opened: print(">>> %ds to open again" % count) count -= 1 if count <= 0: break yield from asyncio.sleep(1) my_listener = MySubscribeCallback() pubnub.add_listener(my_listener) pubnub.subscribe().channels('my_channel').execute() asyncio.ensure_future(close_soon()) asyncio.ensure_future(open_again()) asyncio.ensure_future(countdown()) yield from asyncio.sleep(1000)
async def message_pump(self): pnconfig = PNConfiguration() pnconfig.subscribe_key = config['cardsubkey'] # Why aren't these the default settings? pnconfig.ssl = True pnconfig.reconnect_policy = PNReconnectionPolicy.EXPONENTIAL pubnub = PubNubAsyncio(pnconfig) listener = SubscribeListener() pubnub.add_listener(listener) pubnub.subscribe().channels(config['cardviewerchannel']).execute() await listener.wait_for_connect() log.info("Connected to PubNub") message_future = asyncio.ensure_future( listener.wait_for_message_on(config['cardviewerchannel'])) while True: await asyncio.wait([self.stop_future, message_future], return_when=asyncio.FIRST_COMPLETED) if message_future.done(): message = message_future.result().message log.info("Message from PubNub: %r", message) card_id = self._extract(message) if card_id is not None: await self._card(card_id) message_future = asyncio.ensure_future( listener.wait_for_message_on(config['cardviewerchannel'])) if self.stop_future.done(): break if not message_future.done(): message_future.cancel() pubnub.unsubscribe().channels(config['cardviewerchannel']).execute() await listener.wait_for_disconnect() pubnub.stop() log.info("Disconnected from PubNub")
async def test_multiple_channels(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = 'test-here-now-asyncio-uuid1' ch1 = "test-here-now-asyncio-ch1" ch2 = "test-here-now-asyncio-ch2" callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels([ch1, ch2]).execute() await callback.wait_for_connect() await sleeper(5) env = await pubnub.here_now() \ .channels([ch1, ch2]) \ .future() assert env.result.total_channels == 2 assert env.result.total_occupancy >= 1 channels = env.result.channels assert len(channels) == 2 assert channels[0].occupancy == 1 assert channels[0].occupants[0].uuid == pubnub.uuid assert channels[1].occupancy == 1 assert channels[1].occupants[0].uuid == pubnub.uuid result = await pubnub.here_now() \ .channels([ch1, ch2]) \ .include_state(True) \ .result() assert result.total_channels == 2 pubnub.unsubscribe().channels([ch1, ch2]).execute() await callback.wait_for_disconnect() pubnub.stop()
def test_blah(): pnconf = pnconf_sub_copy() assert isinstance(pnconf, PNConfiguration) pnconf.reconnect_policy = PNReconnectionPolicy.EXPONENTIAL pubnub = PubNubAsyncio(pnconf) time_until_open_again = 8 @asyncio.coroutine def close_soon(): yield from asyncio.sleep(2) pubnub._connector.close() print(">>> connection is broken") @asyncio.coroutine def open_again(): yield from asyncio.sleep(time_until_open_again) pubnub.set_connector(aiohttp.TCPConnector(conn_timeout=pubnub.config.connect_timeout, verify_ssl=True)) print(">>> connection is open again") @asyncio.coroutine def countdown(): asyncio.sleep(2) opened = False count = time_until_open_again while not opened: print(">>> %ds to open again" % count) count -= 1 if count <= 0: break yield from asyncio.sleep(1) my_listener = MySubscribeCallback() pubnub.add_listener(my_listener) pubnub.subscribe().channels("my_channel").execute() asyncio.ensure_future(close_soon()) asyncio.ensure_future(open_again()) asyncio.ensure_future(countdown()) yield from asyncio.sleep(1000)
def test_multiple_channels(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = 'test-here-now-asyncio-uuid1' ch1 = "test-here-now-asyncio-ch1" ch2 = "test-here-now-asyncio-ch2" callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels([ch1, ch2]).execute() yield from callback.wait_for_connect() yield from sleeper(5) env = yield from pubnub.here_now() \ .channels([ch1, ch2]) \ .future() assert env.result.total_channels == 2 assert env.result.total_occupancy >= 1 channels = env.result.channels assert len(channels) == 2 assert channels[0].occupancy == 1 assert channels[0].occupants[0].uuid == pubnub.uuid assert channels[1].occupancy == 1 assert channels[1].occupants[0].uuid == pubnub.uuid result = yield from pubnub.here_now() \ .channels([ch1, ch2]) \ .include_state(True) \ .result() assert result.total_channels == 2 pubnub.unsubscribe().channels([ch1, ch2]).execute() yield from callback.wait_for_disconnect() pubnub.stop()
def test_single_channel(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = 'test-here-now-asyncio-uuid1' ch = "test-here-now-asyncio-ch" callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels(ch).execute() yield from callback.wait_for_connect() yield from sleeper(5) env = yield from pubnub.here_now() \ .channels(ch) \ .include_uuids(True) \ .future() assert env.result.total_channels == 1 assert env.result.total_occupancy >= 1 channels = env.result.channels assert len(channels) == 1 assert channels[0].occupancy == 1 assert channels[0].occupants[0].uuid == pubnub.uuid result = yield from pubnub.here_now() \ .channels(ch) \ .include_state(True) \ .result() assert result.total_channels == 1 assert result.total_occupancy == 1 pubnub.unsubscribe().channels(ch).execute() yield from callback.wait_for_disconnect() pubnub.stop()
async def test_encrypted_subscribe_publish_unsubscribe(event_loop): pubnub = PubNubAsyncio(pnconf_enc_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = 'test-subscribe-asyncio-uuid' with patch("pubnub.crypto.PubNubCryptodome.get_initialization_vector", return_value="knightsofni12345"): callback = VCR599Listener(1) channel = "test-subscribe-asyncio-ch" message = "hey" pubnub.add_listener(callback) pubnub.subscribe().channels(channel).execute() await callback.wait_for_connect() publish_future = asyncio.ensure_future( pubnub.publish().channel(channel).message(message).future()) subscribe_message_future = asyncio.ensure_future( callback.wait_for_message_on(channel)) await asyncio.wait([publish_future, subscribe_message_future]) publish_envelope = publish_future.result() subscribe_envelope = subscribe_message_future.result() assert isinstance(subscribe_envelope, PNMessageResult) assert subscribe_envelope.channel == channel assert subscribe_envelope.subscription is None assert subscribe_envelope.message == message assert subscribe_envelope.timetoken > 0 assert isinstance(publish_envelope, AsyncioEnvelope) assert publish_envelope.result.timetoken > 0 assert publish_envelope.status.original_response[0] == 1 pubnub.unsubscribe().channels(channel).execute() await callback.wait_for_disconnect() await pubnub.stop()
async def message_pump(self): pnconfig = PNConfiguration() pnconfig.subscribe_key = config['cardsubkey'] # Why aren't these the default settings? pnconfig.ssl = True pnconfig.reconnect_policy = PNReconnectionPolicy.EXPONENTIAL pubnub = PubNubAsyncio(pnconfig) listener = SubscribeListener() pubnub.add_listener(listener) pubnub.subscribe().channels(config['cardviewerchannel']).execute() await listener.wait_for_connect() log.info("Connected to PubNub") message_future = asyncio.ensure_future(listener.wait_for_message_on(config['cardviewerchannel'])) while True: await asyncio.wait([self.stop_future, message_future], return_when=asyncio.FIRST_COMPLETED) if message_future.done(): message = message_future.result().message log.info("Message from PubNub: %r", message) card_id = self._extract(message) if card_id is not None: await self._card(card_id) message_future = asyncio.ensure_future(listener.wait_for_message_on(config['cardviewerchannel'])) if self.stop_future.done(): break if not message_future.done(): message_future.cancel() pubnub.unsubscribe().channels(config['cardviewerchannel']).execute() await listener.wait_for_disconnect() pubnub.stop() log.info("Disconnected from PubNub")
def test_cg_subscribe_publish_unsubscribe(event_loop, sleeper=asyncio.sleep): ch = "test-subscribe-asyncio-channel" gr = "test-subscribe-asyncio-group" message = "hey" pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 yield from sleeper(1) callback_messages = VCR599Listener(1) pubnub.add_listener(callback_messages) pubnub.subscribe().channel_groups(gr).execute() yield from callback_messages.wait_for_connect() subscribe_future = asyncio.ensure_future(callback_messages.wait_for_message_on(ch)) publish_future = asyncio.ensure_future(pubnub.publish().channel(ch).message(message).future()) yield from asyncio.wait([subscribe_future, publish_future]) sub_envelope = subscribe_future.result() pub_envelope = publish_future.result() assert pub_envelope.status.original_response[0] == 1 assert pub_envelope.status.original_response[1] == 'Sent' assert sub_envelope.channel == ch assert sub_envelope.subscription == gr assert sub_envelope.message == message pubnub.unsubscribe().channel_groups(gr).execute() yield from callback_messages.wait_for_disconnect() envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 pubnub.stop()
def test_cg_subscribe_unsubscribe(event_loop, sleeper=asyncio.sleep): ch = "test-subscribe-asyncio-channel" gr = "test-subscribe-asyncio-group" pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 yield from sleeper(3) callback_messages = SubscribeListener() pubnub.add_listener(callback_messages) pubnub.subscribe().channel_groups(gr).execute() yield from callback_messages.wait_for_connect() pubnub.unsubscribe().channel_groups(gr).execute() yield from callback_messages.wait_for_disconnect() envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 pubnub.stop()
async def test_subscribe_publish_unsubscribe(event_loop): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) callback = SubscribeListener() channel = helper.gen_channel("test-sub-pub-unsub") message = "hey" pubnub.add_listener(callback) pubnub.subscribe().channels(channel).execute() await callback.wait_for_connect() publish_future = asyncio.ensure_future(pubnub.publish().channel(channel).message(message).future()) subscribe_message_future = asyncio.ensure_future(callback.wait_for_message_on(channel)) await asyncio.wait([ publish_future, subscribe_message_future ]) publish_envelope = publish_future.result() subscribe_envelope = subscribe_message_future.result() assert isinstance(subscribe_envelope, PNMessageResult) assert subscribe_envelope.channel == channel assert subscribe_envelope.subscription is None assert subscribe_envelope.message == message assert subscribe_envelope.timetoken > 0 assert isinstance(publish_envelope, AsyncioEnvelope) assert publish_envelope.result.timetoken > 0 assert publish_envelope.status.original_response[0] == 1 pubnub.unsubscribe().channels(channel).execute() await callback.wait_for_disconnect() pubnub.stop()
async def test_global(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = 'test-here-now-asyncio-uuid1' ch1 = "test-here-now-asyncio-ch1" ch2 = "test-here-now-asyncio-ch2" callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels([ch1, ch2]).execute() await callback.wait_for_connect() await sleeper(5) env = await pubnub.here_now().future() assert env.result.total_channels >= 2 assert env.result.total_occupancy >= 1 pubnub.unsubscribe().channels([ch1, ch2]).execute() await callback.wait_for_disconnect() pubnub.stop()
def test_global(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = 'test-here-now-asyncio-uuid1' ch1 = "test-here-now-asyncio-ch1" ch2 = "test-here-now-asyncio-ch2" callback = VCR599Listener(1) pubnub.add_listener(callback) pubnub.subscribe().channels([ch1, ch2]).execute() yield from callback.wait_for_connect() yield from sleeper(5) env = yield from pubnub.here_now().future() assert env.result.total_channels >= 2 assert env.result.total_occupancy >= 1 pubnub.unsubscribe().channels([ch1, ch2]).execute() yield from callback.wait_for_disconnect() pubnub.stop()
class Messages: """Manage connexion with external device""" def __init__(self, subkey, pubkey, id): """Class constructor :param subkey: PubNub subscription key :param pubkey: PubNub publish key :param id: device id (UUID) """ class MySubscribeListener(SubscribeListener): def __init__(self): self._logger = logging.getLogger('sprinkler') super().__init__() def status(self, pubnub, status): if status.category == PNStatusCategory.PNUnexpectedDisconnectCategory: # This event happens when radio / connectivity is lost self._logger.error("Unexpected disconnection") elif status.category == PNStatusCategory.PNConnectedCategory: # Connect event. You can do stuff like publish, and know you'll get it. # Or just use the connected event to confirm you are subscribed for # UI / internal notifications, etc self._logger.info("Connection OK") elif status.category == PNStatusCategory.PNReconnectedCategory: # Happens as part of our regular operation. This event happens when # radio / connectivity is lost, then regained. self._logger.info("Reconnection OK") elif status.category == PNStatusCategory.PNDecryptionErrorCategory: # Handle message decryption error. Probably client configured to # encrypt messages and on live data feed it received plain text. self._logger.error("Decryption error") super().status(pubnub, status) def message(self, pubnub, message): if message.publisher != pubnub.uuid: self._logger.debug(f"RECV from {message.publisher}: \ {json.dumps(message.message['content'])}") super().message(pubnub, message.message['content']) self._logger = logging.getLogger('sprinkler') self.message_listener = MySubscribeListener() self.messages = self.message_listener.message_queue pnconfig = PNConfiguration() pnconfig.subscribe_key = subkey pnconfig.publish_key = pubkey pnconfig.uuid = id pnconfig.ssl = True pnconfig.reconnect_policy = PNReconnectionPolicy.LINEAR pnconfig.subscribe_timeout = 20 self.pubnub = PubNubAsyncio(pnconfig) self.pubnub.add_listener(self.message_listener) self.pubnub.subscribe().channels('sprinkler').execute() def publish_callback(self, task): exception = task.exception() if exception is not None: self._logger.error(f"Sending error: {str(exception)}") async def send(self, msg): asyncio.create_task(self.pubnub.publish().channel("sprinkler").message({'content': msg}).future()). \ add_done_callback(self.publish_callback) self._logger.debug(f"SEND from {self.pubnub.uuid}: {json.dumps(msg)}") def stop(self): self.pubnub.unsubscribe().channels('sprinkler').execute() try: self.message_listener.wait_for_disconnect() except: # Already disconnected pass self.pubnub.stop() self._logger.debug("Message manager stopped") async def get_message(self): return await self.messages.get() def is_message(self): return not self.messages.empty()
# There was an error with the heartbeat operation, handle here else: pass # Heartbeat operation was successful else: pass # Encountered unknown status type def presence(self, pubnub, presence): pass # handle incoming presence data def message(self, pubnub, message): pass # handle incoming messages pubnub.add_listener(MySubscribeCallback()) # > remove listener snippet my_listener = MySubscribeCallback() pubnub.add_listener(my_listener) # some time later pubnub.remove_listener(my_listener) # > handle disconnect snippet class HandleDisconnectsCallback(SubscribeCallback): def status(self, pubnub, status): if status.category == PNStatusCategory.PNUnexpectedDisconnectCategory: # internet got lost, do some magic and call reconnect when ready
class BeekeeperBot: def __init__(self, beekeeper_client, event_loop): """ Args: beekeeper_client (BeekeeperClient): client event_loop """ self._client = beekeeper_client self._event_loop = event_loop or asyncio.get_event_loop() self._pubnub = None self._is_running = False self._callbacks = [] self.conversation_data = {} try: self._pubnub_key = self._client.user_config['tenant'][ 'integrations']['pubnub']['subscribe_key'] self._pubnub_channel_name = self._client.user_config[ 'enc_channel']['channel'] self._pubnub_channel_key = self._client.user_config['enc_channel'][ 'key'] except KeyError: raise BeekeeperBotException('Failed to retrieve PubNub settings') async def __aenter__(self): message_decrypter = BeekeeperBotMessageDecrypter( base64.b64decode(self._pubnub_channel_key)) message_listener = BeekeeperBotMessageListener( bot=self, decrypter=message_decrypter) pubnub_config = PNConfiguration() pubnub_config.subscribe_key = self._pubnub_key pubnub_config.reconnect_policy = PNReconnectionPolicy.LINEAR pubnub_config.connect_timeout = 30 self._pubnub = PubNubAsyncio(config=pubnub_config) self._pubnub.add_listener(message_listener) self._pubnub.subscribe().channels([self._pubnub_channel_name ]).execute() return self async def __aexit__(self, exc_type, exc_val, exc_tb): self._pubnub.unsubscribe_all() self._pubnub.stop() def on_message(self, message): """ Called by the message listener when there is a new message, this function will call callbacks as well Args: message (Message): new message Returns: None """ futures = [cb(self, message) for cb in self._callbacks] asyncio.ensure_future(*futures, loop=self._event_loop) def get_client(self): """ Returns: BeekeeperClient: beekeeper client object """ return self._client def add_callback(self, callback): """ Adds a callback for when a message arrives Args: callback (func): callback function to call Returns: None """ self._callbacks.append(callback)
class Vivint: """Class for interacting with VivintSky API using asyncio""" def __init__( self, username: str, password: str, client_session: Optional[aiohttp.ClientSession] = None, ): self.__pubnub: pubnub.pubnub_asyncio.PubNubAsyncio = None self.vivintskyapi = VivintSkyApi(username, password, client_session) self.systems: List[pyvivint.system.System] = [] async def connect( self, load_devices: bool = False, subscribe_for_realtime_updates: bool = False, ) -> None: """Connects to vivintsky cloud service.""" _LOGGER.debug("connecting to vivintsky") # initialize the vivintsky cloud session authuser_data = await self.vivintskyapi.connect() # load all systems, panels and devices if load_devices: _LOGGER.debug("loading devices") await self.refresh(authuser_data) # subscribe to pubnub for realtime updates if subscribe_for_realtime_updates: _LOGGER.debug("subscribing to pubnub for realtime updates") await self.subscribe_for_realtime_updates(authuser_data) async def disconnect(self) -> None: _LOGGER.debug("disconnecting from vivintsky") await self.vivintskyapi.disconnect() async def refresh(self, authuser_data: dict = None) -> None: # make a call to vivint's authuser endpoint to get a list of all the system_accounts (locations) & panels if not supplied if not authuser_data: authuser_data = await self.vivintskyapi.get_authuser_data() # for each system_account, make another call to load all the devices for system_data in authuser_data["u"]["system"]: # is this an existing account_system? system = first_or_none( self.systems, lambda system: system.id == system_data["panid"] ) if system: await system.refresh() else: full_system_data = await self.vivintskyapi.get_system_data( system_data["panid"] ) self.systems.append( System(system_data.get("sn"), full_system_data, self.vivintskyapi) ) _LOGGER.debug(f"loaded {len(self.systems)} system(s)") async def subscribe_for_realtime_updates(self, authuser_data: dict = None) -> None: """Subscribes to PubNub for realtime updates.""" # make a call to vivint's authuser endpoint to get message broadcast channel if not supplied if not authuser_data: authuser_data = await self.vivintskyapi.get_authuser_data() pubnub.set_stream_logger("pubnub", logging.INFO) pnconfig = PNConfiguration() pnconfig.subscribe_key = PN_SUBSCRIBE_KEY pnconfig.ssl = True pnconfig.reconnect_policy = PNReconnectionPolicy.LINEAR pnconfig.heartbeat_notification_options = PNHeartbeatNotificationOptions.ALL self.__pubnub = PubNubAsyncio(pnconfig) self.__pubnub.add_listener( VivintPubNubSubscribeListener(self.handle_pubnub_message) ) pn_channel = f"{PN_CHANNEL}#{authuser_data[AuthUserAttribute.USERS][AuthUserAttribute.UserAttribute.MESSAGE_BROADCAST_CHANNEL]}" self.__pubnub.subscribe().channels(pn_channel).with_presence().execute() def handle_pubnub_message(self, message: dict) -> None: """Handles a pubnub message.""" _LOGGER.info(f"message: {json.dumps(message)}") panel_id = message.get(MessageAttributes.PANEL_ID) if not panel_id: _LOGGER.info("ignoring pubnub message. No panel_id specified") return system = first_or_none(self.systems, lambda system: system.id == panel_id) if not system: _LOGGER.info(f"no system found with id {panel_id}") return system.handle_pubnub_message(message)
async def test_cg_join_leave(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub_listener = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = "test-subscribe-asyncio-messenger" pubnub_listener.config.uuid = "test-subscribe-asyncio-listener" ch = "test-subscribe-asyncio-join-leave-cg-channel" gr = "test-subscribe-asyncio-join-leave-cg-group" envelope = await pubnub.add_channel_to_channel_group().channel_group( gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 await sleeper(1) callback_messages = VCR599Listener(1) callback_presence = VCR599Listener(1) pubnub_listener.add_listener(callback_presence) pubnub_listener.subscribe().channel_groups(gr).with_presence().execute() await callback_presence.wait_for_connect() prs_envelope = await callback_presence.wait_for_presence_on(ch) assert prs_envelope.event == 'join' assert prs_envelope.uuid == pubnub_listener.uuid assert prs_envelope.channel == ch assert prs_envelope.subscription == gr pubnub.add_listener(callback_messages) pubnub.subscribe().channel_groups(gr).execute() callback_messages_future = asyncio.ensure_future( callback_messages.wait_for_connect()) presence_messages_future = asyncio.ensure_future( callback_presence.wait_for_presence_on(ch)) await asyncio.wait([callback_messages_future, presence_messages_future]) prs_envelope = presence_messages_future.result() assert prs_envelope.event == 'join' assert prs_envelope.uuid == pubnub.uuid assert prs_envelope.channel == ch assert prs_envelope.subscription == gr pubnub.unsubscribe().channel_groups(gr).execute() callback_messages_future = asyncio.ensure_future( callback_messages.wait_for_disconnect()) presence_messages_future = asyncio.ensure_future( callback_presence.wait_for_presence_on(ch)) await asyncio.wait([callback_messages_future, presence_messages_future]) prs_envelope = presence_messages_future.result() assert prs_envelope.event == 'leave' assert prs_envelope.uuid == pubnub.uuid assert prs_envelope.channel == ch assert prs_envelope.subscription == gr pubnub_listener.unsubscribe().channel_groups(gr).execute() await callback_presence.wait_for_disconnect() envelope = await pubnub.remove_channel_from_channel_group().channel_group( gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 await pubnub.stop() pubnub_listener.stop()
class Vivint: """Class for interacting with VivintSky API using asyncio""" def __init__( self, username: str, password: str, loop: Optional[asyncio.events.AbstractEventLoop] = None, client_session: Optional[aiohttp.ClientSession] = None ): self.__loop: asyncio.events.AbstractEventLoop = loop or asyncio.get_event_loop() self.__pubnub: pubnub.pubnub_asyncio.PubNubAsyncio = None self.vivintskyapi = VivintSkyApi(username, password, self.__loop, client_session) self.systems: List[pyvivint.system.System] = [] async def connect( self, load_devices: bool = False, subscribe_for_realtime_updates: bool = False, enable_token_auto_refresh: bool = False ) -> None: """Connects to vivintsky cloud service.""" _LOGGER.debug('connecting to vivintsky') # initialize the vivintsky cloud session await self.vivintskyapi.connect() # load all systems, panels and devices if load_devices: _LOGGER.debug('loading devices') await self.refresh() # set up loop to periodically refresh the token if enable_token_auto_refresh: _LOGGER.debug('setting up token auto refresh loop') self.setup_token_refresh_handler() # subscript to pubnub for realtime updates if subscribe_for_realtime_updates: _LOGGER.debug('subscribing to pubnub for realtime updates') await self.subscripbe_for_realtime_updates() async def disconnect(self) -> None: _LOGGER.debug('disconnecting from vivintsky') await self.vivintskyapi.disconnect() async def refresh(self) -> None: # make a call to vivint's userauth endpoint to get a list of all the system_accounts (locations) & panels authuser_data = await self.vivintskyapi.get_authuser_data() # for each system_account, make another call to load all the devices for system_data in authuser_data['u']['system']: # is this an existing account_system? system = first_or_none(self.systems, lambda system: system.id == system_data['panid']) if system: await system.refresh() else: full_system_data = await self.vivintskyapi.get_system_data(system_data['panid']) self.systems.append(System(full_system_data, self.vivintskyapi)) _LOGGER.debug(f'loaded {len(self.systems)} system(s)') def setup_token_refresh_handler(self) -> None: """Set up the token refresh handler.""" add_async_job(self.__token_refresh_handler) async def __token_refresh_handler(self) -> None: """Periodically refreshes the idtoken.""" while True: id_token = self.vivintskyapi.parse_id_token(self.vivintskyapi.id_token) if id_token['payload']['exp'] - time.time() < 60: await self.vivintskyapi.refresh_token() await asyncio.sleep(1) async def subscripbe_for_realtime_updates(self) -> None: """Subscribes to PubNub for realtime updates.""" # make a call to vivint's userauth endpoint authuser_data = await self.vivintskyapi.get_authuser_data() pubnub.set_stream_logger("pubnub", logging.INFO) pnconfig = PNConfiguration() pnconfig.subscribe_key = PN_SUBSCRIBE_KEY pnconfig.ssl = True pnconfig.reconnect_policy = PNReconnectionPolicy.LINEAR pnconfig.heartbeat_notification_options = PNHeartbeatNotificationOptions.ALL self.__pubnub = PubNubAsyncio(pnconfig) self.__pubnub.add_listener( VivintPubNubSubscribeListener(self.handle_pubnub_message) ) pn_channel = f'{PN_CHANNEL}#{authuser_data[AuthUserAttributes.Users][AuthUserAttributes.UsersAttributes.MessageBroadcastChannel]}' # noqa self.__pubnub.subscribe().channels(pn_channel).with_presence().execute() def handle_pubnub_message(self, message: dict) -> None: """Handles a pubnub message.""" _LOGGER.info(f"message: {json.dumps(message)}") panel_id = message.get(MessageAttributes.PanelId) if not panel_id: _LOGGER.info('ignoring pubnub message. No panel_id specified') return system = first_or_none(self.systems, lambda system: system.id == panel_id) if not system: _LOGGER.info(f'no system found with id {panel_id}') return system.handle_pubnub_message(message)
def test_cg_join_leave(event_loop, sleeper=asyncio.sleep): pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub_listener = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop) pubnub.config.uuid = "test-subscribe-asyncio-messenger" pubnub_listener.config.uuid = "test-subscribe-asyncio-listener" ch = "test-subscribe-asyncio-join-leave-cg-channel" gr = "test-subscribe-asyncio-join-leave-cg-group" envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 yield from sleeper(1) callback_messages = VCR599Listener(1) callback_presence = VCR599Listener(1) pubnub_listener.add_listener(callback_presence) pubnub_listener.subscribe().channel_groups(gr).with_presence().execute() yield from callback_presence.wait_for_connect() prs_envelope = yield from callback_presence.wait_for_presence_on(ch) assert prs_envelope.event == 'join' assert prs_envelope.uuid == pubnub_listener.uuid assert prs_envelope.channel == ch assert prs_envelope.subscription == gr pubnub.add_listener(callback_messages) pubnub.subscribe().channel_groups(gr).execute() callback_messages_future = asyncio.ensure_future(callback_messages.wait_for_connect()) presence_messages_future = asyncio.ensure_future(callback_presence.wait_for_presence_on(ch)) yield from asyncio.wait([callback_messages_future, presence_messages_future]) prs_envelope = presence_messages_future.result() assert prs_envelope.event == 'join' assert prs_envelope.uuid == pubnub.uuid assert prs_envelope.channel == ch assert prs_envelope.subscription == gr pubnub.unsubscribe().channel_groups(gr).execute() callback_messages_future = asyncio.ensure_future(callback_messages.wait_for_disconnect()) presence_messages_future = asyncio.ensure_future(callback_presence.wait_for_presence_on(ch)) yield from asyncio.wait([callback_messages_future, presence_messages_future]) prs_envelope = presence_messages_future.result() assert prs_envelope.event == 'leave' assert prs_envelope.uuid == pubnub.uuid assert prs_envelope.channel == ch assert prs_envelope.subscription == gr pubnub_listener.unsubscribe().channel_groups(gr).execute() yield from callback_presence.wait_for_disconnect() envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr).channels(ch).future() assert envelope.status.original_response['status'] == 200 pubnub.stop() pubnub_listener.stop()