コード例 #1
0
    def setUp(self):
        """Mock the HTTP request method so that the long poll does not received anything."""
        self.patch = mock.patch('urllib3.PoolManager.request')
        mocked = self.patch.start()
        mocked.return_value.data = b''
        mocked.return_value.status = 200

        self.api = ConnectAPI(dict(autostart_notification_thread=False))
コード例 #2
0
 def test_observer_timeout(self):
     """Test that the observer timeouts"""
     from mbed_cloud.connect import ConnectAPI
     api = ConnectAPI()
     observer = api.subscribe(
         api.subscribe.channels.DeviceStateChanges(device_id=123456))
     with self.assertRaises(CloudTimeoutError) as timeout_error:
         observer.next().block(timeout=2)
     self.assertEqual(str(timeout_error.exception),
                      "No data received after 2.0 seconds.")
コード例 #3
0
def worker(start, api_key, results):
    print('hi')
    start.wait()  # let's all start at the same time
    print('go')
    api = ConnectAPI(dict(api_key=api_key))
    time.sleep(random.triangular(0.1, 0.2, 0.5))
    codegen_layer = api._get_api(NotificationsApi)
    key_set = codegen_layer.api_client.configuration.api_key['Authorization']
    print('get/set %r %r' % (api_key, key_set))
    results.append(key_set)
コード例 #4
0
 def test_live_device_state_change(self):
     # integration - DeviceStateChanges local filter
     from mbed_cloud.connect import ConnectAPI
     api = ConnectAPI()
     d = api.list_connected_devices().first()
     observer = api.subscribe(api.subscribe.channels.DeviceStateChanges(device_id=d.id))
     # cheat, waiting takes too long
     api.subscribe.notify({
         channels.ChannelIdentifiers.reg_updates: [
             dict(a=1, b=2, device_id=d.id),
             dict(a=1, b=2, device_id='A'),
             dict(a=1, b=2, device_id='B'),
         ]
     })
     r = observer.next().block(timeout=2)
     self.assertTrue(r)
コード例 #5
0
    def test_live_device_state_change(self):
        api = ConnectAPI()
        api.delete_presubscriptions()
        d = api.list_connected_devices().first()
        api.delete_device_subscriptions(d.id)
        channel = channels.ResourceValues(device_id=d.id,
                                          resource_path=['/3/0/*'])
        observer = api.subscribe(channel)
        # don't actually care about notifications, we want to see subscriptions
        current_subs = api.list_device_subscriptions(d.id)
        self.assertGreaterEqual(len(current_subs), 3)
        for path in current_subs:
            self.assertIn('/3/0', path)

        channel.stop()
        current_subs = api.list_device_subscriptions(d.id)
        self.assertIsNone(None, current_subs)
コード例 #6
0
    def test_live_device_state_change(self):
        api = ConnectAPI()
        d = api.list_connected_devices().first()
        api.delete_device_subscriptions(d.id)

        # request the `manufacturer` field
        channel = channels.CurrentResourceValue(device_id=d.id, resource_path='/3/0/0')
        observer = api.subscribe(channel)
        value = observer.next().block(timeout=2)
        # should be, in this case, TLV
        self.assertEqual(b'6465765f6d616e756661637475726572', value)
コード例 #7
0
    def test_live_create_and_cleanup(self):
        # integration - ResourceValueCurrent cleans up
        from mbed_cloud.connect import ConnectAPI
        api = ConnectAPI()
        d = api.list_connected_devices().first()
        r = api.subscribe(api.subscribe.channels.ResourceValues(
            device_id=d.id,
            resource_path='/3/0/0',
        )).next().block(timeout=2)
        self.assertTrue(r)

        # wait for notifications to be stopped
        api.stop_notifications()

        # check that the routing table is cleaned up
        for i in range(10):
            time.sleep(0.01)
            if not api.subscribe.list_all():
                break
        else:
            self.fail('Routing table not empty')
コード例 #8
0
class SDKTests(BaseHostTest):

    __result = None
    deviceApi = None
    connectApi = None
    deviceID = None
    iteration = None
    post_timeout = None

    def send_safe(self, key, value):
        #self.send_kv('dummy_start', 0)
        self.send_kv(key, value)
        self.send_kv(key, value)
        self.send_kv(key, value)
        self.send_kv(key, value)
        self.send_kv(key, value)
        #self.send_kv('dummy_end', 1)

    def test_steps(self):
        # Step 0 set up test
        system_reset = yield

        # Step 1 device connected to Pelion should reset.
        self.send_safe('reset', 0)
        time.sleep(self.program_cycle_s)
        self.send_safe('__sync', 0)
        self.iteration = self.iteration + 1
        system_reset = yield

        #Step 2, finish
        yield True

    def _callback_device_ready(self, key, value, timestamp):
        # Send device iteration number after a reset
        self.send_safe('iteration', self.iteration)

    def _callback_advance_test(self, key, value, timestamp):
        # Advance test sequence
        try:
            if self.test_steps_sequence.send(None):
                self.notify_complete(True)
        except (StopIteration, RuntimeError) as exc:
            self.notify_complete(False)

    def _callback_device_api_registration(self, key, value, timestamp):
        try:
            #set value for later use
            self.deviceID = value

            # Check if device is in Mbed Cloud Device Directory
            device = self.deviceApi.get_device(value)

            # Send registraton status to device
            self.send_safe("registration",
                           1 if device.state == "registered" else 0)
        except:
            # SDK throws an exception if the device is not found (unsuccessful registration) or times out
            self.send_safe("registration", 0)

    def _callback_device_verification(self, key, value, timestamp):
        # Send true if old DeviceID is the same as current device is
        self.send_safe("verification", 1 if self.deviceID == value else 0)

    def _callback_fail_test(self, key, value, timestamp):
        # Test failed. End it.
        self.notify_complete(False)

    def _callback_device_lwm2m_get_verification(self, key, value, timestamp):
        timeout = 0

        # Get resource value from device
        async_response = self.connectApi.get_resource_value_async(
            self.deviceID, value)

        # Set a 30 second timeout here.
        while not async_response.is_done and timeout <= 300:
            time.sleep(0.1)
            timeout += 1

        if async_response.is_done:
            # Send resource value back to device
            self.send_safe("get_value", async_response.value)
        else:
            # Request timed out.
            self.send_safe("timeout", 0)

    def _callback_device_lwm2m_set_verification(self, key, value, timestamp):
        timeout = 0

        # Get resource value from device
        async_response = self.connectApi.get_resource_value_async(
            self.deviceID, value)

        # Set a 30 second timeout here.
        while not async_response.is_done and timeout <= 300:
            time.sleep(0.1)
            timeout += 1

        if async_response.is_done:
            # Send resource value back to device
            self.send_safe("set_value", async_response.value)
        else:
            # Request timed out.
            self.send_safe("timeout", 0)

    def _callback_device_lwm2m_put_verification(self, key, value, timestamp):
        timeout = 0

        # Get resource value from device and increment it
        resource_value = self.connectApi.get_resource_value_async(
            self.deviceID, value)

        # Set a 30 second timeout here.
        while not resource_value.is_done and timeout <= 300:
            time.sleep(0.1)
            timeout += 1

        if not resource_value.is_done:
            self.send_safe("timeout", 0)
            return

        updated_value = int(resource_value.value) + 5

        # Set new resource value from cloud
        async_response = self.connectApi.set_resource_value_async(
            self.deviceID, value, updated_value)

        # Set a 30 second timeout here.
        while not async_response.is_done and timeout <= 300:
            time.sleep(0.1)
            timeout += 1

        if not async_response.is_done:
            self.send_safe("timeout", 0)
        else:
            # Send new resource value to device for verification.
            self.send_safe("res_set", updated_value)

    def _callback_device_lwm2m_post_verification(self, key, value, timestamp):
        timeout = 0

        # Execute POST function on device
        resource_value = self.connectApi.execute_resource_async(
            self.deviceID, value)

        # Set a 30 second timeout here.
        while not resource_value.is_done and timeout <= 300:
            time.sleep(0.1)
            timeout += 1

        if not resource_value.is_done:
            self.send_safe("timeout", 0)
            self.post_timeout = 1

    def _callback_device_lwm2m_post_verification_result(
            self, key, value, timestamp):

        # Called from callback function on device, POST function working as expected.
        # If post_timeout is not none, the request took longer than 30 seconds, which is
        # a failure. Don't send this value.
        if not self.post_timeout:
            self.send_safe("post_test_executed", 0)

    def setup(self):
        #Start at iteration 0
        self.iteration = 0

        # Register callbacks from GT tests
        self.register_callback('device_api_registration',
                               self._callback_device_api_registration)
        self.register_callback('advance_test', self._callback_advance_test)
        self.register_callback('device_ready', self._callback_device_ready)
        self.register_callback('device_verification',
                               self._callback_device_verification)
        self.register_callback('fail_test', self._callback_fail_test)
        self.register_callback('device_lwm2m_get_test',
                               self._callback_device_lwm2m_get_verification)
        self.register_callback('device_lwm2m_set_test',
                               self._callback_device_lwm2m_set_verification)
        self.register_callback('device_lwm2m_put_test',
                               self._callback_device_lwm2m_put_verification)
        self.register_callback('device_lwm2m_post_test',
                               self._callback_device_lwm2m_post_verification)
        self.register_callback(
            'device_lwm2m_post_test_result',
            self._callback_device_lwm2m_post_verification_result)

        # Setup API config
        try:
            result = subprocess.check_output(["mbed", "config", "-G", "CLOUD_SDK_API_KEY"], \
                                              stderr=subprocess.STDOUT)
        except Exception, e:
            print "Error: CLOUD_SDK_API_KEY global config is not set: " + str(
                e)
            return -1

        result = str(result).split(' ')
        if result[1] == "No":
            print "Error: CLOUD_SDK_API_KEY global config is not set."
            return -1

        # Get API KEY and remove LF char if included
        api_key_val = str(result[1]).rstrip()
        print "CLOUD_SDK_API_KEY: " + api_key_val

        api_config = {
            "api_key": api_key_val,
            "host": "https://api.us-east-1.mbedcloud.com"
        }

        # Instantiate Device and Connect API
        self.deviceApi = DeviceDirectoryAPI(api_config)
        self.connectApi = ConnectAPI(api_config)
コード例 #9
0
 def test_empty_string(self):
     self.assertEqual(ConnectAPI._base64_encode(""), "")
コード例 #10
0
 def test_string(self):
     self.assertEqual(ConnectAPI._base64_encode("Hello World"),
                      "SGVsbG8gV29ybGQ=")
コード例 #11
0
import os
import pprint
from mbed_cloud.connect import ConnectAPI

TOKEN = "YOUR_ACCESS_KEY"

# set up the Python SDK
config = {}
config['api_key'] = os.getenv('TOKEN') or TOKEN
config['host'] = 'https://api.us-east-1.mbedcloud.com'
api = ConnectAPI(config)
api.start_notifications()

devices = list(
    api.list_connected_devices(filters={'device_type': 'light-system'}))

print("Found %d lights" % (len(devices)), [c.id for c in devices])

for device in devices:

    def pir_callback(device_id, path, count):
        print("Motion detected at %s, new count is %s" % (device_id, count))

    api.add_resource_subscription_async(device.id, '/3201/0/5700',
                                        pir_callback)
    print("subscribed to resource")

    pink = 0xff69b4
    api.set_resource_value(device.id, '/3311/0/5706', pink)
    print("set color to pink")
コード例 #12
0
 def test_positive_int(self):
     self.assertEqual(ConnectAPI._base64_encode(1), "MQ==")
コード例 #13
0
# Use 'threading' async_mode, as we don't use greenlet threads for background threads
# in SDK - and thus we can't use eventlet or gevent.
async_mode = 'threading'

# API key from https://portal.mbedcloud.com/. Can also be set by setting the value
# with ACCESS_KEY environment variable.
api_key = ""

app = Flask(__name__)
socket = SocketIO(app,
                  async_mode=async_mode,
                  logger=True,
                  engineio_logger=True)
#api = DeviceAPI({"api_key": os.environ.get("ACCESS_KEY", api_key)})
api = ConnectAPI({
    "api_key": os.environ.get("ACCESS_KEY", api_key),
    "host": "https://lab-api.mbedcloudintegration.net"
})
logging.basicConfig(stream=sys.stdout, level=logging.INFO)


@app.route('/')
def index():
    devices = []
    for device in api.list_connected_devices():
        logging.info("Device Found: {}".format(device.id))
        value = api.get_resource_value(device.id, BLINK_PATTERN_RESOURCE_PATH)
        devices.append({
            'id': device.id,
            'blink_pattern': value.decode('utf-8')
        })
コード例 #14
0
app.config.from_object(settings.Config)

# Override params with CLI inputs
if args.api_key_val:
    app.config["API_KEY"] = args.api_key_val

if args.host_val:
    app.config["API_HOST"] = args.host_val

WEBHOOK_URL = "%s/api/webhook" % app.config["API_BASE_URL"]
PRODUCT_ID_PATH = "/10341/0/26341"
PRODUCT_CURR_COUNT_PATH = "/10341/0/26342"

# Instatiate cloud connect
api_config = {"api_key": app.config["API_KEY"], "host": app.config["API_HOST"]}
connectApi = ConnectAPI(api_config)
# This should be required, why is it breaking things
connectApi.start_notifications()

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

# Instantiate the database client on Table named 'example'
# Set the username and password to root
db = InfluxDBClient("influxdb", app.config["INFLUX_PORT"], 'root', 'root',
                    'example')

id_num_db = {}


def handleSubscribe(device_id, path, current_value):
    """On change in subscribed resource, dump data to InfluxDB."""
コード例 #15
0
class TestGetResourceValue(BaseCase):
    def setUp(self):
        """Mock the HTTP request method so that the long poll does not received anything."""
        self.patch = mock.patch('urllib3.PoolManager.request')
        mocked = self.patch.start()
        mocked.return_value.data = b''
        mocked.return_value.status = 200

        self.api = ConnectAPI(dict(autostart_notification_thread=False))

    def tearDown(self):
        self.patch.stop()

    def test_async_wait(self):
        """Test a all registration notifications in a single message"""
        async_result = self.api.get_resource_value_async("abc123", "/3/0/0")

        example_data = {
            "async-responses": [{
                "ct": "text/plain",
                "payload": "My4zMQ==",
                "max-age": "60",
                "id": async_result.async_id,
                "error": None,
                "status": 202
            }],
        }
        self.api.notify_webhook_received(payload=json.dumps(example_data))

        self.assertEqual('3.31', async_result.wait())

    def test_async_wait_error(self):
        """Test a all registration notifications in a single message"""
        async_result = self.api.get_resource_value_async("abc123", "/3/0/0")

        example_data = {
            "async-responses": [{
                "ct": "text/plain",
                "payload": "My4zMQ==",
                "max-age": "60",
                "id": async_result.async_id,
                "error": "TIMEOUT",
                "status": 504
            }],
        }
        self.api.notify_webhook_received(payload=json.dumps(example_data))

        # An Async response with an error should raise an exception
        with self.assertRaises(CloudAsyncError) as e:
            async_result.wait()

        self.assertTrue(
            str(e.exception).startswith("(504) 'TIMEOUT' Async response for"))
        self.assertEqual("TIMEOUT", e.exception.reason)
        self.assertEqual(504, e.exception.status)

    def test_async_value_error(self):
        """Test a all registration notifications in a single message"""
        async_result = self.api.get_resource_value_async("abc123", "/3/0/0")

        example_data = {
            "async-responses": [{
                "ct": "text/plain",
                "payload": None,
                "max-age": "60",
                "id": async_result.async_id,
                "error": "AN ERROR",
                "status": 499
            }],
        }

        self.api.notify_webhook_received(payload=json.dumps(example_data))

        # Attempted to get the value when there is an error and no payload should raise an exception
        with self.assertRaises(CloudUnhandledError) as e:
            async_result.value

        self.assertEqual(
            "(499) 'AN ERROR' Attempted to decode async request which returned an error.",
            str(e.exception))
        self.assertEqual("AN ERROR", e.exception.reason)
        self.assertEqual(499, e.exception.status)
コード例 #16
0
- [optional] Visit `https://YOUR_NGROK_ID_GOES_HERE.ngrok.io/404`
  (a 404 page will indicate that your connection works)
- Visit `http://127.0.0.1:8000/start` in your browser to initiate the sequence
- View the result of the application in the terminal

"""
from mbed_cloud.connect import ConnectAPI

import hug

import os
import sys
import threading
import traceback

api = ConnectAPI()
ngrok_url = sys.argv[-1] if len(sys.argv) == 4 else (
    os.environ.get('NGROK_URL') or 'https://YOUR_NGROK_ID_GOES_HERE.ngrok.io')
os.environ['NGROK_URL'] = ngrok_url
resource_path = "/3/0/2"


def my_application(api):
    """An example application.

    - Registers a webhook with mbed cloud services
    - Requests the value of a resource
    - Prints the value when it arrives
    """
    device = api.list_connected_devices().first()
    print('using device #', device.id)
コード例 #17
0
 def test_negative_int(self):
     self.assertEqual(ConnectAPI._base64_encode(-1), "LTE=")
コード例 #18
0
 def test_positive_float(self):
     self.assertEqual(ConnectAPI._base64_encode(1.0), "MS4w")
コード例 #19
0
 def test_negative_float(self):
     self.assertEqual(ConnectAPI._base64_encode(-1.0), "LTEuMA==")
コード例 #20
0
"""

# an example: using a webhook for handling notifications from mbed cloud
from mbed_cloud.connect import ConnectAPI

import hug

import os
import sys
import threading
import traceback

# we must disable automatic creation of a long-poll thread
# as webhooks and long polling are mutually exclusive on mbed cloud
api = ConnectAPI(dict(autostart_notification_thread=False))
ngrok_url = sys.argv[-1] if len(sys.argv) == 4 else (
    os.environ.get('NGROK_URL') or 'https://YOUR_NGROK_ID_GOES_HERE.ngrok.io')
os.environ['NGROK_URL'] = ngrok_url
resource_path = "/3/0/2"


def my_application(api):
    """An example application.

    - Registers a webhook with mbed cloud services
    - Requests the value of a resource
    - Prints the value when it arrives
    """
    device = api.list_connected_devices().first()
    print('using device #', device.id)
コード例 #21
0
 def test_none(self):
     self.assertEqual(ConnectAPI._base64_encode(None), "")
コード例 #22
0
import signal
import threading
import traceback
import binascii
import json
from collections import namedtuple

from mbed_cloud.connect import ConnectAPI
from mbed_cloud.device_directory import DeviceDirectoryAPI
from mbed_cloud.exceptions import CloudApiException

wait_condition = threading.Condition()
wait_condition.acquire()
keep_running = True

API_connect = ConnectAPI()
API_device_directory = DeviceDirectoryAPI()


def byte_to_hex(value):
    return binascii.hexlify(value)


def byte_to_int(value):
    if len(value) == 2:
        # unsigned short, uint16_t
        return struct.unpack("<H", value)[0]
    elif len(value) == 4:
        # unsigned int, uint32_t
        return struct.unpack("<i", value)[0]
    else:
コード例 #23
0
    def test_registration_notifications(self):
        """Test a all registration notifications in a single message"""
        from mbed_cloud.connect import ConnectAPI
        device_id = "015f3850a657000000000001001002ab"
        api = ConnectAPI()
        registrations_observer = api.subscribe(
            api.subscribe.channels.DeviceStateChanges(
                device_id=device_id,
                channel=channels.ChannelIdentifiers.registrations),
            provider=False)
        de_registrations_observer = api.subscribe(
            api.subscribe.channels.DeviceStateChanges(
                device_id=device_id,
                channel=channels.ChannelIdentifiers.de_registrations))
        reg_updates_observer = api.subscribe(
            api.subscribe.channels.DeviceStateChanges(
                device_id=device_id,
                channel=channels.ChannelIdentifiers.reg_updates))
        registrations_expired_observer = api.subscribe(
            api.subscribe.channels.DeviceStateChanges(
                device_id=device_id,
                channel=channels.ChannelIdentifiers.registrations_expired))
        # cheat, waiting takes too long
        example_data = {
            "registrations": [{
                "q":
                False,
                "original-ep":
                "my-device-123",
                "ept":
                "Light",
                "resources": [{
                    "path": "/sen/light",
                    "ct": "text/plain",
                    "obs": True,
                    "rt": "light_sensor",
                    "if": "sensor"
                }],
                "ep":
                device_id
            }],
            "reg_updates": [{
                "q":
                False,
                "original-ep":
                "my-device-123",
                "ept":
                "Light",
                "resources": [{
                    "path": "/sen/light",
                    "ct": "text/plain",
                    "obs": True,
                    "rt": "light_sensor",
                    "if": "sensor"
                }],
                "ep":
                device_id
            }],
            "async_responses": [{
                "ct": "text/plain",
                "payload": "My4zMQ==",
                "max-age": "60",
                "id": "9e3c96b8-c4d7-496a-ab90-cc732b9b560e",
                "error": "TIMEOUT",
                "status": 200
            }],
            "notifications": [{
                "path": "/sen/light",
                "ct": "text/plain",
                "payload": "My4zMQ==",
                "max-age": "60",
                "ep": device_id
            }],
            "de_registrations": [device_id],
            "registrations_expired": [device_id],
        }

        api.subscribe.notify(example_data)

        self.assertEqual(
            registrations_observer.next().block(timeout=2), {
                'alias':
                None,
                'channel':
                'registrations',
                'device_id':
                '015f3850a657000000000001001002ab',
                'device_type':
                'Light',
                'queue_mode':
                False,
                'resources': [{
                    'content_type': 'text/plain',
                    'observable': True,
                    'path': '/sen/light',
                    'type': 'light_sensor'
                }]
            })
        self.assertEqual(
            de_registrations_observer.next().block(timeout=2), {
                'channel': 'de_registrations',
                'device_id': '015f3850a657000000000001001002ab'
            })
        self.assertEqual(
            reg_updates_observer.next().block(timeout=2), {
                'alias':
                None,
                'channel':
                'reg_updates',
                'device_id':
                '015f3850a657000000000001001002ab',
                'device_type':
                'Light',
                'queue_mode':
                False,
                'resources': [{
                    'content_type': 'text/plain',
                    'observable': True,
                    'path': '/sen/light',
                    'type': 'light_sensor'
                }]
            })
        self.assertEqual(
            registrations_expired_observer.next().block(timeout=2), {
                'channel': 'registrations_expired',
                'device_id': '015f3850a657000000000001001002ab'
            })