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:
@@ -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
|
|
@@ -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
|
|
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
83
esphome/components/zephyr_ota_mcumgr/ota_component.cpp
Normal file
83
esphome/components/zephyr_ota_mcumgr/ota_component.cpp
Normal 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
|
@@ -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
|
||||||
|
@@ -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")
|
||||||
|
@@ -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")
|
||||||
|
Reference in New Issue
Block a user