支持设备
  • AECC 智能采集器(工业/商业场景中的数据采集与远程监控智能硬件)
  • 所有使用能控云蓝牙模块的产品(CT电表、红外读表器、P1电表、智能插座、Linky读表器等)
1 方案概述

1.1 背景与目标

AECC 智能采集器是一款用于工业/商业场景中数据采集与远程监控的智能硬件设备。为了让终端用户能够快速将采集器接入自有 App,我们提供了覆盖原生 Android、原生 iOS、Flutter、UniApp 四大主流平台的 SDK 解决方案。

通过本方案,开发者可以:
  • 通过蓝牙与 AECC 采集器建立安全通信
  • 完成采集器的 WiFi 配网(连接路由器 + 连接云端 Server)
  • 远程设置和读取采集器寄存器参数
  • 实时监控采集器与路由器、Server 的通信状态

1.2 方案架构流程

本方案采用分层架构设计,整体数据流转如下:

第五层:云端服务层 云端 Server 负责接收、存储和处理采集器上传的数据,供业务系统调用。
第四层:采集器设备层 AECC 智能采集器内部包含以下功能模块:
  • 蓝牙通信模块:接收 App 指令,返回执行结果
  • WiFi 路由模块:连接局域网路由器
  • 数据采集模块:读取传感器或设备数据
  • 云端通信模块:通过 WiFi/4G 将数据上传至云端
第三层:蓝牙通信 SDK 核心层通过 BLE(蓝牙低功耗)与 AECC 智能采集器建立连接,实现:
  • 设备发现与配对
  • 指令下发与数据接收
  • 配网参数传递
第二层:SDK 核心层 所有平台的 SDK 底层均基于 Setnet-SDK 核心层,负责:
  • 协议组包与解包(0x18/0x19 指令)
  • 数据加密与解密
  • 蓝牙通信管理
第一层:终端 App 层 开发者根据技术栈选择对应平台的 SDK 接入方式:
  • 原生 Android:使用 AAR/JAR 包直接集成
  • 原生 iOS:使用 Setnet_SDK.framework 集成
  • Flutter:通过原生插件(Platform Channel)桥接
  • UniApp:通过原生插件集成,需在 manifest.json 中配置
2 核心功能

2.1 蓝牙通信

SDK 提供完整的蓝牙低功耗(BLE)通信能力:设备自动扫描与连接、加密数据传输、0x18/0x19 指令协议组包/解包。

2.2 WiFi 配网

通过蓝牙通道为采集器配置 WiFi:扫描周围可用路由器、传入 SSID 和密码、实时反馈配网进度和结果。

2.3 参数设置与读取

通过标准化的寄存器机制:0x18 指令向采集器写入寄存器,0x19 指令从采集器读取寄存器。

2.4 状态监控

两个关键状态寄存器用于监控网络连接状况:寄存器 55(路由器状态)、寄存器 60(Server 状态)。

3 接入指南

3.1 前置准备

在开始集成前,请确保:
  1. 获取 SDK 包和授权:联系 NKY 方获取最新版 SDK 包、秘钥及授权码
  2. 获取示例工程:联系 NKY 方获取对应平台的 Demo 示例工程
  3. 开发环境:确保开发环境满足上述平台版本要求

3.2 Android 原生接入

步骤一:引入 SDK

将 SDK 提供的 AAR/JAR 包放入项目的 libs 目录,并在 build.gradle 中添加依赖。

步骤二:组包 — 发送 0x18 设置指令

// 调用 ProtocolTool 类的 setDatalogerByP0x18() 方法
JSONObject params = new JSONObject();
// 构造参数(具体格式参见数据定义章节)
params.put("commandId", "18");
// ... 构造 param18Obj 数组
byte[] result = ProtocolTool.setDatalogerByP0x18(params, new byte[]{});
// 将 result 强转为 Object 后通过蓝牙发送
返回格式:
{"code": 0, "data": "XXXXX"}

步骤三:解包 — 解析 0x18 响应

// 调用 ProtocolTool 类的 parserPro0x18() 方法
boolean success = ProtocolTool.parserPro0x18(bluetoothData, new boolean());
// 返回 true 表示设置成功

步骤四:组包 — 发送 0x19 读取指令

// 调用 ProtocolTool 类的 getDatalogerByP0x19() 方法
byte[] result = ProtocolTool.getDatalogerByP0x19(params, new Object());
// 通过蓝牙发送读取请求

步骤五:解包 — 解析 0x19 响应

// 调用 ProtocolTool 类的 parserPro0x19() 方法
List<Param> paramList = ProtocolTool.parserPro0x19(bluetoothData, new Object());
// 遍历结果
for (Param param : paramList) {
    String value = param.readParamValueText();  // 读取到的值
}
读取周围 WiFi 路由器示例:
{
  "code": 0,
  "data": [{
    "paramNo": 75,
    "value": "[{\"signalStrength\":217,\"ssid\":\"TPshuoxd\"},{\"signalStrength\":217,\"ssid\":\"shuoxd\"},...]"
  }]
}
读取设备状态示例:
// 采集器与路由器状态
{"code": 0, "data": [{"paramNo": 55, "value": "4"}]}
// 采集器与 Server 状态
{"code": 0, "data": [{"paramNo": 60, "value": "4"}]}

3.3 iOS 原生接入

步骤一:引入 SDK

Setnet_SDK.framework 添加到 Xcode 工程,并在 Build Phases 中链接。

步骤二:引入头文件

#import <Setnet_SDK/SetnetManager.h>

步骤三:组包 — 0x18 设置指令

NSDictionary *params = @{
    @"commandId": @"18",
    @"param18Obj": @[
        @{@"paramId": @"寄存器地址", @"param": @"传输的数据"},
        // ... 更多参数
    ]
};
[[SetnetManager sharedInstance] enCodeWithParams:params block:^(NSDictionary * _Nonnull encryptionDataDic) {
    // encryptionDataDic[@"result"] => @"0" 成功, @"1" 失败
    // encryptionDataDic[@"data"] => 打包好的 NSData
}];

步骤四:组包 — 0x19 读取指令

NSDictionary *params = @{
    @"commandId": @"19",
    @"param19Obj": @[@"寄存器地址 1", @"寄存器地址 2"]
};
[[SetnetManager sharedInstance] enCodeWithParams:params block:^(NSDictionary * _Nonnull encryptionDataDic) {
    // 同上处理
}];

步骤五:解包 — 解析蓝牙返回数据

[[SetnetManager sharedInstance] DeCodeWithInputData:bluetoothData block:^(NSDictionary * _Nonnull decryptDataDic) {
    // decryptDataDic[@"result"] => @"0" 成功
    // decryptDataDic[@"msg"] => @"Set successfully" / @"Read successful"
    // decryptDataDic[@"data"] => @{@"57": xxxxx, @"58": xxxxx}
    // decryptDataDic[@"commandId"] => @"18" 或 @"19"
}];

3.4 Flutter 接入

步骤一:获取插件

联系 NKY 方获取 Flutter 平台插件包。

步骤二:集成插件

将插件添加到 pubspec.yamldependencies 中。

步骤三:调用 SDK

具体调用方式请参考 Demo 示例工程(联系 NKY 获取)。Flutter 插件内部封装了 Android/iOS 原生 SDK 的调用逻辑,通过 Platform Channel 桥接。

3.5 UniApp 接入

步骤一:工程配置

1. 将 SDK 压缩文件解压后放入项目的对应目录。
2. 在 manifest.json 中配置 SDK 插件信息(注意 id 要跟文件名对应):
{
  "app-plus": {
    "distribute": {
      "sdkConfigs": {
        // SDK 插件配置
      }
    }
  }
}

步骤二:打自定义基座

配置完成后,必须先打自定义基座,才能调用蓝牙 SDK 相关功能。

步骤三:Android 端使用

// 1. 引入 SDK 模块
const aeccSdk = uni.requireNativePlugin('AECC-SDK-PluginName');

// 2. 组包 — 0x18 设置
let setResult = aeccSdk.setDatalogerByP0x18(params);
// 返回: {"code": 0, "data": "0018000600100119dea56a1b17c8bb99..."}

// 3. 组包 — 0x19 读取
let readResult = aeccSdk.getDatalogerByP0x19(params);
// 返回: {"code": 0, "data": "00280006001501187168c19339b8afd61d..."}

// 4. 解析 — 0x18 响应
let parseSetResult = aeccSdk.parserPro0x18(bluetoothResponse);
// 返回: {"code": 0, "data": true}

// 5. 解析 — 0x19 响应
let parseReadResult = aeccSdk.parserPro0x19(bluetoothResponse);
// 返回: {"code": 0, "data": [{"paramNo": 60, "value": "4"}]}

步骤四:iOS 端使用

iOS 端调用方式与 Android 类似,组包和解析逻辑可参考 Android 示例。SDK 在 iOS 端同样基于 Setnet_SDK.framework 封装。
4 配网流程

4.1 配网整体流程

配网过程共分为 6 个步骤,按以下顺序依次执行:

  • 1
    蓝牙连接
  • 2
    扫描周围 WiFi
  • 3
    下发 WiFi 配置
  • 4
    验证路由器连接
  • 5
    验证 Server 连接
  • 6
    配网完成

4.2 配网详细步骤

第一步:蓝牙连接

App 通过蓝牙扫描并连接 AECC 采集器,需要用户授权蓝牙和定位权限(Android)。

第二步:扫描周围 WiFi

通过 0x19 指令读取寄存器 75,请求采集器扫描周围可用的 WiFi 路由器。采集器将扫描结果(包含 SSID 和信号强度)通过蓝牙返回给 App。

请求参数:
{
  "commandId": "19",
  "param19Obj": [75]
}
返回示例:
{
  "code": 0,
  "data": [{
    "paramNo": 75,
    "value": "[{\"signalStrength\":217,\"ssid\":\"MyRouter\"},{\"signalStrength\":200,\"ssid\":\"OfficeWiFi\"}]"
  }]
}

第三步:下发 WiFi 配置

通过 0x18 指令将选定的 WiFi SSID 和密码写入采集器。采集器收到配置后自动尝试连接路由器。

第四步:验证路由器连接状态

通过 0x19 指令读取寄存器 55,查询采集器与路由器的连接状态。返回值为 0 表示连接成功,其他值请参考状态码表进行排查。

第五步:验证 Server 连接状态

通过 0x19 指令读取寄存器 60,查询采集器与云端 Server 的连接状态。返回值为 3416 均表示连接成功。

第六步:配网完成

两个状态均验证成功后,采集器已通过 WiFi 接入局域网并连接云端 Server,数据上传通道正式建立,配网流程结束。

5 通信协议数据定义

5.1 指令概览

指令 功能 方向
0x18 设置参数 — 向采集器寄存器写入数据 App → 采集器
0x19 读取参数 — 从采集器寄存器读取数据 App → 采集器

5.2 0x18 指令数据格式(设置)

用于向采集器写入参数,支持同时设置多个寄存器。

请求参数结构:
{
  "commandId": "18",
  "param18Obj": [
    {
      "paramId": "寄存器地址",
      "param": "传输的数据"
    }
  ]
}

当需要设置多个参数时,在 param18Obj 数组中追加更多对象即可。

成功返回(组包):
{"code": 0, "data": "XXXXX"}
解析返回:
{"code": 0, "data": true}

5.3 0x19 指令数据格式(读取)

用于从采集器读取参数,支持同时读取多个寄存器。

请求参数结构:
{
  "commandId": "19",
  "param19Obj": ["寄存器地址 1", "寄存器地址 2"]
}
成功返回(组包):
{"code": 0, "data": "XXXXX"}
解析返回(读取状态):
{"code": 0, "data": [{"paramNo": 55, "value": "4"}]}
解析返回(读取 WiFi 列表):
{
  "code": 0,
  "data": [{
    "paramNo": 75,
    "value": "[{\"signalStrength\":217,\"ssid\":\"TPshuoxd\"},...]"
  }]
}

5.4 关键寄存器地址表

寄存器地址 功能 读/写 说明
55 采集器与路由器通讯状态 Read 0 表示连接成功,其他值请参考状态码表进行排查
60 采集器与 Server 通讯状态 Read 3、4、16 均表示连接成功
75 扫描周围 WiFi 路由器 Read 返回包含 SSID 和 signalStrength 的 WiFi 列表
6 状态码参考

6.1 寄存器 55 — 采集器与路由器通讯状态

状态码 含义 处理建议
0 连接成功 进入下一步
199 获取 IP 中 属于正常中间状态,等待 3-5 秒后重新查询
其他 连接失败 检查 WiFi 密码、信号强度、与路由器距离(建议<10米)

6.2 寄存器 60 — 采集器与 Server 通讯状态

状态码 含义 处理建议
3 连接成功 配网完成
4 连接成功 配网完成
16 连接成功 配网完成
其他 连接失败/等待中 依次检查:(1) 路由器是否已连接互联网;(2) 云端 Server 是否正常运行;(3) 采集器固件版本是否匹配
7 集成最佳实践

7.1 权限配置

Android

  • BLUETOOTH / BLUETOOTH_ADMIN
  • ACCESS_FINE_LOCATION (蓝牙扫描需要定位权限,Android 6.0+)
  • ACCESS_WIFI_STATE / CHANGE_WIFI_STATE

iOS

  • NSBluetoothAlwaysUsageDescription
  • 如需后台蓝牙:NSBluetoothPeripheralUsageDescription

7.2 用户体验建议

  1. 配网引导:提供分步引导界面,每步完成后自动进入下一步
  2. 状态反馈:配网过程中实时展示当前步骤和等待状态(如"正在连接路由器...")
  3. 错误处理:针对每种错误状态码提供明确的用户提示和修复建议
  4. 超时机制:查询状态时设置合理的轮询间隔(建议 2-3 秒)和超时时间(建议 30 秒)
  5. 重试机制:配网失败时提供一键重试功能

7.3 安全建议

  1. 授权管理:秘钥和授权码需妥善保管,不要硬编码在前端代码中
  2. 蓝牙安全:确保蓝牙通信使用 SDK 内置的加密机制
  3. WiFi 安全:建议使用 WPA2 及以上安全等级的 WiFi 网络
  4. 传输安全:采集器与 Server 之间的通信应使用 TLS 加密
8 常见问题(FAQ)
Q1:SDK 支持哪些蓝牙协议?
A:SDK 基于 Modbus 协议与采集器通信。
Q2:配网时采集器距离路由器有要求吗?
A:建议配网时采集器与路由器距离不超过 10 米,确保信号强度充足。
Q3:0x18 指令可以同时设置多个寄存器吗?
A:可以。在 param18Obj 数组中添加多个 {paramId, param} 对象即可。
Q4:UniApp / Flutter 需要打基座吗?
A:是的。两个跨平台方案都需要打自定义基座后才能使用蓝牙 SDK 功能。
Q5:如何获取 SDK 和授权码?
A:请联系 NKY 方获取最新版 SDK 包、秘钥、授权码以及对应平台的 Demo 示例工程。
Q6:寄存器 55 返回 199 怎么处理?
A:199 表示采集器正在获取 IP 地址,属于正常中间状态。建议等待 3-5 秒后重新查询。
Q7:寄存器 60 长时间没有返回成功值怎么办?
A:请依次检查:(1) 路由器是否已连接互联网;(2) 云端 Server 是否正常运行;(3) 采集器固件版本是否匹配。
👉 联系 NKY 获取最新版 SDK 包、秘钥、授权码以及 Demo 示例工程 👈
联系我们