HTTPAPI_ERROR 在 Azure IoT 中心上使用本地 python 创建设备标识时

HTTPAPI_ERROR when creating device identity with local python on azure IoT Hub

我想 create/subscribe 一个新的(模拟)设备与我在 Azure IoT 中心的本地机器。

我在 windows7(64 位)机器上使用 python 3.6.4(64 位)和 运行 spyder 的代码。

已安装,相关包:

我按照这里的步骤操作:CreateDeviceIdentity.py

截取的代码:

import sys
import iothub_service_client

CONNECTION_STRING = "myConnectionString"
DEVICE_ID = "pythonDevice_1"

def print_device_info(title, iothub_device):
    print ( title + ":" )
    print ( "iothubDevice.deviceId = {0}".format(iothub_device.deviceId) )
    print ( "iothubDevice.primaryKey = {0}".format(iothub_device.primaryKey) )
    print ( "iothubDevice.secondaryKey = {0}".format(iothub_device.secondaryKey) )
    print ( "iothubDevice.connectionState = {0}".format(iothub_device.connectionState) )
    print ( "iothubDevice.status = {0}".format(iothub_device.status) )
    print ( "iothubDevice.lastActivityTime = {0}".format(iothub_device.lastActivityTime) )
    print ( "iothubDevice.cloudToDeviceMessageCount = {0}".format(iothub_device.cloudToDeviceMessageCount) )
    print ( "iothubDevice.isManaged = {0}".format(iothub_device.isManaged) )
    print ( "iothubDevice.authMethod = {0}".format(iothub_device.authMethod) )
    print ( "" )

#def iothub_createdevice():
try:
    iothub_registry_manager = iothub_service_client.IoTHubRegistryManager(CONNECTION_STRING)
    primary_key = ""
    secondary_key = ""
    auth_method = iothub_service_client.IoTHubRegistryManagerAuthMethod.SHARED_PRIVATE_KEY
    new_device = iothub_registry_manager.create_device(DEVICE_ID, primary_key, secondary_key, auth_method)
    print_device_info("CreateDevice", new_device)

except iothub_service_client.IoTHubError as iothub_error:
    print ( "Unexpected error {0}".format(iothub_error) )
    #return
except KeyboardInterrupt:
    print ( "iothub_createdevice stopped" )


'''
if __name__ == '__main__':
    print ( "" )
    print ( "Python {0}".format(sys.version) )
    print ( "Creating device using the Azure IoT Hub Service SDK for Python" )
    print ( "" )
    print ( "    Connection string = {0}".format(CONNECTION_STRING) )
    print ( "    Device ID         = {0}".format(DEVICE_ID) )

    iothub_createdevice()
'''

如果我运行这个代码我总是得到错误:

Unexpected error IoTHubRegistryManager.create_device, IoTHubRegistryManagerResult.HTTPAPI_ERROR

我在 inet 的几个页面上发现了(或类似的)错误,但从未找到有效的解决方案。微软文档 1 (SimulatedDevice.py) 中的另一个代码示例工作正常。

插件: 当通过命令行 运行 运行脚本时,也可以重现该错误。完整的错误日志:

Error: Time:Thu Apr 5 08:59:55 2018 File:C:\release\iot-sdks-internals\release\python\automation\az iotsdk_pytools\src\c\c-utility\adapters\httpapi_winhttp.c Func:HTTPAPI_Init Line:142 WinHttpOpen failed.

Error: Time:Thu Apr 5 08:59:55 2018 File:C:\release\iot-sdks-internals\release\python\automation\aziotsdk_pytools\src\c\c-utility\adapters\httpapi_winhttp.c Func:HTTPAPI_Init Line:142 GetLastError: Falscher Parameter.

Error: Time:Thu Apr 5 08:59:55 2018 File:C:\release\iot-sdks-internals\release\python\automation\aziotsdk_pytools\src\c\c-utility\src\httpapiex.c Func:HTTPAPIEX_ExecuteRequest Line:475 unable to recover sending to a working state

Error: Time:Thu Apr 5 08:59:55 2018 File:C:\release\iot-sdks-internals\release\python\automation\az iotsdk_pytools\src\c\iothub_service_client\src\iothub_registrymanager.c Func:sendHttpRequestCRUD Line:982 HTTPAPIEX_SAS_ExecuteRequest failed Unexpected error IoTHubRegistryManager.create_device, IoTHubRegistryManagerResult.HTTPAPI_ERROR

我能够 运行 这段代码没有问题。您能确认您的 IoT 中心是否正常工作吗?您是否复制了 IoT 中心连接字符串而不是设备连接字符串?

最初,我也遇到了和你一样的错误。解决方案是卸载两个 pip 包并安装更新版本。如果您 运行 示例代码,它应该可以正常工作。

这已经过时了,但我 运行 一直在研究类似的东西,并想分享一些我找到的解决方案。

我在安装最新的 pip (1.4.5) 和 python3.7 时遇到了同样的问题,并将其诊断为不正确的 openssl / curl 库。我通过自己编译 Azure IOTHub Python SDK 解决了这个问题,它为设备和服务客户​​端创建了 .so 文件,您可以将这些文件放在 python 文件旁边的代码目录中。

我是这样找到它的:

  1. 使用 pip 查找模块目录:

    pip3 show azure-iothub-service-client
    
  2. 这将我指向 /usr/local/lib/python3.7/site-packages。下面是导入使用的文件夹 - /iothub_service_client。我使用 Apple 的 'otool' 实用程序列出服务客户端调用的库(这可以在 linux 上使用 'ldd' 完成):

    otool -L /usr/local/lib/python3.7/site-packages/iothub_service_client/iothub_service_client.so
    
  3. 这表明该库正在使用 MacOSX 附带的 libcurl:

    /usr/local/lib/python3.7/site-packages/iothub_service_client/iothub_service_client.so:
        @rpath/iothub_service_client.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/local/opt/boost-python3/lib/libboost_python37-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/Python (compatibility version 3.7.0, current version 3.7.0)
        /usr/lib/libcurl.4.dylib (compatibility version 7.0.0, current version 9.0.0)
        /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1452.23.0)
        /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork (compatibility version 1.0.0, current version 897.15.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)
        /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1452.23.0)
    

我记得一些关于新的基于 MacOS LibreSSL 的 curl 不适用于 MSFT 客户端的事情,即使我在 DYLD_LIBRARY_PATH env 变量中设置了 brew 安装的 curl 库目录,我还是决定编译iothub 服务和设备客户端,看看它是否解决了问题。我基本上遵循了 https://github.com/Azure/azure-iot-sdk-python/blob/master/doc/python-devbox-setup.md.

中的建议

为了确保编译成功,我做了一些额外的事情:

  1. 首先,使用 brew info <package>
  2. 获取 curl 和 openssl 的 brew 信息
  3. curl 和 openssl 的 brew 版本已经在我的路径中。编译不需要它们,但由于针对 curl 和 openssl 的版本检查,我有其他设置脚本失败,因此暂存脚本可能需要它们。 brew info 为您提供将它们放入您的路径所需的命令。它会是这样的:

    echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
    echo 'export PATH="/usr/local/opt/curl/bin:$PATH"' >> ~/.bash_profile
    
  4. 确保构建将使用您的库并包含 curl 和 openssl:

    export LDFLAGS="-L/usr/local/opt/curl/lib -L/usr/local/opt/openssl/lib"
    export CPPFLAGS="-I/usr/local/opt/curl/include -I/usr/local/opt/openssl/include"
    
  5. 由于这些 SDK 使用 Boost,您需要正确安装它。我终于找到了为 python3 安装 boost 和 boost-python 的正确命令,而无需安装 python2 并拖入大量额外的东西:

    brew install boost-python3 --with-python3 --without-python
    

一旦一切顺利,您应该可以毫无问题地编译客户端。最新版本的 SDK 支持 Python 3.7,一年来第一次,我第一次编译就没有错误。 :D