Flutter智能家居控制插件miio的使用

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

Flutter智能家居控制插件miio的使用

Dart实现的MiIO局域网协议。

该协议是一个基于UDP(端口54321)的加密二进制协议,用于配置和控制小米生态系统的智能家庭设备。

CLI

该包包含一个基于miio构建的简单CLI程序。

安装

  • 从Pub全局激活:
pub global activate miio
  • 从GitHub Action下载预构建的二进制文件:

示例

# 发送发现数据包到广播IP。
miio discover --ip 192.168.1.255

# 向设备发送数据包。
miio send --ip 192.168.1.100 --token ffffffffffffffffffffffffffffffff --payload '{"id": 1, "method": "miIO.info", "params": []}'

# 或者使用设备API。
# 传统方式:
miio device --ip 192.168.1.100 --token ffffffffffffffffffffffffffffffff props -p power
miio device --ip 192.168.1.100 --token ffffffffffffffffffffffffffffffff call -m set_power -p on
# MIoT规范:
miio device --ip 192.168.1.100 --token ffffffffffffffffffffffffffffffff property -s 2 -p 1
miio device --ip 192.168.1.100 --token ffffffffffffffffffffffffffffffff property -s 2 -p 1 -v true

协议

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic Number = 0x2131         | Packet Length (incl. header)  |
|-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
| Unknown                                                       |
|-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
| Device ID ("did")                                             |
|-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
| Stamp                                                         |
|-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
| MD5 Checksum                                                  |
| ... or Device Token in response to the "Hello" packet         |
|-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
| Optional variable-sized payload (encrypted)                   |
|...............................................................|


Packet Length: 16位无符号整数
    整个数据包的长度(包括头部),单位为字节。

Unknown: 32位
    这个值始终为0。
    在“Hello”数据包中为0xFFFFFFFF。

Device ID: 32位
    唯一编号。可能来源于MAC地址。
    在“Hello”数据包中为0xFFFFFFFF。

Stamp: 32位无符号整数
    持续增加的计数器。
    自设备启动以来的秒数。

MD5校验和:
    包括MD5字段本身在内的整个数据包计算得到的校验和,
    必须用令牌初始化。

    在“Hello”数据包中,
    此字段包含128位的0xFF。

    在对第一个“Hello”数据包的响应中,
    此字段包含128位的设备令牌。

可选的可变大小有效载荷:
    使用AES-128-CBC(PKCS#7填充)加密的有效载荷。

        密钥 = MD5(令牌)
        初始化向量 = MD5(密钥 + 令牌)

Flutter示例代码

以下是一个完整的Flutter示例代码,展示如何使用miio插件来控制智能设备。

首先,确保在pubspec.yaml文件中添加miio依赖项:

dependencies:
  flutter:
    sdk: flutter
  miio: ^版本号

然后,在你的Flutter应用中使用miio插件进行设备控制:

import 'package:flutter/material.dart';
import 'package:miio/miio.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _info = '未连接';

  [@override](/user/override)
  void initState() {
    super.initState();
    connectToDevice();
  }

  Future<void> connectToDevice() async {
    try {
      // 初始化MiIO客户端
      final client = MiioClient(
        ip: '192.168.1.100',
        token: 'ffffffffffffffffffffffffffffffff',
      );

      // 获取设备信息
      final info = await client.sendCommand('miIO.info', []);
      setState(() {
        _info = '$info';
      });

      // 控制设备开关
      await client.sendCommand('set_power', ['on']);
    } catch (e) {
      setState(() {
        _info = '错误: $e';
      });
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('MiIO设备控制'),
        ),
        body: Center(
          child: Text(_info),
        ),
      ),
    );
  }
}

更多关于Flutter智能家居控制插件miio的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter智能家居控制插件miio的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter应用中集成智能家居控制插件miio,可以让你通过Flutter应用与小米智能设备(以及其他支持MiOT协议的设备)进行通信。以下是一个简单的代码示例,展示了如何使用miio插件来控制小米智能设备。

首先,确保你的Flutter项目已经配置好,并且已经添加了miio依赖。在pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  miio: ^x.y.z  # 请替换为实际的版本号

然后运行flutter pub get来安装依赖。

接下来,你可以创建一个Flutter页面,用于展示和控制小米智能设备。以下是一个简单的示例代码:

import 'package:flutter/material.dart';
import 'package:miio/miio.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter MiIO Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MiIOControlPage(),
    );
  }
}

class MiIOControlPage extends StatefulWidget {
  @override
  _MiIOControlPageState createState() => _MiIOControlPageState();
}

class _MiIOControlPageState extends State<MiIOControlPage> {
  MiioDevice? _device;
  String _status = "Not Connected";

  @override
  void initState() {
    super.initState();
    _connectToDevice();
  }

  Future<void> _connectToDevice() async {
    try {
      // 替换为你的设备的IP地址和token
      String deviceIp = "192.168.1.100";
      String deviceToken = "your_device_token_here";

      _device = MiioDevice(deviceIp, deviceToken);
      bool isConnected = await _device!.connect();
      if (isConnected) {
        setState(() {
          _status = "Connected";
        });
        // 获取设备状态(示例:开关状态)
        String powerState = await _device!.sendCommand('get_prop', ['power']);
        print("Power State: $powerState");
      } else {
        setState(() {
          _status = "Failed to Connect";
        });
      }
    } catch (e) {
      print("Error connecting to device: $e");
      setState(() {
        _status = "Error: $e";
      });
    }
  }

  Future<void> _togglePower() async {
    if (_device != null && _device!.isConnected()) {
      try {
        // 发送命令切换电源状态
        bool powerState = await _device!.sendCommand('set_power', ['on' == (await _device!.sendCommand('get_prop', ['power'])) ? 'off' : 'on']);
        print("Power State toggled to: $powerState");
      } catch (e) {
        print("Error toggling power: $e");
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MiIO Device Control'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Device Status: $_status',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _togglePower,
              child: Text('Toggle Power'),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项:

  1. 设备IP和Token:在代码中,你需要替换deviceIpdeviceToken为你的实际设备IP地址和token。设备token可以通过小米智能家居APP或其他工具获取。

  2. 依赖库版本:确保你使用的miio库版本是最新的,或者与你的Flutter环境兼容的版本。

  3. 设备兼容性miio库主要支持小米的智能设备,但也可能支持其他遵循MiOT协议的设备。请查阅miio库的文档以获取更多信息。

  4. 错误处理:在实际应用中,你应该添加更多的错误处理逻辑,以处理设备连接失败、命令发送失败等情况。

  5. UI设计:上述示例代码仅用于演示目的,实际应用中你可能需要设计更友好的用户界面。

通过上述代码,你可以在Flutter应用中实现对小米智能设备的基本控制。根据需要,你可以进一步扩展功能,如获取更多设备属性、发送更多控制命令等。

回到顶部