Component implementation for smartliving WiFi SDK of Ali fy(飞燕) platform 生活物联网平台, to control ali-smartliving-device-alios-things with direct(websocket) or indirect WiFi mode.
Suppor 蓝牙辅助配网 of 配置App配网引导方式.
npm install react-native-ali-smartliving
cd ios
pod install
Copy yw_1222_china_production.jpg
downloaded from https://living.aliyun.com/
to ios/
, then drag it into Xcode where AppDelegate.m
lives. Ref to 集成安全图片.
Drag Pods | Development Pods | react-native-ali-smartliving | Resources | xib
into top of Project in Xcode and select "Added folders: Create groups".
- In
ios/YOUR_PROJECT/AppDelegate.m
#import <react-native-ali-smartliving/AliLiving.h>
...
[AliLiving InitializeSmartliving:application launchOptions:launchOptions];
You can customize and localize the login View, ref to the commit "feat(react-native-ali-smartliving): in iOS login View, add a new button to showEmailFindPasswordView, and hide the button which showFindPasswordView with Phone"
Add WiFi support for ios 13 and above.
Add NSBluetoothAlwaysUsageDescription
and NSBluetoothPeripheralUsageDescription
keys to your Info.plist
.
Copy yw_1222_china_production.jpg
downloaded from https://living.aliyun.com/
to android/app/src/main/res/drawable/
. Ref to 集成安全图片, and if runtime ErrorCode = 212
at com.alibaba.wireless.security.open.SecException
after upgrade com.aliyun.iot.aep.sdk:apiclient
in android/dependency.gradle
, you need upload apk and download jpg again.
- In
android/app/build.gradle
/**
* Whether to use Aliyun encryption pic such as yw_1222_china_production.jpg.
*/
def useAliyunEncryptionPic = true
android {
defaultConfig {
minSdkVersion 18
targetSdkVersion 26
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "arm64-v8a" // Aliyun livinglink SDK only support these two ABIs
}
}
signingConfigs {
debug {
if (useAliyunEncryptionPic) {
v2SigningEnabled false
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
} else {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
}
- In
node_modules/react-native-ali-smartliving/android/dependency.gradle
If node_modules/react-native-svg not exist in your project, you should use
api 'com.aliyun.iot.aep.page:rn:0.3.6.1'
- In
node_modules/react-native-ali-smartliving/android/build.gradle
If RN >= 0.65 that remove sourceCompatibility JavaVersion.VERSION_1_8
ref to https://react-native-community.github.io/upgrade-helper/?from=0.64.3&to=0.65.0, you should also remove
compileOptions {
sourceCompatibility rootProject.ext.javaSourceCompatibility
targetCompatibility rootProject.ext.javaTargetCompatibility
}
- In
MainApplication.java
// import com.aliyun.iot.aep.sdk.framework.AApplication;
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new AliLivingReactPackage(getApplication()),
);
}
find android/app/src/main/java/ -name MainApplication.java | xargs sed -i -e "s/extends Application/extends com.aliyun.iot.aep.sdk.framework.AApplication/"
- In
application
ofAndroidManifest.xml
tools:replace="android:allowBackup"
android:usesCleartextTraffic="true"
android:usesCleartextTraffic="true"
here is for WebSocket working in release version, ref to https://github.com/facebook/react-native/issues/24361
import React from 'react';
import { View } from 'react-native';
import meshModule from 'react-native-ali-smartliving';
export default class MeshModuleExample extends React.Component {
constructor(props) {
super(props);
meshModule.passthroughMode = {
silan: [
'a17hN4W4777', // PRODUCT_KEY
'directWifi', // the fake PRODUCT_KEY needed by direct WiFi mode device
],
sllc: [
'directWifi',
],
};
}
componentDidMount() {
meshModule.addListener('leScan', this.onLeScan);
meshModule.doInit();
meshModule.startScan({
meshName: 'sysin_mesh', // if 'sysin_mesh', will scan unclaimed devices, otherwise not
timeoutSeconds: 10,
});
}
// after meshModule.startScan() found some device, will cause onLeScan() here
onLeScan = data => console.warn(data)
render() {
return (
<View/>
);
}
}
The device can be in official indirect WiFi mode or 设备端添加 WebSocket Server 支持 as unofficial direct WiFi mode.
Get the real address of the data.params
comes from various opcode
in AliLiving.java
.
Get the online status of the data.params
comes from various opcode
in AliLiving.java
.
Get the power status of the data.params
comes from various opcode
in AliLiving.java
.
Note whether you defined TimezoneOffset described as code comment in index.native.js
.
Note whether you use alarmId 0 or alarmId 1 as 1st LocalTimer described as code comment in index.native.js
.
No need login, even no need burn info like productKey from https://living.aliyun.com
into device, no need change mac address of device, you can still controll the device, only need your smartphone connect WiFi to the AP comes from the device.
If you want just debug with a device simulated on computer, you need
node node_modules/react-native-ali-smartliving/simSocketDevice/server.js
and comment the line state.details.ipAddress.match
in index.native.js
and edit let host = this.directWifiIpv4Byte3 + '1'
to e.g. let host = '192.168.1.100'
where 192.168.1.100
is the IP address of you computer which connected the same LAN that your smartphone connected.
If you want just debug with a device simulated on computer, you need
git clone https://github.com/warmcat/libwebsockets -b v2.4.1
add lwsl_notice(" %s\n", (const char *)in);
in case LWS_CALLBACK_RECEIVE:
of libwebsockets/test-apps/test-server-dumb-increment.c
, then
cd libwebsockets
mkdir build
cd build
cmake ..
make
./bin/libwebsockets-test-server --port=8821
and edit let host = this.directWifiIpv4Byte3 + '1'
to e.g. let host = '127.0.0.1'
and edit local-ali-smartliving
to dumb-increment-protocol
in index.web.js
.
Actually there is no login function supported by Ali ilop sdk, when it's not login state, the login and register dialog will appears automatically.
Default only email register, if you also want mobile register, on Android, modify
android/src/main/java/ugen/fy/plugin/OALoginActivity.java
supportMobile
to true, on iOS, customize and localize the login View described above, and you need buy sms support on https://living.aliyun.com/
.
example:
meshModule.addListener('leScan', console.warn);
meshModule.startScan({
meshName: 'sysin_mesh', // if 'sysin_mesh', will scan unclaimed devices, otherwise not
timeoutSeconds: 10,
});
when adding device, the param is:
{
node {
macAddress: 'A0:FB:42:00:A1:DB', // mac of the device found from onLeScan after startScan
type: {
p: 'a17hN4W4777', // PRODUCT_KEY
d: 5, // 5 comes from onLeScan means DiscoveryType.COMBO_SUBTYPE_0X03_DEVICE, other discovery type not debug yet
},
},
cfg: {
newName: 'ssid of your WiFi',
newPwd: 'password of your WiFi',
},
isToClaim: true,
}
when removing device, the param is:
{
node {
meshAddress: 'vvssa4DEzVglIGxDl777000000', // iotId
},
isToClaim: false,
}
load devices info from https://living.aliyun.com
and convert them into our nodes format, then init them in native code and return nodes.
the param is:
{
oldNodes = [{
a: 'vvssa4DEzVglIGxDl777000000', // iotId
m: 'A0:FB:42:00:A1:DB', // mac
// i: {
// v: 'app-1.6.0-20201201.1027' // fwVersion
// },
// n: 'testDeviceName7',
// t: {
// d: 0, // 0 comes from loadNodes({forceRefresh: true}) means DiscoveryType.LOCAL_ONLINE_DEVICE
// p: 'a17hN4W4777', // PRODUCT_KEY
// }
}],
forceRefresh = false,
}
example:
await meshModule.send(
'/uc/listBindingByAccount', // path
JSON.stringify({pageNo: 1, pageSize: 100}), // params
'1.0.8', // version
true, // iotAuth
)
When getAliSocketListenerState()
return not CONNECTED, you need startAliSocketListener()
before subscribe()
.
example:
await meshModule.startAliSocketListener();
example:
await meshModule.stopAliSocketListener();
Will return CONNECTED with login, otherwise, please use startAliSocketListener()
.
Need getAliSocketListenerState()
return CONNECTED.
example:
meshModule.addListener('subscribeState', console.warn); // subscribe successful or not
meshModule.addListener('subscribeDownstream', console.warn); // data comes from topic
await meshModule.subscribe(topic);
Need getAliSocketListenerState()
return CONNECTED.
AKA publish.
Need getAliSocketListenerState()
return CONNECTED.
AKA invokeWithTopic.
Need getAliSocketListenerState()
return CONNECTED.
Ref to 长连接通道SDK