1 /*
2 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <ctype.h>
8 //#include <aos/aos.h>
9 #include <aos/kernel.h>
10
11 #include <misc/printk.h>
12 #include <misc/byteorder.h>
13 //#include <hal/soc/gpio.h>
14 //#include <hal/soc/pwm.h>
15
16 #include <bluetooth/bluetooth.h>
17 //#include <soc.h>
18 #include <api/mesh.h>
19 #include "common/log.h"
20 #include "genie_service.h"
21
22 #ifdef CONFIG_MESH_MODEL_TRANS
sig_model_transition_timer_stop(sig_model_element_state_t * p_elem)23 void sig_model_transition_timer_stop(sig_model_element_state_t *p_elem)
24 {
25 k_timer_stop(&p_elem->state.delay_timer);
26 k_timer_stop(&p_elem->state.trans_timer);
27 }
28
sig_model_transition_state_reset(sig_model_element_state_t * p_elem)29 void sig_model_transition_state_reset(sig_model_element_state_t *p_elem)
30 {
31 p_elem->state.trans = 0;
32 p_elem->state.trans_start_time = 0;
33 p_elem->state.trans_end_time = 0;
34 }
35
36 #define DELTA_ACTUAL_MIN 655
37 #define DELTA_TEMP_MIN 192
38
sig_model_transition_update(sig_model_element_state_t * p_elem)39 uint8_t sig_model_transition_update(sig_model_element_state_t *p_elem)
40 {
41 uint8_t cycle = 0;
42 uint16_t delta = 0;
43 bt_u32_t cur_time = k_uptime_get();
44 sig_model_state_t *p_state = &p_elem->state;
45
46 //stop cycle when timeout
47 if (cur_time <= p_state->trans_end_time - SIG_MODEL_TRANSITION_INTERVAL)
48 {
49 #if defined(CONFIG_MESH_MODEL_LIGHTNESS_SRV) || defined(CONFIG_MESH_MODEL_CTL_SRV)
50 uint16_t step = (p_state->trans_end_time - cur_time) / SIG_MODEL_TRANSITION_INTERVAL;
51 #endif
52
53 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
54 if (p_state->onoff[TYPE_PRESENT] != p_state->onoff[TYPE_TARGET])
55 {
56 p_state->onoff[TYPE_PRESENT] = p_state->onoff[TYPE_TARGET];
57 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_ONOFF);
58 }
59 #endif
60
61 #ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
62 if (p_state->lightness[TYPE_PRESENT] != p_state->lightness[TYPE_TARGET])
63 {
64 if (p_state->lightness[TYPE_TARGET] > p_state->lightness[TYPE_PRESENT])
65 {
66 delta = (p_state->lightness[TYPE_TARGET] - p_state->lightness[TYPE_PRESENT]) / step;
67 delta = delta > DELTA_ACTUAL_MIN ? delta : DELTA_ACTUAL_MIN;
68 if (LIGHTNESS_MAX_VALUE - p_state->lightness[TYPE_PRESENT] < delta ||
69 p_state->lightness[TYPE_TARGET] - p_state->lightness[TYPE_PRESENT] < delta)
70 {
71 p_state->lightness[TYPE_PRESENT] = p_state->lightness[TYPE_TARGET];
72 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_LIGHTNESS);
73 }
74 else
75 {
76 p_state->lightness[TYPE_PRESENT] += delta;
77 if (p_state->lightness[TYPE_PRESENT] == p_state->lightness[TYPE_TARGET])
78 {
79 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_LIGHTNESS);
80 }
81 }
82 }
83 else
84 {
85 delta = (p_state->lightness[TYPE_PRESENT] - p_state->lightness[TYPE_TARGET]) / step;
86 delta = delta > DELTA_ACTUAL_MIN ? delta : DELTA_ACTUAL_MIN;
87 if (p_state->lightness[TYPE_PRESENT] < delta ||
88 p_state->lightness[TYPE_PRESENT] - delta < p_state->lightness[TYPE_TARGET])
89 {
90 p_state->lightness[TYPE_PRESENT] = p_state->lightness[TYPE_TARGET];
91 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_LIGHTNESS);
92 }
93 else
94 {
95 p_state->lightness[TYPE_PRESENT] -= delta;
96 if (p_state->lightness[TYPE_PRESENT] == p_state->lightness[TYPE_TARGET])
97 {
98 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_LIGHTNESS);
99 }
100 }
101 }
102 cycle = 1;
103 }
104 #endif
105 #ifdef CONFIG_MESH_MODEL_CTL_SRV
106 if (p_state->color_temperature[TYPE_PRESENT] != p_state->color_temperature[TYPE_TARGET])
107 {
108 if (p_state->color_temperature[TYPE_TARGET] > p_state->color_temperature[TYPE_PRESENT])
109 {
110 delta = (p_state->color_temperature[TYPE_TARGET] - p_state->color_temperature[TYPE_PRESENT]) / step;
111 delta = delta > DELTA_TEMP_MIN ? delta : DELTA_TEMP_MIN;
112 if (COLOR_TEMPERATURE_MAX - p_state->color_temperature[TYPE_PRESENT] < delta ||
113 p_state->color_temperature[TYPE_TARGET] - p_state->color_temperature[TYPE_PRESENT] < delta)
114 {
115 p_state->color_temperature[TYPE_PRESENT] = p_state->color_temperature[TYPE_TARGET];
116 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_CTL);
117 }
118 else
119 {
120 p_state->color_temperature[TYPE_PRESENT] += delta;
121 if (p_state->color_temperature[TYPE_PRESENT] == p_state->color_temperature[TYPE_TARGET])
122 {
123 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_CTL);
124 }
125 }
126 delta += p_state->color_temperature[TYPE_PRESENT];
127 p_state->color_temperature[TYPE_PRESENT] = delta > p_state->color_temperature[TYPE_TARGET] ? p_state->color_temperature[TYPE_TARGET] : delta;
128 }
129 else
130 {
131 delta = (p_state->color_temperature[TYPE_PRESENT] - p_state->color_temperature[TYPE_TARGET]) / step;
132 delta = delta > DELTA_TEMP_MIN ? delta : DELTA_TEMP_MIN;
133 if (p_state->color_temperature[TYPE_PRESENT] < delta + COLOR_TEMPERATURE_MIN ||
134 p_state->color_temperature[TYPE_PRESENT] - delta < p_state->color_temperature[TYPE_TARGET])
135 {
136 p_state->color_temperature[TYPE_PRESENT] = p_state->color_temperature[TYPE_TARGET];
137 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_CTL);
138 }
139 else
140 {
141 p_state->color_temperature[TYPE_PRESENT] -= delta;
142 if (p_state->color_temperature[TYPE_PRESENT] == p_state->color_temperature[TYPE_TARGET])
143 {
144 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_CTL);
145 }
146 }
147 }
148 cycle = 1;
149 }
150 #endif
151 }
152 #if 0
153 printf("next: %d->%d|%02x->%02x|%02x->%02x\n", p_state->onoff[TYPE_PRESENT], p_state->onoff[TYPE_TARGET],
154 p_state->lightness[TYPE_PRESENT], p_state->lightness[TYPE_TARGET], p_state->color_temperature[TYPE_PRESENT], p_state->color_temperature[TYPE_TARGET]);
155 #endif
156 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
157 if (p_state->onoff[TYPE_PRESENT] == p_state->onoff[TYPE_TARGET])
158 #endif
159 #ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
160 if (p_state->lightness[TYPE_PRESENT] == p_state->lightness[TYPE_TARGET])
161 #endif
162 #ifdef CONFIG_MESH_MODEL_CTL_SRV
163 if (p_state->color_temperature[TYPE_PRESENT] == p_state->color_temperature[TYPE_TARGET])
164 #endif
165 cycle = 0;
166
167 //BT_DBG("cycle %d", cycle);
168 if (cycle == 0)
169 {
170 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
171 #ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
172 if (p_state->lightness[TYPE_TARGET] == 0)
173 {
174 p_state->onoff[TYPE_TARGET] = 0;
175 }
176 #endif
177 if (p_state->onoff[TYPE_PRESENT] != p_state->onoff[TYPE_TARGET])
178 {
179 p_state->onoff[TYPE_PRESENT] = p_state->onoff[TYPE_TARGET];
180 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_ONOFF);
181 }
182 //BT_DBG("onoff %d->%d", p_state->onoff[TYPE_PRESENT], p_state->onoff[TYPE_TARGET]);
183 #endif
184 #ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
185 if (p_state->lightness[TYPE_PRESENT] != p_state->lightness[TYPE_TARGET])
186 {
187 p_state->lightness[TYPE_PRESENT] = p_state->lightness[TYPE_TARGET];
188 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_LIGHTNESS);
189 }
190 //BT_DBG("lightness %02x->%02x", p_state->lightness[TYPE_PRESENT], p_state->lightness[TYPE_TARGET]);
191 #endif
192 #ifdef CONFIG_MESH_MODEL_CTL_SRV
193 if (p_state->color_temperature[TYPE_PRESENT] != p_state->color_temperature[TYPE_TARGET])
194 {
195 p_state->color_temperature[TYPE_PRESENT] = p_state->color_temperature[TYPE_TARGET];
196 sig_model_event_set_indicate(SIG_MODEL_INDICATE_GEN_CTL);
197 }
198 //BT_DBG("color_temperature %02x->%02x", p_state->color_temperature[TYPE_PRESENT], p_state->color_temperature[TYPE_TARGET]);
199 #endif
200 p_state->trans = 0;
201 }
202
203 return cycle;
204 }
205 #endif
206
207 #ifdef CONFIG_MESH_MODEL_TRANS
208 bt_u32_t TRANS_TIMES[] = {TRANSITION_TIME_UNIT_1, TRANSITION_TIME_UNIT_2, TRANSITION_TIME_UNIT_3, TRANSITION_TIME_UNIT_4};
209
_get_transition_byte(bt_u32_t time)210 static uint8_t _get_transition_byte(bt_u32_t time)
211 {
212 if (time > TRANS_TIMES[3] * TRANSITION_TIME_VALUE_MAX)
213 {
214 return 0;
215 }
216 else if (time > TRANS_TIMES[2] * TRANSITION_TIME_VALUE_MAX)
217 {
218 return (time / TRANS_TIMES[3]) | TRANSITION_TIME_UNIT_BIT(3);
219 }
220 else if (time > TRANS_TIMES[1] * TRANSITION_TIME_VALUE_MAX)
221 {
222 return (time / TRANS_TIMES[2]) | TRANSITION_TIME_UNIT_BIT(2);
223 }
224 else if (time > TRANS_TIMES[0] * TRANSITION_TIME_VALUE_MAX)
225 {
226 return (time / TRANS_TIMES[1]) | TRANSITION_TIME_UNIT_BIT(1);
227 }
228 else
229 {
230 return (time / TRANS_TIMES[0]);
231 }
232 }
233
234 //unit is 1ms
sig_model_transition_get_transition_time(uint8_t byte)235 bt_u32_t sig_model_transition_get_transition_time(uint8_t byte)
236 {
237 if ((byte & TRANSITION_TIME_VALUE_MASK) == TRANSITION_TIME_VALUE_INVALID)
238 {
239 MODEL_E("%s ERROR, invalid 0x%02X!!!\n", __func__, byte);
240 return TRANSITION_TIME_VALUE_INVALID;
241 }
242
243 return (byte & TRANSITION_TIME_VALUE_MASK) * TRANS_TIMES[byte >> 6];
244 }
245
sig_model_transition_get_remain_time_byte(sig_model_state_t * p_state,bool is_ack)246 uint8_t sig_model_transition_get_remain_time_byte(sig_model_state_t *p_state, bool is_ack)
247 {
248 uint8_t remain_time_byte = p_state->trans;
249 int64_t cur_time = k_uptime_get();
250 int64_t passed_time = 0;
251 bt_u32_t trans_duration = 0;
252
253 if (!is_ack && p_state->trans_start_time < cur_time)
254 {
255 passed_time -= p_state->trans_start_time;
256 trans_duration = sig_model_transition_get_transition_time(p_state->trans);
257
258 if (trans_duration > passed_time)
259 {
260 remain_time_byte = _get_transition_byte(trans_duration - passed_time);
261 }
262 else
263 {
264 remain_time_byte = TRANSITION_TIME_VALUE_MIN;
265 }
266 }
267
268 return remain_time_byte;
269 }
270 #endif
271