Flutter集成Dooz网关服务插件dooz_gateway_sdk的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter集成Dooz网关服务插件dooz_gateway_sdk的使用

在本教程中,我们将展示如何在Flutter项目中集成并使用dooz_gateway_sdk插件来与DooZ网关服务进行交互。该插件允许开发者通过IP-BT网关控制DooZ的mesh网络。

插件简介

dooz_gateway_sdk 是一个Dart SDK,用于与DooZ的ooPLA产品(IP-BT网关)进行交互,并支持对DooZ mesh网络的控制。


步骤1:添加依赖

首先,在您的pubspec.yaml文件中添加dooz_gateway_sdk作为依赖项:

dependencies:
  dooz_gateway_sdk: ^1.0.0

然后运行以下命令以安装依赖:

flutter pub get

步骤2:初始化和连接网关

以下是一个完整的示例代码,展示如何初始化DoozGateway对象并建立与网关的连接。

示例代码

// 忽略打印警告
// ignore_for_file: avoid_print

import 'dart:math';

import 'package:dooz_gateway_sdk/dooz_gateway_sdk.dart';

void main() async {
  // 实例化DoozGateway对象
  final gateway = DoozGateway();

  // 监听来自网关的状态更新
  gateway.notifyState.listen(print);

  // 使用WAN模式连接到网关
  await gateway.connect(
    _gatewayID, // 网关ID
    overWAN: true,
    host: _host, // 网关主机地址
  );

  try {
    print('------------- AUTH -------------');

    // 尝试通过服务器认证
    AuthResponse authResult;
    var authTries = 0;

    do {
      authResult = await gateway
          .authenticate(
            _serverUser, // 服务器用户名
            _serverPassword, // 服务器密码
          )
          .catchError(
            (Object e) => const AuthResponse('refused', 0),
            test: (e) => e is OoplaRequestTimeout,
          );
      authTries++;
      print('尝试 #$authTries : $authResult');

      if (authResult.status == 'OK') break;
    } while (authTries < 3);

    final authSuccess = authResult.status == 'OK';
    if (authSuccess) {
      print('成功通过用户凭证认证,共尝试了 $authTries 次!');
      print('--------------------------------\n');
      await _testScript(gateway);
    } else {
      print('服务器认证失败...回退到本地认证');
      await gateway.disconnect();
      await gateway.connect(_gatewayID);
      authTries = 0;

      do {
        authResult = await gateway
            .authenticate(
              _gatewayUser, // 网关用户名
              _gatewayPassword, // 网关密码
            )
            .catchError(
              (Object e) => const AuthResponse('refused', 0),
              test: (e) => e is OoplaRequestTimeout,
            );
        print(authResult);
        authTries++;
        if (authResult.status == 'OK') break;
      } while (authTries < 3);

      if (authResult.status == 'OK') {
        print('成功通过网关凭证认证!');
        print('--------------------------------\n');
        await _testScript(gateway);
      } else {
        print('无法完成网关认证...');
        print('--------------------------------\n');
      }
    }
  } catch (e) {
    print('捕获错误...$e');
  }

  // 断开与网关的连接
  await gateway.disconnect();
}

// 测试脚本
Future<void> _testScript(DoozGateway gateway) async {
  await _testLogs(gateway);
  await _testVersions(gateway);
  await _testDiscovers(gateway);
  await _testControls(gateway);
  await _testScenarios(gateway);
}

// 测试日志设置
Future<void> _testLogs(DoozGateway gateway) async {
  print('------------- LOGS -------------');
  print('将所有ooPLA的日志级别设置为调试...');
  print(await gateway.setLogLevel(LogLevel.debug));
  print('--------------------------------\n');
}

// 测试版本信息
Future<void> _testVersions(DoozGateway gateway) async {
  print('----------- VERSIONS -----------');
  final softwareVersionResponse = await gateway.getSoftwareVersion();
  print('ooPLA的软件版本是 v${softwareVersionResponse.version}');
  final hardwareVersionResponse = await gateway.getHardwareVersion();
  print('ooPLA的硬件版本是 v${hardwareVersionResponse.hw_version}');
  final modulesVersionsResponse = await gateway.getModulesVersion();
  for (final moduleVersion in modulesVersionsResponse.versions) {
    print('ooPLA的 ${moduleVersion.keys.first} 版本是 v${moduleVersion.values.first}');
  }
  print('--------------------------------\n');
}

// 测试发现功能
Future<void> _testDiscovers(DoozGateway gateway) async {
  print('----------- DISCOVERS -----------');
  await gateway.discoverScenes();
  final rooms = await gateway.discoverRooms();
  for (final room in rooms.rooms.entries) {
    print('房间ID: ${room.key}, 房间名称: ${room.value['name']}');
    await gateway.getNodesInRoomName(room.value['name'] as String);
  }
  await gateway.discoverGroups();
  await gateway.discover();
  print('--------------------------------\n');
}

// 测试控制功能
Future<void> _testControls(DoozGateway gateway) async {
  print('------------ CONTROLS ------------');
  final dooblvs = await _searchDooblvs(gateway, getAll: true);
  if (dooblvs.isNotEmpty) {
    print(dooblvs);
    await _playWithDooblv(dooblvs.first, gateway);
  } else {
    print('未发现当前已配置的DooBLV设备...');
  }
  print('--------------------------------\n');
}

// 搜索DooBLV设备
Future<List<MapEntry<String, dynamic>>> _searchDooblvs(DoozGateway gateway, {bool getAll = false}) async {
  final discover = await gateway.discover();
  final dooblvs = <MapEntry<String, dynamic>>[];
  for (final discoveredNode in discover.mesh.entries) {
    if (discoveredNode.value['type'] == 0x0A &&
        dooblvs.every((dooblv) => dooblv.key != discoveredNode.value['mac_address'])) {
      print('发现网络中的一个DooBLV设备!');
      dynamic confState = discoveredNode.value['conf state'];
      if (confState != 'CONFIGURED') {
        print('但其未报告为已配置状态...(配置状态: $confState)');
      } else {
        dooblvs.add(discoveredNode);
        if (!getAll) {
          break;
        }
      }
    } else {
      print('发现节点ID ${discoveredNode.value['type']} 地址为 ${discoveredNode.key}');
    }
  }
  return dooblvs;
}

// 控制DooBLV设备
Future<void> _playWithDooblv(MapEntry<String, dynamic> firstDooblv, DoozGateway gateway) async {
  final dooblvUnicast = firstDooblv.key;
  print('发现返回的DooBLV设备unicast地址为 $dooblvUnicast!让我们开始玩吧 :D');
  final elements = firstDooblv.value['nodes'] as List;
  assert(elements.length == 4, 'DooBLV设备元素的JSON结构不符合预期');
  final lightElements = elements.getRange(0, 2);
  assert(lightElements.every((dynamic element) => element['output conf'] == 0 || element['output conf'] == 1),
      '元素未按预期配置为灯光...');
  final firstLightAddress = lightElements.first['address'] as String;
  final secondLightAddress = lightElements.last['address'] as String;

  await _lightsToX(gateway, firstLightAddress, secondLightAddress, 50);
  await _shutDownDooblv(gateway, firstLightAddress, secondLightAddress);
  await _lightsRawLevels(gateway, firstLightAddress, secondLightAddress);
  await _shutDownDooblv(gateway, firstLightAddress, secondLightAddress);
  var ioConfigs = await _getIoConfigs(gateway, dooblvUnicast);
  print(ioConfigs);
  await _revertIoConfigs(ioConfigs, gateway, dooblvUnicast);
  ioConfigs = await _getIoConfigs(gateway, dooblvUnicast);
  print(ioConfigs);
  await _revertIoConfigs(ioConfigs, gateway, dooblvUnicast);
  ioConfigs = await _getIoConfigs(gateway, dooblvUnicast);
  print(ioConfigs);
}

// 设置灯光亮度
Future<void> _lightsToX(DoozGateway gateway, String firstLightAddress, String secondLightAddress, int level) async {
  print('发送 $level% 的亮度设置到 $firstLightAddress');
  var setResponse = await gateway.sendLevel(firstLightAddress, level);
  print(setResponse);
  await Future<void>.delayed(const Duration(milliseconds: 500));
  print('发送 $level% 的亮度设置到 $secondLightAddress');
  setResponse = await gateway.sendLevel(secondLightAddress, level);
  print(setResponse);
  await Future<void>.delayed(const Duration(milliseconds: 500));
}

// 关闭灯光
Future<void> _shutDownDooblv(DoozGateway gateway, String firstLightAddress, String secondLightAddress) async {
  print('发送关闭指令到 $firstLightAddress');
  var setResponse = await gateway.sendLevel(firstLightAddress, 'off');
  print(setResponse);
  await Future<void>.delayed(const Duration(milliseconds: 500));
  print('发送关闭指令到 $secondLightAddress');
  setResponse = await gateway.sendLevel(secondLightAddress, 'off');
  print(setResponse);
  await Future<void>.delayed(const Duration(milliseconds: 500));
}

// 设置灯光原始值
Future<void> _lightsRawLevels(DoozGateway gateway, String firstLightAddress, String secondLightAddress) async {
  final max = 32767.toRadixString(16).toUpperCase();
  final min = (-32000).toRadixString(16).toUpperCase();
  print('发送最大值 $maxh 到 $firstLightAddress');
  var setRawResponse = await gateway.sendRaw(firstLightAddress, max);
  print(setRawResponse);
  await Future<void>.delayed(const Duration(milliseconds: 500));
  print('发送最大值 $maxh 到 $secondLightAddress');
  setRawResponse = await gateway.sendRaw(secondLightAddress, max);
  print(setRawResponse);
  await Future<void>.delayed(const Duration(milliseconds: 500));
  print('发送最小值 $minh 到 $firstLightAddress');
  setRawResponse = await gateway.sendRaw(firstLightAddress, min);
  print(setRawResponse);
  await Future<void>.delayed(const Duration(milliseconds: 500));
  print('发送最小值 $minh 到 $secondLightAddress');
  setRawResponse = await gateway.sendRaw(secondLightAddress, min);
  print(setRawResponse);
  await Future<void>.delayed(const Duration(milliseconds: 500));
}

// 获取IO配置
Future<Map<int, Map<String, int>>> _getIoConfigs(DoozGateway gateway, String dooblvUnicast) async {
  final ioConfigs = {
    0: <String, int>{'input': -1, 'output': -1},
    1: <String, int>{'input': -1, 'output': -1},
  };
  final r = Random();
  var getConfig = await gateway.getConfig(
      dooblvUnicast,
      0,
      1,
      int.parse(dooblvUnicast, radix: 16) + r.nextInt(1 << 15));
  print(getConfig);
  ioConfigs[0]!['output'] = getConfig.value;
  getConfig = await gateway.getConfig(
      dooblvUnicast,
      0,
      2,
      int.parse(dooblvUnicast, radix: 16) + r.nextInt(1 << 15));
  print(getConfig);
  ioConfigs[0]!['input'] = getConfig.value;
  getConfig = await gateway.getConfig(
      dooblvUnicast,
      1,
      1,
      int.parse(dooblvUnicast, radix: 16) + r.nextInt(1 << 15));
  print(getConfig);
  ioConfigs[1]!['output'] = getConfig.value;
  getConfig = await gateway.getConfig(
      dooblvUnicast,
      1,
      2,
      int.parse(dooblvUnicast, radix: 16) + r.nextInt(1 << 15));
  print(getConfig);
  ioConfigs[1]!['input'] = getConfig.value;
  return ioConfigs;
}

// 修改IO配置
Future<void> _revertIoConfigs(Map<int, Map<String, int>> ioConfigs, DoozGateway gateway, String dooblvUnicast) async {
  final r = Random();
  for (final ioConfig in ioConfigs.entries) {
    switch (ioConfig.value['input']) {
      case 0:
        print('输入端口 ${ioConfig.key} 配置为开关,改为按钮...');
        print(await gateway.setConfig(
            dooblvUnicast, ioConfig.key, 2, 1, int.parse(dooblvUnicast, radix: 16) + r.nextInt(1 << 15)));
        break;
      case 1:
        print('输入端口 ${ioConfig.key} 配置为按钮,改为开关...');
        print(await gateway.setConfig(
            dooblvUnicast, ioConfig.key, 2, 0, int.parse(dooblvUnicast, radix: 16) + r.nextInt(1 << 15)));
        break;
    }
    switch (ioConfig.value['output']) {
      case 0:
        print('输出端口 ${ioConfig.key} 配置为开关,改为调光器...');
        print(await gateway.setConfig(
            dooblvUnicast, ioConfig.key, 1, 1, int.parse(dooblvUnicast, radix: 16) + r.nextInt(1 << 15)));
        break;
      case 1:
        print('输出端口 ${ioConfig.key} 配置为调光器,改为开关...');
        print(await gateway.setConfig(
            dooblvUnicast, ioConfig.key, 1, 0, int.parse(dooblvUnicast, radix: 16) + r.nextInt(1 << 15)));
        break;
    }
  }
}

// 测试场景功能
Future<void> _testScenarios(DoozGateway gateway) async {
  print('----------- SCENARIOS -----------');
  final scenes = await gateway.discoverScenes();
  final nodeIDs = <int>[];
  for (final scene in scenes.scenes.values.first.scenes) {
    print('-------- 场景#${scene.sceneId} --------');
    if (scene.sceneId == 0 || scene.sceneId == 1) {
      nodeIDs.addAll(scene.steps.map((s) => s.equipment.nodeId));
    }
    print(scene.name);
    print(scene.steps.length);
    print(scene.start);
    print(scene.end);
    // await gateway.startScenario(scene.sceneId);
    print('--------------------------');
  }
  if (nodeIDs.isNotEmpty) {
    // 假设第一个节点是DooBLV,并且目标是根unicast+3,这是包含场景服务器的元素
    final firstScenarioServerAddress = (nodeIDs.first + 3).toRadixString(16).toUpperCase().padLeft(4, '0');
    // 获取当前存储的epoch时间
    await gateway.getEpoch(firstScenarioServerAddress);
    // 更新存储的epoch时间
    await gateway.setEpoch(firstScenarioServerAddress, io: 0);
    await gateway.setEpoch(firstScenarioServerAddress, io: 1);
    // 检查当前存储的epoch时间
    await gateway.getEpoch(firstScenarioServerAddress);
    // 在检测到的DooBLV上设置新场景
    final daysInWeek = [
      'monday',
      'tuesday',
      'wednesday',
      'thursday',
      'friday',
      'saturday',
      'sunday',
    ];
    await gateway.setScenario(
      firstScenarioServerAddress,
      3,
      75,
      daysInWeek: daysInWeek,
      startAt: '16h15',
      duration: '0h15',
    );
    await gateway.setScenario(
      firstScenarioServerAddress,
      3,
      75,
      output: 1,
      daysInWeek: daysInWeek,
      startAt: '16h15',
      duration: '0h15',
    );
    // 检查场景描述
    await gateway.getScenario(firstScenarioServerAddress, 3);
    // 启动新创建的场景
    await gateway.startScenario(3);
    // 关闭灯光
    await gateway.sendLevel((nodeIDs.first + 1).toRadixString(16).toUpperCase().padLeft(4, '0'), 'off');
    await gateway.sendLevel((nodeIDs.first + 2).toRadixString(16).toUpperCase().padLeft(4, '0'), 'off');
  }
}

更多关于Flutter集成Dooz网关服务插件dooz_gateway_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter集成Dooz网关服务插件dooz_gateway_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


要在Flutter应用中集成Dooz网关服务插件 dooz_gateway_sdk,你可以按照以下步骤进行操作:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 dooz_gateway_sdk 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  dooz_gateway_sdk: ^1.0.0  # 请根据实际情况填写版本号

然后运行 flutter pub get 来获取依赖。

2. 初始化 SDK

在你的 Flutter 应用中,首先需要初始化 dooz_gateway_sdk。通常,你可以在 main.dart 文件中进行初始化。

import 'package:dooz_gateway_sdk/dooz_gateway_sdk.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化 Dooz Gateway SDK
  await DoozGatewaySdk.initialize(
    apiKey: 'YOUR_API_KEY',  // 替换为你的 API Key
    environment: Environment.production,  // 或者 Environment.sandbox
  );

  runApp(MyApp());
}

3. 使用 SDK 功能

根据 dooz_gateway_sdk 提供的功能,你可以在应用中使用它。以下是一些常见的操作示例:

3.1 创建网关会话

void createGatewaySession() async {
  try {
    final session = await DoozGatewaySdk.createSession(
      amount: 1000,  // 金额
      currency: 'USD',  // 货币类型
      customerEmail: 'customer@example.com',  // 客户邮箱
    );
    print('Session created: ${session.id}');
  } catch (e) {
    print('Error creating session: $e');
  }
}

3.2 处理支付结果

void handlePaymentResult(String sessionId) async {
  try {
    final result = await DoozGatewaySdk.getPaymentResult(sessionId);
    if (result.status == PaymentStatus.success) {
      print('Payment successful!');
    } else {
      print('Payment failed: ${result.message}');
    }
  } catch (e) {
    print('Error handling payment result: $e');
  }
}

4. 处理回调

如果你的应用需要处理支付回调,你可以在 DoozGatewaySdk 中设置回调监听器。

void setupCallbackListener() {
  DoozGatewaySdk.setPaymentCallbackListener((result) {
    if (result.status == PaymentStatus.success) {
      print('Payment successful!');
    } else {
      print('Payment failed: ${result.message}');
    }
  });
}

5. 清理资源

在应用退出时,确保清理 SDK 资源。

void dispose() {
  DoozGatewaySdk.dispose();
}

6. 处理错误

在使用 SDK 时,确保处理可能出现的错误,例如网络错误、认证错误等。

try {
  // 调用 SDK 方法
} catch (e) {
  print('An error occurred: $e');
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!