diff --git a/.gitignore b/.gitignore index 998f878..2b44de5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ exp.py **/__pycache__ *.pyc *.pyo +.pypirc +*.ini # VSCODE .vscode/ diff --git a/CHANGELOG b/CHANGELOG index c037453..9377fb5 100755 --- a/CHANGELOG +++ b/CHANGELOG @@ -39,7 +39,7 @@ ### 0.3.1 -- new `sendTelemetry` interface for system property support. see README +- new `send_telemetry` interface for system property support. see README - update to 'SettingsUpdated' logic. Now individual setting values include '$version' - new 'setExitOnError' interface provides an option to enable exiting from app on mqtt layer issues. diff --git a/README.md b/README.md index 2f3cef2..9da4821 100755 --- a/README.md +++ b/README.md @@ -12,6 +12,13 @@ ``` pip install azure-iotcentral-device-client ``` +These clients are available with an asynchronous API, as well as a blocking synchronous API for compatibility scenarios. **We recommend you use Python 3.7+ and the asynchronous API.** + +| Python Version | Asynchronous API | Synchronous API | +| -------------- | ---------------- | --------------- | +| Python 3.5.3+ | **YES** | **YES** | +| Python 2.7 | NO | **YES** | + ## Samples Check out the [sample repository](samples) for example code showing how the SDK can be used in the various scenarios: @@ -22,27 +29,44 @@ Check out the [sample repository](samples) for example code showing how the SDK * Sending telemetry and receiving properties and commands with device connected through x509 certificates (Python 2.7+) * Sending telemetry and receiving properties and commands with device connected through x509 certificates (Python 3.7+) +Samples by default parse a configuration file including required credentials. Just create a file called **samples.ini** inside the _samples_ folder with this content: + +```ini +[SymmetricKey] +ScopeId = scopeid +DeviceId = deviceid +Key = group_or_device_key + +[x509] +ScopeId = scopeid +DeviceId = deviceid +CertFilePath = path_to_cert_file +KeyFilePath = path_to_key_file +CertPassphrase = optional password +``` +The configuration file can include one of the sections or both. Section names must match references in the sample file. + ## Importing the module Sync client (Python 2.7+ and 3.7+) can be imported in this way: -``` +```py from azure.iotcentral.device.client import IoTCClient ``` Async client (with asyncio for Python 3.7+ only) can be imported like this: -``` +```py from azure.iotcentral.device.client.aio import IoTCClient ``` ## Connecting #### X509 -``` +```py scopeId = 'scopeID'; -deviceId = 'deviceID'; +device_id = 'device_id'; key = {'certFile':'','keyFile':'','certPhrase':''} -iotc = IoTCClient(deviceId, scopeId, +iotc = IoTCClient(device_id, scopeId, IOTCConnectType.IOTC_CONNECT_X509_CERT, key) ``` IOTCConnectType enum can be imported from the same module of IoTCClient @@ -53,12 +77,12 @@ _'certPhrase'_ is optional and represents the password for the certificate if an #### SAS -``` +```py scopeId = 'scopeID'; -deviceId = 'deviceID'; +device_id = 'device_id'; sasKey = 'masterKey'; # or use device key directly -iotc = IoTCClient(deviceId, scopeId, +iotc = IoTCClient(device_id, scopeId, IOTCConnectType.IOTC_CONNECT_SYMM_KEY, sasKey) ``` IOTCConnectType enum can be imported from the same module of IoTCClient @@ -69,7 +93,7 @@ Sync iotc.connect() ``` Async -``` +```py await iotc.connect() ``` After successfull connection, IOTC context is available for further commands. @@ -78,9 +102,9 @@ After successfull connection, IOTC context is available for further commands. ### Send telemetry e.g. Send telemetry every 3 seconds -``` +```py while iotc.isConnected(): - await iotc.sendTelemetry({ + await iotc.send_telemetry({ 'accelerometerX': str(randint(20, 45)), 'accelerometerY': str(randint(20, 45)), "accelerometerZ": str(randint(20, 45)) @@ -91,15 +115,15 @@ An optional *properties* object can be included in the send methods, to specify Properties can be custom or part of the reserved ones (see list [here](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/src/MessageSystemPropertyNames.cs#L36)). ### Send property update -``` +```py iotc.sendProperty({'fieldName':'fieldValue'}); ``` ### Listen to properties update -``` +```py iotc.on(IOTCEvents.IOTC_PROPERTIES, callback); ``` To provide setting sync aknowledgement, the callback must reply **True** if the new value has been applied or **False** otherwise -``` +```py async def onProps(propName, propValue): print(propValue) return True @@ -108,13 +132,13 @@ iotc.on(IOTCEvents.IOTC_PROPERTIES, onProps); ``` ### Listen to commands -``` +```py iotc.on(IOTCEvents.IOTC_COMMAND, callback) ``` To provide feedbacks for the command like execution result or progress, the client can call the **ack** function available in the callback. The function accepts 3 arguments: command name, a custom response message and the request id for which the ack applies. -``` +```py async def onCommands(command, ack): print(command.name) await ack(command.name, 'Command received', command.request_id) @@ -129,7 +153,7 @@ Template Id can be found in the device explorer page of IoTCentral Then call this method before connect(): -``` +```py iotc.setModelId(''); ``` diff --git a/samples/py2_x509.py b/samples/py2_x509.py index efd46d2..6490271 100644 --- a/samples/py2_x509.py +++ b/samples/py2_x509.py @@ -9,7 +9,7 @@ config.read(os.path.join(os.path.dirname(__file__),'samples.ini')) device_id = config['x509']['DeviceId'] scope_id = config['x509']['ScopeId'] -key = {'certFile': config['x509']['CertFilePath'],'keyFile':config['x509']['KeyFilePath'],'certPhrase':config['x509']['CertPassphrasePath']} +key = {'certFile': config['x509']['CertFilePath'],'keyFile':config['x509']['KeyFilePath'],'certPhrase':config['x509']['CertPassphrase']} # optional model Id for auto-provisioning try: diff --git a/samples/py3_x509.py b/samples/py3_x509.py index c49ffc4..90e38a2 100644 --- a/samples/py3_x509.py +++ b/samples/py3_x509.py @@ -9,7 +9,7 @@ config.read(os.path.join(os.path.dirname(__file__),'samples.ini')) device_id = config['x509']['DeviceId'] scope_id = config['x509']['ScopeId'] -key = {'certFile': config['x509']['CertFilePath'],'keyFile':config['x509']['KeyFilePath'],'certPhrase':config['x509']['CertPassphrasePath']} +key = {'certFile': config['x509']['CertFilePath'],'keyFile':config['x509']['KeyFilePath'],'certPhrase':config['x509']['CertPassphrase']} # optional model Id for auto-provisioning try: