1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-04 04:12:23 +01:00

add ota callbacks

This commit is contained in:
Tomasz Duda
2024-02-13 00:47:53 +01:00
parent 856191760f
commit 9019416a05
10 changed files with 112 additions and 44 deletions

View File

@@ -1,18 +0,0 @@
#include "fota_component.h"
#include <zephyr/usb/usb_device.h>
#include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
extern "C" void start_smp_bluetooth_adverts();
namespace esphome {
namespace fota {
void FOTAComponent::setup() {
if (IS_ENABLED(CONFIG_USB_DEVICE_STACK)) {
usb_enable(NULL);
}
start_smp_bluetooth_adverts();
}
} // namespace fota
} // namespace esphome

View File

@@ -1,14 +0,0 @@
#pragma once
#include "esphome/core/component.h"
namespace esphome {
namespace fota {
class FOTAComponent : public Component {
public:
void setup() override;
};
} // namespace fota
} // namespace esphome

View File

@@ -67,8 +67,8 @@ def zephyr_to_code(conf):
else: else:
raise NotImplementedError raise NotImplementedError
# c++ support # c++ support
zephyr_add_prj_conf("NEWLIB_LIBC", False) zephyr_add_prj_conf("NEWLIB_LIBC", True)
zephyr_add_prj_conf("NEWLIB_LIBC_NANO", True) zephyr_add_prj_conf("CONFIG_FPU", True)
zephyr_add_prj_conf("NEWLIB_LIBC_FLOAT_PRINTF", True) zephyr_add_prj_conf("NEWLIB_LIBC_FLOAT_PRINTF", True)
zephyr_add_prj_conf("CPLUSPLUS", True) zephyr_add_prj_conf("CPLUSPLUS", True)
zephyr_add_prj_conf("LIB_CPLUSPLUS", True) zephyr_add_prj_conf("LIB_CPLUSPLUS", True)

View File

@@ -3,7 +3,6 @@ import esphome.config_validation as cv
from esphome.const import ( from esphome.const import (
CONF_ID, CONF_ID,
) )
from esphome.components.nrf52.zephyr import zephyr_add_prj_conf from esphome.components.nrf52.zephyr import zephyr_add_prj_conf
zephyr_ble_server_ns = cg.esphome_ns.namespace("zephyr_ble_server") zephyr_ble_server_ns = cg.esphome_ns.namespace("zephyr_ble_server")
@@ -23,5 +22,4 @@ async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
zephyr_add_prj_conf("BT", True) zephyr_add_prj_conf("BT", True)
zephyr_add_prj_conf("BT_PERIPHERAL", True) zephyr_add_prj_conf("BT_PERIPHERAL", True)
zephyr_add_prj_conf("BT_DEVICE_NAME_DYNAMIC", True)
await cg.register_component(var, config) await cg.register_component(var, config)

View File

@@ -1,7 +1,6 @@
#include "ble_server.h" #include "ble_server.h"
#include "esphome/core/defines.h" #include "esphome/core/defines.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/application.h"
#include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h> #include <zephyr/bluetooth/conn.h>
@@ -67,12 +66,6 @@ void BLEServer::setup() {
ESP_LOGE(TAG, "Bluetooth enable failed: %d", rc); ESP_LOGE(TAG, "Bluetooth enable failed: %d", rc);
return; return;
} }
rc = bt_set_name(App.get_name().c_str());
if (rc != 0) {
ESP_LOGE(TAG, "Bluetooth set name failed: %d", rc);
return;
}
} }
} // namespace zephyr_ble_server } // namespace zephyr_ble_server

View File

@@ -14,3 +14,7 @@ async def to_code(config):
zephyr_add_prj_conf("FLASH", True) zephyr_add_prj_conf("FLASH", True)
zephyr_add_prj_conf("BOOTLOADER_MCUBOOT", True) zephyr_add_prj_conf("BOOTLOADER_MCUBOOT", True)
zephyr_add_prj_conf("MCUMGR_MGMT_NOTIFICATION_HOOKS", True)
zephyr_add_prj_conf("MCUMGR_GRP_IMG_STATUS_HOOKS", True)
zephyr_add_prj_conf("MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK", True)

View File

@@ -0,0 +1,83 @@
#include "ota_component.h"
#include "esphome/core/defines.h"
#include "esphome/core/log.h"
#include "esphome/core/hal.h"
#include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
#include <zephyr/sys/math_extras.h>
struct img_mgmt_upload_action {
/** The total size of the image. */
unsigned long long size;
};
struct img_mgmt_upload_req {
uint32_t image; /* 0 by default */
size_t off; /* SIZE_MAX if unspecified */
};
namespace esphome {
namespace zephyr_ota_mcumgr {
static const char *const TAG = "zephyr_ota_mcumgr";
static enum mgmt_cb_return mcumgr_img_mgmt_cb(uint32_t event, enum mgmt_cb_return prev_status, int32_t *rc,
uint16_t *group, bool *abort_more, void *data, size_t data_size) {
if (MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK == event) {
const img_mgmt_upload_check &upload = *static_cast<img_mgmt_upload_check *>(data);
static_cast<OTAComponent *>(ota::global_ota_component)->update_chunk(upload);
} else if (MGMT_EVT_OP_IMG_MGMT_DFU_STARTED == event) {
static_cast<OTAComponent *>(ota::global_ota_component)->update_started();
} else if (MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK_WRITE_COMPLETE == event) {
static_cast<OTAComponent *>(ota::global_ota_component)->update_chunk_wrote();
} else if (MGMT_EVT_OP_IMG_MGMT_DFU_PENDING == event) {
static_cast<OTAComponent *>(ota::global_ota_component)->update_pending();
} else {
ESP_LOGD(TAG, "MCUmgr Image Management Event with the %d ID", u32_count_trailing_zeros(MGMT_EVT_GET_ID(event)));
}
return MGMT_CB_OK;
}
static struct mgmt_callback img_mgmt_callback = {
.callback = mcumgr_img_mgmt_cb,
.event_id = MGMT_EVT_OP_IMG_MGMT_ALL,
};
OTAComponent::OTAComponent() { ota::global_ota_component = this; }
void OTAComponent::setup() { mgmt_callback_register(&img_mgmt_callback); }
void OTAComponent::dump_config() {
ESP_LOGCONFIG(TAG, "Over-The-Air Updates:");
}
void OTAComponent::update_chunk(const img_mgmt_upload_check &upload) {
_percentage = (upload.req->off * 100.0f) / upload.action->size;
}
void OTAComponent::update_started() {
ESP_LOGD(TAG, "Starting OTA Update from %s...", "ble");
#ifdef USE_OTA_STATE_CALLBACK
this->state_callback_.call(ota::OTA_STARTED, 0.0f, 0);
#endif
}
void OTAComponent::update_chunk_wrote() {
uint32_t now = millis();
if (now - _last_progress > 1000) {
_last_progress = now;
ESP_LOGD(TAG, "OTA in progress: %0.1f%%", _percentage);
#ifdef USE_OTA_STATE_CALLBACK
this->state_callback_.call(ota::OTA_IN_PROGRESS, _percentage, 0);
#endif
}
}
void OTAComponent::update_pending() {
ESP_LOGD(TAG, "OTA pending");
#ifdef USE_OTA_STATE_CALLBACK
this->state_callback_.call(ota::OTA_COMPLETED, 100.0f, 0);
#endif
}
} // namespace zephyr_ota_mcumgr
} // namespace esphome

View File

@@ -2,10 +2,25 @@
#include "esphome/components/ota/ota_component.h" #include "esphome/components/ota/ota_component.h"
struct img_mgmt_upload_check;
namespace esphome { namespace esphome {
namespace zephyr_ota_mcumgr { namespace zephyr_ota_mcumgr {
class OTAComponent : public ota::OTAComponent {}; class OTAComponent : public ota::OTAComponent {
public:
OTAComponent();
void setup() override;
void dump_config() override;
void update_chunk(const img_mgmt_upload_check &upload);
void update_started();
void update_chunk_wrote();
void update_pending();
protected:
uint32_t _last_progress = 0;
float _percentage = 0;
};
} // namespace zephyr_ota_mcumgr } // namespace zephyr_ota_mcumgr
} // namespace esphome } // namespace esphome

View File

@@ -39,6 +39,7 @@ from esphome.const import (
) )
from esphome.core import CORE, coroutine_with_priority from esphome.core import CORE, coroutine_with_priority
from esphome.helpers import copy_file_if_changed, walk_files from esphome.helpers import copy_file_if_changed, walk_files
from esphome.components.nrf52.zephyr import zephyr_add_prj_conf
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@@ -359,6 +360,9 @@ async def to_code(config):
) )
) )
if CORE.using_zephyr:
zephyr_add_prj_conf("BT_DEVICE_NAME", config[CONF_NAME])
CORE.add_job(_add_automations, config) CORE.add_job(_add_automations, config)
cg.add_build_flag("-fno-exceptions") cg.add_build_flag("-fno-exceptions")

View File

@@ -82,6 +82,9 @@ async def smpmgr_upload(config, host, firmware):
_LOGGER.warning("No images on device!") _LOGGER.warning("No images on device!")
for image in image_state.images: for image in image_state.images:
pprint(image) pprint(image)
if image.active and not image.confirmed:
_LOGGER.error("No free slot")
return 1
if image.hash == image_tlv_sha256: if image.hash == image_tlv_sha256:
if already_uploaded: if already_uploaded:
_LOGGER.error("Both slots have the same image") _LOGGER.error("Both slots have the same image")