-
-
Notifications
You must be signed in to change notification settings - Fork 27
/
zigbee.h
235 lines (173 loc) · 8.35 KB
/
zigbee.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
#ifndef ZIGBEE_H
#define ZIGBEE_H
#define UPDATE_NEIGHBORS_INTERVAL 3600000
#define PING_DEVICES_INTERVAL 300000
#define NETWORK_REQUEST_TIMEOUT 8000
#define DEVICE_REJOIN_TIMEOUT 5000
#define INTER_PAN_CHANNEL_TIMEOUT 100
#define STATUS_LED_TIMEOUT 500
#define TIME_OFFSET 946684800
#define OTA_MAX_LENGTH 10485760
#define IAS_ZONE_ID 0x42
#include <QMetaEnum>
#include "device.h"
class DataRequestObject;
typedef QSharedPointer <DataRequestObject> DataRequest;
class RequestObject;
typedef QSharedPointer <RequestObject> Request;
enum class RequestType
{
Data,
Leave,
LQI,
Interview
};
enum class RequestStatus
{
Pending,
Sent,
Finished,
Aborted
};
class DataRequestObject
{
public:
DataRequestObject(const Device &device, quint8 endpointId, quint16 clusterId, const QByteArray &data, const QString &name, bool debug, quint16 manufacturerCode, const Action &action) :
m_device(device), m_endpointId(endpointId), m_clusterId(clusterId), m_data(data), m_name(name), m_debug(debug), m_manufacturerCode(manufacturerCode), m_action(action) {}
inline Device device(void) { return m_device; }
inline quint8 endpointId(void) { return m_endpointId; }
inline quint16 clusterId(void) { return m_clusterId; }
inline QByteArray data(void) { return m_data; }
inline QString name(void) { return m_name; }
inline bool debug(void) { return m_debug; }
inline quint16 manufacturerCode(void) { return m_manufacturerCode; }
inline Action &action(void) { return m_action; }
private:
Device m_device;
quint8 m_endpointId;
quint16 m_clusterId;
QByteArray m_data;
QString m_name;
bool m_debug;
quint16 m_manufacturerCode;
Action m_action;
};
class RequestObject
{
public:
RequestObject(const QVariant &data, RequestType type) :
m_data(data), m_type(type), m_status(RequestStatus::Pending) {}
inline QVariant data(void) { return m_data; }
inline RequestType type(void) { return m_type; }
inline RequestStatus status(void) { return m_status; }
inline void setStatus(RequestStatus value) { m_status = value; }
private:
QVariant m_data;
RequestType m_type;
RequestStatus m_status;
};
class ZigBee : public QObject
{
Q_OBJECT
public:
ZigBee(QSettings *config, QObject *parent);
~ZigBee(void);
enum class Event
{
deviceJoined,
deviceLeft,
deviceRemoved,
deviceNameDuplicate,
deviceAboutToRename,
deviceUpdated,
interviewFinished,
interviewError,
interviewTimeout,
otaUpgradeStarted,
otaUpgradeFinished,
otaUpgradeError,
clusterRequest,
globalRequest,
requestFinished
};
Q_ENUM(Event)
inline DeviceList *devices(void) { return m_devices; }
inline const char *eventName(Event event) { return m_events.valueToKey(static_cast <int> (event)); }
void init(void);
void setPermitJoin(const QString &deviceName, bool enabled);
void togglePermitJoin(void);
void updateDevice(const QString &deviceName, const QString &name, const QString ¬e, bool active, bool discovery, bool cloud);
void removeDevice(const QString &deviceName, bool force);
void setupDevice(const QString &deviceName, bool reportings);
void setupReporting(const QString &deviceName, quint8 endpointId, const QString &reportingName, quint16 minInterval, quint16 maxInterval, quint16 valueChange);
void bindingControl(const QString &deviceName, quint8 endpointId, quint16 clusterId, const QVariant &dstAddress, quint8 dstEndpointId, bool unbind);
void groupControl(const QString &deviceName, quint8 endpointId, quint16 groupId, bool remove);
void removeAllGroups(const QString &deviceName, quint8 endpointId);
void otaControl(const QString &deviceName, bool refresh, bool upgrade);
void getProperties(const QString &deviceName);
void clusterRequest(const QString &deviceName, quint8 endpointId, quint16 clusterId, quint16 manufacturerCode, quint8 commandId, const QByteArray &payload, bool global);
void touchLinkRequest(const QByteArray &ieeeAddress = QByteArray(), quint8 channel = 11, bool reset = false);
void deviceAction(const QString &deviceName, quint8 endpointId, const QString &name, const QVariant &data);
void groupAction(quint16 groupId, const QString &name, const QVariant &data);
private:
QSettings *m_config;
QTimer *m_requestTimer, *m_neignborsTimer, *m_pingTimer, *m_statusLedTimer;
Adapter *m_adapter;
DeviceList *m_devices;
QMetaEnum m_events;
quint8 m_requestId, m_requestStatus, m_replyId, m_interPanChannel;
bool m_replyReceived, m_groupRequestFinished, m_groupsUpdated, m_interPanLock;
QString m_statusLedPin, m_blinkLedPin;
bool m_debounce, m_discovery, m_cloud, m_debug;
QMap <quint8, Request> m_requests;
void enqueueRequest(const Device &device, quint8 endpointId, quint16 clusterId, const QByteArray &data, const QString &name = QString(), bool debug = false, quint16 manufacturerCode = 0, const Action &action = Action());
void enqueueRequest(const Device &device, RequestType type);
bool interviewRequest(quint8 id, const Device &device);
bool interviewQuirks(const Device &device);
void interviewDevice(const Device &device);
void interviewFinished(const Device &device);
void interviewError(const Device &device, const QString &reason);
bool configureDevice(const Device &device);
bool configureReporting(const Endpoint &endpoint, const Reporting &reporting);
bool bindRequest(const Endpoint &endpoint, quint16 clusterId, const QByteArray &address = QByteArray(), quint8 dstEndpointId = 0, bool unbind = false, bool manual = false);
bool groupRequest(const Endpoint &endpoint, quint16 groupId, bool removeAll = false, bool remove = false);
bool dataRequest(const Endpoint &endpoint, quint16 clusterId, const QByteArray &data, const QString &name);
bool parseProperty(const Endpoint &endpoint, quint16 clusterId, quint8 transactionId, quint16 itemId, const QByteArray &data, bool command = false);
void parseAttribute(const Endpoint &endpoint, quint16 clusterId, quint8 transactionId, quint16 attributeId, quint8 dataType, const QByteArray &data);
void clusterCommandReceived(const Endpoint &endpoint, quint16 clusterId, quint16 manufacturerCode, quint8 transactionId, quint8 commandId, const QByteArray &payload);
void globalCommandReceived(const Endpoint &endpoint, quint16 clusterId, quint16 manufacturerCode, quint8 transactionId, quint8 commandId, QByteArray payload);
void touchLinkReset(const QByteArray &ieeeAddress, quint8 channel);
void touchLinkScan(void);
void interviewTimeoutHandler(const Device &device);
void rejoinHandler(const Device &device);
void restoreGroups(const Device &device);
void storeNeighbors(void);
void otaError(const Endpoint &endpoint, quint16 manufacturerCode, quint8 transactionId, quint8 commandId, const QString &error = QString(), bool response = true);
void blink(quint16 timeout);
private slots:
void adapterReset(void);
void coordinatorReady(void);
void permitJoinUpdated(bool enabled);
void deviceJoined(const QByteArray &ieeeAddress, quint16 networkAddress);
void deviceLeft(const QByteArray &ieeeAddress);
void zdoMessageReveived(quint16 networkAddress, quint16 clusterId, const QByteArray &payload);
void zclMessageReveived(quint16 networkAddress, quint8 endpointId, quint16 clusterId, quint8 linkQuality, const QByteArray &payload);
void rawMessageReveived(const QByteArray &ieeeAddress, quint16 clusterId, quint8 linkQuality, const QByteArray &data);
void requestFinished(quint8 id, quint8 status);
void handleRequests(void);
void updateNeighbors(void);
void pingDevices(void);
void interviewTimeout(void);
void pollRequest(EndpointObject *endpoint, const Poll &poll);
void updateStatusLed(void);
void updateBlinkLed(void);
signals:
void networkStarted(void);
void deviceEvent(DeviceObject *device, ZigBee::Event event, const QJsonObject &json = QJsonObject());
void endpointUpdated(DeviceObject *device, quint8 endpointId);
void statusUpdated(const QJsonObject &json);
void replyReceived(void);
void groupRequestFinished(void);
};
Q_DECLARE_METATYPE(DataRequest)
#endif