forked from dresden-elektronik/deconz-rest-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
de_web_plugin_private.h
1491 lines (1339 loc) · 52.6 KB
/
de_web_plugin_private.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
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (c) 2017-2018 dresden elektronik ingenieurtechnik gmbh.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
* style license a copy of which has been included with this distribution in
* the LICENSE.txt file.
*
*/
#ifndef DE_WEB_PLUGIN_PRIVATE_H
#define DE_WEB_PLUGIN_PRIVATE_H
#include <QtGlobal>
#include <QObject>
#include <QTime>
#include <QTimer>
#include <QElapsedTimer>
#include <stdint.h>
#include <queue>
#if QT_VERSION < 0x050000
#include <QHttpRequestHeader>
#endif
#include "sqlite3.h"
#include <deconz.h>
#include "resource.h"
#include "event.h"
#include "resource.h"
#include "rest_node_base.h"
#include "light_node.h"
#include "group.h"
#include "group_info.h"
#include "scene.h"
#include "sensor.h"
#include "resourcelinks.h"
#include "rule.h"
#include "bindings.h"
#include <math.h>
#include "websocket_server.h"
/*! JSON generic error message codes */
#define ERR_UNAUTHORIZED_USER 1
#define ERR_INVALID_JSON 2
#define ERR_RESOURCE_NOT_AVAILABLE 3
#define ERR_METHOD_NOT_AVAILABLE 4
#define ERR_MISSING_PARAMETER 5
#define ERR_PARAMETER_NOT_AVAILABLE 6
#define ERR_INVALID_VALUE 7
#define ERR_PARAMETER_NOT_MODIFIEABLE 8
#define ERR_TOO_MANY_ITEMS 11
#define ERR_DUPLICATE_EXIST 100 // de extension
#define ERR_NOT_ALLOWED_SENSOR_TYPE 501
#define ERR_SENSOR_LIST_FULL 502
#define ERR_RULE_ENGINE_FULL 601
#define ERR_CONDITION_ERROR 607
#define ERR_ACTION_ERROR 608
#define ERR_INTERNAL_ERROR 901
#define ERR_NOT_CONNECTED 950 // de extension
#define ERR_BRIDGE_BUSY 951 // de extension
#define ERR_LINK_BUTTON_NOT_PRESSED 101
#define ERR_DEVICE_OFF 201
#define ERR_BRIDGE_GROUP_TABLE_FULL 301
#define ERR_DEVICE_GROUP_TABLE_FULL 302
#define ERR_DEVICE_SCENES_TABLE_FULL 402 // de extension
#define IDLE_LIMIT 30
#define IDLE_READ_LIMIT 120
#define IDLE_USER_LIMIT 20
#define IDLE_ATTR_REPORT_BIND_LIMIT 240
#define BUTTON_ATTR_REPORT_BIND_LIMIT 120
#define WARMUP_TIME 120
#define MAX_UNLOCK_GATEWAY_TIME 600
#define PERMIT_JOIN_SEND_INTERVAL (1000 * 1800)
#define EXT_PROCESS_TIMEOUT 10000
#define SET_ENDPOINTCONFIG_DURATION (1000 * 16) // time deCONZ needs to update Endpoints
#define OTA_LOW_PRIORITY_TIME (60 * 2)
#define CHECK_SENSOR_FAST_ROUNDS 3
#define CHECK_SENSOR_FAST_INTERVAL 100
#define CHECK_SENSOR_INTERVAL 1000
#define CHECK_SENSORS_MAX 10
#define DE_OTAU_ENDPOINT 0x50
#define DE_PROFILE_ID 0xDE00
#define ATMEL_WSNDEMO_PROFILE_ID 0x0001
// Generic devices
#define DEV_ID_ONOFF_SWITCH 0x0000 // On/Off switch
#define DEV_ID_LEVEL_CONTROL_SWITCH 0x0001 // Level control switch
#define DEV_ID_ONOFF_OUTPUT 0x0002 // On/Off output
#define DEV_ID_RANGE_EXTENDER 0x0008 // Range extender
#define DEV_ID_MAINS_POWER_OUTLET 0x0009 // Mains power outlet
#define DEV_ID_SMART_PLUG 0x0051 // Smart plug
// HA lighting devices
#define DEV_ID_HA_ONOFF_LIGHT 0x0100 // On/Off light
#define DEV_ID_HA_DIMMABLE_LIGHT 0x0101 // Dimmable light
#define DEV_ID_HA_COLOR_DIMMABLE_LIGHT 0x0102 // Color dimmable light
#define DEV_ID_HA_ONOFF_LIGHT_SWITCH 0x0103 // On/Off light switch
#define DEV_ID_HA_DIMMER_SWITCH 0x0104 // Dimmer switch
#define DEV_ID_HA_LIGHT_SENSOR 0x0106 // Light sensor
#define DEV_ID_HA_OCCUPANCY_SENSOR 0x0107 // Occupancy sensor
//
#define DEV_ID_IAS_ZONE 0x0402 // IAS Zone
#define DEV_ID_IAS_WARNING_DEVICE 0x0403 // IAS Warning Device
// Smart Energy devices
#define DEV_ID_SE_METERING_DEVICE 0x0501 // Smart Energy metering device
// ZLL lighting devices
#define DEV_ID_ZLL_ONOFF_LIGHT 0x0000 // On/Off light
#define DEV_ID_ZLL_ONOFF_PLUGIN_UNIT 0x0010 // On/Off plugin unit
#define DEV_ID_ZLL_DIMMABLE_LIGHT 0x0100 // Dimmable light
#define DEV_ID_ZLL_DIMMABLE_PLUGIN_UNIT 0x0110 // Dimmable plugin unit
#define DEV_ID_ZLL_COLOR_LIGHT 0x0200 // Color light
#define DEV_ID_ZLL_EXTENDED_COLOR_LIGHT 0x0210 // Extended color light
#define DEV_ID_ZLL_COLOR_TEMPERATURE_LIGHT 0x0220 // Color temperature light
// ZigBee 3.0 lighting devices
#define DEV_ID_Z30_ONOFF_PLUGIN_UNIT 0x010a // On/Off plugin unit
#define DEV_ID_Z30_DIMMABLE_PLUGIN_UNIT 0x010b // Dimmable plugin unit
#define DEV_ID_Z30_COLOR_TEMPERATURE_LIGHT 0x010c // Color temperature light
#define DEV_ID_Z30_EXTENDED_COLOR_LIGHT 0x010d // Extended color light
// ZLL controller devices
#define DEV_ID_ZLL_COLOR_CONTROLLER 0x0800 // Color controller
#define DEV_ID_ZLL_COLOR_SCENE_CONTROLLER 0x0810 // Color scene controller
#define DEV_ID_ZLL_NON_COLOR_CONTROLLER 0x0820 // Non color controller
#define DEV_ID_ZLL_NON_COLOR_SCENE_CONTROLLER 0x0830 // Non color scene controller
#define DEV_ID_ZLL_CONTROL_BRIDGE 0x0840 // Control bridge
#define DEV_ID_ZLL_ONOFF_SENSOR 0x0850 // On/Off sensor
#define DEV_ID_XIAOMI_SMART_PLUG 0xffff
#define DEFAULT_TRANSITION_TIME 4 // 400ms
#define MAX_ENHANCED_HUE 65535
#define MAX_ENHANCED_HUE_Z 65278 // max supportet ehue of all devices
#define BASIC_CLUSTER_ID 0x0000
#define POWER_CONFIGURATION_CLUSTER_ID 0x0001
#define IDENTIFY_CLUSTER_ID 0x0003
#define GROUP_CLUSTER_ID 0x0004
#define SCENE_CLUSTER_ID 0x0005
#define ONOFF_CLUSTER_ID 0x0006
#define ONOFF_SWITCH_CONFIGURATION_CLUSTER_ID 0x0007
#define LEVEL_CLUSTER_ID 0x0008
#define ANALOG_INPUT_CLUSTER_ID 0x000C
#define MULTISTATE_INPUT_CLUSTER_ID 0x0012
#define OTAU_CLUSTER_ID 0x0019
#define GREEN_POWER_CLUSTER_ID 0x0021
#define COLOR_CLUSTER_ID 0x0300
#define ILLUMINANCE_MEASUREMENT_CLUSTER_ID 0x0400
#define ILLUMINANCE_LEVEL_SENSING_CLUSTER_ID 0x0401
#define TEMPERATURE_MEASUREMENT_CLUSTER_ID 0x0402
#define PRESSURE_MEASUREMENT_CLUSTER_ID 0x0403
#define RELATIVE_HUMIDITY_CLUSTER_ID 0x0405
#define OCCUPANCY_SENSING_CLUSTER_ID 0x0406
#define IAS_ZONE_CLUSTER_ID 0x0500
#define IAS_WD_CLUSTER_ID 0x0502
#define METERING_CLUSTER_ID 0x0702
#define ELECTRICAL_MEASUREMENT_CLUSTER_ID 0x0B04
#define COMMISSIONING_CLUSTER_ID 0x1000
#define DE_CLUSTER_ID 0xFC00
#define VENDOR_CLUSTER_ID 0xFC00
#define GREEN_POWER_ENDPOINT 0xf2
#define ONOFF_COMMAND_OFF 0x00
#define ONOFF_COMMAND_ON 0x01
#define ONOFF_COMMAND_TOGGLE 0x02
#define ONOFF_COMMAND_OFF_WITH_EFFECT 0x040
#define ONOFF_COMMAND_ON_WITH_TIMED_OFF 0x42
#define LEVEL_COMMAND_MOVE_TO_LEVEL 0x00
#define LEVEL_COMMAND_MOVE 0x01
#define LEVEL_COMMAND_STEP 0x02
#define LEVEL_COMMAND_STOP 0x03
#define LEVEL_COMMAND_MOVE_TO_LEVEL_WITH_ON_OFF 0x04
#define LEVEL_COMMAND_MOVE_WITH_ON_OFF 0x05
#define LEVEL_COMMAND_STEP_WITH_ON_OFF 0x06
#define LEVEL_COMMAND_STOP_WITH_ON_OFF 0x07
#define SCENE_COMMAND_RECALL_SCENE 0x05
#define SCENE_COMMAND_IKEA_STEP_CT 0x07
#define SCENE_COMMAND_IKEA_MOVE_CT 0x08
#define SCENE_COMMAND_IKEA_STOP_CT 0x09
// IAS Zone Types
#define IAS_ZONE_TYPE_STANDARD_CIE 0x0000
#define IAS_ZONE_TYPE_MOTION_SENSOR 0x000d
#define IAS_ZONE_TYPE_CONTACT_SWITCH 0x0015
#define IAS_ZONE_TYPE_FIRE_SENSOR 0x0028
#define IAS_ZONE_TYPE_WATER_SENSOR 0x002a
#define IAS_ZONE_TYPE_CARBON_MONOXIDE_SENSOR 0x002b
#define IAS_ZONE_TYPE_WARNING_DEVICE 0x0225
// read flags
#define READ_MODEL_ID (1 << 0)
#define READ_SWBUILD_ID (1 << 1)
#define READ_ON_OFF (1 << 2)
#define READ_LEVEL (1 << 3)
#define READ_COLOR (1 << 4)
#define READ_GROUPS (1 << 5)
#define READ_SCENES (1 << 6)
#define READ_SCENE_DETAILS (1 << 7)
#define READ_VENDOR_NAME (1 << 8)
#define READ_BINDING_TABLE (1 << 9)
#define READ_OCCUPANCY_CONFIG (1 << 10)
#define READ_GROUP_IDENTIFIERS (1 << 12)
#define READ_MODEL_ID_INTERVAL (60 * 60) // s
#define READ_SWBUILD_ID_INTERVAL (60 * 60) // s
// write flags
#define WRITE_OCCUPANCY_CONFIG (1 << 11)
#define WRITE_DELAY (1 << 13)
#define WRITE_LEDINDICATION (1 << 14)
#define WRITE_SENSITIVITY (1 << 15)
#define WRITE_USERTEST (1 << 16)
// manufacturer codes
// http://cgit.osmocom.org/wireshark/plain/epan/dissectors/packet-zbee.h
#define VENDOR_NONE 0x0000
#define VENDOR_EMBER 0x1002
#define VENDOR_PHILIPS 0x100B
#define VENDOR_ATMEL 0x1014
#define VENDOR_JENNIC 0x1037
#define VENDOR_CENTRALITE 0x104E
#define VENDOR_NYCE 0x10B9
#define VENDOR_UBISYS 0x10F2
#define VENDOR_BEGA 0x1105
#define VENDOR_OSRAM 0x110C
#define VENDOR_DDEL 0x1135
#define VENDOR_LUTRON 0x1144
#define VENDOR_115F 0x115F // Used by Xiaomi
#define VENDOR_INNR 0x1166
#define VENDOR_INNR2 0x1168
#define VENDOR_INSTA 0x117A
#define VENDOR_IKEA 0x117C
#define VENDOR_BUSCH_JAEGER 0x112E
#define VENDOR_PAULMANN 0x119D
#define VENDOR_120B 0x120B // Used by Heiman
#define VENDOR_OSRAM_STACK 0xBBAA
#define ANNOUNCE_INTERVAL 10 // minutes default announce interval
#define MAX_GROUP_SEND_DELAY 5000 // ms between to requests to the same group
#define GROUP_SEND_DELAY 50 // default ms between to requests to the same group
#define MAX_TASKS_PER_NODE 2
#define MAX_BACKGROUND_TASKS 5
#define MAX_SENSORS 1000
#define MAX_RULE_ILLUMINANCE_VALUE_AGE_MS (1000 * 60 * 20) // 20 minutes
// string lengths
#define MAX_GROUP_NAME_LENGTH 32
#define MAX_SCENE_NAME_LENGTH 32
#define MAX_RULE_NAME_LENGTH 32
#define MAX_SENSOR_NAME_LENGTH 32
// REST API return codes
#define REQ_READY_SEND 0
#define REQ_DONE 2
#define REQ_NOT_HANDLED -1
// Special application return codes
#define APP_RET_UPDATE 40
#define APP_RET_RESTART_APP 41
#define APP_RET_UPDATE_BETA 42
#define APP_RET_RESTART_SYS 43
#define APP_RET_SHUTDOWN_SYS 44
#define APP_RET_UPDATE_ALPHA 45
#define APP_RET_UPDATE_FW 46
// Firmware version related (32-bit field)
#define FW_PLATFORM_MASK 0x0000FF00UL
#define FW_PLATFORM_DERFUSB23E0X 0x00000300UL
#define FW_PLATFORM_RPI 0x00000500UL
// schedules
#define SCHEDULE_CHECK_PERIOD 1000
// save database items
#define DB_LIGHTS 0x00000001
#define DB_GROUPS 0x00000002
#define DB_AUTH 0x00000004
#define DB_CONFIG 0x00000008
#define DB_SCENES 0x00000010
#define DB_SCHEDULES 0x00000020
#define DB_RULES 0x00000040
#define DB_SENSORS 0x00000080
#define DB_USERPARAM 0x00000100
#define DB_GATEWAYS 0x00000200
#define DB_RESOURCELINKS 0x00000400
#define DB_HUGE_SAVE_DELAY (60 * 60 * 1000) // 60 minutes
#define DB_LONG_SAVE_DELAY (15 * 60 * 1000) // 15 minutes
#define DB_SHORT_SAVE_DELAY (5 * 1 * 1000) // 5 seconds
#define DB_CONNECTION_TTL (60 * 15) // 15 minutes
// internet discovery
// network reconnect
#define DISCONNECT_CHECK_DELAY 100
#define NETWORK_ATTEMPS 10
#define RECONNECT_CHECK_DELAY 5000
#define RECONNECT_NOW 100
extern const quint64 macPrefixMask;
extern const quint64 bjeMacPrefix;
extern const quint64 emberMacPrefix;
extern const quint64 tiMacPrefix;
extern const quint64 deMacPrefix;
extern const quint64 ikeaMacPrefix;
extern const quint64 instaMacPrefix;
extern const quint64 jennicMacPrefix;
extern const quint64 philipsMacPrefix;
extern const quint64 osramMacPrefix;
extern const quint64 ubisysMacPrefix;
extern const quint64 netvoxMacPrefix;
extern const quint64 heimanMacPrefix;
extern const quint64 lutronMacPrefix;
// HTTP status codes
extern const char *HttpStatusOk;
extern const char *HttpStatusAccepted;
extern const char *HttpStatusNotModified;
extern const char *HttpStatusUnauthorized;
extern const char *HttpStatusBadRequest;
extern const char *HttpStatusForbidden;
extern const char *HttpStatusNotFound;
extern const char *HttpStatusNotImplemented;
extern const char *HttpStatusServiceUnavailable;
extern const char *HttpContentHtml;
extern const char *HttpContentCss;
extern const char *HttpContentJson;
extern const char *HttpContentJS;
extern const char *HttpContentPNG;
extern const char *HttpContentJPG;
extern const char *HttpContentSVG;
// Forward declarations
class Gateway;
class GatewayScanner;
class QUdpSocket;
class QTcpSocket;
class DeRestPlugin;
class QHostInfo;
class QNetworkReply;
class QNetworkAccessManager;
class QProcess;
class PollManager;
struct Schedule
{
enum Week
{
Monday = 0x01,
Tuesday = 0x02,
Wednesday = 0x04,
Thursday = 0x08,
Friday = 0x10,
Saturday = 0x20,
Sunday = 0x40,
};
enum Type
{
TypeInvalid,
TypeAbsoluteTime,
TypeRecurringTime,
TypeTimer
};
enum State
{
StateNormal,
StateDeleted
};
Schedule() :
type(TypeInvalid),
state(StateNormal),
status(QLatin1String("enabled")),
activation(QLatin1String("start")),
autodelete(true),
weekBitmap(0),
recurring(0),
timeout(0),
currentTimeout(0)
{
}
Type type;
State state;
/*! Numeric identifier as string. */
QString id;
/*! etag of Schedule. */
QString etag;
/*! Name length 0..32, if 0 default name "schedule" will be used. (Optional) */
QString name;
/*! Description length 0..64, default is empty string. (Optional) */
QString description;
/*! Command a JSON object with length 0..90. (Required) */
QString command;
/*! Time is given in ISO 8601:2004 format: YYYY-MM-DDTHH:mm:ss. (Required) */
QString time;
/*! Localtime is given in ISO 8601:2004 format: YYYY-MM-DDTHH:mm:ss. (Optional) */
QString localtime;
/*! UTC time that the timer was started. Only provided for timers. */
QString starttime;
/*! status of schedule (enabled or disabled). */
QString status;
/*! should activation of schedule start or end at given time (if a fading time is given) (start or end). */
QString activation;
/*! If set to true, the schedule will be removed automatically if expired, if set to false it will be disabled. */
bool autodelete;
/*! Same as time but as qt object. */
QDateTime datetime;
/*! Date time of last schedule activation. */
QDateTime lastTriggerDatetime;
/*! Whole JSON schedule as received from API as string. */
QString jsonString;
/*! Whole JSON schedule as received from API as map. */
QVariantMap jsonMap;
/*! Bitmap for recurring schedule. */
quint8 weekBitmap;
/*! R[nn], the recurring part, 0 means forever. */
uint recurring;
QDateTime endtime; /*! Localtime of timeout: for timers only. */
/*! Timeout in seconds. */
int timeout;
/*! Current timeout counting down to ::timeout. */
int currentTimeout;
};
enum TaskType
{
TaskIdentify = 0,
TaskGetHue = 1,
TaskSetHue = 2,
TaskSetEnhancedHue = 3,
TaskSetHueAndSaturation = 4,
TaskSetXyColor = 5,
TaskSetColorTemperature = 6,
TaskGetColor = 7,
TaskGetSat = 8,
TaskSetSat = 9,
TaskGetLevel = 10,
TaskSetLevel = 11,
TaskIncColorTemperature = 12,
TaskStopLevel = 13,
TaskSendOnOffToggle = 14,
TaskMoveLevel = 15,
TaskGetOnOff = 16,
TaskSetColorLoop = 17,
TaskGetColorLoop = 18,
TaskReadAttributes = 19,
TaskWriteAttribute = 20,
TaskGetGroupMembership = 21,
TaskGetGroupIdentifiers = 22,
TaskGetSceneMembership = 23,
TaskStoreScene = 24,
TaskCallScene = 25,
TaskViewScene = 26,
TaskAddScene = 27,
TaskRemoveScene = 28,
TaskRemoveAllScenes = 29,
TaskAddToGroup = 30,
TaskRemoveFromGroup = 31,
TaskViewGroup = 32,
TaskTriggerEffect = 33,
TaskWarning = 34
};
struct TaskItem
{
TaskItem()
{
taskId = _taskCounter++;
autoMode = false;
onOff = false;
client = 0;
node = 0;
lightNode = 0;
cluster = 0;
colorX = 0;
colorY = 0;
colorTemperature = 0;
transitionTime = DEFAULT_TRANSITION_TIME;
sendTime = 0;
ordered = false;
}
TaskType taskType;
int taskId;
deCONZ::ApsDataRequest req;
deCONZ::ZclFrame zclFrame;
uint8_t zclSeq;
bool ordered; // won't be send until al prior taskIds are send
int sendTime; // copy of idleTotalCounter
bool confirmed;
bool onOff;
bool colorLoop;
qreal hueReal;
uint16_t identifyTime;
uint8_t effectIdentifier;
uint8_t options;
uint16_t duration;
uint8_t hue;
uint8_t sat;
uint8_t level;
uint16_t enhancedHue;
uint16_t colorX;
uint16_t colorY;
uint16_t colorTemperature;
uint16_t groupId;
uint8_t sceneId;
qint32 inc; // bri_inc, hue_inc, sat_inc, ct_inc
QString etag;
uint16_t transitionTime;
QTcpSocket *client;
bool autoMode; // true then this is a automode task
deCONZ::Node *node;
LightNode *lightNode;
deCONZ::ZclCluster *cluster;
private:
static int _taskCounter;
};
/*! \class ApiAuth
Helper to combine serval authentification parameters.
*/
class ApiAuth
{
public:
enum State
{
StateNormal,
StateDeleted
};
ApiAuth();
void setDeviceType(const QString &devtype);
bool strict;
bool needSaveDatabase;
State state;
QString apikey; // also called username (10..32 chars)
QString devicetype;
QDateTime createDate;
QDateTime lastUseDate;
QString useragent;
};
enum ApiVersion
{
ApiVersion_1, //!< common version 1.0
ApiVersion_1_DDEL //!< version 1.0, "Accept: application/vnd.ddel.v1"
};
/*! \class ApiRequest
Helper to simplify HTTP REST request handling.
*/
class ApiRequest
{
public:
ApiRequest(const QHttpRequestHeader &h, const QStringList &p, QTcpSocket *s, const QString &c);
QString apikey() const;
ApiVersion apiVersion() const { return version; }
const QHttpRequestHeader &hdr;
const QStringList &path;
QTcpSocket *sock;
QString content;
ApiVersion version;
bool strict;
};
/*! \class ApiResponse
Helper to simplify HTTP REST request handling.
*/
struct ApiResponse
{
QString etag;
const char *httpStatus;
const char *contentType;
QList<QPair<QString, QString> > hdrFields; // extra header fields
QVariantMap map; // json content
QVariantList list; // json content
QString str; // json string
};
/*! \class ApiConfig
Provide config to the resource system.
*/
class ApiConfig : public Resource
{
public:
ApiConfig();
};
class TcpClient
{
public:
QHttpRequestHeader hdr;
QDateTime created;
int closeTimeout; // close socket in n seconds
QTcpSocket *sock;
};
/*! \class DeWebPluginPrivate
Pimpl of DeWebPlugin.
*/
class DeRestPluginPrivate : public QObject
{
Q_OBJECT
public:
struct nodeVisited {
const deCONZ::Node* node;
bool visited;
};
DeRestPluginPrivate(QObject *parent = 0);
~DeRestPluginPrivate();
// REST API authentification
void initAuthentification();
bool allowedToCreateApikey(const ApiRequest &req, ApiResponse &rsp, QVariantMap &map);
bool checkApikeyAuthentification(const ApiRequest &req, ApiResponse &rsp);
QString encryptString(const QString &str);
// REST API gateways
int handleGatewaysApi(const ApiRequest &req, ApiResponse &rsp);
int getAllGateways(const ApiRequest &req, ApiResponse &rsp);
int getGatewayState(const ApiRequest &req, ApiResponse &rsp);
int setGatewayState(const ApiRequest &req, ApiResponse &rsp);
int addCascadeGroup(const ApiRequest &req, ApiResponse &rsp);
int deleteCascadeGroup(const ApiRequest &req, ApiResponse &rsp);
void gatewayToMap(const ApiRequest &req, const Gateway *gw, QVariantMap &map);
// REST API configuration
void initConfig();
int handleConfigurationApi(const ApiRequest &req, ApiResponse &rsp);
int createUser(const ApiRequest &req, ApiResponse &rsp);
int getFullState(const ApiRequest &req, ApiResponse &rsp);
int getConfig(const ApiRequest &req, ApiResponse &rsp);
int getBasicConfig(const ApiRequest &req, ApiResponse &rsp);
int getChallenge(const ApiRequest &req, ApiResponse &rsp);
int modifyConfig(const ApiRequest &req, ApiResponse &rsp);
int deleteUser(const ApiRequest &req, ApiResponse &rsp);
int updateSoftware(const ApiRequest &req, ApiResponse &rsp);
int restartGateway(const ApiRequest &req, ApiResponse &rsp);
int restartApp(const ApiRequest &req, ApiResponse &rsp);
int shutDownGateway(const ApiRequest &req, ApiResponse &rsp);
int updateFirmware(const ApiRequest &req, ApiResponse &rsp);
int exportConfig(const ApiRequest &req, ApiResponse &rsp);
int importConfig(const ApiRequest &req, ApiResponse &rsp);
int resetConfig(const ApiRequest &req, ApiResponse &rsp);
int changePassword(const ApiRequest &req, ApiResponse &rsp);
int deletePassword(const ApiRequest &req, ApiResponse &rsp);
int getWifiState(const ApiRequest &req, ApiResponse &rsp);
int configureWifi(const ApiRequest &req, ApiResponse &rsp);
int restoreWifiConfig(const ApiRequest &req, ApiResponse &rsp);
int putWifiScanResult(const ApiRequest &req, ApiResponse &rsp);
int putWifiUpdated(const ApiRequest &req, ApiResponse &rsp);
void configToMap(const ApiRequest &req, QVariantMap &map);
void basicConfigToMap(QVariantMap &map);
// REST API userparameter
int handleUserparameterApi(const ApiRequest &req, ApiResponse &rsp);
int createUserParameter(const ApiRequest &req, ApiResponse &rsp);
int addUserParameter(const ApiRequest &req, ApiResponse &rsp);
int modifyUserParameter(const ApiRequest &req, ApiResponse &rsp);
int getUserParameter(const ApiRequest &req, ApiResponse &rsp);
int getAllUserParameter(const ApiRequest &req, ApiResponse &rsp);
int deleteUserParameter(const ApiRequest &req, ApiResponse &rsp);
// REST API lights
int handleLightsApi(ApiRequest &req, ApiResponse &rsp);
int getAllLights(const ApiRequest &req, ApiResponse &rsp);
int searchLights(const ApiRequest &req, ApiResponse &rsp);
int getNewLights(const ApiRequest &req, ApiResponse &rsp);
int getLightState(const ApiRequest &req, ApiResponse &rsp);
int setLightState(const ApiRequest &req, ApiResponse &rsp);
int setLightAttributes(const ApiRequest &req, ApiResponse &rsp);
int deleteLight(const ApiRequest &req, ApiResponse &rsp);
int removeAllScenes(const ApiRequest &req, ApiResponse &rsp);
int removeAllGroups(const ApiRequest &req, ApiResponse &rsp);
int getConnectivity(const ApiRequest &req, ApiResponse &rsp, bool alt);
void handleLightEvent(const Event &e);
bool lightToMap(const ApiRequest &req, const LightNode *webNode, QVariantMap &map);
// REST API groups
int handleGroupsApi(ApiRequest &req, ApiResponse &rsp);
int getAllGroups(const ApiRequest &req, ApiResponse &rsp);
int createGroup(const ApiRequest &req, ApiResponse &rsp);
int getGroupAttributes(const ApiRequest &req, ApiResponse &rsp);
int setGroupAttributes(const ApiRequest &req, ApiResponse &rsp);
int setGroupState(const ApiRequest &req, ApiResponse &rsp);
int deleteGroup(const ApiRequest &req, ApiResponse &rsp);
void handleGroupEvent(const Event &e);
Group *addGroup();
// REST API groups > scenes
int createScene(const ApiRequest &req, ApiResponse &rsp);
int getAllScenes(const ApiRequest &req, ApiResponse &rsp);
int getSceneAttributes(const ApiRequest &req, ApiResponse &rsp);
int setSceneAttributes(const ApiRequest &req, ApiResponse &rsp);
int storeScene(const ApiRequest &req, ApiResponse &rsp);
int recallScene(const ApiRequest &req, ApiResponse &rsp);
int modifyScene(const ApiRequest &req, ApiResponse &rsp);
int deleteScene(const ApiRequest &req, ApiResponse &rsp);
bool groupToMap(const Group *group, QVariantMap &map);
// REST API schedules
void initSchedules();
int handleSchedulesApi(ApiRequest &req, ApiResponse &rsp);
int getAllSchedules(const ApiRequest &req, ApiResponse &rsp);
int createSchedule(const ApiRequest &req, ApiResponse &rsp);
int getScheduleAttributes(const ApiRequest &req, ApiResponse &rsp);
int setScheduleAttributes(const ApiRequest &req, ApiResponse &rsp);
int deleteSchedule(const ApiRequest &req, ApiResponse &rsp);
bool jsonToSchedule(const QString &jsonString, Schedule &schedule, ApiResponse *rsp);
// REST API touchlink
void initTouchlinkApi();
int handleTouchlinkApi(ApiRequest &req, ApiResponse &rsp);
int touchlinkScan(ApiRequest &req, ApiResponse &rsp);
int getTouchlinkScanResults(ApiRequest &req, ApiResponse &rsp);
int identifyLight(ApiRequest &req, ApiResponse &rsp);
int resetLight(ApiRequest &req, ApiResponse &rsp);
// REST API sensors
int handleSensorsApi(ApiRequest &req, ApiResponse &rsp);
int getAllSensors(const ApiRequest &req, ApiResponse &rsp);
int getSensor(const ApiRequest &req, ApiResponse &rsp);
int findNewSensors(const ApiRequest &req, ApiResponse &rsp);
int getNewSensors(const ApiRequest &req, ApiResponse &rsp);
int updateSensor(const ApiRequest &req, ApiResponse &rsp);
int deleteSensor(const ApiRequest &req, ApiResponse &rsp);
int changeSensorConfig(const ApiRequest &req, ApiResponse &rsp);
int changeSensorState(const ApiRequest &req, ApiResponse &rsp);
int createSensor(const ApiRequest &req, ApiResponse &rsp);
int getGroupIdentifiers(const ApiRequest &req, ApiResponse &rsp);
int recoverSensor(const ApiRequest &req, ApiResponse &rsp);
bool sensorToMap(const Sensor *sensor, QVariantMap &map, bool strictMode);
void handleSensorEvent(const Event &e);
// REST API resourcelinks
int handleResourcelinksApi(ApiRequest &req, ApiResponse &rsp);
int getAllResourcelinks(ApiRequest &req, ApiResponse &rsp);
int getResourcelinks(ApiRequest &req, ApiResponse &rsp);
int createResourcelinks(ApiRequest &req, ApiResponse &rsp);
int updateResourcelinks(ApiRequest &req, ApiResponse &rsp);
int deleteResourcelinks(ApiRequest &req, ApiResponse &rsp);
// REST API rules
int handleRulesApi(const ApiRequest &req, ApiResponse &rsp);
int getAllRules(const ApiRequest &req, ApiResponse &rsp);
int getRule(const ApiRequest &req, ApiResponse &rsp);
int createRule(const ApiRequest &req, ApiResponse &rsp);
int updateRule(const ApiRequest &req, ApiResponse &rsp);
int deleteRule(const ApiRequest &req, ApiResponse &rsp);
void queueCheckRuleBindings(const Rule &rule);
bool evaluateRule(Rule &rule, const Event &e, Resource *eResource, ResourceItem *eItem);
void indexRuleTriggers(Rule &rule);
void triggerRule(Rule &rule);
bool ruleToMap(const Rule *rule, QVariantMap &map);
bool checkActions(QVariantList actionsList, ApiResponse &rsp);
bool checkConditions(QVariantList conditionsList, ApiResponse &rsp);
// REST API common
QVariantMap errorToMap(int id, const QString &ressource, const QString &description);
// UPNP discovery
void initUpnpDiscovery();
void initDescriptionXml();
// Internet discovery
void initInternetDicovery();
bool setInternetDiscoveryInterval(int minutes);
// Permit join
void initPermitJoin();
bool setPermitJoinDuration(uint8_t duration);
// Otau
void initOtau();
void otauDataIndication(const deCONZ::ApsDataIndication &ind, const deCONZ::ZclFrame &zclFrame);
void otauSendStdNotify(LightNode *node);
bool isOtauBusy();
bool isOtauActive();
int otauLastBusyTimeDelta() const;
// WSNDemo sensor
void wsnDemoDataIndication(const deCONZ::ApsDataIndication &ind);
//Channel Change
void initChangeChannelApi();
bool startChannelChange(quint8 channel);
//reset Device
void initResetDeviceApi();
//Timezone
std::string getTimezone();
//Export/Import/Reset Configuration
bool exportConfiguration();
bool importConfiguration();
bool resetConfiguration(bool resetGW, bool deleteDB);
public Q_SLOTS:
Resource *getResource(const char *resource, const QString &id = QString());
void announceUpnp();
void upnpReadyRead();
void apsdeDataIndication(const deCONZ::ApsDataIndication &ind);
void apsdeDataConfirm(const deCONZ::ApsDataConfirm &conf);
void gpDataIndication(const deCONZ::GpDataIndication &ind);
void gpProcessButtonEvent(const deCONZ::GpDataIndication &ind);
int taskCountForAddress(const deCONZ::Address &address);
void processTasks();
void processGroupTasks();
void nodeEvent(const deCONZ::NodeEvent &event);
void initTimezone();
void initWiFi();
void internetDiscoveryTimerFired();
void internetDiscoveryFinishedRequest(QNetworkReply *reply);
void internetDiscoveryExtractVersionInfo(QNetworkReply *reply);
void internetDiscoveryExtractGeo(QNetworkReply *reply);
void inetProxyHostLookupDone(const QHostInfo &host);
void inetProxyCheckHttpVia(const QString &via);
void scheduleTimerFired();
void permitJoinTimerFired();
void resendPermitJoinTimerFired();
void otauTimerFired();
void lockGatewayTimerFired();
void openClientTimerFired();
void clientSocketDestroyed();
void saveDatabaseTimerFired();
void userActivity();
bool sendBindRequest(BindingTask &bt);
bool sendConfigureReportingRequest(BindingTask &bt, const std::vector<ConfigureReportingRequest> &requests);
bool sendConfigureReportingRequest(BindingTask &bt);
void checkLightBindingsForAttributeReporting(LightNode *lightNode);
void checkSensorBindingsForAttributeReporting(Sensor *sensor);
void checkSensorBindingsForClientClusters(Sensor *sensor);
void checkSensorGroup(Sensor *sensor);
void checkOldSensorGroups(Sensor *sensor);
void deleteGroupsWithDeviceMembership(const QString &id);
void bindingTimerFired();
void bindingToRuleTimerFired();
void bindingTableReaderTimerFired();
void verifyRuleBindingsTimerFired();
void indexRulesTriggers();
void fastRuleCheckTimerFired();
void daylightTimerFired();
void handleRuleEvent(const Event &e);
void queueBindingTask(const BindingTask &bindingTask);
void restartAppTimerFired();
void pollSwUpdateStateTimerFired();
void pollDatabaseWifiTimerFired();
void restartGatewayTimerFired();
void shutDownGatewayTimerFired();
void simpleRestartAppTimerFired();
void pushSensorInfoToCore(Sensor *sensor);
// touchlink
void touchlinkDisconnectNetwork();
void checkTouchlinkNetworkDisconnected();
void startTouchlinkMode(uint8_t channel);
void startTouchlinkModeConfirm(deCONZ::TouchlinkStatus status);
void sendTouchlinkConfirm(deCONZ::TouchlinkStatus status);
void sendTouchlinkScanRequest();
void sendTouchlinkIdentifyRequest();
void sendTouchlinkResetRequest();
void touchlinkTimerFired();
void touchlinkScanTimeout();
void interpanDataIndication(const QByteArray &data);
void touchlinkStartReconnectNetwork(int delay);
void touchlinkReconnectNetwork();
bool isTouchlinkActive();
// channel change
void channelchangeTimerFired();
void changeChannel(quint8 channel);
bool verifyChannel(quint8 channel);
void channelChangeSendConfirm(bool success);
void channelChangeDisconnectNetwork();
void checkChannelChangeNetworkDisconnected();
void channelChangeStartReconnectNetwork(int delay);
void channelChangeReconnectNetwork();
void channelWatchdogTimerFired();
// generic reconnect network
void reconnectTimerFired();
void genericDisconnectNetwork();
void checkNetworkDisconnected();
void startReconnectNetwork(int delay);
void reconnectNetwork();
//reset device
void resetDeviceTimerFired();
void checkResetState();
void resetDeviceSendConfirm(bool success);
// sensors
void startFindSensors();
void findSensorsTimerFired();
void checkInstaModelId(Sensor *sensor);
void delayedFastEnddeviceProbe();
void checkSensorStateTimerFired();
// events
void initEventQueue();
void eventQueueTimerFired();
void enqueueEvent(const Event &event);
// firmware update
void initFirmwareUpdate();
void firmwareUpdateTimerFired();
void checkFirmwareDevices();
void queryFirmwareVersion();
void updateFirmwareDisconnectDevice();
void updateFirmware();
void updateFirmwareWaitFinished();
bool startUpdateFirmware();
//wifi settings
int scanWifiNetworks(const ApiRequest &req, ApiResponse &rsp);
// time manager
void timeManagerTimerFired();
void ntpqFinished();
// gateways
void foundGateway(const QHostAddress &host, quint16 port, const QString &uuid, const QString &name);
public:
void checkRfConnectState();
bool isInNetwork();
void generateGatewayUuid();
void updateEtag(QString &etag);
qint64 getUptime();
void addLightNode(const deCONZ::Node *node);
void updatedLightNodeEndpoint(const deCONZ::NodeEvent &event);
void nodeZombieStateChanged(const deCONZ::Node *node);
LightNode *updateLightNode(const deCONZ::NodeEvent &event);
LightNode *getLightNodeForAddress(const deCONZ::Address &addr, quint8 endpoint = 0);
int getNumberOfEndpoints(quint64 extAddr);
LightNode *getLightNodeForId(const QString &id);
Rule *getRuleForId(const QString &id);
Rule *getRuleForName(const QString &name);
void addSensorNode(const deCONZ::Node *node, const deCONZ::NodeEvent *event = 0);
void addSensorNode(const deCONZ::Node *node, const SensorFingerprint &fingerPrint, const QString &type, const QString &modelId, const QString &manufacturer);
void checkUpdatedFingerPrint(const deCONZ::Node *node, quint8 endpoint, Sensor *sensorNode);
void checkSensorNodeReachable(Sensor *sensor, const deCONZ::NodeEvent *event = 0);
void checkSensorButtonEvent(Sensor *sensor, const deCONZ::ApsDataIndication &ind, const deCONZ::ZclFrame &zclFrame);
void updateSensorNode(const deCONZ::NodeEvent &event);
void updateSensorLightLevel(Sensor &sensor, quint16 measuredValue);
bool isDeviceSupported(const deCONZ::Node *node, const QString &modelId);
Sensor *getSensorNodeForAddressAndEndpoint(const deCONZ::Address &addr, quint8 ep);
Sensor *getSensorNodeForAddress(quint64 extAddr);
Sensor *getSensorNodeForAddress(const deCONZ::Address &addr);
Sensor *getSensorNodeForFingerPrint(quint64 extAddr, const SensorFingerprint &fingerPrint, const QString &type);
Sensor *getSensorNodeForUniqueId(const QString &uniqueId);
Sensor *getSensorNodeForId(const QString &id);
Group *getGroupForName(const QString &name);
Group *getGroupForId(uint16_t id);
Group *getGroupForId(const QString &id);
bool deleteOldGroupOfSwitch(Sensor *sensor, quint16 newGroupId);
Scene *getSceneForId(uint16_t gid, uint8_t sid);
GroupInfo *getGroupInfo(LightNode *lightNode, uint16_t id);
GroupInfo *createGroupInfo(LightNode *lightNode, uint16_t id);
deCONZ::Node *getNodeForAddress(uint64_t extAddr);
deCONZ::ZclCluster *getInCluster(deCONZ::Node *node, uint8_t endpoint, uint16_t clusterId);
uint8_t getSrcEndpoint(RestNodeBase *restNode, const deCONZ::ApsDataRequest &req);
bool processZclAttributes(LightNode *lightNode);
bool processZclAttributes(Sensor *sensorNode);
bool readBindingTable(RestNodeBase *node, quint8 startIndex);
bool getGroupIdentifiers(RestNodeBase *node, quint8 endpoint, quint8 startIndex);
bool readAttributes(RestNodeBase *restNode, quint8 endpoint, uint16_t clusterId, const std::vector<uint16_t> &attributes, uint16_t manufacturerCode = 0);
bool writeAttribute(RestNodeBase *restNode, quint8 endpoint, uint16_t clusterId, const deCONZ::ZclAttribute &attribute, uint16_t manufacturerCode = 0);
bool readSceneAttributes(LightNode *lightNode, uint16_t groupId, uint8_t sceneId);
bool readGroupMembership(LightNode *lightNode, const std::vector<uint16_t> &groups);
void foundGroupMembership(LightNode *lightNode, uint16_t groupId);
void foundGroup(uint16_t groupId);
bool isLightNodeInGroup(const LightNode *lightNode, uint16_t groupId) const;
void deleteLightFromScenes(QString lightId, uint16_t groupId);
// void readAllInGroup(Group *group);