diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c index 472726676c5167..fba5d69870430f 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c @@ -209,6 +209,7 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, state->target_onoff = onoff; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = ONOFF_TT; if (state->target_onoff != state->onoff) { onoff_tt_values(state); @@ -283,6 +284,7 @@ static void gen_onoff_set(struct bt_mesh_model *model, state->target_onoff = onoff; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = ONOFF_TT; if (state->target_onoff != state->onoff) { onoff_tt_values(state); @@ -338,9 +340,15 @@ static void gen_level_get(struct bt_mesh_model *model, } if (state->transition->counter) { - calculate_rt(state->transition); - net_buf_simple_add_le16(msg, state->target_level); - net_buf_simple_add_u8(msg, state->transition->rt); + if (state->transition->type == LEVEL_TT_MOVE || + state->transition->type == LEVEL_TEMP_TT_MOVE) { + net_buf_simple_add_le16(msg, state->target_level); + net_buf_simple_add_u8(msg, UNKNOWN_VALUE); + } else { + calculate_rt(state->transition); + net_buf_simple_add_le16(msg, state->target_level); + net_buf_simple_add_u8(msg, state->transition->rt); + } } send: @@ -367,9 +375,15 @@ void gen_level_publish(struct bt_mesh_model *model) } if (state->transition->counter) { - calculate_rt(state->transition); - net_buf_simple_add_le16(msg, state->target_level); - net_buf_simple_add_u8(msg, state->transition->rt); + if (state->transition->type == LEVEL_TT_MOVE || + state->transition->type == LEVEL_TEMP_TT_MOVE) { + net_buf_simple_add_le16(msg, state->target_level); + net_buf_simple_add_u8(msg, UNKNOWN_VALUE); + } else { + calculate_rt(state->transition); + net_buf_simple_add_le16(msg, state->target_level); + net_buf_simple_add_u8(msg, state->transition->rt); + } } publish: @@ -426,6 +440,7 @@ static void gen_level_set_unack(struct bt_mesh_model *model, state->target_level = level; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { level_tt_values(state); @@ -444,11 +459,11 @@ static void gen_level_set_unack(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT; + state->transition->type = LEVEL_TT; level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT; + state->transition->type = LEVEL_TEMP_TT; level_temp_handler(state); } } @@ -501,6 +516,7 @@ static void gen_level_set(struct bt_mesh_model *model, state->target_level = level; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { level_tt_values(state); @@ -521,11 +537,11 @@ static void gen_level_set(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT; + state->transition->type = LEVEL_TT; level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT; + state->transition->type = LEVEL_TEMP_TT; level_temp_handler(state); } } @@ -593,6 +609,7 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, state->target_level = tmp32; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { level_tt_values(state); @@ -611,12 +628,11 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT_DELTA; + state->transition->type = LEVEL_TT_DELTA; level_lightness_handler(state); - } else if (bt_mesh_model_elem(model)->addr == - elements[1].addr) { + } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT_DELTA; + state->transition->type = LEVEL_TEMP_TT_DELTA; level_temp_handler(state); } } @@ -685,6 +701,7 @@ static void gen_delta_set(struct bt_mesh_model *model, state->target_level = tmp32; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { level_tt_values(state); @@ -705,76 +722,21 @@ static void gen_delta_set(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT_DELTA; + state->transition->type = LEVEL_TT_DELTA; level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT_DELTA; + state->transition->type = LEVEL_TEMP_TT_DELTA; level_temp_handler(state); } } -static void gen_level_move_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) -{ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4); - struct generic_level_state *state = model->user_data; - - bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS); - net_buf_simple_add_le16(msg, state->level); - - if (state->transition->counter) { - if (state->last_delta < 0) { - net_buf_simple_add_le16(msg, INT16_MIN); - } else { /* 0 should not be possible */ - net_buf_simple_add_le16(msg, INT16_MAX); - } - - net_buf_simple_add_u8(msg, UNKNOWN_VALUE); - } - - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { - printk("Unable to send GEN_LEVEL_SRV Status response\n"); - } -} - -static void gen_level_move_publish(struct bt_mesh_model *model) -{ - int err; - struct net_buf_simple *msg = model->pub->msg; - struct generic_level_state *state = model->user_data; - - if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; - } - - bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS); - net_buf_simple_add_le16(msg, state->level); - - if (state->transition->counter) { - if (state->last_delta < 0) { - net_buf_simple_add_le16(msg, INT16_MIN); - } else { /* 0 should not be possible */ - net_buf_simple_add_le16(msg, INT16_MAX); - } - - net_buf_simple_add_u8(msg, UNKNOWN_VALUE); - } - - err = bt_mesh_model_publish(model); - if (err) { - printk("bt_mesh_model_publish err %d\n", err); - } -} - static void gen_move_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { u8_t tid, tt, delay; s16_t delta; - s32_t tmp32; s64_t now; struct generic_level_state *state = model->user_data; @@ -815,21 +777,22 @@ static void gen_move_set_unack(struct bt_mesh_model *model, state->last_msg_timestamp = now; state->last_delta = delta; - tmp32 = state->level + delta; - if (tmp32 < INT16_MIN) { - tmp32 = INT16_MIN; - } else if (tmp32 > INT16_MAX) { - tmp32 = INT16_MAX; + if (delta < 0) { + state->target_level = INT16_MIN; + } else if (delta > 0) { + state->target_level = INT16_MAX; + } else if (delta == 0) { + state->target_level = state->level; } - state->target_level = tmp32; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { - level_tt_values(state); + level_move_tt_values(state); } else { - gen_level_move_publish(model); + gen_level_publish(model); return; } @@ -838,15 +801,16 @@ static void gen_move_set_unack(struct bt_mesh_model *model, } state->transition->just_started = true; - gen_level_move_publish(model); if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT_MOVE; + state->transition->type = LEVEL_TT_MOVE; + gen_level_publish(model); level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT_MOVE; + state->transition->type = LEVEL_TEMP_TT_MOVE; + gen_level_publish(model); level_temp_handler(state); } } @@ -857,7 +821,6 @@ static void gen_move_set(struct bt_mesh_model *model, { u8_t tid, tt, delay; s16_t delta; - s32_t tmp32; s64_t now; struct generic_level_state *state = model->user_data; @@ -869,7 +832,7 @@ static void gen_move_set(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - gen_level_move_get(model, ctx, buf); + gen_level_get(model, ctx, buf); return; } @@ -899,22 +862,23 @@ static void gen_move_set(struct bt_mesh_model *model, state->last_msg_timestamp = now; state->last_delta = delta; - tmp32 = state->level + delta; - if (tmp32 < INT16_MIN) { - tmp32 = INT16_MIN; - } else if (tmp32 > INT16_MAX) { - tmp32 = INT16_MAX; + if (delta < 0) { + state->target_level = INT16_MIN; + } else if (delta > 0) { + state->target_level = INT16_MAX; + } else if (delta == 0) { + state->target_level = state->level; } - state->target_level = tmp32; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { - level_tt_values(state); + level_move_tt_values(state); } else { - gen_level_move_get(model, ctx, buf); - gen_level_move_publish(model); + gen_level_get(model, ctx, buf); + gen_level_publish(model); return; } @@ -923,16 +887,18 @@ static void gen_move_set(struct bt_mesh_model *model, } state->transition->just_started = true; - gen_level_move_get(model, ctx, buf); - gen_level_move_publish(model); if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT_MOVE; + state->transition->type = LEVEL_TT_MOVE; + gen_level_get(model, ctx, buf); + gen_level_publish(model); level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT_MOVE; + state->transition->type = LEVEL_TEMP_TT_MOVE; + gen_level_get(model, ctx, buf); + gen_level_publish(model); level_temp_handler(state); } } @@ -1313,6 +1279,7 @@ static void light_lightness_set_unack(struct bt_mesh_model *model, state->target_actual = actual; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_ACTUAL_TT; if (state->target_actual != state->actual) { light_lightness_actual_tt_values(state); @@ -1386,6 +1353,7 @@ static void light_lightness_set(struct bt_mesh_model *model, state->target_actual = actual; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_ACTUAL_TT; if (state->target_actual != state->actual) { light_lightness_actual_tt_values(state); @@ -1511,6 +1479,7 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model, state->target_linear = linear; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_LINEAR_TT; if (state->target_linear != state->linear) { light_lightness_linear_tt_values(state); @@ -1577,6 +1546,7 @@ static void light_lightness_linear_set(struct bt_mesh_model *model, state->target_linear = linear; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_LINEAR_TT; if (state->target_linear != state->linear) { light_lightness_linear_tt_values(state); @@ -1960,6 +1930,7 @@ static void light_ctl_set_unack(struct bt_mesh_model *model, state->target_delta_uv = delta_uv; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_CTL_TT; if (state->target_lightness != state->lightness || state->target_temp != state->temp || @@ -2046,6 +2017,7 @@ static void light_ctl_set(struct bt_mesh_model *model, state->target_delta_uv = delta_uv; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_CTL_TT; if (state->target_lightness != state->lightness || state->target_temp != state->temp || @@ -2446,6 +2418,7 @@ static void light_ctl_temp_set_unack(struct bt_mesh_model *model, state->target_delta_uv = delta_uv; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_CTL_TEMP_TT; if (state->target_temp != state->temp || state->target_delta_uv != state->delta_uv) { @@ -2528,6 +2501,7 @@ static void light_ctl_temp_set(struct bt_mesh_model *model, state->target_delta_uv = delta_uv; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_CTL_TEMP_TT; if (state->target_temp != state->temp || state->target_delta_uv != state->delta_uv) { diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c index bd280f67dbf89c..d7500bc4e466ba 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c @@ -13,7 +13,7 @@ #include "state_binding.h" #include "transition.h" -u8_t transition_type, default_tt; +u8_t default_tt; u32_t *ptr_counter; struct k_timer *ptr_timer = &dummy_timer; @@ -130,6 +130,23 @@ void level_tt_values(struct generic_level_state *state) state->transition->counter); } +void level_move_tt_values(struct generic_level_state *state) +{ + if (state == &gen_level_srv_root_user_data) { + calculate_lightness_target_values(LEVEL); + } else if (state == &gen_level_srv_s0_user_data) { + calculate_temp_target_values(LEVEL_TEMP); + } + + if (!tt_values_calculator(state->transition)) { + return; + } + + state->transition->quo_tt = state->transition->total_duration; + + state->tt_delta = state->last_delta; +} + void light_lightness_actual_tt_values(struct light_lightness_state *state) { calculate_lightness_target_values(ACTUAL); @@ -249,12 +266,35 @@ static void onoff_work_handler(struct k_work *work) } } +static void level_move_lightness_work_handler(void) +{ + s32_t level; + struct generic_level_state *state = &gen_level_srv_root_user_data; + + level = state->level + state->tt_delta; + if (level <= INT16_MIN || level >= INT16_MAX) { + state->transition->counter = 0U; + k_timer_stop(ptr_timer); + + if (level > 0) { + level = INT16_MAX; + } else if (level < 0) { + level = INT16_MIN; + } + } + + state->level = level; + + state_binding(LEVEL, IGNORE_TEMP); + update_light_state(); +} + static void level_lightness_work_handler(struct k_work *work) { u8_t level; struct generic_level_state *state = &gen_level_srv_root_user_data; - switch (transition_type) { + switch (state->transition->type) { case LEVEL_TT: level = LEVEL; break; @@ -262,8 +302,13 @@ static void level_lightness_work_handler(struct k_work *work) level = DELTA_LEVEL; break; case LEVEL_TT_MOVE: - level = LEVEL; - break; + if (state->transition->just_started) { + state->transition->just_started = false; + return; + } + + level_move_lightness_work_handler(); + return; default: return; } @@ -302,17 +347,46 @@ static void level_lightness_work_handler(struct k_work *work) } } +static void level_move_temp_work_handler(void) +{ + s32_t level; + struct generic_level_state *state = &gen_level_srv_s0_user_data; + + level = state->level + state->tt_delta; + if (level <= INT16_MIN || level >= INT16_MAX) { + state->transition->counter = 0U; + k_timer_stop(ptr_timer); + + if (level > 0) { + level = INT16_MAX; + } else if (level < 0) { + level = INT16_MIN; + } + } + + state->level = level; + + state_binding(IGNORE, LEVEL_TEMP); + update_light_state(); +} + static void level_temp_work_handler(struct k_work *work) { struct generic_level_state *state = &gen_level_srv_s0_user_data; - switch (transition_type) { + switch (state->transition->type) { case LEVEL_TEMP_TT: break; case LEVEL_TEMP_TT_DELTA: break; case LEVEL_TEMP_TT_MOVE: - break; + if (state->transition->just_started) { + state->transition->just_started = false; + return; + } + + level_move_temp_work_handler(); + return; default: return; } diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.h b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.h index a815d9fa7ebfa3..73e4dc4988d1ad 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.h +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.h @@ -12,17 +12,24 @@ #define DEVICE_SPECIFIC_RESOLUTION 10 enum level_transition_types { + UNKNOWN_TT, + ONOFF_TT, LEVEL_TT, LEVEL_TT_DELTA, LEVEL_TT_MOVE, + LIGHT_ACTUAL_TT, + LIGHT_LINEAR_TT, + LIGHT_CTL_TT, LEVEL_TEMP_TT, LEVEL_TEMP_TT_DELTA, LEVEL_TEMP_TT_MOVE, + LIGHT_CTL_TEMP_TT, }; struct transition { bool just_started; + u8_t type; u8_t tt; u8_t rt; u8_t delay; @@ -34,7 +41,7 @@ struct transition { struct k_timer timer; }; -extern u8_t transition_type, default_tt; +extern u8_t default_tt; extern u32_t *ptr_counter; extern struct k_timer *ptr_timer; @@ -47,6 +54,7 @@ void calculate_rt(struct transition *transition); void onoff_tt_values(struct generic_onoff_state *state); void level_tt_values(struct generic_level_state *state); +void level_move_tt_values(struct generic_level_state *state); void light_lightness_actual_tt_values(struct light_lightness_state *state); void light_lightness_linear_tt_values(struct light_lightness_state *state); void light_ctl_tt_values(struct light_ctl_state *state);