设备孪生报告的属性无法使用python sdk正确更新

时间:2019-01-28 15:38:21

标签: python azure-iot-hub azure-iot-sdk

我已将软件更新过程划分为多个阶段,例如(下载,解压缩,预安装,安装,安装后)。我正在设置报告的属性 相应地在每个阶段。但是这些属性不会在安装过程中更新(即无法在azure门户上的device twin中看到报告属性的更改),但是在安装结束时,我会收到所有设置的“报告”属性的回调响应。

我正在使用python设备sdk使用Azure IOT进行软件更新。 为此,我修改了SDK中提供的示例(即iothub_client_sample_class.py文件)。我正在使用设备twin来更新软件。我在设备twin中为“ software_version”创建了“所需”属性。一旦更改了“ software_version”的“所需”属性,就开始软件更新过程。软件更新过程执行各种操作,因此我将这个过程划分为各个阶段。我会将“已报告的”属性发送到IotHub。但是这些“报告的”并没有在天蓝色门户网站上的设备孪生报告的属性中按顺序更新。

import random
import time
import sys
import iothub_client
import json
from iothub_client import IoTHubClient, IoTHubClientError,  IoTHubTransportProvider
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError, DeviceMethodReturnValue
from iothub_client_args import get_iothub_opt, OptionError

# HTTP options
# Because it can poll "after 9 seconds" polls will happen effectively
# at ~10 seconds.
# Note that for scalabilty, the default value of minimumPollingTime
# is 25 minutes. For more information, see:
# https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
TIMEOUT = 241000
MINIMUM_POLLING_TIME = 9

# messageTimeout - the maximum time in milliseconds until a message times out.
# The timeout period starts at IoTHubClient.send_event_async.
# By default, messages do not expire.
MESSAGE_TIMEOUT = 1000

RECEIVE_CONTEXT = 0
AVG_WIND_SPEED = 10.0
MIN_TEMPERATURE = 20.0
MIN_HUMIDITY = 60.0
MESSAGE_COUNT = 5
RECEIVED_COUNT = 0
TWIN_CONTEXT = 0
METHOD_CONTEXT = 0

# global counters
RECEIVE_CALLBACKS = 0
SEND_CALLBACKS = 0
BLOB_CALLBACKS = 0
TWIN_CALLBACKS = 0
SEND_REPORTED_STATE_CALLBACKS = 0
METHOD_CALLBACKS = 0

firstTime = True
hub_manager = None

PROTOCOL = IoTHubTransportProvider.MQTT
CONNECTION_STRING = "XXXXXX"

base_version = '1.0.0.000'
SUCCESS = 0
firstTime = True

def downloadImage(url):
    # Code for downloading the package from url
    return 0

def unzipPackage():
    #code for unzipping the package
    return 0

def readPackageData():
    # code reading package data
    return 0

def pre_install():
    #code for installing dependencies
    return 0

def install():
    #code for installing main package
    return 0

def post_install():
    #code for verifying installation 
    return 0


def start_software_update(url,message):
    global hub_manager
    print "Starting software update process!!!!"

    reported_state = "{\"updateStatus\":\"softwareUpdateinprogress\"}"
    hub_manager.send_reported_state(reported_state, len(reported_state), 1003)
    time.sleep(1)
    status = downloadImage(url)
    if status == SUCCESS:
        reported_state = "{\"updateStatus\":\"downloadComplete\"}"
        hub_manager.send_reported_state(reported_state, len(reported_state), 1004)
        print "Downlaod Phase Done!!!"
        time.sleep(1)
    else:
        print "Download Phase failed!!!!"
        return False
    status = unzipPackage()
    if status == SUCCESS:
        reported_state = "{\"updateStatus\":\"UnzipComplete\"}"
        hub_manager.send_reported_state(reported_state, len(reported_state), 1005)
        print "Unzip Package Done!!!"
        time.sleep(1)
    else:
        print "Unzip package failed!!!"
        return False
    status = readPackageData()
    if status == SUCCESS:
        reported_state = "{\"updateStatus\":\"ReadPackageData\"}"
        hub_manager.send_reported_state(reported_state, len(reported_state), 1006)
        print "Reading package json data"
        time.sleep(1)
    else:
        print "Failed Reading package!!!"
        return False
    status = pre_install()
    if status == SUCCESS:
        reported_state = "{\"updateStatus\":\"PreInstallComplete\"}"
        hub_manager.send_reported_state(reported_state, len(reported_state), 1007)
        time.sleep(1)
        print "pre_install state successful!!!"
    else:
        print "pre_install failed!!!!"
        return False
    status = install()
    if status == SUCCESS:   
        reported_state = "{\"updateStatus\":\"InstallComplete\"}"
        hub_manager.send_reported_state(reported_state, len(reported_state), 1008)
        time.sleep(1)
        print "install sucessful!!!"
    else:
        print "install failed!!!"
        return False
    status = post_install()
    if status == SUCCESS:   
        reported_state = "{\"updateStatus\":\"SoftwareUpdateComplete\"}"
        hub_manager.send_reported_state(reported_state, len(reported_state), 1009)
        time.sleep(1)
        print "post install sucessful!!!"
    else:
        print "post install failed!!!"
        return False
    return True


def device_twin_callback(update_state, payload, user_context):
    global TWIN_CALLBACKS
    global firstTime
    global base_version
    print ( "\nTwin callback called with:\nupdateStatus = %s\npayload = %s\ncontext = %s" % (update_state, payload, user_context) )
    TWIN_CALLBACKS += 1
    print ( "Total calls confirmed: %d\n" % TWIN_CALLBACKS )
    message = json.loads(payload)
    if not firstTime:
        if message["software_version"] != base_version:
            url = message["url"]
            status = start_software_update(url,message)
            if status:
                print "software Update Successful!!!"
            else:
                print "software Update Unsuccessful!!!"
    else:
        base_version = message["desired"]["software_version"]
        print "Set firstTime to false", base_version
        firstTime = False


def send_reported_state_callback(status_code, user_context):
    global SEND_REPORTED_STATE_CALLBACKS
    print ( "Confirmation for reported state received with:\nstatus_code = [%d]\ncontext = %s" % (status_code, user_context) )
    SEND_REPORTED_STATE_CALLBACKS += 1
    print ( "    Total calls confirmed: %d" % SEND_REPORTED_STATE_CALLBACKS )


class HubManager(object):

    def __init__(
            self,
            connection_string,
            protocol=IoTHubTransportProvider.MQTT):
        self.client_protocol = protocol
        self.client = IoTHubClient(connection_string, protocol)
        if protocol == IoTHubTransportProvider.HTTP:
            self.client.set_option("timeout", TIMEOUT)
            self.client.set_option("MinimumPollingTime", MINIMUM_POLLING_TIME)
        # set the time until a message times out
        self.client.set_option("messageTimeout", MESSAGE_TIMEOUT)
        # some embedded platforms need certificate information
        # self.set_certificates()
        self.client.set_device_twin_callback(device_twin_callback, TWIN_CONTEXT)



    def send_reported_state(self, reported_state, size, user_context):
        self.client.send_reported_state(
            reported_state, size,
            send_reported_state_callback, user_context)    

def main(connection_string, protocol):
    global hub_manager
    try:
        print ( "\nPython %s\n" % sys.version )
        print ( "IoT Hub Client for Python" )

        hub_manager = HubManager(connection_string, protocol)

        print ( "Starting the IoT Hub Python sample using protocol %s..." % hub_manager.client_protocol )
        reported_state = "{\"updateStatus\":\"waitingforupdate\"}"
        hub_manager.send_reported_state(reported_state, len(reported_state), 1002)

        while True:
            time.sleep(1)

    except IoTHubError as iothub_error:
        print ( "Unexpected error %s from IoTHub" % iothub_error )
        return
    except KeyboardInterrupt:
        print ( "IoTHubClient sample stopped" )

if __name__ == '__main__':
    try:
        (CONNECTION_STRING, PROTOCOL) = get_iothub_opt(sys.argv[1:], CONNECTION_STRING)
    except OptionError as option_error:
        print ( option_error )
        usage()
        sys.exit(1)

    main(CONNECTION_STRING, PROTOCOL)

预期结果:软件更新中每个阶段的“已报告”属性都应该在Azure门户中的孪生设备中正确更新。

实际结果:软件更新过程中每个阶段的“已报告”属性未正确更新。

0 个答案:

没有答案