class IoTHub:
    def __init__(self, iothub_name, owner_key, suffix='.azure-devices.net'):
        self.iothub_name = iothub_name
        self.owner_key = owner_key
        self.suffix = suffix
        self.owner_connection_string = 'HostName={0}{1};SharedAccessKeyName=iothubowner;SharedAccessKey={2}'.format(
            self.iothub_name, self.suffix, owner_key)
        self.registry_manager = IoTHubRegistryManager(
            self.owner_connection_string)
        self.device_twin = IoTHubDeviceTwin(self.owner_connection_string)
        self.__device_clients = {}

    def create_device(self, device_id, primary_key='', secondary_key=''):
        return self.registry_manager.create_device(
            device_id, primary_key, secondary_key,
            IoTHubRegistryManagerAuthMethod.SHARED_PRIVATE_KEY)

    def get_device_list(self):
        return self.registry_manager.get_device_list(
            1000)  # NOTE: this API is marked as deprecated,
        # but Python SDK doesn't seem to offer
        # an alternative yet (03/25/2018).

    def get_device_twin(self, device_id):
        return self.device_twin.get_twin(device_id)

    def update_twin(self, device_id, payload):
        return self.device_twin.update_twin(device_id, payload)
Exemple #2
0
def get_iothub_device_twin(methodname):

    try:
        retVal = 0
        iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
        # Query for device twin
        twin_info = iothub_twin_method.get_twin(DEVICE_ID)
        payload = json.loads(twin_info)
        if methodname == 'ota':
            retVal = payload["properties"]["reported"]["softwareUpdate"]
        if methodname == 'failure_status':
            data = payload["properties"]["reported"]["softwareUpdate"][
                "failure_status"]
            msg = dict()
            msg["failure_status"] = data
            retVal = msg
        if methodname == 'reboot':
            retVal = payload["properties"]["reported"]["rebootStatus"]
        if methodname == 'id':
            data = payload["properties"]["reported"]["Id"]
            msg = dict()
            msg["Id"] = data
            retVal = msg
        return retVal

    except IoTHubError as iothub_error:
        print("")
        print("Unexpected error {0}" % iothub_error)
        return "error"
    except KeyboardInterrupt:
        print("")
        print("IoTHubModuleTwin sample stopped")
Exemple #3
0
 def __init__(self, iothub_name, owner_key, suffix='.azure-devices.net'):
     self.iothub_name = iothub_name
     self.owner_key = owner_key
     self.iothub_host = iothub_name + suffix
     self.owner_connection_string ='HostName={0};SharedAccessKeyName=iothubowner;SharedAccessKey={1}'.format(self.iothub_host, owner_key)
     self.registry_manager = IoTHubRegistryManager(self.owner_connection_string)
     self.device_twin = IoTHubDeviceTwin(self.owner_connection_string)
     self.__device_clients = {}
Exemple #4
0
    def _update_reboot(self):
        UPDATE_JSON = "{\"properties\":{\"desired\":{\"reboot\":\"%s\"}}}"
        try:
            post = json.load(request.body)
            msg_json = UPDATE_JSON % (str(post['reboot']))
            iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
            twin_info = iothub_twin_method.update_twin(DEVICE_ID, msg_json)
        except Exception as err:
            return str(err)

        return "200 OK\n"
def iothub_devicetwin():

    iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
    twin_info = iothub_twin_method.get_twin(DEVICE_ID)
    print("")
    print("Device Twin before update    :")
    print("{0}".format(twin_info))

    twin_info = iothub_twin_method.update_twin(DEVICE_ID, TWIN_MSG)
    print("")
    print("Device Twin after update     :")
    print("{0}".format(twin_info))
Exemple #6
0
    def _update_device_twin(self):
        #self._enable_cors()
        UPDATE_JSON = "{\"properties\":{\"desired\":{\"software_version\":\"%s\", \"reboot\":\"%s\", \"url\":\"%s\"}}}"
        try:
            post = json.load(request.body)
            msg_json = UPDATE_JSON % (str(post['software_version']),
                                      str(post['reboot']), str(post['url']))
            iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
            twin_info = iothub_twin_method.update_twin(DEVICE_ID, msg_json)
        except Exception as err:
            return str(err)

        return "200 OK\n"
Exemple #7
0
    def _update_log_time(self):
        self._enable_cors()
        UPDATE_JSON = "{\"properties\":{\"desired\":{\"time\":\"%s\"}}}"
        try:
            byte_str = request.body.read()
            text_obj = byte_str.decode('UTF-8')
            post = json.loads(text_obj)
            msg_json = UPDATE_JSON % (str(post['time']))
            iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
            twin_info = iothub_twin_method.update_twin(DEVICE_ID, msg_json)
        except Exception as err:
            return str(err)

        return "200 OK\n"
Exemple #8
0
def get_iothub_device_twin():

    try:
        iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
        # Query for device twin
        twin_info = iothub_twin_method.get_twin(DEVICE_ID)
        payload = json.loads(twin_info)
        return payload["properties"]["reported"]["softwareUpdate"]

    except IoTHubError as iothub_error:
        print("")
        print("Unexpected error {0}" % iothub_error)
        return "error"
    except KeyboardInterrupt:
        print("")
        print("IoTHubModuleTwin sample stopped")
def iothub_firmware_sample_run():
    try:
        iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)

        print("")
        print("Direct Method called.")
        iothub_device_method = IoTHubDeviceMethod(CONNECTION_STRING)

        response = iothub_device_method.invoke(DEVICE_ID, METHOD_NAME,
                                               METHOD_PAYLOAD, TIMEOUT)
        print(response.payload)

        print("")
        print("Device Twin queried, press Ctrl-C to exit")
        while True:
            twin_info = iothub_twin_method.get_twin(DEVICE_ID)

            if "\"firmwareStatus\":\"standBy\"" in twin_info:
                print("Waiting on device...")
            elif "\"firmwareStatus\":\"downloading\"" in twin_info:
                print("Downloading firmware...")
            elif "\"firmwareStatus\":\"applying\"" in twin_info:
                print("Download complete, applying firmware...")
            elif "\"firmwareStatus\":\"completed\"" in twin_info:
                print("Firmware applied")
                print("")
                print("Get reported properties from device twin:")
                print(twin_info)
                break
            else:
                print("Unknown status")

            status_counter = 0
            while status_counter <= MESSAGE_COUNT:
                time.sleep(1)
                status_counter += 1

    except IoTHubError as iothub_error:
        print("")
        print("Unexpected error {0}" % iothub_error)
        return
    except KeyboardInterrupt:
        print("")
        print("IoTHubService sample stopped")
def iothub_devicemethod_sample_run():
    try:
        iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
        iothub_device_method = IoTHubDeviceMethod(CONNECTION_STRING)

        print("")
        print("Invoking device to reboot...")

        response = iothub_device_method.invoke(DEVICE_ID, METHOD_NAME,
                                               METHOD_PAYLOAD, TIMEOUT)

        print("")
        print("Successfully invoked the device to reboot.")

        print("")
        print(response.payload)

        while True:
            print("")
            print("IoTHubClient waiting for commands, press Ctrl-C to exit")

            status_counter = 0
            while status_counter <= WAIT_COUNT:
                twin_info = iothub_twin_method.get_twin(DEVICE_ID)

                if twin_info.find("rebootTime") != -1:
                    print("Last reboot time: " +
                          twin_info[twin_info.find("rebootTime") +
                                    11:twin_info.find("rebootTime") + 37])
                else:
                    print("Waiting for device to report last reboot time...")

                time.sleep(5)
                status_counter += 1

    except IoTHubError as iothub_error:
        print("")
        print("Unexpected error {0}".format(iothub_error))
        return
    except KeyboardInterrupt:
        print("")
        print("IoTHubDeviceMethod sample stopped")
def iothub_devicetwin_sample_run():

    try:
        iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
        twin_info = iothub_twin_method.get_twin(DEVICE_ID)
        print("")
        print("Device Twin before update    :")
        print("{0}".format(twin_info))

        twin_info = iothub_twin_method.update_twin(DEVICE_ID, UPDATE_JSON)
        print("")
        print("Device Twin after update     :")
        print("{0}".format(twin_info))

    except IoTHubError as iothub_error:
        print("")
        print("Unexpected error {0}" % iothub_error)
        return
    except KeyboardInterrupt:
        print("")
        print("IoTHubDeviceTwin sample stopped")
def iothub_twin_sample_run():

    try:
        iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
        if (MODULE_ID is None):
            # Query for device twin
            twin_info = iothub_twin_method.get_twin(DEVICE_ID)
        else:
            # Query for module twin
            twin_info = iothub_twin_method.get_twin(DEVICE_ID, MODULE_ID)
        print("")
        print("Twin before update    :")
        print("{0}".format(twin_info))

        if (MODULE_ID is None):
            # Update device twin
            twin_info = iothub_twin_method.update_twin(DEVICE_ID, UPDATE_JSON)
        else:
            # Update module twin
            twin_info = iothub_twin_method.update_twin(DEVICE_ID, MODULE_ID,
                                                       UPDATE_JSON)
        print("")
        print("Twin after update     :")
        print("{0}".format(twin_info))

    except IoTHubError as iothub_error:
        print("")
        print("Unexpected error {0}" % iothub_error)
        return
    except KeyboardInterrupt:
        print("")
        print("IoTHubModuleTwin sample stopped")
Exemple #13
0
def sc_create_twin(iothub_connection_string):
    iothub_device_twin = IoTHubDeviceTwin(IOTHUB_CONNECTION_STRING)
    assert iothub_device_twin != None, "iothub_device_twin is NULL"
    return iothub_device_twin
Exemple #14
0
def run_e2e_twin(iothub_connection_string, testing_modules):
    try:
        # prepare
        device_id = generate_device_name()
        assert isinstance(device_id, str), 'Invalid type returned!'

        primary_key = ""
        secondary_key = ""
        auth_method = IoTHubRegistryManagerAuthMethod.SHARED_PRIVATE_KEY

        iothub_registry_manager = IoTHubRegistryManager(
            iothub_connection_string)
        new_device = iothub_registry_manager.create_device(
            device_id, primary_key, secondary_key, auth_method)

        if testing_modules == True:
            new_module = iothub_registry_manager.create_module(
                device_id, primary_key, secondary_key, TEST_MODULE_ID,
                auth_method)

        ###########################################################################
        # IoTHubDeviceTwin

        # act
        iothub_device_twin = IoTHubDeviceTwin(IOTHUB_CONNECTION_STRING)

        # verify
        assert iothub_device_twin != None, "iothub_device_twin is NULL"
        ###########################################################################

        ###########################################################################

        # Wait before get twin...
        sleep_before_device_action()

        ###########################################################################
        # get_twin

        # act
        if testing_modules == True:
            twin_info = iothub_device_twin.get_twin(device_id, TEST_MODULE_ID)
        else:
            twin_info = iothub_device_twin.get_twin(device_id)

        # verify
        assert twin_info != None, "twin_info is NULL"
        json_ok = twin_info.find("deviceId")
        assert json_ok > 0, "twin_info does not contain deviceId tag"
        json_ok = twin_info.find(device_id)
        assert json_ok > 0, "twin_info does not contain the correct device id"

        if testing_modules == True:
            json_ok = twin_info.find("moduleId")
            assert json_ok > 0, "twin_info does not contain moduleId tag"

        json_ok = twin_info.find("etag")
        assert json_ok > 0, "twin_info does not contain etag tag"
        json_ok = twin_info.find("properties")
        assert json_ok > 0, "twin_info does not contain properties tag"
        ###########################################################################

        print("")
        print("Twin before update:")
        print("{0}".format(twin_info))

        ###########################################################################
        # update_twin

        # prepare
        new_property_name = "telemetryInterval"
        new_property_value = "42"
        UPDATE_JSON = "{\"properties\":{\"desired\":{\"" + new_property_name + "\":" + new_property_value + "}}}"

        # act
        if testing_modules == True:
            twin_info = iothub_device_twin.update_twin(device_id,
                                                       TEST_MODULE_ID,
                                                       UPDATE_JSON)
        else:
            twin_info = iothub_device_twin.update_twin(device_id, UPDATE_JSON)

        # verify
        assert twin_info != None, "twin_info is NULL"
        json_ok = twin_info.find("deviceId")
        assert json_ok > 0, "twin_info does not contain deviceId tag"
        json_ok = twin_info.find(device_id)
        assert json_ok > 0, "twin_info does not contain the correct device id"

        json_ok = twin_info.find("etag")
        assert json_ok > 0, "twin_info does not contain etag tag"
        json_ok = twin_info.find("properties")
        assert json_ok > 0, "twin_info does not contain properties tag"

        json_ok = twin_info.find(new_property_name)
        assert json_ok > 0, "twin_info does not contain " + new_property_name + " tag"
        json_ok = twin_info.find(new_property_value)
        assert json_ok > 0, "twin_info does not contain " + new_property_value
        ###########################################################################

        print("")
        print("Device Twin after update:")
        print("{0}".format(twin_info))
        print("")
        retval = 0
    except Exception as e:
        print("")
        print("run_e2e_twin() failed with exception: {0}".format(e))
        retval = 1
    finally:
        # clean-up
        if testing_modules == True:
            iothub_registry_manager.delete_module(device_id, TEST_MODULE_ID)

        iothub_registry_manager.delete_device(device_id)

    return retval
class IoTHub:
    def __init__(self, iothub_name, owner_key, suffix='.azure-devices.net'):
        self.iothub_name = iothub_name
        self.owner_key = owner_key
        self.iothub_host = iothub_name + suffix
        self.owner_connection_string = 'HostName={0};SharedAccessKeyName=iothubowner;SharedAccessKey={1}'.format(
            self.iothub_host, owner_key)
        self.registry_manager = IoTHubRegistryManager(
            self.owner_connection_string)
        self.device_twin = IoTHubDeviceTwin(self.owner_connection_string)
        self.__device_clients = {}

    def create_device(self, device_id, primary_key='', secondary_key=''):
        return self.registry_manager.create_device(
            device_id, primary_key, secondary_key,
            IoTHubRegistryManagerAuthMethod.SHARED_PRIVATE_KEY)

    def get_device_list(self):
        return self.registry_manager.get_device_list(
            1000)  # NOTE: this API is marked as deprecated,
        # but Python SDK doesn't seem to offer
        # an alternative yet (03/25/2018).

    def get_device_twin(self, device_id):
        return self.device_twin.get_twin(device_id)

    def __get_sas_token(self, device_id, key, policy, expiry=3600):
        ttl = time() + expiry
        uri = '{0}/devices/{1}'.format(self.iothub_host, device_id)
        sign_key = "%s\n%d" % ((quote_plus(uri)), int(ttl))

        signature = b64encode(
            HMAC(b64decode(key), sign_key.encode('utf-8'), sha256).digest())

        rawtoken = {'sr': uri, 'sig': signature, 'se': str(int(ttl))}

        rawtoken['skn'] = policy

        sas = 'SharedAccessSignature ' + urlencode(rawtoken)
        return sas
        # return 'HostName={0}{1};DeviceId={2};SharedAccessSignature={3}'.format(self.iothub_name, self.suffix, device_id, sas)

    def update_twin(self, device_id, payload, etag='*'):
        """
            Update device twin.
            Unfortunately, Python IoTHub SDK does not implement optimistic concurrency, so
            falling back to the REST API.

            SDK equivalent:
            return self.device_twin.update_twin(device_id, payload)
        """
        twin_url = 'https://{0}/twins/{1}?api-version=2017-06-30'.format(
            self.iothub_host, device_id)
        sas_token = self.__get_sas_token(device_id, self.owner_key,
                                         'iothubowner')
        headers = {
            'Authorization': sas_token,
            'Content-Type': 'application/json',
            'If-Match': '"{0}"'.format(etag)
        }

        payload_json = json.loads(payload)

        keys = map(str.lower, payload_json.keys())

        if 'tags' not in keys:
            payload_json['tags'] = {}

        if 'desiredproperties' not in keys:
            payload_json['desiredProperties'] = {}

        payload = json.dumps(payload_json)

        r = requests.patch(twin_url, data=payload, headers=headers)
        assert r.status_code == HTTPStatus.OK

        return r.text

    def claim_device(self, client_id):
        while True:
            claimed_device = self.try_claim_device(client_id)
            if claimed_device:
                return claimed_device
            sleep(5)

    def try_claim_device(self, client_id):
        try:
            devices = self.get_device_list()
        except:
            return

        random.shuffle(devices)
        for device in devices:
            if device.connectionState == IoTHubDeviceConnectionState.CONNECTED:
                continue

            if device.status == IoTHubDeviceStatus.DISABLED:
                continue

            # attempt to acquire lock using device twin's optimistic concurrency
            twin_data = self.get_device_twin(device.deviceId)
            twin_data_json = json.loads(twin_data)
            etag = twin_data_json['etag']

            twin_tags = None
            if 'tags' not in twin_data_json:
                twin_tags = {}
            else:
                twin_tags = twin_data_json['tags']

            if 'simulated' not in twin_tags or not twin_tags['simulated']:
                continue

            if 'simulator' not in twin_tags:
                continue

            current_time = datetime.datetime.now().replace(tzinfo=None)

            if '_claim' in twin_tags:
                simulator_data = twin_tags['_claim']
                if 'lastClaimed' in simulator_data:
                    last_claimed = dateutil.parser.parse(
                        simulator_data['lastClaimed']).replace(tzinfo=None)
                    if (current_time - last_claimed).total_seconds() < 30:
                        continue

            twin_tags['_claim'] = {
                'clientId': client_id,
                'lastClaimed': current_time.isoformat()
            }

            updated_properties = {'tags': twin_tags}

            try:
                updated_twin_data = self.update_twin(
                    device.deviceId, json.dumps(updated_properties), etag)
                return device, updated_twin_data
            except:
                continue
def run_e2e_devicetwin(iothub_connection_string):
    try:
        # prepare
        device_id = generate_device_name()
        assert isinstance(device_id, str), 'Invalid type returned!'

        primary_key = ""
        secondary_key = ""
        auth_method = IoTHubRegistryManagerAuthMethod.SHARED_PRIVATE_KEY

        iothub_registry_manager = IoTHubRegistryManager(iothub_connection_string)
        new_device = iothub_registry_manager.create_device(device_id, primary_key, secondary_key, auth_method)

        ###########################################################################
        # IoTHubDeviceTwin

        # act
        iothub_device_twin = IoTHubDeviceTwin(IOTHUB_CONNECTION_STRING)

        # verify
        assert iothub_device_twin != None, "iothub_device_twin is NULL"
        ###########################################################################

        ###########################################################################

        # Wait before get twin...
        time.sleep(SLEEP_BEFORE_DEVICE_ACTION)

        ###########################################################################
        # get_twin

        # act
        twin_info = iothub_device_twin.get_twin(device_id)

        # verify
        assert twin_info != None, "twin_info is NULL"
        json_ok = twin_info.find("deviceId")
        assert json_ok > 0, "twin_info does not contain deviceId tag"
        json_ok = twin_info.find(device_id)
        assert json_ok > 0, "twin_info does not contain the correct device id"

        json_ok = twin_info.find("etag")
        assert json_ok > 0, "twin_info does not contain etag tag"
        json_ok = twin_info.find("properties")
        assert json_ok > 0, "twin_info does not contain properties tag"
        ###########################################################################

        print ( "" )
        print ( "Device Twin before update:" )
        print ( "{0}".format(twin_info) )

        ###########################################################################
        # update_twin

        # prepare
        new_property_name = "telemetryInterval"
        new_property_value = "42"
        UPDATE_JSON = "{\"properties\":{\"desired\":{\"" + new_property_name + "\":" + new_property_value + "}}}"

        # act
        twin_info = iothub_device_twin.update_twin(device_id, UPDATE_JSON)

        # verify
        assert twin_info != None, "twin_info is NULL"
        json_ok = twin_info.find("deviceId")
        assert json_ok > 0, "twin_info does not contain deviceId tag"
        json_ok = twin_info.find(device_id)
        assert json_ok > 0, "twin_info does not contain the correct device id"

        json_ok = twin_info.find("etag")
        assert json_ok > 0, "twin_info does not contain etag tag"
        json_ok = twin_info.find("properties")
        assert json_ok > 0, "twin_info does not contain properties tag"

        json_ok = twin_info.find(new_property_name)
        assert json_ok > 0, "twin_info does not contain " + new_property_name + " tag"
        json_ok = twin_info.find(new_property_value)
        assert json_ok > 0, "twin_info does not contain " + new_property_value
        ###########################################################################

        print ( "" )
        print ( "Device Twin after update:" )
        print ( "{0}".format(twin_info) )
        print ( "" )
        retval = 0
    except Exception as e:
        print ( "" )
        print ("run_e2e_devicetwin() failed with exception: {0}".format(e))
        retval = 1
    finally:
        # clean-up
        iothub_registry_manager.delete_device(device_id)

    return retval