<a href='https://coveralls.io/github/gizwits/mini_program_gizwits_sdk?branch=master'><img src='https://coveralls.io/repos/github/gizwits/mini_program_gizwits_sdk/badge.svg?branch=master' alt='Coverage Status' /></a><img alt="npm" src="https://img.shields.io/npm/v/mini_program_gizwits_sdk">[![Build Status](https://travis-ci.org/gizwits/mini_program_gizwits_sdk.svg?branch=master)](https://travis-ci.org/gizwits/mini_program_gizwits_sdk)

# 机智云小程序 SDK


## ⚠️ 重要

使用小程序 sdk 前，请在微信开发者后台-开发管理-开发设置-服务器域名添加以下请求地址。

- request 合法域名

```txt
https://api.gizwits.com
https://site.gizwits.com
```

- socket 合法域名

```txt
wss://wxstage.gizwits.com
wss://wxm2m.gizwits.com
```

- 关于services

为了搜索效率，sdk会根据`services `过滤蓝牙设备。默认  ['ABF8', 'ABF0', 'F0AB', 'F8AB']。
如果有特殊情况，不想用`services `过滤设备，可以

```js
sdk.scanBleDevice(3000, [])
sdk.startAutoScan([])
```


## 🔧 安装

```bash
npm install mini_program_gizwits_sdk
// or
yarn add mini_program_gizwits_sdk
```

## 📑 代码示例

> 采用小程序代码片段，安装新版小程序开发工具，点击链接即可打开

### 蓝牙配网

[点击打开微信开发者工具](https://developers.weixin.qq.com/s/Wk0aZlmg7jOR)

### 设备控制

[点击打开微信开发者工具](https://developers.weixin.qq.com/s/Kh0CMlmq77OA)

## 🏍 初始化 Sdk

```ts
import GizwitsSdk from 'mini_program_gizwits_sdk';
import { Component } from 'react';
import { View } from '@tarojs/components';

export default class Index extends Component {
  private gizSdk: GizwitsSdk;

  componentDidMount() {
    this.gizSdk = new GizwitsSdk({
      appID: 'appID',
      appSecret: 'appSecret',
      productInfo: [
        {
          productKey: 'productKey',
          productSecret: 'productSecret',
        },
      ],
      uid: 'giz_uid', // 必填
      token: 'giz_token', // 必填
    });
  }

  render() {
    return <View>hello</View>;
  }
}
```

## 📋 日志
sdk.setLogLevel("debug")

## 📖 API

小程序相关 API。

### sdk.initBle()

初始化 sdk 蓝牙能力。使用其他`BLE API`前**必须**进行初始化。

### sdk.scanBleDevice(delay?:number, services?: string[])

搜索蓝牙设备。搜索到的蓝牙设备会被 [onScanListChange](#onScanListChange) 事件监听。

#### 参数

- delay: 超时时间。
- services: 过滤services的条件，不传默认 ['ABF8', 'ABF0', 'F0AB', 'F8AB']

### sdk.startAutoScan(services?: string[])

间隔自动搜索蓝牙设备 [onScanListChange](#onScanListChange) 事件监听。

#### 参数
- services: 过滤services的条件，不传默认 ['ABF8', 'ABF0', 'F0AB', 'F8AB']

### sdk.deviceSafetyRegister(Object object)

安全注册目标设备，蓝牙设备绑定前，需要调用这个接口，否则无法发起设备绑定。返回值中可以拿到注册结果。

#### 参数

- Object object

| 属性       | 类型   | 描述               |
| ---------- | ------ | ------------------ |
| mac        | string | 待注册设备 mac     |
| productKey | string | 待注册设备所属产品 |

### sdk.bindRemoteDevice(Object object)

绑定远程设备，否则无法发起设备订阅。返回值中可以拿到绑定结果。

### sdk.unbindDevice({devices: [IDevice]})

解绑设备

#### 参数

- Object object

| 属性       | 类型   | 描述               |
| ---------- | ------ | ------------------ |
| mac        | string | 待绑定设备 mac     |
| productKey | string | 待绑定设备所属产品 |

### sdk.subscribe(device:[IDevice](#IDevice),connectType:[TConnectType](#TConnectType))

订阅目标设备，订阅成功后可控制设备。返回值中可以拿到订阅结果。

### sdk.getDeviceStatus(device:[IDevice](#IDevice), attrNames?: string[])

查询目标设备当前状态，attrNames 不传则查询所有数据

### sdk.write(device:[IDevice](#IDevice),cmd:{[key]:value})

向目标设备发送指令。 其中`key`为数据点名称，value 为数据点的值。

### sdk.unSubscribe(device:[IDevice](#IDevice))

取消订阅目标设备。蓝牙设备会断开连接。返回值中可拿到取消订阅结果。

### sdk.getDevices()
刷新设备列表(同时也会在 GizDeviceListNotifications 事件里推送)
```ts
const data = await sdk.getDevices()
console.log(data)
```

### sdk.stopDeviceOnboardingDeploy
停止配网

### sdk.setDeviceOnboardingDeploy
开始配网

详细参数请查阅类型定义

### sdk.addEventListener(type,listener)

#### 概览

| 事件种类 type               | 回调参数类型                          | 回调参数描述         |
| --------------------------- | ------------------------------------- | -------------------- |
| GizDeviceListNotifications | [IDevice[]](#IDevice) | 设备列表变更   |
| GizDeviceStatusNotifications | [IDeviceStatusNoti](#IDeviceStatusNoti) | 设备在线状态变更   |
| GizDeviceAttrsNotifications | [IDeviceAttrsNoti](#IDeviceAttrsNoti) | 设备数据点变更通知   |
| onScanListChange            | [IDevice[]](#IDevice)                 | 扫描设备列表变更通知 |
| onBleHandleError            | [IError](#IError)                     | ble 错误通知         |

- <a id="GizDeviceListNotifications"> GizDeviceListNotifications </a>

```ts
this.gizSdk.addEventListener('GizDeviceListNotifications', (deviceList: IDevice[]) => {
  console.log('列表发生变化', deviceList);
});
```

- <a id="GizDeviceStatusNotifications"> GizDeviceStatusNotifications </a>

```ts
this.gizSdk.addEventListener('GizDeviceStatusNotifications', (e: IDeviceStatusNoti) => {
  console.log('设备在线状态变化', e);
});
```

- <a id="onScanListChange">onScanListChange</a>

```ts
const initBle = () => {
  this.gizSdk.initBle();
};

const scanBle = async () => {
  const data = await this.gizSdk.scanBleDevice(60000);
  console.log('scanBle', data);
};

this.gizSdk.addEventListener('onScanListChange', (deviceList: IDevice[]) => {
  console.log('扫描列表发生变化', deviceList);
  deviceListModal.updateScan(deviceList);
});

initBle();
scanBle();
```

- <a id="GizDeviceAttrsNotifications">GizDeviceAttrsNotifications</a>

监听设备上报数据。

```ts
this.gizSdk.addEventListener(
  'GizDeviceAttrsNotifications',
  ({ device, data }) => {
    console.log("====设备状态发生变化====", device,data);
  };
);
```

#### 类型定义

- <a id="IDevice">IDevice</a>

```ts
interface IDevice {
  mac: string; // 设备mac
  productKey: string; // 机智云pk
  did?: string; // 云平台did
  name: string; // 设备名称
  isBind: boolean; // 是否绑定
  bleDeviceID?: string; // 本地蓝牙设备id
  isOnline: boolean; // 代表大循环在线
  isLanOnline: boolean; // 代表小循环在线
  isBleOnline: boolean; // 代表蓝牙在线
  bleWorkStatus?: number; // 蓝牙设备状态 0 默认状态 1 配网状态
  connectType: TConnectType; // 当前连接类型
}
```

- <a id="TConnectType">TConnectType</a>

```ts
type TConnectType = 'BLE' | 'BLE_BROADCAST' | 'LAN' | 'WAN' | 'NONE';
}
```

- <a id="IDeviceAttrsNoti">IDeviceAttrsNoti</a>

```ts
interface IDeviceAttrsNoti {
  device: IDevice;
  data: object; // 设备上报数据点
}
```

- <a id="IDeviceStatusNoti">IDeviceStatusNoti</a>

```ts
interface IDeviceStatusNoti {
  device: IDevice;
  connectType: TConnectType;
}
```

- <a id="TConnectType">TConnectType</a>

```ts
type TConnectType = 'BLE' | 'BLE_BROADCAST' | 'LAN' | 'WAN' | 'NONE';
```

- <a id="IError">IError</a>

```ts
interface IError {
  errorCode: number;
  errorMessage?: string; // 错误信息
}
```

### sdk.removeEventListener(type:K,func:TListenerType[K])

销毁事件监听。

# 配网相关

## 使用方法

```javascript
import GizwitsSdk, { errorCode } from 'mini_program_gizwits_sdk';

const configData = {
  appID: "xxx",
  appSecret: "xxx",
  productInfo: [
    {
      productKey: "xxx",
      productSecret: "xxx",
    },
  ],
};
const sdk = new GizwitsSdk(configData);

try {
  const data = await sdk.setDeviceOnboardingDeploy({
    ssid: SSID,
    password: password,
    mode: 3, // 蓝牙配网
    // mode:0 // softAp
    timeout: 60,
    softAPSSIDPrefix: 'XPG-GAgent-',
  });
} catch (error) {
  console.log(error);
}
```

其中`data`代表配网成功的设备。

如果失败的话会返回数据

```javascript
{
  success: false,
  err: {
    errorCode: 'code',
    errorMessage: 'message',
  }
}
```

```ts
const errorCode: IErrorCode = {
  GIZ_OPENAPI_DEVICE_NOT_BOUND: {
    errorCode: 9017,
    errorMessage: 'not bind',
  },
  GIZ_SDK_HTTP_REQUEST_FAILED: {
    errorCode: 8099,
    errorMessage: '网络请求失败',
  },
  GIZ_SDK_SDK_NOT_INITIALIZED: {
    errorCode: 8300,
    errorMessage: 'not init',
  },
  CONFIG_TIME_OUT: {
    errorCode: 8023,
    errorMessage: 'Config Timeout',
  },
  WECHAT_ERROR: {
    errorCode: 10000,
    errorMessage: 'wechat error',
  },
  GIZ_SDK_ONBOARDING_STOPPED: {
    errorCode: 8318,
    errorMessage: '配网中断',
  },
  GIZ_SDK_DEVICE_CONFIG_IS_RUNNING: {
    errorCode: 8022,
    errorMessage: '配置正在进行中',
  },
  GIZ_OPENAPI_TOKEN_INVALID: {
    errorCode: 9004,
    errorMessage: 'token 失效',
  },
  GIZ_SDK_BIND_DEVICE_FAILED: {
    errorCode: 8039,
    errorMessage: '设备绑定失败',
  },
  GIZ_SDK_BLE_BLUETOOTH_FUNCTION_NOT_TURNED_ON: {
    errorCode: 8281,
    errorMessage: '蓝牙未启用',
  },
  GIZ_SDK_OTHERWISE: {
    errorCode: 8100,
    errorMessage: '',
  },
  GIZ_SDK_DEVICE_NOT_SUBSCRIBED: {
    errorCode: 8029,
    errorMessage: '设备还未订阅',
  },
  GIZ_SDK_PRODUCTKEY_NOT_IN_SPECIFY: {
    errorCode: 8250,
    errorMessage: '产品类型不在指定范围内',
  },
};
```
