@camera.ui/camera-ui-tuya 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,214 @@
1
+ import { Camera } from './camera.js';
2
+ import { TuyaCloud } from './tuya/cloud.js';
3
+ import { TuyaPulsar } from './tuya/pulsar.js';
4
+ import { getTuyaPulsarEndpoint, TUYA_COUNTRIES } from './tuya/utils.js';
5
+ export default class Tuya {
6
+ config;
7
+ logger;
8
+ api;
9
+ cameras = new Map();
10
+ tuyaCameras = new Map();
11
+ cloud;
12
+ pulsar;
13
+ cleanOrphanedCamerasTimeout;
14
+ constructor(logger, api) {
15
+ this.logger = logger;
16
+ this.api = api;
17
+ this.config = api.configService.all();
18
+ this.config.homeWhitelist = api.configService.get('homeWhitelist', [], (value) => Array.isArray(value), false, true);
19
+ this.api.on('finishLaunching', this.start.bind(this));
20
+ this.api.on('shutdown', this.stop.bind(this));
21
+ }
22
+ configureCameras(cameras) {
23
+ for (const camera of cameras) {
24
+ this.cameras.set(camera.id, camera);
25
+ }
26
+ }
27
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
+ async onFormSubmit(actionId, payload) { }
29
+ async start() {
30
+ try {
31
+ await this.connect();
32
+ }
33
+ catch (error) {
34
+ this.logger.error('An error occured during connecting:', error);
35
+ }
36
+ this.cleanOrphanedCamerasTimeout = setTimeout(() => {
37
+ this.checkOrphanedCameras();
38
+ }, 45 * 1000);
39
+ }
40
+ stop() {
41
+ clearTimeout(this.cleanOrphanedCamerasTimeout);
42
+ this.pulsar?.stop();
43
+ this.cloud = undefined;
44
+ this.pulsar = undefined;
45
+ this.logger.log('Plugin stopped');
46
+ }
47
+ async connect() {
48
+ try {
49
+ const userId = this.config.userId;
50
+ const accessId = this.config.accessId;
51
+ const accessKey = this.config.accessKey;
52
+ const country = TUYA_COUNTRIES.find((value) => value.country == this.config.country);
53
+ const missingItems = [];
54
+ if (!userId) {
55
+ missingItems.push('User Id');
56
+ }
57
+ if (!accessId) {
58
+ missingItems.push('Access Id');
59
+ }
60
+ if (!accessKey) {
61
+ missingItems.push('Access Key');
62
+ }
63
+ if (!country) {
64
+ missingItems.push('Country');
65
+ }
66
+ if (missingItems.length > 0) {
67
+ this.logger.error(`You must provide your ${missingItems.join(', ')}.`);
68
+ return;
69
+ }
70
+ if (!this.cloud) {
71
+ this.cloud = new TuyaCloud(userId, accessId, accessKey, country);
72
+ }
73
+ // If it cannot fetch devices, then that means it's permission denied.
74
+ // For some reason, when generating a token does not validate authorization.
75
+ if (!(await this.cloud.fetchDevices())) {
76
+ this.logger.error('Failed to log in with credentials. Please try again.');
77
+ this.cloud = undefined;
78
+ return;
79
+ }
80
+ this.logger.log('Successsfully logged in with credentials! Now discovering devices.');
81
+ if (this.pulsar) {
82
+ this.pulsar.stop();
83
+ }
84
+ this.pulsar = new TuyaPulsar({
85
+ accessId: accessId,
86
+ accessKey: accessKey,
87
+ url: getTuyaPulsarEndpoint(country),
88
+ });
89
+ this.pulsar.open(() => {
90
+ this.logger.log('TulsaPulse: opened connection.');
91
+ });
92
+ this.pulsar.message((ws, message) => {
93
+ this.pulsar?.ackMessage(message.messageId);
94
+ const tuyaDevice = this.handlePulsarMessage(message);
95
+ if (!tuyaDevice) {
96
+ return;
97
+ }
98
+ tuyaDevice.updateState();
99
+ });
100
+ this.pulsar.reconnect(() => {
101
+ this.logger.log('TuyaPulse: restarting connection.');
102
+ });
103
+ this.pulsar.close(() => {
104
+ this.logger.warn('TuyaPulse: closed connection.');
105
+ });
106
+ this.pulsar.error((ws, error) => {
107
+ this.logger.error(`TuyaPulse: ${error}`);
108
+ });
109
+ this.pulsar.maxRetries(() => {
110
+ this.logger.error('There was an error trying to connect to Message Service (TuyaPulse). Connection Max Reconnection Timed Out');
111
+ });
112
+ this.pulsar.start();
113
+ for (const cloudCamera of this.cloud.cameras || []) {
114
+ this.addOrUpdateDevice(cloudCamera);
115
+ }
116
+ }
117
+ catch (error) {
118
+ this.logger.error('An error occured during connecting:', error);
119
+ }
120
+ }
121
+ handlePulsarMessage(message) {
122
+ const data = message.payload.data;
123
+ const { devId } = data;
124
+ let refreshDevice = false;
125
+ const device = this.cloud?.cameras?.find((c) => c.id === devId);
126
+ const pulsarMessageLogs = ['Received new TuyaPulsar Message:'];
127
+ if (data.bizCode) {
128
+ if (device && (data.bizCode === 'online' || data.bizCode === 'offline')) {
129
+ // Device status changed
130
+ const isOnline = data.bizCode === 'online';
131
+ device.online = isOnline;
132
+ refreshDevice = true;
133
+ pulsarMessageLogs.push(`- Changed device to ${data.bizCode} for ${device.name}`);
134
+ }
135
+ else if (device && data.bizCode === 'delete') {
136
+ // Device needs to be deleted
137
+ // - devId
138
+ // - uid
139
+ pulsarMessageLogs.push(`- Delete ${device.name}`);
140
+ this.deviceRemoved(device);
141
+ }
142
+ else if (data.bizCode === 'add') {
143
+ // There is a new device added, refetch
144
+ pulsarMessageLogs.push(`- Add new device with devId: ${data.devId}`);
145
+ this.cloud?.fetchDevices();
146
+ for (const cloudCamera of this.cloud?.cameras || []) {
147
+ if (this.tuyaCameras.get(cloudCamera.id)) {
148
+ continue;
149
+ }
150
+ this.addOrUpdateDevice(cloudCamera);
151
+ }
152
+ }
153
+ else {
154
+ pulsarMessageLogs.push(`- Unknown bizCode: ${data.bizCode} with data: ${JSON.stringify(data.bizData)}.`);
155
+ }
156
+ }
157
+ else if (device && data.status) {
158
+ const newStatus = data.status || [];
159
+ pulsarMessageLogs.push(`- ${device.name} received new status updates:`);
160
+ newStatus.forEach((item) => {
161
+ pulsarMessageLogs.push(`\t- ${JSON.stringify(item)}`);
162
+ const index = device.status.findIndex((status) => status.code == item.code);
163
+ if (index !== -1) {
164
+ device.status[index].value = item.value;
165
+ }
166
+ });
167
+ refreshDevice = true;
168
+ }
169
+ else {
170
+ pulsarMessageLogs.push(`- Unknown TuyaPulsar message received: ${JSON.stringify(data)}`);
171
+ }
172
+ pulsarMessageLogs.push('');
173
+ this.logger.log(pulsarMessageLogs.join('\n'));
174
+ if (refreshDevice) {
175
+ return this.tuyaCameras.get(devId);
176
+ }
177
+ }
178
+ async addOrUpdateDevice(cloudCamera) {
179
+ const nativeId = cloudCamera.id;
180
+ if (this.tuyaCameras.get(nativeId)) {
181
+ this.logger.debug(`Device ${cloudCamera.name} already exists, skipping...`);
182
+ return;
183
+ }
184
+ const camera = new Camera(this, this.cloud, cloudCamera, this.logger);
185
+ await camera.createCameraDevice();
186
+ this.cameras.set(camera.cameraDevice.id, camera.cameraDevice);
187
+ this.tuyaCameras.set(nativeId, camera);
188
+ this.cameras.set(camera.cameraDevice.id, camera.cameraDevice);
189
+ }
190
+ async deviceRemoved(cloudCamera) {
191
+ const nativeId = cloudCamera.id;
192
+ this.logger.debug(`A device has been removed: ${cloudCamera.name}`);
193
+ this.tuyaCameras.delete(nativeId);
194
+ this.cameras.forEach(async (cameraDevice) => {
195
+ if (cameraDevice.nativeId === nativeId) {
196
+ this.logger.debug(`Removing camera ${cameraDevice.name}`);
197
+ this.cameras.delete(cameraDevice.id);
198
+ await this.api.deviceManager.removeCameraById(cameraDevice.id);
199
+ }
200
+ });
201
+ }
202
+ async checkOrphanedCameras() {
203
+ // Remove orphaned cameras
204
+ for (const [cameraId, cameraDevice] of this.cameras) {
205
+ const nativeId = cameraDevice.nativeId;
206
+ if (!this.tuyaCameras.get(nativeId)) {
207
+ this.logger.warn('Removing camera', cameraDevice.name);
208
+ this.cameras.delete(cameraId);
209
+ await this.api.deviceManager.removeCameraById(cameraDevice.id);
210
+ }
211
+ }
212
+ }
213
+ }
214
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/peer.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { ReplaySubject, Subject } from 'rxjs';
2
+ import { MediaStreamTrack, RTCIceCandidate } from 'werift';
3
+ import type { BasicPeerConnection, CameraDevice, PluginLogger } from '@camera.ui/types';
4
+ import type { RtcpPacket, RTCSessionDescription, RtpPacket } from 'werift';
5
+ import type Tuya from './index.js';
6
+ import type { TuyaDeviceConfig } from './tuya/const.js';
7
+ export declare class CustomPeerConnection implements BasicPeerConnection {
8
+ private pc?;
9
+ private sessionId;
10
+ private platform;
11
+ private cameraDevice;
12
+ private cloudCamera;
13
+ private logger;
14
+ private mqtt?;
15
+ private deviceWebRTConfig?;
16
+ private mqttWebRTConfig?;
17
+ onAudioRtp: Subject<RtpPacket>;
18
+ onAudioRtcp: Subject<RtcpPacket>;
19
+ onVideoRtp: Subject<RtpPacket>;
20
+ onVideoRtcp: Subject<RtcpPacket>;
21
+ onIceCandidate: Subject<RTCIceCandidate>;
22
+ onConnectionState: ReplaySubject<"closed" | "failed" | "disconnected" | "new" | "connecting" | "connected">;
23
+ returnAudioTrack: MediaStreamTrack;
24
+ constructor(platform: Tuya, cameraDevice: CameraDevice, cloudCamera: TuyaDeviceConfig, logger: PluginLogger);
25
+ createPeerConnection(): Promise<void>;
26
+ createOffer(): Promise<RTCSessionDescription>;
27
+ acceptAnswer(answer: RTCSessionDescription): Promise<void>;
28
+ addIceCandidate(candidate: RTCIceCandidate): Promise<void>;
29
+ close(): Promise<void>;
30
+ private createLocalDescription;
31
+ private sendIceCandidate;
32
+ private endSession;
33
+ private reset;
34
+ }
package/dist/peer.js ADDED
@@ -0,0 +1,274 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { ReplaySubject, Subject } from 'rxjs';
3
+ import { MediaStreamTrack, RTCIceCandidate, RTCPeerConnection, RTCRtpCodecParameters } from 'werift';
4
+ import { TuyaMQ } from './tuya/mq.js';
5
+ export class CustomPeerConnection {
6
+ pc;
7
+ sessionId;
8
+ platform;
9
+ cameraDevice;
10
+ cloudCamera;
11
+ logger;
12
+ mqtt;
13
+ deviceWebRTConfig;
14
+ mqttWebRTConfig;
15
+ onAudioRtp = new Subject();
16
+ onAudioRtcp = new Subject();
17
+ onVideoRtp = new Subject();
18
+ onVideoRtcp = new Subject();
19
+ onIceCandidate = new Subject();
20
+ onConnectionState = new ReplaySubject(1);
21
+ returnAudioTrack = new MediaStreamTrack({ kind: 'audio' });
22
+ constructor(platform, cameraDevice, cloudCamera, logger) {
23
+ this.platform = platform;
24
+ this.cameraDevice = cameraDevice;
25
+ this.cloudCamera = cloudCamera;
26
+ this.logger = logger;
27
+ this.sessionId = randomUUID();
28
+ }
29
+ async createPeerConnection() {
30
+ const deviceWebRTConfigResponse = await this.platform.cloud?.getDeviceWebRTConfig(this.cloudCamera);
31
+ if (!deviceWebRTConfigResponse?.success) {
32
+ this.logger.error(`[${this.cameraDevice.name}] There was an error retrieving WebRTConfig.`);
33
+ throw new Error(`Failed to create device rtc config for ${this.cameraDevice.name}: request failed: ${deviceWebRTConfigResponse?.result}.`);
34
+ }
35
+ this.deviceWebRTConfig = deviceWebRTConfigResponse.result;
36
+ const mqResponse = await this.platform.cloud?.getWebRTCMQConfig(this.deviceWebRTConfig);
37
+ if (!mqResponse?.success) {
38
+ this.logger.error(`[${this.cameraDevice.name}] There was an error retrieving WebRTC MQTT RTC Config.`);
39
+ throw new Error(`Failed to create rtc mqtt config for ${this.cameraDevice.name}: request failed: ${mqResponse?.result}.`);
40
+ }
41
+ this.mqttWebRTConfig = mqResponse.result;
42
+ this.mqtt = new TuyaMQ(this.mqttWebRTConfig);
43
+ await this.mqtt.connect();
44
+ const iceServers = this.deviceWebRTConfig.p2p_config.ices.map((ice) => {
45
+ return {
46
+ credential: ice.credential,
47
+ urls: ice.urls,
48
+ username: ice.username,
49
+ };
50
+ });
51
+ const pc = (this.pc = new RTCPeerConnection({
52
+ codecs: {
53
+ audio: [
54
+ new RTCRtpCodecParameters({
55
+ mimeType: 'audio/opus',
56
+ clockRate: 48000,
57
+ channels: 2,
58
+ }),
59
+ new RTCRtpCodecParameters({
60
+ mimeType: 'audio/PCMU',
61
+ clockRate: 8000,
62
+ channels: 1,
63
+ payloadType: 0,
64
+ }),
65
+ ],
66
+ video: [
67
+ new RTCRtpCodecParameters({
68
+ mimeType: 'video/H264',
69
+ clockRate: 90000,
70
+ rtcpFeedback: [{ type: 'transport-cc' }, { type: 'ccm', parameter: 'fir' }, { type: 'nack' }, { type: 'nack', parameter: 'pli' }, { type: 'goog-remb' }],
71
+ parameters: 'packetization-mode=1;profile-level-id=640029;level-asymmetry-allowed=1',
72
+ }),
73
+ ],
74
+ },
75
+ iceServers,
76
+ iceTransportPolicy: 'all',
77
+ // bundlePolicy: 'disable',
78
+ }));
79
+ const audioTransceiver = pc.addTransceiver(this.returnAudioTrack, {
80
+ direction: 'sendrecv',
81
+ });
82
+ const videoTransceiver = pc.addTransceiver('video', {
83
+ direction: 'recvonly',
84
+ });
85
+ audioTransceiver.onTrack.subscribe((track) => {
86
+ track.onReceiveRtp.subscribe((rtp) => {
87
+ this.onAudioRtp.next(rtp);
88
+ });
89
+ track.onReceiveRtcp.subscribe((rtcp) => {
90
+ this.onAudioRtcp.next(rtcp);
91
+ });
92
+ });
93
+ videoTransceiver.onTrack.subscribe((track) => {
94
+ track.onReceiveRtp.subscribe((rtp) => {
95
+ this.onVideoRtp.next(rtp);
96
+ });
97
+ track.onReceiveRtcp.subscribe((rtcp) => {
98
+ this.onVideoRtcp.next(rtcp);
99
+ });
100
+ track.onReceiveRtp.once(() => {
101
+ setInterval(() => videoTransceiver.receiver.sendRtcpPLI(track.ssrc), 4000);
102
+ });
103
+ });
104
+ pc.onIceCandidate.subscribe((iceCandidate) => {
105
+ this.onIceCandidate.next(iceCandidate);
106
+ });
107
+ pc.iceConnectionStateChange.subscribe(() => {
108
+ if (pc.iceConnectionState === 'closed') {
109
+ this.onConnectionState.next('closed');
110
+ }
111
+ });
112
+ pc.connectionStateChange.subscribe(() => {
113
+ this.onConnectionState.next(pc.connectionState);
114
+ });
115
+ this.onIceCandidate.subscribe((candidate) => {
116
+ this.sendIceCandidate(candidate);
117
+ });
118
+ const offer = await pc.createOffer();
119
+ const offerMessage = {
120
+ mode: 'webrtc',
121
+ sdp: offer.sdp,
122
+ auth: this.deviceWebRTConfig.auth,
123
+ stream_type: 1,
124
+ };
125
+ const webRTCMessage = {
126
+ protocol: 302,
127
+ pv: '2.2',
128
+ t: Date.now(),
129
+ data: {
130
+ header: {
131
+ type: 'offer',
132
+ from: this.mqttWebRTConfig.source_topic.split('/')[3],
133
+ to: this.deviceWebRTConfig.id,
134
+ sub_dev_id: '',
135
+ sessionid: this.sessionId,
136
+ moto_id: this.deviceWebRTConfig.moto_id,
137
+ tid: '',
138
+ },
139
+ msg: offerMessage,
140
+ },
141
+ };
142
+ this.mqtt.publish(JSON.stringify(webRTCMessage));
143
+ this.logger.log('[WebRTC] - TuyaMQ: Sent Offer w/ sdp.');
144
+ const answer = await this.createLocalDescription();
145
+ await this.acceptAnswer(answer);
146
+ }
147
+ async createOffer() {
148
+ if (!this.pc) {
149
+ throw new Error('Peer connection not created');
150
+ }
151
+ const offer = await this.pc.createOffer();
152
+ await this.pc.setLocalDescription(offer);
153
+ return offer;
154
+ }
155
+ async acceptAnswer(answer) {
156
+ if (!this.pc) {
157
+ throw new Error('Peer connection not created');
158
+ }
159
+ await this.pc.setRemoteDescription(answer);
160
+ }
161
+ async addIceCandidate(candidate) {
162
+ if (!this.pc) {
163
+ throw new Error('Peer connection not created');
164
+ }
165
+ await this.pc.addIceCandidate(candidate);
166
+ }
167
+ async close() {
168
+ try {
169
+ this.endSession();
170
+ await this.pc?.close();
171
+ }
172
+ catch {
173
+ //
174
+ }
175
+ this.reset();
176
+ }
177
+ async createLocalDescription() {
178
+ return new Promise((resolve, reject) => {
179
+ const messageHandler = (_client, message) => {
180
+ const webRTCMessage = JSON.parse(message);
181
+ this.logger.log(`[WebRTC] - TuyaMQ message received: ${JSON.stringify(webRTCMessage)}`);
182
+ if (webRTCMessage.data.header.type == 'answer') {
183
+ const answer = webRTCMessage.data.msg;
184
+ resolve({
185
+ sdp: answer.sdp,
186
+ type: 'answer',
187
+ });
188
+ }
189
+ else if (webRTCMessage.data.header.type == 'candidate') {
190
+ const candidate = webRTCMessage.data.msg;
191
+ if (!candidate?.candidate || candidate.candidate == '') {
192
+ return;
193
+ }
194
+ this.addIceCandidate(new RTCIceCandidate({
195
+ candidate: candidate.candidate,
196
+ sdpMid: '0',
197
+ sdpMLineIndex: 0,
198
+ }));
199
+ }
200
+ else {
201
+ this.logger.error('[WebRTC] - TuyaMQ: There was an error trying to get an answer or candidate from TuyaMQ.');
202
+ this.mqtt?.removeMessageListener(messageHandler);
203
+ this.mqtt?.stop();
204
+ reject(new Error('[WebRTC] - TuyaMQ: There was an error trying to get an answer or candidate from TuyaMQ.'));
205
+ }
206
+ };
207
+ this.mqtt?.message(messageHandler);
208
+ });
209
+ }
210
+ async sendIceCandidate(candidate) {
211
+ if (!this.deviceWebRTConfig || !this.mqttWebRTConfig || !this.mqtt) {
212
+ return;
213
+ }
214
+ const acandidate = candidate.candidate ? `a=${candidate.candidate}` : '';
215
+ const candidateMessage = {
216
+ mode: 'webrtc',
217
+ candidate: acandidate,
218
+ };
219
+ const webRTCMQMessage = {
220
+ protocol: 302,
221
+ pv: '2.2',
222
+ t: Date.now(),
223
+ data: {
224
+ header: {
225
+ type: 'candidate',
226
+ from: this.mqttWebRTConfig.source_topic.split('/')[3],
227
+ to: this.deviceWebRTConfig.id,
228
+ sub_dev_id: '',
229
+ sessionid: this.sessionId,
230
+ moto_id: this.deviceWebRTConfig.moto_id,
231
+ tid: '',
232
+ },
233
+ msg: candidateMessage,
234
+ },
235
+ };
236
+ this.mqtt.publish(JSON.stringify(webRTCMQMessage));
237
+ this.logger.log('[WebRTC] - TuyaMQ: Sent candidate.');
238
+ }
239
+ endSession() {
240
+ if (!this.deviceWebRTConfig || !this.mqttWebRTConfig || !this.mqtt) {
241
+ return;
242
+ }
243
+ const webRTCMessage = {
244
+ protocol: 302,
245
+ pv: '2.2',
246
+ t: Date.now(),
247
+ data: {
248
+ header: {
249
+ type: 'disconnect',
250
+ from: this.mqttWebRTConfig.source_topic.split('/')[3],
251
+ to: this.deviceWebRTConfig.id,
252
+ sub_dev_id: '',
253
+ sessionid: this.sessionId,
254
+ moto_id: this.deviceWebRTConfig.moto_id,
255
+ tid: '',
256
+ },
257
+ msg: {
258
+ mode: 'webrtc',
259
+ },
260
+ },
261
+ };
262
+ this.mqtt.publish(JSON.stringify(webRTCMessage));
263
+ this.logger.log('[WebRTC] - TuyaMQ: Sent disconnect.');
264
+ this.mqtt.stop();
265
+ }
266
+ reset() {
267
+ this.mqtt?.stop();
268
+ this.mqtt = undefined;
269
+ this.deviceWebRTConfig = undefined;
270
+ this.mqttWebRTConfig = undefined;
271
+ this.pc = undefined;
272
+ }
273
+ }
274
+ //# sourceMappingURL=peer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer.js","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { DeviceWebRTConfig, MQTTConfig, RTSPToken, TuyaDeviceConfig, TuyaDeviceStatus, TuyaResponse } from './const.js';
2
+ import type { TuyaSupportedCountry } from './utils.js';
3
+ export declare class TuyaCloud {
4
+ private readonly userId;
5
+ private readonly clientId;
6
+ private readonly secret;
7
+ private readonly country;
8
+ private readonly nonce;
9
+ private session?;
10
+ private client;
11
+ private _cameras;
12
+ constructor(userId: string, clientId: string, secret: string, country: TuyaSupportedCountry);
13
+ login(): Promise<boolean>;
14
+ isLoggedIn(): boolean;
15
+ updateDevice(device: TuyaDeviceConfig, statuses: TuyaDeviceStatus[]): Promise<boolean>;
16
+ fetchDevices(): Promise<boolean>;
17
+ get cameras(): TuyaDeviceConfig[] | undefined;
18
+ getRTSPS(camera: TuyaDeviceConfig): Promise<RTSPToken | undefined>;
19
+ getDeviceWebRTConfig(camera: TuyaDeviceConfig): Promise<TuyaResponse<DeviceWebRTConfig>>;
20
+ getWebRTCMQConfig(webRTCDeviceConfig: DeviceWebRTConfig): Promise<TuyaResponse<MQTTConfig>>;
21
+ getSessionUserId(): string | undefined;
22
+ get<T>(path: string, query?: {
23
+ [k: string]: any;
24
+ }): Promise<TuyaResponse<T>>;
25
+ post<T>(path: string, body?: {
26
+ [k: string]: any;
27
+ }): Promise<TuyaResponse<T>>;
28
+ private request;
29
+ private getStringToSign;
30
+ private refreshAccessTokenIfNeeded;
31
+ }