alibaba / AliOS-Things

面向IoT领域的、高可伸缩的物联网操作系统,可去官网了解更多信息https://www.aliyun.com/product/aliosthings
Apache License 2.0
4.58k stars 1.14k forks source link

[Bug Report]: 设备端使用HaaS Python ota库,云端物联网平台发起OTA升级失败 #1950

Open forchine opened 1 year ago

forchine commented 1 year ago

Contact Details

No response

HaaS Python OTA升级失败

运行环境: ESP32 m5stackcore2 固件版本: HaaSPython-ESP32-8M-v2.1.0 HaaSPython-ESP32-8M-v2.2.0

相关文档:OTA - 远程升级

haas python code:

from aliyunIoT import Device     # 连接阿里云物联网平台的组件
import network                   # 
import ujson
import kv
import utime
import ota

#按照实际情况,填写Wifi热点名称和密码。
Wifi_SSID = 'Xxxxxxxx'
Wifi_Password = 'Xxxxxxxxx'

# 物联网设备实例
device = None
productKey = ''
deviceName= '' 
deviceSecret = ''
# 物联网平台连接标志位
iot_connected = False
wlan = None

report_string_builder = None
props_hander = None

info = {
    'url': '',
    'store_path': '/',
    'install_path': '/data/pyamp',
    'length': 0,
    'hash_type':'',
    'hash':''
}

def on_trigger(data):
    global info
    # 保存服务端推送的ota信息
    info['url'] = data['url']
    info['length'] = data['length']
    info['module_name'] = data['module_name']
    info['version'] = data['version']
    info['hash'] = data['hash']
    info['hash_type'] = data['hash_type']

    print('ota trigger')
    print('info:')
    print(info)
    # 开始ota 包下载
    dl_data = {}
    dl_data['url'] = info['url']
    dl_data['store_path'] = info['store_path']
    print('dl_data:')
    print(dl_data)
    ota.download(dl_data)

def on_download(data):
    global info

    if data >= 0:
        print('Ota download succeed')
    else:
        print('on download , data zero.')

    print(data)
    # 开始ota包校验
    param = {}
    param['length'] = info['length']
    param['store_path'] = info['store_path']
    param['hash_type'] = info['hash_type']
    param['hash'] = info['hash']
    ota.verify(param)

def on_verify(data):
    global info
    print(data)
    if data >= 0 :
        print('Ota verify succeed')
    return True

def init_cloud_ota():
    global productKey,deviceName,device
    data_handle = {}
    data_handle['device_handle'] =  device.getDeviceHandle()

    ota.init(data_handle)

    report_info = { 
                          "device_handle": device.getDeviceHandle() ,
                          "product_key": productKey ,
                          "device_name": deviceName,
                          "module_name": 'default',
                          "version": 'app-0.0.1-20221001.1111'
                      }   

    ota.report(report_info)
    ota.on(1, on_trigger)
    ota.on(2, on_download)
    ota.on(3, on_verify)

# 物联网平台连接成功的回调函数
def on_connect(data):
    global iot_connected,device
    iot_connected = True

def on_props(data):
    global props_hander
    if props_hander != None:
        props_hander(data)

def connect_lk(productKey, deviceName, deviceSecret):
    global device, iot_connected
    # 将三元组信息设置到iot组件中
    key_info = {
        'region': 'cn-shanghai',
        'productKey': productKey,
        'deviceName': deviceName,
        'deviceSecret': deviceSecret,
        'keepaliveSec': 60
    }
    device = Device()

    # 设定连接到物联网平台的回调函数,如果连接物联网平台成功,则调用on_connect函数
    #                            云端下发物模型属性设置,调用on_props函数
    device.on(Device.ON_CONNECT, on_connect)
    device.on(Device.ON_PROPS,on_props)

    # 启动连接阿里云物联网平台过程
    device.connect(key_info)

    # 等待设备成功连接到物联网平台
    while(True):
        if iot_connected:
            print('iot platform connected.')
            break
        else:
            print('sleep for 1 s')
            utime.sleep(1)
    print('sleep for 2s')

    init_cloud_ota()

    utime.sleep(2)

def cloud_report_props():
    global iot_connected,device,report_string_builder
    if(iot_connected):
        if report_string_builder != None:
            data = report_string_builder()
            ret = device.postProps(data)
            if ret == 0 :
                print('report property ok.')
            else :
                print('report property failed')
        else:
            print('No report string builder.')

if __name__ == '__main__':
    wlan = network.WLAN(network.STA_IF)
#    if(wlan.isconnected() == False):
#        wlan.active(True)
#        wlan.connect(Wifi_SSID,Wifi_Password)

    print('check wifi connection')
    while(wlan.isconnected() == False):
        utime.sleep(1)
    print('wifi connected')
    try:
        f = open('/data/pyamp/DeviceInfo.json', 'r')
        deviceinfo = ujson.loads(f.readline())
        productKey = deviceinfo['productKey']
        deviceName = deviceinfo['deviceName']
        deviceSecret = deviceinfo['deviceSecret']
        f.close()
    except Exception as e:
        print('[ERROR] Get device info failed.')
        raise e

    connect_lk(productKey, deviceName, deviceSecret)

    while(True):
        cloud_report_props()
        utime.sleep(600)

Version

rel_3.3.0 (Main)

What soultions are you seeing the problem on?

py_engine_esp32_demo

Relevant log output

云端操作: Screenshot from 2022-10-16 07-42-18

设备端串口输出:

ver:app-0.0.2-20221001.1112 current_ver:app-0.0.1-20221001.1111
[httpclient_retrieve_content 579] no more(content-length) 
ota_file_size 2076
[httpclient_retrieve_content 579] no more(content-length) 
mbedtls_ssl_recv error, res: -0x004C
_core_sysdep_network_tcp_recv, errno: 113
_core_sysdep_network_tcp_recv, nwk recv error: : Software caused connection abort
skylarCai commented 1 year ago
感谢您提出的宝贵问题,我们有7x24小时服务的“HaaS百事通”客服系统,
您可以先尝试能否解决您的问题(https://haas.iot.aliyun.com/?ask=1&f=a2cre.b82925042)

如果“HaaS百事通”没有解决您的问题,请回复“人工支持”,我们会在工作日(10:00-12:00/14:00-18:00)10分钟内回复您。