.. _subscriptions: Subscriptions ************* In the Conductor/Airfinder python library, any :class:`.UplinkSubject` can be subscribed to. While this would naturally include all Conductor :ref:`c-devices` and Airfinder :ref:`af-devices`. It also includes some other subjects such as :ref:`account`/:ref:`user`, :ref:`app-tok`, and :ref:`asset_groups`. To instantiate the `sub` (subscription) object, you must first choose which type of subscription to instantiate. **Polling Subscription** While not being true "subscription", the :class:`.PollingSubscription` provides a quick and easy way to receive uplink events in the same paradigm as the other subscription subclasses. All that is required to instantiate a polling subscription is the :class:`.UplinkSubject` and the polling interval. :: u = conductor.airfinder.User("handle@email.com") ap = u.get_access_point("xx:xx:xx:xx:xx:xx") sub = ap.build_polling_sub(polling_int_s=5) Then, retrieving the uplink events would be the same as previously described from the :class:`.SubscriptionBase` class. In this example, the polling interval is set to 5 seconds. This indicates that the subscription thread will issue an HTTP GET call every 5 seconds, then notify the user when a new message is detected. This is a good subscription mechanism for prototyping as it does not require any external dependencies or network setups, while using the same paradigm as more production-ready subscription models offered by the Conductor/Airfinder Library. **ZeroMQ 2 Subscription** .. important:: ZeroMQ Subscriptions require port-forwarding on the machine that is executing the subscription, as well as sufficient firewall permissions given the port number of choice. ZeroMQ offers a more faster, more efficient and more reliable subscription mechanism to retrieve uplink events. However, networking must be configured on the machine of operation to utilize the subscription. To utilize the ZeroMQ subscription, one must first install the zmq library :: pip install pyzmq With the library installed, only the selected open port is required to setup the subscription :: u = conductor.airfinder.User("handle@email.com") ap = u.get_access_point("xx:xx:xx:xx:xx:xx") sub = ap.build_zmq_sub(port=11101) Retrieving uplink events would be the same as previously described from the :class:`.SubscriptionBase` class. **WebSocket Subscription** .. danger:: Websockets are currently proxied in the Conductor backend, which the websocket library we used does not currently support! The workaround here is to manually install this fork of the library for the proxy work-around: https://github.com/mdymike/websockets. While more data efficient than the :class:`.PollingSubscription`, the :class:`.WebsocketSubscription` is slightly less reliable. They will occasionally close need to be reopened behind the scenes. However, they do not require any firewall or port-forwarding modifications. To enable the websocket subscription, the following dependency is required :: pip install websockets No further arguments are required to instanciate a websocket subscription. :: u = conductor.airfinder.User("handle@email.com") ap = u.get_access_point("xx:xx:xx:xx:xx:xx") sub = ap.build_ws_sub() **MQTT Subscription** .. danger:: Not Implemented! Stay tuned. :: pip install paho-mqtt **Recieving Messages from Subscriptions** All subscriptions are based off the :class:`.SubscriptionBase`, which offers both asynchronous and blocking methods for receiving subscription events. Here is a generic example of using callbacks to asynchronously receive subscription events :: sub.start() # Start Subscription Thread while True: # Do other stuff continue sub.stop() # Kill Subscription Thread Here is a generic example of using an iterator to receive subscription events while blocking :: sub.start() # Start Subscription Thread for msg in sub.iter(): # Iterate through each rxed message # Do other stuff. print(msg) sub.stop() # Kill Subscription Thread