samples: mesh: nrf52: revised status resp. behaviour & TT calculation
With this it is possible to get proper target value & remaining time in status response from Servers when transition in progress. If transition is not in progress then those things would not get integrate into status response. This is as per Bluetooth Mesh Model specification. It is inspired concept from Bluetooth Mesh Developer study Guide. Also updated Transition Time (TT) related parameter calculation. Signed-off-by: Vikrant More <vikrant8051@gmail.com>
This commit is contained in:
parent
6858cb417d
commit
864ebaaba6
5 changed files with 622 additions and 304 deletions
|
@ -105,13 +105,12 @@ static void gen_onoff_get(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS);
|
||||
net_buf_simple_add_u8(msg, state->onoff);
|
||||
|
||||
if (state->is_optional_para_available) {
|
||||
if (state->tt_counter) {
|
||||
onoff_calculate_rt(state);
|
||||
net_buf_simple_add_u8(msg, state->target_onoff);
|
||||
net_buf_simple_add_u8(msg, state->tt);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x00;
|
||||
|
||||
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
|
||||
printk("Unable to send GEN_ONOFF_SRV Status response\n");
|
||||
}
|
||||
|
@ -136,16 +135,13 @@ static bool gen_onoff_setunack(struct bt_mesh_model *model,
|
|||
now = k_uptime_get();
|
||||
if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
|
||||
(now - state->last_msg_timestamp <= K_SECONDS(6))) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x01;
|
||||
|
||||
switch (buf->len) {
|
||||
case 0x00: /* No optional fields are available */
|
||||
state->tt = default_tt;
|
||||
state->delay = 0;
|
||||
state->is_optional_para_available = 0x00;
|
||||
break;
|
||||
case 0x02: /* Optional fields are available */
|
||||
state->tt = net_buf_simple_pull_u8(buf);
|
||||
|
@ -155,6 +151,7 @@ static bool gen_onoff_setunack(struct bt_mesh_model *model,
|
|||
return false;
|
||||
}
|
||||
|
||||
*ptr_tt_counter = 0;
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
|
||||
state->last_tid = tid;
|
||||
|
@ -162,10 +159,16 @@ static bool gen_onoff_setunack(struct bt_mesh_model *model,
|
|||
state->last_msg_timestamp = now;
|
||||
state->target_onoff = onoff;
|
||||
|
||||
onoff_tt_values(state);
|
||||
state->tt_counter = 0;
|
||||
if (state->target_onoff != state->onoff) {
|
||||
onoff_tt_values(state);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* For Instantaneous Transition */
|
||||
if (state->tt_counter == 0) {
|
||||
state->onoff = onoff;
|
||||
state->onoff = state->target_onoff;
|
||||
}
|
||||
|
||||
if (bt_mesh_model_elem(model)->addr == elements[0].addr) {
|
||||
|
@ -182,6 +185,12 @@ static bool gen_onoff_setunack(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS);
|
||||
net_buf_simple_add_u8(msg, state->onoff);
|
||||
|
||||
if (state->tt_counter) {
|
||||
onoff_calculate_rt(state);
|
||||
net_buf_simple_add_u8(msg, state->target_onoff);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
err = bt_mesh_model_publish(model);
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish err %d\n", err);
|
||||
|
@ -232,30 +241,33 @@ static void gen_level_get(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
|
||||
net_buf_simple_add_le16(msg, state->level);
|
||||
|
||||
if (state->is_optional_para_available == 0x01) {
|
||||
net_buf_simple_add_le16(msg, state->target_level);
|
||||
net_buf_simple_add_u8(msg, state->tt);
|
||||
} else if (state->is_optional_para_available == 0x02) {
|
||||
if (state->tt_counter) {
|
||||
if (enable_transition == LEVEL_TT_MOVE ||
|
||||
enable_transition == LEVEL_TEMP_TT_MOVE) {
|
||||
|
||||
if (state->last_delta < 0) {
|
||||
net_buf_simple_add_le16(msg, INT16_MIN);
|
||||
} else if (state->last_delta > 0) {
|
||||
net_buf_simple_add_le16(msg, INT16_MAX);
|
||||
if (state->last_delta < 0) {
|
||||
net_buf_simple_add_le16(msg, INT16_MIN);
|
||||
} else if (state->last_delta > 0) {
|
||||
net_buf_simple_add_le16(msg, INT16_MAX);
|
||||
}
|
||||
|
||||
/* This is as per PTS requirement */
|
||||
net_buf_simple_add_u8(msg, 0x3F);
|
||||
} else {
|
||||
level_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_level);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
net_buf_simple_add_u8(msg, state->tt);
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x00;
|
||||
|
||||
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
|
||||
printk("Unable to send GEN_LEVEL_SRV Status response\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_level_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
static bool gen_level_setunack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
u8_t tid;
|
||||
s16_t level;
|
||||
|
@ -269,25 +281,23 @@ static void gen_level_set_unack(struct bt_mesh_model *model,
|
|||
now = k_uptime_get();
|
||||
if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
|
||||
(now - state->last_msg_timestamp <= K_SECONDS(6))) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x01;
|
||||
|
||||
switch (buf->len) {
|
||||
case 0x00: /* No optional fields are available */
|
||||
state->tt = default_tt;
|
||||
state->delay = 0;
|
||||
state->is_optional_para_available = 0x00;
|
||||
break;
|
||||
case 0x02: /* Optional fields are available */
|
||||
state->tt = net_buf_simple_pull_u8(buf);
|
||||
state->delay = net_buf_simple_pull_u8(buf);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
*ptr_tt_counter = 0;
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
|
||||
state->last_tid = tid;
|
||||
|
@ -295,10 +305,16 @@ static void gen_level_set_unack(struct bt_mesh_model *model,
|
|||
state->last_msg_timestamp = now;
|
||||
state->target_level = level;
|
||||
|
||||
level_tt_values(state);
|
||||
state->tt_counter = 0;
|
||||
if (state->target_level != state->level) {
|
||||
level_tt_values(state);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* For Instantaneous Transition */
|
||||
if (state->tt_counter == 0) {
|
||||
state->level = level;
|
||||
state->level = state->target_level;
|
||||
}
|
||||
|
||||
if (bt_mesh_model_elem(model)->addr == elements[0].addr) {
|
||||
|
@ -317,24 +333,40 @@ static void gen_level_set_unack(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
|
||||
net_buf_simple_add_le16(msg, state->level);
|
||||
|
||||
if (state->tt_counter) {
|
||||
level_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_level);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
err = bt_mesh_model_publish(model);
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish err %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gen_level_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
gen_level_setunack(model, ctx, buf);
|
||||
}
|
||||
|
||||
static void gen_level_set(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
gen_level_set_unack(model, ctx, buf);
|
||||
gen_level_get(model, ctx, buf);
|
||||
if (gen_level_setunack(model, ctx, buf) == true) {
|
||||
gen_level_get(model, ctx, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_delta_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
static bool gen_delta_setunack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
u8_t tid;
|
||||
s32_t tmp32, delta;
|
||||
|
@ -350,11 +382,11 @@ static void gen_delta_set_unack(struct bt_mesh_model *model,
|
|||
|
||||
if (now - state->last_msg_timestamp <= K_SECONDS(6)) {
|
||||
if (state->last_delta == delta) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
tmp32 = state->last_level + delta;
|
||||
} else {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -362,22 +394,20 @@ static void gen_delta_set_unack(struct bt_mesh_model *model,
|
|||
tmp32 = state->level + delta;
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x01;
|
||||
|
||||
switch (buf->len) {
|
||||
case 0x00: /* No optional fields are available */
|
||||
state->tt = default_tt;
|
||||
state->delay = 0;
|
||||
state->is_optional_para_available = 0x00;
|
||||
break;
|
||||
case 0x02: /* Optional fields are available */
|
||||
state->tt = net_buf_simple_pull_u8(buf);
|
||||
state->delay = net_buf_simple_pull_u8(buf);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
*ptr_tt_counter = 0;
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
|
||||
state->last_delta = delta;
|
||||
|
@ -393,10 +423,16 @@ static void gen_delta_set_unack(struct bt_mesh_model *model,
|
|||
|
||||
state->target_level = tmp32;
|
||||
|
||||
delta_level_tt_values(state);
|
||||
state->tt_counter = 0;
|
||||
if (state->target_level != state->level) {
|
||||
level_tt_values(state);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (state->tt_counter_delta == 0) {
|
||||
state->level = tmp32;
|
||||
/* For Instantaneous Transition */
|
||||
if (state->tt_counter == 0) {
|
||||
state->level = state->target_level;
|
||||
}
|
||||
|
||||
if (bt_mesh_model_elem(model)->addr == elements[0].addr) {
|
||||
|
@ -415,24 +451,40 @@ static void gen_delta_set_unack(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
|
||||
net_buf_simple_add_le16(msg, state->level);
|
||||
|
||||
if (state->tt_counter) {
|
||||
level_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_level);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
err = bt_mesh_model_publish(model);
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish err %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gen_delta_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
gen_delta_setunack(model, ctx, buf);
|
||||
}
|
||||
|
||||
static void gen_delta_set(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
gen_delta_set_unack(model, ctx, buf);
|
||||
gen_level_get(model, ctx, buf);
|
||||
if (gen_delta_setunack(model, ctx, buf) == true) {
|
||||
gen_level_get(model, ctx, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_move_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
static bool gen_move_setunack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
u8_t tid;
|
||||
s16_t delta;
|
||||
|
@ -447,25 +499,23 @@ static void gen_move_set_unack(struct bt_mesh_model *model,
|
|||
now = k_uptime_get();
|
||||
if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
|
||||
(now - state->last_msg_timestamp <= K_SECONDS(6))) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x02;
|
||||
|
||||
switch (buf->len) {
|
||||
case 0x00: /* No optional fields are available */
|
||||
state->tt = default_tt;
|
||||
state->delay = 0;
|
||||
state->is_optional_para_available = 0x00;
|
||||
break;
|
||||
case 0x02: /* Optional fields are available */
|
||||
state->tt = net_buf_simple_pull_u8(buf);
|
||||
state->delay = net_buf_simple_pull_u8(buf);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
*ptr_tt_counter = 0;
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
|
||||
state->last_delta = delta;
|
||||
|
@ -482,7 +532,15 @@ static void gen_move_set_unack(struct bt_mesh_model *model,
|
|||
|
||||
state->target_level = tmp32;
|
||||
|
||||
move_level_tt_values(state);
|
||||
state->tt_counter = 0;
|
||||
if (state->target_level != state->level) {
|
||||
level_tt_values(state);
|
||||
}
|
||||
|
||||
/* For Instantaneous Transition */
|
||||
if (state->tt_counter == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bt_mesh_model_elem(model)->addr == elements[0].addr) {
|
||||
/* Root element */
|
||||
|
@ -508,19 +566,41 @@ static void gen_move_set_unack(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
|
||||
net_buf_simple_add_le16(msg, state->level);
|
||||
|
||||
if (state->tt_counter) {
|
||||
|
||||
if (state->last_delta < 0) {
|
||||
net_buf_simple_add_le16(msg, INT16_MIN);
|
||||
} else if (state->last_delta > 0) {
|
||||
net_buf_simple_add_le16(msg, INT16_MAX);
|
||||
}
|
||||
|
||||
/* This is as per PTS requirement */
|
||||
net_buf_simple_add_u8(msg, 0x3F);
|
||||
}
|
||||
|
||||
err = bt_mesh_model_publish(model);
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish err %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gen_move_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
gen_move_setunack(model, ctx, buf);
|
||||
}
|
||||
|
||||
static void gen_move_set(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
gen_move_set_unack(model, ctx, buf);
|
||||
gen_level_get(model, ctx, buf);
|
||||
if (gen_move_setunack(model, ctx, buf) == true) {
|
||||
gen_level_get(model, ctx, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Generic Level Client message handlers */
|
||||
|
@ -772,21 +852,20 @@ static void light_lightness_get(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x4E));
|
||||
net_buf_simple_add_le16(msg, state->actual);
|
||||
|
||||
if (state->is_optional_para_available) {
|
||||
if (state->tt_counter_actual) {
|
||||
light_lightness_actual_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_actual);
|
||||
net_buf_simple_add_u8(msg, state->tt);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x00;
|
||||
|
||||
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
|
||||
printk("Unable to send LightLightnessAct Status response\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void light_lightness_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
static bool light_lightness_setunack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
u8_t tid;
|
||||
u16_t actual;
|
||||
|
@ -800,25 +879,23 @@ static void light_lightness_set_unack(struct bt_mesh_model *model,
|
|||
now = k_uptime_get();
|
||||
if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
|
||||
(now - state->last_msg_timestamp <= K_SECONDS(6))) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x01;
|
||||
|
||||
switch (buf->len) {
|
||||
case 0x00: /* No optional fields are available */
|
||||
state->tt = default_tt;
|
||||
state->delay = 0;
|
||||
state->is_optional_para_available = 0x00;
|
||||
break;
|
||||
case 0x02: /* Optional fields are available */
|
||||
state->tt = net_buf_simple_pull_u8(buf);
|
||||
state->delay = net_buf_simple_pull_u8(buf);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
*ptr_tt_counter = 0;
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
|
||||
state->last_tid = tid;
|
||||
|
@ -833,10 +910,16 @@ static void light_lightness_set_unack(struct bt_mesh_model *model,
|
|||
|
||||
state->target_actual = actual;
|
||||
|
||||
light_lightnes_actual_tt_values(state);
|
||||
state->tt_counter_actual = 0;
|
||||
if (state->target_actual != state->actual) {
|
||||
light_lightnes_actual_tt_values(state);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* For Instantaneous Transition */
|
||||
if (state->tt_counter_actual == 0) {
|
||||
state->actual = actual;
|
||||
state->actual = state->target_actual;
|
||||
}
|
||||
|
||||
light_lightness_actual_handler(state);
|
||||
|
@ -847,19 +930,35 @@ static void light_lightness_set_unack(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x4E));
|
||||
net_buf_simple_add_le16(msg, state->actual);
|
||||
|
||||
if (state->tt_counter_actual) {
|
||||
light_lightness_actual_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_actual);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
err = bt_mesh_model_publish(model);
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish err %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void light_lightness_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
light_lightness_setunack(model, ctx, buf);
|
||||
}
|
||||
|
||||
static void light_lightness_set(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
light_lightness_set_unack(model, ctx, buf);
|
||||
light_lightness_get(model, ctx, buf);
|
||||
if (light_lightness_setunack(model, ctx, buf) == true) {
|
||||
light_lightness_get(model, ctx, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void light_lightness_linear_get(struct bt_mesh_model *model,
|
||||
|
@ -872,21 +971,20 @@ static void light_lightness_linear_get(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x52));
|
||||
net_buf_simple_add_le16(msg, state->linear);
|
||||
|
||||
if (state->is_optional_para_available) {
|
||||
if (state->tt_counter_linear) {
|
||||
light_lightness_linear_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_linear);
|
||||
net_buf_simple_add_u8(msg, state->tt);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x00;
|
||||
|
||||
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
|
||||
printk("Unable to send LightLightnessLin Status response\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void light_lightness_linear_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
static bool light_lightness_linear_setunack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
u8_t tid;
|
||||
u16_t linear;
|
||||
|
@ -900,25 +998,23 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model,
|
|||
now = k_uptime_get();
|
||||
if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
|
||||
(now - state->last_msg_timestamp <= K_SECONDS(6))) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x01;
|
||||
|
||||
switch (buf->len) {
|
||||
case 0x00: /* No optional fields are available */
|
||||
state->tt = default_tt;
|
||||
state->delay = 0;
|
||||
state->is_optional_para_available = 0x00;
|
||||
break;
|
||||
case 0x02: /* Optional fields are available */
|
||||
state->tt = net_buf_simple_pull_u8(buf);
|
||||
state->delay = net_buf_simple_pull_u8(buf);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
*ptr_tt_counter = 0;
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
|
||||
state->last_tid = tid;
|
||||
|
@ -926,10 +1022,16 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model,
|
|||
state->last_msg_timestamp = now;
|
||||
state->target_linear = linear;
|
||||
|
||||
light_lightnes_linear_tt_values(state);
|
||||
state->tt_counter_linear = 0;
|
||||
if (state->target_linear != state->linear) {
|
||||
light_lightnes_linear_tt_values(state);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* For Instantaneous Transition */
|
||||
if (state->tt_counter_linear == 0) {
|
||||
state->linear = linear;
|
||||
state->linear = state->target_linear;
|
||||
}
|
||||
|
||||
light_lightness_linear_handler(state);
|
||||
|
@ -940,19 +1042,35 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model,
|
|||
bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x52));
|
||||
net_buf_simple_add_le16(msg, state->linear);
|
||||
|
||||
if (state->tt_counter_linear) {
|
||||
light_lightness_linear_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_linear);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
err = bt_mesh_model_publish(model);
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish err %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void light_lightness_linear_set_unack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
light_lightness_linear_setunack(model, ctx, buf);
|
||||
}
|
||||
|
||||
static void light_lightness_linear_set(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
light_lightness_linear_set_unack(model, ctx, buf);
|
||||
light_lightness_linear_get(model, ctx, buf);
|
||||
if (light_lightness_linear_setunack(model, ctx, buf) == true) {
|
||||
light_lightness_linear_get(model, ctx, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void light_lightness_last_get(struct bt_mesh_model *model,
|
||||
|
@ -1173,14 +1291,13 @@ static void light_ctl_get(struct bt_mesh_model *model,
|
|||
net_buf_simple_add_le16(msg, state->lightness);
|
||||
net_buf_simple_add_le16(msg, state->temp);
|
||||
|
||||
if (state->is_optional_para_available) {
|
||||
if (state->tt_counter) {
|
||||
light_ctl_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_lightness);
|
||||
net_buf_simple_add_le16(msg, state->target_temp);
|
||||
net_buf_simple_add_u8(msg, state->tt);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x00;
|
||||
|
||||
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
|
||||
printk("Unable to send LightCTL Status response\n");
|
||||
}
|
||||
|
@ -1209,16 +1326,13 @@ static bool light_ctl_setunack(struct bt_mesh_model *model,
|
|||
now = k_uptime_get();
|
||||
if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
|
||||
(now - state->last_msg_timestamp <= K_SECONDS(6))) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x01;
|
||||
|
||||
switch (buf->len) {
|
||||
case 0x00: /* No optional fields are available */
|
||||
state->tt = default_tt;
|
||||
state->delay = 0;
|
||||
state->is_optional_para_available = 0x00;
|
||||
break;
|
||||
case 0x02: /* Optional fields are available */
|
||||
state->tt = net_buf_simple_pull_u8(buf);
|
||||
|
@ -1228,6 +1342,7 @@ static bool light_ctl_setunack(struct bt_mesh_model *model,
|
|||
return false;
|
||||
}
|
||||
|
||||
*ptr_tt_counter = 0;
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
|
||||
state->last_tid = tid;
|
||||
|
@ -1244,12 +1359,20 @@ static bool light_ctl_setunack(struct bt_mesh_model *model,
|
|||
state->target_temp = temp;
|
||||
state->target_delta_uv = delta_uv;
|
||||
|
||||
light_ctl_tt_values(state);
|
||||
state->tt_counter = 0;
|
||||
if (state->target_lightness != state->lightness ||
|
||||
state->target_temp != state->temp ||
|
||||
state->target_delta_uv != state->delta_uv) {
|
||||
light_ctl_tt_values(state);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* For Instantaneous Transition */
|
||||
if (state->tt_counter == 0) {
|
||||
state->lightness = lightness;
|
||||
state->temp = temp;
|
||||
state->delta_uv = delta_uv;
|
||||
state->lightness = state->target_lightness;
|
||||
state->temp = state->target_temp;
|
||||
state->delta_uv = state->target_delta_uv;
|
||||
}
|
||||
|
||||
light_ctl_handler(state);
|
||||
|
@ -1265,6 +1388,13 @@ static bool light_ctl_setunack(struct bt_mesh_model *model,
|
|||
net_buf_simple_add_le16(msg, state->lightness);
|
||||
net_buf_simple_add_le16(msg, state->temp);
|
||||
|
||||
if (state->tt_counter) {
|
||||
light_ctl_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_lightness);
|
||||
net_buf_simple_add_le16(msg, state->target_temp);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
err = bt_mesh_model_publish(model);
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish err %d\n", err);
|
||||
|
@ -1531,14 +1661,13 @@ static void light_ctl_temp_get(struct bt_mesh_model *model,
|
|||
net_buf_simple_add_le16(msg, state->temp);
|
||||
net_buf_simple_add_le16(msg, state->delta_uv);
|
||||
|
||||
if (state->is_optional_para_available) {
|
||||
if (state->tt_counter_temp) {
|
||||
light_ctl_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_temp);
|
||||
net_buf_simple_add_le16(msg, state->target_delta_uv);
|
||||
net_buf_simple_add_u8(msg, state->tt);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x00;
|
||||
|
||||
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
|
||||
printk("Unable to send LightCTL Temp. Status response\n");
|
||||
}
|
||||
|
@ -1567,16 +1696,13 @@ static bool light_ctl_temp_setunack(struct bt_mesh_model *model,
|
|||
now = k_uptime_get();
|
||||
if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
|
||||
(now - state->last_msg_timestamp <= K_SECONDS(6))) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
state->is_optional_para_available = 0x01;
|
||||
|
||||
switch (buf->len) {
|
||||
case 0x00: /* No optional fields are available */
|
||||
state->tt = default_tt;
|
||||
state->delay = 0;
|
||||
state->is_optional_para_available = 0x00;
|
||||
break;
|
||||
case 0x02: /* Optional fields are available */
|
||||
state->tt = net_buf_simple_pull_u8(buf);
|
||||
|
@ -1586,6 +1712,7 @@ static bool light_ctl_temp_setunack(struct bt_mesh_model *model,
|
|||
return false;
|
||||
}
|
||||
|
||||
*ptr_tt_counter = 0;
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
|
||||
state->last_tid = tid;
|
||||
|
@ -1601,11 +1728,18 @@ static bool light_ctl_temp_setunack(struct bt_mesh_model *model,
|
|||
state->target_temp = temp;
|
||||
state->target_delta_uv = delta_uv;
|
||||
|
||||
light_ctl_temp_tt_values(state);
|
||||
state->tt_counter_temp = 0;
|
||||
if (state->target_temp != state->temp ||
|
||||
state->target_delta_uv != state->delta_uv) {
|
||||
light_ctl_temp_tt_values(state);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* For Instantaneous Transition */
|
||||
if (state->tt_counter_temp == 0) {
|
||||
state->temp = temp;
|
||||
state->delta_uv = delta_uv;
|
||||
state->temp = state->target_temp;
|
||||
state->delta_uv = state->target_delta_uv;
|
||||
}
|
||||
|
||||
light_ctl_temp_handler(state);
|
||||
|
@ -1617,6 +1751,13 @@ static bool light_ctl_temp_setunack(struct bt_mesh_model *model,
|
|||
net_buf_simple_add_le16(msg, state->temp);
|
||||
net_buf_simple_add_le16(msg, state->delta_uv);
|
||||
|
||||
if (state->tt_counter_temp) {
|
||||
light_ctl_calculate_rt(state);
|
||||
net_buf_simple_add_le16(msg, state->target_temp);
|
||||
net_buf_simple_add_le16(msg, state->target_delta_uv);
|
||||
net_buf_simple_add_u8(msg, state->rt);
|
||||
}
|
||||
|
||||
err = bt_mesh_model_publish(model);
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish err %d\n", err);
|
||||
|
@ -1884,3 +2025,4 @@ const struct bt_mesh_comp comp = {
|
|||
.elem = elements,
|
||||
.elem_count = ARRAY_SIZE(elements),
|
||||
};
|
||||
|
||||
|
|
|
@ -53,11 +53,14 @@ struct generic_onoff_state {
|
|||
s64_t last_msg_timestamp;
|
||||
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t rt;
|
||||
u32_t quo_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
bool is_new_transition_start;
|
||||
u32_t total_transition_duration;
|
||||
s64_t transition_start_timestamp;
|
||||
};
|
||||
|
||||
struct generic_level_state {
|
||||
|
@ -73,13 +76,14 @@ struct generic_level_state {
|
|||
|
||||
s32_t tt_delta;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t rt;
|
||||
u32_t quo_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
u32_t tt_counter_delta;
|
||||
u32_t tt_counter_move;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
bool is_new_transition_start;
|
||||
u32_t total_transition_duration;
|
||||
s64_t transition_start_timestamp;
|
||||
};
|
||||
|
||||
struct generic_onpowerup_state {
|
||||
|
@ -121,12 +125,15 @@ struct light_lightness_state {
|
|||
s32_t tt_delta_actual;
|
||||
s32_t tt_delta_linear;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t rt;
|
||||
u32_t quo_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter_actual;
|
||||
u32_t tt_counter_linear;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
bool is_new_transition_start;
|
||||
u32_t total_transition_duration;
|
||||
s64_t transition_start_timestamp;
|
||||
};
|
||||
|
||||
struct light_ctl_state {
|
||||
|
@ -157,12 +164,15 @@ struct light_ctl_state {
|
|||
s32_t tt_temp_delta;
|
||||
s32_t tt_duv_delta;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t rt;
|
||||
u32_t quo_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
u32_t tt_counter_temp;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
bool is_new_transition_start;
|
||||
u32_t total_transition_duration;
|
||||
s64_t transition_start_timestamp;
|
||||
};
|
||||
|
||||
extern struct generic_onoff_state gen_onoff_srv_root_user_data;
|
||||
|
|
|
@ -106,6 +106,10 @@ void publish(struct k_work *work)
|
|||
net_buf_simple_add_le16(root_models[5].pub->msg, LEVEL_S25);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[5]);
|
||||
#elif defined(ONOFF_GET)
|
||||
bt_mesh_model_msg_init(root_models[3].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_ONOFF_GET);
|
||||
err = bt_mesh_model_publish(&root_models[3]);
|
||||
#elif defined(GENERIC_DELTA_LEVEL)
|
||||
bt_mesh_model_msg_init(root_models[5].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_DELTA_SET_UNACK);
|
||||
|
@ -237,3 +241,4 @@ void publish(struct k_work *work)
|
|||
printk("bt_mesh_model_publish: err: %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,142 @@
|
|||
#include "state_binding.h"
|
||||
#include "transition.h"
|
||||
|
||||
u8_t enable_transition;
|
||||
u8_t default_tt;
|
||||
u8_t enable_transition, default_tt;
|
||||
u32_t *ptr_tt_counter;
|
||||
|
||||
static u32_t tt_counter_calculator(u8_t *tt, u32_t *cal_tt)
|
||||
/* Functions to calculate Remaining Time (Start) */
|
||||
u8_t calculate_rt(s32_t duration_remainder)
|
||||
{
|
||||
u8_t steps, resolution;
|
||||
|
||||
if (duration_remainder > 620000) {
|
||||
/* > 620 seconds -> resolution = 0b11 [10 minutes] */
|
||||
resolution = 0x03;
|
||||
steps = duration_remainder / 600000;
|
||||
} else if (duration_remainder > 62000) {
|
||||
/* > 62 seconds -> resolution = 0b10 [10 seconds] */
|
||||
resolution = 0x02;
|
||||
steps = duration_remainder / 10000;
|
||||
} else if (duration_remainder > 6200) {
|
||||
/* > 6.2 seconds -> resolution = 0b01 [1 seconds] */
|
||||
resolution = 0x01;
|
||||
steps = duration_remainder / 1000;
|
||||
} else if (duration_remainder > 0) {
|
||||
/* <= 6.2 seconds -> resolution = 0b00 [100 ms] */
|
||||
resolution = 0x00;
|
||||
steps = duration_remainder / 100;
|
||||
} else {
|
||||
resolution = 0x00;
|
||||
steps = 0x00;
|
||||
}
|
||||
|
||||
return ((resolution << 6) | steps);
|
||||
}
|
||||
|
||||
void onoff_calculate_rt(struct generic_onoff_state *state)
|
||||
{
|
||||
s32_t duration_remainder;
|
||||
s64_t now;
|
||||
|
||||
if (state->is_new_transition_start) {
|
||||
state->rt = state->tt;
|
||||
} else {
|
||||
now = k_uptime_get();
|
||||
duration_remainder =
|
||||
state->total_transition_duration -
|
||||
(now - state->transition_start_timestamp);
|
||||
|
||||
state->rt = calculate_rt(duration_remainder);
|
||||
}
|
||||
}
|
||||
|
||||
void level_calculate_rt(struct generic_level_state *state)
|
||||
{
|
||||
s32_t duration_remainder;
|
||||
s64_t now;
|
||||
|
||||
if (state->is_new_transition_start) {
|
||||
state->rt = state->tt;
|
||||
} else {
|
||||
now = k_uptime_get();
|
||||
duration_remainder =
|
||||
state->total_transition_duration -
|
||||
(now - state->transition_start_timestamp);
|
||||
|
||||
state->rt = calculate_rt(duration_remainder);
|
||||
}
|
||||
}
|
||||
|
||||
void light_lightness_actual_calculate_rt(struct light_lightness_state *state)
|
||||
{
|
||||
s32_t duration_remainder;
|
||||
s64_t now;
|
||||
|
||||
if (state->is_new_transition_start) {
|
||||
state->rt = state->tt;
|
||||
} else {
|
||||
now = k_uptime_get();
|
||||
duration_remainder =
|
||||
state->total_transition_duration -
|
||||
(now - state->transition_start_timestamp);
|
||||
|
||||
state->rt = calculate_rt(duration_remainder);
|
||||
}
|
||||
}
|
||||
|
||||
void light_lightness_linear_calculate_rt(struct light_lightness_state *state)
|
||||
{
|
||||
s32_t duration_remainder;
|
||||
s64_t now;
|
||||
|
||||
if (state->is_new_transition_start) {
|
||||
state->rt = state->tt;
|
||||
} else {
|
||||
now = k_uptime_get();
|
||||
duration_remainder =
|
||||
state->total_transition_duration -
|
||||
(now - state->transition_start_timestamp);
|
||||
|
||||
state->rt = calculate_rt(duration_remainder);
|
||||
}
|
||||
}
|
||||
|
||||
void light_ctl_calculate_rt(struct light_ctl_state *state)
|
||||
{
|
||||
s32_t duration_remainder;
|
||||
s64_t now;
|
||||
|
||||
if (state->is_new_transition_start) {
|
||||
state->rt = state->tt;
|
||||
} else {
|
||||
now = k_uptime_get();
|
||||
duration_remainder =
|
||||
state->total_transition_duration -
|
||||
(now - state->transition_start_timestamp);
|
||||
|
||||
state->rt = calculate_rt(duration_remainder);
|
||||
}
|
||||
}
|
||||
|
||||
void light_ctl_temp_calculate_rt(struct light_ctl_state *state)
|
||||
{
|
||||
s32_t duration_remainder;
|
||||
s64_t now;
|
||||
|
||||
if (state->is_new_transition_start) {
|
||||
state->rt = state->tt;
|
||||
} else {
|
||||
now = k_uptime_get();
|
||||
duration_remainder =
|
||||
state->total_transition_duration -
|
||||
(now - state->transition_start_timestamp);
|
||||
|
||||
state->rt = calculate_rt(duration_remainder);
|
||||
}
|
||||
}
|
||||
/* Functions to calculate Remaining Time (End) */
|
||||
|
||||
static u32_t tt_values_calculator(u8_t *tt, u32_t *total_transition_duration)
|
||||
{
|
||||
u8_t steps_multiplier, resolution;
|
||||
u32_t tt_counter;
|
||||
|
@ -27,93 +159,77 @@ static u32_t tt_counter_calculator(u8_t *tt, u32_t *cal_tt)
|
|||
|
||||
switch (resolution) {
|
||||
case 0: /* 100ms */
|
||||
*cal_tt = steps_multiplier * 100;
|
||||
*total_transition_duration = steps_multiplier * 100;
|
||||
break;
|
||||
case 1: /* 1 second */
|
||||
*cal_tt = steps_multiplier * 1000;
|
||||
*total_transition_duration = steps_multiplier * 1000;
|
||||
break;
|
||||
case 2: /* 10 seconds */
|
||||
*cal_tt = steps_multiplier * 10000;
|
||||
*total_transition_duration = steps_multiplier * 10000;
|
||||
break;
|
||||
case 3: /* 10 minutes */
|
||||
*cal_tt = steps_multiplier * 600000;
|
||||
*total_transition_duration = steps_multiplier * 600000;
|
||||
break;
|
||||
}
|
||||
|
||||
tt_counter = ((float) *cal_tt / 100);
|
||||
tt_counter = ((float) *total_transition_duration / 100);
|
||||
|
||||
if (tt_counter > DEVICE_SPECIFIC_RESOLUTION) {
|
||||
tt_counter = DEVICE_SPECIFIC_RESOLUTION;
|
||||
}
|
||||
|
||||
if (tt_counter != 0) {
|
||||
*cal_tt = *cal_tt / tt_counter;
|
||||
}
|
||||
|
||||
return tt_counter;
|
||||
}
|
||||
|
||||
void onoff_tt_values(struct generic_onoff_state *state)
|
||||
{
|
||||
state->tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
state->tt_counter =
|
||||
tt_values_calculator(&state->tt,
|
||||
&state->total_transition_duration);
|
||||
ptr_tt_counter = &state->tt_counter;
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state->quo_tt = 0;
|
||||
} else {
|
||||
state->quo_tt = state->total_transition_duration /
|
||||
state->tt_counter;
|
||||
}
|
||||
}
|
||||
|
||||
void level_tt_values(struct generic_level_state *state)
|
||||
{
|
||||
u32_t tt_counter;
|
||||
|
||||
tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
tt_counter = tt_values_calculator(&state->tt,
|
||||
&state->total_transition_duration);
|
||||
state->tt_counter = tt_counter;
|
||||
ptr_tt_counter = &state->tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
state->quo_tt = 0;
|
||||
tt_counter = 1;
|
||||
} else {
|
||||
state->quo_tt = state->total_transition_duration / tt_counter;
|
||||
}
|
||||
|
||||
state->tt_delta = ((float) (state->level - state->target_level) /
|
||||
tt_counter);
|
||||
}
|
||||
|
||||
void delta_level_tt_values(struct generic_level_state *state)
|
||||
{
|
||||
u32_t tt_counter;
|
||||
|
||||
tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
state->tt_counter_delta = tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
tt_counter = 1;
|
||||
}
|
||||
|
||||
state->tt_delta = ((float) state->last_delta / tt_counter);
|
||||
|
||||
state->tt_delta *= -1;
|
||||
}
|
||||
|
||||
void move_level_tt_values(struct generic_level_state *state)
|
||||
{
|
||||
u32_t tt_counter;
|
||||
|
||||
tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
state->tt_counter_move = tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
tt_counter = 1;
|
||||
}
|
||||
|
||||
state->tt_delta = ((float) state->last_delta / tt_counter);
|
||||
|
||||
state->tt_delta *= -1;
|
||||
}
|
||||
|
||||
void light_lightnes_actual_tt_values(struct light_lightness_state *state)
|
||||
{
|
||||
u32_t tt_counter;
|
||||
|
||||
tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
tt_counter = tt_values_calculator(&state->tt,
|
||||
&state->total_transition_duration);
|
||||
state->tt_counter_actual = tt_counter;
|
||||
ptr_tt_counter = &state->tt_counter_actual;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
state->quo_tt = 0;
|
||||
tt_counter = 1;
|
||||
} else {
|
||||
state->quo_tt = state->total_transition_duration / tt_counter;
|
||||
}
|
||||
|
||||
state->tt_delta_actual =
|
||||
|
@ -125,11 +241,16 @@ void light_lightnes_linear_tt_values(struct light_lightness_state *state)
|
|||
{
|
||||
u32_t tt_counter;
|
||||
|
||||
tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
tt_counter = tt_values_calculator(&state->tt,
|
||||
&state->total_transition_duration);
|
||||
state->tt_counter_linear = tt_counter;
|
||||
ptr_tt_counter = &state->tt_counter_linear;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
state->quo_tt = 0;
|
||||
tt_counter = 1;
|
||||
} else {
|
||||
state->quo_tt = state->total_transition_duration / tt_counter;
|
||||
}
|
||||
|
||||
state->tt_delta_linear =
|
||||
|
@ -141,11 +262,16 @@ void light_ctl_tt_values(struct light_ctl_state *state)
|
|||
{
|
||||
u32_t tt_counter;
|
||||
|
||||
tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
tt_counter = tt_values_calculator(&state->tt,
|
||||
&state->total_transition_duration);
|
||||
state->tt_counter = tt_counter;
|
||||
ptr_tt_counter = &state->tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
state->quo_tt = 0;
|
||||
tt_counter = 1;
|
||||
} else {
|
||||
state->quo_tt = state->total_transition_duration / tt_counter;
|
||||
}
|
||||
|
||||
state->tt_lightness_delta =
|
||||
|
@ -165,11 +291,16 @@ void light_ctl_temp_tt_values(struct light_ctl_state *state)
|
|||
{
|
||||
u32_t tt_counter;
|
||||
|
||||
tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
tt_counter = tt_values_calculator(&state->tt,
|
||||
&state->total_transition_duration);
|
||||
state->tt_counter_temp = tt_counter;
|
||||
ptr_tt_counter = &state->tt_counter_temp;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
state->quo_tt = 0;
|
||||
tt_counter = 1;
|
||||
} else {
|
||||
state->quo_tt = state->total_transition_duration / tt_counter;
|
||||
}
|
||||
|
||||
state->tt_temp_delta = ((float) (state->temp - state->target_temp) /
|
||||
|
@ -190,17 +321,30 @@ static void onoff_work_handler(struct k_work *work)
|
|||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter != 0) {
|
||||
state->tt_counter--;
|
||||
|
||||
if (state->target_onoff == STATE_ON) {
|
||||
state->onoff = STATE_ON;
|
||||
if (state->is_new_transition_start) {
|
||||
state->is_new_transition_start = false;
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state_binding(ONOFF, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
k_timer_stop(&onoff_transition_timer);
|
||||
} else {
|
||||
state->transition_start_timestamp = k_uptime_get();
|
||||
|
||||
if (state->target_onoff == STATE_ON) {
|
||||
state->onoff = STATE_ON;
|
||||
|
||||
state_binding(ONOFF, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter != 0) {
|
||||
state->tt_counter--;
|
||||
}
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
|
@ -215,50 +359,45 @@ static void onoff_work_handler(struct k_work *work)
|
|||
|
||||
static void level_lightness_work_handler(struct k_work *work)
|
||||
{
|
||||
u32_t *tt_counter;
|
||||
struct generic_level_state *state = &gen_level_srv_root_user_data;
|
||||
|
||||
tt_counter = NULL;
|
||||
|
||||
switch (enable_transition) {
|
||||
case LEVEL_TT:
|
||||
tt_counter = &state->tt_counter;
|
||||
break;
|
||||
case LEVEL_TT_DELTA:
|
||||
tt_counter = &state->tt_counter_delta;
|
||||
break;
|
||||
case LEVEL_TT_MOVE:
|
||||
tt_counter = &state->tt_counter_move;
|
||||
break;
|
||||
default:
|
||||
k_timer_stop(&level_lightness_transition_timer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*tt_counter != 0) {
|
||||
s32_t lightness;
|
||||
|
||||
(*tt_counter)--;
|
||||
|
||||
lightness = state->level - state->tt_delta;
|
||||
|
||||
if (lightness > INT16_MAX) {
|
||||
lightness = INT16_MAX;
|
||||
} else if (lightness < INT16_MIN) {
|
||||
lightness = INT16_MIN;
|
||||
}
|
||||
|
||||
if (state->level != lightness) {
|
||||
state->level = lightness;
|
||||
if (state->is_new_transition_start) {
|
||||
state->is_new_transition_start = false;
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state_binding(LEVEL, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
k_timer_stop(&level_lightness_transition_timer);
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
state->transition_start_timestamp = k_uptime_get();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (*tt_counter == 0) {
|
||||
if (state->tt_counter != 0) {
|
||||
state->tt_counter--;
|
||||
|
||||
state->level -= state->tt_delta;
|
||||
|
||||
state_binding(LEVEL, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
}
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state->level = state->target_level;
|
||||
|
||||
state_binding(LEVEL, IGNORE_TEMP);
|
||||
|
@ -270,50 +409,45 @@ static void level_lightness_work_handler(struct k_work *work)
|
|||
|
||||
static void level_temp_work_handler(struct k_work *work)
|
||||
{
|
||||
u32_t *tt_counter;
|
||||
struct generic_level_state *state = &gen_level_srv_s0_user_data;
|
||||
|
||||
tt_counter = NULL;
|
||||
|
||||
switch (enable_transition) {
|
||||
case LEVEL_TT:
|
||||
tt_counter = &state->tt_counter;
|
||||
case LEVEL_TEMP_TT:
|
||||
break;
|
||||
case LEVEL_TT_DELTA:
|
||||
tt_counter = &state->tt_counter_delta;
|
||||
case LEVEL_TEMP_TT_DELTA:
|
||||
break;
|
||||
case LEVEL_TT_MOVE:
|
||||
tt_counter = &state->tt_counter_move;
|
||||
case LEVEL_TEMP_TT_MOVE:
|
||||
break;
|
||||
default:
|
||||
k_timer_stop(&level_temp_transition_timer);
|
||||
k_timer_stop(&level_lightness_transition_timer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*tt_counter != 0) {
|
||||
s32_t temp;
|
||||
|
||||
(*tt_counter)--;
|
||||
|
||||
temp = state->level - state->tt_delta;
|
||||
|
||||
if (temp > INT16_MAX) {
|
||||
temp = INT16_MAX;
|
||||
} else if (temp < INT16_MIN) {
|
||||
temp = INT16_MIN;
|
||||
}
|
||||
|
||||
if (state->level != temp) {
|
||||
state->level = temp;
|
||||
if (state->is_new_transition_start) {
|
||||
state->is_new_transition_start = false;
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state_binding(IGNORE, LEVEL_TEMP);
|
||||
update_light_state();
|
||||
|
||||
k_timer_stop(&level_temp_transition_timer);
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
state->transition_start_timestamp = k_uptime_get();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (*tt_counter == 0) {
|
||||
if (state->tt_counter != 0) {
|
||||
state->tt_counter--;
|
||||
|
||||
state->level -= state->tt_delta;
|
||||
|
||||
state_binding(IGNORE, LEVEL_TEMP);
|
||||
update_light_state();
|
||||
}
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state->level = state->target_level;
|
||||
|
||||
state_binding(IGNORE, LEVEL_TEMP);
|
||||
|
@ -332,21 +466,28 @@ static void light_lightness_actual_work_handler(struct k_work *work)
|
|||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter_actual != 0) {
|
||||
u32_t actual;
|
||||
|
||||
state->tt_counter_actual--;
|
||||
|
||||
actual = state->actual - state->tt_delta_actual;
|
||||
|
||||
if (state->actual != actual) {
|
||||
state->actual = actual;
|
||||
if (state->is_new_transition_start) {
|
||||
state->is_new_transition_start = false;
|
||||
|
||||
if (state->tt_counter_actual == 0) {
|
||||
state_binding(ACTUAL, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
k_timer_stop(&light_lightness_actual_transition_timer);
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
state->transition_start_timestamp = k_uptime_get();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter_actual != 0) {
|
||||
state->tt_counter_actual--;
|
||||
|
||||
state->actual -= state->tt_delta_actual;
|
||||
|
||||
state_binding(ACTUAL, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
}
|
||||
|
||||
if (state->tt_counter_actual == 0) {
|
||||
|
@ -368,21 +509,28 @@ static void light_lightness_linear_work_handler(struct k_work *work)
|
|||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter_linear != 0) {
|
||||
u32_t linear;
|
||||
|
||||
state->tt_counter_linear--;
|
||||
|
||||
linear = state->linear - state->tt_delta_linear;
|
||||
|
||||
if (state->linear != linear) {
|
||||
state->linear = linear;
|
||||
if (state->is_new_transition_start) {
|
||||
state->is_new_transition_start = false;
|
||||
|
||||
if (state->tt_counter_linear == 0) {
|
||||
state_binding(LINEAR, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
k_timer_stop(&light_lightness_linear_transition_timer);
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
state->transition_start_timestamp = k_uptime_get();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter_linear != 0) {
|
||||
state->tt_counter_linear--;
|
||||
|
||||
state->linear -= state->tt_delta_linear;
|
||||
|
||||
state_binding(LINEAR, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
}
|
||||
|
||||
if (state->tt_counter_linear == 0) {
|
||||
|
@ -404,38 +552,35 @@ static void light_ctl_work_handler(struct k_work *work)
|
|||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter != 0) {
|
||||
u32_t lightness, temp;
|
||||
s32_t delta_uv;
|
||||
if (state->is_new_transition_start) {
|
||||
state->is_new_transition_start = false;
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state_binding(CTL, CTL_TEMP);
|
||||
update_light_state();
|
||||
|
||||
k_timer_stop(&light_ctl_transition_timer);
|
||||
} else {
|
||||
state->transition_start_timestamp = k_uptime_get();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter != 0) {
|
||||
state->tt_counter--;
|
||||
|
||||
/* Lightness */
|
||||
lightness = state->lightness - state->tt_lightness_delta;
|
||||
state->lightness -= state->tt_lightness_delta;
|
||||
|
||||
/* Temperature */
|
||||
temp = state->temp - state->tt_temp_delta;
|
||||
state->temp -= state->tt_temp_delta;
|
||||
|
||||
/* Delta_UV */
|
||||
delta_uv = state->delta_uv - state->tt_duv_delta;
|
||||
state->delta_uv -= state->tt_duv_delta;
|
||||
|
||||
if (delta_uv > INT16_MAX) {
|
||||
delta_uv = INT16_MAX;
|
||||
} else if (delta_uv < INT16_MIN) {
|
||||
delta_uv = INT16_MIN;
|
||||
}
|
||||
|
||||
if (state->lightness != lightness || state->temp != temp ||
|
||||
state->delta_uv != delta_uv) {
|
||||
state->lightness = lightness;
|
||||
state->temp = temp;
|
||||
state->delta_uv = delta_uv;
|
||||
|
||||
state_binding(CTL, CTL_TEMP);
|
||||
update_light_state();
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
}
|
||||
state_binding(CTL, CTL_TEMP);
|
||||
update_light_state();
|
||||
}
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
|
@ -459,33 +604,32 @@ static void light_ctl_temp_work_handler(struct k_work *work)
|
|||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter_temp != 0) {
|
||||
s32_t delta_uv;
|
||||
u32_t temp;
|
||||
if (state->is_new_transition_start) {
|
||||
state->is_new_transition_start = false;
|
||||
|
||||
if (state->tt_counter_temp == 0) {
|
||||
state_binding(IGNORE, CTL_TEMP);
|
||||
update_light_state();
|
||||
|
||||
k_timer_stop(&light_ctl_temp_transition_timer);
|
||||
} else {
|
||||
state->transition_start_timestamp = k_uptime_get();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter_temp != 0) {
|
||||
state->tt_counter_temp--;
|
||||
|
||||
/* Temperature */
|
||||
temp = state->temp - state->tt_temp_delta;
|
||||
state->temp -= state->tt_temp_delta;
|
||||
|
||||
/* Delta UV */
|
||||
delta_uv = state->delta_uv - state->tt_duv_delta;
|
||||
state->delta_uv -= state->tt_duv_delta;
|
||||
|
||||
if (delta_uv > INT16_MAX) {
|
||||
delta_uv = INT16_MAX;
|
||||
} else if (delta_uv < INT16_MIN) {
|
||||
delta_uv = INT16_MIN;
|
||||
}
|
||||
|
||||
if (state->temp != temp || state->delta_uv != delta_uv) {
|
||||
state->temp = temp;
|
||||
state->delta_uv = delta_uv;
|
||||
|
||||
state_binding(IGNORE, CTL_TEMP);
|
||||
update_light_state();
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
}
|
||||
state_binding(IGNORE, CTL_TEMP);
|
||||
update_light_state();
|
||||
}
|
||||
|
||||
if (state->tt_counter_temp == 0) {
|
||||
|
@ -547,57 +691,66 @@ static void light_ctl_temp_tt_handler(struct k_timer *dummy)
|
|||
void onoff_handler(struct generic_onoff_state *state)
|
||||
{
|
||||
enable_transition = ONOFF_TT;
|
||||
state->is_new_transition_start = true;
|
||||
|
||||
k_timer_start(&onoff_transition_timer, K_MSEC(5 * state->delay),
|
||||
K_MSEC(state->cal_tt));
|
||||
K_MSEC(state->quo_tt));
|
||||
}
|
||||
|
||||
void level_lightness_handler(struct generic_level_state *state)
|
||||
{
|
||||
state->is_new_transition_start = true;
|
||||
|
||||
k_timer_start(&level_lightness_transition_timer,
|
||||
K_MSEC(5 * state->delay),
|
||||
K_MSEC(state->cal_tt));
|
||||
K_MSEC(state->quo_tt));
|
||||
}
|
||||
|
||||
void level_temp_handler(struct generic_level_state *state)
|
||||
{
|
||||
state->is_new_transition_start = true;
|
||||
|
||||
k_timer_start(&level_temp_transition_timer, K_MSEC(5 * state->delay),
|
||||
K_MSEC(state->cal_tt));
|
||||
K_MSEC(state->quo_tt));
|
||||
}
|
||||
|
||||
void light_lightness_actual_handler(struct light_lightness_state *state)
|
||||
{
|
||||
enable_transition = LIGTH_LIGHTNESS_ACTUAL_TT;
|
||||
state->is_new_transition_start = true;
|
||||
|
||||
k_timer_start(&light_lightness_actual_transition_timer,
|
||||
K_MSEC(5 * state->delay),
|
||||
K_MSEC(state->cal_tt));
|
||||
K_MSEC(state->quo_tt));
|
||||
}
|
||||
|
||||
void light_lightness_linear_handler(struct light_lightness_state *state)
|
||||
{
|
||||
enable_transition = LIGTH_LIGHTNESS_LINEAR_TT;
|
||||
state->is_new_transition_start = true;
|
||||
|
||||
k_timer_start(&light_lightness_linear_transition_timer,
|
||||
K_MSEC(5 * state->delay),
|
||||
K_MSEC(state->cal_tt));
|
||||
K_MSEC(state->quo_tt));
|
||||
}
|
||||
|
||||
void light_ctl_handler(struct light_ctl_state *state)
|
||||
{
|
||||
enable_transition = LIGTH_CTL_TT;
|
||||
state->is_new_transition_start = true;
|
||||
|
||||
k_timer_start(&light_ctl_transition_timer, K_MSEC(5 * state->delay),
|
||||
K_MSEC(state->cal_tt));
|
||||
K_MSEC(state->quo_tt));
|
||||
}
|
||||
|
||||
void light_ctl_temp_handler(struct light_ctl_state *state)
|
||||
{
|
||||
enable_transition = LIGHT_CTL_TEMP_TT;
|
||||
state->is_new_transition_start = true;
|
||||
|
||||
k_timer_start(&light_ctl_temp_transition_timer,
|
||||
K_MSEC(5 * state->delay),
|
||||
K_MSEC(state->cal_tt));
|
||||
K_MSEC(state->quo_tt));
|
||||
}
|
||||
/* Messages handlers (End) */
|
||||
|
||||
|
|
|
@ -25,8 +25,9 @@ enum transition_time {
|
|||
LIGHT_CTL_TEMP_TT
|
||||
};
|
||||
|
||||
extern u8_t enable_transition;
|
||||
extern u8_t default_tt;
|
||||
extern u8_t enable_transition, default_tt;
|
||||
extern u32_t *ptr_tt_counter;
|
||||
extern s64_t transition_start_timestamp;
|
||||
|
||||
struct k_timer onoff_transition_timer;
|
||||
struct k_timer level_lightness_transition_timer;
|
||||
|
@ -36,10 +37,17 @@ struct k_timer light_lightness_linear_transition_timer;
|
|||
struct k_timer light_ctl_transition_timer;
|
||||
struct k_timer light_ctl_temp_transition_timer;
|
||||
|
||||
u8_t calculate_rt(s32_t duration_remainder);
|
||||
|
||||
void onoff_calculate_rt(struct generic_onoff_state *state);
|
||||
void level_calculate_rt(struct generic_level_state *state);
|
||||
void light_lightness_actual_calculate_rt(struct light_lightness_state *state);
|
||||
void light_lightness_linear_calculate_rt(struct light_lightness_state *state);
|
||||
void light_ctl_calculate_rt(struct light_ctl_state *state);
|
||||
void light_ctl_temp_calculate_rt(struct light_ctl_state *state);
|
||||
|
||||
void onoff_tt_values(struct generic_onoff_state *state);
|
||||
void level_tt_values(struct generic_level_state *state);
|
||||
void delta_level_tt_values(struct generic_level_state *state);
|
||||
void move_level_tt_values(struct generic_level_state *state);
|
||||
void light_lightnes_actual_tt_values(struct light_lightness_state *state);
|
||||
void light_lightnes_linear_tt_values(struct light_lightness_state *state);
|
||||
void light_ctl_tt_values(struct light_ctl_state *state);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue