2.12 haas506 2.0开发教程-高级组件库-ota(2.2版本接口有更新)

最新案例教程点击下方链接跳转,优快云已停止更新

点击跳转HaaS506官方最新案例







ota升级

1、案例说明

  1. OTA升级是通过无线网络在线升级,简单来说就是在连接无线网络的情况下,通过系统自带的更新设置来进行设备系统升级。比如手机系统更新。

  2. Haas506开发板完成动态注册连接云端后可以完成OTA升级(远程更新)。

    (1) 系统文件升级需要注册3个函数,在云端触发文件升级后,会触发on_trigger函数,并将文件的一系列信息通过on_trigger参数传入,我们可以将这些参数保存到全局变量中;
    (2)在on_trigger触发后,我们在on_trigger回调函数中调用ota.download函数来下载文件,ota.download函数下载完成后,会产生on_download回调,我们根据on_download的传入参数判断下载文件是否成功,如果成功, 我们在on_download回调函数中调用ota.verify来做文件校验;
    (3)ota.verify函数校验完成后,会产生on_verify回调,我们根据on_verify的传入参数来判断校验文件是否成功。

2、代码

  • 需要将产品的productKey和productSecret,粘贴到代码的指定位置
  • 2.2版本获取IMEI号接口有更新,需要更改以下内容(Ctrl+F 查找modem)
# 获取设备的IMEI 作为deviceName 进行动态注册
deviceName = modem.info.getDevImei()
...

  • main.py
# coding=utf-8

from driver import GPIO
import network
import ujson
import utime as time
import modem
from  aliyunIoT import Device
import ota
import kv


 # ota 消息推送的接受函数
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']
    # 开始ota 包下载
     dl_data = {}
     dl_data['url'] = info['url']
     dl_data['store_path'] = info['store_path']
     ota.download(dl_data)



 # ota 升级包下载结果回调函数
def on_download(data):
     global info
     if data >= 0:
         print('Ota download succeed')
     # 开始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)

 # ota 升级包校验结果回调函数
def on_verify(data):
      global info
      print(data)
      if data >= 0 :
          print('Ota verify succeed')
          print('Start Upgrade')
     # 开始ota升级
          param = {}
          param['length'] = info['length']
          param['store_path'] = info['store_path']
          param['install_path'] = info['install_path']
          ota.upgrade(param)

 # ota 升级包结果回调函数
def on_upgrade(data):
     if data >= 0 :
        print('Ota succeed')
        #ota升完级后 重启设备
        reboot()
 
#当iot设备连接到物联网平台的时候触发'connect' 事件
def on_connect(data):
    global module_name,default_ver,productKey,deviceName,deviceSecret,on_trigger,on_download,on_verify,on_upgrade
    print('***** connect lp succeed****')
    data_handle = {}
    data_handle['device_handle'] = device.getDeviceHandle()

 # 初始化ota服务
    ota.init(data_handle)

 # ota 回调函数注册
    ota.on(1,on_trigger)
    ota.on(2,on_download)
    ota.on(3,on_verify)
    ota.on(4,on_upgrade)
    report_info = {
         "device_handle": data_handle['device_handle'],
         "product_key": productKey ,
         "device_name": deviceName ,
         "module_name": module_name ,
         "version": default_ver
         }
 # 上报本机ota相关信息,上报版本信息返回以后程序返回,知道后台推送ota升级包,才会调用on_trigger函数
    ota.report(report_info)    


#当连接断开时,触发'disconnect'事件
def on_disconnect():
    print('linkkit is disconnected')

#当iot云端下发属性设置时,触发'props'事件
def on_props(request):
    print('clound req data is {}'.format(request))

#当iot云端调用设备service时,触发'service'事件
def on_service(id,request):
    print('clound req id  is {} , req is {}'.format(id,request))
#当设备跟iot平台通信过程中遇到错误时,触发'error'事件
def on_error(err):
    print('err msg is {} '.format(err))

#网络连接的回调函数
def on_4g_cb(args):
     global g_connect_status
     pdp = args[0]
     netwk_sta = args[1]
     if netwk_sta == 1:
         g_connect_status = True
     else:
         g_connect_status = False

#网络连接
def connect_network():
     global net,on_4g_cb,g_connect_status
     #NetWorkClient该类是一个单例类,实现网络管理相关的功能,包括初始化,联网,状态信息等.
     net = network.NetWorkClient()
     g_register_network = False
     if net._stagecode is not None and net._stagecode == 3 and net._subcode == 1:
         g_register_network = True
     else:
         g_register_network = False
     if g_register_network:
    #注册网络连接的回调函数on(self,id,func);  1代表连接,func 回调函数  ;return 0 成功
         net.on(1,on_4g_cb)    
         net.connect(None)
     else:
         print('网络注册失败')
     while True:
         if g_connect_status:
             print('网络连接成功')
             break
         time.sleep_ms(20)

#动态注册回调函数
def on_dynreg_cb(data):
     global deviceSecret,device_dyn_resigter_succed
     deviceSecret = data
     device_dyn_resigter_succed = True


 # 连接物联网平台
def dyn_register_device(productKey,productSecret,deviceName):
    global on_dynreg_cb,device,deviceSecret,device_dyn_resigter_succed
    key = '_amp_customer_devicesecret'
    deviceSecretdict = kv.get(key)
    print("deviceSecretdict:",deviceSecretdict)
    if isinstance(deviceSecretdict,str):    
        deviceSecret = deviceSecretdict 

    if deviceSecretdict is None or deviceSecret is None:
        key_info = {
            'productKey': productKey  ,
            'productSecret': productSecret ,
            'deviceName': deviceName
            }
        # 动态注册一个设备,获取设备的deviceSecret
        #下面的if防止多次注册,当前若是注册过一次了,重启设备再次注册就会卡住,
        if not device_dyn_resigter_succed:
            device.register(key_info,on_dynreg_cb)   



if __name__ == '__main__':
    ICCID=None
    g_connect_status = False
    net = None
    device = None
    deviceSecret = None
    deviceName = None
    productKey = "a1aNr1wef2c"
    productSecret = "Jppqfgx4tHeZh1Zi"
    device_dyn_resigter_succed = False
    # 定义需要升级的模块和版本号
    module_name = 'default'
    default_ver = '2.0.1'
# 定义升级包的下载和安装路径,其中url,hash_type和hash 会通过服务端推送被保存下来

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

    # 连接网络
    connect_network()
    # 获取设备的IMEI 作为deviceName 进行动态注册
    #2.2版本改为
    #deviceName = modem.info.getDevImei()
    deviceName = modem.getDevImei()
    #获取设备的ICCID
    ICCID=modem.sim.getIccid()
    #初始化物联网平台Device类,获取device实例
    device = Device()
    if deviceName is not None and len(deviceName) > 0 :
     #动态注册一个设备
        dyn_register_device(productKey,productSecret,deviceName)
    else:
        print("获取设备IMEI失败,无法进行动态注册")
    while deviceSecret is None:
        time.sleep(0.2)
    print('动态注册成功:' + deviceSecret)

    key_info = {
        'region' : 'cn-shanghai' ,
        'productKey': productKey ,
        'deviceName': deviceName ,
        'deviceSecret': deviceSecret ,
        'keepaliveSec': 60,
        }
    #打印设备信息
    print(key_info)

    #device.ON_CONNECT 是事件,on_connect是事件处理函数/回调函数
    device.on(device.ON_CONNECT,on_connect)
    device.on(device.ON_DISCONNECT,on_disconnect)
    device.on(device.ON_PROPS,on_props)
    device.on(device.ON_SERVICE,on_service)
    device.on(device.ON_ERROR,on_error)
    device.connect(key_info)

    #上报版本信息
    FwVersion={}
    FwVersion["FwVersion"]="amp-v1.16 build on 2021-11-17, 15:18:23"
    FwVersionStr=ujson.dumps(FwVersion)
    data0={
        'params':FwVersionStr
    }
    time.sleep_ms(1000)
    device.postProps(data0)
    print("FwVersionStr:",FwVersionStr)

    #将ICCID,IMEI数据放入字典
    imei_iccid={}
    imei_iccid["IMEI"]=deviceName
    imei_iccid["ICCID"]=ICCID
    #将字典转换为字符串
    imei_iccid_str=ujson.dumps(imei_iccid)
    data1={
        'params':imei_iccid_str
    }
    #10S上报一次
    time.sleep_ms(1000)
    device.postProps(data1)
    while True:
        print('当前App版本号:' + default_ver)
        print('等待Ota升级包.....')
        print('--------------------------------------------------------------------')
        time.sleep(1)

  • board.json

{
  "name": "haas506",
  "version": "2.0.0",
  "io": {
      "cloud_led":{
        "type":"GPIO",
        "port": 9,
        "dir": "output",
        "pull":"pulldown"
      },    
    "serial1":{
      "type":"UART",
      "port":0,
      "dataWidth":8,
      "baudRate":115200,
      "stopBits":1,
      "flowControl":"disable",
      "parity":"none"
    },
    "serial2":{
      "type":"UART",
      "port":1,
      "dataWidth":8,
      "baudRate":115200,
      "stopBits":1,
      "flowControl":"disable",
      "parity":"none"
    },
    "serial3":{
      "type":"UART",
      "port":2,
      "dataWidth":8,
      "baudRate":115200,
      "stopBits":1,
      "flowControl":"disable",
      "parity":"none"
    }
  },
  "debugLevel": "ERROR"
}


3、上传升级包

(1)在阿里云物联网平台创建一个设备、打开动态注册
(2)在设备的功能定义中设置自定义功能,如IMEI、ICCID和FwVersion,然后发布上线
(3)在产品下创建一个设备,建议使用设备的IMEI号作为deviceName
(4)复制产品的productKey和productSecret,粘贴到程序的相应位置
(5)烧录程序,查看日志获取到当前版本为2.0.1
在这里插入图片描述
(6)当修改代码后,将代码中的default_ver改为2.0.6,保存
(7)将当前项目的x.py和board.json一起打包成xx.zip
(8)打开ota升级面板
在这里插入图片描述
(9)添加升级包,填写升级包名称、所属产品、升级包模块、升级包版本号、签名算法、上传升级包
注意:升级包版本号必须与程序中更改的版本号一致
例如,上传的压缩包版本号为2.0.6 ,这里必须填写2.0.6 。否则云端会显示更新失败,但程序能正常下载至开发板。
在这里插入图片描述

(10)点击验证
在这里插入图片描述
(11)输入待升级版本号、待验证的设备
在这里插入图片描述
在这里插入图片描述
(12)验证中
在这里插入图片描述
(13)点击查看
在这里插入图片描述
(14)等待升级成功
在这里插入图片描述
(15)查看日志/设备详情,查看设备是否升级成功
在这里插入图片描述

Class-ota

initonreportdownloadverifyupgrade
初始化ota服务注册ota升级相关的回调函数上报ota升级版本号,模块名等信息下载ota升级包升级包校验执行ota升级操作

ota.init(data_handle) - 初始化

函数功能:ota 初始化,建立ota后台服务线程
注意事项:确保wifi连接成功 确保aliyunIoT连接成功
参数说明:
参数类型必选参数?说明
data_handledictionaryota初始化需要参数
data_handle参数说明:
参数类型必选参数?说明
device_handleintaliyunIoT句柄
返回值说明:成功返回0, 其他表示失败

ota.report(report_info) - 上报当前模块版本

函数功能:上报模块版本号信息
注意事项:确保wifi连接成功
		 确保aliyunIoT连接成功
参数说明:
参数类型必选参数?说明
report_infodictionary上报模块版本号需要的信息
report_info参数说明:
参数类型必选参数?说明
device_handleintaliyunIoT句柄
product_keystring上云三元组信息product_key
device_namestring上云三元组信息device_name
module_namestring待上报模块的名字
module_namestring待上报模块的版本号
返回值说明:成功返回0, 其他表示失败。

ota.on(1, on_trigger) - 回调注册 - 1

函数功能:注册OTA的on_trigger回调函数,在升级开始时触发
注意事项:确保wifi连接成功。
		 确保aliyunIoT连接成功。
	   	 确保ota.init执行完成。
参数说明:
参数类型必选参数?说明
on_triggerfuncCallback文件升级触发时的回调函数
on_trigger函数原型:def on_trigger(data)

Copy to clipboardErrorCopied
on_trigger函数参数说明:

参数类型必选参数?说明
datadictionaryon_trigger函数触发时传入on_trigger的参数
on_trigger函数data参数说明:
参数类型必选参数?说明
urlstring待升级文件所在url
lengthint待升级文件文件长度,单位是字节
module_namestring待升级文件的模块名称
versionstring待升级文件的版本号
hashstring待升级文件的哈希值
hash_typestring待升级文件的哈希类型
返回值说明:成功返回0, 其他表示失败。

ota.on(2, on_download) - 回调注册 - 2

函数功能:注册OTA的on_download回调函数,在download完成时触发
注意事项:确保wifi连接成功
		 确保aliyunIoT连接成功
	 	 确保ota.init执行完成
参数说明:
参数类型必选参数?说明
on_downloadfuncCallback文件下载完成时的回调函数
on_download函数原型:def on_download(data)

on_download函数参数说明:
参数类型必选参数?说明
datainton_download函数触发时传入on_download的参数 ,大于等于0说明download成功,否则失败
返回值说明:成功返回0, 其他表示失败。

ota.on(3, on_verify) - 回调注册 - 3

函数功能:注册OTA的on_verify回调函数,在verify完成时触发
注意事项:确保wifi连接成功
		 确保aliyunIoT连接成功
		 确保ota.init执行完成
参数说明:
参数类型必选参数?说明
on_verifyfuncCallback文件校验完成时的回调函数
on_verify函数原型:def on_verify(data)
on_verify函数参数说明:
参数类型必选参数?说明
datainton_verify函数触发时传入on_download的参数 ,大于等于0说明verify成功,否则失败
返回值说明:成功返回0, 其他表示失败。

ota.download(data) - 文件下载

函数功能:发起文件下载流程。
注意事项:确保wifi连接成功
		 确保aliyunIoT连接成功
		 确保ota.init执行完成

参数说明:
参数类型必选参数?说明
datadictionary发起文件下载流程所需要的信息
data参数说明:
参数类型必选参数?说明
urlstring文件所在的url信息
store_pathstring文件要下载到的文件系统路径
返回值说明:成功返回0, 其他表示失败。

ota.verify(data) - 文件校验

函数功能:发起文件校验流程
注意事项:确保wifi连接成功
		 确保aliyunIoT连接成功
		 确保ota.init执行完成
参数说明:
参数类型必选参数?说明
datadictionary发起文件校验流程所需要的信息
data参数说明:
参数类型必选参数?说明
lengthint文件长度,单位是字节
store_pathstring文件所在的文件系统路径
hash_typestring文件的哈希类型
hashstring文件的哈希值
返回值说明:成功返回0, 其他表示失败。

ota.upgrade(param)
+ 作用: 执行ota升级操作
+ 参数: param是一个字典,包含length,store_path,install_path
+ 返回: 0成功

属性类型说明
length字符串ota的升级包大小
store_path字符串ota包的保存路径
install_path字符串ota包的安装路径

3.总结

本节介绍了如何使用haas506高级组件库中的ota模块,实现了ota升级功能。

<think>好的,用户现在想了解如何在HaaS506-LD1上开发MODBUS相关功能。首先,我需要回顾之前的对话,确保当前回答与之前的建议一致。之前用户询问了关于HaaS506-LD1的资料获取途径,我提供了官方文档、GitHub仓库和快速入门步骤,还提到了技术特性和相关问题。现在用户的新问题是关于MODBUS开发的指南,需要结合之前的建议和现有的引用内容来回答。 首先,检查提供的引用内容。引用[1]提到了HaaS506-HD1的OTA升级和本地更新固件,引用[2]涉及驱动安装和固件烧写,引用[3]是智能路灯的案例,引用[4]介绍了硬件接口,包括485和232,这两个接口常用于MODBUS通信。虽然用户提到的是LD1型号,但引用中都是HD1,可能需要确认是否有误,或者假设接口相似。此外,用户之前的问题中提到的开发板支持LoRaWAN和云连接,但MODBUS通常使用串口(如RS485/RS232),所以需要确保硬件支持这些接口。 接下来,用户需要的是开发指南,所以步骤要清晰。首先,硬件连接部分,需要确定HaaS506-LD1是否有RS485或RS232接口,根据引用[4],HD1型号有这些接口,假设LD1类似。然后,配置开发环境,用户之前已经安装了VS Code和HaaS Studio,可能需要安装额外的MODBUS库。接着,编写代码部分,可能需要示例代码,比如使用Python的modbus_tk库,或阿里提供的API。然后,测试与调试,使用工具如Modbus Poll或自己编写主机程序。云端集成部分,可能需要将数据上传到阿里云IoT平台,引用[3]中的智能路灯案例可能有参考价值。 还需要考虑用户可能遇到的问题,比如硬件连接是否正确、库的安装问题、协议配置错误等,所以要在注意事项里提到这些。此外,引用[1]中的本地固件更新和引用[2]的驱动安装可能与MODBUS开发相关,比如确保固件版本支持相关功能,驱动安装正确才能使用串口。 用户可能没有明确说明使用MODBUS RTU还是ASCII,或者TCP,但通常硬件串口使用RTU模式,所以默认假设RTU。同时,需要指导用户如何设置从机地址、寄存器地址等参数,这些在示例代码中需要体现。 另外,用户可能希望知道如何将MODBUS数据上传到云端,结合之前的回答中的云连接方案,需要将MODBUS设备的数据通过HaaS506-LD1传输到阿里云,这部分可能需要MQTT协议,如引用[4]中提到的透传模式,或者使用阿里云IoT SDK。 最后,生成的相关问题需要围绕MODBUS开发的扩展,比如协议选择、多设备、异常处理、云平台集成等,帮助用户进一步探索。</think>### HaaS506-LD1 MODBUS 开发指南 #### 一、硬件准备与接口说明 1. **硬件接口** HaaS506-LD1 支持 RS485 和 RS232 通信接口(需确认具体硬件版本)[^4]。 - **RS485**:通常用于工业级 MODBUS RTU 协议,支持多点通信。 - **RS232**:适用于点对点 MODBUS ASCII 协议。 2. **接线示例** ```plaintext HaaS506-LD1 (主设备) <--> MODBUS 从设备(如传感器、PLC) RS485_A 接从设备 A+ RS485_B 接从设备 B- GND 共地 ``` #### 二、开发环境配置 1. **依赖库安装** - 通过 HaaS Studio 安装 `modbus_tk` 库(Python MODBUS 协议栈): ```bash pip install modbus_tk ``` - 阿里云 IoT 提供的 `haas_modbus` 扩展(参考官方 GitHub 仓库)[^1]。 2. **硬件驱动配置** 确保串口驱动已正确安装(如 CH340/CP2102 等),并在代码中绑定对应串口号(如 `UART1`)[^2]。 #### 三、MODBUS 功能实现 1. **代码框架(主设备模式)** ```python import modbus_tk.defines as cst from modbus_tk import modbus_rtu # 初始化 RS485 串口 port = "/dev/ttyS1" # 根据实际端口修改 master = modbus_rtu.RtuMaster(serial.Serial(port=port, baudrate=9600)) master.set_timeout(2.0) # 读取从设备寄存器 try: data = master.execute(slave=1, function_code=cst.READ_HOLDING_REGISTERS, starting_address=0, quantity=5) print("寄存器值:", data) except Exception as e: print("MODBUS 通信异常:", e) ``` 2. **关键参数说明** - `slave`: 从设备地址(1-247) - `function_code`: 功能码(如 `READ_COILS`, `WRITE_SINGLE_REGISTER`) - `starting_address`: 寄存器起始地址(需根据从设备手册配置) #### 四、云端数据上传(可选) 将 MODBUS 数据通过 MQTT 上传至阿里云 IoT 平台: ```python from aliyunIoT import Device # 初始化设备三元组(替换实际值) device = Device({ "productKey": "pk_xxx", "deviceName": "dn_xxx", "deviceSecret": "ds_xxx" }) # 上传数据 def upload_to_cloud(data): payload = {"params": {"modbus_data": data}} device.postProps(payload) ``` #### 五、注意事项 1. **协议一致性** - 确认从设备的 MODBUS 协议类型(RTU/ASCII)和波特率(如 9600/19200)。 - 地址偏移问题:部分设备寄存器地址需从 0 或 1 开始计算[^3]。 2. **调试工具** - 使用 `Modbus Poll` 或 `QModMaster` 工具模拟从设备测试通信。 - 通过 `逻辑分析仪` 抓取 RS485 波形排查物理层问题。 --- ### 相关问题 1. MODBUS RTU 和 ASCII 协议在 HaaS506-LD1 上如何选择? 2. 如何实现 HaaS506-LD1 同时连接多个 MODBUS 从设备? 3. MODBUS 通信中出现超时错误应如何排查? 4. 是否支持将 MODBUS 数据直接映射到阿里云 IoT 物模型? --- ### 参考来源 : HaaS506-HD1 本地固件更新开发框架说明 [^2]: RS485 驱动安装与串口配置实践 [^3]: 工业协议调试案例(智能路灯项目) [^4]: HaaS506-HD1 硬件接口技术规格
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值