Skip to content

Commit 22d63a7

Browse files
authored
Improve behavior after connection drops, bump dependencies (TuyaAPI#32)
Improve behavior after connection drops, bump dependencies
2 parents ff290e1 + 9f57ba1 commit 22d63a7

6 files changed

Lines changed: 143 additions & 40 deletions

File tree

package-lock.json

Lines changed: 65 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@
3333
"license": "MIT",
3434
"devDependencies": {
3535
"@types/debug": "4.1.5",
36-
"@typescript-eslint/eslint-plugin": "2.3.2",
37-
"@typescript-eslint/parser": "2.3.2",
36+
"@typescript-eslint/eslint-plugin": "2.12.0",
37+
"@typescript-eslint/parser": "2.12.0",
3838
"babel-cli": "6.26.0",
3939
"babel-preset-env": "1.7.0",
40-
"eslint-config-xo-typescript": "0.19.0",
41-
"husky": "3.0.8",
42-
"typescript": "3.6.3",
40+
"eslint-config-xo-typescript": "0.23.0",
41+
"husky": "3.1.0",
42+
"typescript": "3.7.3",
4343
"xo": "0.25.3"
4444
},
4545
"xo": {

src/device.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Device extends EventEmitter implements Device {
2626
private _lastHeartbeat: Date;
2727

2828
constructor({ip, id, gwId = id, key, version = 3.1, port = 6668}: {
29-
ip: string; port: number; key: string; id: string; gwId: string; version: number;
29+
ip: string; port?: number; key: string; id: string; gwId?: string; version?: number;
3030
}) {
3131
super();
3232

@@ -69,6 +69,9 @@ class Device extends EventEmitter implements Device {
6969
// Connect to device
7070
this._log('Connecting...');
7171
this._socket.connect(this.port, this.ip);
72+
73+
// TODO: we should probably set a timeout on connect. Otherwise we just rely
74+
// on TCP to retry sending SYN packets.
7275
}
7376

7477
disconnect(): void {
@@ -144,6 +147,11 @@ class Device extends EventEmitter implements Device {
144147

145148
this.emit('connect');
146149

150+
this._lastHeartbeat = new Date();
151+
152+
// Fetch default property
153+
this.update();
154+
147155
// Start heartbeat pings
148156
this._recursiveHeartbeat();
149157
}
@@ -152,6 +160,8 @@ class Device extends EventEmitter implements Device {
152160
this.connected = false;
153161

154162
this._log('Disconnected.');
163+
164+
this.emit('disconnected');
155165
}
156166

157167
private _handleSocketData(data: Buffer): void {

src/find.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {EventEmitter} from 'events';
2+
import * as dgram from 'dgram';
3+
import Messenger from './lib/messenger';
4+
5+
class Find extends EventEmitter {
6+
private readonly _messenger: Messenger;
7+
private readonly _listener: dgram.Socket;
8+
private readonly _listenerEncrypted: dgram.Socket;
9+
10+
constructor() {
11+
super();
12+
13+
this._messenger = new Messenger({key: '', version: 0});
14+
15+
this._listener = dgram.createSocket({type: 'udp4', reuseAddr: true});
16+
this._listenerEncrypted = dgram.createSocket({type: 'udp4', reuseAddr: true});
17+
18+
this._listener.on('message', this._broadcastHandler.bind(this));
19+
20+
this._listenerEncrypted.on('message', this._broadcastHandler.bind(this));
21+
}
22+
23+
start(): void {
24+
this._listener.bind(6666);
25+
this._listenerEncrypted.bind(6667);
26+
}
27+
28+
stop(): void {
29+
this._listener.close();
30+
this._listener.removeAllListeners();
31+
this._listenerEncrypted.close();
32+
this._listenerEncrypted.removeAllListeners();
33+
}
34+
35+
private _broadcastHandler(message: Buffer): void {
36+
try {
37+
const frame = this._messenger.decode(message);
38+
39+
const payload = JSON.parse(frame.payload.toString('ascii'));
40+
41+
this.emit('broadcast', payload);
42+
} catch (error) {
43+
console.log(error);
44+
// It's possible another application is
45+
// using ports 6666 or 6667, so we shouldn't
46+
// throw on failure.
47+
this.emit('error', error);
48+
}
49+
}
50+
}
51+
52+
export default Find;

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import 'core-js/stable';
44
import 'regenerator-runtime/runtime';
55

66
import Device from './device';
7+
import Find from './find';
78

89
import * as Constants from './lib/constants';
910
import crc from './lib/crc';
1011
import * as crypto from './lib/crypto';
1112
import Frame from './lib/frame';
1213
import Messenger from './lib/messenger';
1314

14-
export {Device, Constants, crc, crypto, Frame, Messenger};
15+
export {Device, Find, Constants, crc, crypto, Frame, Messenger};

src/lib/messenger.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,14 @@ class Messenger extends EventEmitter {
5959
// Absent in messages sent to device
6060
const returnCode = packet.readUInt32BE(16);
6161

62-
// Get the payload
63-
let payload = packet.slice(HEADER_SIZE + 4, HEADER_SIZE + payloadSize - 8);
62+
// Get the payloads
63+
let offset = HEADER_SIZE;
64+
65+
if (returnCode === 0) {
66+
offset = HEADER_SIZE + 4;
67+
}
68+
69+
let payload = packet.slice(offset, offset + payloadSize - 8);
6470

6571
// Check CRC
6672
const expectedCrc = packet.readInt32BE(HEADER_SIZE + payloadSize - 8);

0 commit comments

Comments
 (0)