利用vsc+py+巴法云实现带版本号的OTA自动更新检测

原理

在巴法云上传OTA之前的文章已经有介绍,这里不在多说,巴法云提供了https://api.bemfa.com/api/device/v1/bin的地址获取OTA固件的地址.它使用GET接口完整的地址为https://api.bemfa.com/api/device/v1/bin?uid=xxxx&topic=xxxx&type=xxx这几个名字都可以望文生意,这里只说type MQTT设备=1 TCP设备=2 图云=3.具体可以参考巴法开放平台 (bemfa.com)

在VSC里提供了方便的运行脚本的方法,这里可以利用py访问上面这个址即可方便的获取ota固件信息,能过这个信息生成相应的版本宏定义,这里我生成一个名叫ota_version.h的头文件方便引用,通过这个脚本即可在每次编译前获取一次亲了最新的版本号,这个版本号+1即是当前版本号.这想通过对比自己的版本号和远程的版本号即可确定是否需要更新.当然在ESP8266HTTPUpdate的实现其实已经考虑了这个问题,但是巴法云的文档并未说明是否支持这个特性,所以我这里自己检测一下.当然感兴趣的也可以自己测试一下.httpUpdate.update(UpdateClient, otaurl /*, current_ver*/);这个current_ver即是版本号.

步骤

在vsc的资源管理器窗口建立一个叫UpdateVer.py的文件.(顺便一说,要使用py,当然要先安装好py的运行环境,因为我这里使用了新特性,所以需要py3.10版本以上)正常情况你安装了py会在vs的下面显示版本如下图

 UpdateVer.py内容如下:

import urllib3
import json
http = urllib3.PoolManager()  # 线程池生成请求
res = http.request('GET', 'https://api.bemfa.com/api/device/v1/bin?uid=纟xxxx&topic=xxx&type=1')

'''
5723001	缺少uid字段
5723002	uid值为空或不正确
5723003	缺少type字段
5723004	type值为空或不正确
5723005	缺少topic字段
5723007	获取成功
5724009	固件为空不存在
'''
#{"code":5723007,"data":{"url":"http:\/\/bin.bemfa.com\/b\/.bin","time":"2023-07-11 21:13:46","v":"19","tag":""}}
jsonobject = json.loads(res.data.decode())
successed=False
match jsonobject["code"]:
    case 5723001:print('缺少uid字段')
    case 5723002:print('缺少uid字段')
    case 5723003:print('缺少type字段')
    case 5723004:print('type值为空或不正确')
    case 5723005:print('缺少topic字段')
    case 5723007:
        print('获取成功')
        successed=True
    case 5724009:print('固件为空不存在')

print('当前版本发布号:'+(str(int(jsonobject['data']['v'])+1) if successed else '1'))
with open("ota_version.h",mode='w',encoding='utf-8') as ff:
            ff.write( '#define OTA_VER '+str(int(jsonobject['data']['v'])+1) if successed else '#define OTA_VER '+'1')

上面uid topic type需要按实际情况修改.

下面在资源管理器里找到.vscode/arduino.json打开.添加 如下行"prebuild": "py ./UpdateVer.py"

现在就像如上.这样每次编译前就会执行updatever.py.生成  ota_version.h.这样即可保证每次编译的版本号都 比远程的大1.

在8266上检测是否有更新

代码如下

String CheckUpdate(const char *uid, const char *topic, const char *devType)
    {
        String ota_url;
        if (uid == nullptr || topic == nullptr || devType == nullptr)
            return ota_url;

        // https://api.bemfa.com/api/device/v1/bin/
        String otaInfoUrl = R"(https://api.bemfa.com/api/device/v1/bin?uid=)";
        // uid=%s&topic=%s&type=%d
        otaInfoUrl += uid;
        otaInfoUrl += "&topic=";
        otaInfoUrl += topic;
        otaInfoUrl += "&type=";
        otaInfoUrl += devType;
        Serial.println(u8"从" + otaInfoUrl + u8"获取ota信息");

        std::unique_ptr<BearSSL::WiFiClientSecure> client(new BearSSL::WiFiClientSecure);
        client->setInsecure();
        HTTPClient httpClient;
        httpClient.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
        if (httpClient.begin(*client, otaInfoUrl))
        {
            int httpCode = httpClient.GET();
            if (httpCode == HTTP_CODE_OK)
            {
                String json = httpClient.getString(); // 使用getString函数获取服务器响应体内容
                DynamicJsonDocument doc(512);
                // 反序列数据

                if (!deserializeJson(doc, json))
                {
                    //{"code":5723007,"data":{"url":"http:\/\/bin.bemfa.com\/b\/.bin","time":"2023-07-11 21:13:46","v":"19","tag":""}}
                    if (doc["code"].as<uint64_t>() == 5723007)
                    {
                        Serial.println(u8"获取ota信息成功");
                        String verStr = doc["data"]["v"];
                        int ver = verStr.toInt();
                        if (ver > OTA_VER)
                        {
                            Serial.print(u8"获取ota url成功:");
                            ota_url = doc["data"]["url"].as<String>();
                            Serial.println(ota_url);
                        }
                        else
                        {
                            Serial.println(u8"当前已经是最新版本,ota无更新");
                        }
                    }
                    else
                    {
                        Serial.println(doc["code"].as<uint64_t>());
                    }
                }
                else{
                    Serial.println("json反序列化失败");
                }
            }
            else
            {
                Serial.print("\r\nServer Respose Code: ");
                Serial.println(httpCode);
            }
            httpClient.end();
        }
        return ota_url;
    }

这样即可正常检测,有更新即返回ota的url.当然 这里可以做理精细处理,比如没有更新时给出原因方便分析.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值