1 /* AliGenie - Example
2 
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4 
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9 
10 #include <stdio.h>
11 
12 #include "driver/gpio.h"
13 #include "esp_log.h"
14 
15 #include "iot_button.h"
16 #include "light_driver.h"
17 
18 #include "genie_event.h"
19 
20 #define BUTTON_ON_OFF          0   /* on/off button */
21 #define BUTTON_ACTIVE_LEVEL    0
22 
23 static const char *TAG  = "board";
24 
25 static uint32_t dev_on_btn_num = BUTTON_ON_OFF;
26 
27 extern void user_genie_event_handle(genie_event_t event, void *p_arg);
28 
button_tap_cb(void * arg)29 void button_tap_cb(void* arg)
30 {
31     user_genie_event_handle(GENIE_EVT_BUTTON_TAP, NULL);
32 }
33 
board_led_init(void)34 static void board_led_init(void)
35 {
36     /**
37      * NOTE:
38      *  If the module has SPI flash, GPIOs 6-11 are connected to the module’s integrated SPI flash and PSRAM.
39      *  If the module has PSRAM, GPIOs 16 and 17 are connected to the module’s integrated PSRAM.
40      */
41     light_driver_config_t driver_config = {
42         .gpio_red        = CONFIG_LIGHT_GPIO_RED,
43         .gpio_green      = CONFIG_LIGHT_GPIO_GREEN,
44         .gpio_blue       = CONFIG_LIGHT_GPIO_BLUE,
45         .gpio_cold       = CONFIG_LIGHT_GPIO_COLD,
46         .gpio_warm       = CONFIG_LIGHT_GPIO_WARM,
47         .fade_period_ms  = CONFIG_LIGHT_FADE_PERIOD_MS,
48         .blink_period_ms = CONFIG_LIGHT_BLINK_PERIOD_MS,
49     };
50 
51     /**
52      * @brief Light driver initialization
53      */
54     ESP_ERROR_CHECK(light_driver_init(&driver_config));
55     light_driver_set_mode(MODE_HSL);
56     // light_driver_set_switch(true);
57 
58     button_handle_t dev_on_off_btn = iot_button_create(BUTTON_ON_OFF, BUTTON_ACTIVE_LEVEL);
59     iot_button_set_evt_cb(dev_on_off_btn, BUTTON_CB_TAP, button_tap_cb, &dev_on_btn_num);
60 }
61 
board_init(void)62 void board_init(void)
63 {
64     board_led_init();
65 }
66 
67 /**
68  * hsl
69  */
board_led_hsl(uint8_t elem_index,uint16_t hue,uint16_t saturation,uint16_t lightness)70 void board_led_hsl(uint8_t elem_index, uint16_t hue, uint16_t saturation, uint16_t lightness)
71 {
72     static uint16_t last_hue        = 0xFFFF;
73     static uint16_t last_saturation = 0xFFFF;
74     static uint16_t last_lightness  = 0xFFFF;
75 
76     ESP_LOGD(TAG, "hue last state %d, state %d", last_hue, hue);
77     ESP_LOGD(TAG, "saturation last state %d, state %d", last_saturation, saturation);
78     ESP_LOGD(TAG, "lightness last state %d, state %d", last_lightness, lightness);
79 
80     if(last_hue != hue || last_saturation != saturation || last_lightness != lightness ) {
81         last_hue        = hue;
82         last_saturation = saturation;
83         last_lightness  = lightness;
84 
85         uint16_t actual_hue        = (float)last_hue / (UINT16_MAX / 360.0);
86         uint8_t  actual_saturation = (float)last_saturation / (UINT16_MAX / 100.0);
87         uint8_t  actual_lightness  = (float)last_lightness / (UINT16_MAX / 100.0);
88 
89         ESP_LOGD(TAG, "hsl: %d, %d, %d operation", actual_hue, actual_saturation, actual_lightness);
90         light_driver_set_hsl(actual_hue, actual_saturation, actual_lightness);
91     }
92 }
93 
94 /**
95  * temperature light temp
96  */
board_led_temperature(uint8_t elem_index,uint16_t temperature)97 void board_led_temperature(uint8_t elem_index, uint16_t temperature)
98 {
99     static uint16_t last_temperature = 0xFFFF;
100 
101     ESP_LOGD(TAG, "temperature last state %d, state %d", last_temperature, temperature);
102 
103     if(last_temperature != temperature) {
104         last_temperature = temperature;
105 
106         uint16_t actual_temperature = (float)last_temperature / (UINT16_MAX / 100.0);
107         ESP_LOGD(TAG, "temperature %d %%%d operation", last_temperature, actual_temperature);
108         light_driver_set_color_temperature(actual_temperature);
109     }
110 }
111 
112 /**
113  * actual lightness
114  */
board_led_lightness(uint8_t elem_index,uint16_t actual)115 void board_led_lightness(uint8_t elem_index, uint16_t actual)
116 {
117     static uint16_t last_acual = 0xFFFF;
118 
119     ESP_LOGD(TAG, "actual last state %d, state %d", last_acual, actual);
120 
121     if(last_acual != actual) {
122         last_acual = actual;
123 
124         uint16_t actual_lightness = (float)last_acual / (UINT16_MAX / 100.0);
125         ESP_LOGD(TAG, "lightness %d %%%d operation", last_acual, actual_lightness);
126         light_driver_set_lightness(actual_lightness);
127     }
128 }
129 
130 /**
131  * onoff on/off
132  */
board_led_switch(uint8_t elem_index,uint8_t onoff)133 void board_led_switch(uint8_t elem_index, uint8_t onoff)
134 {
135     static uint8_t last_onoff = 0xFF;
136 
137     ESP_LOGD(TAG, "onoff last state %d, state %d", last_onoff, onoff);
138     if(last_onoff != onoff) {
139         last_onoff = onoff;
140         if (last_onoff) {
141             ESP_LOGD(TAG, "onoff %d operation", last_onoff);
142             light_driver_set_switch(true);
143         } else {
144             ESP_LOGD(TAG, "onoff %d operation", last_onoff);
145             light_driver_set_switch(false);
146         }
147     }
148 }
149 
150 #define MINDIFF (2.25e-308)
151 
bt_mesh_sqrt(float square)152 static float bt_mesh_sqrt(float square)
153 {
154     float root, last, diff;
155 
156     root = square / 3.0;
157     diff = 1;
158 
159     if (square <= 0) {
160         return 0;
161     }
162 
163     do {
164         last = root;
165         root = (root + square / root) / 2.0;
166         diff = root - last;
167     } while (diff > MINDIFF || diff < -MINDIFF);
168 
169     return root;
170 }
171 
bt_mesh_ceiling(float num)172 static int32_t bt_mesh_ceiling(float num)
173 {
174     int32_t inum = (int32_t)num;
175     if (num == (float)inum) {
176         return inum;
177     }
178     return inum + 1;
179 }
180 
convert_lightness_actual_to_linear(uint16_t actual)181 uint16_t convert_lightness_actual_to_linear(uint16_t actual)
182 {
183     float tmp = ((float) actual / UINT16_MAX);
184     return bt_mesh_ceiling(UINT16_MAX * tmp * tmp);
185 }
186 
convert_lightness_linear_to_actual(uint16_t linear)187 uint16_t convert_lightness_linear_to_actual(uint16_t linear)
188 {
189     return (uint16_t)(UINT16_MAX * bt_mesh_sqrt(((float) linear / UINT16_MAX)));
190 }
191 
convert_temperature_to_level(uint16_t temp,uint16_t min,uint16_t max)192 int16_t convert_temperature_to_level(uint16_t temp, uint16_t min, uint16_t max)
193 {
194     float tmp = (temp - min) * UINT16_MAX / (max - min);
195     return (int16_t) (tmp + INT16_MIN);
196 }
197 
covert_level_to_temperature(int16_t level,uint16_t min,uint16_t max)198 uint16_t covert_level_to_temperature(int16_t level, uint16_t min, uint16_t max)
199 {
200     float diff = (float) (max - min) / UINT16_MAX;
201     uint16_t tmp = (uint16_t) ((level - INT16_MIN) * diff);
202     return (uint16_t) (min + tmp);
203 }
204 
205 /* swap octets */
swap_buf(uint8_t * dst,const uint8_t * src,int len)206 void swap_buf(uint8_t *dst, const uint8_t *src, int len)
207 {
208     int i;
209 
210     for (i = 0; i < len; i++) {
211         dst[len - 1 - i] = src[i];
212     }
213 }
214 
mac_str2hex(const char * mac_str,uint8_t * mac_hex)215 uint8_t *mac_str2hex(const char *mac_str, uint8_t *mac_hex)
216 {
217     uint32_t mac_data[6] = {0};
218 
219     sscanf(mac_str, "%02x%02x%02x%02x%02x%02x",
220            mac_data, mac_data + 1, mac_data + 2, mac_data + 3, mac_data + 4, mac_data + 5);
221 
222     for (int i = 0; i < 6; i++) {
223         mac_hex[i] = mac_data[i];
224     }
225 
226     return mac_hex;
227 }
228