├── android
├── gradle.properties
├── src
│ └── main
│ │ ├── res
│ │ └── values
│ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── tuya
│ │ └── smart
│ │ └── rnsdk
│ │ ├── utils
│ │ ├── ReactParamsCheck.kt
│ │ ├── JsonUtils.kt
│ │ ├── BridgeUtils.kt
│ │ ├── Constant.kt
│ │ └── TuyaReactUtils.kt
│ │ ├── push
│ │ └── TuyaPushModule.kt
│ │ ├── home
│ │ ├── TuyaRoomModule.kt
│ │ ├── TuyaHomeMemberModule.kt
│ │ ├── TuyaHomeManagerModule.kt
│ │ └── TuyaHomeDataManagerModule.kt
│ │ ├── message
│ │ └── TuyaMessageModule.kt
│ │ ├── TuyaReactPackage.kt
│ │ ├── device
│ │ ├── TuyaSingleTransferModule.kt
│ │ ├── TuyaOTAModule.kt
│ │ ├── TuyaGatewayModule.kt
│ │ └── TuyaDeviceModule.kt
│ │ ├── core
│ │ └── TuyaCoreModule.kt
│ │ ├── feedback
│ │ └── TuyaFeedBackModule.kt
│ │ ├── group
│ │ └── TuyaGroupModule.kt
│ │ └── timer
│ │ └── TuyaTimerModule.kt
├── consumer-rules.pro
├── README.md
├── proguard-rules.pro
└── build.gradle
├── .eslintrc.js
├── pic
└── android1.png
├── .commitlintrc.json
├── ios
├── RNTuyaSdk.xcodeproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── RNTuyaSdk.xcworkspace
│ └── contents.xcworkspacedata
└── RNTuyaSdk
│ ├── Utils
│ ├── TuyaRNUtils+DeviceParser.m
│ ├── Listener
│ │ ├── TuyaRNGroupListener.h
│ │ ├── TuyaRNEventEmitter.h
│ │ ├── TuyaRNHomeManagerListener.h
│ │ ├── TuyaRNHomeListener.h
│ │ ├── TuyaRNDeviceListener.h
│ │ ├── TuyaRNEventEmitter.m
│ │ ├── TuyaRNHomeManagerListener.m
│ │ ├── TuyaRNGroupListener.m
│ │ └── TuyaRNHomeListener.m
│ ├── TuyaRNUtils+Network.h
│ ├── TuyaRNUtils+Cache.h
│ ├── TuyaRNUtils.h
│ ├── TuyaRNUtils.m
│ ├── TuyaRNUtils+Cache.m
│ ├── TuyaRNUtils+Network.m
│ └── TuyaRNUtils+DeviceParser.h
│ ├── Core
│ ├── TuyaRNCoreModule.h
│ └── TuyaRNCoreModule.m
│ ├── Home
│ ├── TuyaRNHomeModule.h
│ ├── TuyaRNHomeMemberModule.h
│ ├── TuyaRNHomeManagerModule.h
│ ├── TuyaRNHomeDataManagerModule.h
│ ├── TuyaRNHomeDataManagerModule.m
│ ├── TuyaRNHomeManagerModule.m
│ └── TuyaRNHomeMemberModule.m
│ ├── User
│ └── TuyaRNUserModule.h
│ ├── Group
│ ├── TuyaRNGroupModule.h
│ └── TuyaRNGroupModule.m
│ ├── Room
│ ├── TuyaRNRoomModule.h
│ └── TuyaRNRoomModule.m
│ ├── Scene
│ └── TuyaRNSceneModule.h
│ ├── Timer
│ ├── TuyaRNTimerModule.h
│ └── TuyaRNTimerModule.m
│ ├── GateWay
│ ├── TuyaRNGatewayModule.h
│ └── TuyaRNGatewayModule.m
│ ├── ShareDevice
│ └── TuyaRNShareModule.h
│ ├── DeviceControl
│ ├── TuyaRNDeviceModule.h
│ └── TuyaRNDeviceModule.m
│ ├── Feedback
│ ├── TuyaRNFeedBackModule.h
│ └── TuyaRNFeedBackModule.m
│ ├── Activator
│ ├── TuyaRNActivatorModule.h
│ └── TuyaRNActivatorModule.m
│ ├── BLEScanner
│ ├── TuyaBLERNScannerModule.h
│ └── TuyaBLERNScannerModule.m
│ ├── MessageCenter
│ ├── TuyaRNMessageModule.h
│ └── TuyaRNMessageModule.m
│ └── BLEActivator
│ ├── TuyaBLERNActivatorModule.h
│ └── TuyaBLERNActivatorModule.m
├── .editorconfig
├── src
├── index.ts
├── homeDataManager.ts
├── bridgeUtils.ts
├── ota.ts
├── homeManager.ts
├── homeMember.ts
├── activator.ts
├── home.ts
├── user.ts
├── device.ts
└── timer.ts
├── .github
└── workflows
│ ├── lint.yml
│ └── release.yml
├── .releaserc.json
├── RNTuyaSdk.podspec
├── tsconfig.json
├── LICENSE
├── .gitignore
├── package.json
└── README.md
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | android.useAndroidX=true
2 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: '@volst',
3 | };
4 |
--------------------------------------------------------------------------------
/pic/android1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/owowagency/react-native-tuya/HEAD/pic/android1.png
--------------------------------------------------------------------------------
/.commitlintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "@commitlint/config-conventional"
4 | ]
5 | }
--------------------------------------------------------------------------------
/android/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | tuyasmart-sdk-react-native
3 |
4 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 |
3 |
5 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [*.pbxproj]
16 | indent_style = tabs
17 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/TuyaRNUtils+DeviceParser.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUtils+DeviceParser.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/4.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNUtils+DeviceParser.h"
10 |
11 | @implementation TuyaRNUtils (DeviceParser)
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './activator';
2 | export * from './bridgeUtils';
3 | export * from './device';
4 | export * from './home';
5 | export * from './homeDataManager';
6 | export * from './homeManager';
7 | export * from './homeMember';
8 | export * from './ota';
9 | export * from './timer';
10 | export * from './user';
11 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNGroupListener.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNGroupListener.h
3 | // TuyaRnDemo
4 | //
5 | // Created by Elon on 2019/3/7.
6 | // Copyright © 2019 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TuyaRNGroupListener : NSObject
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | name: Lint & Build
2 |
3 | on: [pull_request]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v4
10 | - uses: actions/setup-node@v4
11 | with:
12 | node-version: 18
13 | cache: 'yarn'
14 | - run: yarn install --frozen-lockfile
15 | - run: yarn lint
16 | - run: yarn build
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/TuyaRNUtils+Network.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUtils+Network.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/2.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNUtils.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TuyaRNUtils (Network)
14 |
15 | + (void)openNetworkSettings;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Core/TuyaRNCoreModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaCoreApi.h
3 | // TuyaSdkTest
4 | //
5 | // Created by 浩天 on 2019/2/27.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNCoreModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Home/TuyaRNHomeModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/1.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNHomeModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/User/TuyaRNUserModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUserModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNUserModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Group/TuyaRNGroupModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNGroupModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNGroupModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Room/TuyaRNRoomModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNRoomModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface TuyaRNRoomModule : NSObject
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Scene/TuyaRNSceneModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNSceneModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNSceneModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Timer/TuyaRNTimerModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNTimerModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNTimerModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/GateWay/TuyaRNGatewayModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNGatewayModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNGatewayModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/ShareDevice/TuyaRNShareModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNShareModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNShareModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/DeviceControl/TuyaRNDeviceModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNDeviceModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNDeviceModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Feedback/TuyaRNFeedBackModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNFeedBackModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNFeedBackModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/GateWay/TuyaRNGatewayModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNGatewayModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNGatewayModule.h"
10 |
11 | @implementation TuyaRNGatewayModule
12 |
13 | RCT_EXPORT_MODULE(TuyaGatewayModule)
14 |
15 | RCT_EXPORT_METHOD(initWithOptions:(NSDictionary *)params) {
16 |
17 | }
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Home/TuyaRNHomeMemberModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeMemberModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/1.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNHomeMemberModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Activator/TuyaRNActivatorModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNActivatorModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNActivatorModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Home/TuyaRNHomeManagerModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeManagerModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNHomeManagerModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/BLEScanner/TuyaBLERNScannerModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaBLERNScannerModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaBLERNScannerModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/MessageCenter/TuyaRNMessageModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNMessageModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface TuyaRNMessageModule : NSObject
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/TuyaRNUtils+Cache.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUtils+Cache.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/2.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNUtils.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TuyaRNUtils (Cache)
14 |
15 | + (NSNumber *)currentHomeId;
16 |
17 | + (void)setCurrentHomeId:(NSNumber *)homeId;
18 |
19 | @end
20 |
21 | NS_ASSUME_NONNULL_END
22 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/BLEActivator/TuyaBLERNActivatorModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaBLERNActivatorModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaBLERNActivatorModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Home/TuyaRNHomeDataManagerModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeDataManagerModule.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/2.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface TuyaRNHomeDataManagerModule : NSObject
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/src/homeDataManager.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native';
2 |
3 | const tuya = NativeModules.TuyaHomeDataManagerModule;
4 |
5 | export type GetRoomDeviceListParams = {
6 | homeId?: number;
7 | roomId: number;
8 | };
9 |
10 | export type GetRoomDeviceListResponse = {
11 | deviceList: {}[];
12 | groupList: {}[];
13 | };
14 |
15 | export function getRoomDeviceList(
16 | params: GetRoomDeviceListParams
17 | ): Promise {
18 | return tuya.getRoomDeviceList(params);
19 | }
20 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/utils/ReactParamsCheck.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.utils
2 |
3 | import com.facebook.react.bridge.ReadableMap
4 |
5 | object ReactParamsCheck {
6 | /**
7 | * 接口输入参数check
8 | */
9 | fun checkParams(keys: Array, params: ReadableMap): Boolean {
10 | for (key in keys) {
11 | if (!params.hasKey(key)) {
12 | throw IllegalArgumentException("need ${key}")
13 | }
14 | }
15 | return true
16 | }
17 | }
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v4
13 | - uses: actions/setup-node@v4
14 | with:
15 | node-version: 18
16 | cache: 'yarn'
17 | - run: yarn install --frozen-lockfile
18 | - run: yarn build
19 | - env:
20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
22 | run: yarn semantic-release
--------------------------------------------------------------------------------
/.releaserc.json:
--------------------------------------------------------------------------------
1 | {
2 | "branches": [
3 | "master"
4 | ],
5 | "plugins": [
6 | "@semantic-release/commit-analyzer",
7 | "@semantic-release/release-notes-generator",
8 | "@semantic-release/github",
9 | "@semantic-release/npm",
10 | [
11 | "@semantic-release/git",
12 | {
13 | "assets": [
14 | "docs",
15 | "package.json"
16 | ],
17 | "message": "chore(release): ${nextRelease.version} [skip ci]"
18 | }
19 | ]
20 | ],
21 | "tagFormat": "${version}"
22 | }
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/TuyaRNUtils.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUtils.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface TuyaRNUtils : NSObject
16 |
17 | + (void)rejecterWithError:(NSError *)error
18 | handler:(RCTPromiseRejectBlock)rejecter;
19 |
20 | + (void)resolverWithHandler:(RCTPromiseResolveBlock)resolver;
21 |
22 | @end
23 |
24 | NS_ASSUME_NONNULL_END
25 |
--------------------------------------------------------------------------------
/RNTuyaSdk.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4 |
5 | Pod::Spec.new do |s|
6 | s.name = "RNTuyaSdk"
7 | s.version = package['version']
8 | s.summary = package['description']
9 | s.license = package['license']
10 |
11 | s.authors = package['author']
12 | s.homepage = package['homepage']
13 | s.platforms = { :ios => "12.0" }
14 |
15 | s.source = { :git => "https://github.com/owowagency/react-native-tuya.git", :tag => "v#{s.version}" }
16 | s.source_files = "ios/**/*.{h,m}"
17 |
18 | s.dependency 'React'
19 | s.dependency 'ThingSmartHomeKit', '~> 5.8.0'
20 | end
21 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/TuyaRNUtils.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUtils.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNUtils.h"
10 |
11 |
12 | @implementation TuyaRNUtils
13 |
14 | + (void)rejecterWithError:(NSError *)error
15 | handler:(RCTPromiseRejectBlock)rejecter {
16 | if (rejecter) {
17 | rejecter([NSString stringWithFormat:@"%ld", error.code], error.userInfo[NSLocalizedDescriptionKey], error);
18 | }
19 | }
20 |
21 | + (void)resolverWithHandler:(RCTPromiseResolveBlock)resolver {
22 | if (resolver) {
23 | resolver(@"success");
24 | }
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/android/consumer-rules.pro:
--------------------------------------------------------------------------------
1 | # https://developer.tuya.com/en/docs/app-development/integrated?id=Ka69nt96cw0uj#title-7-Step%205%3A%20Obfuscate%20the%20code
2 |
3 | #fastJson
4 | -keep class com.alibaba.fastjson.**{*;}
5 | -dontwarn com.alibaba.fastjson.**
6 |
7 | #mqtt
8 | -keep class com.thingclips.smart.mqttclient.mqttv3.** { *; }
9 | -dontwarn com.thingclips.smart.mqttclient.mqttv3.**
10 |
11 | #OkHttp3
12 | -keep class okhttp3.** { *; }
13 | -keep interface okhttp3.** { *; }
14 | -dontwarn okhttp3.**
15 |
16 | -keep class okio.** { *; }
17 | -dontwarn okio.**
18 |
19 | -keep class com.thingclips.**{*;}
20 | -dontwarn com.thingclips.**
21 |
22 | # Matter SDK
23 | -keep class chip.** { *; }
24 | -dontwarn chip.**
--------------------------------------------------------------------------------
/android/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | If you want to publish the lib as a maven dependency, follow these steps before publishing a new version to npm:
4 |
5 | 1. Be sure to have the Android [SDK](https://developer.android.com/studio/index.html) and [NDK](https://developer.android.com/ndk/guides/index.html) installed
6 | 2. Be sure to have a `local.properties` file in this folder that points to the Android SDK and NDK
7 |
8 | ```
9 | ndk.dir=/Users/{username}/Library/Android/sdk/ndk-bundle
10 | sdk.dir=/Users/{username}/Library/Android/sdk
11 | ```
12 |
13 | 3. Delete the `maven` folder
14 | 4. Run `sudo ./gradlew installArchives`
15 | 5. Verify that latest set of generated files is in the maven folder with the correct version number
16 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/TuyaRNUtils+Cache.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUtils+Cache.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/2.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNUtils+Cache.h"
10 |
11 | #define kTuyaRNSDKCurrentHomeId @"TuyaRNSDKCurrentHomeId"
12 |
13 | @implementation TuyaRNUtils (Cache)
14 |
15 | + (NSNumber *)currentHomeId {
16 | return [[NSUserDefaults standardUserDefaults] objectForKey:kTuyaRNSDKCurrentHomeId];
17 | }
18 |
19 | + (void)setCurrentHomeId:(NSNumber *)homeId {
20 | if (!homeId) {
21 | return;
22 | }
23 | [[NSUserDefaults standardUserDefaults] setObject:homeId forKey:kTuyaRNSDKCurrentHomeId];
24 | [[NSUserDefaults standardUserDefaults] synchronize];
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/src/bridgeUtils.ts:
--------------------------------------------------------------------------------
1 | import { NativeEventEmitter, NativeModules } from 'react-native';
2 |
3 | export const GROUPLISTENER = 'groupListener';
4 | export const HARDWAREUPGRADELISTENER = 'hardwareUpgradeListener';
5 | export const DEVLISTENER = 'devListener';
6 | export const SUBDEVLISTENER = 'subDevListener';
7 | export const HOMESTATUS = 'homeStatus';
8 | export const HOMECHANGE = 'homeChange';
9 | export const SINGLETRANSFER = 'SingleTransfer';
10 |
11 | let eventEmitter = new NativeEventEmitter(NativeModules.TuyaRNEventEmitter);
12 |
13 | export function addEvent(eventName: string, callback: (data: any) => any) {
14 | return eventEmitter.addListener(eventName, callback);
15 | }
16 | export const bridge = (key: string, id: string | number) => `${key}//${id}`;
17 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNEventEmitter.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNEventEmitter.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/4.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | extern NSString *const kTYEventEmitterDeviceInfoEvent;
13 | //extern NSString *const kTYEventEmitterFirmwareUpdateEvent;
14 | extern NSString *const kTYEventEmitterGroupInfoEvent;
15 | extern NSString *const kTYEventEmitterHomeChangeEvent;
16 | extern NSString *const kTYEventEmitterHomeStatusEvent;
17 |
18 | NS_ASSUME_NONNULL_BEGIN
19 |
20 | @interface TuyaRNEventEmitter : RCTEventEmitter
21 |
22 | + (void)ty_sendEvent:(NSString *)event withBody:(id)body;
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNHomeManagerListener.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeManagerListener.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/6.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import
13 |
14 |
15 |
16 |
17 | NS_ASSUME_NONNULL_BEGIN
18 |
19 | @interface TuyaRNHomeManagerListener : NSObject
20 |
21 | /**
22 | 单例
23 | */
24 | + (instancetype)sharedInstance;
25 |
26 | /**
27 | 注册家庭管理通知
28 |
29 | */
30 | - (void)registerSmartHomeManager:(ThingSmartHomeManager *)homeManager;
31 |
32 |
33 | /**
34 | 移除家庭管理的通知
35 | */
36 | - (void)removeSmartHomeManager;
37 |
38 | @end
39 |
40 | NS_ASSUME_NONNULL_END
41 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src", "types", "test"],
3 | "compilerOptions": {
4 | "target": "es5",
5 | "module": "esnext",
6 | "lib": ["dom", "esnext"],
7 | "importHelpers": true,
8 | "declaration": true,
9 | "sourceMap": true,
10 | "rootDir": "./",
11 | "strict": true,
12 | "noImplicitAny": true,
13 | "strictNullChecks": true,
14 | "strictFunctionTypes": true,
15 | "strictPropertyInitialization": true,
16 | "noImplicitThis": true,
17 | "alwaysStrict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "noImplicitReturns": true,
21 | "noFallthroughCasesInSwitch": true,
22 | "moduleResolution": "node",
23 | "baseUrl": "./",
24 | "paths": {
25 | "*": ["src/*", "node_modules/*"]
26 | },
27 | "jsx": "react",
28 | "esModuleInterop": true
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNHomeListener.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeListener.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/6.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import
13 |
14 |
15 | NS_ASSUME_NONNULL_BEGIN
16 |
17 | @interface TuyaRNHomeListener : NSObject
18 |
19 | + (instancetype)shareInstance;
20 |
21 | //注册新的SmartHome
22 | - (void)registerHomeChangeWithSmartHome:(ThingSmartHome *)smartHome;
23 |
24 | //取消注册
25 | - (void)removeHomeChangeSmartHome;
26 |
27 | //注册新的 监听status
28 | - (void)registerHomeStatusWithSmartHome:(ThingSmartHome *)smartHome;
29 |
30 | //取消 监听
31 | - (void)removeHomeStatusSmartHome;
32 |
33 | @end
34 |
35 | NS_ASSUME_NONNULL_END
36 |
--------------------------------------------------------------------------------
/src/ota.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native';
2 | import { addEvent, bridge, HARDWAREUPGRADELISTENER } from './bridgeUtils';
3 |
4 | const tuya = NativeModules.TuyaDeviceModule;
5 |
6 | export type StartOtaParams = {
7 | devId: string;
8 | };
9 |
10 | export function startOta(
11 | params: StartOtaParams,
12 | onSuccess: (data: any) => void,
13 | onFailure: (data: any) => void,
14 | onProgress: (data: any) => void
15 | ) {
16 | tuya.startOta(params);
17 | return addEvent(bridge(HARDWAREUPGRADELISTENER, params.devId), data => {
18 | if (data.type === 'onSuccess') {
19 | onSuccess(data);
20 | } else if (data.type === 'onFailure') {
21 | onFailure(data);
22 | } else if (data.type === 'onProgress') {
23 | onProgress(data);
24 | }
25 | });
26 | }
27 |
28 | export function getOtaInfo(params: StartOtaParams): Promise {
29 | return tuya.getOtaInfo(params);
30 | }
31 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNDeviceListener.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNDeviceListener.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/4.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class ThingSmartDevice;
12 |
13 | typedef NS_OPTIONS(NSUInteger, TuyaRNDeviceListenType) {
14 | TuyaRNDeviceListenType_None = 1<<0,
15 | TuyaRNDeviceListenType_DeviceInfo = 1 << 1,
16 | };
17 |
18 | NS_ASSUME_NONNULL_BEGIN
19 |
20 | @interface TuyaRNDeviceListener : NSObject
21 |
22 | @property (nonatomic, copy, readonly) NSArray *listenDevices;
23 |
24 | + (instancetype)shareInstance;
25 |
26 | /**
27 | 添加设备监听, 当设备状态变更时,会自动发送 kTYEventEmitterDeviceListenerEvent
28 | */
29 | + (void)registerDevice:(ThingSmartDevice *)device type:(TuyaRNDeviceListenType)type;
30 |
31 | /*
32 | * 移除设备监听
33 | */
34 | + (void)removeDevice:(ThingSmartDevice *)device type:(TuyaRNDeviceListenType)type;
35 |
36 |
37 | @end
38 |
39 | NS_ASSUME_NONNULL_END
40 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/TuyaRNUtils+Network.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUtils+Network.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/2.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNUtils+Network.h"
10 | #import
11 |
12 | @implementation TuyaRNUtils (Network)
13 |
14 | + (void)openNetworkSettings {
15 |
16 | NSData *data = [[NSData alloc] initWithBase64EncodedString:@"QXBwLVByZWZzJTNBcm9vdCUzRFdJRkk=" options:0];
17 | NSString *urlStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
18 | urlStr = [urlStr stringByRemovingPercentEncoding];
19 | NSURL *targetUrl = [NSURL URLWithString:urlStr];
20 | if (targetUrl && [[UIApplication sharedApplication] canOpenURL:targetUrl]) {
21 | if (@available(iOS 10.0, *)) {
22 | [[UIApplication sharedApplication] openURL:targetUrl options:@{} completionHandler:nil];
23 | } else {
24 | [[UIApplication sharedApplication] openURL:targetUrl];
25 | }
26 | }
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/push/TuyaPushModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.push
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.tuya.smart.rnsdk.utils.Constant
6 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
7 |
8 | class TuyaPushModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
9 | override fun getName(): String {
10 | return "TuyaPushModule"
11 | }
12 |
13 | /* Push涂鸦云注册 */
14 | @ReactMethod
15 | fun registerDevice(params: ReadableMap, promise: Promise) {
16 | if (ReactParamsCheck.checkParams(arrayOf(Constant.ALIASID, Constant.PUSHPROVIDER), params)) {
17 | ThingHomeSdk.getPushInstance().registerDevice(params.getString(Constant.ALIASID),params.getString(Constant.PUSHPROVIDER),Constant.getIResultCallback(promise))
18 | }
19 | }
20 |
21 |
22 | /* 手机密码登录 */
23 | @ReactMethod
24 | fun onDestroy() {
25 | ThingHomeSdk.getPushInstance().onDestroy()
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Volst
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/utils/JsonUtils.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.utils
2 |
3 | import com.alibaba.fastjson.JSON
4 | import com.alibaba.fastjson.JSONArray
5 | import com.alibaba.fastjson.JSONObject
6 | import com.facebook.react.bridge.ReadableArray
7 | import com.facebook.react.bridge.ReadableMap
8 |
9 | object JsonUtils {
10 | fun parse(json: String, c: Class<*>): Any {
11 | return JSONObject.parseObject(json, c)
12 | }
13 |
14 |
15 | fun parseArray(json: String, c: Class<*>): List {
16 | return JSONObject.parseArray(json, c)
17 | }
18 |
19 | fun parserArraybyMap(map: ReadableArray, c: Class<*>): List? {
20 | return parseArray(toString(TuyaReactUtils.parseToList(map)), c)
21 | }
22 |
23 | fun parseBymap(map: ReadableMap, c: Class<*>): Any? {
24 | return parse(JSONObject(TuyaReactUtils.parseToMap(map)).toJSONString(), c)
25 | }
26 | fun toString(obj:Any):String{
27 | return JSONObject.toJSONString(obj)
28 | }
29 | fun toJsonArray(obj:Any):JSONArray{
30 | return JSONArray.parseArray(JSON.toJSONString(obj))
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | dist/
3 | */build/
4 |
5 | node_modules/
6 |
7 | # OSX
8 | #
9 | .DS_Store
10 |
11 | # Xcode
12 | #
13 | *.pbxuser
14 | !default.pbxuser
15 | *.mode1v3
16 | !default.mode1v3
17 | *.mode2v3
18 | !default.mode2v3
19 | *.perspectivev3
20 | !default.perspectivev3
21 | xcuserdata
22 | *.xccheckout
23 | *.moved-aside
24 | DerivedData
25 | *.hmap
26 | *.ipa
27 | *.xcuserstate
28 |
29 | # Android/IntelliJ
30 | #
31 | build/
32 | .idea
33 | .gradle
34 | .settings
35 | .project
36 | local.properties
37 | *.iml
38 | .classpath
39 | gradlew*
40 | gradle
41 |
42 |
43 |
44 | # node.js
45 | #
46 | npm-debug.log
47 | yarn-error.log
48 |
49 | # BUCK
50 | buck-out/
51 | \.buckd/
52 | *.keystore
53 |
54 | # fastlane
55 | #
56 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
57 | # screenshots whenever they are needed.
58 | # For more information about the recommended setup visit:
59 | # https://docs.fastlane.tools/best-practices/source-control/
60 |
61 | */fastlane/report.xml
62 | */fastlane/Preview.html
63 | */fastlane/screenshots
64 |
65 | # Bundle artifact
66 | *.jsbundle
67 | *.zip
68 | *.lock
69 | !yarn.lock
70 | !package-lock.json
71 |
--------------------------------------------------------------------------------
/src/homeManager.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules, Platform } from 'react-native';
2 |
3 | const tuya = NativeModules.TuyaHomeManagerModule;
4 |
5 | export type CreateHomeParams = {
6 | name: string;
7 | geoName: string;
8 | lon: number;
9 | lat: number;
10 | rooms: string[];
11 | };
12 |
13 | export function createHome(params: CreateHomeParams): Promise {
14 | return tuya.createHome(params);
15 | }
16 |
17 | export type HomeDetailsResponse = {
18 | name: string;
19 | admin: boolean;
20 | background: string;
21 | dealStatus: 1 | 2; // 1 = unaccepted 2 = accepted
22 | displayOrder: number;
23 | geoName: string;
24 | gid: number;
25 | homeId: number;
26 | lat: number;
27 | lon: number;
28 | };
29 |
30 | export type QueryHomeListResponse = HomeDetailsResponse[];
31 |
32 | export async function queryHomeList(): Promise {
33 | let homes = await tuya.queryHomeList();
34 | // Tuya's Android SDK uses different property names than the iOS SDK...
35 | if (Platform.OS === 'android') {
36 | homes = homes.map((m: any) => ({
37 | ...m,
38 | dealStatus: m.homeStatus,
39 | }));
40 | }
41 | return homes;
42 | }
43 |
44 | export type JoinFamilyParams = {
45 | homeId: number;
46 | action: boolean;
47 | };
48 |
49 | export function joinFamily(params: JoinFamilyParams) {
50 | return tuya.joinFamily(params);
51 | }
52 |
--------------------------------------------------------------------------------
/src/homeMember.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules, Platform } from 'react-native';
2 |
3 | const tuya = NativeModules.TuyaHomeMemberModule;
4 |
5 | export type QueryMemberListParams = { homeId: number };
6 | export type MemberListItem = {
7 | admin: boolean;
8 | username: string;
9 | id: number;
10 | dealStatus: number;
11 | };
12 | export type QueryMemberListResponse = MemberListItem[];
13 |
14 | export async function queryMemberList(
15 | params: QueryMemberListParams
16 | ): Promise {
17 | let members = await tuya.queryMemberList(params);
18 | // Tuya's Android SDK uses different property names than the iOS SDK...
19 | if (Platform.OS === 'android') {
20 | members = members.map((m: any) => ({
21 | admin: m.admin,
22 | username: m.account,
23 | id: m.memberId,
24 | dealStatus: m.memberStatus,
25 | }));
26 | }
27 | return members;
28 | }
29 |
30 | export type AddMemberParams = {
31 | homeId: number;
32 | userAccount: string; // email
33 | countryCode: string;
34 | name: string;
35 | admin: boolean;
36 | };
37 |
38 | export function addMember(params: AddMemberParams): Promise {
39 | return tuya.addMember(params);
40 | }
41 |
42 | export type RemoveMemberParams = {
43 | memberId: number;
44 | };
45 |
46 | export function removeMember(params: RemoveMemberParams): Promise {
47 | return tuya.removeMember(params);
48 | }
49 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/TuyaRNUtils+DeviceParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNUtils+DeviceParser.h
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/4.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNUtils.h"
10 | #import
11 | #import
12 | #import
13 |
14 | static inline NSArray *getValidDataForDeviceModel(NSArray *deviceModelList) {
15 | if(!deviceModelList || [deviceModelList count] == 0) {
16 | return @[];
17 | }
18 | NSMutableArray *list = [NSMutableArray array];
19 | for (ThingSmartDeviceModel *tempModel in deviceModelList) {
20 |
21 | NSDictionary *dic = [tempModel yy_modelToJSONObject];
22 | [list addObject:dic];
23 | }
24 | return list;
25 | }
26 |
27 | static inline NSArray *getValidDataForGroupModel(NSArray *groupModelList) {
28 | if(!groupModelList || [groupModelList count] == 0) {
29 | return @[];
30 | }
31 |
32 | NSMutableArray *list = [NSMutableArray array];
33 | for (ThingSmartGroupModel *tempModel in groupModelList) {
34 | NSDictionary *dic = [tempModel yy_modelToJSONObject];
35 | [list addObject:dic];
36 | }
37 | return list;
38 | }
39 |
40 |
41 | NS_ASSUME_NONNULL_BEGIN
42 |
43 | @interface TuyaRNUtils (DeviceParser)
44 |
45 | @end
46 |
47 | NS_ASSUME_NONNULL_END
48 |
--------------------------------------------------------------------------------
/android/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | # https://developer.tuya.com/en/docs/app-development/integrated?id=Ka69nt96cw0uj#title-7-Step%205%3A%20Obfuscate%20the%20code
24 |
25 | #fastJson
26 | -keep class com.alibaba.fastjson.**{*;}
27 | -dontwarn com.alibaba.fastjson.**
28 |
29 | #mqtt
30 | -keep class com.thingclips.smart.mqttclient.mqttv3.** { *; }
31 | -dontwarn com.thingclips.smart.mqttclient.mqttv3.**
32 |
33 | #OkHttp3
34 | -keep class okhttp3.** { *; }
35 | -keep interface okhttp3.** { *; }
36 | -dontwarn okhttp3.**
37 |
38 | -keep class okio.** { *; }
39 | -dontwarn okio.**
40 |
41 | -keep class com.thingclips.**{*;}
42 | -dontwarn com.thingclips.**
43 |
44 | # Matter SDK
45 | -keep class chip.** { *; }
46 | -dontwarn chip.**
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/BLEScanner/TuyaBLERNScannerModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaBLERNScannerModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaBLERNScannerModule.h"
10 | #import
11 | #import
12 | #import
13 | #import
14 | #import "TuyaRNUtils+Network.h"
15 | #import "YYModel.h"
16 |
17 | // Bluetooth Pairing
18 | static TuyaBLERNScannerModule * scannerInstance = nil;
19 |
20 | @interface TuyaBLERNScannerModule()
21 |
22 | @property(copy, nonatomic) RCTPromiseResolveBlock promiseResolveBlock;
23 | @property(copy, nonatomic) RCTPromiseRejectBlock promiseRejectBlock;
24 |
25 | @end
26 |
27 | @implementation TuyaBLERNScannerModule
28 |
29 | RCT_EXPORT_MODULE(TuyaBLEScannerModule)
30 |
31 | RCT_EXPORT_METHOD(startBluetoothScan:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
32 | if (scannerInstance == nil) {
33 | scannerInstance = [TuyaBLERNScannerModule new];
34 | }
35 |
36 | [ThingSmartBLEManager sharedInstance].delegate = scannerInstance;
37 | scannerInstance.promiseResolveBlock = resolver;
38 | scannerInstance.promiseRejectBlock = rejecter;
39 |
40 | [[ThingSmartBLEManager sharedInstance] startListening:YES];
41 | }
42 |
43 | - (void)didDiscoveryDeviceWithDeviceInfo:(ThingBLEAdvModel *)deviceInfo {
44 | if (scannerInstance.promiseResolveBlock) {
45 | self.promiseResolveBlock([deviceInfo yy_modelToJSONObject]);
46 | }
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/src/activator.ts:
--------------------------------------------------------------------------------
1 | import { DeviceBean } from './device';
2 | import { NativeModules, Platform } from 'react-native';
3 | import { DeviceDetailResponse } from './home';
4 |
5 | const tuya = NativeModules.TuyaActivatorModule;
6 | const tuyaBLEActivator = NativeModules.TuyaBLEActivatorModule;
7 | const tuyaBLEScanner = NativeModules.TuyaBLEScannerModule;
8 |
9 | export function openNetworkSettings() {
10 | return tuya.openNetworkSettings({});
11 | }
12 |
13 | export enum ActivatorType {
14 | AP = 'THING_AP',
15 | EZ = 'THING_EZ',
16 | AP_4G_GATEWAY = 'THING_4G_GATEWAY',
17 | QR = 'THING_QR',
18 | }
19 |
20 | export type InitActivatorParams = {
21 | homeId: number;
22 | ssid: string;
23 | password: string;
24 | time: number;
25 | type: ActivatorType;
26 | };
27 |
28 | export interface InitBluetoothActivatorParams {
29 | deviceId?: string;
30 | homeId: number;
31 | ssid: string;
32 | password: string;
33 | }
34 |
35 | export function initActivator(
36 | params: InitActivatorParams
37 | ): Promise {
38 | return tuya.initActivator(params);
39 | }
40 |
41 | export function stopConfig() {
42 | return tuya.stopConfig();
43 | }
44 |
45 | export function startBluetoothScan() {
46 | if (Platform.OS === 'ios') {
47 | return tuyaBLEScanner.startBluetoothScan();
48 | }
49 | return tuya.startBluetoothScan();
50 | }
51 |
52 | export function initBluetoothDualModeActivator(
53 | params: InitBluetoothActivatorParams
54 | ): Promise {
55 | if (Platform.OS === 'ios') {
56 | return tuyaBLEActivator.initActivator(params);
57 | }
58 | return tuya.initBluetoothDualModeActivator(params);
59 | }
60 |
61 | export function getCurrentWifi(
62 | success: (ssid: string) => void,
63 | error: () => void
64 | ) {
65 | // We need the Allow While Using App location permission to use this.
66 | return tuya.getCurrentWifi({}, success, error);
67 | }
68 |
--------------------------------------------------------------------------------
/src/home.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native';
2 | import { DeviceDps } from './device';
3 |
4 | const tuya = NativeModules.TuyaHomeModule;
5 |
6 | export type QueryRoomListParams = {
7 | homeId?: number;
8 | };
9 | export type QueryRoomListResponse = {
10 | name: string;
11 | displayOrder: number;
12 | id: number;
13 | roomId: number;
14 | }[];
15 |
16 | export function queryRoomList(
17 | params: QueryRoomListParams
18 | ): Promise {
19 | return tuya.queryRoomList(params);
20 | }
21 |
22 | export type GetHomeDetailParams = {
23 | homeId: number;
24 | };
25 | export type DeviceDetailResponse = {
26 | homeId: number;
27 | isOnline: boolean;
28 | productId: string;
29 | devId: string;
30 | verSw: string;
31 | name: string;
32 | dps: DeviceDps;
33 | homeDisplayOrder: number;
34 | roomId: number;
35 | };
36 | export type GetHomeDetailResponse = {
37 | deviceList: DeviceDetailResponse[];
38 | groupList: any[];
39 | meshList: any[];
40 | sharedDeviceList: any[];
41 | sharedGroupList: any[];
42 | };
43 |
44 | export function getHomeDetail(
45 | params: GetHomeDetailParams
46 | ): Promise {
47 | return tuya.getHomeDetail(params);
48 | }
49 |
50 | export type UpdateHomeParams = {
51 | homeId: number;
52 | name: string;
53 | geoName: string;
54 | lon: number;
55 | lat: number;
56 | };
57 |
58 | export function updateHome(params: UpdateHomeParams): Promise {
59 | return tuya.updateHome(params);
60 | }
61 |
62 | export type DismissHomeParams = {
63 | homeId: number;
64 | };
65 |
66 | export function dismissHome(params: DismissHomeParams): Promise {
67 | return tuya.dismissHome(params);
68 | }
69 |
70 | export type SortRoomsParams = {
71 | idList: number[];
72 | homeId: number;
73 | };
74 |
75 | export function sortRoom(params: SortRoomsParams): Promise {
76 | return tuya.sortRoom(params);
77 | }
78 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/utils/BridgeUtils.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.utils
2 |
3 | import android.util.Log
4 | import com.facebook.react.bridge.ReactContext
5 | import com.facebook.react.bridge.WritableMap
6 |
7 | object BridgeUtils {
8 |
9 | private val GROUPLISTENER = "groupListener"
10 | private val HARDWAREUPGRADELISTENER = "hardwareUpgradeListener"
11 | private val DEVLISTENER = "devListener"
12 | private val SUBDEVLISTENER = "subDevListener"
13 | private val HOMESTATUS = "homeStatus"
14 | private val HOMECHANGE = "homeChange"
15 | private val SINGLETRANSFER = "SingleTransfer"
16 |
17 | fun groupListener(context: ReactContext, map: WritableMap, groupId: Long) {
18 | TuyaReactUtils.sendEvent(context, bindEventname(GROUPLISTENER, groupId), map)
19 | }
20 |
21 | fun hardwareUpgradeListener(context: ReactContext, map: WritableMap, devId: String){
22 | TuyaReactUtils.sendEvent(context, bindEventname(HARDWAREUPGRADELISTENER, devId), map)
23 | }
24 | fun devListener(context: ReactContext, map: WritableMap, devId: String){
25 | TuyaReactUtils.sendEvent(context, bindEventname(DEVLISTENER, devId), map)
26 | }
27 | fun subDevListener(context: ReactContext, map: WritableMap, devId: String){
28 | TuyaReactUtils.sendEvent(context, bindEventname(SUBDEVLISTENER, devId), map)
29 | }
30 | fun singleTransferListener(context: ReactContext, map: WritableMap, devId: String){
31 | TuyaReactUtils.sendEvent(context, bindEventname(SINGLETRANSFER, devId), map)
32 | }
33 | fun homeStatus(context: ReactContext, map: WritableMap, devId: String){
34 | TuyaReactUtils.sendEvent(context, bindEventname(HOMESTATUS, devId), map)
35 | }
36 |
37 | fun homeChange(context: ReactContext, map: WritableMap, homeId: Double){
38 | TuyaReactUtils.sendEvent(context, HOMECHANGE, map)
39 | }
40 |
41 | private fun bindEventname(key: String, id: Any): String {
42 | return key + "//" + id.toString()
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0-RC.2",
3 | "license": "MIT",
4 | "private": false,
5 | "main": "dist/index.js",
6 | "typings": "dist/index.d.ts",
7 | "keywords": [
8 | "react-native",
9 | "tuyasmart",
10 | "iot",
11 | "tuya"
12 | ],
13 | "files": [
14 | "android",
15 | "ios",
16 | "dist",
17 | "RNTuyaSdk.podspec"
18 | ],
19 | "scripts": {
20 | "start": "tsdx watch",
21 | "build": "tsdx build",
22 | "test": "tsdx test",
23 | "lint": "tsdx lint",
24 | "commit": "cz",
25 | "prepare": "husky install"
26 | },
27 | "peerDependencies": {
28 | "react-native": ">=0.61.5"
29 | },
30 | "husky": {
31 | "hooks": {
32 | "pre-commit": "tsdx lint"
33 | }
34 | },
35 | "prettier": {
36 | "singleQuote": true,
37 | "trailingComma": "es5"
38 | },
39 | "name": "@owowagency/react-native-tuya",
40 | "description": "React Native bindings for the Tuya SDK",
41 | "homepage": "https://github.com/owowagency/react-native-tuya#readme",
42 | "author": "Kees Kluskens",
43 | "module": "dist/react-native-tuya.esm.js",
44 | "devDependencies": {
45 | "@types/jest": "^25.1.2",
46 | "@types/react-native": "^0.61.16",
47 | "@volst/eslint-config": "^4.1.1",
48 | "react-native": "^0.61.5",
49 | "tsdx": "^0.12.3",
50 | "tslib": "^1.10.0",
51 | "typescript": "^3.7.5",
52 | "@commitlint/cli": "^18.1.0",
53 | "@commitlint/config-conventional": "^18.1.0",
54 | "@semantic-release/commit-analyzer": "^11.0.0",
55 | "@semantic-release/exec": "^6.0.3",
56 | "@semantic-release/git": "^10.0.1",
57 | "@semantic-release/npm": "^11.0.0",
58 | "commitizen": "^4.3.0",
59 | "commitlint": "^18.1.0",
60 | "conventional-changelog-conventionalcommits": "^7.0.2",
61 | "cz-conventional-changelog": "^3.3.0",
62 | "husky": "^8.0.3",
63 | "semantic-release": "^22.0.5"
64 | },
65 | "config": {
66 | "commitizen": {
67 | "path": "./node_modules/cz-conventional-changelog"
68 | }
69 | },
70 | "publishConfig": {
71 | "access": "public",
72 | "registry": "https://registry.npmjs.org/"
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/user.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native';
2 |
3 | const tuya = NativeModules.TuyaUserModule;
4 |
5 | export function registerAccountWithEmail(
6 | params: RegisterAccountWithEmailParams
7 | ): Promise {
8 | return tuya.registerAccountWithEmail(params);
9 | }
10 |
11 | export function getRegisterEmailValidateCode(
12 | params: GetEmailValidateCodeParams
13 | ): Promise {
14 | return tuya.getRegisterEmailValidateCode(params);
15 | }
16 |
17 | export function loginWithEmail(params: LoginWithEmailParams): Promise {
18 | return tuya.loginWithEmail(params);
19 | }
20 |
21 | export function getEmailValidateCode(
22 | params: GetEmailValidateCodeParams
23 | ): Promise {
24 | return tuya.getEmailValidateCode(params);
25 | }
26 |
27 | export function resetEmailPassword(
28 | params: ResetEmailPasswordParams
29 | ): Promise {
30 | return tuya.resetEmailPassword(params);
31 | }
32 |
33 | export function logout(): Promise {
34 | return tuya.logout();
35 | }
36 |
37 | export async function getCurrentUser(): Promise {
38 | const user = await tuya.getCurrentUser();
39 | // The iOS SDK returns an empty user model but the Android one doesn't.
40 | return user && user.email ? user : null;
41 | }
42 |
43 | export function cancelAccount(): Promise {
44 | return tuya.cancelAccount();
45 | }
46 |
47 | export type User = {
48 | email: string;
49 | username: string;
50 | sid: string;
51 | timezoneId: string;
52 | uid: string;
53 | userType: number;
54 | headPic: string;
55 | mobile: string;
56 | nickName: string;
57 | phoneCode: string;
58 | };
59 |
60 | export type RegisterAccountWithEmailParams = {
61 | countryCode: string;
62 | email: string;
63 | validateCode: string;
64 | password: string;
65 | };
66 |
67 | export type GetEmailValidateCodeParams = {
68 | countryCode: string;
69 | email: string;
70 | };
71 |
72 | export type LoginWithEmailParams = {
73 | email: string;
74 | password: string;
75 | countryCode: string;
76 | };
77 |
78 | export type ResetEmailPasswordParams = {
79 | email: string;
80 | countryCode: string;
81 | validateCode: string;
82 | newPassword: string;
83 | };
84 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNEventEmitter.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNEventEmitter.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/4.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNEventEmitter.h"
10 |
11 | NSString *const kTYEventEmitterDeviceInfoEvent = @"devListener";
12 | //NSString *const kTYEventEmitterFirmwareUpdateEvent = @"hardwareUpgradeListener";
13 | NSString *const kTYEventEmitterGroupInfoEvent = @"groupListener";
14 | NSString *const kTYEventEmitterHomeChangeEvent = @"homeChange";
15 | NSString *const kTYEventEmitterHomeStatusEvent = @"homeStatus";
16 |
17 |
18 |
19 | @interface TuyaRNEventEmitter()
20 |
21 | @property (nonatomic) BOOL hasListeners;
22 |
23 | @property (nonatomic, strong) NSMutableArray *supportedEvents;
24 |
25 | @end
26 |
27 | @implementation TuyaRNEventEmitter
28 |
29 |
30 | RCT_EXPORT_MODULE()
31 |
32 | - (NSArray *)supportedEvents {
33 | return _supportedEvents;
34 | }
35 |
36 | - (void)addListener:(NSString *)eventName {
37 | [_supportedEvents addObject:eventName];
38 | [[NSNotificationCenter defaultCenter] addObserver:self
39 | selector:@selector(deviceInfoNotification:)
40 | name:eventName
41 | object:nil];
42 | [super addListener:eventName];
43 | }
44 |
45 | - (void)startObserving {
46 |
47 | }
48 |
49 | - (void)stopObserving {
50 | [[NSNotificationCenter defaultCenter] removeObserver:self];
51 | }
52 |
53 | #pragma mark - Native
54 | - (instancetype)init {
55 | if (self = [super init]) {
56 | _supportedEvents = [NSMutableArray array];
57 | }
58 | return self;
59 | }
60 |
61 | + (BOOL)requiresMainQueueSetup {
62 | return YES;
63 | }
64 |
65 | - (void)deviceInfoNotification:(NSNotification *)notification {
66 | NSDictionary *body = notification.object;
67 | [self sendEventWithName:notification.name body:body];
68 | }
69 |
70 | + (void)ty_sendEvent:(NSString *)event withBody:(id)body {
71 | [[NSNotificationCenter defaultCenter] postNotificationName:event object:body];
72 | // [[TuyaRNEventEmitter sharedInstance] sendEventWithName:event body:body];
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/src/device.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules, EmitterSubscription } from 'react-native';
2 | import { addEvent, bridge, DEVLISTENER } from './bridgeUtils';
3 |
4 | const tuya = NativeModules.TuyaDeviceModule;
5 |
6 | export type DeviceBean = {
7 | productId: string;
8 | devId: string;
9 | verSw: string;
10 | name: string;
11 | dps: DeviceDps;
12 | };
13 |
14 | export type DevListenerParams = {
15 | devId: string;
16 | };
17 |
18 | export type DevListenerType =
19 | | 'onDpUpdate'
20 | | 'onRemoved'
21 | | 'onStatusChanged'
22 | | 'onNetworkStatusChanged'
23 | | 'onDevInfoUpdate'
24 | | 'onFirmwareUpgradeSuccess'
25 | | 'onFirmwareUpgradeFailure'
26 | | 'onFirmwareUpgradeProgress';
27 |
28 | let devListenerSubs: { [devId: string]: EmitterSubscription } = {};
29 |
30 | export function registerDevListener(
31 | params: DevListenerParams,
32 | type: DevListenerType,
33 | callback: (data: any) => void
34 | ) {
35 | tuya.registerDevListener(params);
36 | const sub = addEvent(bridge(DEVLISTENER, params.devId), data => {
37 | if (data.type === type) {
38 | callback(data);
39 | }
40 | });
41 | devListenerSubs[params.devId] = sub;
42 | }
43 |
44 | export function unRegisterAllDevListeners() {
45 | for (const devId in devListenerSubs) {
46 | const sub = devListenerSubs[devId];
47 | sub.remove();
48 | tuya.unRegisterDevListener({ devId });
49 | }
50 | devListenerSubs = {};
51 | }
52 |
53 | export type DeviceDpValue = boolean | number | string;
54 | export type DeviceDps = {
55 | [dpId: string]: DeviceDpValue;
56 | };
57 | export type SendParams = {
58 | devId: string;
59 | } & DeviceDps;
60 |
61 | export function send(params: object) {
62 | return tuya.send(params);
63 | }
64 |
65 | export type RemoveDeviceParams = { devId: string };
66 |
67 | export function removeDevice(params: RemoveDeviceParams): Promise {
68 | return tuya.removeDevice(params);
69 | }
70 |
71 | export type RenameDeviceParams = { devId: string; name: string };
72 |
73 | export function renameDevice(params: RenameDeviceParams): Promise {
74 | return tuya.renameDevice(params);
75 | }
76 |
77 | export type GetDataPointStatsParams = {
78 | devId: string;
79 | DataPointTypeEnum: 'DAY' | 'WEEK' | 'MONTH';
80 | number: number; // number of historical data result values, up to 50
81 | dpId: string;
82 | startTime: number; // in ms
83 | };
84 |
85 | export function getDataPointStat(
86 | params: GetDataPointStatsParams
87 | ): Promise {
88 | return tuya.getDataPointStat(params);
89 | }
90 |
--------------------------------------------------------------------------------
/src/timer.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native';
2 | import { DeviceDps } from './device';
3 |
4 | const tuya = NativeModules.TuyaTimerModule;
5 |
6 | export type AddTimerWithTaskDpsParams = {
7 | devId: number;
8 | taskName: string;
9 | loops: string; // Number of cycles "0000000", each 0: off, 1: on, from left to right: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
10 | time: string; // e.g. 14:29
11 | dps: DeviceDps;
12 | };
13 |
14 | export function addTimerWithTask(
15 | params: AddTimerWithTaskDpsParams
16 | ): Promise {
17 | return tuya.addTimerWithTask(params);
18 | }
19 |
20 | export type UpdateTimerWithTaskParams = AddTimerWithTaskDpsParams & {
21 | timerId: string;
22 | isOpen: boolean;
23 | };
24 |
25 | export function updateTimerWithTask(
26 | params: UpdateTimerWithTaskParams
27 | ): Promise {
28 | return tuya.updateTimerWithTask(params);
29 | }
30 |
31 | export type GetTimerTaskStatusWithDeviceIdParams = {
32 | devId: number;
33 | };
34 |
35 | export function getTimerTaskStatusWithDeviceId(
36 | params: GetTimerTaskStatusWithDeviceIdParams
37 | ): Promise {
38 | return tuya.getTimerTaskStatusWithDeviceId(params);
39 | }
40 |
41 | export type GetAllTimerWithDeviceIdParams = {
42 | devId: number;
43 | };
44 |
45 | export type TimerTask = {
46 | timerList: {
47 | timerId: string;
48 | loops: string;
49 | time: string;
50 | status: number;
51 | }[];
52 | timerTaskStatus: { open: boolean; timerName: string };
53 | };
54 |
55 | export type GetAllTimerWithDeviceIdResponse = TimerTask[];
56 |
57 | export async function getAllTimerWithDeviceId(
58 | params: GetAllTimerWithDeviceIdParams
59 | ): Promise {
60 | const timers = await tuya.getAllTimerWithDeviceId(params);
61 | timers.forEach((t: any) => {
62 | t.timerTaskStatus.open = !!t.timerTaskStatus.open;
63 | });
64 | return timers;
65 | }
66 |
67 | export type RemoveTimerWithTaskParams = {
68 | devId: number;
69 | taskName: string;
70 | timerId: string;
71 | };
72 |
73 | export function removeTimerWithTask(
74 | params: RemoveTimerWithTaskParams
75 | ): Promise {
76 | return tuya.removeTimerWithTask(params);
77 | }
78 |
79 | export type UpdateTimerStatusWithTaskParams = {
80 | devId: number;
81 | taskName: string;
82 | timerId: string;
83 | isOpen: boolean;
84 | };
85 |
86 | export function updateTimerStatusWithTask(
87 | params: UpdateTimerStatusWithTaskParams
88 | ): Promise {
89 | return tuya.updateTimerStatusWithTask(params);
90 | }
91 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/MessageCenter/TuyaRNMessageModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNMessageModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNMessageModule.h"
10 | #import "TuyaRNUtils.h"
11 | #import
12 | #import
13 |
14 |
15 | @interface TuyaRNMessageModule()
16 | @property (nonatomic, strong) ThingSmartMessage *smartMessage;
17 | @end
18 |
19 |
20 | @implementation TuyaRNMessageModule
21 |
22 | RCT_EXPORT_MODULE(TuyaMessageModule)
23 |
24 | RCT_EXPORT_METHOD(initWithOptions:(NSDictionary *)params) {
25 |
26 | }
27 |
28 | RCT_EXPORT_METHOD(onDestory:(NSDictionary *)params) {
29 |
30 | }
31 |
32 |
33 | // 获取消息列表:
34 | RCT_EXPORT_METHOD(getMessageList:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
35 | ThingSmartMessage *smartMessage = [[ThingSmartMessage alloc] init];
36 | self.smartMessage = smartMessage;
37 | [smartMessage getMessageList:^(NSArray *list) {
38 | NSMutableArray *res = [NSMutableArray array];
39 | for (ThingSmartMessageListModel *item in list) {
40 | NSDictionary *dic = [item yy_modelToJSONObject];
41 | [res addObject:dic];
42 | }
43 | if (resolver) {
44 | resolver(res);
45 | }
46 | } failure:^(NSError *error) {
47 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
48 | }];
49 | }
50 |
51 |
52 | // 删除消息:
53 | RCT_EXPORT_METHOD(deleteMessage:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
54 | ThingSmartMessage *smartMessage = [[ThingSmartMessage alloc] init];
55 | self.smartMessage = smartMessage;
56 | [smartMessage deleteMessage:params[@"ids"] success:^{
57 | if (resolver) {
58 | resolver(@"seccess");
59 | }
60 | } failure:^(NSError *error) {
61 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
62 | }];
63 | }
64 |
65 | // 获取最新的时间戳:
66 | RCT_EXPORT_METHOD(getMessageMaxTime:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
67 | ThingSmartMessage *smartMessage = [[ThingSmartMessage alloc] init];
68 | self.smartMessage = smartMessage;
69 | [smartMessage getMessageMaxTime:^(int result) {
70 | if (resolver) {
71 | resolver(@(result));
72 | }
73 | } failure:^(NSError *error) {
74 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
75 | }];
76 | }
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNHomeManagerListener.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeManagerListener.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/6.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNHomeManagerListener.h"
10 | #import "TuyaRNEventEmitter.h"
11 |
12 | @interface TuyaRNHomeManagerListener()
13 |
14 | @property (nonatomic, strong) ThingSmartHomeManager *currentSmartHomeManager;
15 |
16 | @end
17 |
18 | @implementation TuyaRNHomeManagerListener
19 |
20 | + (instancetype)sharedInstance {
21 | static TuyaRNHomeManagerListener *_instanced = nil;
22 | static dispatch_once_t onceToken;
23 | dispatch_once(&onceToken, ^{
24 | _instanced = [[TuyaRNHomeManagerListener alloc] init];
25 | });
26 | return _instanced;
27 | }
28 |
29 | //注册家庭管理监听:
30 | - (void)registerSmartHomeManager:(ThingSmartHomeManager *)homeManager {
31 | if (!homeManager) {
32 | return;
33 | }
34 | [TuyaRNHomeManagerListener sharedInstance].currentSmartHomeManager = homeManager;
35 | homeManager.delegate = self;
36 | }
37 |
38 | - (void)removeSmartHomeManager {
39 | [TuyaRNHomeManagerListener sharedInstance].currentSmartHomeManager = nil;
40 | [TuyaRNHomeManagerListener sharedInstance].currentSmartHomeManager.delegate = nil;
41 | }
42 |
43 | #pragma mark -
44 | #pragma mark - ThingSmartHomeManagerDelegate
45 | // 添加一个家庭
46 | - (void)homeManager:(ThingSmartHomeManager *)manager didAddHome:(ThingSmartHomeModel *)home {
47 |
48 | long long homeId = home.homeId;
49 | if (!(homeId > 0)) {
50 | return;
51 | }
52 | NSDictionary *dic = @{
53 | @"homeId": [NSNumber numberWithLongLong:homeId],
54 | @"type": @"onHomeAdded"
55 | };
56 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeChangeEvent stringByAppendingString:@"//"] withBody:dic];
57 | }
58 |
59 | // 删除一个家庭
60 | - (void)homeManager:(ThingSmartHomeManager *)manager didRemoveHome:(long long)homeId {
61 |
62 | if (!(homeId > 0)) {
63 | return;
64 | }
65 | NSDictionary *dic = @{
66 | @"homeId": [NSNumber numberWithLongLong:homeId],
67 | @"type": @"onHomeRemoved"
68 | };
69 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeChangeEvent stringByAppendingString:@"//"] withBody:dic];
70 |
71 | }
72 |
73 | // MQTT连接成功
74 | - (void)serviceConnectedSuccess {
75 | // NSDictionary *dic = @{@"type": @"onServerConnectSuccess"};
76 | // [TuyaRNEventEmitter ty_sendEvent:kTYEventEmitterHomeChangeEvent withBody:dic];
77 | }
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/home/TuyaRoomModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.home
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.thingclips.smart.home.sdk.api.IThingRoom
6 | import com.tuya.smart.rnsdk.utils.Constant.NAME
7 | import com.tuya.smart.rnsdk.utils.Constant.DEVID
8 | import com.tuya.smart.rnsdk.utils.Constant.GROUPID
9 | import com.tuya.smart.rnsdk.utils.Constant.ROOMID
10 | import com.tuya.smart.rnsdk.utils.Constant.getIResultCallback
11 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
12 |
13 |
14 | class TuyaRoomModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
15 | override fun getName(): String {
16 | return "TuyaRoomModule"
17 | }
18 |
19 | /* 更新房间名称 */
20 | @ReactMethod
21 | fun updateRoom(params: ReadableMap, promise: Promise) {
22 | if (ReactParamsCheck.checkParams(arrayOf(ROOMID, NAME), params)) {
23 | getRoomInstance(params.getDouble(ROOMID)).updateRoom(params.getString(NAME), getIResultCallback(promise))
24 | }
25 | }
26 |
27 | /* 添加设备 */
28 | @ReactMethod
29 | fun addDevice(params: ReadableMap, promise: Promise) {
30 | if (ReactParamsCheck.checkParams(arrayOf(ROOMID, DEVID), params)) {
31 | getRoomInstance(params.getDouble(ROOMID)).addDevice(params.getString(DEVID), getIResultCallback(promise))
32 | }
33 | }
34 |
35 | /* 删除设备 */
36 | @ReactMethod
37 | fun removeDevice(params: ReadableMap, promise: Promise) {
38 | if (ReactParamsCheck.checkParams(arrayOf(ROOMID, DEVID), params)) {
39 | getRoomInstance(params.getDouble(ROOMID)).removeDevice(params.getString(DEVID), getIResultCallback(promise))
40 | }
41 | }
42 |
43 | /* 删除群组 */
44 | @ReactMethod
45 | fun removeGroup(params: ReadableMap, promise: Promise) {
46 | if (ReactParamsCheck.checkParams(arrayOf(ROOMID, GROUPID), params)) {
47 | getRoomInstance(params.getDouble(ROOMID)).removeGroup(params.getDouble(GROUPID).toLong(), getIResultCallback(promise))
48 | }
49 | }
50 |
51 | /* 添加群组 */
52 | @ReactMethod
53 | fun addGroup(params: ReadableMap, promise: Promise) {
54 | if (ReactParamsCheck.checkParams(arrayOf(ROOMID, GROUPID), params)) {
55 | getRoomInstance(params.getDouble(ROOMID)).addGroup(params.getDouble(GROUPID).toLong(), getIResultCallback(promise))
56 | }
57 | }
58 |
59 | fun getRoomInstance(roomId: Double): IThingRoom {
60 | return ThingHomeSdk.newRoomInstance(roomId.toLong())
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/message/TuyaMessageModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.message
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.android.user.api.IBooleanCallback
5 | import com.thingclips.smart.home.sdk.ThingHomeSdk
6 | import com.thingclips.smart.sdk.api.IThingDataCallback
7 | import com.thingclips.smart.sdk.bean.message.MessageBean
8 | import com.tuya.smart.rnsdk.utils.Constant
9 | import com.tuya.smart.rnsdk.utils.Constant.IDS
10 | import com.tuya.smart.rnsdk.utils.JsonUtils
11 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
12 | import com.tuya.smart.rnsdk.utils.TuyaReactUtils
13 | import java.util.ArrayList
14 |
15 |
16 |
17 | class TuyaMessageModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
18 | override fun getName(): String {
19 | return "TuyaMessageModule"
20 | }
21 | @ReactMethod
22 | fun getMessageList(promise: Promise) {
23 | ThingHomeSdk.getMessageInstance().getMessageList(object : IThingDataCallback> {
24 | override fun onSuccess(p0: List?) {
25 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(p0!!)))
26 | }
27 |
28 | override fun onError(p0: String?, p1: String?) {
29 | promise.reject(p0,p1)
30 | }
31 | })
32 | }
33 |
34 | @ReactMethod
35 | fun deleteMessage(params: ReadableMap, promise: Promise) {
36 | if (ReactParamsCheck.checkParams(arrayOf(IDS), params)) {
37 | var list = ArrayList()
38 | var length = (params.getArray(Constant.IDS) as ReadableArray).size()-1
39 | for (index in 0..length) {
40 | list.add((params.getArray(Constant.IDS) as ReadableArray).getString(index) as String)
41 | }
42 | ThingHomeSdk.getMessageInstance().deleteMessages(list,object : IBooleanCallback {
43 | override fun onSuccess(){
44 | promise.resolve(Constant.SUCCESS)
45 | }
46 |
47 | override fun onError(var1: String, var2: String) {
48 | promise.reject(var1,var2)
49 | }
50 | })
51 | }
52 | }
53 |
54 | @ReactMethod
55 | fun getMessageMaxTime(promise: Promise){
56 | ThingHomeSdk.getMessageInstance().getMessageMaxTime(object : IThingDataCallback {
57 | override fun onSuccess(p0: Int) {
58 | promise.resolve(p0)
59 | }
60 |
61 | override fun onError(p0: String?, p1: String?) {
62 | promise.reject(p0,p1)
63 | }
64 | })
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'maven-publish'
4 |
5 |
6 | buildscript {
7 | ext.kotlin_version = '1.7.20'
8 | repositories {
9 | jcenter()
10 | google()
11 | }
12 |
13 | dependencies {
14 | classpath 'com.android.tools.build:gradle:7.0.0'
15 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
16 | }
17 | }
18 |
19 |
20 | android {
21 | compileSdkVersion 31
22 |
23 | defaultConfig {
24 | minSdkVersion 23
25 | targetSdkVersion 25
26 | versionCode 1
27 | versionName "1.0"
28 |
29 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
30 |
31 | ndk {
32 | abiFilters "armeabi-v7a","arm64-v8a"
33 | }
34 | }
35 |
36 | packagingOptions {
37 | pickFirst 'lib/*/libc++_shared.so'
38 | }
39 |
40 | buildTypes {
41 | release {
42 | minifyEnabled false
43 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
44 | }
45 | }
46 |
47 | compileOptions {
48 | sourceCompatibility JavaVersion.VERSION_1_8
49 | targetCompatibility JavaVersion.VERSION_1_8
50 | }
51 | }
52 |
53 | configurations.all {
54 | exclude group: "com.thingclips.smart", module: 'thingsmart-modularCampAnno'
55 | }
56 |
57 | dependencies {
58 | implementation fileTree(dir: 'libs', include: ['*.jar'])
59 | implementation 'com.alibaba:fastjson:1.1.67.android'
60 | implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.6.0'
61 | implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0'
62 | implementation 'com.thingclips.smart:thingsmart:5.11.3'
63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
64 | implementation 'com.facebook.react:react-native:+'
65 | implementation 'de.greenrobot:eventbus:2.4.0'
66 | implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
67 | implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
68 | implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
69 | implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
70 | }
71 |
72 | repositories {
73 | mavenCentral()
74 | google()
75 | maven { url 'https://maven-other.tuya.com/repository/maven-releases/' }
76 | maven { url "https://maven-other.tuya.com/repository/maven-commercial-releases/" }
77 | maven { url 'https://maven.aliyun.com/repository/public' }
78 | maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
79 | maven { url 'https://developer.huawei.com/repo/' }
80 | maven { url 'https://jitpack.io' }
81 | }
82 |
83 | allprojects {
84 | repositories {
85 | exclusiveContent {
86 | filter {
87 | includeGroup "com.facebook.react"
88 | }
89 | forRepository {
90 | maven {
91 | url "$rootDir/../node_modules/react-native/android"
92 | }
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/BLEActivator/TuyaBLERNActivatorModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaBLERNActivatorModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaBLERNActivatorModule.h"
10 | #import
11 | #import
12 | #import
13 | #import
14 | #import
15 | #import "TuyaRNUtils+Network.h"
16 | #import "YYModel.h"
17 |
18 | #define kTuyaRNActivatorModuleHomeId @"homeId"
19 | #define kTuyaRNActivatorModuleDeviceId @"deviceId"
20 | #define kTuyaRNActivatorModuleProductId @"productId"
21 | #define kTuyaRNActivatorModuleSSID @"ssid"
22 | #define kTuyaRNActivatorModulePassword @"password"
23 |
24 | // Bluetooth Pairing
25 | static TuyaBLERNActivatorModule * activatorInstance = nil;
26 |
27 | @interface TuyaBLERNActivatorModule()
28 |
29 | @property(copy, nonatomic) RCTPromiseResolveBlock promiseResolveBlock;
30 | @property(copy, nonatomic) RCTPromiseRejectBlock promiseRejectBlock;
31 |
32 | @end
33 |
34 | @implementation TuyaBLERNActivatorModule
35 |
36 | RCT_EXPORT_MODULE(TuyaBLEActivatorModule)
37 |
38 | RCT_EXPORT_METHOD(initActivator:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
39 | if (activatorInstance == nil) {
40 | activatorInstance = [TuyaBLERNActivatorModule new];
41 | }
42 |
43 | [ThingSmartBLEWifiActivator sharedInstance].bleWifiDelegate = activatorInstance;
44 | activatorInstance.promiseResolveBlock = resolver;
45 | activatorInstance.promiseRejectBlock = rejecter;
46 |
47 | NSNumber *homeId = params[kTuyaRNActivatorModuleHomeId];
48 | NSString *deviceId = params[kTuyaRNActivatorModuleDeviceId];
49 | NSString *productId = params[kTuyaRNActivatorModuleProductId];
50 | NSString *ssid = params[kTuyaRNActivatorModuleSSID];
51 | NSString *password = params[kTuyaRNActivatorModulePassword];
52 | long long int homeIdValue = [homeId longLongValue];
53 |
54 | [[ThingSmartBLEWifiActivator sharedInstance] startConfigBLEWifiDeviceWithUUID:deviceId homeId:homeIdValue productId:productId ssid:ssid password:password timeout:180 success:^{
55 | // Wait for activation
56 | } failure:^ {
57 | if (activatorInstance.promiseRejectBlock) {
58 | [TuyaRNUtils rejecterWithError:nil handler:rejecter];
59 | }
60 | return;
61 | }];
62 | }
63 |
64 | - (void)bleWifiActivator:(ThingSmartBLEWifiActivator *)activator didReceiveBLEWifiConfigDevice:(ThingSmartDeviceModel *)deviceModel error:(NSError *)error {
65 | if (!error && deviceModel) {
66 | if (activatorInstance.promiseResolveBlock) {
67 | self.promiseResolveBlock([deviceModel yy_modelToJSONObject]);
68 | }
69 | }
70 | if (error) {
71 | if (activatorInstance.promiseRejectBlock) {
72 | [TuyaRNUtils rejecterWithError:error handler:activatorInstance.promiseRejectBlock];
73 | }
74 | }
75 |
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/TuyaReactPackage.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk
2 |
3 |
4 | import com.facebook.react.ReactPackage
5 | import com.facebook.react.bridge.JavaScriptModule
6 | import com.facebook.react.bridge.NativeModule
7 | import com.facebook.react.bridge.ReactApplicationContext
8 | import com.facebook.react.uimanager.ViewManager
9 | import com.tuya.smart.rnsdk.activator.TuyaActivatorModule
10 | import com.tuya.smart.rnsdk.core.TuyaCoreModule
11 | import com.tuya.smart.rnsdk.device.TuyaDeviceModule
12 | import com.tuya.smart.rnsdk.device.TuyaGatewayModule
13 | import com.tuya.smart.rnsdk.device.TuyaOTAModule
14 | import com.tuya.smart.rnsdk.device.TuyaSingleTransferModule
15 | import com.tuya.smart.rnsdk.feedback.TuyaFeedBackModule
16 | import com.tuya.smart.rnsdk.group.TuyaGroupModule
17 | import com.tuya.smart.rnsdk.home.TuyaHomeDataManagerModule
18 | import com.tuya.smart.rnsdk.home.TuyaHomeManagerModule
19 | import com.tuya.smart.rnsdk.home.TuyaHomeMemberModule
20 | import com.tuya.smart.rnsdk.home.TuyaHomeModule
21 | import com.tuya.smart.rnsdk.home.TuyaRoomModule
22 | import com.tuya.smart.rnsdk.message.TuyaMessageModule
23 | import com.tuya.smart.rnsdk.push.TuyaPushModule
24 | import com.tuya.smart.rnsdk.scene.TuyaSceneModule
25 | import com.tuya.smart.rnsdk.share.TuyaShareModule
26 | import com.tuya.smart.rnsdk.timer.TuyaTimerModule
27 | import com.tuya.smart.rnsdk.user.TuyaUserModule
28 |
29 | import java.util.*
30 |
31 | class TuyaReactPackage : ReactPackage {
32 |
33 | // override fun createJSModules(): MutableList> {
34 | // return Collections.emptyList();
35 | // }
36 |
37 | override fun createNativeModules(reactContext: ReactApplicationContext): MutableList {
38 | val module: ArrayList = ArrayList()
39 | module.add(TuyaActivatorModule(reactContext))
40 | module.add(TuyaCoreModule(reactContext))
41 | module.add(TuyaDeviceModule(reactContext))
42 | module.add(TuyaGatewayModule(reactContext))
43 | module.add(TuyaOTAModule(reactContext))
44 | module.add(TuyaSingleTransferModule(reactContext))
45 | module.add(TuyaFeedBackModule(reactContext))
46 | module.add(TuyaGroupModule(reactContext))
47 | module.add(TuyaHomeDataManagerModule(reactContext))
48 | module.add(TuyaHomeManagerModule(reactContext))
49 | module.add(TuyaHomeMemberModule(reactContext))
50 | module.add(TuyaHomeModule(reactContext))
51 | module.add(TuyaRoomModule(reactContext))
52 | module.add(TuyaMessageModule(reactContext))
53 | module.add(TuyaPushModule(reactContext))
54 | module.add(TuyaShareModule(reactContext))
55 | module.add(TuyaTimerModule(reactContext))
56 | module.add(TuyaUserModule(reactContext))
57 | module.add(TuyaSceneModule(reactContext))
58 | return module
59 | }
60 |
61 | override fun createViewManagers(reactContext: ReactApplicationContext): List> {
62 | val managers = ArrayList>()
63 | return managers
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Room/TuyaRNRoomModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNRoomModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNRoomModule.h"
10 | #import
11 | #import "TuyaRNUtils.h"
12 |
13 | #define kTuyaRNRoomModuleName @"name"
14 | #define kTuyaRNRoomModuleGroupId @"groupId"
15 | #define kTuyaRNRoomModuleDevId @"devId"
16 | #define kTuyaRNRoomModuleRoomId @"roomId"
17 | #define kTuyaRNRoomModuleHomeId @"homeId"
18 |
19 | @interface TuyaRNRoomModule()
20 |
21 | @property (strong, nonatomic) ThingSmartRoom *smartRoom;
22 |
23 | @end
24 |
25 | @implementation TuyaRNRoomModule
26 |
27 | RCT_EXPORT_MODULE(TuyaRoomModule)
28 |
29 | /**
30 | * 更新房间名称
31 | *
32 | * @param name 新房间名称
33 | */
34 | RCT_EXPORT_METHOD(updateRoom:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
35 |
36 | self.smartRoom = [self smartRoomWithParams:params];
37 | NSString *name = params[kTuyaRNRoomModuleName];
38 |
39 | [self.smartRoom updateRoomName:name success:^{
40 | [TuyaRNUtils resolverWithHandler:resolver];
41 | } failure:^(NSError *error) {
42 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
43 | }];
44 |
45 | }
46 |
47 | RCT_EXPORT_METHOD(addDevice:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
48 |
49 | self.smartRoom = [self smartRoomWithParams:params];
50 | NSString *deviceId = params[kTuyaRNRoomModuleDevId];
51 |
52 | [self.smartRoom addDeviceWithDeviceId:deviceId success:^{
53 | [TuyaRNUtils resolverWithHandler:resolver];
54 | } failure:^(NSError *error) {
55 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
56 | }];
57 | }
58 |
59 |
60 | RCT_EXPORT_METHOD(removeDevice:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
61 |
62 | self.smartRoom = [self smartRoomWithParams:params];
63 |
64 | NSString *deviceId = params[kTuyaRNRoomModuleDevId];
65 |
66 | [self.smartRoom removeDeviceWithDeviceId:deviceId success:^{
67 | [TuyaRNUtils resolverWithHandler:resolver];
68 | } failure:^(NSError *error) {
69 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
70 | }];
71 |
72 | }
73 |
74 | RCT_EXPORT_METHOD(removeGroup:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
75 |
76 | self.smartRoom = [self smartRoomWithParams:params];
77 |
78 | NSString *groupId = params[kTuyaRNRoomModuleGroupId];
79 |
80 | [self.smartRoom removeGroupWithGroupId:groupId success:^{
81 | [TuyaRNUtils resolverWithHandler:resolver];
82 | } failure:^(NSError *error) {
83 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
84 | }];
85 |
86 | }
87 |
88 | #pragma mark -
89 | #pragma mark - init
90 | - (ThingSmartRoom *)smartRoomWithParams:(NSDictionary *)params {
91 |
92 | NSNumber *homeId = params[kTuyaRNRoomModuleHomeId];
93 | NSNumber *roomId = params[kTuyaRNRoomModuleRoomId];
94 | return [ThingSmartRoom roomWithRoomId:roomId.longLongValue homeId:homeId.longLongValue];
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/device/TuyaSingleTransferModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.device
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.thingclips.smart.home.sdk.bean.TransferDataBean
6 | import com.thingclips.smart.sdk.api.IThingDataCallback
7 | import com.tuya.smart.rnsdk.utils.BridgeUtils
8 | import com.tuya.smart.rnsdk.utils.Constant
9 | import com.tuya.smart.rnsdk.utils.Constant.DEVID
10 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
11 | import com.tuya.smart.rnsdk.utils.TuyaReactUtils
12 |
13 | class TuyaSingleTransferModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
14 | override fun getName(): String {
15 | return "TuyaSingleTransferModule"
16 | }
17 |
18 | /**
19 | * 开始连接
20 | */
21 | @ReactMethod
22 | fun startConnect() {
23 | ThingHomeSdk.getTransferInstance().startConnect()
24 | }
25 |
26 | /**
27 | * 是否在线
28 | */
29 | @ReactMethod
30 | fun isOnline(promise: Promise) {
31 | promise.resolve(ThingHomeSdk.getTransferInstance().isOnline)
32 | }
33 |
34 | /**
35 | * 订阅设备数据,订阅设备之后,设备如果有数据上报上来,便可以通过 registerTransferDataListener 回调上来。需要注意的是,每次通道连接成功都需要重新订阅设备数据
36 | */
37 | @ReactMethod
38 | fun subscribeDevice(params: ReadableMap) {
39 | if (ReactParamsCheck.checkParams(arrayOf(Constant.DEVID), params)) {
40 | ThingHomeSdk.getTransferInstance().subscribeDevice(params.getString(DEVID))
41 | }
42 | }
43 |
44 | /**
45 | * 取消订阅设备信息,则设备数据不在收到
46 | *
47 | */
48 | @ReactMethod
49 | fun unSubscribeDevice(params: ReadableMap) {
50 | if (ReactParamsCheck.checkParams(arrayOf(Constant.DEVID), params)) {
51 | ThingHomeSdk.getTransferInstance().unSubscribeDevice(params.getString(DEVID))
52 | }
53 | }
54 |
55 | @ReactMethod
56 | fun registerTransferDataListener(params: ReadableMap) {
57 | if (ReactParamsCheck.checkParams(arrayOf(Constant.DEVID), params)) {
58 | ThingHomeSdk.getTransferInstance().registerTransferDataListener(object : IThingDataCallback {
59 | override fun onSuccess(var1: TransferDataBean){
60 | val map = Arguments.createMap()
61 | map.putString("devId", params.getString(DEVID))
62 | map.putMap("data", TuyaReactUtils.parseToWritableMap(var1))
63 | map.putString("type", "onSuccess");
64 | BridgeUtils.singleTransferListener(reactApplicationContext, map, params.getString(DEVID) as String)
65 | }
66 |
67 | override fun onError(var1: String, var2: String){
68 | val map = Arguments.createMap()
69 | map.putString("devId", params.getString(DEVID))
70 | map.putString("var1", var1)
71 | map.putString("var2", var2)
72 | map.putString("type", "onError");
73 | BridgeUtils.singleTransferListener(reactApplicationContext, map, params.getString(DEVID) as String)
74 | }
75 | })
76 | }
77 | }
78 |
79 | @ReactMethod
80 | fun unRegisterTransferDataListener(params: ReadableMap) {
81 | }
82 | @ReactMethod
83 | fun stopConnect() {
84 | ThingHomeSdk.getTransferInstance().stopConnect()
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/home/TuyaHomeMemberModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.home
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.thingclips.smart.home.sdk.bean.MemberBean
6 | import com.thingclips.smart.home.sdk.callback.IThingGetMemberListCallback
7 | import com.thingclips.smart.home.sdk.callback.IThingMemberResultCallback
8 | import com.tuya.smart.rnsdk.utils.Constant
9 | import com.tuya.smart.rnsdk.utils.JsonUtils
10 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
11 | import com.tuya.smart.rnsdk.utils.TuyaReactUtils
12 |
13 | class TuyaHomeMemberModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
14 | override fun getName(): String {
15 | return "TuyaHomeMemberModule"
16 | }
17 | /* 添加成员 */
18 | @ReactMethod
19 | fun addMember(params: ReadableMap, promise: Promise) {
20 | if (ReactParamsCheck.checkParams(arrayOf(Constant.HOMEID, Constant.COUNTRYCODE, Constant.USERACCOUNT, Constant.NAME, Constant.ADMIN), params)) {
21 | ThingHomeSdk.getMemberInstance().addMember(
22 | params.getDouble(Constant.HOMEID).toLong(),
23 | params.getString(Constant.COUNTRYCODE),
24 | params.getString(Constant.USERACCOUNT),
25 | params.getString(Constant.NAME),
26 | params.getBoolean(Constant.ADMIN),
27 | object : IThingMemberResultCallback {
28 | override fun onSuccess(var1: MemberBean){
29 | promise.resolve(TuyaReactUtils.parseToWritableMap(var1))
30 | }
31 |
32 | override fun onError(var1: String, var2: String){
33 | promise.reject(var1,var2)
34 | }
35 | }
36 | )
37 | }
38 | }
39 | /* 移除Home下面的成员 */
40 | @ReactMethod
41 | fun removeMember(params: ReadableMap, promise: Promise) {
42 | if (ReactParamsCheck.checkParams(arrayOf(Constant.MEMBERID),params)) {
43 | ThingHomeSdk.getMemberInstance().removeMember(params.getDouble(Constant.MEMBERID).toLong(), Constant.getIResultCallback(promise))
44 | }
45 | }
46 | /* 更新成员备注名和权限 */
47 | @ReactMethod
48 | fun updateMember(params: ReadableMap, promise: Promise) {
49 | if (ReactParamsCheck.checkParams(arrayOf(Constant.MEMBERID, Constant.NAME, Constant.ADMIN),params)) {
50 | ThingHomeSdk.getMemberInstance().updateMember(params.getDouble(Constant.MEMBERID).toLong(),params.getString(Constant.NAME),params.getBoolean(Constant.ADMIN), Constant.getIResultCallback(promise))
51 | }
52 | }
53 |
54 | /* 查询Home下面的成员列表 */
55 | @ReactMethod
56 | fun queryMemberList(params: ReadableMap, promise: Promise) {
57 | if (ReactParamsCheck.checkParams(arrayOf(Constant.HOMEID),params)) {
58 | ThingHomeSdk.getMemberInstance().queryMemberList(params.getDouble(Constant.HOMEID).toLong(),object : IThingGetMemberListCallback {
59 | override fun onSuccess(var1: List){
60 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(var1)))
61 | }
62 |
63 | override fun onError(var1: String, var2: String){
64 | promise.reject(var1,var2)
65 | }
66 | })
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Group/TuyaRNGroupModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNGroupModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNGroupModule.h"
10 | #import
11 | #import "TuyaRNUtils.h"
12 | #import
13 |
14 |
15 |
16 | @implementation TuyaRNGroupModule
17 |
18 | RCT_EXPORT_MODULE(TuyaGroupModule)
19 |
20 | RCT_EXPORT_METHOD(initWithOptions:(NSDictionary *)params) {
21 |
22 | }
23 |
24 | RCT_EXPORT_METHOD(onDestory:(NSDictionary *)params) {
25 |
26 | }
27 |
28 |
29 | // 创建群组:
30 | RCT_EXPORT_METHOD(createGroup:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
31 | [ThingSmartGroup createGroupWithName:params[@"name"] productId:params[@"productId"] homeId:[params[@"homeId"] integerValue] devIdList:params[@"devIds"] success:^(ThingSmartGroup *group) {
32 | if (resolver) {
33 | resolver([group yy_modelToJSONObject]);
34 | }
35 | } failure:^(NSError *error) {
36 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
37 | }];
38 | }
39 |
40 |
41 | // 群组列表获取:
42 | RCT_EXPORT_METHOD(queryDeviceListToAddGroup:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
43 | [ThingSmartGroup getDevList:params[@"productId"] homeId:[params[@"homeId"] integerValue] success:^(NSArray *list) {
44 | NSMutableArray *res = [NSMutableArray array];
45 | for (ThingSmartGroupDevListModel *item in list) {
46 | NSDictionary *dic = [item yy_modelToJSONObject];
47 | [res addObject:dic];
48 | }
49 | if (resolver) {
50 | resolver(res);
51 | }
52 | } failure:^(NSError *error) {
53 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
54 | }];
55 | }
56 |
57 | // 群组修改名称:
58 | RCT_EXPORT_METHOD(updateGroupName:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
59 | ThingSmartGroup *smartGroup = [ThingSmartGroup groupWithGroupId:params[@"groupID"]];
60 | [smartGroup updateGroupName:params[@"name"] success:^{
61 | if (resolver) {
62 | resolver(@"success");
63 | }
64 | } failure:^(NSError *error) {
65 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
66 | }];
67 | }
68 |
69 | // 解散群组:
70 | RCT_EXPORT_METHOD(dismissGroup:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
71 | ThingSmartGroup *smartGroup = [ThingSmartGroup groupWithGroupId:params[@"groupID"]];
72 | [smartGroup dismissGroup:^{
73 | if (resolver) {
74 | resolver(@"success");
75 | }
76 | } failure:^(NSError *error) {
77 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
78 | }];
79 | }
80 |
81 |
82 | // 发送群组控制命令:
83 | RCT_EXPORT_METHOD(publishDps:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
84 | ThingSmartGroup *smartGroup = [ThingSmartGroup groupWithGroupId:params[@"groupID"]];
85 | NSDictionary *dps = @{@"1": @(YES)};
86 | [smartGroup publishDps:dps success:^{
87 | if (resolver) {
88 | resolver(@"success");
89 | }
90 | } failure:^(NSError *error) {
91 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
92 | }];
93 |
94 | }
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | @end
106 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Feedback/TuyaRNFeedBackModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNFeedBackModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNFeedBackModule.h"
10 | #import
11 | #import "TuyaRNUtils.h"
12 | #import "YYModel.h"
13 |
14 | @interface TuyaRNFeedBackModule()
15 | @property (nonatomic, strong) ThingSmartFeedback *smartFeedback;
16 | @end
17 |
18 |
19 | @implementation TuyaRNFeedBackModule
20 |
21 | RCT_EXPORT_MODULE(TuyaFeedBackModule)
22 |
23 | RCT_EXPORT_METHOD(initWithOptions:(NSDictionary *)params) {
24 |
25 | }
26 |
27 | // 获取反馈列表:
28 | RCT_EXPORT_METHOD(getFeedbackMsg:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
29 | ThingSmartFeedback *feedBack = [[ThingSmartFeedback alloc] init];
30 | self.smartFeedback = feedBack;
31 | [feedBack getFeedbackList:params[@"hdId"] hdType:[params[@"hdType"] unsignedIntegerValue] success:^(NSArray *list) {
32 | NSMutableArray *res = [NSMutableArray array];
33 | for (ThingSmartFeedbackModel *item in list) {
34 | NSDictionary *dic = [item yy_modelToJSONObject];
35 | [res addObject:dic];
36 | }
37 | if (resolver) {
38 | resolver(res);
39 | }
40 | } failure:^(NSError *error) {
41 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
42 | }];
43 |
44 | }
45 |
46 |
47 |
48 | // 获取反馈类型列表:
49 | RCT_EXPORT_METHOD(getFeedbackType:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
50 | ThingSmartFeedback *feedBack = [[ThingSmartFeedback alloc] init];
51 | self.smartFeedback = feedBack;
52 | [feedBack getFeedbackTypeList:^(NSArray *list) {
53 |
54 | NSMutableArray *res = [NSMutableArray array];
55 | for (ThingSmartFeedbackTypeListModel *item in list) {
56 | NSDictionary *dic = [item yy_modelToJSONObject];
57 | [res addObject:dic];
58 | }
59 | if (resolver) {
60 | resolver(res);
61 | }
62 | } failure:^(NSError *error) {
63 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
64 | }];
65 | }
66 |
67 |
68 | // 新增反馈:
69 | RCT_EXPORT_METHOD(addMsg:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
70 | ThingSmartFeedback *feedBack = [[ThingSmartFeedback alloc] init];
71 | self.smartFeedback = feedBack;
72 | [feedBack addFeedback:params[@"message"] hdId:params[@"hdId"] hdType:[params[@"hdType"] integerValue] contact:params[@"contact"] success:^{
73 | if (resolver) {
74 | resolver(@"success");
75 | }
76 | } failure:^(NSError *error) {
77 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
78 | }];
79 | }
80 |
81 |
82 | // 反馈消息管理:
83 | RCT_EXPORT_METHOD(getFeedbackList:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
84 | ThingSmartFeedback *feedBack = [[ThingSmartFeedback alloc] init];
85 | self.smartFeedback = feedBack;
86 | [feedBack getFeedbackTalkList:^(NSArray *list) {
87 | NSMutableArray *res = [NSMutableArray array];
88 | for (ThingSmartFeedbackTalkListModel *item in list) {
89 | NSDictionary *dic = [item yy_modelToJSONObject];
90 | [res addObject:dic];
91 | }
92 | if (resolver) {
93 | resolver(res);
94 | }
95 | } failure:^(NSError *error) {
96 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
97 | }];
98 | }
99 |
100 |
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/device/TuyaOTAModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.device
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.android.device.bean.UpgradeInfoBean
5 | import com.thingclips.smart.home.sdk.ThingHomeSdk
6 | import com.thingclips.smart.sdk.api.IGetOtaInfoCallback
7 | import com.thingclips.smart.sdk.api.IOtaListener
8 | import com.thingclips.smart.sdk.api.IThingOta
9 | import com.thingclips.smart.sdk.bean.OTAErrorMessageBean
10 | import com.tuya.smart.rnsdk.utils.*
11 | import com.tuya.smart.rnsdk.utils.Constant.DEVID
12 |
13 |
14 | class TuyaOTAModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
15 | override fun getName(): String {
16 | return "TuyaOTAModule"
17 | }
18 |
19 | var iTuyaOta: IThingOta?=null
20 | /* 获取固件升级信息 */
21 | @ReactMethod
22 | fun getOtaInfo(params: ReadableMap,promise: Promise) {
23 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
24 | getIoat(params.getString(DEVID) as String).getOtaInfo(object : IGetOtaInfoCallback {
25 | override fun onSuccess(list: List) {
26 | promise.resolve(TuyaReactUtils.parseToWritableArray(
27 | JsonUtils.toJsonArray(list)))
28 | }
29 |
30 | override fun onFailure(code: String, error: String){
31 | promise.reject(code,error)
32 | }
33 | })
34 | }
35 | }
36 | /* 设置升级状态回调 */
37 | @ReactMethod
38 | fun startOta(params: ReadableMap) {
39 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
40 | iTuyaOta = getIoat(params.getString(DEVID) as String)
41 | iTuyaOta?.setOtaListener(object : IOtaListener {
42 | override fun onSuccess(otaType: Int) {
43 | var map=Arguments.createMap();
44 | map.putInt("otaType",otaType)
45 | map.putString("type","onSuccess")
46 | BridgeUtils.hardwareUpgradeListener(reactApplicationContext,map,params.getString(DEVID) as String)
47 | }
48 |
49 | override fun onStatusChanged(otaStatus: Int, otaType: Int) {
50 | //
51 | }
52 |
53 | override fun onTimeout(otaType: Int) {
54 | //
55 | }
56 |
57 | override fun onFailureWithText(otaType: Int, code: String, messageBean: OTAErrorMessageBean) {
58 | //
59 | }
60 |
61 | override fun onFailure(otaType: Int, code: String, error: String) {
62 | var map=Arguments.createMap();
63 | map.putInt("otaType",otaType)
64 | map.putString("error",error)
65 | map.putString("code",code)
66 | map.putString("type","onFailure")
67 | BridgeUtils.hardwareUpgradeListener(reactApplicationContext,map,params.getString(DEVID) as String)
68 | }
69 |
70 | override fun onProgress(otaType: Int, progress: Int) {
71 | var map=Arguments.createMap();
72 | map.putInt("otaType",otaType)
73 | map.putInt("progress",progress)
74 | map.putString("type","onProgress")
75 | BridgeUtils.hardwareUpgradeListener(reactApplicationContext,map,params.getString(DEVID) as String)
76 | }
77 | })
78 | iTuyaOta?.startOta()
79 | }
80 | }
81 | @ReactMethod
82 | fun onDestroy(){
83 | iTuyaOta?.onDestroy()
84 | }
85 | fun getIoat(devId:String): IThingOta {
86 | return ThingHomeSdk.newOTAInstance(devId)
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Home/TuyaRNHomeDataManagerModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeDataManagerModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/2.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNHomeDataManagerModule.h"
10 | #import
11 | #import "TuyaRNUtils+Cache.h"
12 | #import "TuyaRNUtils+DeviceParser.h"
13 |
14 | #define kTuyaRNHomeDataManagerModuleHomeId @"homeId"
15 | #define kTuyaRNHomeDataManagerModuleRoomId @"roomId"
16 |
17 | @interface TuyaRNHomeDataManagerModule()
18 |
19 | @property (strong, nonatomic) ThingSmartRoom *smartRoom;
20 |
21 | @end
22 |
23 | @implementation TuyaRNHomeDataManagerModule
24 |
25 | RCT_EXPORT_MODULE(TuyaHomeDataManagerModule)
26 |
27 | RCT_EXPORT_METHOD(getHomeRoomList:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
28 |
29 | }
30 |
31 | RCT_EXPORT_METHOD(getHomeDeviceList:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
32 |
33 | }
34 |
35 | RCT_EXPORT_METHOD(getHomeGroupList:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
36 |
37 | }
38 |
39 |
40 | RCT_EXPORT_METHOD(getGroupBean:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
41 |
42 | }
43 |
44 | RCT_EXPORT_METHOD(getDeviceBean:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
45 |
46 | }
47 |
48 | RCT_EXPORT_METHOD(getGroupRoomBean:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
49 |
50 | }
51 |
52 |
53 | RCT_EXPORT_METHOD(getRoomBean:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
54 |
55 | }
56 |
57 | RCT_EXPORT_METHOD(getDeviceRoomBean:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
58 |
59 | }
60 |
61 | RCT_EXPORT_METHOD(getGroupDeviceList:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
62 |
63 | }
64 |
65 |
66 | RCT_EXPORT_METHOD(getMeshGroupList:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
67 |
68 | }
69 |
70 | RCT_EXPORT_METHOD(getMeshDeviceList:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
71 |
72 | }
73 |
74 | RCT_EXPORT_METHOD(getRoomDeviceList:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
75 |
76 | //获取room下的Device
77 | NSNumber *homeId = params[kTuyaRNHomeDataManagerModuleHomeId];
78 | if(!homeId) {
79 | homeId = [TuyaRNUtils currentHomeId];
80 | }
81 | NSNumber *roomId = params[kTuyaRNHomeDataManagerModuleRoomId];
82 |
83 | //获取room下的设备
84 | self.smartRoom = [ThingSmartRoom roomWithRoomId:roomId.longLongValue homeId:homeId.longLongValue];
85 | if(resolver) {
86 | NSMutableDictionary *roomDic = [[NSMutableDictionary alloc] initWithCapacity:2];
87 | [roomDic setObject:getValidDataForDeviceModel(self.smartRoom.deviceList) forKey:@"deviceList"];
88 | [roomDic setObject:getValidDataForGroupModel(self.smartRoom.groupList) forKey:@"groupList"];
89 | resolver(roomDic);
90 | }
91 | }
92 |
93 | RCT_EXPORT_METHOD(getRoomGroupList:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
94 |
95 | }
96 |
97 | RCT_EXPORT_METHOD(getHomeBean:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
98 |
99 | }
100 |
101 | @end
102 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/utils/Constant.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.utils
2 |
3 | import com.facebook.react.bridge.Promise
4 | import com.thingclips.smart.sdk.api.IResultCallback
5 |
6 | object Constant {
7 |
8 | /**
9 | * 在创建自动化条件时标识符
10 | */
11 | const val ENTITY_TYPE_TIMER = 6
12 | const val ENTITY_TYPE_WEATHER = 3
13 | const val ENTITY_TYPE_DEVICE = 1
14 | const val ENTITY_TYPE = "entityType"
15 |
16 | const val SUCCESS = "success"
17 | const val FAILED = "failed"
18 |
19 | const val NEEDLOGIN = "needLogin"
20 | const val API_REQUEST_ERROR = "api request error"
21 |
22 | const val COUNTRYCODE = "countryCode"
23 | const val EMAIL = "email"
24 | const val PHONENUMBER = "phoneNumber"
25 | const val VALIDATECODE = "validateCode"
26 | const val PASSWORD = "password"
27 | const val NEWPASSWORD = "newPassword"
28 | const val CODE = "code"
29 | const val UID = "uid"
30 | const val KEY = "key"
31 | const val SECRET = "secret"
32 | const val USERID = "userId"
33 | const val ACCESSTOKEN = "accessToken"
34 | const val TOKEN = "token"
35 | const val FILEPATH = "filePath"
36 | const val TEMPUNITENUM = "tempUnitEnum"
37 |
38 | const val DEVID = "devId"
39 | const val GROUPID = "groupId"
40 | const val MESHID = "meshId"
41 | const val HOMEID = "homeId"
42 | const val NAME = "name"
43 | const val LON = "lon"
44 | const val LAT = "lat"
45 | const val GEONAME = "geoName"
46 | const val ROOMID = "roomId"
47 | const val ACTION = "action"
48 | const val IDLIST = "idList"
49 | const val PRODUCTID = "productId"
50 | const val DEVIDLIST = "devIdList"
51 | const val ROMMS = "rooms"
52 | const val MEMBERID = "memberId"
53 | const val USERACCOUNT = "userAccount"
54 | const val ADMIN = "admin"
55 | const val SSID = "ssid"
56 | const val TIME = "time"
57 | const val ACTIVATORMODELENUM = "ActivatorModelEnum"
58 | const val COMMAND = "command"
59 | const val DATAPOINTTYPEENUM = "DataPointTypeEnum"
60 | const val NUMBER = "number"
61 | const val STARTTIME = "startTime"
62 | const val DEVIDS = "devIds"
63 | const val IDS = "ids"
64 | const val OPERATOR = "operator"
65 |
66 | const val TASKNAME = "taskName"
67 | const val LOOPS = "loops"
68 | const val DPS = "dps"
69 | const val TIMERID = "timerId"
70 | const val INSTRUCT = "instruct"
71 | const val DPID = "dpId"
72 | const val ISOPEN = "isOpen"
73 | const val STATUS = "status"
74 | const val SHAREID = "shareId"
75 | const val GROUPNAME = "groupName"
76 | const val GROUPLISTENER = "GroupListener"
77 | const val SHOWFAHRENHEIT = "showFahrenheit"
78 |
79 | const val LOCALID = "localId"
80 |
81 | const val CITYID = "cityId"
82 | const val CITYIDS = "cityIdS"
83 | const val CONDITIONLISTS = "conditionList"
84 |
85 | const val RULE = "rule"
86 | const val CONDITIONS = "conditions"
87 | const val SCENETASK = "SceneTask"
88 | const val SCENEID = "sceneId"
89 | const val SCENEIDS = "sceneIds"
90 | const val TASK = "task"
91 | const val TYPE = "type"
92 | const val DISPLAY = "display"
93 | const val VALUE = "value"
94 | const val TASKS = "tasks"
95 | const val RANGE = "range"
96 | const val ID = "id"
97 | const val MESEAGE = "message"
98 | const val CONTACT = "contact"
99 | const val HDID = "hdId"
100 | const val HDTYPE = "hdType"
101 | const val RULES = "rules"
102 | const val DPVALUE = "dpvalue"
103 |
104 | const val STICKYONTOP = "stickyOnTop"
105 | const val BACKGROUND = "background"
106 | const val MATCHTYPE = "matchType"
107 | const val ALIASID = "aliasId"
108 | const val PUSHPROVIDER = "pushProvider"
109 | fun getIResultCallback(promise: Promise): IResultCallback? {
110 | return object : IResultCallback {
111 | override fun onSuccess() {
112 | promise.resolve(Constant.SUCCESS)
113 | }
114 |
115 | override fun onError(code: String?, error: String?) {
116 | promise.reject(code, error)
117 | }
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/device/TuyaGatewayModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.device
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.thingclips.smart.sdk.api.ISubDevListener
6 | import com.tuya.smart.rnsdk.utils.*
7 |
8 | class TuyaGatewayModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
9 | override fun getName(): String {
10 | return "TuyaGatewayModule"
11 | }
12 |
13 | @ReactMethod
14 | fun publishDps(params: ReadableMap,promise: Promise) {
15 | if (ReactParamsCheck.checkParams(arrayOf(Constant.DEVID,Constant.LOCALID,Constant.DPS), params)) {
16 | ThingHomeSdk.newGatewayInstance(params.getString(Constant.DEVID)).publishDps(params.getString(Constant.LOCALID),params.getString(Constant.DPS),Constant.getIResultCallback(promise))
17 | }
18 | }
19 |
20 |
21 |
22 | @ReactMethod
23 | fun broadcastDps(params: ReadableMap,promise: Promise) {
24 | if (ReactParamsCheck.checkParams(arrayOf(Constant.DEVID,Constant.DPS), params)) {
25 | ThingHomeSdk.newGatewayInstance(params.getString(Constant.DEVID)).broadcastDps(params.getString(Constant.DPS),Constant.getIResultCallback(promise))
26 | }
27 | }
28 |
29 | @ReactMethod
30 | fun multicastDps(params: ReadableMap,promise: Promise) {
31 | if (ReactParamsCheck.checkParams(arrayOf(Constant.DEVID,Constant.LOCALID,Constant.DPS), params)) {
32 | ThingHomeSdk.newGatewayInstance(params.getString(Constant.DEVID)).multicastDps(params.getString(Constant.LOCALID),params.getString(Constant.DPS),Constant.getIResultCallback(promise))
33 | }
34 | }
35 |
36 |
37 |
38 | @ReactMethod
39 | fun registerSubDevListener(params: ReadableMap) {
40 | if (ReactParamsCheck.checkParams(arrayOf(Constant.DEVID), params)) {
41 | ThingHomeSdk.newGatewayInstance(params.getString(Constant.DEVID)).registerSubDevListener(object : ISubDevListener {
42 | override fun onSubDevDpUpdate(var1: String, var2: String){
43 | val map = Arguments.createMap()
44 | map.putString("devId", var1)
45 | map.putString("dpStr", var2)
46 | map.putString("type", "onSubDevDpUpdate");
47 | BridgeUtils.subDevListener(reactApplicationContext, map, params.getString(Constant.DEVID) as String)
48 | }
49 |
50 | override fun onSubDevRemoved(var1: String){
51 | val map = Arguments.createMap()
52 | map.putString("devId", var1)
53 | map.putString("type", "onSubDevRemoved");
54 | BridgeUtils.subDevListener(reactApplicationContext, map, params.getString(Constant.DEVID) as String)
55 | }
56 |
57 | override fun onSubDevAdded(var1: String){
58 | val map = Arguments.createMap()
59 | map.putString("devId", var1)
60 | map.putString("type", "onSubDevAdded");
61 | BridgeUtils.subDevListener(reactApplicationContext, map, params.getString(Constant.DEVID) as String)
62 | }
63 |
64 | override fun onSubDevInfoUpdate(var1: String){
65 | val map = Arguments.createMap()
66 | map.putString("devId", var1)
67 | map.putString("type", "onSubDevInfoUpdate");
68 | BridgeUtils.subDevListener(reactApplicationContext, map, params.getString(Constant.DEVID) as String)
69 | }
70 |
71 | override fun onSubDevStatusChanged(var1: List, var2: List){
72 | val map = Arguments.createMap()
73 | map.putArray("data1", TuyaReactUtils.parseToWritableArray(
74 | JsonUtils.toJsonArray(var1)))
75 | map.putArray("data2", TuyaReactUtils.parseToWritableArray(
76 | JsonUtils.toJsonArray(var2)));
77 | map.putString("type", "onSubDevStatusChanged");
78 | BridgeUtils.subDevListener(reactApplicationContext, map, params.getString(Constant.DEVID) as String)
79 | }
80 | })
81 | }
82 | }
83 |
84 | @ReactMethod
85 | fun unRegisterSubDevListener(params: ReadableMap) {
86 | if (ReactParamsCheck.checkParams(arrayOf(Constant.DEVID), params)) {
87 | ThingHomeSdk.newGatewayInstance(params.getString(Constant.DEVID)).unRegisterSubDevListener()
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNGroupListener.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNGroupListener.m
3 | // TuyaRnDemo
4 | //
5 | // Created by Elon on 2019/3/7.
6 | // Copyright © 2019 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNGroupListener.h"
10 | #import
11 | #import
12 | #import
13 | #import "TuyaRNEventEmitter.h"
14 |
15 | @interface TuyaRNGroupListener()
16 |
17 | @property (nonatomic, strong) NSMutableArray *listenGroupArr;
18 | @end
19 |
20 | @implementation TuyaRNGroupListener
21 |
22 | + (instancetype)shareInstance {
23 | static TuyaRNGroupListener *listenerInstance = nil;
24 | static dispatch_once_t onceToken;
25 | dispatch_once(&onceToken, ^{
26 | listenerInstance = [TuyaRNGroupListener new];
27 | });
28 | return listenerInstance;
29 | }
30 |
31 |
32 | - (instancetype)init {
33 | if (self = [super init]) {
34 | _listenGroupArr = [NSMutableArray new];
35 | }
36 | return self;
37 | }
38 |
39 | + (void)registerGroup:(ThingSmartGroup *)group {
40 |
41 | __block BOOL exist = NO;
42 | [[TuyaRNGroupListener shareInstance].listenGroupArr enumerateObjectsUsingBlock:^(ThingSmartGroup * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
43 | if ([obj.groupModel.groupId isEqualToString:group.groupModel.groupId]) {
44 | exist = YES;
45 | *stop = YES;
46 | }
47 | }];
48 |
49 | group.delegate = [TuyaRNGroupListener shareInstance];
50 |
51 | if (!exist) {
52 | if ([TuyaRNGroupListener shareInstance].listenGroupArr.count == 0) {
53 | }
54 | [[TuyaRNGroupListener shareInstance].listenGroupArr addObject:group];
55 | }
56 | }
57 |
58 | + (void)removeDevice:(ThingSmartGroup *)group {
59 | [[[TuyaRNGroupListener shareInstance].listenGroupArr mutableCopy] enumerateObjectsUsingBlock:^(ThingSmartGroup * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
60 | if ([obj.groupModel.groupId isEqualToString:group.groupModel.groupId]) {
61 | obj.delegate = nil;
62 | [[TuyaRNGroupListener shareInstance].listenGroupArr removeObject:obj];
63 | *stop = YES;
64 | }
65 | }];
66 | }
67 |
68 |
69 | #pragma mark -
70 | #pragma mark - TuyaSmartGroupDelegate
71 | /// 群组dp数据更新
72 | - (void)group:(ThingSmartGroup *)group dpsUpdate:(NSDictionary *)dps {
73 | NSDictionary *dic = @{
74 | @"devId": group.groupModel.groupId,
75 | @"dps": dps,
76 | @"type": @"onDpUpdate"
77 | };
78 |
79 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterGroupInfoEvent stringByAppendingFormat:@"//%@", group.groupModel.groupId] withBody:dic];
80 | }
81 |
82 | /// 群组信息更新
83 | - (void)groupInfoUpdate:(ThingSmartGroup *)group {
84 |
85 | NSDictionary *dic = @{
86 | @"id": group.groupModel.groupId,
87 | @"type": @"onGroupInfoUpdate"
88 | };
89 |
90 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterGroupInfoEvent stringByAppendingFormat:@"//%@", group.groupModel.groupId] withBody:dic];
91 | }
92 |
93 | /// 群组移除
94 | - (void)groupRemove:(ThingSmartGroup *)group {
95 | NSDictionary *dic = @{
96 | @"id": group.groupModel.groupId,
97 | @"type": @"onGroupRemoved"
98 | };
99 |
100 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterGroupInfoEvent stringByAppendingFormat:@"//%@", group.groupModel.groupId] withBody:dic];
101 | }
102 |
103 | ///// zigbee 设备加入到网关群组响应
104 | ///// 1:超过场景数上限 2:子设备超时 3:设置值超出范围 4:写文件错误 5:其他错误
105 | //- (void)group:(TuyaSmartGroup *)group addResponseCode:(NSArray *)responseCode {
106 | // NSDictionary *dic = @{
107 | // @"id": group.groupModel.groupId,
108 | // @"type": @"onGroupRemoved"
109 | // };
110 | // [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterGroupInfoEvent stringByAppendingFormat:@"//%@", group.groupModel.groupId] withBody:dic];
111 | //}
112 | //
113 | ///// zigbee 设备从网关群组移除响应
114 | ///// 1:超过场景数上限 2:子设备超时 3:设置值超出范围 4:写文件错误 5:其他错误
115 | //- (void)group:(TuyaSmartGroup *)group removeResponseCode:(NSArray *)responseCode {
116 | // NSDictionary *dic = @{
117 | // @"id": group.groupModel.groupId,
118 | // @"type": @"onGroupRemoved"
119 | // };
120 | // [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterGroupInfoEvent stringByAppendingFormat:@"//%@", group.groupModel.groupId] withBody:dic];
121 | //}
122 |
123 |
124 | @end
125 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/core/TuyaCoreModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.core
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import android.text.TextUtils
6 | import android.util.Log
7 | import com.alibaba.fastjson.JSON
8 | import com.alibaba.fastjson.JSONArray
9 | import com.facebook.react.bridge.*
10 | import com.thingclips.smart.home.sdk.ThingHomeSdk
11 | import com.thingclips.smart.sdk.api.INeedLoginListener
12 | import com.thingclips.smart.sdk.api.IThingDataCallback
13 | import com.tuya.smart.rnsdk.utils.Constant.API_REQUEST_ERROR
14 | import com.tuya.smart.rnsdk.utils.Constant.NEEDLOGIN
15 | import com.tuya.smart.rnsdk.utils.TYRCTCommonUtil
16 | import com.tuya.smart.rnsdk.utils.TuyaReactUtils
17 | import java.util.HashMap
18 |
19 |
20 | class TuyaCoreModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
21 |
22 | companion object {
23 | fun initTuyaSDk(appKey:String,appSecret:String,application: Application){
24 | ThingHomeSdk.init(application, appKey, appSecret)
25 | }
26 |
27 | fun initTuyaSDKWithoutOptions(application: Application){
28 | ThingHomeSdk.init(application)
29 | }
30 |
31 | fun setSDKDebug(open:Boolean){
32 | ThingHomeSdk.setDebugMode(open)
33 | }
34 | }
35 |
36 | override fun getName(): String {
37 | return "TuyaCoreModule"
38 | }
39 |
40 | /**
41 | * 不带参数的初始化,appKey和appSecret要写在AndroidManifest中
42 | */
43 | @ReactMethod
44 | @Deprecated("Android can't initSDK in react-native,it should be used in application")
45 | fun initWithoutOptions() {
46 | ThingHomeSdk.init(reactApplicationContext.applicationContext as Application?);
47 | ThingHomeSdk.setOnNeedLoginListener {
48 | TuyaReactUtils.sendEvent(reactApplicationContext, NEEDLOGIN, null)
49 | }
50 | }
51 |
52 | @ReactMethod
53 | @Deprecated("Android can't initSDK in react-native,it should be used in application")
54 | fun initWithOptions(params: ReadableMap) {
55 | val appKey = params.getString("appKey")
56 | val appSecret = params.getString("appSecret")
57 | ThingHomeSdk.init(reactApplicationContext.applicationContext as Application?, appKey, appSecret)
58 | ThingHomeSdk.setOnNeedLoginListener(INeedLoginListener() {
59 | fun onNeedLogin(context: Context?) {
60 | TuyaReactUtils.sendEvent(reactApplicationContext, NEEDLOGIN, null)
61 | }
62 | })
63 | }
64 |
65 | @ReactMethod
66 | fun setOnNeedLoginListener(){
67 | ThingHomeSdk.setOnNeedLoginListener(INeedLoginListener() {
68 | fun onNeedLogin(context: Context?) {
69 | TuyaReactUtils.sendEvent(reactApplicationContext, NEEDLOGIN, null)
70 | }
71 | })
72 | }
73 |
74 |
75 |
76 | @ReactMethod
77 | fun exitApp() {
78 | ThingHomeSdk.onDestroy();
79 | }
80 |
81 | @ReactMethod
82 | fun apiRequest(params: ReadableMap, promise: Promise) {
83 | val callback = object : IThingDataCallback {
84 | override fun onSuccess(data: Any?) {
85 | if (data is Boolean) {
86 | Log.e("apiRequest", data.toString())
87 | promise.resolve("success")
88 | return
89 | }
90 |
91 | if(data is JSONArray){
92 | val writableArray = TYRCTCommonUtil.parseToWritableArray(data as com.alibaba.fastjson.JSONArray)
93 | promise.resolve(writableArray)
94 | return
95 | }
96 | val writableMap = TYRCTCommonUtil.parseToWritableMap(data)
97 | promise.resolve(writableMap)
98 |
99 | }
100 |
101 | override fun onError(errorCode: String?, errorMsg: String?) {
102 | promise.reject(errorCode, errorMsg)
103 | }
104 |
105 | }
106 |
107 | // val withoutSession = params.getBoolean("withoutSession")
108 | val withoutSession = false
109 | val apiName = params.getString("apiName")
110 | val apiVersion = params.getString("version")
111 | val postData = TYRCTCommonUtil.parseToMap(params.getMap("postData"))
112 | if (TextUtils.isEmpty(apiName)) {
113 | promise.reject(API_REQUEST_ERROR, "ApiName is empty")
114 | return
115 | }
116 |
117 | if (withoutSession) {
118 | ThingHomeSdk.getRequestInstance().requestWithApiNameWithoutSession(apiName, apiVersion, postData, Any::class.java, callback)
119 | } else {
120 | ThingHomeSdk.getRequestInstance().requestWithApiName(apiName, apiVersion, postData, Any::class.java,callback)
121 | }
122 |
123 | }
124 |
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/feedback/TuyaFeedBackModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.feedback
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.thingclips.smart.sdk.api.IThingDataCallback
6 | import com.thingclips.smart.sdk.bean.feedback.FeedbackBean
7 | import com.thingclips.smart.sdk.bean.feedback.FeedbackMsgBean
8 | import com.thingclips.smart.sdk.bean.feedback.FeedbackTypeRespBean
9 | import com.tuya.smart.rnsdk.utils.Constant
10 | import com.tuya.smart.rnsdk.utils.Constant.HDID
11 | import com.tuya.smart.rnsdk.utils.Constant.HDTYPE
12 | import com.tuya.smart.rnsdk.utils.JsonUtils
13 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
14 | import com.tuya.smart.rnsdk.utils.TuyaReactUtils
15 |
16 |
17 | class TuyaFeedBackModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
18 | override fun getName(): String {
19 | return "TuyaFeedBackModule"
20 | }
21 |
22 | /*获取反馈列表*/
23 | @ReactMethod
24 | fun getFeedbackList(promise: Promise) {
25 | ThingHomeSdk.getThingFeekback().getFeedbackManager().getFeedbackList(object : IThingDataCallback> {
26 | override fun onSuccess(var1: List) {
27 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(var1!!)))
28 | }
29 |
30 | override fun onError(var1: String, var2: String) {
31 | promise.reject(var1, var2)
32 | }
33 | })
34 | }
35 |
36 |
37 | /*获取反馈列表*/
38 | @ReactMethod
39 | fun getFeedbackType(promise: Promise) {
40 | ThingHomeSdk.getThingFeekback().getFeedbackManager().getFeedbackType(object : IThingDataCallback> {
41 | override fun onSuccess(var1: List) {
42 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(var1!!)))
43 | }
44 |
45 | override fun onError(var1: String, var2: String) {
46 | promise.reject(var1, var2)
47 | }
48 | })
49 | }
50 |
51 |
52 | /*添加反馈*/
53 | @ReactMethod
54 | fun addFeedback(params: ReadableMap, promise: Promise) {
55 | if (ReactParamsCheck.checkParams(arrayOf(Constant.MESEAGE, Constant.CONTACT, Constant.HDID, Constant.HDTYPE), params)) {
56 | ThingHomeSdk.getThingFeekback().getFeedbackManager().addFeedback(params.getString(Constant.MESEAGE), params.getString(Constant.CONTACT),
57 | params.getString(HDID), params.getInt(HDTYPE),
58 | object : IThingDataCallback {
59 | override fun onSuccess(var1: FeedbackMsgBean) {
60 | promise.resolve(TuyaReactUtils.parseToWritableMap(var1!!))
61 | }
62 |
63 | override fun onError(var1: String, var2: String) {
64 | promise.reject(var1, var2)
65 | }
66 | })
67 | }
68 | }
69 |
70 |
71 | /*获取反馈消息列表*/
72 | @ReactMethod
73 | fun getFeedbackMsg(params: ReadableMap, promise: Promise) {
74 | if (ReactParamsCheck.checkParams(arrayOf(Constant.HDID, Constant.HDTYPE), params)) {
75 | ThingHomeSdk.getThingFeekback().getFeedbackMsg(params.getString(HDID), params.getInt(HDTYPE))
76 | .getMsgList(
77 | object : IThingDataCallback> {
78 | override fun onSuccess(var1: List) {
79 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(var1!!)))
80 | }
81 |
82 | override fun onError(var1: String, var2: String) {
83 | promise.reject(var1, var2)
84 | }
85 | })
86 | }
87 | }
88 |
89 |
90 | /*添加新反馈*/
91 | @ReactMethod
92 | fun addMsg(params: ReadableMap, promise: Promise) {
93 | if (ReactParamsCheck.checkParams(arrayOf(Constant.HDID, Constant.HDTYPE, Constant.MESEAGE, Constant.CONTACT), params)) {
94 | ThingHomeSdk.getThingFeekback().getFeedbackMsg(params.getString(HDID), params.getInt(HDTYPE))
95 | .addMsg(params.getString(Constant.MESEAGE), params.getString(Constant.CONTACT),
96 | object : IThingDataCallback {
97 | override fun onSuccess(var1: FeedbackMsgBean) {
98 | promise.resolve(TuyaReactUtils.parseToWritableMap(var1!!))
99 | }
100 |
101 | override fun onError(var1: String, var2: String) {
102 | promise.reject(var1, var2)
103 | }
104 | })
105 | }
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Home/TuyaRNHomeManagerModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeManagerModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNHomeManagerModule.h"
10 | #import
11 | #import
12 | #import
13 | #import "YYModel.h"
14 | #import "TuyaRNUtils.h"
15 | #import "TuyaRNHomeManagerListener.h"
16 | #import "TuyaRNHomeListener.h"
17 |
18 | #define kTuyaHomeManagerModuleName @"name"
19 | #define kTuyaHomeManagerModuleLon @"lon"
20 | #define kTuyaHomeManagerModuleLat @"lat"
21 | #define kTuyaHomeManagerModuleGeoName @"geoName"
22 | #define kTuyaHomeManagerModuleRooms @"rooms"
23 | #define kTuyaHomeManagerModuleHomeId @"homeId"
24 | #define kTuyaHomeManagerModuleAction @"action"
25 |
26 |
27 | @interface TuyaRNHomeManagerModule()
28 |
29 | @property (nonatomic, strong) ThingSmartHomeManager *homeManager;
30 | @property (nonatomic, strong) ThingSmartRequest *request;
31 |
32 | @end
33 |
34 | @implementation TuyaRNHomeManagerModule
35 |
36 | RCT_EXPORT_MODULE(TuyaHomeManagerModule)
37 |
38 | /**
39 | * 获取家庭列表
40 | *
41 | * @param listener
42 | */
43 | RCT_EXPORT_METHOD(queryHomeList:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
44 |
45 | [self.homeManager getHomeListWithSuccess:^(NSArray *homes) {
46 |
47 | if (homes.count == 0) {
48 | if (resolver) {
49 | resolver(@[]);
50 | }
51 | return;
52 | }
53 |
54 | NSMutableArray *list = [NSMutableArray array];
55 | for (ThingSmartHomeModel *homeModel in homes) {
56 | NSDictionary *dic = [homeModel yy_modelToJSONObject];
57 | NSMutableDictionary *homeDic = [NSMutableDictionary dictionaryWithDictionary:dic];
58 | [homeDic setObject:[NSNumber numberWithLongLong:homeModel.homeId] forKey:@"homeId"];
59 | [list addObject:homeDic];
60 | }
61 |
62 | if (resolver) {
63 | resolver(list);
64 | }
65 | } failure:^(NSError *error) {
66 |
67 | }];
68 | }
69 |
70 | /**
71 | * 创建家庭
72 | * @param name 家庭名称
73 | * @param lon 经度
74 | * @param lat 纬度
75 | * @param geoName 家庭地理位置名称
76 | * @param rooms 房间列表
77 | * @param callback
78 | */
79 | RCT_EXPORT_METHOD(createHome:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
80 |
81 | NSString *name = params[kTuyaHomeManagerModuleName];
82 | NSString *geoName = params[kTuyaHomeManagerModuleGeoName];
83 | NSNumber *lat = params[kTuyaHomeManagerModuleLat];
84 | NSNumber *lon = params[kTuyaHomeManagerModuleLon];
85 | NSArray *rooms = params[kTuyaHomeManagerModuleRooms];
86 |
87 | double latValue = lat.doubleValue;
88 | double lonValue = lon.doubleValue;
89 |
90 | [self.homeManager addHomeWithName:name geoName:geoName rooms:rooms latitude:latValue longitude:lonValue success:^(long long result) {
91 | [TuyaRNUtils resolverWithHandler:resolver];
92 | } failure:^(NSError *error) {
93 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
94 | }];
95 | }
96 |
97 | /**
98 | * 注册家庭信息的变更
99 | * 有:家庭的增加、删除、信息变更、分享列表的变更和服务器连接成功的监听
100 | *
101 | * @param listener
102 | */
103 | RCT_EXPORT_METHOD(registerTuyaHomeChangeListener:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
104 |
105 | NSNumber *homeIdNum = params[kTuyaHomeManagerModuleHomeId];
106 | if (!homeIdNum || homeIdNum.longLongValue <= 0) {
107 | return;
108 | }
109 | //开始监听家庭的情况
110 | [[TuyaRNHomeManagerListener sharedInstance] registerSmartHomeManager:[ThingSmartHomeManager new]];
111 | [[TuyaRNHomeListener shareInstance] registerHomeChangeWithSmartHome:[ThingSmartHome homeWithHomeId:homeIdNum.longLongValue]];
112 | }
113 |
114 | /**
115 | * 注销家庭信息的变更
116 | *
117 | * @param listener
118 | */
119 | RCT_EXPORT_METHOD(unregisterTuyaHomeChangeListener:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
120 |
121 | //结束家庭的监听情况
122 | [[TuyaRNHomeManagerListener sharedInstance] removeSmartHomeManager];
123 | [[TuyaRNHomeListener shareInstance] removeHomeChangeSmartHome];
124 |
125 | }
126 |
127 | RCT_EXPORT_METHOD(joinFamily:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
128 | NSNumber *homeIdNum = params[kTuyaHomeManagerModuleHomeId];
129 | NSString *action = params[kTuyaHomeManagerModuleAction];
130 | ThingSmartHome *newHome = [ThingSmartHome homeWithHomeId:homeIdNum.longLongValue];
131 |
132 | [newHome joinFamilyWithAccept:action.boolValue success:^(BOOL result) {
133 | [TuyaRNUtils resolverWithHandler:resolver];
134 | } failure:^(NSError *error) {
135 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
136 | }];
137 | }
138 |
139 | RCT_EXPORT_METHOD(onDestory:(NSDictionary *)params) {
140 |
141 | }
142 |
143 | #pragma mark -
144 | #pragma mark - init
145 | - (ThingSmartHomeManager *)homeManager {
146 | if (!_homeManager) {
147 | _homeManager = [[ThingSmartHomeManager alloc] init];
148 | }
149 | return _homeManager;
150 | }
151 |
152 | - (ThingSmartRequest *)request {
153 | if (!_request) {
154 | _request = [ThingSmartRequest new];
155 | }
156 | return _request;
157 | }
158 |
159 | @end
160 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Home/TuyaRNHomeMemberModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeMemberModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/1.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNHomeMemberModule.h"
10 | #import "TuyaRNUtils.h"
11 | #import "YYModel.h"
12 | #import
13 | #import
14 |
15 | #define kTuyaRNHomeMemberModuleHomeId @"homeId"
16 | #define kTuyaRNHomeMemberModuleCountryCode @"countryCode"
17 | #define kTuyaRNHomeMemberModuleUserAccount @"userAccount"
18 | #define kTuyaRNHomeMemberModuleName @"name"
19 | #define kTuyaRNHomeMemberModuleAdmin @"admin"
20 | #define kTuyaRNHomeMemberModuleMemberId @"memberId"
21 | //#define kTuyaRNHomeMemberModule
22 |
23 | @interface TuyaRNHomeMemberModule()
24 |
25 | @property (nonatomic, strong) ThingSmartHomeMember *homeMember;
26 | @property (nonatomic, strong) ThingSmartHome *smartHome;
27 |
28 | @end
29 |
30 | @implementation TuyaRNHomeMemberModule
31 |
32 | RCT_EXPORT_MODULE(TuyaHomeMemberModule)
33 |
34 | /**
35 | * 给这个Home下面添加成员
36 | *
37 | * @param countryCode 国家码
38 | * @param userAccount 用户名
39 | * @param name 昵称
40 | * @param admin 是否拥有管理员权限
41 | * @param callback
42 | */
43 |
44 | RCT_EXPORT_METHOD(addMember:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
45 |
46 | ThingSmartHome *smartHome = [self smartHomeWithParams:params];
47 |
48 | ThingSmartHomeAddMemberRequestModel *requestModel = [[ThingSmartHomeAddMemberRequestModel alloc] init];
49 |
50 | NSString *name = params[kTuyaRNHomeMemberModuleName];
51 | NSString *userAccount = params[kTuyaRNHomeMemberModuleUserAccount];
52 | NSString *countryCode = params[kTuyaRNHomeMemberModuleCountryCode];
53 | NSString *admin = params[kTuyaRNHomeMemberModuleAdmin];
54 |
55 | requestModel.name = name;
56 | requestModel.account = userAccount;
57 | requestModel.countryCode = countryCode;
58 | requestModel.autoAccept = NO;
59 | requestModel.role = admin.boolValue ? ThingHomeRoleType_Admin : ThingHomeRoleType_Member;
60 |
61 | [smartHome addHomeMemberWithAddMemeberRequestModel:requestModel success:^(NSDictionary *dict) {
62 | if (resolver) {
63 | resolver(dict);
64 | }
65 | } failure:^(NSError *error) {
66 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
67 | }];
68 | }
69 |
70 | /**
71 | * 移除Home下面的成员
72 | *
73 | * @param id
74 | * @param callback
75 | */
76 | RCT_EXPORT_METHOD(removeMember:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
77 |
78 | NSNumber *memberId = params[kTuyaRNHomeMemberModuleMemberId];
79 | [self.homeMember removeHomeMemberWithMemberId:memberId.longLongValue success:^{
80 | [TuyaRNUtils resolverWithHandler:resolver];
81 | } failure:^(NSError *error) {
82 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
83 | }];
84 | }
85 |
86 | /**
87 | * 更新成员备注名和权限
88 | * @param name 备注名 如果不更改备注名,传入从memberBean获取的nickName
89 | * @param admin 是否是管理员
90 | * @param callback
91 | */
92 | RCT_EXPORT_METHOD(updateMember:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
93 |
94 | NSNumber *memberId = params[kTuyaRNHomeMemberModuleMemberId];
95 | NSString *admin = params[kTuyaRNHomeMemberModuleAdmin];
96 |
97 | ThingSmartHomeMemberRequestModel *requestModel = [[ThingSmartHomeMemberRequestModel alloc] init];
98 | requestModel.memberId = memberId.longLongValue;
99 | requestModel.name = params[kTuyaRNHomeMemberModuleName];
100 | requestModel.role = admin.boolValue ? ThingHomeRoleType_Admin : ThingHomeRoleType_Member;
101 |
102 | [self.homeMember updateHomeMemberInfoWithMemberRequestModel:requestModel success:^{
103 | [TuyaRNUtils resolverWithHandler:resolver];
104 | } failure:^(NSError *error) {
105 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
106 | }];
107 | }
108 |
109 | /**
110 | * 查询Home下面的成员列表
111 | *
112 | */
113 | RCT_EXPORT_METHOD(queryMemberList:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
114 |
115 | self.smartHome = [self smartHomeWithParams:params];
116 | [self.smartHome getHomeMemberListWithSuccess:^(NSArray *memberList) {
117 | if (memberList.count == 0) {
118 | if (resolver) {
119 | resolver(@[]);
120 | }
121 | return;
122 | }
123 | NSMutableArray *memberDicList = [NSMutableArray array];
124 | for (ThingSmartHomeMemberModel *memberModel in memberList) {
125 | NSDictionary *dic = [memberModel yy_modelToJSONObject];
126 | if (dic) {
127 | [memberDicList addObject:dic];
128 | }
129 | }
130 | if (resolver) {
131 | resolver(memberDicList);
132 | }
133 | } failure:^(NSError *error) {
134 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
135 | }];
136 |
137 | }
138 |
139 | #pragma mark -
140 | #pragma mark - init
141 | - (ThingSmartHome *)smartHomeWithParams:(NSDictionary *)params {
142 | long long homeId = ((NSNumber *)params[kTuyaRNHomeMemberModuleHomeId]).longLongValue;
143 | return [ThingSmartHome homeWithHomeId:homeId];
144 | }
145 |
146 | - (ThingSmartHomeMember *)homeMember {
147 | if (!_homeMember) {
148 | _homeMember = [[ThingSmartHomeMember alloc] init];
149 | }
150 | return _homeMember;
151 | }
152 |
153 | @end
154 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Activator/TuyaRNActivatorModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNActivatorModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNActivatorModule.h"
10 | #import
11 | #import
12 | #import
13 | #import "TuyaRNUtils+Network.h"
14 | #import "YYModel.h"
15 |
16 | #define kTuyaRNActivatorModuleHomeId @"homeId"
17 | #define kTuyaRNActivatorModuleSSID @"ssid"
18 | #define kTuyaRNActivatorModulePassword @"password"
19 | #define kTuyaRNActivatorModuleActivatorMode @"type"
20 | #define kTuyaRNActivatorModuleOverTime @"time"
21 | #define kTuyaRNActivatorModuleAcccessToken @"token"
22 | #define kTuyaRNActivatorModuleDeviceId @"devId"
23 |
24 | static TuyaRNActivatorModule * activatorInstance = nil;
25 |
26 | @interface TuyaRNActivatorModule()
27 |
28 | @property(copy, nonatomic) RCTPromiseResolveBlock promiseResolveBlock;
29 | @property(copy, nonatomic) RCTPromiseRejectBlock promiseRejectBlock;
30 |
31 | @end
32 |
33 | @implementation TuyaRNActivatorModule
34 |
35 | RCT_EXPORT_MODULE(TuyaActivatorModule)
36 |
37 | /** 开始配网
38 | * @param homeId 当前用户的homeId
39 | * @param ssid 配网之后,设备工作WiFi的名称。(家庭网络)
40 | * @param password 配网之后,设备工作WiFi的密码。(家庭网络)
41 | * @param activatorModel: 现在给设备配网有以下两种方式:
42 | ActivatorModelEnum.TY_EZ: 传入该参数则进行EZ配网
43 | ActivatorModelEnum.TY_AP: 传入该参数则进行AP配网
44 | * @param timeout 配网的超时时间设置,默认是100s.
45 | */
46 | RCT_EXPORT_METHOD(initActivator:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
47 |
48 | NSNumber *homeId = params[kTuyaRNActivatorModuleHomeId];
49 | NSString *ssid = params[kTuyaRNActivatorModuleSSID];
50 | NSString *password = params[kTuyaRNActivatorModulePassword];
51 | NSNumber *time = params[kTuyaRNActivatorModuleOverTime];
52 | NSString *type = params[kTuyaRNActivatorModuleActivatorMode];
53 | // NSString *token = params[kTuyaRNActivatorModuleActivatorToken];
54 |
55 | ThingActivatorMode mode = ThingActivatorModeEZ;
56 |
57 | if ([type isEqualToString:@"THING_AP"]) {
58 | mode = ThingActivatorModeAP;
59 | } else if([type isEqualToString:@"THING_EZ"]) {
60 | mode = ThingActivatorModeEZ;
61 | } else if([type isEqualToString:@"THING_4G_GATEWAY"]) {
62 | mode = ThingActivatorModeAP4GGateway;
63 | } else if([type isEqualToString:@"THING_QR"]) {
64 | mode = ThingActivatorModeQRCode;
65 | }
66 |
67 | if (activatorInstance == nil) {
68 | activatorInstance = [TuyaRNActivatorModule new];
69 | }
70 |
71 | [ThingSmartActivator sharedInstance].delegate = activatorInstance;
72 | activatorInstance.promiseResolveBlock = resolver;
73 | activatorInstance.promiseRejectBlock = rejecter;
74 |
75 | [[ThingSmartActivator sharedInstance] getTokenWithHomeId:homeId.longLongValue success:^(NSString *result) {
76 | //开始配置网络:
77 | [[ThingSmartActivator sharedInstance] startConfigWiFi:mode ssid:ssid password:password token:result timeout:time.doubleValue];
78 | } failure:^(NSError *error) {
79 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
80 | }];
81 | }
82 |
83 |
84 | RCT_EXPORT_METHOD(stopConfig:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
85 |
86 | [[ThingSmartActivator sharedInstance] stopConfigWiFi];
87 | }
88 |
89 | //ZigBee子设备配网需要ZigBee网关设备云在线的情况下才能发起,且子设备处于配网状态。
90 |
91 | RCT_EXPORT_METHOD(newGwSubDevActivator:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
92 |
93 | NSString *deviceId = params[kTuyaRNActivatorModuleDeviceId];
94 | NSNumber *time = params[kTuyaRNActivatorModuleOverTime];
95 |
96 | if (activatorInstance == nil) {
97 | activatorInstance = [TuyaRNActivatorModule new];
98 | }
99 |
100 | [ThingSmartActivator sharedInstance].delegate = activatorInstance;
101 | activatorInstance.promiseResolveBlock = resolver;
102 | activatorInstance.promiseRejectBlock = rejecter;
103 |
104 | [[ThingSmartActivator sharedInstance] activeSubDeviceWithGwId:deviceId timeout:time.doubleValue];
105 |
106 | }
107 |
108 | RCT_EXPORT_METHOD(stopNewGwSubDevActivatorConfig:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
109 |
110 | NSString *deviceId = params[kTuyaRNActivatorModuleDeviceId];
111 | [[ThingSmartActivator sharedInstance] stopActiveSubDeviceWithGwId:deviceId];
112 | }
113 |
114 | /**
115 | 获取wifi信息
116 | */
117 | RCT_EXPORT_METHOD(getCurrentWifi:(NSDictionary *)params success:(RCTResponseSenderBlock)succ failure:(RCTResponseErrorBlock)fail) {
118 | NSString *ssid = [ThingSmartActivator currentWifiSSID];
119 | if ([ssid isKindOfClass:[NSString class]] && ssid.length > 0) {
120 | succ(@[ssid]);
121 | } else {
122 | fail(nil);
123 | }
124 | }
125 |
126 |
127 | //判断网络
128 | RCT_EXPORT_METHOD(openNetworkSettings:(NSDictionary *)params resolver :(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
129 |
130 | [TuyaRNUtils openNetworkSettings];
131 |
132 | }
133 |
134 | RCT_EXPORT_METHOD(onDestory:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
135 |
136 | }
137 |
138 |
139 | #pragma mark -
140 | #pragma mark - delegate
141 | /// 配网状态更新的回调,wifi单品,zigbee网关,zigbee子设备
142 | - (void)activator:(ThingSmartActivator *)activator didReceiveDevice:(ThingSmartDeviceModel *)deviceModel error:(NSError *)error {
143 |
144 | if (error) {
145 | if (activatorInstance.promiseRejectBlock) {
146 | [TuyaRNUtils rejecterWithError:error handler:activatorInstance.promiseRejectBlock];
147 | }
148 | return;
149 | }
150 |
151 | //开始回调
152 | if (activatorInstance.promiseResolveBlock) {
153 | self.promiseResolveBlock([deviceModel yy_modelToJSONObject]);
154 | }
155 | }
156 |
157 | @end
158 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @owowagency/react-native-tuya
2 |
3 | This is a fork of [TuyaInc/tuyasmart-home-sdk-react-native](https://github.com/TuyaInc/tuyasmart-home-sdk-react-native), fixing a lot of issues we came across and a better install guide. It also uses TypeScript. We use it currently in multiple projects for clients and it is stable.
4 |
5 | Some features are not implemented, feel free to send a PR for those missing features. Unfortunately there is no demo yet
6 |
7 | ## Feature Overview
8 |
9 | Tuya Smart APP SDK provides the interface package for the communication with hardware and Tuya Cloud to accelerate the application development process, including the following features:
10 |
11 | Hardware functions (network configuration, control, status reporting, regular tasks, groups, firmware upgrades, sharing)
12 | Account system (phone number, email registration, login, password reset and other general account functions)
13 | Tuya Cloud HTTP API interface package
14 |
15 | ## Getting started
16 |
17 | ```
18 | npm install @owowagency/react-native-tuya
19 | ```
20 |
21 | This library contains native code which is automatically linked in React Native >= 0.59. For iOS, run `cd ios && pod install`.
22 |
23 | ## Installation
24 |
25 | In the Tuya development environment create a new app and make sure you have an "App key", "App secret" [Read how to do this](https://tuyainc.github.io/tuyasmart_home_ios_sdk_doc/en/resource/Preparation.html).
26 |
27 | ### iOS
28 |
29 | Download the security dependency and add it to the project as [explained here](https://developer.tuya.com/en/docs/app-development/integrate-sdk?id=Ka5d52ewngdoi#title-1-Integrate%20with%20the%20SDK).
30 |
31 | In `ios/AppDelegate.m`, add the following import;
32 |
33 | ```obj-c
34 | #import
35 | ```
36 |
37 | Then, under the `roootView.backgroundColor` line in the same file, add this:
38 |
39 | ```obj-c
40 | #ifdef DEBUG
41 | [[ThingSmartSDK sharedInstance] setDebugMode:YES];
42 | #endif
43 |
44 | [[ThingSmartSDK sharedInstance] startWithAppKey:@"xxx" secretKey:@"xxx"];
45 | ```
46 |
47 | Now replace the `xxx` with your app key and secret key.
48 |
49 | ### Android
50 |
51 | Assuming you already have created an app in the Tuya development environment (otherwise follow the iOS steps before this), follow [these steps](https://developer.tuya.com/en/docs/app-development/integrated?id=Ka69nt96cw0uj#title-5-Step%203%3A%20Integrate%20with%20security%20component). You should now have an app key, app secret and security dependency for Android
52 |
53 | Open your `AndroidManifest.xml` and put the following **in the `` tag**:
54 |
55 | ```xml
56 |
59 |
62 | ```
63 |
64 | Replace the `xxx` with your app key and secret key.
65 |
66 | Now open `MainApplication.java` and add the following import to the top:
67 |
68 | ```java
69 | import com.tuya.smart.rnsdk.core.TuyaCoreModule;
70 | ```
71 |
72 | Change the `onCreate` function to look like this:
73 |
74 | ```java
75 | @Override
76 | public void onCreate() {
77 | super.onCreate();
78 | SoLoader.init(this, /* native exopackage */ false);
79 | initializeFlipper(this); // Remove this line if you don't want Flipper enabled
80 | TuyaCoreModule.Companion.initTuyaSDKWithoutOptions(this);
81 | }
82 | ```
83 |
84 | Now you can try to build, but you'll probably run into an error saying that it can't choose between `libc++_shared` or something. One fix for this (don't know if it's the best fix) is to open `android/app/build.gradle` and add this;
85 |
86 | ```
87 | android {
88 | ...
89 | packagingOptions {
90 | pickFirst '**/armeabi-v7a/libc++_shared.so'
91 | pickFirst '**/x86/libc++_shared.so'
92 | pickFirst '**/arm64-v8a/libc++_shared.so'
93 | pickFirst '**/x86_64/libc++_shared.so'
94 | pickFirst '**/x86/libjsc.so'
95 | pickFirst '**/armeabi-v7a/libjsc.so'
96 | }
97 | }
98 | ```
99 |
100 | ## Usage
101 |
102 | Now you can actually use the methods in this package. Unfortunately I don't have time to document them all, so it is advised to read the source code, but here's a start.
103 |
104 | To login with an existing account:
105 |
106 | ```js
107 | import { loginWithEmail } from '@owowagency/react-native-tuya';
108 |
109 | await loginWithEmail({
110 | countryCode: '+1',
111 | email: 'you@example.com',
112 | password: 'testtest'
113 | });
114 | ```
115 |
116 | To register a new account you first need to validate the email address. And then actually register using the code in the email.
117 |
118 | ```js
119 | import { getRegisterEmailValidateCode, registerAccountWithEmail } from '@owowagency/react-native-tuya';
120 |
121 | await getRegisterEmailValidateCode({
122 | countryCode: '+1',
123 | email: 'you@example.com'
124 | });
125 |
126 | ...
127 |
128 | await registerAccountWithEmail({
129 | countryCode: '+1',
130 | email: 'you@example.com',
131 | password: 'testtest',
132 | validateCode: 'xxxxxx'
133 | })
134 | ```
135 |
136 | To get the currently logged in user:
137 |
138 | ```js
139 | import { getCurrentUser } from '@owowagency/react-native-tuya';
140 |
141 | const user = await getCurrentUser();
142 | ```
143 |
144 | ## Local Development
145 |
146 | ### `yarn start`
147 |
148 | Runs the project in development/watch mode. Your project will be rebuilt upon changes. TSDX has a special logger for you convenience. Error messages are pretty printed and formatted for compatibility VS Code's Problems tab.
149 |
150 |
151 |
152 | Your library will be rebuilt if you make edits.
153 |
154 | ### `yarn build`
155 |
156 | Bundles the package to the `dist` folder.
157 | The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module).
158 |
159 |
160 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/home/TuyaHomeManagerModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.home
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.thingclips.smart.home.sdk.api.IThingHomeChangeListener
6 | import com.thingclips.smart.home.sdk.bean.HomeBean
7 | import com.thingclips.smart.home.sdk.callback.IThingGetHomeListCallback
8 | import com.thingclips.smart.home.sdk.callback.IThingHomeResultCallback
9 | import com.thingclips.smart.sdk.bean.DeviceBean
10 | import com.thingclips.smart.sdk.bean.GroupBean
11 | import com.tuya.smart.rnsdk.utils.*
12 |
13 | class TuyaHomeManagerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
14 | override fun getName(): String {
15 | return "TuyaHomeManagerModule"
16 | }
17 |
18 |
19 | /* 获取家庭列表 */
20 | @ReactMethod
21 | fun queryHomeList(promise: Promise) {
22 | ThingHomeSdk.getHomeManagerInstance().queryHomeList(object : IThingGetHomeListCallback {
23 | override fun onSuccess(var1: List) {
24 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(var1!!)))
25 | }
26 |
27 | override fun onError(var1: String, var2: String) {
28 | promise.reject(var1, var2)
29 | }
30 | })
31 | }
32 |
33 | /* 创建家庭 */
34 | @ReactMethod
35 | fun createHome(params: ReadableMap, promise: Promise) {
36 | if (ReactParamsCheck.checkParams(arrayOf(Constant.NAME, Constant.LON, Constant.LAT, Constant.GEONAME, Constant.ROMMS), params)) {
37 | var list = ArrayList()
38 | var length = (params.getArray(Constant.ROMMS) as ReadableArray).size()
39 | for (index in 0 until length) {
40 | list.add((params.getArray(Constant.ROMMS) as ReadableArray).getString(index) as String)
41 | }
42 | ThingHomeSdk.getHomeManagerInstance().createHome(
43 | params.getString(Constant.NAME),
44 | params.getDouble(Constant.LON),
45 | params.getDouble(Constant.LAT),
46 | params.getString(Constant.GEONAME),
47 | list,
48 | getITuyaHomeResultCallback(promise)
49 | )
50 |
51 | }
52 | }
53 |
54 |
55 | @ReactMethod
56 | fun joinFamily(params: ReadableMap, promise: Promise) {
57 | if (ReactParamsCheck.checkParams(arrayOf(Constant.HOMEID, Constant.ACTION), params)) {
58 | ThingHomeSdk.getMemberInstance().processInvitation(
59 | params.getDouble(Constant.HOMEID).toLong(),
60 | params.getBoolean(Constant.ACTION),
61 | Constant.getIResultCallback(promise)
62 | )
63 |
64 | }
65 | }
66 |
67 |
68 | /* 注册家庭信息的变更
69 | * 有:家庭的增加、删除、信息变更、分享列表的变更和服务器连接成功的监听 */
70 | @ReactMethod
71 | fun registerTuyaHomeChangeListener(params: ReadableMap) {
72 | ThingHomeSdk.getHomeManagerInstance().registerThingHomeChangeListener(object : IThingHomeChangeListener {
73 | override fun onHomeInvite(p0: Long, p1: String?) {
74 | val map = Arguments.createMap()
75 | map.putDouble("homeId", p0.toDouble())
76 | map.putString("homeName", p1)
77 | BridgeUtils.homeChange(reactApplicationContext, map, params.getDouble("homeId"))
78 | }
79 |
80 | override fun onHomeAdded(var1: Long) {
81 | val map = Arguments.createMap()
82 | map.putDouble("homeId", var1.toDouble())
83 | map.putString("type", "onHomeAdded");
84 | BridgeUtils.homeChange(reactApplicationContext, map, params.getDouble("homeId"))
85 | }
86 |
87 | override fun onHomeRemoved(var1: Long) {
88 | val map = Arguments.createMap()
89 | map.putDouble("homeId", var1.toDouble())
90 | map.putString("type", "onHomeRemoved");
91 | BridgeUtils.homeChange(reactApplicationContext, map, params.getDouble("homeId"))
92 | }
93 |
94 | override fun onHomeInfoChanged(var1: Long) {
95 | val map = Arguments.createMap()
96 | map.putDouble("homeId", var1.toDouble())
97 | map.putString("type", "onHomeInfoChanged");
98 | BridgeUtils.homeChange(reactApplicationContext, map, params.getDouble("homeId"))
99 | }
100 |
101 | override fun onSharedDeviceList(var1: List) {
102 | val map = Arguments.createMap()
103 | map.putArray("deviceBeans", TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(var1)))
104 | map.putString("type", "onSharedDeviceList");
105 | BridgeUtils.homeChange(reactApplicationContext, map, params.getDouble("homeId"))
106 | }
107 |
108 | override fun onSharedGroupList(var1: List) {
109 | val map = Arguments.createMap()
110 | map.putArray("groupBeans", TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(var1)))
111 | map.putString("type", "onSharedGroupList");
112 | BridgeUtils.homeChange(reactApplicationContext, map, params.getDouble("homeId"))
113 | }
114 |
115 | override fun onServerConnectSuccess() {
116 | val map = Arguments.createMap()
117 | map.putString("type", "onServerConnectSuccess");
118 | BridgeUtils.homeChange(reactApplicationContext, map, params.getDouble("homeId"))
119 | }
120 | })
121 | }
122 |
123 |
124 | fun getITuyaHomeResultCallback(promise: Promise): IThingHomeResultCallback? {
125 | return object : IThingHomeResultCallback {
126 | override fun onSuccess(p0: HomeBean?) {
127 | promise.resolve(TuyaReactUtils.parseToWritableMap(p0))
128 | }
129 |
130 | override fun onError(code: String?, error: String?) {
131 | promise.reject(code, error)
132 | }
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Core/TuyaRNCoreModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaCoreApi.m
3 | // TuyaSdkTest
4 | //
5 | // Created by 浩天 on 2019/2/27.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNCoreModule.h"
10 | #import
11 | #import
12 | #import
13 | #import
14 | #import "TuyaRNUtils+Network.h"
15 |
16 | #define kTuyaCoreModuleAppkey @""
17 | #define kTuyaCoreModuleAppSecret @""
18 | #define kTuyaCoreModuleParamLat @"lat"
19 | #define kTuyaCoreModuleParamLon @"lon"
20 |
21 | #define kTuyaCoreModuleUserDefaultLocation_lat @"ty_rn_lat"
22 | #define kTuyaCoreModuleUserDefaultLocation_lon @"ty_rn_lon"
23 |
24 | @interface TuyaRNCoreModule()
25 |
26 | @property (nonatomic, strong) CLLocationManager *locationManager;
27 |
28 | @end
29 |
30 |
31 | @implementation TuyaRNCoreModule
32 |
33 | RCT_EXPORT_MODULE(TuyaCoreModule)
34 |
35 | RCT_EXPORT_METHOD(initWithOptions:(NSDictionary *)params) {
36 |
37 | NSString *appKey = params[kTuyaCoreModuleAppkey];
38 | NSString *appSecret = params[kTuyaCoreModuleAppSecret];
39 |
40 | dispatch_async(dispatch_get_main_queue(), ^{
41 | // [[TuyaSmartSDK sharedInstance] startWithAppKey:appKey secretKey:appSecret];
42 | //#ifdef DEBUG
43 | // [TuyaSmartSDK sharedInstance].debugMode = YES;
44 | //#endif
45 |
46 | if (!self.locationManager) {
47 | self.locationManager = [CLLocationManager new];
48 | self.locationManager.delegate = self;
49 | }
50 | if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) {
51 | [self.locationManager startUpdatingLocation];
52 | } else {
53 | if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
54 | [self.locationManager requestWhenInUseAuthorization];
55 | }
56 | }
57 | });
58 | }
59 |
60 | //通用api
61 | RCT_REMAP_METHOD(apiRequest,
62 | postData:(NSDictionary *)parameters
63 | resolver:(RCTPromiseResolveBlock)resolver
64 | rejecter:(RCTPromiseRejectBlock)rejecter) {
65 |
66 | NSString *apiName = [parameters objectForKey:@"apiName"];
67 | NSDictionary *postData = [parameters objectForKey:@"postData"];
68 | NSString *version = [parameters objectForKey:@"version"];
69 |
70 | ThingSmartRequest *request = [ThingSmartRequest new];
71 |
72 | [request requestWithApiName:apiName postData:postData version:version success:^(id result) {
73 | if ([result isKindOfClass:[NSDictionary class]] || [result isKindOfClass:[NSArray class]]) {
74 | if (resolver) {
75 | resolver([result thingsdk_JSONString]);
76 | }
77 | } else {
78 | if (resolver) {
79 | resolver([result description]);
80 | }
81 | }
82 | } failure:^(NSError *error) {
83 | if (rejecter) {
84 | rejecter([NSString stringWithFormat:@"%ld", error.code], error.userInfo[NSLocalizedDescriptionKey], error);
85 | }
86 | }];
87 | }
88 |
89 | //判断网络
90 | RCT_EXPORT_METHOD(openNetworkSettings:(NSDictionary *)params) {
91 |
92 | [TuyaRNUtils openNetworkSettings];
93 |
94 | }
95 |
96 | RCT_EXPORT_METHOD(exitApp:(NSDictionary *)params) {
97 |
98 | }
99 |
100 | RCT_EXPORT_METHOD(onDestory:(NSDictionary *)params) {
101 |
102 | }
103 |
104 | RCT_EXPORT_METHOD(setLocation:(NSDictionary *)params) {
105 | NSString *lat = params[kTuyaCoreModuleParamLat];
106 | NSString *lon = params[kTuyaCoreModuleParamLon];
107 | if ([lat isKindOfClass:[NSString class]] && lat.length > 0
108 | && [lon isKindOfClass:[NSString class]] && lon.length > 0) {
109 | [[ThingSmartSDK sharedInstance] setValue:lat forKey:@"latitude"];
110 | [[ThingSmartSDK sharedInstance] setValue:lon forKey:@"longitude"];
111 | [self.locationManager stopUpdatingLocation];
112 | }
113 | }
114 |
115 | RCT_EXPORT_METHOD(getLocationData:(RCTPromiseResolveBlock)resolver
116 | rejecter:(RCTPromiseRejectBlock)rejecter) {
117 | // BOOL gpsAvaliable = [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways;
118 | //
119 | NSString *lat = [[NSUserDefaults standardUserDefaults] objectForKey:kTuyaCoreModuleUserDefaultLocation_lat];
120 | NSString *lon = [[NSUserDefaults standardUserDefaults] objectForKey:kTuyaCoreModuleUserDefaultLocation_lon];
121 |
122 | if (lat.length == 0) {
123 | lat = @"";
124 | }
125 | if (lon.length == 0) {
126 | lon = @"";
127 | }
128 |
129 | if (resolver) {
130 | resolver(@{
131 | kTuyaCoreModuleParamLat: [lat isKindOfClass:[NSString class]] ? lat : @"",
132 | kTuyaCoreModuleParamLon: [lat isKindOfClass:[NSString class]] ? lon : @""
133 | });
134 | }
135 | }
136 |
137 |
138 | #pragma mark - delegate
139 | #pragma mark -
140 |
141 | - (void)locationManager:(CLLocationManager *)manager
142 | didUpdateLocations:(NSArray *)locations {
143 | if (!([locations isKindOfClass:[NSArray class]] && locations.count > 0)) {
144 | return;
145 | }
146 | CLLocation *location = locations[0];
147 |
148 | [self.locationManager stopUpdatingLocation];
149 |
150 | NSString *latitude = [NSString stringWithFormat:@"%f", location.coordinate.latitude];
151 | NSString *longitude = [NSString stringWithFormat:@"%f", location.coordinate.longitude];
152 |
153 | [[NSUserDefaults standardUserDefaults] setObject:latitude forKey:kTuyaCoreModuleParamLat];
154 | [[NSUserDefaults standardUserDefaults] setObject:longitude forKey:kTuyaCoreModuleParamLon];
155 | [[NSUserDefaults standardUserDefaults] synchronize];
156 | }
157 |
158 | - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
159 | if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) {
160 | [self.locationManager startUpdatingLocation];
161 | }
162 | }
163 |
164 | @end
165 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/home/TuyaHomeDataManagerModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.home
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.tuya.smart.rnsdk.utils.Constant.DEVID
6 | import com.tuya.smart.rnsdk.utils.Constant.GROUPID
7 | import com.tuya.smart.rnsdk.utils.Constant.HOMEID
8 | import com.tuya.smart.rnsdk.utils.Constant.MESHID
9 | import com.tuya.smart.rnsdk.utils.Constant.ROOMID
10 | import com.tuya.smart.rnsdk.utils.JsonUtils
11 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
12 | import com.tuya.smart.rnsdk.utils.TuyaReactUtils
13 |
14 |
15 | class TuyaHomeDataManagerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
16 | override fun getName(): String {
17 | return "TuyaHomeDataManagerModule"
18 | }
19 |
20 |
21 | /* 家庭下面的房间列表 */
22 | @ReactMethod
23 | fun getHomeRoomList(params: ReadableMap, promise: Promise) {
24 | promise.resolve(TuyaReactUtils.parseToWritableArray(
25 | JsonUtils.toJsonArray(ThingHomeSdk.getDataInstance().getHomeRoomList(params.getDouble(HOMEID).toLong()))))
26 | }
27 |
28 |
29 | /* 获取家庭下面的设备列表 */
30 | @ReactMethod
31 | fun getHomeDeviceList(params: ReadableMap, promise: Promise) {
32 | if (ReactParamsCheck.checkParams(arrayOf(HOMEID), params)) {
33 | promise.resolve(TuyaReactUtils.parseToWritableArray(
34 | JsonUtils.toJsonArray(ThingHomeSdk.getDataInstance().getHomeDeviceList(params.getDouble(HOMEID).toLong()))))
35 | }
36 | }
37 | /* 获取家庭下面的群组列表 */
38 | @ReactMethod
39 | fun getHomeGroupList(params: ReadableMap, promise: Promise) {
40 | if (ReactParamsCheck.checkParams(arrayOf(HOMEID), params)) {
41 | promise.resolve(TuyaReactUtils.parseToWritableArray(
42 | JsonUtils.toJsonArray(ThingHomeSdk.getDataInstance().getHomeGroupList(params.getDouble(HOMEID).toLong()))))
43 | }
44 | }
45 |
46 | /* 获取群组 */
47 | @ReactMethod
48 | fun getGroupBean(params: ReadableMap, promise: Promise) {
49 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID), params)) {
50 | promise.resolve(TuyaReactUtils.parseToWritableMap(ThingHomeSdk.getDataInstance().getGroupBean(params.getDouble(GROUPID).toLong())))
51 | }
52 | }
53 |
54 | /* 获取设备 */
55 | @ReactMethod
56 | fun getDeviceBean(params: ReadableMap, promise: Promise) {
57 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
58 | promise.resolve(TuyaReactUtils.parseToWritableMap(ThingHomeSdk.getDataInstance().getDeviceBean(params.getString(DEVID))))
59 | }
60 | }
61 |
62 | /* 获取设备 */
63 | @ReactMethod
64 | fun getGroupRoomBean(params: ReadableMap, promise: Promise) {
65 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID), params)) {
66 | promise.resolve(TuyaReactUtils.parseToWritableMap(ThingHomeSdk.getDataInstance().getGroupRoomBean(params.getDouble(GROUPID).toLong())))
67 | }
68 | }
69 |
70 | /* 获取房间 */
71 | @ReactMethod
72 | fun getRoomBean(params: ReadableMap, promise: Promise) {
73 | if (ReactParamsCheck.checkParams(arrayOf(ROOMID), params)) {
74 | promise.resolve(TuyaReactUtils.parseToWritableMap(ThingHomeSdk.getDataInstance().getRoomBean(params.getDouble(ROOMID).toLong())))
75 | }
76 | }
77 |
78 | /* 根据设备获取房间信息 */
79 | @ReactMethod
80 | fun getDeviceRoomBean(params: ReadableMap, promise: Promise) {
81 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
82 | promise.resolve(TuyaReactUtils.parseToWritableMap(ThingHomeSdk.getDataInstance().getDeviceRoomBean(params.getString(DEVID))))
83 | }
84 | }
85 |
86 | /* 获取群组下面的设备列表 */
87 | @ReactMethod
88 | fun getGroupDeviceList(params: ReadableMap, promise: Promise) {
89 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID), params)) {
90 | promise.resolve(TuyaReactUtils.parseToWritableArray(
91 | JsonUtils.toJsonArray(ThingHomeSdk.getDataInstance().getGroupDeviceList(params.getDouble(GROUPID).toLong()))))
92 | }
93 | }
94 |
95 | /* 获取mesh下面的群组列表 */
96 | @ReactMethod
97 | fun getMeshGroupList(params: ReadableMap, promise: Promise) {
98 | if (ReactParamsCheck.checkParams(arrayOf(MESHID), params)) {
99 | promise.resolve(TuyaReactUtils.parseToWritableArray(
100 | JsonUtils.toJsonArray(ThingHomeSdk.getDataInstance().getMeshGroupList(params.getString(MESHID)))))
101 | }
102 | }
103 |
104 | @ReactMethod
105 | fun getMeshDeviceList(params: ReadableMap, promise: Promise) {
106 | if (ReactParamsCheck.checkParams(arrayOf(MESHID), params)) {
107 | promise.resolve(TuyaReactUtils.parseToWritableArray(
108 | JsonUtils.toJsonArray(ThingHomeSdk.getDataInstance().getMeshDeviceList(params.getString(MESHID)))))
109 | }
110 | }
111 |
112 |
113 | /* 根据房间ID获取房间下面的设备列表 */
114 | @ReactMethod
115 | fun getRoomDeviceList(params: ReadableMap, promise: Promise) {
116 | if (ReactParamsCheck.checkParams(arrayOf(ROOMID), params)) {
117 | promise.resolve(TuyaReactUtils.parseToWritableArray(
118 | JsonUtils.toJsonArray(ThingHomeSdk.getDataInstance().getRoomDeviceList(params.getDouble(ROOMID).toLong()))))
119 | }
120 | }
121 |
122 |
123 | /* 根据房间ID获取房间下面的群组列表 */
124 | @ReactMethod
125 | fun getRoomGroupList(params: ReadableMap, promise: Promise) {
126 | if (ReactParamsCheck.checkParams(arrayOf(ROOMID), params)) {
127 | promise.resolve(TuyaReactUtils.parseToWritableArray(
128 | JsonUtils.toJsonArray(ThingHomeSdk.getDataInstance().getRoomGroupList(params.getDouble(ROOMID).toLong()))))
129 | }
130 | }
131 |
132 | /* 根据房间ID获取房间下面的群组列表 */
133 | @ReactMethod
134 | fun getHomeBean(params: ReadableMap, promise: Promise) {
135 | if (ReactParamsCheck.checkParams(arrayOf(HOMEID), params)) {
136 | promise.resolve(TuyaReactUtils.parseToWritableMap(ThingHomeSdk.getDataInstance().getHomeBean(params.getDouble(HOMEID).toLong())))
137 | }
138 | }
139 |
140 | }
141 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/group/TuyaGroupModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.group
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.thingclips.smart.home.sdk.api.IThingHome
6 | import com.thingclips.smart.home.sdk.callback.IThingResultCallback
7 | import com.thingclips.smart.sdk.api.IGroupListener
8 | import com.thingclips.smart.sdk.api.IThingGroup
9 | import com.thingclips.smart.sdk.bean.GroupDeviceBean
10 | import com.tuya.smart.rnsdk.utils.*
11 | import com.tuya.smart.rnsdk.utils.Constant.COMMAND
12 | import com.tuya.smart.rnsdk.utils.Constant.DEVIDS
13 | import com.tuya.smart.rnsdk.utils.Constant.GROUPID
14 | import com.tuya.smart.rnsdk.utils.Constant.HOMEID
15 | import com.tuya.smart.rnsdk.utils.Constant.NAME
16 | import com.tuya.smart.rnsdk.utils.Constant.PRODUCTID
17 | import com.tuya.smart.rnsdk.utils.Constant.getIResultCallback
18 |
19 |
20 |
21 |
22 | class TuyaGroupModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
23 | override fun getName(): String {
24 | return "TuyaGroupModule"
25 | }
26 |
27 | /*创建群组*/
28 | @ReactMethod
29 | fun createGroup(params: ReadableMap, promise: Promise) {
30 | if (ReactParamsCheck.checkParams(arrayOf(HOMEID, PRODUCTID, NAME, DEVIDS), params)) {
31 | getITuyaHome(params.getDouble(HOMEID).toLong()).createGroup(
32 | params.getString((PRODUCTID)),
33 | params.getString(NAME),
34 | JsonUtils.parserArraybyMap(params.getArray(DEVIDS) as ReadableArray,
35 | String::class.java) as MutableList?,
36 | object : IThingResultCallback {
37 | override fun onSuccess(p0: Long) {
38 | promise.resolve(p0)
39 | }
40 |
41 | override fun onError(p0: String?, p1: String?) {
42 | promise.reject(p0,p1)
43 | }
44 | }
45 | )
46 | }
47 | }
48 |
49 | /**onNetworkStatusChanged
50 | * 此接口主要是从云端拉取最新群组列表 根据产品ID
51 | */
52 | @ReactMethod
53 | fun queryDeviceListToAddGroup(params: ReadableMap, promise: Promise) {
54 | if (ReactParamsCheck.checkParams(arrayOf(HOMEID,PRODUCTID), params)) {
55 | getITuyaHome(params.getDouble(HOMEID).toLong()).queryDeviceListToAddGroup(params.getDouble(HOMEID).toLong(),params.getString(PRODUCTID),
56 | object : IThingResultCallback>{
57 | override fun onSuccess(bizResult: List) {
58 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(bizResult)))
59 | }
60 |
61 | override fun onError(errorCode: String, errorMsg: String) {
62 | promise.reject(errorCode,errorMsg)
63 | }
64 | })
65 | }
66 | }
67 |
68 | @ReactMethod
69 | fun dismissGroup(params: ReadableMap, promise: Promise) {
70 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID), params)) {
71 | getITuyaGroup(params.getDouble(GROUPID).toLong())
72 | ?.dismissGroup(getIResultCallback(promise)
73 | )
74 | }
75 | }
76 |
77 | @ReactMethod
78 | fun updateGroupName(params: ReadableMap, promise: Promise){
79 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID, NAME), params)) {
80 | getITuyaGroup(params.getDouble(GROUPID).toLong())
81 | ?.renameGroup( params.getString(NAME)
82 | ,getIResultCallback(promise)
83 | )
84 | }
85 | }
86 |
87 | @ReactMethod
88 | fun registerGroupListener(params: ReadableMap) {
89 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID), params)) {
90 | getITuyaGroup(params.getDouble(GROUPID).toLong())
91 | ?.registerGroupListener(object : IGroupListener {
92 | override fun onDpUpdate(var1: Long, var3: String){
93 | var map=Arguments.createMap();
94 | map.putDouble("id",var1.toDouble())
95 | map.putString("dps",var3)
96 | map.putString("type","onDpUpdate")
97 | BridgeUtils.groupListener(reactApplicationContext,map,params.getDouble(GROUPID).toLong())
98 | }
99 |
100 | override fun onDpCodeUpdate(groupId: Long, dpCodeMap: MutableMap?) {
101 | //
102 | }
103 |
104 | override fun onGroupInfoUpdate(var1: Long){
105 | var map=Arguments.createMap();
106 | map.putDouble("id",var1.toDouble())
107 | map.putString("type","onGroupInfoUpdate")
108 | BridgeUtils.groupListener(reactApplicationContext,map,params.getDouble(GROUPID).toLong())
109 | }
110 |
111 | override fun onGroupRemoved(var1: Long){
112 | var map=Arguments.createMap();
113 | map.putDouble("id",var1.toDouble())
114 | map.putString("type","onGroupRemoved")
115 | BridgeUtils.groupListener(reactApplicationContext,map,params.getDouble(GROUPID).toLong())
116 | }
117 | })
118 | }
119 | }
120 |
121 | @ReactMethod
122 | fun unregisterGroupListener(params: ReadableMap) {
123 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID), params)) {
124 | getITuyaGroup(params.getDouble(GROUPID).toLong())
125 | ?.unRegisterGroupListener()
126 | }
127 | }
128 | @ReactMethod
129 | fun publishDps(params: ReadableMap,promise: Promise){
130 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID,COMMAND), params)) {
131 | getITuyaGroup(params.getDouble(GROUPID).toLong())
132 | ?.publishDps(JsonUtils.toString(TuyaReactUtils.parseToMap(params.getMap(COMMAND) as ReadableMap)), getIResultCallback(promise))
133 | }
134 | }
135 |
136 | @ReactMethod
137 | fun onDestroy(params: ReadableMap){
138 | if (ReactParamsCheck.checkParams(arrayOf(GROUPID,COMMAND), params)) {
139 | getITuyaGroup(params.getDouble(GROUPID).toLong())
140 | ?.onDestroy()
141 | }
142 | }
143 |
144 | fun getITuyaHome(homeId: Long): IThingHome {
145 | return ThingHomeSdk.newHomeInstance(homeId)
146 | }
147 |
148 | fun getITuyaGroup(groupId: Long): IThingGroup {
149 | return ThingHomeSdk.newGroupInstance(groupId)
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/DeviceControl/TuyaRNDeviceModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNDeviceModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNDeviceModule.h"
10 | #import "TuyaRNDeviceListener.h"
11 | #import
12 | #import "TuyaRNUtils.h"
13 | #import "YYModel.h"
14 |
15 |
16 | #define kTuyaDeviceModuleDevId @"devId"
17 | #define kTuyaDeviceModuleCommand @"command"
18 | #define kTuyaDeviceModuleDpId @"dpId"
19 | #define kTuyaDeviceModuleDeviceName @"name"
20 |
21 | @interface TuyaRNDeviceModule()
22 |
23 | @property (strong, nonatomic) ThingSmartDevice *smartDevice;
24 |
25 | @end
26 |
27 | @implementation TuyaRNDeviceModule
28 |
29 | RCT_EXPORT_MODULE(TuyaDeviceModule)
30 |
31 | /**
32 | 设备监听开启
33 | */
34 | RCT_EXPORT_METHOD(registerDevListener:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
35 |
36 | self.smartDevice = [self smartDeviceWithParams:params];
37 | //监听设备
38 | [TuyaRNDeviceListener registerDevice:self.smartDevice type:TuyaRNDeviceListenType_DeviceInfo];
39 | }
40 |
41 | /**
42 | 设备监听删除
43 |
44 | */
45 | RCT_EXPORT_METHOD(unRegisterDevListener:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
46 | NSString *deviceId = params[kTuyaDeviceModuleDevId];
47 | if(deviceId.length == 0) {
48 | return;
49 | }
50 |
51 | ThingSmartDevice *device = [ThingSmartDevice deviceWithDeviceId:deviceId];
52 |
53 | // 移除监听设备
54 | [TuyaRNDeviceListener removeDevice:device type:TuyaRNDeviceListenType_DeviceInfo];
55 |
56 | self.smartDevice = [self smartDeviceWithParams:params];
57 | //取消设备监听
58 | [TuyaRNDeviceListener removeDevice:self.smartDevice type:TuyaRNDeviceListenType_DeviceInfo];
59 | }
60 |
61 |
62 | /*
63 | * 通过局域网或者云端这两种方式发送控制指令给设备。send(通过局域网或者云端这两种方式发送控制指令给设备。)
64 | command的格式应符合{key:value} 例如 {"1":true}
65 | */
66 | RCT_EXPORT_METHOD(send:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
67 | //设备发送消息
68 | self.smartDevice = [self smartDeviceWithParams:params];
69 | NSDictionary *command = params[kTuyaDeviceModuleCommand];
70 | [self.smartDevice publishDps:command success:^{
71 | [TuyaRNUtils resolverWithHandler:resolver];
72 | } failure:^(NSError *error) {
73 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
74 | }];
75 | }
76 |
77 | /**
78 | 查询单个dp数据
79 | */
80 | RCT_EXPORT_METHOD(getDp:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
81 |
82 | NSString *dpId = params[kTuyaDeviceModuleDpId];
83 | //读取dp点
84 | self.smartDevice = [self smartDeviceWithParams:params];
85 | if (self.smartDevice) {
86 | if (resolver) {
87 | resolver(self.smartDevice.deviceModel.dps[dpId]?:@"");
88 | }
89 | }
90 | }
91 |
92 |
93 | /**
94 | 设备重命名
95 | */
96 | RCT_EXPORT_METHOD(renameDevice:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
97 |
98 | self.smartDevice = [self smartDeviceWithParams:params];
99 | NSString *deviceName = params[kTuyaDeviceModuleDeviceName];
100 | [self.smartDevice updateName:deviceName success:^{
101 | [TuyaRNUtils resolverWithHandler:resolver];
102 | } failure:^(NSError *error) {
103 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
104 | }];
105 | }
106 |
107 | // 更新单个设备信息:
108 | //RCT_EXPORT_METHOD(getDp:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
109 | // TuyaSmartDevice *device = [TuyaSmartDevice deviceWithDeviceId:params[@"devId"]];
110 | // [device syncWithCloud:^{
111 | // if (resolver) {
112 | // resolver(@"syncWithCloud success");
113 | // }
114 | // } failure:^(NSError *error) {
115 | // [TuyaRNUtils rejecterWithError:error handler:rejecter];
116 | // }];
117 | //}
118 |
119 |
120 | RCT_EXPORT_METHOD(getDataPointStat:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
121 | self.smartDevice = [self smartDeviceWithParams:params];
122 | }
123 |
124 |
125 | /**
126 | 删除设备
127 | */
128 | RCT_EXPORT_METHOD(removeDevice:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
129 |
130 | self.smartDevice = [self smartDeviceWithParams:params];
131 | [self.smartDevice remove:^{
132 | [TuyaRNUtils resolverWithHandler:resolver];
133 | } failure:^(NSError *error) {
134 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
135 | }];
136 | }
137 |
138 | // 设备重命名:已验证
139 | //RCT_EXPORT_METHOD(renameDevice:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
140 | //
141 | // TuyaSmartDevice *device = [TuyaSmartDevice deviceWithDeviceId:params[@"devId"]];
142 | // [device updateName:params[@"name"] success:^{
143 | // if (resolver) {
144 | // resolver(@"rename success");
145 | // }
146 | // } failure:^(NSError *error) {
147 | // [TuyaRNUtils rejecterWithError:error handler:rejecter];
148 | // }];
149 | //}
150 |
151 |
152 | RCT_EXPORT_METHOD(onDestroy:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
153 |
154 | }
155 |
156 | // 下发升级指令:
157 | RCT_EXPORT_METHOD(startOta:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
158 | ThingSmartDevice *device = [ThingSmartDevice deviceWithDeviceId:params[@"devId"]];
159 | [device upgradeFirmware:[params[@"type"] integerValue] success:^{
160 | if (resolver) {
161 | resolver(@"success");
162 | }
163 | } failure:^(NSError *error) {
164 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
165 | }];
166 | }
167 |
168 | // 查询固件升级信息:
169 | RCT_EXPORT_METHOD(getOtaInfo:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
170 |
171 | ThingSmartDevice *device = [ThingSmartDevice deviceWithDeviceId:params[@"devId"]];
172 | [device getFirmwareUpgradeInfo:^(NSArray *upgradeModelList) {
173 |
174 | NSMutableArray *res = [NSMutableArray array];
175 | for (ThingSmartFirmwareUpgradeModel *item in upgradeModelList) {
176 | NSDictionary *dic = [item yy_modelToJSONObject];
177 | [res addObject:dic];
178 | }
179 | if (resolver) {
180 | resolver(res);
181 | }
182 |
183 | NSLog(@"getFirmwareUpgradeInfo success");
184 | } failure:^(NSError *error) {
185 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
186 | }];
187 |
188 | }
189 |
190 |
191 | #pragma mark -
192 | - (ThingSmartDevice *)smartDeviceWithParams:(NSDictionary *)params {
193 | NSString *deviceId = params[kTuyaDeviceModuleDevId];
194 | if(deviceId.length == 0) {
195 | return nil;
196 | }
197 | return [ThingSmartDevice deviceWithDeviceId:deviceId];
198 | }
199 |
200 |
201 | @end
202 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Timer/TuyaRNTimerModule.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNTimerModule.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/2/28.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNTimerModule.h"
10 | #import
11 | #import
12 | #import "TuyaRNUtils.h"
13 | #import
14 |
15 | @interface TuyaRNTimerModule()
16 | @property (nonatomic, strong) ThingSmartTimer *timer;
17 | @end
18 |
19 | @implementation TuyaRNTimerModule
20 |
21 | RCT_EXPORT_MODULE(TuyaTimerModule)
22 |
23 | RCT_EXPORT_METHOD(initWithOptions:(NSDictionary *)params) {
24 |
25 | }
26 |
27 | RCT_EXPORT_METHOD(onDestory:(NSDictionary *)params) {
28 |
29 | }
30 |
31 | // 增加定时器,带有自己定义dp点:
32 | RCT_EXPORT_METHOD(addTimerWithTask:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
33 | ThingSmartTimer *timer = [[ThingSmartTimer alloc] init];
34 | self.timer = timer;
35 |
36 | [timer addTimerWithTask:params[@"taskName"] loops:params[@"loops"] bizId:params[@"devId"] bizType:0 time:params[@"time"] dps:params[@"dps"] status:YES isAppPush:NO aliasName:@"" success:^{
37 | if (resolver) {
38 | resolver(@"addTimerWithTask success");
39 | }
40 | } failure:^(NSError *error) {
41 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
42 | }];
43 | }
44 |
45 |
46 | // 获取某设备下的所有定时任务状态:
47 | RCT_EXPORT_METHOD(getTimerTaskStatusWithDeviceId:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
48 | ThingSmartTimer *timer = [[ThingSmartTimer alloc] init];
49 | self.timer = timer;
50 | [timer getTimerTaskStatusWithDeviceId:params[@"devid"] success:^(NSArray *list) {
51 |
52 | NSMutableArray *res = [NSMutableArray array];
53 | for (ThingTimerTaskModel *item in list) {
54 | NSDictionary *dic = [item yy_modelToJSONObject];
55 | [res addObject:dic];
56 | }
57 |
58 | if (resolver) {
59 | resolver(res);
60 | }
61 | } failure:^(NSError *error) {
62 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
63 | }];
64 | }
65 |
66 | // 控制定时任务中所有定时器的开关状态:
67 | RCT_EXPORT_METHOD(updateTimerTaskStatusWithTask:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
68 | ThingSmartTimer *timer = [[ThingSmartTimer alloc] init];
69 | self.timer = timer;
70 | [timer updateTimerTaskStatusWithTask:params[@"taskName"] bizId:params[@"devId"] bizType:0 updateType:[params[@"status"] integerValue] success:^{
71 | if (resolver) {
72 | resolver(@"success");
73 | }
74 | } failure:^(NSError *error) {
75 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
76 | }];
77 | }
78 |
79 | // 控制某个定时器的开关状态:
80 | RCT_EXPORT_METHOD(updateTimerStatusWithTask:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
81 | ThingSmartTimer *timer = [[ThingSmartTimer alloc] init];
82 | self.timer = timer;
83 |
84 | NSInteger status = [params[@"isOpen"] boolValue]?1:0;
85 |
86 | [timer updateTimerStatusWithTask:params[@"taskName"] bizId:params[@"devId"] bizType:0 status:status success:^{
87 | if (resolver) {
88 | resolver(@"success");
89 | }
90 | } failure:^(NSError *error) {
91 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
92 | }];
93 | }
94 |
95 | // 删除定时器:
96 | RCT_EXPORT_METHOD(removeTimerWithTask:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
97 | ThingSmartTimer *timer = [[ThingSmartTimer alloc] init];
98 | self.timer = timer;
99 |
100 | [timer removeTimerWithTask:params[@"taskName"] bizId:params[@"devId"] bizType:0 success:^{
101 | if (resolver) {
102 | resolver(@"success");
103 | }
104 | } failure:^(NSError *error) {
105 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
106 | }];
107 | }
108 |
109 | // 更新定时器的状态:
110 | RCT_EXPORT_METHOD(updateTimerWithTask:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
111 | ThingSmartTimer *timer = [[ThingSmartTimer alloc] init];
112 | self.timer = timer;
113 |
114 | [timer updateTimerWithTimerId:params[@"timerId"] loops:params[@"loops"] bizId:params[@"devId"] bizType:0 time:params[@"time"] dps:params[@"dps"] status:YES isAppPush:NO aliasName:@"" success:^{
115 | if (resolver) {
116 | resolver(@"success");
117 | }
118 | } failure:^(NSError *error) {
119 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
120 | }];
121 | }
122 |
123 | // 获取定时任务下所有定时器:
124 | RCT_EXPORT_METHOD(getTimerWithTask:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
125 | ThingSmartTimer *timer = [[ThingSmartTimer alloc] init];
126 | self.timer = timer;
127 |
128 | [timer getTimerListWithTask:params[@"taskName"] bizId:params[@"devId"] bizType:0 success:^(NSArray *list) {
129 |
130 | NSMutableArray *res = [NSMutableArray array];
131 | for (ThingTimerModel *item in list) {
132 | NSDictionary *dic = [item yy_modelToJSONObject];
133 | [res addObject:dic];
134 | }
135 |
136 | if (resolver) {
137 | resolver(res);
138 | }
139 | } failure:^(NSError *error) {
140 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
141 | }];
142 | }
143 |
144 |
145 | // 获取设备所有定时任务下所有定时器:
146 | RCT_EXPORT_METHOD(getAllTimerWithDeviceId:(NSDictionary *)params resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter) {
147 | ThingSmartTimer *timer = [[ThingSmartTimer alloc] init];
148 | self.timer = timer;
149 | [timer getAllTimerWithDeviceId:params[@"devId"] success:^(NSDictionary *dict) {
150 |
151 | NSMutableArray *res = [NSMutableArray array];
152 |
153 | [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, NSArray* _Nonnull obj, BOOL * _Nonnull stop) {
154 | NSMutableArray *arr = [NSMutableArray array];
155 |
156 | NSMutableDictionary *timerTaskStatus = [NSMutableDictionary dictionary];
157 | timerTaskStatus[@"timerName"] = key;
158 | NSMutableDictionary *task = [NSMutableDictionary dictionary];
159 | task[@"timerTaskStatus"] = timerTaskStatus;
160 |
161 | if([obj isKindOfClass:[NSArray class]]) {
162 | for (ThingTimerModel *item in obj) {
163 | NSMutableDictionary *dic = [item yy_modelToJSONObject];
164 | dic[@"timerId"] = item.timerId;
165 | dic[@"status"] = item.status?@(1):@(0);
166 | task[@"timerTaskStatus"][@"open"] = item.status?@(true):@(false);
167 | [arr addObject:dic];
168 | }
169 | }
170 |
171 | task[@"timerList"] = arr;
172 | [res addObject:task];
173 | }];
174 | if (resolver) {
175 | resolver(res);
176 | }
177 | } failure:^(NSError *error) {
178 | [TuyaRNUtils rejecterWithError:error handler:rejecter];
179 | }];
180 | }
181 |
182 | @end
183 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/utils/TuyaReactUtils.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.utils
2 |
3 | import android.text.TextUtils
4 | import com.alibaba.fastjson.JSON
5 | import com.alibaba.fastjson.JSONArray
6 | import com.alibaba.fastjson.JSONObject
7 | import com.facebook.react.bridge.*
8 | import com.facebook.react.modules.core.DeviceEventManagerModule
9 | import java.math.BigDecimal
10 | import java.util.ArrayList
11 | import java.util.HashMap
12 |
13 |
14 | object TuyaReactUtils {
15 | /**
16 | * 发送事件给React Native
17 | */
18 | fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap?) {
19 | reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
20 | .emit(eventName, params)
21 | }
22 |
23 | fun parseToMap(readableMap: ReadableMap): HashMap {
24 | val iterator = readableMap.keySetIterator()
25 | val deconstructedMap = HashMap()
26 | while (iterator.hasNextKey()) {
27 | val key = iterator.nextKey()
28 | val type = readableMap.getType(key)
29 | when (type) {
30 | ReadableType.Null -> deconstructedMap[key] = null
31 | ReadableType.Boolean -> deconstructedMap[key] = readableMap.getBoolean(key)
32 | ReadableType.Number -> {
33 | val value = readableMap.getDouble(key)
34 | try {
35 | // Long型支持,如果数字大于int, 且是整数,转化成long
36 | if (value > Integer.MAX_VALUE && value % 1 == 0.0) {
37 | deconstructedMap[key] = value.toLong()
38 | } else {
39 | deconstructedMap[key] = value
40 | }
41 | } catch (e: Exception) {
42 | deconstructedMap[key] = value
43 | }
44 |
45 | }
46 | ReadableType.String -> deconstructedMap[key] = readableMap.getString(key)
47 | ReadableType.Map -> deconstructedMap[key] = parseToMap(readableMap.getMap(key) as ReadableMap)
48 | ReadableType.Array -> deconstructedMap[key] = parseToList(readableMap.getArray(key) as ReadableArray)
49 | }
50 |
51 | }
52 | return deconstructedMap
53 | }
54 |
55 | fun parseToLongMap(readableMap: ReadableMap): HashMap {
56 | val iterator = readableMap.keySetIterator()
57 | val deconstructedMap = HashMap()
58 | while (iterator.hasNextKey()) {
59 | val key = iterator.nextKey()
60 | val type = readableMap.getType(key)
61 | when (type) {
62 | ReadableType.Null -> deconstructedMap[key] = null
63 | ReadableType.Boolean -> deconstructedMap[key] = readableMap.getBoolean(key)
64 | ReadableType.Number -> {
65 | val value = readableMap.getDouble(key)
66 | try {
67 | // Long型支持,如果数字大于int, 且是整数,转化成long
68 | if (value > Integer.MAX_VALUE && value % 1 == 0.0) {
69 | deconstructedMap[key] = value.toLong()
70 | } else {
71 | deconstructedMap[key] = value.toLong()
72 | }
73 | } catch (e: Exception) {
74 | deconstructedMap[key] = value
75 | }
76 |
77 | }
78 | ReadableType.String -> deconstructedMap[key] = readableMap.getString(key)
79 | ReadableType.Map -> deconstructedMap[key] = parseToMap(readableMap.getMap(key) as ReadableMap)
80 | ReadableType.Array -> deconstructedMap[key] = parseToList(readableMap.getArray(key) as ReadableArray)
81 | }
82 |
83 | }
84 | return deconstructedMap
85 | }
86 |
87 | fun parseToList(readableArray: ReadableArray): ArrayList {
88 | val deconstructedList = ArrayList(readableArray.size())
89 | for (i in 0 until readableArray.size()) {
90 | val indexType = readableArray.getType(i)
91 | when (indexType) {
92 | ReadableType.Null -> deconstructedList.add(i, null)
93 | ReadableType.Boolean -> deconstructedList.add(i, readableArray.getBoolean(i))
94 | ReadableType.Number -> {
95 | val value = readableArray.getDouble(i)
96 | try {
97 | // Long型支持,如果数字大于int, 且是整数,转化成long
98 | if (value > Integer.MAX_VALUE && value % 1 == 0.0) {
99 | deconstructedList.add(i, value.toLong())
100 | } else {
101 | deconstructedList.add(i, value)
102 | }
103 | } catch (e: Exception) {
104 | deconstructedList.add(i, value)
105 | }
106 |
107 | }
108 | ReadableType.String -> deconstructedList.add(i, readableArray.getString(i))
109 | ReadableType.Map -> deconstructedList.add(i, parseToMap(readableArray.getMap(i) as ReadableMap))
110 | ReadableType.Array -> deconstructedList.add(i, parseToList(readableArray.getArray(i) as ReadableArray))
111 | }
112 | }
113 | return deconstructedList
114 | }
115 |
116 | fun parseToWritableMap(s: String): WritableMap {
117 | return if (TextUtils.isEmpty(s)) Arguments.createMap() else parseToWritableMap(JSON.parseObject(s))
118 | }
119 |
120 | fun parseToWritableMap(data: Any?): WritableMap {
121 | return if (null == data) Arguments.createMap() else parseToWritableMap(JSON.toJSONString(data))
122 | }
123 |
124 | fun parseToWritableMap(json: JSONObject): WritableMap {
125 | val map = Arguments.createMap()
126 | val entries = json.entries
127 | for ((key, obv) in entries) {
128 | when (obv) {
129 | is JSONObject -> map.putMap(key, parseToWritableMap(obv))
130 | is JSONArray -> map.putArray(key, parseToWritableArray(obv))
131 | is Int -> map.putInt(key, obv)
132 | is String -> map.putString(key, obv)
133 | is Boolean -> map.putBoolean(key, obv)
134 | is Double -> map.putDouble(key, obv)
135 | is BigDecimal -> map.putDouble(key, obv.toDouble())
136 | is Long ->map.putString(key,obv.toString())
137 | else -> map.putNull(key)
138 | }
139 | }
140 | return map
141 | }
142 |
143 | fun parseToWritableArray(jsonArray: JSONArray): WritableArray {
144 | val list = Arguments.createArray()
145 | for (obv in jsonArray.toTypedArray()) {
146 | when (obv) {
147 | is JSONObject -> list.pushMap(parseToWritableMap(obv))
148 | is JSONArray -> list.pushArray(parseToWritableArray(obv))
149 | is Int -> list.pushInt(obv)
150 | is String -> list.pushString(obv)
151 | is Boolean -> list.pushBoolean(obv)
152 | is Double -> list.pushDouble(obv)
153 | is BigDecimal -> list.pushDouble(obv.toDouble())
154 | is Long -> list.pushString(obv.toString())
155 | else -> list.pushNull()
156 | }
157 | }
158 | return list
159 |
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/device/TuyaDeviceModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.device
2 |
3 | import android.util.Log
4 | import com.alibaba.fastjson.JSONObject
5 | import com.facebook.react.bridge.*
6 | import com.thingclips.smart.android.device.api.IGetDataPointStatCallback
7 | import com.thingclips.smart.android.device.bean.DataPointStatBean
8 | import com.thingclips.smart.android.device.enums.DataPointTypeEnum
9 | import com.thingclips.smart.home.sdk.ThingHomeSdk
10 | import com.thingclips.smart.sdk.api.IDevListener
11 | import com.thingclips.smart.sdk.api.IThingDevice
12 | import com.tuya.smart.rnsdk.utils.BridgeUtils
13 | import com.tuya.smart.rnsdk.utils.Constant.COMMAND
14 | import com.tuya.smart.rnsdk.utils.Constant.DATAPOINTTYPEENUM
15 | import com.tuya.smart.rnsdk.utils.Constant.DEVID
16 | import com.tuya.smart.rnsdk.utils.Constant.DPID
17 | import com.tuya.smart.rnsdk.utils.Constant.NAME
18 | import com.tuya.smart.rnsdk.utils.Constant.NUMBER
19 | import com.tuya.smart.rnsdk.utils.Constant.STARTTIME
20 | import com.tuya.smart.rnsdk.utils.Constant.getIResultCallback
21 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
22 | import com.tuya.smart.rnsdk.utils.TuyaReactUtils
23 |
24 |
25 | class TuyaDeviceModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
26 |
27 | var device: IThingDevice? = null
28 |
29 | override fun getName(): String {
30 | return "TuyaDeviceModule"
31 | }
32 |
33 | @ReactMethod
34 | fun getDevice(params: ReadableMap, promise: Promise) {
35 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
36 | promise.resolve(TuyaReactUtils.parseToWritableMap(getDevice(params.getString(DEVID) as String)))
37 | }
38 | }
39 |
40 | @ReactMethod
41 | fun getDeviceData(params: ReadableMap, promise: Promise) {
42 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
43 | promise.resolve(TuyaReactUtils.parseToWritableMap(ThingHomeSdk.getDataInstance().getDeviceBean(params.getString(DEVID))))
44 | }
45 | }
46 |
47 | @ReactMethod
48 | fun registerDevListener(params: ReadableMap) {
49 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
50 | device = getDevice(params.getString(DEVID) as String)
51 | device?.registerDevListener(object : IDevListener {
52 | override fun onDpUpdate(devId: String, dpStr: String) {
53 | //dp数据更新:devId 和相应dp数据
54 | val map = Arguments.createMap()
55 | map.putString("devId", devId)
56 | map.putString("dpStr", dpStr)
57 | map.putString("type", "onDpUpdate");
58 | BridgeUtils.devListener(reactApplicationContext, map, params.getString(DEVID) as String)
59 | }
60 |
61 | override fun onRemoved(devId: String) {
62 | //设备被移除
63 | val map = Arguments.createMap()
64 | map.putString("devId", devId)
65 | map.putString("type", "onRemoved");
66 | BridgeUtils.devListener(reactApplicationContext, map, params.getString(DEVID) as String)
67 | }
68 |
69 | override fun onStatusChanged(devId: String, online: Boolean) {
70 | //设备在线状态,online
71 | val map = Arguments.createMap()
72 | map.putString("devId", devId)
73 | map.putBoolean("online", online)
74 | map.putString("type", "onStatusChanged");
75 | BridgeUtils.devListener(reactApplicationContext, map, params.getString(DEVID) as String)
76 | }
77 |
78 | override fun onNetworkStatusChanged(devId: String, status: Boolean) {
79 | //网络状态监听
80 | val map = Arguments.createMap()
81 | map.putString("devId", devId)
82 | map.putBoolean("status", status)
83 | map.putString("type", "onNetworkStatusChanged");
84 |
85 | BridgeUtils.devListener(reactApplicationContext, map, params.getString(DEVID) as String)
86 | }
87 |
88 | override fun onDevInfoUpdate(devId: String) {
89 | //设备信息变更,目前只有设备名称变化,会调用该接口
90 | val map = Arguments.createMap()
91 | map.putString("devId", devId)
92 | map.putString("type", "onDevInfoUpdate");
93 | BridgeUtils.devListener(reactApplicationContext, map, params.getString(DEVID) as String)
94 | }
95 | })
96 |
97 | }
98 | }
99 |
100 | @ReactMethod
101 | fun unRegisterDevListener(params: ReadableMap) {
102 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
103 | if (device != null) {
104 | device!!.unRegisterDevListener()
105 | }
106 | }
107 | }
108 |
109 | @ReactMethod
110 | fun onDestroy(params: ReadableMap) {
111 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
112 | getDevice(params.getString(DEVID) as String)?.onDestroy()
113 | }
114 | }
115 |
116 |
117 | @ReactMethod
118 | fun send(params: ReadableMap, promise: Promise) {
119 | if (ReactParamsCheck.checkParams(arrayOf(DEVID, COMMAND), params)) {
120 | getDevice(params.getString(DEVID) as String)?.publishDps(JSONObject.toJSONString(TuyaReactUtils.parseToMap(params.getMap(COMMAND) as ReadableMap))
121 | , getIResultCallback(promise))
122 | }
123 | }
124 |
125 |
126 | @ReactMethod
127 | fun getDp(params: ReadableMap, promise: Promise) {
128 | if (ReactParamsCheck.checkParams(arrayOf(DEVID, DPID), params)) {
129 | promise.resolve(getDevice(params.getString(DEVID) as String)?.getDp(
130 | params.getString(DPID),
131 | getIResultCallback(promise)
132 | ))
133 | }
134 | }
135 |
136 | @ReactMethod
137 | fun renameDevice(params: ReadableMap, promise: Promise) {
138 | if (ReactParamsCheck.checkParams(arrayOf(DEVID, NAME), params)) {
139 | getDevice(params.getString(DEVID) as String)?.renameDevice(params.getString(NAME), getIResultCallback(promise))
140 | }
141 | }
142 |
143 | @ReactMethod
144 | fun getDataPointStat(params: ReadableMap, promise: Promise) {
145 | if (ReactParamsCheck.checkParams(arrayOf(DEVID, DATAPOINTTYPEENUM, NUMBER, DPID, STARTTIME), params)) {
146 | getDevice(params.getString(DEVID) as String)?.getDataPointStat(DataPointTypeEnum.valueOf(params.getString(DATAPOINTTYPEENUM) as String),
147 | params.getDouble(STARTTIME).toLong(),
148 | params.getInt(NUMBER),
149 | params.getString(DPID),
150 | getIGetDataPointStatCallback(promise)
151 | )
152 | }
153 | }
154 |
155 | @ReactMethod
156 | fun removeDevice(params: ReadableMap, promise: Promise) {
157 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
158 | getDevice(params.getString(DEVID) as String)?.removeDevice(getIResultCallback(promise))
159 | }
160 | }
161 |
162 | fun getIGetDataPointStatCallback(promise: Promise): IGetDataPointStatCallback {
163 | return object : IGetDataPointStatCallback {
164 |
165 | override fun onSuccess(p0: DataPointStatBean?) {
166 | promise.resolve(TuyaReactUtils.parseToWritableMap(p0))
167 | }
168 |
169 |
170 | override fun onError(code: String?, error: String?) {
171 | promise.reject(code, error)
172 | }
173 | }
174 | }
175 |
176 |
177 | fun getDevice(devId: String): IThingDevice {
178 | return ThingHomeSdk.newDeviceInstance(devId);
179 | }
180 |
181 | }
182 |
--------------------------------------------------------------------------------
/ios/RNTuyaSdk/Utils/Listener/TuyaRNHomeListener.m:
--------------------------------------------------------------------------------
1 | //
2 | // TuyaRNHomeListener.m
3 | // TuyaRnDemo
4 | //
5 | // Created by 浩天 on 2019/3/6.
6 | // Copyright © 2019年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "TuyaRNHomeListener.h"
10 | #import
11 | #import
12 | #import "TuyaRNEventEmitter.h"
13 | #import
14 | #import
15 | #import
16 |
17 | @interface TuyaRNHomeListener()
18 |
19 | @property (strong, nonatomic) ThingSmartHome *homeChangeSmartHome;
20 | @property (strong, nonatomic) ThingSmartHome *homeStatusSmartHome;
21 |
22 | @end
23 |
24 | @implementation TuyaRNHomeListener
25 |
26 | + (instancetype)shareInstance {
27 | static TuyaRNHomeListener *_instance = nil;
28 | static dispatch_once_t onceToken;
29 | dispatch_once(&onceToken, ^{
30 | _instance = [[TuyaRNHomeListener alloc] init];
31 | });
32 | return _instance;
33 | }
34 |
35 | - (void)registerHomeChangeWithSmartHome:(ThingSmartHome *)smartHome {
36 |
37 | if (!smartHome) {
38 | return;
39 | }
40 | [TuyaRNHomeListener shareInstance].homeChangeSmartHome = smartHome;
41 | [TuyaRNHomeListener shareInstance].homeChangeSmartHome.delegate = self;
42 | }
43 |
44 | - (void)removeHomeChangeSmartHome {
45 |
46 | [TuyaRNHomeListener shareInstance].homeChangeSmartHome = nil;
47 | [TuyaRNHomeListener shareInstance].homeChangeSmartHome.delegate = nil;
48 |
49 | }
50 |
51 | - (void)registerHomeStatusWithSmartHome:(ThingSmartHome *)smartHome {
52 |
53 | if (!smartHome) {
54 | return;
55 | }
56 | [TuyaRNHomeListener shareInstance].homeStatusSmartHome = smartHome;
57 | [TuyaRNHomeListener shareInstance].homeStatusSmartHome.delegate = self;
58 | }
59 |
60 | - (void)removeHomeStatusSmartHome {
61 |
62 | [TuyaRNHomeListener shareInstance].homeStatusSmartHome = nil;
63 | [TuyaRNHomeListener shareInstance].homeStatusSmartHome.delegate = nil;
64 |
65 | }
66 |
67 |
68 | #pragma mark - ThingSmartHomeDelegate
69 |
70 | // 家庭的信息更新,例如name
71 | - (void)homeDidUpdateInfo:(ThingSmartHome *)home {
72 |
73 | if (!self.homeChangeSmartHome) {
74 | return;
75 | }
76 |
77 | if (home.homeModel.homeId <= 0) {
78 | return;
79 | }
80 | NSDictionary *dic = @{
81 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
82 | @"type": @"onHomeInfoChanged"
83 | };
84 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeChangeEvent stringByAppendingString:@"//"] withBody:dic];
85 | }
86 |
87 | // 我收到的共享设备列表变化
88 | - (void)homeDidUpdateSharedInfo:(ThingSmartHome *)home {
89 |
90 | if (!self.homeChangeSmartHome) {
91 | return;
92 | }
93 |
94 | if (home.homeModel.homeId <= 0) {
95 | return;
96 | }
97 | NSDictionary *dic = @{
98 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
99 | @"type": @"onSharedDeviceList"
100 | };
101 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeChangeEvent stringByAppendingString:@"//"] withBody:dic];
102 | }
103 |
104 | // 房间信息变更,例如name
105 | - (void)home:(ThingSmartHome *)home roomInfoUpdate:(ThingSmartRoomModel *)room {
106 |
107 | if (!self.homeChangeSmartHome) {
108 | return;
109 | }
110 |
111 | //房间的名字的变更
112 | if (home.homeModel.homeId <= 0) {
113 | return;
114 | }
115 | NSDictionary *dic = @{
116 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
117 | @"roomId": [NSNumber numberWithLongLong:room.roomId],
118 | @"type": @"onHomeRoomInfo"
119 | };
120 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeChangeEvent stringByAppendingFormat:@"//%lld",home.homeModel.homeId] withBody:dic];
121 | }
122 |
123 | // 房间与设备,群组的关系变化
124 | - (void)home:(ThingSmartHome *)home roomRelationUpdate:(ThingSmartRoomModel *)room {
125 |
126 | }
127 |
128 | // 添加设备
129 | - (void)home:(ThingSmartHome *)home didAddDeivice:(ThingSmartDeviceModel *)device {
130 |
131 | if (!self.homeStatusSmartHome) {
132 | return;
133 | }
134 |
135 | NSDictionary *dic = @{
136 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
137 | @"devId": device.devId,
138 | @"type": @"onDeviceAdded"
139 | };
140 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeStatusEvent stringByAppendingFormat:@"//%lld",home.homeModel.homeId] withBody:dic];
141 |
142 | }
143 |
144 | // 删除设备
145 | - (void)home:(ThingSmartHome *)home didRemoveDeivice:(NSString *)devId {
146 |
147 | if (!self.homeStatusSmartHome) {
148 | return;
149 | }
150 | NSDictionary *dic = @{
151 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
152 | @"devId": devId,
153 | @"type": @"onDeviceRemoved"
154 | };
155 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeStatusEvent stringByAppendingFormat:@"//%lld",home.homeModel.homeId] withBody:dic];
156 |
157 | }
158 |
159 | // 设备信息更新,例如name
160 | - (void)home:(ThingSmartHome *)home deviceInfoUpdate:(ThingSmartDeviceModel *)device {
161 |
162 | }
163 |
164 | // 设备dp数据更新
165 | - (void)home:(ThingSmartHome *)home device:(ThingSmartDeviceModel *)device dpsUpdate:(NSDictionary *)dps {
166 |
167 | }
168 |
169 | // 添加群组
170 | - (void)home:(ThingSmartHome *)home didAddGroup:(ThingSmartGroupModel *)group {
171 | if (!self.homeStatusSmartHome) {
172 | return;
173 | }
174 | NSDictionary *dic = @{
175 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
176 | @"devId": group.groupId,
177 | @"type": @"onGroupAdded"
178 | };
179 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeStatusEvent stringByAppendingFormat:@"//%lld",home.homeModel.homeId] withBody:dic];
180 | }
181 |
182 | // 群组dp数据更新
183 | - (void)home:(ThingSmartHome *)home group:(ThingSmartGroupModel *)group dpsUpdate:(NSDictionary *)dps {
184 | if (!self.homeStatusSmartHome || !dps || dps.count == 0) {
185 | return;
186 | }
187 | NSDictionary *dic = @{
188 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
189 | @"groupId": group,
190 | @"dps":dps,
191 | @"type": @"onGroupDpsUpdate"
192 | };
193 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeStatusEvent stringByAppendingFormat:@"//%lld",home.homeModel.homeId] withBody:dic];
194 | }
195 |
196 | // 删除群组
197 | - (void)home:(ThingSmartHome *)home didRemoveGroup:(NSString *)groupId {
198 | if (!self.homeStatusSmartHome) {
199 | return;
200 | }
201 | NSDictionary *dic = @{
202 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
203 | @"groupId": groupId,
204 | @"type": @"onGroupRemoved"
205 | };
206 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeStatusEvent stringByAppendingFormat:@"//%lld",home.homeModel.homeId] withBody:dic];
207 | }
208 |
209 | // 群组信息更新,例如name
210 | - (void)home:(ThingSmartHome *)home groupInfoUpdate:(ThingSmartGroupModel *)group {
211 | if (!self.homeStatusSmartHome) {
212 | return;
213 | }
214 | NSDictionary *dic = @{
215 | @"homeId": [NSNumber numberWithLongLong:home.homeModel.homeId],
216 | @"groupId": group.groupId,
217 | @"type": @"onGroupInfoUpdate"
218 | };
219 | [TuyaRNEventEmitter ty_sendEvent:[kTYEventEmitterHomeStatusEvent stringByAppendingFormat:@"//%lld",home.homeModel.homeId] withBody:dic];
220 | }
221 |
222 | @end
223 |
--------------------------------------------------------------------------------
/android/src/main/java/com/tuya/smart/rnsdk/timer/TuyaTimerModule.kt:
--------------------------------------------------------------------------------
1 | package com.tuya.smart.rnsdk.timer
2 |
3 | import com.facebook.react.bridge.*
4 | import com.thingclips.smart.home.sdk.ThingHomeSdk
5 | import com.thingclips.smart.sdk.api.IGetAllTimerWithDevIdCallback
6 | import com.thingclips.smart.sdk.api.IGetDeviceTimerStatusCallback
7 | import com.thingclips.smart.sdk.api.IGetTimerWithTaskCallback
8 | import com.thingclips.smart.sdk.api.IResultStatusCallback
9 | import com.thingclips.smart.sdk.bean.TimerTask
10 | import com.thingclips.smart.sdk.bean.TimerTaskStatus
11 | import com.tuya.smart.rnsdk.utils.Constant
12 | import com.tuya.smart.rnsdk.utils.Constant.DEVID
13 | import com.tuya.smart.rnsdk.utils.Constant.DPS
14 | import com.tuya.smart.rnsdk.utils.Constant.ISOPEN
15 | import com.tuya.smart.rnsdk.utils.Constant.LOOPS
16 | import com.tuya.smart.rnsdk.utils.Constant.STATUS
17 | import com.tuya.smart.rnsdk.utils.Constant.TASKNAME
18 | import com.tuya.smart.rnsdk.utils.Constant.TIME
19 | import com.tuya.smart.rnsdk.utils.Constant.TIMERID
20 | import com.tuya.smart.rnsdk.utils.JsonUtils
21 | import com.tuya.smart.rnsdk.utils.ReactParamsCheck
22 | import com.tuya.smart.rnsdk.utils.TuyaReactUtils
23 | import java.util.ArrayList
24 |
25 |
26 | class TuyaTimerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
27 |
28 | override fun getName(): String {
29 | return "TuyaTimerModule"
30 | }
31 |
32 | /**
33 | * 增加定时器 单dp点 默认置为true 支持子设备
34 | * @param taskName 定时任务名称
35 | * @param loops 循环次数 "0000000", 每一位 0:关闭,1:开启, 从左至右依次表示: 周日 周一 周二 周三 周四 周五 周六
36 | * @param devId 设备Id或群组Id
37 | * @param dps dp点键值对,key是dpId,value是dpValue,仅支持单dp点
38 | * @param time 定时任务下的定时钟
39 | * @param callback 回调
40 | */
41 | @ReactMethod
42 | fun addTimerWithTask(params: ReadableMap,promise: Promise) {
43 | if (ReactParamsCheck.checkParams(arrayOf(TASKNAME, LOOPS,DEVID, DPS, TIME), params)) {
44 | ThingHomeSdk.getTimerManagerInstance().addTimerWithTask(
45 | params.getString(TASKNAME),
46 | params.getString(DEVID),
47 | params.getString(LOOPS),
48 | TuyaReactUtils.parseToMap(params.getMap(DPS) as ReadableMap),
49 | params.getString(TIME),
50 | getIResultStatusCallback(promise)
51 | )
52 | }
53 | }
54 |
55 | /*获取某设备下的所有定时任务状态*/
56 | @ReactMethod
57 | fun getTimerTaskStatusWithDeviceId(params: ReadableMap,promise: Promise) {
58 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
59 | ThingHomeSdk.getTimerManagerInstance().getTimerTaskStatusWithDeviceId(
60 | params.getString(DEVID),
61 | getIGetDeviceTimerStatusCallback(promise)
62 | )
63 | }
64 | }
65 |
66 | /*控制定时任务中所有定时器的开关状态*/
67 | @ReactMethod
68 | fun updateTimerTaskStatusWithTask(params: ReadableMap,promise: Promise) {
69 | if (ReactParamsCheck.checkParams(arrayOf(TASKNAME,DEVID,STATUS), params)) {
70 | ThingHomeSdk.getTimerManagerInstance().updateTimerTaskStatusWithTask(
71 | params.getString(TASKNAME),
72 | params.getString(DEVID),
73 | params.getInt(STATUS),
74 | getIResultStatusCallback(promise)
75 | )
76 | }
77 | }
78 |
79 | /*控制某个定时器的开关状态*/
80 | @ReactMethod
81 | fun updateTimerStatusWithTask(params: ReadableMap,promise: Promise) {
82 | if (ReactParamsCheck.checkParams(arrayOf(TASKNAME,DEVID,TIMERID, ISOPEN), params)) {
83 | ThingHomeSdk.getTimerManagerInstance().updateTimerStatusWithTask(
84 | params.getString(TASKNAME),
85 | params.getString(DEVID),
86 | params.getString(TIMERID),
87 | params.getBoolean(ISOPEN),
88 | getIResultStatusCallback(promise)
89 | )
90 | }
91 | }
92 |
93 |
94 | /*删除定时器*/
95 | @ReactMethod
96 | fun removeTimerWithTask(params: ReadableMap,promise: Promise) {
97 | if (ReactParamsCheck.checkParams(arrayOf(TASKNAME,DEVID, TIMERID), params)) {
98 | ThingHomeSdk.getTimerManagerInstance().removeTimerWithTask(
99 | params.getString(TASKNAME),
100 | params.getString(DEVID),
101 | params.getString(TIMERID),
102 | getIResultStatusCallback(promise)
103 | )
104 | }
105 | }
106 |
107 | /**
108 | * * 更新定时器的状态
109 | * @param taskName 定时任务名称
110 | * @param loops 循环次数 如每周每天传”1111111”
111 | * @param devId 设备Id或群组Id
112 | * @param timerId 定时钟Id
113 | * @param time 定时时间
114 | * @param isOpen 是否开启
115 | * @param callback 回调
116 | */
117 | @ReactMethod
118 | fun updateTimerWithTask(params: ReadableMap,promise: Promise) {
119 | if (ReactParamsCheck.checkParams(arrayOf(TASKNAME, LOOPS, DEVID, TIMERID, TIME, ISOPEN), params)) {
120 | ThingHomeSdk.getTimerManagerInstance().updateTimerWithTask(
121 | params.getString(TASKNAME),
122 | params.getString(LOOPS),
123 | params.getString(DEVID),
124 | params.getString(TIMERID),
125 | // Unfortunately we cannot update dps values, we can only give a single dp id but we also want to control the dp value
126 | null,
127 | params.getString(TIME),
128 | params.getBoolean(ISOPEN),
129 | getIResultStatusCallback(promise))
130 | }
131 | }
132 |
133 | /*获取定时任务下所有定时器*/
134 | @ReactMethod
135 | fun getTimerWithTask(params: ReadableMap,promise: Promise) {
136 | if (ReactParamsCheck.checkParams(arrayOf(TASKNAME, DEVID), params)) {
137 | ThingHomeSdk.getTimerManagerInstance().getTimerWithTask(
138 | params.getString(TASKNAME),
139 | params.getString(DEVID),
140 | getIGetTimerWithTaskCallback(promise))
141 | }
142 | }
143 |
144 | /*获取设备所有定时任务下所有定时器*/
145 | @ReactMethod
146 | fun getAllTimerWithDeviceId(params: ReadableMap,promise: Promise) {
147 | if (ReactParamsCheck.checkParams(arrayOf(DEVID), params)) {
148 | ThingHomeSdk.getTimerManagerInstance().getAllTimerWithDeviceId(
149 | params.getString(DEVID),
150 | getIGetAllTimerWithDevIdCallback(promise))
151 | }
152 | }
153 |
154 | fun getIGetAllTimerWithDevIdCallback(promise: Promise): IGetAllTimerWithDevIdCallback {
155 | return object : IGetAllTimerWithDevIdCallback {
156 | override fun onSuccess(p0: ArrayList?) {
157 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(p0!!)))
158 | }
159 |
160 | override fun onError(code: String?, error: String?) {
161 | promise.reject(code, error)
162 | }
163 | }
164 | }
165 | fun getIGetTimerWithTaskCallback(promise: Promise): IGetTimerWithTaskCallback {
166 | return object : IGetTimerWithTaskCallback {
167 | override fun onSuccess(p0: TimerTask?) {
168 | promise.resolve(TuyaReactUtils.parseToWritableMap(p0))
169 | }
170 |
171 | override fun onError(code: String?, error: String?) {
172 | promise.reject(code, error)
173 | }
174 | }
175 | }
176 | fun getIGetDeviceTimerStatusCallback(promise: Promise): IGetDeviceTimerStatusCallback {
177 | return object : IGetDeviceTimerStatusCallback {
178 | override fun onSuccess(p0: ArrayList?) {
179 | promise.resolve(TuyaReactUtils.parseToWritableArray(JsonUtils.toJsonArray(p0!!)))
180 | }
181 |
182 | override fun onError(code: String?, error: String?) {
183 | promise.reject(code, error)
184 | }
185 | }
186 | }
187 |
188 | fun getIResultStatusCallback(promise: Promise): IResultStatusCallback {
189 | return object : IResultStatusCallback {
190 | override fun onSuccess() {
191 | promise.resolve(Constant.SUCCESS)
192 | }
193 |
194 | override fun onError(code: String?, error: String?) {
195 | promise.reject(code, error)
196 | }
197 | }
198 | }
199 | }
200 |
--------------------------------------------------------------------------------