-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzha_constants.h
414 lines (378 loc) · 9.71 KB
/
zha_constants.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
#include <stdint.h>
#include <EEPROM.h>
#include <XBee.h>
// Used to keep SRAM down
#define ZCL_HDR_LEN 6
// Device Type
constexpr uint8_t MAINS_PWR_DEV = 0x8c;
// Frame Control
#define FRAME_CTRL_GLBL 0b00011000
#define FRAME_CTRL_CLSTR 0b01011000
#define UKN_NET_ADDR 0xFFFE
// #define HA_PROFILE_ID 0x0104
constexpr uint16_t HA_PROFILE_ID = 0x0104;
#define COORDINATOR_NWK 0x0000
#define MATCH_DESC_RQST 0x0006
#define MATCH_DESC_RSP 0x8006
#define SIMPLE_DESC_RSP 0x8004
#define ACTIVE_EP_RSP 0x8005
#define ACTIVE_EP_RQST 0x0005
#define SIMPLE_DESC_RQST 0x0004
#define IEEE_ADDR_RESP_CMD 0x8001
#define NODE_DESC_RESP_CMD 0x8002
#define DEV_ANN_CMD 0x0013
#define READ_ATTRIBUTES 0x00
#define READ_ATTRIBUTES_RESP 0x01
#define DEF_RESP 0x0B
#define WRITE_ATTRIBUTES 0x02
#define REPORT_ATTRIBUTES 0x0a
#define WRITE_ATTR_RESP 0x04
#define READ_RPT_CFG 0x08
#define READ_RPT_CFG_RESP 0x09
#define CFG_RPT 0x06
#define CFG_RPT_RESP 0x07
// Command resp
#define ATTR_RSP_CMD 0x0b
// Input Clusters
#define BASIC_CLUSTER_ID 0x0000 // server
#define IDENTIFY_CLUSTER_ID 0x0003
#define GROUPS_CLUSTER_ID 0x0004 // server
#define SCENES_CLUSTER_ID 0x0005 // server
#define ON_OFF_CLUSTER_ID 0x0006 // server
#define ON_OF_SWITCH_CLUSTER_ID 0x0007 // server
#define LEVEL_CONTROL_CLUSTER_ID 0x0008 // server
#define LIGHT_LINK_CLUSTER_ID 0x1000
#define TEMP_CLUSTER_ID 0x0402 // server
#define HUMIDITY_CLUSTER_ID 0x405 // server
#define BINARY_INPUT_CLUSTER_ID 0x000f // server
#define IAS_ZONE_CLUSTER_ID 0x0500 // server
#define METERING_CLUSTER_ID 0x0702 // Smart Energy Metering //server
#define COLOR_CLUSTER_ID 0x0300 // server
#define ELECTRICAL_MEASUREMENT 0x0b04 // server
#define ANALOG_IN_CLUSTER_ID 0x000c // server
#define ANALOG_OUT_CLUSTER_ID 0x000d // server
#define MULTISTATE_IN_CLUSTER_ID 0x0012 // server
// Attr id
#define INSTANTANEOUS_DEMAND 0x0400
#define MEASUREMENT_TYPE 0x0000
#define MANUFACTURER_ATTR 0x0004
#define MODEL_ATTR 0x0005
#define BINARY_PV_ATTR 0x0055 // Should rename
#define BINARY_STATUS_FLG 0x006F
#define CURRENT_STATE 0x0000
#define IAS_ZONE_STATE 0x0000
#define IAS_ZONE_TYPE 0x0001
#define IAS_ZONE_STATUS 0x0002
#define OUT_OF_SERVICE 0x0051
#define RESOLUTION_ATTR 0x006A
#define ENG_UNITS_ATTR 0x0075
#define DESCRIPTION_ATTR 0x001C
#define MAX_PV_ATTR 0x0041
#define MIN_PV_ATTR 0x0045
#define NUM_OF_STATES 0x004A
#define DESCRIPTION_ATTR 0x001C
#define STATE_TEXT_ATTR 0x000E
// Energy
#define ACTIVE_POWER_ATTR 0x050b // int16
#define REACTIVE_POWER_ATTR 0x050e // int16
#define APPARENT_POWER_ATTR 0x050f // uint16
#define POWER_FACTOR_ATTR 0x0510 // int8
#define AC_FREQUENCY_ATTR 0x0300 // uint16
#define RMS_VOLTAGE_ATTR 0x0505 // uint16
#define RMS_CURRENT_ATTR 0x0508 // uint16
// Energy MinMax
#define ACTIVE_POWER_MIN 0x050c
#define ACTIVE_POWER_MAX 0x050d
#define AC_FREQUENCY_MAX 0x0302
#define RMS_VOLTAGE_MAX 0x0507
// Energy scaling
#define AC_FREQUENCY_MULTIPLIER 0x0400 // uint16
#define AC_FREQUENCY_DIVISOR 0x0401 // uint16
#define POWER_MULTIPLIER 0x0402 // uint32
#define POWER_DIVISOR 0x0403 // uint32
#define AC_VOLTAGE_MULTIPLIER 0x0600 // uint16
#define AC_VOLTAGE_DIVISOR 0x0601 // uint16
#define AC_CURRENT_MULTIPLIER 0x0602 // uint16
#define AC_CURRENT_DIVISOR 0x0603 // uint16
#define AC_POWER_MULTIPLIER 0x0604 // uint16
#define AC_POWER_DIVISOR 0x0605 // uint16
// Output
#define OTA_CLUSTER_ID 0x0019 // Upgrade
// Data Types
#define ZCL_INT8_T 0x28
#define ZCL_INT16_T 0x29 // Signed Analog
#define ZCL_CHAR_STR 0x42
#define ZCL_UINT8_T 0x20
#define ZCL_UINT16_T 0x21
#define ZCL_BOOL 0x10
#define ZCL_ENUM8 0x30
#define ZCL_ENUM16 0x31
#define ZCL_MAP8 0x18
#define ZCL_MAP16 0x19
#define ZCL_MAP32 0x1b
#define ZCL_SINGLE 0x39
#define ZCL_ARRAY 0x48 // Length 2+sum of length of contents , first element is 2byte uint for num elements
// Device
#define ON_OFF_LIGHT 0x0100
#define DIMMABLE_LIGHT 0x0101
#define COLOR_LIGHT 0x0102
#define TEMPERATURE_SENSOR 0x0302
#define ON_OFF_OUTPUT 0x0002
#define IAS_ZONE 0x0402
#define ON_OFF_SENSOR 0x0850
#define COMBINED_INTERFACE 0x0007
// Attributes
#define ATTR_CURRENT_X 0x0003
#define ATTR_CURRENT_Y 0x0004
#define ATTR_CURRENT_CT_MRDS 0x0006
#define ATTR_COLOR_CAP 0x400A
#define ATTR_COLOR_MODE 0x0008
#define ATTR_COLOR_OPT 0x000F
#define ATTR_ENH_COLOR_MODE 0x4001
// Define Steps
#define START 0
#define ASSOCIATE 1
#define NWK 2
#define CFG_CMP 3
#define DEV_ANN 4
#define READY 5
// Attribute Write Responses
#define CMD_SUCCESS 0x00
#define CMD_FAILURE 0x01
#define UNSUP_CLUSTER_COMMAND 0x81
#define UNSUP_GENERAL_COMMAND 0x82
#define UNSUPPORTED_ATTRIBUTE 0x86
// CMD types
#define CMD_CLUSTER 0x01
#define CMD_GLOBAL 0x00
#define SWAP_UINT16(x) (((x) >> 8) | ((x) << 8))
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))
// ieee high
constexpr uint8_t shCmd[] = {'S', 'H'};
// ieee low
constexpr uint8_t slCmd[] = {'S', 'L'};
// association status
constexpr uint8_t assocCmd[] = {'A', 'I'};
// panID
constexpr uint8_t netCmd[] = {'M', 'Y'};
XBeeAddress64 COORDINATOR64 = XBeeAddress64(0, 0);
class attribute
{
public:
uint16_t id;
uint8_t *value;
uint8_t val_len;
uint8_t type;
uint8_t is_const;
attribute(uint16_t a_id, uint8_t *a_value, uint8_t a_val_len, uint8_t a_type, bool is_const = 0x00)
{
this->id = a_id;
this->val_len = a_val_len;
this->type = a_type;
this->is_const = is_const;
if (is_const)
{
this->value = new uint8_t;
this->value = a_value;
}
else
{
this->value = new uint8_t[a_val_len];
memcpy(this->value, a_value, a_val_len);
}
}
void SetValue(uint32_t new_value)
{
for (uint8_t i = 0; i < val_len; i++)
{
value[i] = ((uint32_t)new_value >> (i * 8)) & 0xff;
}
}
uint32_t GetIntValue(uint8_t pr = 0x01)
{
uint32_t res_int = 0;
if (val_len == 1)
{
res_int = (uint32_t)value[0];
}
if (val_len == 2)
{
res_int = (uint32_t)value[0] | ((uint32_t)value[1] << 8);
}
if (val_len == 3)
{
res_int = (uint32_t)value[0] | ((uint32_t)value[1] << 8) | ((uint32_t)value[2] << 16);
}
if (val_len == 4)
{
res_int = (uint32_t)value[0] | ((uint32_t)value[1] << 8) | ((uint32_t)value[2] << 16) | ((uint32_t)value[3] << 24);
}
if (pr)
{
Serial.print(F(" "));
Serial.println(res_int, HEX);
}
return res_int;
}
float GetFloatValue()
{
float res;
uint32_t int_res = this->GetIntValue(0x00);
memcpy(&res, &int_res, 4);
return res;
}
void SetFloatValue(float new_value)
{
uint32_t int_res;
memcpy(&int_res, &new_value, 4);
this->SetValue(int_res);
}
};
class Cluster
{
private:
attribute *attributes;
uint8_t num_attr;
public:
uint16_t id;
Cluster(uint16_t cl_id, attribute *attr, uint8_t num)
{
id = cl_id;
attributes = attr;
num_attr = num;
}
bool AttributeExists(uint16_t attr_id)
{
for (uint8_t i = 0; i < num_attr; i++)
{
if (attributes[i].id == attr_id)
{
return 0x01;
}
}
return 0x00;
}
bool GetAttr(attribute **attr, uint16_t attr_id)
{
for (uint8_t i = 0; i < num_attr; i++)
{
if (this->attributes[i].id == attr_id)
{
*attr = &this->attributes[i];
return 0x01;
}
}
Serial.print(F("Attr Not Found: "));
Serial.println(attr_id, HEX);
return 0x00;
}
};
class LocalMac
{
private:
uint8_t addr;
public:
void Set(XBeeAddress64 mac)
{
EEPROM.put(addr, mac);
}
XBeeAddress64 Get()
{
XBeeAddress64 mac;
EEPROM.get(addr, mac);
return mac;
}
LocalMac(uint8_t mem_loc = 0)
{
addr = mem_loc;
}
};
class Endpoint
{
private:
uint8_t num_in_clusters;
uint8_t num_out_clusters;
Cluster *out_clusters;
uint16_t dev_type;
public:
uint8_t id;
Cluster *in_clusters;
public:
Endpoint(uint8_t ep_id = 0, uint16_t type_dev = 0, Cluster *in_cls = {}, Cluster *out_cls = {}, uint8_t num_in_cls = 0, uint8_t num_out_cls = 0)
{
id = ep_id;
dev_type = type_dev;
num_in_clusters = num_in_cls;
num_out_clusters = num_out_cls;
in_clusters = in_cls;
out_clusters = out_cls;
}
bool ClusterExists(uint16_t cl_id)
{
for (uint8_t i = 0; i < num_in_clusters; i++)
{
if (cl_id == in_clusters[i].id)
{
return 0x01;
}
}
Serial.print(F("No Cl "));
Serial.println(cl_id, HEX);
return 0x00;
}
Cluster GetCluster(uint16_t cl_id)
{
for (uint8_t i = 0; i < num_in_clusters; i++)
{
if (cl_id == in_clusters[i].id)
{
return in_clusters[i];
}
}
Serial.print(F("No Cl "));
Serial.println(cl_id, HEX);
return in_clusters[0]; // Also probably a mistake
}
void FillInCluster(uint8_t *buffer, uint8_t buf_start)
{
// Fill cluster ids in to a buffer, in reverse endian
for (uint8_t i = 0; i < num_in_clusters; i++)
{
memcpy(buffer + buf_start + (i * 2), &in_clusters[i].id, 2);
}
}
void FillOutCluster(uint8_t *buffer, uint8_t buf_start)
{
// Fill cluster ids in to a buffer, in reverse endian
for (uint8_t i = 0; i < num_out_clusters; i++)
{
memcpy(buffer + buf_start + (i * 2), &out_clusters[i].id, 2);
}
}
void GetInClusters(uint16_t *in_cl)
{
for (uint8_t i = 0; i < num_in_clusters; i++)
{
*(in_cl + i) = in_clusters[i].id;
}
}
void GetOutClusters(uint16_t *out_cl)
{
for (uint8_t i = 0; i < num_out_clusters; i++)
{
*(out_cl + i) = out_clusters[i].id;
}
}
uint8_t GetNumInClusters()
{
return num_in_clusters;
}
uint8_t GetNumOutClusters()
{
return num_out_clusters;
}
uint16_t GetDevType()
{
return dev_type;
}
};