mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-06 05:14:45 +00:00
apps/blemesh_models_example_2: Add app with various models
This is a application demonstrating a Bluetooth mesh node in which Root element has following models - Generic OnOff Server - Generic OnOff Client - Generic Level Server - Generic Level Client - Generic Power OnOff Server - Generic Power OnOff Setup Server - Generic Power OnOff Client - Light Lightness Server - Light Lightness Setup Server - Light Lightness Client - Light CTL Server - Light CTL Setup Server - Light CTL Client - Vendor Model And Secondary element has following models - Generic OnOff Server - Generic OnOff Client - Generic Level Server - Generic Level Client - Light CTL Temperature Server Prior to provisioning, an unprovisioned beacon is broadcast that contains a unique UUID. Each button controls the state of its corresponding LED and does not initiate any mesh activity
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
#### Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
|
||||
##### Overview
|
||||
********
|
||||
|
||||
This is a application demonstrating a Bluetooth mesh node in
|
||||
which Root element has following models
|
||||
|
||||
- Generic OnOff Server
|
||||
- Generic OnOff Client
|
||||
- Generic Level Server
|
||||
- Generic Level Client
|
||||
- Generic Power OnOff Server
|
||||
- Generic Power OnOff Setup Server
|
||||
- Generic Power OnOff Client
|
||||
- Light Lightness Server
|
||||
- Light Lightness Setup Server
|
||||
- Light Lightness Client
|
||||
- Light CTL Server
|
||||
- Light CTL Setup Server
|
||||
- Light CTL Client
|
||||
- Vendor Model
|
||||
|
||||
And Secondary element has following models
|
||||
|
||||
- Generic OnOff Server
|
||||
- Generic OnOff Client
|
||||
- Generic Level Server
|
||||
- Generic Level Client
|
||||
- Light CTL Temperature Server
|
||||
|
||||
Prior to provisioning, an unprovisioned beacon is broadcast that contains
|
||||
a unique UUID. Each button controls the state of its
|
||||
corresponding LED and does not initiate any mesh activity
|
||||
|
||||
##### Associations of Models with hardware
|
||||
************************************
|
||||
For the nRF52840-PDK board, these are the model associations:
|
||||
|
||||
* LED1 is associated with generic OnOff Server's state which is part of Root element
|
||||
* LED2 is associated with Vendor Model which is part of Root element
|
||||
* LED3 is associated with generic Level (ROOT) / Light Lightness Actual value
|
||||
* LED4 is associated with generic Level (Secondary) / Light CTL Temperature value
|
||||
* Button1 and Button2 are associated with gen. OnOff Client or Vendor Model which is part of Root element
|
||||
* Button3 and Button4 are associated with gen. Level Client / Light Lightness Client / Light CTL Client which is part of Root element
|
||||
|
||||
States of Servers are bounded as per Bluetooth SIG Mesh Model Specification v1.0
|
||||
|
||||
After provisioning, the button clients must
|
||||
be configured to publish and the LED servers to subscribe.
|
||||
If a server is provided with a publish address, it will
|
||||
also publish its relevant status.
|
||||
|
||||
##### Requirements
|
||||
************
|
||||
This sample has been tested on the Nordic nRF52840-PDK board, but would
|
||||
likely also run on the nrf52_pca10040 board.
|
||||
|
||||
|
||||
##### Running
|
||||
************
|
||||
|
||||
Provisioning is done using the BlueZ meshctl utility. In this example, we'll use meshctl commands to bind:
|
||||
|
||||
- Button1, Button2, and LED1 to application key 1. It then configures Button1 and Button2
|
||||
to publish to group 0xC000 and LED1 to subscribe to that group.
|
||||
- Button3, Button4, and LED3 to application key 1. It then configures Button3 and Button4
|
||||
to publish to group 0xC000 and LED3 to subscribe to that group.
|
||||
|
||||
```
|
||||
discover-unprovisioned on
|
||||
provision <discovered UUID>
|
||||
menu config
|
||||
target 0100
|
||||
appkey-add 1
|
||||
bind 0 1 1000
|
||||
bind 0 1 1001
|
||||
bind 0 1 1002
|
||||
bind 0 1 1003
|
||||
sub-add 0100 c000 1000
|
||||
sub-add 0100 c000 1002
|
||||
pub-set 0100 c000 1 0 5 1001
|
||||
pub-set 0100 c000 1 0 5 1003
|
||||
```
|
||||
|
||||
The meshctl utility maintains a persistent JSON database containing
|
||||
the mesh configuration. As additional nodes (boards) are provisioned, it
|
||||
assigns sequential unicast addresses based on the number of elements
|
||||
supported by the node. This example supports 2 elements per node.
|
||||
|
||||
The meshctl target for configuration must be the root element's unicast
|
||||
address as it is the only one that has a configuration server model. If
|
||||
meshctl is gracefully exited, it can be restarted and reconnected to
|
||||
network 0x0.
|
||||
|
||||
The meshctl utility also supports a onoff model client that can be used to
|
||||
change the state of any LED that is bound to application key 0x1.
|
||||
This is done by setting the target to the unicast address of the element
|
||||
that has that LED's model and issuing the onoff command.
|
||||
Group addresses are not supported.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
pkg.name: apps/blemesh_models_example_2
|
||||
pkg.type: app
|
||||
pkg.description: Sample application for BLE Mesh node with on/off, level, light and vendor models on nRF52840pdk
|
||||
pkg.author: "Michał Narajowski <michal.narajowski@codecoup.pl>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
pkg.keywords:
|
||||
|
||||
pkg.deps:
|
||||
- "@apache-mynewt-core/kernel/os"
|
||||
- "@apache-mynewt-core/sys/console/full"
|
||||
- "@apache-mynewt-core/sys/log/full"
|
||||
- "@apache-mynewt-core/sys/stats/full"
|
||||
- nimble/controller
|
||||
- nimble/host
|
||||
- nimble/host/services/gap
|
||||
- nimble/host/services/gatt
|
||||
- nimble/transport/ram
|
||||
|
||||
pkg.lflags:
|
||||
- -DFLOAT_SUPPORT
|
||||
- -lm
|
||||
@@ -0,0 +1,93 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "console/console.h"
|
||||
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
|
||||
#define OOB_AUTH_ENABLE 1
|
||||
|
||||
#ifdef OOB_AUTH_ENABLE
|
||||
|
||||
static int output_number(bt_mesh_output_action_t action, u32_t number)
|
||||
{
|
||||
printk("OOB Number: %lu\n", number);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_string(const char *str)
|
||||
{
|
||||
printk("OOB String: %s\n", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void prov_complete(u16_t net_idx, u16_t addr)
|
||||
{
|
||||
}
|
||||
|
||||
static void prov_reset(void)
|
||||
{
|
||||
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
|
||||
}
|
||||
|
||||
static u8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
|
||||
|
||||
static const struct bt_mesh_prov prov = {
|
||||
.uuid = dev_uuid,
|
||||
|
||||
#ifdef OOB_AUTH_ENABLE
|
||||
|
||||
.output_size = 6,
|
||||
.output_actions = BT_MESH_DISPLAY_NUMBER | BT_MESH_DISPLAY_STRING,
|
||||
.output_number = output_number,
|
||||
.output_string = output_string,
|
||||
|
||||
#endif
|
||||
|
||||
.complete = prov_complete,
|
||||
.reset = prov_reset,
|
||||
};
|
||||
|
||||
void blemesh_on_reset(int reason)
|
||||
{
|
||||
BLE_HS_LOG(ERROR, "Resetting state; reason=%d\n", reason);
|
||||
}
|
||||
|
||||
void blemesh_on_sync(void)
|
||||
{
|
||||
int err;
|
||||
ble_addr_t addr;
|
||||
|
||||
console_printf("Bluetooth initialized\n");
|
||||
|
||||
/* Use NRPA */
|
||||
err = ble_hs_id_gen_rnd(1, &addr);
|
||||
assert(err == 0);
|
||||
err = ble_hs_id_set_rnd(addr.val);
|
||||
assert(err == 0);
|
||||
|
||||
err = bt_mesh_init(addr.type, &prov, &comp);
|
||||
if (err) {
|
||||
console_printf("Initializing mesh failed (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_SETTINGS)) {
|
||||
settings_load();
|
||||
}
|
||||
|
||||
if (bt_mesh_is_provisioned()) {
|
||||
console_printf("Mesh network restored from flash\n");
|
||||
}
|
||||
|
||||
bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
|
||||
|
||||
console_printf("Mesh initialized\n");
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BLE_MESH_H
|
||||
#define _BLE_MESH_H
|
||||
|
||||
#include "mesh/mesh.h"
|
||||
#include "mesh/glue.h"
|
||||
|
||||
/* Model Operation Codes */
|
||||
#define BT_MESH_MODEL_OP_GEN_ONOFF_GET BT_MESH_MODEL_OP_2(0x82, 0x01)
|
||||
#define BT_MESH_MODEL_OP_GEN_ONOFF_SET BT_MESH_MODEL_OP_2(0x82, 0x02)
|
||||
#define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03)
|
||||
#define BT_MESH_MODEL_OP_GEN_ONOFF_STATUS BT_MESH_MODEL_OP_2(0x82, 0x04)
|
||||
|
||||
#define BT_MESH_MODEL_OP_GEN_LEVEL_GET BT_MESH_MODEL_OP_2(0x82, 0x05)
|
||||
#define BT_MESH_MODEL_OP_GEN_LEVEL_SET BT_MESH_MODEL_OP_2(0x82, 0x06)
|
||||
#define BT_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x07)
|
||||
#define BT_MESH_MODEL_OP_GEN_LEVEL_STATUS BT_MESH_MODEL_OP_2(0x82, 0x08)
|
||||
#define BT_MESH_MODEL_OP_GEN_DELTA_SET BT_MESH_MODEL_OP_2(0x82, 0x09)
|
||||
#define BT_MESH_MODEL_OP_GEN_DELTA_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x0A)
|
||||
#define BT_MESH_MODEL_OP_GEN_MOVE_SET BT_MESH_MODEL_OP_2(0x82, 0x0B)
|
||||
#define BT_MESH_MODEL_OP_GEN_MOVE_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x0C)
|
||||
|
||||
void blemesh_on_reset(int reason);
|
||||
void blemesh_on_sync(void);
|
||||
void init_pub(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
extern int button_device[];
|
||||
extern int led_device[];
|
||||
|
||||
void update_light_state(void);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,182 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _DEVICE_COMPOSITION_H
|
||||
#define _DEVICE_COMPOSITION_H
|
||||
|
||||
#define CID_RUNTIME 0x05C3
|
||||
|
||||
#define STATE_OFF 0x00
|
||||
#define STATE_ON 0x01
|
||||
#define STATE_DEFAULT 0x01
|
||||
#define STATE_RESTORE 0x02
|
||||
|
||||
/* Following 4 values are as per Mesh Model specification */
|
||||
#define LIGHTNESS_MIN 0x0001
|
||||
#define LIGHTNESS_MAX 0xFFFF
|
||||
#define TEMP_MIN 0x0320
|
||||
#define TEMP_MAX 0x4E20
|
||||
|
||||
/* Refer 7.2 of Mesh Model Specification */
|
||||
#define RANGE_SUCCESSFULLY_UPDATED 0x00
|
||||
#define CANNOT_SET_RANGE_MIN 0x01
|
||||
#define CANNOT_SET_RANGE_MAX 0x02
|
||||
|
||||
enum lightness {
|
||||
ONPOWERUP = 0x01,
|
||||
ONOFF,
|
||||
LEVEL,
|
||||
DELTA_LEVEL,
|
||||
ACTUAL,
|
||||
LINEAR,
|
||||
CTL,
|
||||
IGNORE
|
||||
};
|
||||
|
||||
enum temperature {
|
||||
ONOFF_TEMP = 0x01,
|
||||
LEVEL_TEMP,
|
||||
CTL_TEMP,
|
||||
IGNORE_TEMP
|
||||
};
|
||||
|
||||
struct generic_onoff_state {
|
||||
u8_t onoff;
|
||||
u8_t target_onoff;
|
||||
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
};
|
||||
|
||||
struct generic_level_state {
|
||||
s16_t level;
|
||||
s16_t target_level;
|
||||
|
||||
s16_t last_level;
|
||||
s32_t last_delta;
|
||||
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
|
||||
s32_t tt_delta;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
u32_t tt_counter_delta;
|
||||
u32_t tt_counter_move;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
};
|
||||
|
||||
struct generic_onpowerup_state {
|
||||
u8_t onpowerup;
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
};
|
||||
|
||||
struct gen_def_trans_time_state {
|
||||
u8_t tt;
|
||||
};
|
||||
|
||||
struct vendor_state {
|
||||
int current;
|
||||
u32_t response;
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
};
|
||||
|
||||
struct light_lightness_state {
|
||||
u16_t linear;
|
||||
u16_t target_linear;
|
||||
|
||||
u16_t actual;
|
||||
u16_t target_actual;
|
||||
|
||||
u16_t last;
|
||||
u16_t def;
|
||||
|
||||
u8_t status_code;
|
||||
u16_t light_range_min;
|
||||
u16_t light_range_max;
|
||||
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
|
||||
s32_t tt_delta_actual;
|
||||
s32_t tt_delta_linear;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter_actual;
|
||||
u32_t tt_counter_linear;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
};
|
||||
|
||||
struct light_ctl_state {
|
||||
u16_t lightness;
|
||||
u16_t target_lightness;
|
||||
|
||||
u16_t temp;
|
||||
u16_t target_temp;
|
||||
|
||||
s16_t delta_uv;
|
||||
s16_t target_delta_uv;
|
||||
|
||||
u8_t status_code;
|
||||
u16_t temp_range_min;
|
||||
u16_t temp_range_max;
|
||||
|
||||
u16_t lightness_def;
|
||||
u16_t temp_def;
|
||||
s16_t delta_uv_def;
|
||||
|
||||
u16_t temp_last;
|
||||
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
|
||||
s32_t tt_lightness_delta;
|
||||
s32_t tt_temp_delta;
|
||||
s32_t tt_duv_delta;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
u32_t tt_counter_temp;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
};
|
||||
|
||||
extern struct generic_onoff_state gen_onoff_srv_root_user_data;
|
||||
extern struct generic_level_state gen_level_srv_root_user_data;
|
||||
extern struct gen_def_trans_time_state gen_def_trans_time_srv_user_data;
|
||||
extern struct generic_onpowerup_state gen_power_onoff_srv_user_data;
|
||||
extern struct light_lightness_state light_lightness_srv_user_data;
|
||||
extern struct light_ctl_state light_ctl_srv_user_data;
|
||||
extern struct generic_level_state gen_level_srv_s0_user_data;
|
||||
|
||||
extern struct bt_mesh_model root_models[];
|
||||
extern struct bt_mesh_model vnd_models[];
|
||||
extern struct bt_mesh_model s0_models[];
|
||||
|
||||
extern const struct bt_mesh_comp comp;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,198 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "bsp/bsp.h"
|
||||
#include "console/console.h"
|
||||
#include "hal/hal_gpio.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
#include "publisher.h"
|
||||
#include "state_binding.h"
|
||||
#include "transition.h"
|
||||
|
||||
int button_device[] = {
|
||||
BUTTON_1,
|
||||
BUTTON_2,
|
||||
BUTTON_3,
|
||||
BUTTON_4,
|
||||
};
|
||||
|
||||
int led_device[] = {
|
||||
LED_1,
|
||||
LED_2,
|
||||
LED_3,
|
||||
LED_4,
|
||||
};
|
||||
|
||||
static struct ble_npl_callout button_work;
|
||||
|
||||
static void button_pressed(struct os_event *ev)
|
||||
{
|
||||
k_work_submit(&button_work);
|
||||
}
|
||||
|
||||
static struct os_event button_event;
|
||||
|
||||
static void
|
||||
gpio_irq_handler(void *arg)
|
||||
{
|
||||
button_event.ev_arg = arg;
|
||||
os_eventq_put(os_eventq_dflt_get(), &button_event);
|
||||
}
|
||||
|
||||
static void gpio_init(void)
|
||||
{
|
||||
/* LEDs configiuratin & setting */
|
||||
|
||||
hal_gpio_init_out(led_device[0], 1);
|
||||
hal_gpio_init_out(led_device[1], 1);
|
||||
hal_gpio_init_out(led_device[2], 1);
|
||||
hal_gpio_init_out(led_device[3], 1);
|
||||
|
||||
/* Buttons configiuratin & setting */
|
||||
|
||||
k_work_init(&button_work, publish);
|
||||
|
||||
button_event.ev_cb = button_pressed;
|
||||
|
||||
hal_gpio_irq_init(button_device[0], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[0]);
|
||||
|
||||
hal_gpio_irq_init(button_device[1], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[1]);
|
||||
|
||||
hal_gpio_irq_init(button_device[2], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[2]);
|
||||
|
||||
hal_gpio_irq_init(button_device[3], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[3]);
|
||||
}
|
||||
|
||||
void light_default_status_init(void)
|
||||
{
|
||||
/* Assume vaules are retrived from Persistence Storage (Start).
|
||||
* These had saved by respective Setup Servers.
|
||||
*/
|
||||
gen_power_onoff_srv_user_data.onpowerup = STATE_DEFAULT;
|
||||
|
||||
light_lightness_srv_user_data.light_range_min = LIGHTNESS_MIN;
|
||||
light_lightness_srv_user_data.light_range_max = LIGHTNESS_MAX;
|
||||
light_lightness_srv_user_data.def = LIGHTNESS_MAX;
|
||||
|
||||
/* Following 2 values are as per specification */
|
||||
light_ctl_srv_user_data.temp_range_min = TEMP_MIN;
|
||||
light_ctl_srv_user_data.temp_range_max = TEMP_MAX;
|
||||
|
||||
light_ctl_srv_user_data.temp_def = TEMP_MIN;
|
||||
/* (End) */
|
||||
|
||||
/* Assume following values are retrived from Persistence
|
||||
* Storage (Start).
|
||||
* These values had saved before power down.
|
||||
*/
|
||||
light_lightness_srv_user_data.last = LIGHTNESS_MAX;
|
||||
light_ctl_srv_user_data.temp_last = TEMP_MIN;
|
||||
/* (End) */
|
||||
|
||||
light_ctl_srv_user_data.temp = light_ctl_srv_user_data.temp_def;
|
||||
|
||||
if (gen_power_onoff_srv_user_data.onpowerup == STATE_OFF) {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
|
||||
state_binding(ONOFF, ONOFF_TEMP);
|
||||
} else if (gen_power_onoff_srv_user_data.onpowerup == STATE_DEFAULT) {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
state_binding(ONOFF, ONOFF_TEMP);
|
||||
} else if (gen_power_onoff_srv_user_data.onpowerup == STATE_RESTORE) {
|
||||
/* Assume following values is retrived from Persistence
|
||||
* Storage (Start).
|
||||
* This value had saved before power down.
|
||||
*/
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
/* (End) */
|
||||
|
||||
light_ctl_srv_user_data.temp =
|
||||
light_ctl_srv_user_data.temp_last;
|
||||
|
||||
state_binding(ONPOWERUP, ONOFF_TEMP);
|
||||
}
|
||||
}
|
||||
|
||||
void update_light_state(void)
|
||||
{
|
||||
u8_t power, color;
|
||||
|
||||
power = 100 * ((float) light_lightness_srv_user_data.actual / 65535);
|
||||
color = 100 * ((float) (gen_level_srv_s0_user_data.level + 32768)
|
||||
/ 65535);
|
||||
|
||||
printk("power-> %d, color-> %d\n", power, color);
|
||||
|
||||
if (gen_onoff_srv_root_user_data.onoff == STATE_ON) {
|
||||
/* LED1 On */
|
||||
hal_gpio_write(led_device[0], 0);
|
||||
} else {
|
||||
/* LED1 Off */
|
||||
hal_gpio_write(led_device[0], 1);
|
||||
}
|
||||
|
||||
if (power < 50) {
|
||||
/* LED3 On */
|
||||
hal_gpio_write(led_device[2], 0);
|
||||
} else {
|
||||
/* LED3 Off */
|
||||
hal_gpio_write(led_device[2], 1);
|
||||
}
|
||||
|
||||
if (color < 50) {
|
||||
/* LED4 On */
|
||||
hal_gpio_write(led_device[3], 0);
|
||||
} else {
|
||||
/* LED4 Off */
|
||||
hal_gpio_write(led_device[3], 1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#ifdef ARCH_sim
|
||||
mcu_sim_parse_args(argc, argv);
|
||||
#endif
|
||||
|
||||
/* Initialize OS */
|
||||
sysinit();
|
||||
|
||||
light_default_status_init();
|
||||
|
||||
transition_timers_init();
|
||||
|
||||
gpio_init();
|
||||
|
||||
update_light_state();
|
||||
|
||||
init_pub();
|
||||
|
||||
printk("Initializing...\n");
|
||||
|
||||
/* Initialize the NimBLE host configuration. */
|
||||
ble_hs_cfg.reset_cb = blemesh_on_reset;
|
||||
ble_hs_cfg.sync_cb = blemesh_on_sync;
|
||||
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
|
||||
|
||||
randomize_publishers_TID();
|
||||
|
||||
while (1) {
|
||||
os_eventq_run(os_eventq_dflt_get());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "console/console.h"
|
||||
#include "hal/hal_gpio.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "ble_mesh.h"
|
||||
#include "publisher.h"
|
||||
#include "device_composition.h"
|
||||
|
||||
#define ONOFF
|
||||
#define GENERIC_LEVEL
|
||||
/* #define LIGHT_CTL */
|
||||
/* #define LIGHT_CTL_TEMP */
|
||||
|
||||
static bool is_randomization_of_TIDs_done;
|
||||
|
||||
#if defined(ONOFF)
|
||||
static u8_t tid_onoff;
|
||||
#elif defined(VND_MODEL_TEST)
|
||||
static u8_t tid_vnd;
|
||||
#endif
|
||||
|
||||
static u8_t tid_level;
|
||||
|
||||
void randomize_publishers_TID(void)
|
||||
{
|
||||
#if defined(ONOFF)
|
||||
bt_rand(&tid_onoff, sizeof(tid_onoff));
|
||||
#elif defined(VND_MODEL_TEST)
|
||||
bt_rand(&tid_vnd, sizeof(tid_vnd));
|
||||
#endif
|
||||
|
||||
bt_rand(&tid_level, sizeof(tid_level));
|
||||
|
||||
is_randomization_of_TIDs_done = true;
|
||||
}
|
||||
|
||||
static u32_t button_read(int button)
|
||||
{
|
||||
return (uint32_t) hal_gpio_read(button);
|
||||
}
|
||||
|
||||
void publish(struct ble_npl_event *work)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (is_randomization_of_TIDs_done == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (button_read(button_device[0]) == 0) {
|
||||
#if defined(ONOFF)
|
||||
bt_mesh_model_msg_init(root_models[3].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, 0x01);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, tid_onoff++);
|
||||
err = bt_mesh_model_publish(&root_models[3]);
|
||||
#elif defined(ONOFF_TT)
|
||||
bt_mesh_model_msg_init(root_models[3].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, 0x01);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, tid_onoff++);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, 0x45);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, 0x28);
|
||||
err = bt_mesh_model_publish(&root_models[3]);
|
||||
#elif defined(VND_MODEL_TEST)
|
||||
bt_mesh_model_msg_init(vnd_models[0].pub->msg,
|
||||
BT_MESH_MODEL_OP_3(0x02, CID_RUNTIME));
|
||||
net_buf_simple_add_le16(vnd_models[0].pub->msg, 0x0001);
|
||||
net_buf_simple_add_u8(vnd_models[0].pub->msg, tid_vnd++);
|
||||
err = bt_mesh_model_publish(&vnd_models[0]);
|
||||
#endif
|
||||
|
||||
} else if (button_read(button_device[1]) == 0) {
|
||||
#if defined(ONOFF)
|
||||
bt_mesh_model_msg_init(root_models[3].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, 0x00);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, tid_onoff++);
|
||||
err = bt_mesh_model_publish(&root_models[3]);
|
||||
#elif defined(ONOFF_TT)
|
||||
bt_mesh_model_msg_init(root_models[3].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, 0x00);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, tid_onoff++);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, 0x45);
|
||||
net_buf_simple_add_u8(root_models[3].pub->msg, 0x28);
|
||||
err = bt_mesh_model_publish(&root_models[3]);
|
||||
#elif defined(VND_MODEL_TEST)
|
||||
bt_mesh_model_msg_init(vnd_models[0].pub->msg,
|
||||
BT_MESH_MODEL_OP_3(0x02, CID_RUNTIME));
|
||||
net_buf_simple_add_le16(vnd_models[0].pub->msg, 0x0000);
|
||||
net_buf_simple_add_u8(vnd_models[0].pub->msg, tid_vnd++);
|
||||
err = bt_mesh_model_publish(&vnd_models[0]);
|
||||
#endif
|
||||
|
||||
} else if (button_read(button_device[2]) == 0) {
|
||||
#if defined(GENERIC_LEVEL)
|
||||
bt_mesh_model_msg_init(root_models[5].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK);
|
||||
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(GENERIC_DELTA_LEVEL)
|
||||
bt_mesh_model_msg_init(root_models[5].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_DELTA_SET_UNACK);
|
||||
net_buf_simple_add_le32(root_models[5].pub->msg, 100);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[5]);
|
||||
#elif defined(GENERIC_MOVE_LEVEL_TT)
|
||||
bt_mesh_model_msg_init(root_models[5].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_MOVE_SET_UNACK);
|
||||
net_buf_simple_add_le16(root_models[5].pub->msg, 13100);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, tid_level++);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, 0x45);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, 0x00);
|
||||
err = bt_mesh_model_publish(&root_models[5]);
|
||||
#elif defined(LIGHT_LIGHTNESS_TT)
|
||||
bt_mesh_model_msg_init(root_models[13].pub->msg,
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x4D));
|
||||
net_buf_simple_add_le16(root_models[13].pub->msg, LEVEL_U25);
|
||||
net_buf_simple_add_u8(root_models[13].pub->msg, tid_level++);
|
||||
net_buf_simple_add_u8(root_models[13].pub->msg, 0x45);
|
||||
net_buf_simple_add_u8(root_models[13].pub->msg, 0x28);
|
||||
err = bt_mesh_model_publish(&root_models[13]);
|
||||
#elif defined(LIGHT_CTL)
|
||||
bt_mesh_model_msg_init(root_models[16].pub->msg,
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x5F));
|
||||
/* Lightness */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, LEVEL_U25);
|
||||
/* Temperature (value should be from 0x0320 to 0x4E20 */
|
||||
/* This is as per 6.1.3.1 in Mesh Model Specification */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0320);
|
||||
/* Delta UV */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0000);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[16]);
|
||||
#elif defined(LIGHT_CTL_TT)
|
||||
bt_mesh_model_msg_init(root_models[16].pub->msg,
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x5F));
|
||||
/* Lightness */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, LEVEL_U25);
|
||||
/* Temperature (value should be from 0x0320 to 0x4E20 */
|
||||
/* This is as per 6.1.3.1 in Mesh Model Specification */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0320);
|
||||
/* Delta UV */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0000);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, tid_level++);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, 0x45);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, 0x00);
|
||||
err = bt_mesh_model_publish(&root_models[16]);
|
||||
#elif defined(LIGHT_CTL_TEMP)
|
||||
bt_mesh_model_msg_init(root_models[16].pub->msg,
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x65));
|
||||
/* Temperature (value should be from 0x0320 to 0x4E20 */
|
||||
/* This is as per 6.1.3.1 in Mesh Model Specification */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0320);
|
||||
/* Delta UV */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0000);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[16]);
|
||||
#endif
|
||||
|
||||
} else if (button_read(button_device[3]) == 0) {
|
||||
#if defined(GENERIC_LEVEL)
|
||||
bt_mesh_model_msg_init(root_models[5].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK);
|
||||
net_buf_simple_add_le16(root_models[5].pub->msg, LEVEL_S100);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[5]);
|
||||
#elif defined(GENERIC_DELTA_LEVEL)
|
||||
bt_mesh_model_msg_init(root_models[5].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_DELTA_SET_UNACK);
|
||||
net_buf_simple_add_le32(root_models[5].pub->msg, -100);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[5]);
|
||||
#elif defined(GENERIC_MOVE_LEVEL_TT)
|
||||
bt_mesh_model_msg_init(root_models[5].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_MOVE_SET_UNACK);
|
||||
net_buf_simple_add_le16(root_models[5].pub->msg, -13100);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, tid_level++);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, 0x45);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, 0x00);
|
||||
err = bt_mesh_model_publish(&root_models[5]);
|
||||
#elif defined(LIGHT_LIGHTNESS_TT)
|
||||
bt_mesh_model_msg_init(root_models[13].pub->msg,
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x4D));
|
||||
net_buf_simple_add_le16(root_models[13].pub->msg, LEVEL_U100);
|
||||
net_buf_simple_add_u8(root_models[13].pub->msg, tid_level++);
|
||||
net_buf_simple_add_u8(root_models[13].pub->msg, 0x45);
|
||||
net_buf_simple_add_u8(root_models[13].pub->msg, 0x28);
|
||||
err = bt_mesh_model_publish(&root_models[13]);
|
||||
#elif defined(LIGHT_CTL)
|
||||
bt_mesh_model_msg_init(root_models[16].pub->msg,
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x5F));
|
||||
/* Lightness */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, LEVEL_U100);
|
||||
/* Temperature (value should be from 0x0320 to 0x4E20 */
|
||||
/* This is as per 6.1.3.1 in Mesh Model Specification */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x4E20);
|
||||
/* Delta UV */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0000);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[16]);
|
||||
#elif defined(LIGHT_CTL_TT)
|
||||
bt_mesh_model_msg_init(root_models[16].pub->msg,
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x5F));
|
||||
/* Lightness */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, LEVEL_U100);
|
||||
/* Temperature (value should be from 0x0320 to 0x4E20 */
|
||||
/* This is as per 6.1.3.1 in Mesh Model Specification */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x4E20);
|
||||
/* Delta UV */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0000);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, tid_level++);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, 0x45);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, 0x00);
|
||||
err = bt_mesh_model_publish(&root_models[16]);
|
||||
#elif defined(LIGHT_CTL_TEMP)
|
||||
bt_mesh_model_msg_init(root_models[16].pub->msg,
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x65));
|
||||
/* Temperature (value should be from 0x0320 to 0x4E20 */
|
||||
/* This is as per 6.1.3.1 in Mesh Model Specification */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x4E20);
|
||||
/* Delta UV */
|
||||
net_buf_simple_add_le16(root_models[16].pub->msg, 0x0000);
|
||||
net_buf_simple_add_u8(root_models[16].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[16]);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (err) {
|
||||
printk("bt_mesh_model_publish: err: %d\n", err);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _PUBLISHER_H
|
||||
#define _PUBLISHER_H
|
||||
|
||||
/* Others */
|
||||
#define LEVEL_S0 -32768
|
||||
#define LEVEL_S25 -16384
|
||||
#define LEVEL_S50 0
|
||||
#define LEVEL_S75 16384
|
||||
#define LEVEL_S100 32767
|
||||
|
||||
#define LEVEL_U0 0
|
||||
#define LEVEL_U25 16384
|
||||
#define LEVEL_U50 32768
|
||||
#define LEVEL_U75 49152
|
||||
#define LEVEL_U100 65535
|
||||
|
||||
void randomize_publishers_TID(void);
|
||||
void publish(struct ble_npl_event *work);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,183 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
|
||||
static s32_t ceiling(float num)
|
||||
{
|
||||
s32_t inum;
|
||||
|
||||
inum = (s32_t) num;
|
||||
if (num == (float) inum) {
|
||||
return inum;
|
||||
}
|
||||
|
||||
return inum + 1;
|
||||
}
|
||||
|
||||
static bool constrain_light_actual_state(u16_t var)
|
||||
{
|
||||
bool is_value_within_range;
|
||||
|
||||
is_value_within_range = false;
|
||||
|
||||
if (var > 0 &&
|
||||
var < light_lightness_srv_user_data.light_range_min) {
|
||||
var = light_lightness_srv_user_data.light_range_min;
|
||||
} else if (var > light_lightness_srv_user_data.light_range_max) {
|
||||
var = light_lightness_srv_user_data.light_range_max;
|
||||
} else {
|
||||
is_value_within_range = true;
|
||||
}
|
||||
|
||||
light_lightness_srv_user_data.actual = var;
|
||||
|
||||
return is_value_within_range;
|
||||
}
|
||||
|
||||
static void update_gen_onoff_state(void)
|
||||
{
|
||||
if (light_lightness_srv_user_data.actual == 0) {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
|
||||
} else {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
}
|
||||
}
|
||||
|
||||
void state_binding(u8_t lightness, u8_t temperature)
|
||||
{
|
||||
bool is_value_within_range;
|
||||
u16_t tmp16;
|
||||
float tmp;
|
||||
|
||||
switch (temperature) {
|
||||
case ONOFF_TEMP:/* Temp. update as per Light CTL temp. default state */
|
||||
case CTL_TEMP: /* Temp. update as per Light CTL temp. state */
|
||||
/* Mesh Model Specification 6.1.3.1.1 2nd formula start */
|
||||
tmp = (light_ctl_srv_user_data.temp -
|
||||
light_ctl_srv_user_data.temp_range_min) * 65535;
|
||||
tmp = tmp / (light_ctl_srv_user_data.temp_range_max -
|
||||
light_ctl_srv_user_data.temp_range_min);
|
||||
gen_level_srv_s0_user_data.level = tmp - 32768;
|
||||
/* 6.1.3.1.1 2nd formula end */
|
||||
break;
|
||||
case LEVEL_TEMP:/* Temp. update as per Generic Level (s0) state */
|
||||
/* Mesh Model Specification 6.1.3.1.1 1st formula start */
|
||||
tmp = (float) (light_ctl_srv_user_data.temp_range_max -
|
||||
light_ctl_srv_user_data.temp_range_min) / 65535;
|
||||
tmp = (gen_level_srv_s0_user_data.level + 32768) * tmp;
|
||||
light_ctl_srv_user_data.temp =
|
||||
light_ctl_srv_user_data.temp_range_min + tmp;
|
||||
/* 6.1.3.1.1 1st formula end */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tmp16 = 0;
|
||||
|
||||
switch (lightness) {
|
||||
case ONPOWERUP: /* Lightness update as per Generic OnPowerUp state */
|
||||
if (gen_onoff_srv_root_user_data.onoff == STATE_OFF) {
|
||||
light_lightness_srv_user_data.actual = 0;
|
||||
light_lightness_srv_user_data.linear = 0;
|
||||
gen_level_srv_root_user_data.level = -32768;
|
||||
light_ctl_srv_user_data.lightness = 0;
|
||||
return;
|
||||
} else if (gen_onoff_srv_root_user_data.onoff == STATE_ON) {
|
||||
light_lightness_srv_user_data.actual =
|
||||
light_lightness_srv_user_data.last;
|
||||
}
|
||||
|
||||
break;
|
||||
case ONOFF: /* Lightness update as per Generic OnOff (root) state */
|
||||
if (gen_onoff_srv_root_user_data.onoff == STATE_OFF) {
|
||||
light_lightness_srv_user_data.actual = 0;
|
||||
light_lightness_srv_user_data.linear = 0;
|
||||
gen_level_srv_root_user_data.level = -32768;
|
||||
light_ctl_srv_user_data.lightness = 0;
|
||||
return;
|
||||
} else if (gen_onoff_srv_root_user_data.onoff == STATE_ON) {
|
||||
if (light_lightness_srv_user_data.def == 0) {
|
||||
light_lightness_srv_user_data.actual =
|
||||
light_lightness_srv_user_data.last;
|
||||
} else {
|
||||
light_lightness_srv_user_data.actual =
|
||||
light_lightness_srv_user_data.def;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case LEVEL: /* Lightness update as per Generic Level (root) state */
|
||||
tmp16 = gen_level_srv_root_user_data.level + 32768;
|
||||
constrain_light_actual_state(tmp16);
|
||||
update_gen_onoff_state();
|
||||
break;
|
||||
case DELTA_LEVEL: /* Lightness update as per Gen. Level (root) state */
|
||||
/* This is as per Mesh Model Specification 3.3.2.2.3 */
|
||||
tmp16 = gen_level_srv_root_user_data.level + 32768;
|
||||
if (tmp16 > 0 &&
|
||||
tmp16 < light_lightness_srv_user_data.light_range_min) {
|
||||
if (gen_level_srv_root_user_data.last_delta < 0) {
|
||||
tmp16 = 0;
|
||||
} else {
|
||||
tmp16 =
|
||||
light_lightness_srv_user_data.light_range_min;
|
||||
}
|
||||
} else if (tmp16 >
|
||||
light_lightness_srv_user_data.light_range_max) {
|
||||
tmp16 =
|
||||
light_lightness_srv_user_data.light_range_max;
|
||||
}
|
||||
|
||||
light_lightness_srv_user_data.actual = tmp16;
|
||||
|
||||
update_gen_onoff_state();
|
||||
break;
|
||||
case ACTUAL: /* Lightness update as per Light Lightness Actual state */
|
||||
update_gen_onoff_state();
|
||||
break;
|
||||
case LINEAR: /* Lightness update as per Light Lightness Linear state */
|
||||
tmp16 = (u16_t) 65535 *
|
||||
sqrt(((float) light_lightness_srv_user_data.linear /
|
||||
65535));
|
||||
|
||||
is_value_within_range = constrain_light_actual_state(tmp16);
|
||||
update_gen_onoff_state();
|
||||
|
||||
if (is_value_within_range) {
|
||||
goto ignore_linear_update_others;
|
||||
}
|
||||
|
||||
break;
|
||||
case CTL: /* Lightness update as per Light CTL Lightness state */
|
||||
constrain_light_actual_state(light_ctl_srv_user_data.lightness);
|
||||
update_gen_onoff_state();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = ((float) light_lightness_srv_user_data.actual / 65535);
|
||||
light_lightness_srv_user_data.linear = ceiling(65535 * tmp * tmp);
|
||||
|
||||
ignore_linear_update_others:
|
||||
if (light_lightness_srv_user_data.actual != 0) {
|
||||
light_lightness_srv_user_data.last =
|
||||
light_lightness_srv_user_data.actual;
|
||||
}
|
||||
|
||||
gen_level_srv_root_user_data.level =
|
||||
light_lightness_srv_user_data.actual - 32768;
|
||||
|
||||
light_ctl_srv_user_data.lightness =
|
||||
light_lightness_srv_user_data.actual;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _STATE_BINDING_H
|
||||
#define _STATE_BINDING_H
|
||||
|
||||
void state_binding(u8_t lightness, u8_t temperature);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,678 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
#include "state_binding.h"
|
||||
#include "transition.h"
|
||||
|
||||
u8_t enable_transition;
|
||||
u8_t default_tt;
|
||||
|
||||
struct ble_npl_callout onoff_work;
|
||||
struct ble_npl_callout level_lightness_work;
|
||||
struct ble_npl_callout level_temp_work;
|
||||
struct ble_npl_callout light_lightness_actual_work;
|
||||
struct ble_npl_callout light_lightness_linear_work;
|
||||
struct ble_npl_callout light_ctl_work;
|
||||
struct ble_npl_callout light_ctl_temp_work;
|
||||
|
||||
struct ble_npl_callout onoff_transition_timer;
|
||||
struct ble_npl_callout level_lightness_transition_timer;
|
||||
struct ble_npl_callout level_temp_transition_timer;
|
||||
struct ble_npl_callout light_lightness_actual_transition_timer;
|
||||
struct ble_npl_callout light_lightness_linear_transition_timer;
|
||||
struct ble_npl_callout light_ctl_transition_timer;
|
||||
struct ble_npl_callout light_ctl_temp_transition_timer;
|
||||
|
||||
static u32_t tt_counter_calculator(u8_t *tt, u32_t *cal_tt)
|
||||
{
|
||||
u8_t steps_multiplier, resolution;
|
||||
u32_t tt_counter;
|
||||
|
||||
resolution = ((*tt) >> 6);
|
||||
steps_multiplier = (*tt) & 0x3F;
|
||||
|
||||
switch (resolution) {
|
||||
case 0: /* 100ms */
|
||||
*cal_tt = steps_multiplier * 100;
|
||||
break;
|
||||
case 1: /* 1 second */
|
||||
*cal_tt = steps_multiplier * 1000;
|
||||
break;
|
||||
case 2: /* 10 seconds */
|
||||
*cal_tt = steps_multiplier * 10000;
|
||||
break;
|
||||
case 3: /* 10 minutes */
|
||||
*cal_tt = steps_multiplier * 600000;
|
||||
break;
|
||||
}
|
||||
|
||||
tt_counter = ((float) *cal_tt / 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);
|
||||
}
|
||||
|
||||
void 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 = tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
tt_counter = 1;
|
||||
}
|
||||
|
||||
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);
|
||||
state->tt_counter_actual = tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
tt_counter = 1;
|
||||
}
|
||||
|
||||
state->tt_delta_actual =
|
||||
((float) (state->actual - state->target_actual) /
|
||||
tt_counter);
|
||||
}
|
||||
|
||||
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);
|
||||
state->tt_counter_linear = tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
tt_counter = 1;
|
||||
}
|
||||
|
||||
state->tt_delta_linear =
|
||||
((float) (state->linear - state->target_linear) /
|
||||
tt_counter);
|
||||
}
|
||||
|
||||
void light_ctl_tt_values(struct light_ctl_state *state)
|
||||
{
|
||||
u32_t tt_counter;
|
||||
|
||||
tt_counter = tt_counter_calculator(&state->tt, &state->cal_tt);
|
||||
state->tt_counter = tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
tt_counter = 1;
|
||||
}
|
||||
|
||||
state->tt_lightness_delta =
|
||||
((float) (state->lightness - state->target_lightness) /
|
||||
tt_counter);
|
||||
|
||||
state->tt_temp_delta =
|
||||
((float) (state->temp - state->target_temp) /
|
||||
tt_counter);
|
||||
|
||||
state->tt_duv_delta =
|
||||
((float) (state->delta_uv - state->target_delta_uv) /
|
||||
tt_counter);
|
||||
}
|
||||
|
||||
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);
|
||||
state->tt_counter_temp = tt_counter;
|
||||
|
||||
if (tt_counter == 0) {
|
||||
tt_counter = 1;
|
||||
}
|
||||
|
||||
state->tt_temp_delta = ((float) (state->temp - state->target_temp) /
|
||||
tt_counter);
|
||||
|
||||
state->tt_duv_delta =
|
||||
((float) (state->delta_uv - state->target_delta_uv) /
|
||||
tt_counter);
|
||||
}
|
||||
|
||||
/* Timers related handlers & threads (Start) */
|
||||
static void onoff_work_handler(struct ble_npl_event *work)
|
||||
{
|
||||
struct generic_onoff_state *state = &gen_onoff_srv_root_user_data;
|
||||
|
||||
if (enable_transition != ONOFF_TT) {
|
||||
ble_npl_callout_stop(&onoff_transition_timer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter != 0) {
|
||||
state->tt_counter--;
|
||||
|
||||
if (state->target_onoff == STATE_ON) {
|
||||
state->onoff = STATE_ON;
|
||||
|
||||
state_binding(ONOFF, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state->onoff = state->target_onoff;
|
||||
|
||||
state_binding(ONOFF, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
ble_npl_callout_stop(&onoff_transition_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void level_lightness_work_handler(struct ble_npl_event *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:
|
||||
ble_npl_callout_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;
|
||||
|
||||
state_binding(LEVEL, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
}
|
||||
}
|
||||
|
||||
if (*tt_counter == 0) {
|
||||
state->level = state->target_level;
|
||||
|
||||
state_binding(LEVEL, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
ble_npl_callout_stop(&level_lightness_transition_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void level_temp_work_handler(struct ble_npl_event *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;
|
||||
break;
|
||||
case LEVEL_TT_DELTA:
|
||||
tt_counter = &state->tt_counter_delta;
|
||||
break;
|
||||
case LEVEL_TT_MOVE:
|
||||
tt_counter = &state->tt_counter_move;
|
||||
break;
|
||||
default:
|
||||
ble_npl_callout_stop(&level_temp_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;
|
||||
|
||||
state_binding(IGNORE, LEVEL_TEMP);
|
||||
update_light_state();
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
}
|
||||
}
|
||||
|
||||
if (*tt_counter == 0) {
|
||||
state->level = state->target_level;
|
||||
|
||||
state_binding(IGNORE, LEVEL_TEMP);
|
||||
update_light_state();
|
||||
|
||||
ble_npl_callout_stop(&level_temp_transition_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void light_lightness_actual_work_handler(struct ble_npl_event *work)
|
||||
{
|
||||
struct light_lightness_state *state = &light_lightness_srv_user_data;
|
||||
|
||||
if (enable_transition != LIGTH_LIGHTNESS_ACTUAL_TT) {
|
||||
ble_npl_callout_stop(&light_lightness_actual_transition_timer);
|
||||
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;
|
||||
|
||||
state_binding(ACTUAL, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->tt_counter_actual == 0) {
|
||||
state->actual = state->target_actual;
|
||||
|
||||
state_binding(ACTUAL, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
ble_npl_callout_stop(&light_lightness_actual_transition_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void light_lightness_linear_work_handler(struct ble_npl_event *work)
|
||||
{
|
||||
struct light_lightness_state *state = &light_lightness_srv_user_data;
|
||||
|
||||
if (enable_transition != LIGTH_LIGHTNESS_LINEAR_TT) {
|
||||
ble_npl_callout_stop(&light_lightness_linear_transition_timer);
|
||||
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;
|
||||
|
||||
state_binding(LINEAR, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
} else {
|
||||
enable_transition = DISABLE_TRANSITION;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->tt_counter_linear == 0) {
|
||||
state->linear = state->target_linear;
|
||||
|
||||
state_binding(LINEAR, IGNORE_TEMP);
|
||||
update_light_state();
|
||||
|
||||
ble_npl_callout_stop(&light_lightness_linear_transition_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void light_ctl_work_handler(struct ble_npl_event *work)
|
||||
{
|
||||
struct light_ctl_state *state = &light_ctl_srv_user_data;
|
||||
|
||||
if (enable_transition != LIGTH_CTL_TT) {
|
||||
ble_npl_callout_stop(&light_ctl_transition_timer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter != 0) {
|
||||
u32_t lightness, temp;
|
||||
s32_t delta_uv;
|
||||
|
||||
state->tt_counter--;
|
||||
|
||||
/* Lightness */
|
||||
lightness = state->lightness - state->tt_lightness_delta;
|
||||
|
||||
/* Temperature */
|
||||
temp = state->temp - state->tt_temp_delta;
|
||||
|
||||
/* Delta_UV */
|
||||
delta_uv = 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->tt_counter == 0) {
|
||||
state->lightness = state->target_lightness;
|
||||
state->temp = state->target_temp;
|
||||
state->delta_uv = state->target_delta_uv;
|
||||
|
||||
state_binding(CTL, CTL_TEMP);
|
||||
update_light_state();
|
||||
|
||||
ble_npl_callout_stop(&light_ctl_transition_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void light_ctl_temp_work_handler(struct ble_npl_event *work)
|
||||
{
|
||||
struct light_ctl_state *state = &light_ctl_srv_user_data;
|
||||
|
||||
if (enable_transition != LIGHT_CTL_TEMP_TT) {
|
||||
ble_npl_callout_stop(&light_ctl_temp_transition_timer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tt_counter_temp != 0) {
|
||||
s32_t delta_uv;
|
||||
u32_t temp;
|
||||
|
||||
state->tt_counter_temp--;
|
||||
|
||||
/* Temperature */
|
||||
temp = state->temp - state->tt_temp_delta;
|
||||
|
||||
/* Delta UV */
|
||||
delta_uv = 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->tt_counter_temp == 0) {
|
||||
state->temp = state->target_temp;
|
||||
state->delta_uv = state->target_delta_uv;
|
||||
|
||||
state_binding(IGNORE, CTL_TEMP);
|
||||
update_light_state();
|
||||
|
||||
ble_npl_callout_stop(&light_ctl_temp_transition_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void onoff_tt_handler(struct ble_npl_event *ev)
|
||||
{
|
||||
struct generic_onoff_state *state = ble_npl_event_get_arg(ev);
|
||||
|
||||
assert(state != NULL);
|
||||
ble_npl_callout_reset(&onoff_work, 0);
|
||||
ble_npl_callout_reset(&onoff_transition_timer, K_MSEC(state->cal_tt));
|
||||
}
|
||||
|
||||
static void level_lightness_tt_handler(struct ble_npl_event *ev)
|
||||
{
|
||||
struct generic_level_state *state = ble_npl_event_get_arg(ev);
|
||||
|
||||
assert(state != NULL);
|
||||
ble_npl_callout_reset(&level_lightness_work, 0);
|
||||
ble_npl_callout_reset(&level_lightness_transition_timer, K_MSEC(state->cal_tt));
|
||||
}
|
||||
|
||||
static void level_temp_tt_handler(struct ble_npl_event *ev)
|
||||
{
|
||||
struct generic_level_state *state = ble_npl_event_get_arg(ev);
|
||||
|
||||
assert(state != NULL);
|
||||
ble_npl_callout_reset(&level_temp_work, 0);
|
||||
ble_npl_callout_reset(&level_temp_transition_timer, K_MSEC(state->cal_tt));
|
||||
}
|
||||
|
||||
static void light_lightness_actual_tt_handler(struct ble_npl_event *ev)
|
||||
{
|
||||
struct light_lightness_state *state = ble_npl_event_get_arg(ev);
|
||||
|
||||
assert(state != NULL);
|
||||
ble_npl_callout_reset(&light_lightness_actual_work, 0);
|
||||
ble_npl_callout_reset(&light_lightness_actual_transition_timer, K_MSEC(state->cal_tt));
|
||||
}
|
||||
|
||||
static void light_lightness_linear_tt_handler(struct ble_npl_event *ev)
|
||||
{
|
||||
struct light_lightness_state *state = ble_npl_event_get_arg(ev);
|
||||
|
||||
assert(state != NULL);
|
||||
ble_npl_callout_reset(&light_lightness_linear_work, 0);
|
||||
ble_npl_callout_reset(&light_lightness_linear_transition_timer, K_MSEC(state->cal_tt));
|
||||
}
|
||||
|
||||
static void light_ctl_tt_handler(struct ble_npl_event *ev)
|
||||
{
|
||||
struct light_ctl_state *state = ble_npl_event_get_arg(ev);
|
||||
|
||||
assert(state != NULL);
|
||||
ble_npl_callout_reset(&light_ctl_work, 0);
|
||||
ble_npl_callout_reset(&light_ctl_transition_timer, K_MSEC(state->cal_tt));
|
||||
}
|
||||
|
||||
static void light_ctl_temp_tt_handler(struct ble_npl_event *ev)
|
||||
{
|
||||
struct light_ctl_state *state = ble_npl_event_get_arg(ev);
|
||||
|
||||
assert(state != NULL);
|
||||
ble_npl_callout_reset(&light_ctl_temp_work, 0);
|
||||
ble_npl_callout_reset(&light_ctl_temp_transition_timer, K_MSEC(state->cal_tt));
|
||||
}
|
||||
/* Timers related handlers & threads (End) */
|
||||
|
||||
/* Messages handlers (Start) */
|
||||
void onoff_handler(struct generic_onoff_state *state)
|
||||
{
|
||||
enable_transition = ONOFF_TT;
|
||||
|
||||
ble_npl_callout_set_arg(&onoff_transition_timer, state);
|
||||
ble_npl_callout_reset(&onoff_transition_timer, K_MSEC(5 * state->delay));
|
||||
}
|
||||
|
||||
void level_lightness_handler(struct generic_level_state *state)
|
||||
{
|
||||
ble_npl_callout_set_arg(&level_lightness_transition_timer, state);
|
||||
ble_npl_callout_reset(&level_lightness_transition_timer,
|
||||
K_MSEC(5 * state->delay));
|
||||
}
|
||||
|
||||
void level_temp_handler(struct generic_level_state *state)
|
||||
{
|
||||
ble_npl_callout_set_arg(&level_temp_transition_timer, state);
|
||||
ble_npl_callout_reset(&level_temp_transition_timer, K_MSEC(5 * state->delay));
|
||||
}
|
||||
|
||||
void light_lightness_actual_handler(struct light_lightness_state *state)
|
||||
{
|
||||
enable_transition = LIGTH_LIGHTNESS_ACTUAL_TT;
|
||||
|
||||
ble_npl_callout_set_arg(&light_lightness_actual_transition_timer, state);
|
||||
ble_npl_callout_reset(&light_lightness_actual_transition_timer,
|
||||
K_MSEC(5 * state->delay));
|
||||
}
|
||||
|
||||
void light_lightness_linear_handler(struct light_lightness_state *state)
|
||||
{
|
||||
enable_transition = LIGTH_LIGHTNESS_LINEAR_TT;
|
||||
|
||||
ble_npl_callout_set_arg(&light_lightness_linear_transition_timer, state);
|
||||
ble_npl_callout_reset(&light_lightness_linear_transition_timer,
|
||||
K_MSEC(5 * state->delay));
|
||||
}
|
||||
|
||||
void light_ctl_handler(struct light_ctl_state *state)
|
||||
{
|
||||
enable_transition = LIGTH_CTL_TT;
|
||||
|
||||
ble_npl_callout_set_arg(&light_ctl_transition_timer, state);
|
||||
ble_npl_callout_reset(&light_ctl_transition_timer, K_MSEC(5 * state->delay));
|
||||
}
|
||||
|
||||
void light_ctl_temp_handler(struct light_ctl_state *state)
|
||||
{
|
||||
enable_transition = LIGHT_CTL_TEMP_TT;
|
||||
|
||||
ble_npl_callout_set_arg(&light_ctl_temp_transition_timer, state);
|
||||
ble_npl_callout_reset(&light_ctl_temp_transition_timer,
|
||||
K_MSEC(5 * state->delay));
|
||||
}
|
||||
/* Messages handlers (End) */
|
||||
|
||||
void transition_timers_init(void)
|
||||
{
|
||||
ble_npl_callout_init(&onoff_work, ble_npl_eventq_dflt_get(),
|
||||
onoff_work_handler, NULL);
|
||||
|
||||
ble_npl_callout_init(&level_lightness_work, ble_npl_eventq_dflt_get(),
|
||||
level_lightness_work_handler, NULL);
|
||||
ble_npl_callout_init(&level_temp_work, ble_npl_eventq_dflt_get(),
|
||||
level_temp_work_handler, NULL);
|
||||
|
||||
ble_npl_callout_init(&light_lightness_actual_work, ble_npl_eventq_dflt_get(),
|
||||
light_lightness_actual_work_handler, NULL);
|
||||
ble_npl_callout_init(&light_lightness_linear_work, ble_npl_eventq_dflt_get(),
|
||||
light_lightness_linear_work_handler, NULL);
|
||||
|
||||
ble_npl_callout_init(&light_ctl_work, ble_npl_eventq_dflt_get(),
|
||||
light_ctl_work_handler, NULL);
|
||||
ble_npl_callout_init(&light_ctl_temp_work, ble_npl_eventq_dflt_get(),
|
||||
light_ctl_temp_work_handler, NULL);
|
||||
|
||||
ble_npl_callout_init(&onoff_transition_timer, ble_npl_eventq_dflt_get(),
|
||||
onoff_tt_handler, NULL);
|
||||
|
||||
ble_npl_callout_init(&level_lightness_transition_timer, ble_npl_eventq_dflt_get(),
|
||||
level_lightness_tt_handler, NULL);
|
||||
ble_npl_callout_init(&level_temp_transition_timer, ble_npl_eventq_dflt_get(),
|
||||
level_temp_tt_handler, NULL);
|
||||
|
||||
ble_npl_callout_init(&light_lightness_actual_transition_timer, ble_npl_eventq_dflt_get(),
|
||||
light_lightness_actual_tt_handler, NULL);
|
||||
ble_npl_callout_init(&light_lightness_linear_transition_timer, ble_npl_eventq_dflt_get(),
|
||||
light_lightness_linear_tt_handler, NULL);
|
||||
|
||||
ble_npl_callout_init(&light_ctl_transition_timer, ble_npl_eventq_dflt_get(),
|
||||
light_ctl_tt_handler, NULL);
|
||||
ble_npl_callout_init(&light_ctl_temp_transition_timer, ble_npl_eventq_dflt_get(),
|
||||
light_ctl_temp_tt_handler, NULL);
|
||||
|
||||
ble_npl_callout_init(&light_ctl_temp_transition_timer, ble_npl_eventq_dflt_get(),
|
||||
light_ctl_temp_tt_handler, NULL);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _TRANSITION_H
|
||||
#define _TRANSITION_H
|
||||
|
||||
#define DEVICE_SPECIFIC_RESOLUTION 10
|
||||
|
||||
enum transition_time {
|
||||
DISABLE_TRANSITION = 0x00,
|
||||
ONOFF_TT = 0x01,
|
||||
LEVEL_TT,
|
||||
LEVEL_TT_DELTA,
|
||||
LEVEL_TT_MOVE,
|
||||
LIGTH_LIGHTNESS_ACTUAL_TT,
|
||||
LIGTH_LIGHTNESS_LINEAR_TT,
|
||||
LIGTH_CTL_TT,
|
||||
LEVEL_TEMP_TT,
|
||||
LEVEL_TEMP_TT_DELTA,
|
||||
LEVEL_TEMP_TT_MOVE,
|
||||
LIGHT_CTL_TEMP_TT
|
||||
};
|
||||
|
||||
extern u8_t enable_transition;
|
||||
extern u8_t default_tt;
|
||||
|
||||
extern struct ble_npl_callout onoff_transition_timer;
|
||||
extern struct ble_npl_callout level_lightness_transition_timer;
|
||||
extern struct ble_npl_callout level_temp_transition_timer;
|
||||
extern struct ble_npl_callout light_lightness_actual_transition_timer;
|
||||
extern struct ble_npl_callout light_lightness_linear_transition_timer;
|
||||
extern struct ble_npl_callout light_ctl_transition_timer;
|
||||
extern struct ble_npl_callout light_ctl_temp_transition_timer;
|
||||
|
||||
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);
|
||||
void light_ctl_temp_tt_values(struct light_ctl_state *state);
|
||||
|
||||
void onoff_handler(struct generic_onoff_state *state);
|
||||
void level_lightness_handler(struct generic_level_state *state);
|
||||
void level_temp_handler(struct generic_level_state *state);
|
||||
void light_lightness_actual_handler(struct light_lightness_state *state);
|
||||
void light_lightness_linear_handler(struct light_lightness_state *state);
|
||||
void light_ctl_handler(struct light_ctl_state *state);
|
||||
void light_ctl_temp_handler(struct light_ctl_state *state);
|
||||
|
||||
void transition_timers_init(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
# Package: apps/blemesh
|
||||
|
||||
syscfg.vals:
|
||||
# Set log level to info (disable debug logging).
|
||||
LOG_LEVEL: 1
|
||||
|
||||
# Default task settings
|
||||
OS_MAIN_STACK_SIZE: 768
|
||||
|
||||
# Newtmgr is not supported in this app, so disable newtmgr-over-shell.
|
||||
SHELL_NEWTMGR: 0
|
||||
|
||||
MSYS_1_BLOCK_COUNT: 48
|
||||
|
||||
FLOAT_USER: 1
|
||||
HARD_FLOAT: 1
|
||||
|
||||
BLE_MESH_ADV_BUF_COUNT: 20
|
||||
BLE_MESH_TX_SEG_MAX: 9
|
||||
|
||||
BLE_MESH: 1
|
||||
BLE_MESH_CFG_CLI: 1
|
||||
BLE_MESH_DEV_UUID: "((uint8_t[16]){0xdd, 0xdd, 0})"
|
||||
BLE_MESH_SETTINGS: 0
|
||||
CONFIG_NFFS: 0
|
||||
|
||||
BLE_MESH_DEBUG: 0
|
||||
BLE_MESH_DEBUG_NET: 0
|
||||
BLE_MESH_DEBUG_TRANS: 0
|
||||
BLE_MESH_DEBUG_BEACON: 0
|
||||
BLE_MESH_DEBUG_CRYPTO: 0
|
||||
BLE_MESH_DEBUG_PROV: 0
|
||||
BLE_MESH_DEBUG_ACCESS: 0
|
||||
BLE_MESH_DEBUG_MODEL: 0
|
||||
BLE_MESH_DEBUG_ADV: 0
|
||||
BLE_MESH_DEBUG_LOW_POWER: 0
|
||||
BLE_MESH_DEBUG_FRIEND: 0
|
||||
BLE_MESH_DEBUG_PROXY: 0
|
||||
Reference in New Issue
Block a user