Compare commits
7 commits
main
...
zigbee-ota
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b72b97091c | ||
|
|
7dcd4bfe53 | ||
|
|
4bb9a97daa | ||
|
|
76a76de52c | ||
|
|
bb2f3cc3c2 | ||
|
|
61533da1b6 | ||
|
|
a15bd37a1a |
12 changed files with 156 additions and 23 deletions
2
.github/workflows/b-parasite.yml
vendored
2
.github/workflows/b-parasite.yml
vendored
|
|
@ -86,7 +86,7 @@ jobs:
|
|||
sample-dir: code/nrf-connect/samples/ble
|
||||
board: bparasite_${{ matrix.soc }}
|
||||
revision: ${{ matrix.revision }}
|
||||
cmake-extra: -DCONFIG_PRST_BLE_ENCODING_BTHOME_V2=y -DCONFIG_PRST_SLEEP_DURATION_MSEC=1000 -DCONFIG_PRSTLIB_LOG_LEVEL_DBG=y
|
||||
cmake-extra: -DCONFIG_PRST_BLE_ENCODING_BTHOME_V2=y -DCONFIG_PRST_SLEEP_DURATION_SEC=1 -DCONFIG_PRSTLIB_LOG_LEVEL_DBG=y
|
||||
output-bin: ble_${{ matrix.soc }}_${{ matrix.revision }}_debug.hex
|
||||
|
||||
build-zigbee:
|
||||
|
|
|
|||
|
|
@ -49,12 +49,6 @@ We have three different 3D-printable cases:
|
|||
1. Original snap-on case - [case/Top.stl](./case/Top.stl), [case/Bottom.stl](./case/Bottom.stl)
|
||||
2. High airflow - [case/b_parasite_case_high_airflow.stl](./case/b_parasite_case_high_airflow.stl)
|
||||
3. Mushroom-style - available on [Printables](https://www.printables.com/model/456571-mushroomcap-for-b-parasite-soil-moisture-sensor)
|
||||
4. b-parasite Hat - available on [Printables](https://www.printables.com/model/901220-waterproof-case-for-b-parasite-soil-moisture-air-s)
|
||||
|
||||
# Accessories
|
||||
|
||||
Designs and hardware to help you, when building your own:
|
||||
1. Desk holder for b-parasites [Printables](https://www.printables.com/de/model/566974-b-parasite-holder)
|
||||
|
||||
# License
|
||||
The hardware and associated design files are released under the [Creative Commons CC BY-SA 4.0 license](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@ int prst_sensors_read_all(prst_sensors_t *sensors) {
|
|||
|
||||
LOG_DBG("Batt: %d mV (%.2f%%)", sensors->batt.adc_read.millivolts,
|
||||
100 * sensors->batt.percentage);
|
||||
LOG_DBG("Soil: %.0f %%", 100 * sensors->soil.percentage);
|
||||
LOG_DBG("Soil: %.0f %% (%d mV)", 100 * sensors->soil.percentage,
|
||||
sensors->soil.adc_read.millivolts);
|
||||
LOG_DBG("Photo: %u lx (%d mV)", sensors->photo.brightness,
|
||||
sensors->photo.adc_read.millivolts);
|
||||
sensors->soil.adc_read.millivolts);
|
||||
LOG_DBG("Temp: %f oC", sensors->shtc3.temp_c);
|
||||
LOG_DBG("Humi: %.0f %%", 100 * sensors->shtc3.rel_humi);
|
||||
LOG_DBG("--------------------------------------------------");
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
source "Kconfig.zephyr"
|
||||
rsource "../../prstlib/Kconfig"
|
||||
|
||||
config PRST_SLEEP_DURATION_MSEC
|
||||
int "Sleep duration in milliseconds"
|
||||
default 600000
|
||||
config PRST_SLEEP_DURATION_SEC
|
||||
int "Sleep duration in seconds"
|
||||
default 600
|
||||
|
||||
config PRST_BLE_ADV_DURATION_MSEC
|
||||
int "Advertising duration in milliseconds"
|
||||
default 1000
|
||||
config PRST_BLE_ADV_DURATION_SEC
|
||||
int "Advertising duration in seconds"
|
||||
default 1
|
||||
|
||||
config PRST_BLE_MIN_ADV_INTERVAL
|
||||
int "Minimum advertising interval in milliseconds"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Available configurations and their default values are in [`Kconfig`](./Kconfig).
|
|||
To save energy, the board spends most of the time in a "deep sleep" state, in which most peripherals and radio are completely turned off. The period of sleep is controlled by the `PRST_SLEEP_DURATION_SEC` config.
|
||||
|
||||
### Advertising Duration
|
||||
When it wakes up, the sample reads all sensors and keep broadcasting advertising packets for `PRST_BLE_ADV_DURATION_MSEC` before going back to sleep.
|
||||
When it wakes up, the sample reads all sensors and keep broadcasting advertising packets for `PRST_BLE_ADV_DURATION_SEC` before going back to sleep.
|
||||
|
||||
### Advertising Packet Encoding
|
||||
There are different ways to encode the sensor data in a BLE advertising packet.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ CONFIG_ASSERT=y
|
|||
|
||||
# Application config - see all options in Kconfig.
|
||||
# CONFIG_PRST_BLE_ENCODING_BTHOME_V2=y
|
||||
# CONFIG_PRST_SLEEP_DURATION_MSEC=1000
|
||||
# CONFIG_PRST_SLEEP_DURATION_SEC=1
|
||||
|
||||
# prstlib config - ser all options in prstlib/Kconfig.
|
||||
# CONFIG_PRSTLIB_LOG_LEVEL_DBG=y
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ static int prst_loop(prst_sensors_t *sensors) {
|
|||
RET_IF_ERR(prst_sensors_read_all(sensors));
|
||||
RET_IF_ERR(prst_ble_adv_set_data(sensors));
|
||||
RET_IF_ERR(prst_ble_adv_start());
|
||||
k_msleep(CONFIG_PRST_BLE_ADV_DURATION_MSEC);
|
||||
k_sleep(K_SECONDS(CONFIG_PRST_BLE_ADV_DURATION_SEC));
|
||||
RET_IF_ERR(prst_ble_adv_stop());
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -37,6 +37,6 @@ int main(void) {
|
|||
prst_sensors_t sensors;
|
||||
while (true) {
|
||||
__ASSERT(!prst_loop(&sensors), "Error in prst_loop()");
|
||||
k_msleep(CONFIG_PRST_SLEEP_DURATION_MSEC);
|
||||
k_sleep(K_SECONDS(CONFIG_PRST_SLEEP_DURATION_SEC));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ config PRST_ZB_BUILD_DATE
|
|||
string "Zigbee basic cluster build date attribute. Max 16 bytes."
|
||||
default ""
|
||||
|
||||
config PRST_ZB_SOFTWARE_VERSION
|
||||
string "Zigbee basic cluster software version attribute. Max 16 bytes."
|
||||
default ""
|
||||
|
||||
config PRST_ZB_MODEL_ID
|
||||
string "Zigbee basic cluster model id attribute. Max 32 bytes."
|
||||
default "b-parasite"
|
||||
|
|
@ -42,3 +46,39 @@ endchoice # PRST_ZB_FACTORY_RESET_METHOD
|
|||
config PRST_ZB_RESTART_WATCHDOG_TIMEOUT_SEC
|
||||
int "Duration after the device will restart the rejoin procedure if a network has not been successfully joined."
|
||||
default 3600
|
||||
|
||||
if ZIGBEE_FOTA
|
||||
|
||||
config ZIGBEE_FOTA_ENDPOINT
|
||||
int "Endpoint number for ota zigbee endpoint. Must not be used by another application."
|
||||
default 5
|
||||
|
||||
config ZIGBEE_FOTA_COMMENT
|
||||
string
|
||||
default "b-parasite"
|
||||
|
||||
config IMG_MANAGER
|
||||
bool "Ensure an MCUboot-compatible binary for ota update is generated."
|
||||
default y
|
||||
|
||||
config STREAM_FLASH
|
||||
bool
|
||||
default y
|
||||
|
||||
config DFU_TARGET_MCUBOOT
|
||||
bool
|
||||
default y
|
||||
|
||||
config IMG_ERASE_PROGRESSIVELY
|
||||
bool
|
||||
default y
|
||||
|
||||
config ZIGBEE_FOTA_PROGRESS_EVT
|
||||
bool
|
||||
default y
|
||||
|
||||
config NRF_802154_RX_BUFFERS
|
||||
int "Increase the number of RX buffers for ota functionality."
|
||||
default 32
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@ Available options in `Kconfig`. Notable options:
|
|||
* `CONFIG_PRST_ZB_SLEEP_DURATION_SEC`: amount of time (in seconds) the device sleeps between reading all sensors and updating its clusters
|
||||
* `CONFIG_PRST_ZB_PARENT_POLL_INTERVAL_SEC`: amount of time (in seconds) the device waits between polling its parent for data
|
||||
|
||||
### Over the air (OTA) updates
|
||||
The firmware is prepared for accepting over the air updates. You need to set the toggle `CONFIG_ZIGBEE_OTA` in the `prj.conf` to `y` to compile OTA functionality in the firmware.
|
||||
|
||||
Once the toggle is set, during compilation there will be a *.zigbee file generated as well, which is the firmware update file. This needs to be provided to your zigbee coordinator, so that it can be discovered by your deployed and paired parasites. The version `CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION` needs to be increased to allow the device to recognize the firmware file as an actual update.
|
||||
|
||||
Some helpful information on how to provide an firmware update via Home Assistant and ZHA integration can be found in the [Home Assistant forums](https://community.home-assistant.io/t/zha-ota-firmware-update-upgrade/488960).
|
||||
|
||||
## Home Assistant Integration
|
||||
This firmware sample has only been tested with Home Assistant, using one of the following integrations.
|
||||
|
||||
|
|
|
|||
|
|
@ -70,3 +70,8 @@ CONFIG_ASSERT=y
|
|||
# Factory reset method selection. Only hardware revision 2.0.0+ has button SW1. Earlier
|
||||
# revisions must select a different method. See Kconfig for options.
|
||||
# CONFIG_PRST_ZB_FACTORY_RESET_VIA_SW1=y
|
||||
## OTA section
|
||||
|
||||
# OTA update configuration. This is based on the zigbee light switch example from the nrf-connect toolkit.
|
||||
CONFIG_ZIGBEE_FOTA=n
|
||||
CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="1.0.0" # Increase this version for generating an update for the devices.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@
|
|||
#include <zigbee/zigbee_app_utils.h>
|
||||
#include <zigbee/zigbee_error_handler.h>
|
||||
|
||||
#if CONFIG_ZIGBEE_FOTA
|
||||
#include <zephyr/dfu/mcuboot.h>
|
||||
#include <zephyr/sys/reboot.h>
|
||||
#include <zigbee/zigbee_fota.h>
|
||||
#endif
|
||||
|
||||
#include "debug_counters.h"
|
||||
#include "factory_reset.h"
|
||||
#include "flash_fs.h"
|
||||
|
|
@ -115,9 +121,62 @@ PRST_ZB_DECLARE_ENDPOINT(
|
|||
PRST_ZIGBEE_ENDPOINT,
|
||||
app_template_clusters);
|
||||
|
||||
#ifndef CONFIG_ZIGBEE_FOTA
|
||||
ZBOSS_DECLARE_DEVICE_CTX_1_EP(
|
||||
app_template_ctx,
|
||||
app_template_ep);
|
||||
#else
|
||||
|
||||
extern zb_af_endpoint_desc_t zigbee_fota_client_ep;
|
||||
|
||||
ZBOSS_DECLARE_DEVICE_CTX_2_EP(
|
||||
app_template_ctx,
|
||||
zigbee_fota_client_ep,
|
||||
app_template_ep);
|
||||
|
||||
static void confirm_image(void) {
|
||||
if (!boot_is_img_confirmed()) {
|
||||
int ret = boot_write_img_confirmed();
|
||||
|
||||
if (ret) {
|
||||
LOG_ERR("Couldn't confirm image: %d", ret);
|
||||
} else {
|
||||
LOG_INF("Marked image as OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ota_evt_handler(const struct zigbee_fota_evt *evt) {
|
||||
switch (evt->id) {
|
||||
case ZIGBEE_FOTA_EVT_PROGRESS:
|
||||
prst_led_flash(1);
|
||||
break;
|
||||
case ZIGBEE_FOTA_EVT_FINISHED:
|
||||
LOG_INF("Reboot application.");
|
||||
/* Power on unused sections of RAM to allow MCUboot to use it. */
|
||||
if (IS_ENABLED(CONFIG_RAM_POWER_DOWN_LIBRARY)) {
|
||||
power_up_unused_ram();
|
||||
}
|
||||
sys_reboot(SYS_REBOOT_COLD);
|
||||
break;
|
||||
|
||||
case ZIGBEE_FOTA_EVT_ERROR:
|
||||
LOG_ERR("OTA image transfer failed.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void zcl_device_cb(zb_bufid_t bufid) {
|
||||
zb_zcl_device_callback_param_t *device_cb_param =
|
||||
ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t);
|
||||
|
||||
if (device_cb_param->device_cb_id == ZB_ZCL_OTA_UPGRADE_VALUE_CB_ID) {
|
||||
zigbee_fota_zcl_cb(bufid);
|
||||
} else {
|
||||
device_cb_param->status = RET_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_ZIGBEE_FOTA */
|
||||
|
||||
void identify_cb(zb_bufid_t bufid) {
|
||||
LOG_DBG("Remote identify command called");
|
||||
|
|
@ -185,6 +244,12 @@ void update_sensors_cb(zb_uint8_t arg) {
|
|||
|
||||
void zboss_signal_handler(zb_bufid_t bufid) {
|
||||
// See zigbee_default_signal_handler() for all available signals.
|
||||
|
||||
#ifdef CONFIG_ZIGBEE_FOTA
|
||||
/* Pass signal to the OTA client implementation. */
|
||||
zigbee_fota_signal_handler(bufid);
|
||||
#endif /* CONFIG_ZIGBEE_FOTA */
|
||||
|
||||
zb_zdo_app_signal_hdr_t *sig_hndler = NULL;
|
||||
zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, /*sg_p=*/&sig_hndler);
|
||||
zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
|
||||
|
|
@ -314,15 +379,31 @@ int main(void) {
|
|||
|
||||
prst_zb_attrs_init(&dev_ctx);
|
||||
|
||||
ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx);
|
||||
|
||||
prst_led_flash(2);
|
||||
k_msleep(100);
|
||||
|
||||
ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(PRST_ZIGBEE_ENDPOINT, identify_cb);
|
||||
|
||||
zigbee_configure_sleepy_behavior(/*enable=*/true);
|
||||
power_down_unused_ram();
|
||||
|
||||
#ifdef CONFIG_ZIGBEE_FOTA
|
||||
/* Initialize Zigbee FOTA download service. */
|
||||
zigbee_fota_init(ota_evt_handler);
|
||||
|
||||
/* Mark the current firmware as valid. */
|
||||
confirm_image();
|
||||
|
||||
/* Register callback for handling ZCL commands. */
|
||||
ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
|
||||
#endif /* CONFIG_ZIGBEE_FOTA */
|
||||
|
||||
ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx);
|
||||
|
||||
ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(PRST_ZIGBEE_ENDPOINT, identify_cb);
|
||||
|
||||
#ifdef CONFIG_ZIGBEE_FOTA
|
||||
ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(CONFIG_ZIGBEE_FOTA_ENDPOINT, identify_cb);
|
||||
#endif
|
||||
|
||||
zigbee_enable();
|
||||
|
||||
prst_debug_counters_increment("main_finish");
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ void prst_zb_attrs_init(struct zb_device_ctx *dev_ctx) {
|
|||
CONFIG_PRST_ZB_BUILD_DATE,
|
||||
ZB_ZCL_STRING_CONST_SIZE(CONFIG_PRST_ZB_BUILD_DATE));
|
||||
|
||||
ZB_ZCL_SET_STRING_VAL(
|
||||
dev_ctx->basic_attr.sw_ver,
|
||||
CONFIG_PRST_ZB_SOFTWARE_VERSION,
|
||||
ZB_ZCL_STRING_CONST_SIZE(CONFIG_PRST_ZB_SOFTWARE_VERSION));
|
||||
|
||||
dev_ctx->basic_attr.hw_version = CONFIG_PRST_ZB_HARDWARE_VERSION;
|
||||
|
||||
dev_ctx->batt_attrs.quantity = 1;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue