Metadata-Version: 2.1
Name: iotc
Version: 0.3.8
Summary: Azure IoT Central device client for Python
Home-page: https://github.com/Azure/iot-central-firmware
Author: Oguz Bastemur
Author-email: ogbastem@microsoft.com
License: MIT
Keywords: iot,azure,iotcentral
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Description-Content-Type: text/markdown
Requires-Dist: paho-mqtt
Requires-Dist: httplib2

## iotc - Azure IoT Central - Python (light) device SDK Documentation

### Prerequisites

Python 2.7+ or Python 3.4+ or Micropython 1.9+

*Runtime dependencies vary per platform*

### Install

Python 2/3
```shell
pip install iotc
```

### Common Concepts

- API calls should return `0` on success and `error code` otherwise.
- External API naming convention follows `lowerCamelCase` for `Device` class members

### Usage

```py
import iotc
device = iotc.Device(scopeId, keyORCert, deviceId, credType)
```

- *scopeId*    : Azure IoT DPS Scope Id
- *keyORcert*  : Symmetric key or x509 Certificate
- *deviceId*   : Device Id
- *credType*   : `IOTConnectType.IOTC_CONNECT_SYMM_KEY` or `IOTConnectType.IOTC_CONNECT_X509_CERT`

`keyORcert` for `X509` certificate:
```py
credType = IOTConnectType.IOTC_CONNECT_X509_CERT
keyORcert = {
  "keyfile": "/src/python/test/device.key.pem",
  "certfile": "/src/python/test/device.cert.pem"
}
```

`keyORcert` for `SAS` token:
```py
credType = IOTConnectType.IOTC_CONNECT_SYMM_KEY
keyORcert = "xxxxxxxxxxxxxxx........"
```

#### setLogLevel
set logging level
```py
device.setLogLevel(logLevel)
```

*logLevel*   : (default value is `IOTC_LOGGING_DISABLED`)
```py
class IOTLogLevel:
  IOTC_LOGGING_DISABLED =  1
  IOTC_LOGGING_API_ONLY =  2
  IOTC_LOGGING_ALL      = 16
```

*i.e.* => `device.setLogLevel(IOTLogLevel.IOTC_LOGGING_API_ONLY)`

#### setExitOnError
enable/disable application termination on mqtt later exceptions. (default false)
```py
device.setExitOnError(isEnabled)
```

*i.e.* => `device.setExitOnError(True)`

#### setModelData
set the device model data (if any)
```py
device.setModelData(modelJSON)
```

*modelJSON*  : Device model definition.

*i.e.* => `device.setModelData({"iotcModelId":"PUT_MODEL_ID_HERE"})`

#### setTokenExpiration
set the token expiration timeout. default is 21600 seconds (6 hours)
```py
device.setTokenExpiration(totalSeconds)
```

*totalSeconds*  : timeout in seconds.

*i.e.* => `device.setTokenExpiration(600)`

#### setServiceHost
set the service endpoint URL
```py
device.setServiceHost(url)
```

*url*    : URL for service endpoint. (default value is `global.azure-devices-provisioning.net`)

*call this before connect*

#### setQosLevel
Set the MQTT Quality of Service (QoS) level desired for all MQTT publish calls
```py
device.setQosLevel(qosLevel)
```

*qosLevel*   : (default value is `IOTC_QOS_AT_MOST_ONCE`)
```py
class IOTQosLevel:
  IOTC_QOS_AT_MOST_ONCE  = 0
  IOTC_QOS_AT_LEAST_ONCE = 1
```

Note: IOTC_QOS_AT_LEAST_ONCE will have slower performance than IOTC_QOS_AT_MOST_ONCE as the MQTT client must store the value for possible replay and also wait for an acknowledgement from the IoT Hub that the MQTT message has been received.  Think of IOTC_QOS_AT_MOST_ONCE as "fire and forget" vs. IOTC_QOS_AT_LEAST_ONCE as "guaranteed delivery".  As the developer you should consider the importance of 100% data delivery vs. increased connection time and data traffic over the data connection.

*call this before connect*

#### setCleanSession
set the clean session flag of the mqtt client
```py
device.setCleanSession(value)
```

*value*   : boolean flag to enable or disable clean session (default is True)

*call this before connect*

#### connect
connect device client  `# blocking`. Raises `ConnectionStatus` event.

```py
device.connect()
```

or

```py
device.connect(hostName)
```

*i.e.* => `device.connect()`

#### sendTelemetry
send telemetry

```py
device.sendTelemetry(payload, [[optional system properties]])
```

*payload*  : A text payload.

*i.e.* => `device.sendTelemetry('{ "temperature": 15 }')`

You may also set system properties for the telemetry message. See also [iothub message format](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-construct)

*i.e.* => `device.sendTelemetry('{ "temperature":22 }', {"iothub-creation-time-utc": time.time()})`

#### sendState
send device state

```py
device.sendState(payload)
```

*payload*  : A text payload.

*i.e.* => `device.sendState('{ "status": "WARNING"}')`

#### sendProperty
send reported property

```py
device.sendProperty(payload)
```

*payload*  : A text payload.

*i.e.* => `device.sendProperty('{"countdown":{"value": %d}}')`

#### doNext
let framework do the partial MQTT work.

```py
device.doNext()
```

#### isConnected
returns whether the connection was established or not.

```py
device.isConnected()
```

*i.e.* => `device.isConnected()`

#### disconnect
disconnect device client

```py
device.disconnect()
```

*i.e.* => `device.disconnect()`

#### getDeviceSettings
pulls latest twin data (device properties). Raises `SettingsUpdated` event.

```py
device.getDeviceSettings()
```

*i.e.* => `device.getDeviceSettings()`

#### getHostName
returns the iothub hostname cached during the initial connection.

```py
device.getHostName()
```

*i.e.* => `device.getDeviceHostName()`

#### on
set event callback to listen events

- `ConnectionStatus` : connection status has changed
- `MessageSent`      : message was sent
- `Command`          : a command received from Azure IoT Central
- `SettingsUpdated`  : device settings were updated

i.e.
```py
def onconnect(info):
  if info.getStatusCode() == 0:
    print("connected!")

device.on("ConnectionStatus", onconnect)
```

```py
def onmessagesent(info):
  print("message sent -> " + info.getPayload())

device.on("MessageSent", onmessagesent)
```

```py
def oncommand(info):
  print("command name:", info.getTag())
  print("command args: ", info.getPayload())

device.on("Command", oncommand)
```

```py
def onsettingsupdated(info):
  print("setting name:", info.getTag())
  print("setting value: ", info.getPayload())

device.on("SettingsUpdated", onsettingsupdated)
```

#### callback info class

`iotc` callbacks have a single argument derived from `IOTCallbackInfo`.
Using this interface, you can get the callback details and respond back when it's necessary.

public members of `IOTCallbackInfo` are;

`getResponseCode()` : get response code or `None`

`getResponseMessage()` : get response message or `None`

`setResponse(responseCode, responseMessage)` : set callback response

*i.e.* => `info.setResponse(200, 'completed')`

`getClient()` : get active `device` client

`getEventName()` : get the name of the event

`getPayload()` : get the payload or `None`

`getTag()` : get the tag or `None`

`getStatusCode()` : get callback status code

#### sample app

```py
import iotc
from iotc import IOTConnectType, IOTLogLevel
from random import randint

deviceId = "DEVICE_ID"
scopeId = "SCOPE_ID"
deviceKey = "DEVICE_KEY"

# see iotc.Device documentation above for x509 argument sample
iotc = iotc.Device(scopeId, deviceKey, deviceId, IOTConnectType.IOTC_CONNECT_SYMM_KEY)
iotc.setLogLevel(IOTLogLevel.IOTC_LOGGING_API_ONLY)
iotc.setQosLevel(IOTQosLevel.IOTC_QOS_AT_MOST_ONCE)

gCanSend = False
gCounter = 0

def onconnect(info):
  global gCanSend
  print("- [onconnect] => status:" + str(info.getStatusCode()))
  if info.getStatusCode() == 0:
     if iotc.isConnected():
       gCanSend = True
  elif info.getStatusCode() == 5: # token expired. force reconnection
       gCanSend = False
       iotc.connect()

def onmessagesent(info):
  print("\t- [onmessagesent] => " + str(info.getPayload()))

def oncommand(info):
  print("command name:", info.getTag())
  print("command value: ", info.getPayload())

def onsettingsupdated(info):
  print("setting name:", info.getTag())
  print("setting value: ", info.getPayload())

iotc.on("ConnectionStatus", onconnect)
iotc.on("MessageSent", onmessagesent)
iotc.on("Command", oncommand)
iotc.on("SettingsUpdated", onsettingsupdated)

iotc.connect()

while iotc.isConnected():
  iotc.doNext() # do the async work needed to be done for MQTT
  if gCanSend == True:
    if gCounter % 20 == 0:
      gCounter = 0
      print("Sending telemetry..")
      iotc.sendTelemetry("{\"temp\": " + str(randint(20, 45)) + "}")

    gCounter += 1
```

