Flutter物联网通信插件flutter_thingspeak的使用

Flutter物联网通信插件flutter_thingspeak的使用

Flutter ThingSpeak 是一个Dart包,提供了与ThingSpeak频道交互的客户端。它涵盖了ThingSpeak API的所有功能,使用户能够更新频道信息、获取和分析数据流,并查询公共频道。该插件兼容托管在 api.thingspeak.com 的ThingSpeak服务器以及自托管的开源服务器。

开始使用

要使用此插件,你需要在项目的 pubspec.yaml 文件中添加 flutter_thingspeak 作为依赖项:

dependencies:
  flutter_thingspeak: ^1.1.0

然后运行以下命令以获取依赖项:

dart pub get

使用示例

以下是一个简单的示例代码,展示了如何初始化 FlutterThingspeakClient 并从ThingSpeak通道获取所有数据:

import 'package:flutter_thingspeak/flutter_thingspeak.dart';

void main() async {
  final flutterThingspeak = FlutterThingspeakClient(channelID: '12397');

  // 初始化客户端
  flutterThingspeak.initialize();

  // 获取ThingSpeak通道的数据
  final result = await flutterThingspeak.getAllData();
  print(result);
}

查询参数

这些是可选的查询参数,可以在请求ThingSpeak API时包含在 [options] 参数中。它们允许你根据特定标准自定义响应。

  • results: 要检索的条目数。最大数量为8000。
  • days: 包含在响应中的天数。默认为1。
  • minutes: 包含在响应中的分钟数。默认为1440。
  • start: 开始日期,格式为 YYYY-MM-DD%20HH:NN:SS
  • end: 结束日期,格式为 YYYY-MM-DD%20HH:NN:SS
  • timezone: 此请求的时间区域标识符。
  • offset: 结果显示的时间区域偏移量。使用 timezone 参数可以获得更高的准确性。
  • status: 通过设置 "status=true" 包含状态更新。
  • metadata: 通过设置 "metadata=true" 包含频道元数据。
  • location: 通过设置 "location=true" 包含纬度、经度和海拔。
  • min: 包含在响应中的最小值。
  • max: 包含在响应中的最大值。
  • round: 四舍五入到小数点后几位。
  • timescale: 每个时间窗口获取第一个值,有效值为 10, 15, 20, 30, 60, 240, 720, 1440, "daily"
  • sum: 每个时间窗口获取总和,有效值同上。
  • average: 每个时间窗口获取平均值,有效值同上。
  • median: 每个时间窗口获取中位数,有效值同上。

完整示例

下面是一个更详细的示例,展示了如何从ThingSpeak通道获取温度数据并将其显示在一个图表中:

import 'package:flutter/material.dart';
import 'package:flutter_thingspeak/flutter_thingspeak.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import './channel_model.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Thingspeak demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final flutterThingspeak = FlutterThingspeakClient(
      channelID: '12397', options: {'results': '5', 'timescale': '5'});
  Channel? channel;
  List<Feed> feeds = [];

  Future<void> getTemperatureData() async {
    flutterThingspeak.initialize();
    try {
      // 获取通道的温度数据
      final result = await flutterThingspeak.getFieldData('4');

      channel = Channel.fromJson(result);
      feeds = (result['feeds'] as List<dynamic>)
          .map((feed) => Feed.fromJson(feed))
          .toList();
    } catch (e) {}
  }

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: SafeArea(
        child: FutureBuilder(
          future: getTemperatureData(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasError) {
                // 显示加载数据时的错误信息
                return Center(
                  child: Text('Error loading data: ${snapshot.error}'),
                );
              }

              if (channel != null) {
                return Column(
                  children: [
                    Container(
                      margin: const EdgeInsets.all(10),
                      decoration: BoxDecoration(
                        border: Border.all(color: Colors.black45, width: .5),
                        borderRadius: const BorderRadius.all(Radius.circular(5)),
                      ),
                      child: ListBody(
                        children: [
                          ListTile(
                            title: const Text("Channel ID"),
                            subtitle: Text(channel!.id.toString()),
                          ),
                          ListTile(
                            title: const Text("Channel Name"),
                            subtitle: Text(channel!.name),
                          ),
                          ListTile(
                            title: const Text("Channel Description"),
                            subtitle: Text(channel!.description),
                          ),
                          ListTile(
                            title: const Text("Location"),
                            subtitle: Text(
                                "${channel!.latitude.toString()},${channel!.longitude}"),
                          )
                        ],
                      ),
                    ),
                    SfCartesianChart(
                        primaryXAxis: const CategoryAxis(),
                        // 图表标题
                        title: const ChartTitle(text: 'Temperature Data Chart'),
                        // 启用图例
                        legend: const Legend(isVisible: true),
                        // 启用工具提示
                        tooltipBehavior: TooltipBehavior(enable: true),
                        series: <CartesianSeries<Feed, String>>[
                          LineSeries<Feed, String>(
                              dataSource: feeds,
                              xValueMapper: (Feed feed, _) => feed.createdAt.minute.toString(),
                              yValueMapper: (Feed feed, _) => feed.field4,
                              name: 'Temperature',
                              // 启用数据标签
                              dataLabelSettings: const DataLabelSettings(isVisible: true))
                        ]),
                  ],
                );
              } else {
                // 显示数据不可用的消息
                return const Center(
                  child: Text('No data available.'),
                );
              }
            } else {
              // 显示加载指示器
              return const Center(
                child: CircularProgressIndicator(),
              );
            }
          },
        ),
      ),
    );
  }
}

更多关于Flutter物联网通信插件flutter_thingspeak的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter物联网通信插件flutter_thingspeak的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter应用中使用flutter_thingspeak插件进行物联网通信的示例代码。这个插件允许你与Thingspeak平台进行数据交互,Thingspeak是一个开源的物联网分析平台,可以方便地存储和分析传感器数据。

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

dependencies:
  flutter:
    sdk: flutter
  flutter_thingspeak: ^x.y.z  # 替换为最新版本号

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

接下来,我们编写一个示例代码来展示如何使用flutter_thingspeak插件。

示例代码

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

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final Thingspeak _thingspeak = Thingspeak();
  String _response = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Thingspeak Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Response:', style: TextStyle(fontSize: 18)),
            SizedBox(height: 10),
            Text(_response, style: TextStyle(fontSize: 16)),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _sendDataToThingspeak,
              child: Text('Send Data to Thingspeak'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _sendDataToThingspeak() async {
    String apiKey = 'YOUR_THINGSPEAK_API_KEY';  // 替换为你的Thingspeak API Key
    String channelId = 'YOUR_THINGSPEAK_CHANNEL_ID';  // 替换为你的Thingspeak Channel ID

    var data = {
      'field1': 25.0,  // 示例数据
      'field2': 60.0,  // 示例数据
      'field3': 'example',  // 示例数据
    };

    try {
      var result = await _thingspeak.writeToChannel(apiKey, channelId, data);
      setState(() {
        _response = 'Success: ${result['status']}\nResponse: ${result['response']}';
      });
    } catch (e) {
      setState(() {
        _response = 'Error: $e';
      });
    }
  }
}

注意事项

  1. API Key和Channel ID:确保你已经替换了YOUR_THINGSPEAK_API_KEYYOUR_THINGSPEAK_CHANNEL_ID为你的实际Thingspeak API Key和Channel ID。
  2. 数据格式data变量中的数据字段(如field1, field2, field3)应该与你Thingspeak通道中定义的字段匹配。
  3. 错误处理:在示例中,我们简单地捕获并显示了错误。在实际应用中,你可能需要更详细的错误处理逻辑。

这个示例展示了如何使用flutter_thingspeak插件将数据发送到Thingspeak平台。你可以根据需要扩展这个示例,例如从传感器读取数据,或者处理Thingspeak平台的响应数据。

回到顶部