Skip to content

Commit 134c4f1

Browse files
author
ludruda
committed
refactor samples
1 parent cf4e832 commit 134c4f1

23 files changed

+729
-613
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ build
1616
dist
1717

1818
# virtualenv
19+
.env2
20+
.env3
1921
Include/
2022
Lib/
2123
Scripts/

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ These clients are available with an asynchronous API, as well as a blocking sync
3434
## Samples
3535
Check out the [sample repository](samples) for example code showing how the SDK can be used in the various scenarios:
3636

37-
* [py3](samples/py3.py) - Sending telemetry and receiving properties and commands with device connected through **symmetric key** (Python 3.7+)
38-
* [py3_x509](samples/py3_x509.py) - Sending telemetry and receiving properties and commands with device connected through **x509 certificates** (Python 3.7+)
39-
* [py3_file_logger](samples/py3_file_logger.py) - Print logs on file with rotation (Python 3.7+)
40-
* [py3_eventhub_logger](samples/py3_eventhub_logger.py) - Redirect logs to Azure Event Hub (Python 3.7+)
37+
* [async_device_key](samples/async_device_key) - Sending telemetry and receiving properties and commands with device connected through **symmetric key** (Python 3.7+)
38+
* [async_x509](samples/async_x509.py) - Sending telemetry and receiving properties and commands with device connected through **x509 certificates** (Python 3.7+)
39+
* [async_file_logger](samples/async_file_logger.py) - Print logs on file with rotation (Python 3.7+)
40+
* [async_eventhub_logger](samples/async_eventhub_logger.py) - Redirect logs to Azure Event Hub (Python 3.7+)
4141

4242

4343
**The following samples are legacy samples**, they work with the sycnhronous API intended for use with Python 2.7, or in compatibility scenarios with later versions. We recommend you use the asynchronous API and Python3 samples above instead.
4444

4545

46-
* [py2](samples/py2.py) - Sending telemetry and receiving properties and commands with device connected through **symmetric key** (Python 2.7+)
47-
* [py2_x509](samples/py2_x509.py) - Sending telemetry and receiving properties and commands with device connected through **x509 certificates** (Python 2.7+)
46+
* [sync_device_key](samples/sync_device_key.py) - Sending telemetry and receiving properties and commands with device connected through **symmetric key** (Python 2.7+)
47+
* [sync_x509](samples/sync_x509.py) - Sending telemetry and receiving properties and commands with device connected through **x509 certificates** (Python 2.7+)
4848

4949

5050
Samples by default parse a configuration file including required credentials. Just create a file called **samples.ini** inside the _samples_ folder with a content like this:

samples/py3.py renamed to samples/async_device_key.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,19 @@
2424
device_id = config["DEVICE_M3"]["DeviceId"]
2525
scope_id = config["DEVICE_M3"]["ScopeId"]
2626
key = config["DEVICE_M3"]["DeviceKey"]
27+
hub_name = config["DEVICE_M3"]["HubName"]
2728

2829

2930
class MemStorage(Storage):
3031
def retrieve(self):
3132
return CredentialsCache(
32-
"iotc-1f9e162c-eacc-408d-9fb2-c9926a071037.azure-devices.net",
33-
"javasdkcomponents2",
33+
hub_name,
34+
device_id,
3435
key,
3536
)
3637

3738
def persist(self, credentials):
39+
# a further option would be updating config file with latest hub name
3840
return None
3941

4042

@@ -59,7 +61,15 @@ async def on_enqueued_commands(command:Command):
5961
print("Received offline command {} with value {}".format(command.name, command.value))
6062

6163

62-
# change connect type to reflect the used key (device or group)
64+
#### change connect type to reflect the used key (device or group)
65+
# client = IoTCClient(
66+
# device_id,
67+
# scope_id,
68+
# IOTCConnectType.IOTC_CONNECT_SYMM_KEY,
69+
# group_key,
70+
# storage=MemStorage(),
71+
# )
72+
6373
client = IoTCClient(
6474
device_id,
6575
scope_id,
@@ -75,25 +85,9 @@ async def on_enqueued_commands(command:Command):
7585
client.on(IOTCEvents.IOTC_COMMAND, on_commands)
7686
client.on(IOTCEvents.IOTC_ENQUEUED_COMMAND, on_enqueued_commands)
7787

78-
# iotc.setQosLevel(IOTQosLevel.IOTC_QOS_AT_MOST_ONCE)
79-
80-
async def telemetry_loop():
81-
while client.is_connected():
82-
await client.send_telemetry(
83-
{
84-
"acceleration": {
85-
"x": str(randint(20, 45)),
86-
"y": str(randint(20, 45)),
87-
"z": str(randint(20, 45)),
88-
}
89-
}
90-
)
91-
await asyncio.sleep(3)
92-
9388
async def main():
9489
await client.connect()
9590
await client.send_property({"writeableProp": 50})
96-
# await client.run_telemetry_loop(telemetry_loop)
9791

9892
while client.is_connected():
9993
print("client connected {}".format(client._device_client.connected))
@@ -107,6 +101,5 @@ async def main():
107101
}
108102
)
109103
await asyncio.sleep(3)
110-
# await client.disconnect()
111104

112105
asyncio.run(main())

samples/async_eventhub_logger.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import os
2+
import asyncio
3+
import configparser
4+
import sys
5+
6+
from random import randint
7+
8+
config = configparser.ConfigParser()
9+
config.read(os.path.join(os.path.dirname(__file__), "samples.ini"))
10+
11+
if config["DEFAULT"].getboolean("Local"):
12+
sys.path.insert(0, "src")
13+
14+
from iotc import (
15+
IOTCConnectType,
16+
IOTCLogLevel,
17+
IOTCEvents,
18+
Command,
19+
CredentialsCache,
20+
Storage,
21+
)
22+
from iotc.aio import IoTCClient
23+
24+
class EventHubLogger:
25+
def __init__(self, conn_str, eventhub_name):
26+
self._producer = EventHubProducerClient.from_connection_string(conn_str, eventhub_name=eventhub_name)
27+
28+
async def _create_batch(self):
29+
self._event_data_batch = await self._producer.create_batch()
30+
31+
async def _log(self, message):
32+
event_data_batch = await self._producer.create_batch()
33+
event_data_batch.add(EventData(message))
34+
await self._producer.send_batch(event_data_batch)
35+
36+
async def info(self, message):
37+
if self._log_level != IOTCLogLevel.IOTC_LOGGING_DISABLED:
38+
await self._log(message)
39+
40+
async def debug(self, message):
41+
if self._log_level == IOTCLogLevel.IOTC_LOGGING_ALL:
42+
await self._log(message)
43+
44+
def set_log_level(self, log_level):
45+
self._log_level = log_level
46+
47+
48+
49+
device_id = config["DEVICE_M3"]["DeviceId"]
50+
scope_id = config["DEVICE_M3"]["ScopeId"]
51+
key = config["DEVICE_M3"]["DeviceKey"]
52+
hub_name = config["DEVICE_M3"]["HubName"]
53+
54+
event_hub_conn_str = config['EventHub']['ConnectionString']
55+
event_hub_name = config['EventHub']['EventHubName']
56+
57+
58+
59+
class MemStorage(Storage):
60+
def retrieve(self):
61+
return CredentialsCache(
62+
hub_name,
63+
device_id,
64+
key,
65+
)
66+
67+
def persist(self, credentials):
68+
# a further option would be updating config file with latest hub name
69+
return None
70+
71+
72+
# optional model Id for auto-provisioning
73+
try:
74+
model_id = config["DEVICE_M3"]["ModelId"]
75+
except:
76+
model_id = None
77+
78+
79+
async def on_props(property_name, property_value, component_name):
80+
print("Received {}:{}".format(property_name, property_value))
81+
return True
82+
83+
84+
async def on_commands(command: Command):
85+
print("Received command {} with value {}".format(command.name, command.value))
86+
await command.reply()
87+
88+
89+
async def on_enqueued_commands(command:Command):
90+
print("Received offline command {} with value {}".format(command.name, command.value))
91+
92+
93+
# change connect type to reflect the used key (device or group)
94+
client = IoTCClient(
95+
device_id,
96+
scope_id,
97+
IOTCConnectType.IOTC_CONNECT_DEVICE_KEY,
98+
key,
99+
logger=EventHubLogger(event_hub_conn_str,event_hub_name)
100+
storage=MemStorage(),
101+
)
102+
if model_id != None:
103+
client.set_model_id(model_id)
104+
105+
client.set_log_level(IOTCLogLevel.IOTC_LOGGING_ALL)
106+
client.on(IOTCEvents.IOTC_PROPERTIES, on_props)
107+
client.on(IOTCEvents.IOTC_COMMAND, on_commands)
108+
client.on(IOTCEvents.IOTC_ENQUEUED_COMMAND, on_enqueued_commands)
109+
110+
async def main():
111+
await client.connect()
112+
await client.send_property({"writeableProp": 50})
113+
114+
while client.is_connected():
115+
print("client connected {}".format(client._device_client.connected))
116+
await client.send_telemetry(
117+
{
118+
"acceleration": {
119+
"x": str(randint(20, 45)),
120+
"y": str(randint(20, 45)),
121+
"z": str(randint(20, 45)),
122+
}
123+
}
124+
)
125+
await asyncio.sleep(3)
126+
127+
asyncio.run(main())

samples/async_file_logger.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import os
2+
import asyncio
3+
import configparser
4+
import sys
5+
6+
from random import randint
7+
8+
config = configparser.ConfigParser()
9+
config.read(os.path.join(os.path.dirname(__file__), "samples.ini"))
10+
11+
if config["DEFAULT"].getboolean("Local"):
12+
sys.path.insert(0, "src")
13+
14+
from iotc import (
15+
IOTCConnectType,
16+
IOTCLogLevel,
17+
IOTCEvents,
18+
Command,
19+
CredentialsCache,
20+
Storage,
21+
)
22+
from iotc.aio import IoTCClient
23+
24+
class FileLogger:
25+
def __init__(self,logpath,logname="iotc_py_log"):
26+
self._logger=logging.getLogger(logname)
27+
self._logger.setLevel(logging.DEBUG)
28+
handler= logging.handlers.RotatingFileHandler(
29+
os.path.join(logpath,logname), maxBytes=20, backupCount=5)
30+
self._logger.addHandler(handler)
31+
32+
async def _log(self, message):
33+
print(message)
34+
self._logger.debug(message)
35+
36+
async def info(self, message):
37+
if self._log_level != IOTCLogLevel.IOTC_LOGGING_DISABLED:
38+
await self._log(message)
39+
40+
async def debug(self, message):
41+
if self._log_level == IOTCLogLevel.IOTC_LOGGING_ALL:
42+
await self._log(message)
43+
44+
def set_log_level(self, log_level):
45+
self._log_level = log_level
46+
47+
48+
49+
device_id = config["DEVICE_M3"]["DeviceId"]
50+
scope_id = config["DEVICE_M3"]["ScopeId"]
51+
key = config["DEVICE_M3"]["DeviceKey"]
52+
hub_name = config["DEVICE_M3"]["HubName"]
53+
log_path = config['FileLog']['LogsPath']
54+
55+
56+
57+
class MemStorage(Storage):
58+
def retrieve(self):
59+
return CredentialsCache(
60+
hub_name,
61+
device_id,
62+
key,
63+
)
64+
65+
def persist(self, credentials):
66+
# a further option would be updating config file with latest hub name
67+
return None
68+
69+
70+
# optional model Id for auto-provisioning
71+
try:
72+
model_id = config["DEVICE_M3"]["ModelId"]
73+
except:
74+
model_id = None
75+
76+
77+
async def on_props(property_name, property_value, component_name):
78+
print("Received {}:{}".format(property_name, property_value))
79+
return True
80+
81+
82+
async def on_commands(command: Command):
83+
print("Received command {} with value {}".format(command.name, command.value))
84+
await command.reply()
85+
86+
87+
async def on_enqueued_commands(command:Command):
88+
print("Received offline command {} with value {}".format(command.name, command.value))
89+
90+
91+
# change connect type to reflect the used key (device or group)
92+
client = IoTCClient(
93+
device_id,
94+
scope_id,
95+
IOTCConnectType.IOTC_CONNECT_DEVICE_KEY,
96+
key,
97+
logger=FileLogger(log_path)
98+
storage=MemStorage(),
99+
)
100+
if model_id != None:
101+
client.set_model_id(model_id)
102+
103+
client.set_log_level(IOTCLogLevel.IOTC_LOGGING_ALL)
104+
client.on(IOTCEvents.IOTC_PROPERTIES, on_props)
105+
client.on(IOTCEvents.IOTC_COMMAND, on_commands)
106+
client.on(IOTCEvents.IOTC_ENQUEUED_COMMAND, on_enqueued_commands)
107+
108+
async def main():
109+
await client.connect()
110+
await client.send_property({"writeableProp": 50})
111+
112+
while client.is_connected():
113+
print("client connected {}".format(client._device_client.connected))
114+
await client.send_telemetry(
115+
{
116+
"acceleration": {
117+
"x": str(randint(20, 45)),
118+
"y": str(randint(20, 45)),
119+
"z": str(randint(20, 45)),
120+
}
121+
}
122+
)
123+
await asyncio.sleep(3)
124+
125+
asyncio.run(main())

0 commit comments

Comments
 (0)