fix tests and readme
This commit is contained in:
Родитель
c6b9ce4582
Коммит
acfbe660da
|
@ -11,6 +11,6 @@ samples/
|
|||
.vscode/
|
||||
|
||||
# publish
|
||||
iotc.egg-info
|
||||
azure_iotcentral_device_client.egg-info
|
||||
build
|
||||
dist
|
|
@ -1 +1,2 @@
|
|||
include src/iotc/baltimore.pem
|
||||
include src/iotc/baltimore.pem
|
||||
include assets/*
|
|
@ -1,12 +1,15 @@
|
|||
#!/bin/bash
|
||||
shopt -s expand_aliases
|
||||
source ~/.bashrc
|
||||
|
||||
rm -rf build/ dist/ src/azure/iotcentral/device/client/iotc_device.egg-info src/azure/iotcentral/device/client/_pycache_ src/azure/iotcentral/device/client/_init_.pyc
|
||||
|
||||
TEST=""
|
||||
if [[ $1 == 'test' ]]; then
|
||||
TEST="-r testpypi"
|
||||
TEST="--repository testpypi"
|
||||
fi
|
||||
|
||||
python2 setup.py sdist bdist_wheel
|
||||
|
||||
#python2 setup.py sdist bdist_wheel
|
||||
python3 setup.py sdist bdist_wheel
|
||||
twine upload dist/* $TEST
|
||||
python3 -m twine upload $TEST dist/*
|
|
@ -7,9 +7,12 @@ from azure.iotcentral.device.client import IoTCClient, IOTCConnectType, IOTCLogL
|
|||
|
||||
|
||||
|
||||
deviceId = "nuovodev"
|
||||
scopeId = "0ne00052362"
|
||||
key = '68p6zEjwVNB6L/Dz8Wkz4VhaTrYqkndPrB0uJbWr2Hc/AmB+Qxz/eJJ9MIhLZFJ6hC0RmHMgfaYBkNTq84OCNQ=='
|
||||
deviceId = "<DEVICE_ID>"
|
||||
scopeId = "<SCOPE_ID>"
|
||||
key = '<DEVICE_OR_GROUP_KEY>'
|
||||
|
||||
# optional model Id for auto-provisioning
|
||||
modelId= '<TEMPLATE_ID>'
|
||||
|
||||
|
||||
def onProps(propName, propValue):
|
||||
|
@ -25,12 +28,11 @@ def onCommands(command, ack):
|
|||
# see iotc.Device documentation above for x509 argument sample
|
||||
iotc = IoTCClient(deviceId, scopeId,
|
||||
IOTCConnectType.IOTC_CONNECT_SYMM_KEY, key)
|
||||
iotc.setModelId('c318d580-39fc-4aca-b995-843719821049/1.5.0')
|
||||
iotc.setModelId(modelId)
|
||||
iotc.setLogLevel(IOTCLogLevel.IOTC_LOGGING_ALL)
|
||||
iotc.on(IOTCEvents.IOTC_PROPERTIES, onProps)
|
||||
# iotc.on(IOTCEvents.IOTC_COMMAND, onCommands)
|
||||
|
||||
# iotc.setQosLevel(IOTQosLevel.IOTC_QOS_AT_MOST_ONCE)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import sys
|
||||
sys.path.insert(0, 'src')
|
||||
|
||||
import time
|
||||
import asyncio
|
||||
from random import randint
|
||||
from azure.iotcentral.device.client.aio import IoTCClient, IOTCConnectType, IOTCLogLevel, IOTCEvents
|
||||
|
||||
|
||||
|
||||
deviceId = "nuovodev"
|
||||
scopeId = "0ne00052362"
|
||||
key = '68p6zEjwVNB6L/Dz8Wkz4VhaTrYqkndPrB0uJbWr2Hc/AmB+Qxz/eJJ9MIhLZFJ6hC0RmHMgfaYBkNTq84OCNQ=='
|
||||
deviceId = "<DEVICE_ID>"
|
||||
scopeId = "<SCOPE_ID>"
|
||||
key = '<DEVICE_OR_GROUP_KEY>'
|
||||
|
||||
# optional model Id for auto-provisioning
|
||||
modelId= '<TEMPLATE_ID>'
|
||||
|
||||
|
||||
async def onProps(propName, propValue):
|
||||
|
@ -23,10 +25,10 @@ async def onCommands(command, ack):
|
|||
await ack(command.name, 'Command received', command.request_id)
|
||||
|
||||
|
||||
# see iotc.Device documentation above for x509 argument sample
|
||||
# change connect type to reflect the used key (device or group)
|
||||
iotc = IoTCClient(deviceId, scopeId,
|
||||
IOTCConnectType.IOTC_CONNECT_SYMM_KEY, key)
|
||||
iotc.setModelId('c318d580-39fc-4aca-b995-843719821049/1.5.0')
|
||||
iotc.setModelId(modelId)
|
||||
iotc.setLogLevel(IOTCLogLevel.IOTC_LOGGING_ALL)
|
||||
iotc.on(IOTCEvents.IOTC_PROPERTIES, onProps)
|
||||
iotc.on(IOTCEvents.IOTC_COMMAND, onCommands)
|
||||
|
@ -42,7 +44,7 @@ async def main():
|
|||
'accelerometerY': str(randint(20, 45)),
|
||||
"accelerometerZ": str(randint(20, 45))
|
||||
})
|
||||
time.sleep(3)
|
||||
await asyncio.sleep(3)
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
|
|
10
setup.py
10
setup.py
|
@ -2,7 +2,7 @@ import setuptools
|
|||
import sys
|
||||
|
||||
sys.path.insert(0, 'src')
|
||||
from iotc import __version__, __name__
|
||||
from azure.iotcentral.device.client import __version__, __name__
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
@ -15,7 +15,7 @@ setuptools.setup(
|
|||
description="Azure IoT Central device client for Python",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/lucadruda/azure-iotcentral-device-client",
|
||||
url="https://github.com/lucadruda/iotc-python-device-client",
|
||||
packages=setuptools.find_packages('src'),
|
||||
package_dir={'': 'src'},
|
||||
license="MIT",
|
||||
|
@ -27,10 +27,8 @@ setuptools.setup(
|
|||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy'
|
||||
'Programming Language :: Python :: 3.8',
|
||||
],
|
||||
include_package_data=True,
|
||||
install_requires=["paho-mqtt", "httplib2"]
|
||||
install_requires=["azure-iot-device"]
|
||||
)
|
||||
|
|
|
@ -9,7 +9,7 @@ from azure.iot.device import ProvisioningDeviceClient
|
|||
from azure.iot.device import Message, MethodResponse
|
||||
from datetime import datetime
|
||||
|
||||
__version__ = "0.0.1-beta.2"
|
||||
__version__ = "0.2.0-beta.3"
|
||||
__name__ = "azure-iotcentral-device-client"
|
||||
|
||||
|
||||
|
@ -57,11 +57,6 @@ class IOTCConnectType:
|
|||
IOTC_CONNECT_DEVICE_KEY = 3
|
||||
|
||||
|
||||
class IOTCProtocol:
|
||||
IOTC_PROTOCOL_MQTT = 1
|
||||
IOTC_PROTOCOL_AMQP = 2
|
||||
IOTC_PROTOCOL_HTTP = 4
|
||||
|
||||
|
||||
class IOTCLogLevel:
|
||||
IOTC_LOGGING_DISABLED = 1
|
||||
|
@ -116,7 +111,6 @@ class IoTCClient:
|
|||
self._credType = credType
|
||||
self._keyORCert = keyOrCert
|
||||
self._modelId = None
|
||||
self._protocol = IOTCProtocol.IOTC_PROTOCOL_MQTT
|
||||
self._connected = False
|
||||
self._events = {}
|
||||
self._propThread = None
|
||||
|
@ -138,12 +132,6 @@ class IoTCClient:
|
|||
else:
|
||||
return False
|
||||
|
||||
def setProtocol(self, protocol):
|
||||
"""
|
||||
Set the connection protocol to be used.
|
||||
:param IOTCProtocol protocol: One protocol between MQTT, AMQP and HTTPS (default MQTT)
|
||||
"""
|
||||
self._protocol = protocol
|
||||
|
||||
def setGlobalEndpoint(self, endpoint):
|
||||
"""
|
||||
|
|
|
@ -5,7 +5,7 @@ from azure.iot.device.aio import ProvisioningDeviceClient
|
|||
from azure.iot.device import Message, MethodResponse
|
||||
from datetime import datetime
|
||||
|
||||
__version__ = "0.0.1-beta.2"
|
||||
__version__ = "0.2.0-beta.3"
|
||||
__name__ = "azure-iotcentral-device-client"
|
||||
|
||||
|
||||
|
@ -53,11 +53,6 @@ class IOTCConnectType:
|
|||
IOTC_CONNECT_DEVICE_KEY = 3
|
||||
|
||||
|
||||
class IOTCProtocol:
|
||||
IOTC_PROTOCOL_MQTT = 1
|
||||
IOTC_PROTOCOL_AMQP = 2
|
||||
IOTC_PROTOCOL_HTTP = 4
|
||||
|
||||
|
||||
class IOTCLogLevel:
|
||||
IOTC_LOGGING_DISABLED = 1
|
||||
|
@ -112,7 +107,6 @@ class IoTCClient:
|
|||
self._credType = credType
|
||||
self._keyORCert = keyOrCert
|
||||
self._modelId = None
|
||||
self._protocol = IOTCProtocol.IOTC_PROTOCOL_MQTT
|
||||
self._connected = False
|
||||
self._events = {}
|
||||
# self._threads = None
|
||||
|
@ -125,24 +119,44 @@ class IoTCClient:
|
|||
self._logger = logger
|
||||
|
||||
def isConnected(self):
|
||||
"""
|
||||
Check if device is connected to IoTCentral
|
||||
:returns: Connection state
|
||||
:rtype: bool
|
||||
"""
|
||||
if self._connected:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def setProtocol(self, protocol):
|
||||
self._protocol = protocol
|
||||
|
||||
def setGlobalEndpoint(self, endpoint):
|
||||
"""
|
||||
Set the device provisioning endpoint.
|
||||
:param str endpoint: Custom device provisioning endpoint. Default ('global.azure-devices-provisioning.net')
|
||||
"""
|
||||
self._globalEndpoint = endpoint
|
||||
|
||||
def setModelId(self, modelId):
|
||||
"""
|
||||
Set the model Id for the device to be associated
|
||||
:param str modelId: Id for an existing model in the IoTCentral app
|
||||
"""
|
||||
self._modelId = modelId
|
||||
|
||||
def setLogLevel(self, logLevel):
|
||||
"""
|
||||
Set the logging level
|
||||
:param IOTCLogLevel: Logging level. Available options are: ALL, API_ONLY, DISABLE
|
||||
"""
|
||||
self._logger.setLogLevel(logLevel)
|
||||
|
||||
def on(self, eventname, callback):
|
||||
"""
|
||||
Set a listener for a specific event
|
||||
:param IOTCEvents eventname: Supported events: IOTC_PROPERTIES, IOTC_COMMANDS
|
||||
:param function callback: Function executed when the specified event occurs
|
||||
"""
|
||||
self._events[eventname] = callback
|
||||
return 0
|
||||
|
||||
|
@ -216,16 +230,31 @@ class IoTCClient:
|
|||
callback()
|
||||
|
||||
async def sendProperty(self, payload, callback=None):
|
||||
"""
|
||||
Send a property message
|
||||
:param dict payload: The properties payload. Can contain multiple properties in the form {'<propName>':{'value':'<propValue>'}}
|
||||
:param function callback: Function executed after successfull dispatch
|
||||
"""
|
||||
self._logger.debug('Sending property {}'.format(json.dumps(payload)))
|
||||
await self._deviceClient.patch_twin_reported_properties(payload)
|
||||
if callback is not None:
|
||||
callback()
|
||||
|
||||
async def sendTelemetry(self, payload, properties=None, callback=None):
|
||||
"""
|
||||
Send a telemetry message
|
||||
:param dict payload: The telemetry payload. Can contain multiple telemetry fields in the form {'<fieldName1>':<fieldValue1>,...,'<fieldNameN>':<fieldValueN>}
|
||||
:param dict optional properties: An object with custom properties to add to the message.
|
||||
:param function callback: Function executed after successfull dispatch
|
||||
"""
|
||||
self._logger.info('Sending telemetry message: {}'.format(payload))
|
||||
await self._sendMessage(json.dumps(payload), properties, callback)
|
||||
|
||||
async def connect(self):
|
||||
"""
|
||||
Connects the device.
|
||||
:raises exception: If connection fails
|
||||
"""
|
||||
if self._credType in (IOTCConnectType.IOTC_CONNECT_DEVICE_KEY, IOTCConnectType.IOTC_CONNECT_SYMM_KEY):
|
||||
if self._credType == IOTCConnectType.IOTC_CONNECT_SYMM_KEY:
|
||||
self._keyORCert = self._computeDerivedSymmetricKey(
|
||||
|
@ -269,8 +298,7 @@ class IoTCClient:
|
|||
|
||||
# setup listeners
|
||||
self._propThread = asyncio.create_task(self._onProperties())
|
||||
await self._propThread
|
||||
#self._cmdThread = asyncio.create_task(self._onCommands())
|
||||
self._cmdThread = asyncio.create_task(self._onCommands())
|
||||
# self._threads = await asyncio.gather(
|
||||
# self._onProperties(),
|
||||
# self._onCommands()
|
||||
|
|
|
@ -66,9 +66,7 @@ def async_return(result):
|
|||
|
||||
async def stopThreads(iotc):
|
||||
iotc._propThread.cancel()
|
||||
with suppress(asyncio.CancelledError):
|
||||
return True
|
||||
#iotc._cmdThread.cancel()
|
||||
iotc._cmdThread.cancel()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
@ -91,7 +89,7 @@ async def test_deviceKeyGeneration(mocker):
|
|||
iotc = init(mocker)
|
||||
await iotc.connect()
|
||||
assert iotc._keyORCert == deviceKey
|
||||
stopThreads(iotc)
|
||||
await stopThreads(iotc)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
@ -99,14 +97,33 @@ async def test_hubConnectionString(mocker):
|
|||
iotc = init(mocker)
|
||||
await iotc.connect()
|
||||
assert iotc._hubCString == expectedHub
|
||||
stopThreads(iotc)
|
||||
await stopThreads(iotc)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_onproperties_before(mocker):
|
||||
|
||||
iotc = init(mocker)
|
||||
|
||||
async def onProps(propname,propvalue):
|
||||
assert propname == 'prop1'
|
||||
assert propvalue == 40
|
||||
await stopThreads(iotc)
|
||||
|
||||
mocker.patch.object(iotc,'sendProperty',return_value=True)
|
||||
iotc.on(IOTCEvents.IOTC_PROPERTIES,onProps)
|
||||
await iotc.connect()
|
||||
try:
|
||||
await iotc._propThread
|
||||
await iotc._cmdThread
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_onproperties_after(mocker):
|
||||
iotc = init(mocker)
|
||||
|
||||
async def onProps(propname,propvalue):
|
||||
assert propname == 'prop1'
|
||||
assert propvalue == 40
|
||||
|
@ -114,64 +131,62 @@ async def test_onproperties_before(mocker):
|
|||
return True
|
||||
|
||||
mocker.patch.object(iotc,'sendProperty',return_value=True)
|
||||
iotc.on(IOTCEvents.IOTC_PROPERTIES,onProps)
|
||||
await iotc.connect()
|
||||
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_onproperties_after(mocker):
|
||||
mock_async=mock.Mock()
|
||||
async def onProps(propname,propvalue):
|
||||
return True
|
||||
|
||||
mock_async.return_value=await onProps('prop1',40)
|
||||
|
||||
iotc = init(mocker)
|
||||
mocker.patch.object(iotc,'sendProperty',return_value=True)
|
||||
asyncio.run(iotc.connect())
|
||||
iotc.on(IOTCEvents.IOTC_PROPERTIES,onProps)
|
||||
# give at least 10 seconds for the new listener to be recognized. assign the listener after connection is discouraged
|
||||
time.sleep(11)
|
||||
mock_async.assert_called_with('prop1',40)
|
||||
stopThreads(iotc)
|
||||
|
||||
try:
|
||||
await iotc._propThread
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_onCommands_before(mocker):
|
||||
|
||||
onCmds=mock.Mock()
|
||||
iotc = init(mocker)
|
||||
|
||||
def mockedAck():
|
||||
print('Callback called')
|
||||
async def onCmds(command,ack):
|
||||
ret=ack()
|
||||
assert ret=='mocked'
|
||||
await stopThreads(iotc)
|
||||
return True
|
||||
|
||||
iotc = init(mocker)
|
||||
|
||||
def mockedAck():
|
||||
return 'mocked'
|
||||
|
||||
mocker.patch.object(iotc,'_cmdAck',mockedAck)
|
||||
|
||||
iotc.on(IOTCEvents.IOTC_COMMAND,onCmds)
|
||||
asyncio.run(iotc.connect())
|
||||
onCmds.assert_called_with(methodRequest,mockedAck)
|
||||
stopThreads(iotc)
|
||||
await iotc.connect()
|
||||
try:
|
||||
await iotc._cmdThread
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_onCommands_after(mocker):
|
||||
|
||||
onCmds=mock.Mock()
|
||||
iotc = init(mocker)
|
||||
|
||||
def mockedAck():
|
||||
print('Callback called')
|
||||
async def onCmds(command,ack):
|
||||
ret=ack()
|
||||
assert ret=='mocked'
|
||||
await stopThreads(iotc)
|
||||
return True
|
||||
|
||||
iotc = init(mocker)
|
||||
|
||||
def mockedAck():
|
||||
return 'mocked'
|
||||
|
||||
mocker.patch.object(iotc,'_cmdAck',mockedAck)
|
||||
asyncio.run(iotc.connect())
|
||||
|
||||
await iotc.connect()
|
||||
iotc.on(IOTCEvents.IOTC_COMMAND,onCmds)
|
||||
|
||||
# give at least 10 seconds for the new listener to be recognized. assign the listener after connection is discouraged
|
||||
time.sleep(11)
|
||||
onCmds.assert_called_with(methodRequest,mockedAck)
|
||||
stopThreads(iotc)
|
||||
|
||||
try:
|
||||
await iotc._cmdThread
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче