1'use strict';
2
3const EventEmitter = require('events');
4
5class IotDeviceClient extends EventEmitter {
6    constructor(options){
7        super();
8        if(!options || !options.productKey || !options.deviceName || !options.deviceSecret){
9            throw new Error('device info error');
10        }
11
12        this.options = {
13            productKey: options.productKey,
14            deviceName: options.deviceName,
15            deviceSecret: options.deviceSecret,
16            region: options.region || 'cn-shanghai',
17            keepaliveSec: options.keepaliveSec || 60
18        }
19
20        this._connect();
21    }
22
23    _connect() {
24        __native.AIOT_DEVICE.device(this.options, function(res) {
25            if (!res.handle) {
26                return;
27            }
28            this.IoTDeviceInstance = res.handle;
29            switch (res.code) {
30                case 0:
31                    this.emit('connect'); break;
32                case 1:
33                    this.emit('reconnect'); break;
34                case 2:
35                    this.emit('disconnect'); break;
36                case 3:
37                    this.emit('message', res); break;
38                default : break ;
39            }
40        }.bind(this));
41    }
42
43    getDeviceHandle() {
44        return this.IoTDeviceInstance;
45    }
46
47    subscribe(options, cb) {
48        var ret = __native.AIOT_DEVICE.subscribe(this.IoTDeviceInstance, options, cb || function() {});
49        if (ret < 0) {
50            throw new Error('subscribe topic error', options.topic);
51        }
52
53        return ret;
54    }
55
56    unsubscribe(topic, cb) {
57        var ret = __native.AIOT_DEVICE.unsubscribe(this.IoTDeviceInstance, topic, cb || function() {});
58        if (ret < 0) {
59            throw new Error('unsubscribe topic error', topic);
60        }
61
62        return ret;
63    }
64
65    publish(options, cb) {
66        var ret = __native.AIOT_DEVICE.publish(this.IoTDeviceInstance, options, cb || function() {});
67        if (ret < 0) {
68            throw new Error('publish topic info error', options.topic);
69        }
70
71        return ret;
72    }
73
74    postProps(params, cb) {
75        var ret = __native.AIOT_DEVICE.postProps(this.IoTDeviceInstance, params, cb || function() {});
76        if (ret < 0) {
77            throw new Error('post props error');
78        }
79
80        return ret;
81    }
82
83    onProps(cb) {
84        var ret = __native.AIOT_DEVICE.onProps(this.IoTDeviceInstance, cb);
85        if (ret < 0) {
86            throw new Error('on props error');
87        }
88
89        return ret;
90    }
91
92    postEvent(options, cb) {
93        var ret = __native.AIOT_DEVICE.postEvent(this.IoTDeviceInstance, options, cb || function() {});
94        if (ret < 0) {
95            throw new Error('post event error');
96        }
97
98        return ret;
99    }
100
101    onService(cb) {
102        var ret = __native.AIOT_DEVICE.onService(this.IoTDeviceInstance, cb);
103        if (ret < 0) {
104            throw new Error('on service error');
105        }
106
107        return ret;
108    }
109
110    end(cb) {
111        var ret = __native.AIOT_DEVICE.close(this.IoTDeviceInstance, cb || function() {});
112        if (ret < 0) {
113            throw new Error('end iot client error');
114        }
115
116        return ret;
117    }
118}
119
120class IotGatewayClient extends EventEmitter{
121    constructor(options){
122        super();
123        if(!options || !options.productKey || !options.deviceName || !options.deviceSecret){
124            throw new Error('device info error');
125        }
126
127        this.options = {
128            productKey: options.productKey,
129            deviceName: options.deviceName,
130            deviceSecret: options.deviceSecret,
131            keepaliveSec: options.keepaliveSec || 60,
132            region: options.region || 'cn-shanghai'
133        }
134
135        this._on();
136        this._connect();
137    }
138
139    _connect() {
140        __native.AIOT_GATEWAY.gateway(this.options, function(res) {
141            if (!res.handle || res.code != 0) {
142                return;
143            }
144            this.IoTGatewayInstance = res.handle;
145            this.emit('connect');
146        }.bind(this));
147    }
148
149    _on() {
150        __native.AIOT_GATEWAY.onMqttMessage(function(res) {
151            switch (res.code) {
152                case 1:
153                    this.emit('reconnect'); break;
154                case 2:
155                    this.emit('disconnect'); break;
156                case 3:
157                    this.emit('message', res); break;
158                default : break ;
159            }
160        }.bind(this));
161    }
162
163    addTopo(options, cb) {
164        var ret = __native.AIOT_GATEWAY.addTopo(this.IoTGatewayInstance, options, cb || function(ret, message) {});
165        if (ret < 0) {
166            throw new Error('add topo error');
167        }
168
169        return ret;
170    }
171
172    getTopo(cb) {
173        var ret = __native.AIOT_GATEWAY.getTopo(this.IoTGatewayInstance, cb || function(ret, message) {});
174        if (ret < 0) {
175            throw new Error('get topo error');
176        }
177
178        return ret;
179    }
180
181    removeTopo(options, cb) {
182        var ret = __native.AIOT_GATEWAY.removeTopo(this.IoTGatewayInstance, options, cb || function() {});
183        if (ret < 0) {
184            throw new Error('remove topo error');
185        }
186
187        return ret;
188    }
189
190    login(options, cb) {
191        var ret = __native.AIOT_GATEWAY.login(this.IoTGatewayInstance, options, cb || function() {});
192        if (ret < 0) {
193            throw new Error('aiot subdev login error');
194        }
195
196        return ret;
197    }
198
199    logout(options, cb) {
200        var ret = __native.AIOT_GATEWAY.logout(this.IoTGatewayInstance, options, cb || function() {});
201        if (ret < 0) {
202            throw new Error('aiot subdev logout error');
203        }
204
205        return ret;
206    }
207
208    registerSubDevice(options, cb) {
209        var ret = __native.AIOT_GATEWAY.registerSubDevice(this.IoTGatewayInstance, options, cb || function(ret, message) {});
210        if (ret < 0) {
211            throw new Error('aiot register subdev error');
212        }
213
214        return ret;
215    }
216
217    subscribe(params, cb) {
218        var ret = __native.AIOT_GATEWAY.subscribe(this.IoTGatewayInstance, params, cb || function() {});
219        if (ret < 0) {
220            throw new Error('subscribe topic error', options.topic);
221        }
222
223        return ret;
224    }
225
226    unsubscribe(topic, cb) {
227        var ret = __native.AIOT_GATEWAY.unsubscribe(this.IoTGatewayInstance, topic, cb || function() {});
228        if (ret < 0) {
229            throw new Error('unsubscribe topic error', topic);
230        }
231
232        return ret;
233    }
234
235    publish(options, cb) {
236        var ret = __native.AIOT_GATEWAY.publish(this.IoTGatewayInstance, options, cb || function() {});
237        if (ret < 0) {
238            throw new Error('publish topic info error', options.topic);
239        }
240
241        return ret;
242    }
243}
244
245function dynreg(options, cb) {
246    var ret = __native.AIOT_DEVICE.register(options, cb);
247        if (ret < 0) {
248            throw new Error('dynmic register error');
249        }
250
251    return ret;
252}
253
254function device(options) {
255    return new IotDeviceClient(options);
256}
257
258function gateway(options){
259    return new IotGatewayClient(options);
260}
261
262module.exports = {
263    device,
264    gateway,
265    dynreg
266}