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")
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)
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")
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))
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 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