HTTPAPI_ERROR al crear la identidad del dispositivo con python local e
Avatar eid
Pregunta contestada

HTTPAPI_ERROR al crear la identidad del dispositivo con python local en Azure IoT Hub

Quiero crear/suscribir un nuevo dispositivo (simulado) con mi máquina local en Azure IoT Hub.

Estoy usando python 3.6.4 (64 bits) en una máquina con Windows 7 (64 bits) y ejecuto el código con spyder.

Paquetes relevantes instalados:

  • azure-iothub-dispositivo-cliente (1.3.1)
  • azure-iothub-servicio-cliente (1.3.1)
  • araña (3.2.8)

Seguí los pasos desde aquí: CreateDeviceIdentity.py

El código cortado:

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()
'''

Si ejecuto este código siempre obtengo el error:

Error inesperado IoTHubRegistryManager.create_device, IoTHubRegistryManagerResult.HTTPAPI_ERROR

Encontré el error (o uno similar) en varias páginas de Internet, pero nunca obtuve una solución que funcionara. El otro ejemplo de código de la documentación de Microsoft 1 (DispositivoSimulado.py) funciona bien.

complemento: el error también se puede reproducir al ejecutar el script por línea de comando. El registro de errores completo:

Error: hora: jueves 5 de abril 08:59:55 2018 Archivo: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 falló.

Error: hora: jueves 5 de abril 08:59:55 2018 Archivo:C:\release\iot-sdks-internals\release\python\automation\aziotsdk_pytools\src\c\c-utility\adapters\httpapi_winhttp.c Func:HTTPAPI_Init Line:142 GetLastError: Parámetro Falscher.

Error: hora: jueves 5 de abril 08:59:55 2018 Archivo:C:\release\iot-sdks-internals\release\python\automation\aziotsdk_pytools\src\c\c-utility\src\httpapiex.c Func:HTTPAPIEX_ExecuteRequest Line:475 no se pudo recuperar el envío a un estado de trabajo

Error: hora: jueves 5 de abril 08:59:55 2018 Archivo:C:\release\iot-sdks-internals\release\python\automation\az iotsdk_pytools\src\c\iothub_service_client\src\iothub_registrymanager.c Func:sendHttpRequestCRUD Línea:982 HTTPAPIEX_SAS_ExecuteRequest falló Error inesperado IoTHubRegistryManager.create_device, IoTHubRegistryManagerResult.HTTPAPI_ERROR

Mostrar la mejor respuesta

¿Puedes reproducir este problema y ejecutar el script de Python usando la línea de comando? Además, comparta el código de error detallado con nosotros si sale, como este fuera de problema de memoria?

Avatar eid

hola, no, no es un error de memoria. Consulte mi entrada adicional en la primera etiqueta de pregunta.

Según el mensaje de error, el problema se produjo en HTTPAPI_Init. ¿Construyó usted mismo el SDK de python para Azure Iot o simplemente lo descargó a través de pip? ¿Qué es esa línea de código? Para reducir este problema, también sugiero que intente crear una identidad de dispositivo usando otro SDK de idioma (p. ej., .Net) para ver si el problema es relativo al entorno o SDK específico.

Avatar eid

Descargué e instalé los dos paquetes azure-iot a través de pip. Pero también descargué el SDK de git, pero no pude compilarlo con ...\azure-iot-sdk-python\build_all\windows\build_client.cmd. En un raspberry pi pude construirlo y creé un iothub_client.so. Pero el mismo error que el anterior (HTTPAPI_ERROR) al ejecutar iothub_registrymanager_sample.py o CreateDeviceIdentity.py. El otro código de muestra (iothub_client_sample.py o SimulatedDevice.py) todavía funciona bien en ambos sistemas. Ejecutando el código de muestra para trabajos c-sharp.

Este problema ya se solucionó en la última versión del SDK (1.3.3). Por favor, hágame saber si funciona para usted.

Avatar eid

¡gracias por la pista! --> actualizó ambas bibliotecas pip. El código anterior funciona directamente. ¿Sabe si también funciona en un sistema Linux (como rsp pi) (solo instalando los paquetes pip, sin compilar un archivo .so del SDK)?

Sí, también debería funcionar. Sin embargo, según tengo entendido, deberíamos usar la biblioteca azure-iothub-service-client en el servicio de back-end en lugar del lado del cliente (en un dispositivo).

Pude ejecutar este código sin ningún problema. ¿Puede confirmar si su IoT Hub funciona correctamente? ¿Copiaste la cadena de conexión de IoT Hub en lugar de una cadena de conexión del dispositivo?

ingrese la descripción de la imagen aquí

Avatar eid

OK veo. Quizás haya algunas restricciones en mi máquina hechas por mi compañía (no lo sé). El código de ejemplo anterior no funciona en mi máquina ni en la de un compañero (siempre el mismo error). Encontré una solución usando paho mqtt para manejar el tráfico y usar la API REST para registrar dispositivos, etc. Esta solución funciona totalmente sin ningún paquete o sdk de azure-iothub, por lo que también podría estar ejecutándose en una raspberry pi.

@eid, ¿su máquina está en un entorno proxy?

Avatar eid

gracias por tu comentario. No estoy seguro si mi empresa utiliza un proxy. Consulte los comentarios anteriores: el problema debe resolverse actualizando las bibliotecas de 1.3.1 a 1.3.3

Al principio, también recibí el mismo error que tú. La solución es desinstalar ambos paquetes pip e instalar la versión actualizada. Si ejecuta el código de muestra, se supone que funciona bien.

Esto ya es antiguo, pero sigo encontrando cosas similares y quería compartir algunas soluciones que he encontrado.

Tuve este mismo problema con las instalaciones pip más recientes (1.4.5) y python3.7 y lo diagnostiqué como bibliotecas openssl/curl incorrectas. Lo resolví compilando el SDK de Python de Azure IOTHub yo mismo, que crea archivos .so para el dispositivo y los clientes de servicio que puede colocar en su directorio de código junto a sus archivos de python.

Así es como lo localicé:

  1. Use pip para encontrar el directorio del módulo:

    pip3 show azure-iothub-service-client
    
  2. Esto me dirigió a /usr/local/lib/python3.7/site-packages. Debajo estaba la carpeta que usa la importación: /iothub_service_client. Usé la utilidad 'otool' de Apple para enumerar las bibliotecas a las que llama el cliente del servicio (esto se puede hacer en Linux usando 'ldd'):

    otool -L /usr/local/lib/python3.7/site-packages/iothub_service_client/iothub_service_client.so
    
  3. Eso me mostró que la biblioteca estaba usando libcurl que viene con MacOSX:

    /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)
    

Recordé algo acerca de que el nuevo curl basado en MacOS LibreSSL no funcionaba para los clientes de MSFT, y aunque tenía mi directorio de biblioteca curl instalado en brew configurado en una variable de entorno DYLD_LIBRARY_PATH, decidí compilar el servicio iothub y los clientes del dispositivo mismo para ver si solucionaba el problema. Seguí en gran medida las sugerencias en https://github.com/Azure/azure-iot-sdk-python/blob/master/doc/python-devbox-setup.md.

Algunas cosas adicionales que hice para asegurar una compilación exitosa:

  1. Primero, obtenga información de preparación para curl y openssl usando brew info <package>
  2. Las versiones de cerveza de curl y openssl ya estaban en mi camino. No deberían ser necesarios para una compilación, pero otros scripts de configuración fallaron debido a las comprobaciones de versión contra curl y openssl, por lo que pueden ser necesarios para los scripts de preparación. brew info te da los comandos que necesitas para ponerlos en tu camino. Será algo como:

    echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
    echo 'export PATH="/usr/local/opt/curl/bin:$PATH"' >> ~/.bash_profile
    
  3. Asegúrese de que la compilación utilizará sus bibliotecas e incluye curl y 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"
    
  4. Dado que estos SDK usan Boost, debe instalarlo correctamente. Finalmente encontré el comando correcto para instalar boost y boost-python para python3 sin instalar python2 y arrastrar un montón de cosas adicionales:

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

Una vez que todo esté bien, debería poder compilar los clientes sin problemas. La última versión del SDK es compatible con Python 3.7 y, por primera vez en un año, tuve una compilación sin errores al principio. :D