1 |
|
2 | "use strict";
|
3 | var request = require("request");
|
4 | var mqtt = require("mqtt");
|
5 | var Q = require("q");
|
6 | var low = require("lowdb");
|
7 | var fs = require("fs");
|
8 | (function () {
|
9 | var dir = './resource';
|
10 | if (!fs.existsSync(dir)) {
|
11 | fs.mkdirSync(dir);
|
12 | }
|
13 | })();
|
14 | var db = new low('./resource/db.json');
|
15 | var messageHandler;
|
16 |
|
17 | function init(_appID, _appKey, _site) {
|
18 | db.defaults({ app: {}, gateway: {}, endNodes: [] }).value();
|
19 | exports.appID = _appID;
|
20 | exports.appKey = _appKey;
|
21 | exports.site = _site;
|
22 | db.set('app.appID', exports.appID).value();
|
23 | db.set('app.appKey', exports.appKey).value();
|
24 | db.set('app.site', exports.site).value();
|
25 | }
|
26 | exports.init = init;
|
27 |
|
28 | function onboardGatewayByOwner(ownerToken, ownerID, vendorThingID, password, type, properties) {
|
29 | var deferred = Q.defer();
|
30 | var options = {
|
31 | method: 'POST',
|
32 | url: exports.site + '/thing-if/apps/' + exports.appID + '/onboardings',
|
33 | headers: {
|
34 | authorization: 'Bearer ' + ownerToken,
|
35 | 'content-type': 'application/vnd.kii.onboardingWithVendorThingIDByOwner+json'
|
36 | },
|
37 | body: JSON.stringify({
|
38 | 'vendorThingID': vendorThingID,
|
39 | 'thingPassword': password,
|
40 | 'owner': 'USER:' + ownerID,
|
41 | 'thingType': type,
|
42 | 'layoutPosition': 'GATEWAY'
|
43 | })
|
44 | };
|
45 | request(options, function (error, response, body) {
|
46 | if (error)
|
47 | deferred.reject(new Error(error));
|
48 | db.set('gateway.vendorThingID', vendorThingID).value();
|
49 | db.set('gateway.thingID', JSON.parse(body).thingID).value();
|
50 | db.set('gateway.accessToken', JSON.parse(body).accessToken).value();
|
51 | deferred.resolve({
|
52 | gatewayInfo: JSON.parse(body)
|
53 | });
|
54 | });
|
55 | return deferred.promise;
|
56 | }
|
57 | exports.onboardGatewayByOwner = onboardGatewayByOwner;
|
58 |
|
59 | function onboardEndnodeByOwner(ownerToken, ownerID, endNodeVendorThingID, endNodePassword, type, properties) {
|
60 | var gatewayThingID = db.get('gateway.thingID').value();
|
61 | var deferred = Q.defer();
|
62 | var options = {
|
63 | method: 'POST',
|
64 | url: exports.site + '/thing-if/apps/' + exports.appID + '/onboardings',
|
65 | headers: {
|
66 | authorization: 'Bearer ' + ownerToken,
|
67 | 'content-type': 'application/vnd.kii.OnboardingEndNodeWithGatewayThingID+json'
|
68 | },
|
69 | body: JSON.stringify({
|
70 | 'endNodeVendorThingID': endNodeVendorThingID,
|
71 | 'endNodePassword': endNodePassword,
|
72 | 'gatewayThingID': gatewayThingID,
|
73 | 'endNodeThingProperties': properties,
|
74 | 'endNodeThingType': type,
|
75 | 'owner': 'USER:' + ownerID
|
76 | })
|
77 | };
|
78 | request(options, function (error, response, body) {
|
79 | if (error)
|
80 | deferred.reject(new Error(error));
|
81 | if (db.get('endNodes').find({ 'vendorThingID': endNodeVendorThingID }).value())
|
82 | db.get('endNodes').find({ 'vendorThingID': endNodeVendorThingID }).assign({
|
83 | vendorThingID: endNodeVendorThingID,
|
84 | accessToken: JSON.parse(body).accessToken,
|
85 | endNodeThingID: JSON.parse(body).endNodeThingID
|
86 | }).value();
|
87 | else {
|
88 | if (!db.has('endNodes').value())
|
89 | db.set('endNodes', []).value();
|
90 | db.get('endNodes').push({
|
91 | vendorThingID: endNodeVendorThingID,
|
92 | accessToken: JSON.parse(body).accessToken,
|
93 | endNodeThingID: JSON.parse(body).endNodeThingID
|
94 | }).value();
|
95 | }
|
96 | deferred.resolve(JSON.parse(body));
|
97 | });
|
98 | return deferred.promise;
|
99 | }
|
100 | exports.onboardEndnodeByOwner = onboardEndnodeByOwner;
|
101 |
|
102 | function updateEndnodeState(ownerToken, endNodeThingID, states) {
|
103 | var deferred = Q.defer();
|
104 | var options = {
|
105 | method: 'PUT',
|
106 | url: exports.site + ("/thing-if/apps/" + exports.appID + "/targets/thing:" + endNodeThingID + "/states"),
|
107 | headers: {
|
108 | authorization: 'Bearer ' + ownerToken,
|
109 | 'content-type': 'application/json'
|
110 | },
|
111 | body: JSON.stringify(states)
|
112 | };
|
113 | request(options, function (error, response, body) {
|
114 | if (error)
|
115 | deferred.reject(new Error(error));
|
116 | if (response.statusCode !== 204)
|
117 | deferred.reject(body);
|
118 | deferred.resolve(response.statusCode);
|
119 | });
|
120 | return deferred.promise;
|
121 | }
|
122 | exports.updateEndnodeState = updateEndnodeState;
|
123 |
|
124 | function updateEndnodeConnectivity(ownerToken, endNodeThingID, online) {
|
125 | var gatewayThingID = db.get('gateway.thingID').value();
|
126 | var deferred = Q.defer();
|
127 | var options = {
|
128 | method: 'PUT',
|
129 | url: exports.site + ("/thing-if/apps/" + exports.appID + "/things/" + gatewayThingID + "/end-nodes/" + endNodeThingID + "/connection"),
|
130 | headers: {
|
131 | authorization: 'Bearer ' + ownerToken,
|
132 | 'content-type': 'application/json'
|
133 | },
|
134 | body: JSON.stringify({
|
135 | 'online': online
|
136 | })
|
137 | };
|
138 | request(options, function (error, response, body) {
|
139 | if (error)
|
140 | deferred.reject(new Error(error));
|
141 | if (response.statusCode !== 204)
|
142 | deferred.reject(body);
|
143 | deferred.resolve(response.statusCode);
|
144 | });
|
145 | return deferred.promise;
|
146 | }
|
147 | exports.updateEndnodeConnectivity = updateEndnodeConnectivity;
|
148 |
|
149 | function detectEndnodeOnboardingStatus(endNodeVendorThingID) {
|
150 | return !!db.get('endNodes').find({ vendorThingID: endNodeVendorThingID }).value();
|
151 | }
|
152 | exports.detectEndnodeOnboardingStatus = detectEndnodeOnboardingStatus;
|
153 |
|
154 | function startCommandReceiver(chainInput) {
|
155 | var _this = this;
|
156 | var deferred = Q.defer();
|
157 | var gatewayInfo = chainInput.gatewayInfo;
|
158 | var mqttEndpoint = gatewayInfo.mqttEndpoint;
|
159 | var option = {
|
160 | 'port': mqttEndpoint.portTCP,
|
161 | 'clientId': mqttEndpoint.mqttTopic,
|
162 | 'username': mqttEndpoint.username,
|
163 | 'password': mqttEndpoint.password,
|
164 | 'reconnectPeriod': 55000,
|
165 | 'keepalive': 60
|
166 | };
|
167 | console.log(mqttEndpoint);
|
168 | var client = mqtt.connect('tcp://' + mqttEndpoint.host, option);
|
169 | client.on('connect', function (connack) {
|
170 | if (!connack.sessionPresent) {
|
171 | client.subscribe(mqttEndpoint.mqttTopic, {
|
172 | qos: 0,
|
173 | retain: false
|
174 | }, function (err, granted) {
|
175 | if (err)
|
176 | deferred.reject(err);
|
177 | });
|
178 | }
|
179 | else {
|
180 | throw new Error('error connecting to MQTT broker');
|
181 | }
|
182 | });
|
183 | client.on('error', function (error) {
|
184 | throw new Error(error);
|
185 | });
|
186 | client.on('message', function (topic, message, packet) {
|
187 | var i;
|
188 | var messageStr = '';
|
189 | for (i = 0; i < message.length; i++) {
|
190 | messageStr += '%' + ('0' + message[i].toString(16)).slice(-2);
|
191 | }
|
192 | messageStr = decodeURIComponent(messageStr);
|
193 | _this.messageHandler(messageStr);
|
194 | });
|
195 | }
|
196 | exports.startCommandReceiver = startCommandReceiver;
|
197 | function setOnCommandMessage(messageHandler) {
|
198 | this.messageHandler = messageHandler;
|
199 | }
|
200 | exports.setOnCommandMessage = setOnCommandMessage;
|