如何从面板中导出 DP 数据?详细流程介绍

1. 前置知识

本文档面向已经了解 面板小程序开发 的开发者,您需要充分的了解什么是面板小程序,什么是 DP 功能。

相关知识

2. 使用场景

在某些设备的面板中需要提供给 C 端用户查看设备数据的能力,并需要导出数据使用户能够进一步分析。这里一般会导出如:温度、湿度、PM2.5 等的数据,涂鸦提供了相关的接口,可以按小时、天、月等粒度导出数据,把数据生成 Excel 文件,并通过邮件的方式发送给用户。

3. 接口介绍

按小时粒度导出数据接口

  • api: exportStatisticsHour
  • 说明: 可选择某一天中 24 小时的数据

入参

参数名称

参数类型

是否必选

默认值

描述

email

string

接收导出文件的邮箱地址

devId

string

待操作的设备 ID

dpExcelQuery

string

具体 DP 点的查询条件

date

string

待导出数据的日期,格式:20230901

type

string

DP 点的统计类型,支持:sum/avg/minux/min/max/count 等

auto

number

0

补数据的类型, 0:代表无数据补 0,1:代表无数据时会拿上一个时间点的数据补到当前时间点,2:代表无数据时补#

keepScalaPoint

boolean

false

是否按照 dp 点上报扩大倍数保留小数点

lang

string

多语言 code

title

string

邮件标题

按天粒度导出数据接口

  • api: exportStatisticsDay
  • 说明: 可选择一个日期范围内每天的统计数据,日期范围不能超过 1 年

入参

参数名称

参数类型

是否必选

默认值

描述

email

string

接收导出文件的邮箱地址

devId

string

待操作的设备 ID

dpExcelQuery

string

具体 DP 点的查询条件

startDay

string

待导出数据的开始日期,格式:20230901

endDay

string

待导出数据的结束日期,格式:20230930

type

string

DP 点的统计类型,支持:sum/avg/minux/min/max/count 等

keepScalaPoint

boolean

false

是否按照 dp 点上报扩大倍数保留小数点

lang

string

多语言 code

title

string

邮件标题

👉 立即免费领取开发资源,体验涂鸦 MiniApp 小程序开发。

按月粒度导出数据接口

  • api: exportStatisticsMonth
  • 说明: 可选择一个日期范围内每月的统计数据,日期范围不能超过 1 年

入参

参数名称

参数类型

是否必选

默认值

描述

email

string

接收导出文件的邮箱地址

devId

string

待操作的设备 ID

dpExcelQuery

string

具体 DP 点的查询条件

startMonth

string

待导出数据的开始年月,格式:202309

endMonth

string

待导出数据的结束年月,格式:202309

type

string

DP 点的统计类型,支持:sum/avg/minux/min/max/count 等

keepScalaPoint

boolean

false

是否按照 dp 点上报扩大倍数保留小数点

lang

string

多语言 code

title

string

邮件标题

dpExcelQuery 的结构

此值为一个数组结构的 JSON 字符串,数组元素的结构为:

属性名称

类型

是否必须

描述

dpId

Number

DP 功能的 ID

name

String

DP 功能名称

handler

String

可支持温度的转换,值可为 temperatureF2C 或 temperatureC2F

示例

[{"dpId":"101","name":"华氏度转摄氏度","handler":"temperatureF2C"}]
        

4. 示例

示例为:需要导出设备的温度 (101)、湿度 (102)两个 DP 的数据,并且需要支持将温度的单位转为华氏度。

功能描述

  • 温度 DP 默认为摄氏度单位,交互上支持用户可选择将摄氏度转华氏度;
  • 支持可选择导出数据的粒度:时、天、月;
  • 支持可选择导出的时间范围,注意选择导出时粒度时,只能选择一个日期;
  • 提供输入电子邮箱地址的功能;

 👉 立即免费领取开发资源,体验涂鸦 MiniApp 小程序开发。

UI 实现

import React, { FC, useState, useCallback, useRef } from
          "react";
          import { View, Text, Button, Checkbox, showToast } from "@ray-js/ray";
          import SwitchButton from "@ray-js/components-ty-switch";
          import ActionSheet from "@ray-js/components-ty-actionsheet";
          import List from "@ray-js/components-ty-cell";
          import DatePicker from "@ray/components-ty-datetime-picker";
          import Input from "@ray-js/components-ty-input";
          import { hooks } from "@ray-js/panel-sdk";
          import * as api from "./api";

          const langs = {
          hour: "时",
          day: "天",
          month: "月",
          };

          const exportFn = {
          hour: api.exportHour,
          day: api.exportDay,
          month: api.exportMonth,
          };

          const formDate = (date, format = "YYYYMMDD") => {
          const year = date.getFullYear();
          const month = date.getMonth() + 1;
          const day = date.getDate();

          return format
          .replace("YYYY", year)
          .replace("MM", month.toString().padStart(2, "0"))
          .replace("DD", day.toString().padStart(2, "0"));
          };

          const Page: FC = () => {
          const devInfo = hooks.useDevInfo();
          const [unit, setUnit] = useState(false);
          const [type, setType] = useState("hour");
          const [email, setEmail] = useState("");
          const isEnd = useRef(false);
          const [showList, setShowList] = useState(false);
          const [showTime, setShowTime] = useState(false);
          const [startTime, setStartTime] = useState(new Date());
          const [endTime, setEndTime] = useState(new Date());

          const handleShowEnd = useCallback(() => {
          isEnd.current = true;
          setShowTime(true);
          }, []);
          const handleShowStart = useCallback(() => {
          isEnd.current = false;
          setShowTime(true);
          }, []);
          const handleSelectTime = useCallback((v) => {
          if (isEnd.current) {
          setEndTime(v);
          } else {
          setStartTime(v);
          }
          }, []);

          const handleExport = useCallback(() => {
          if (!email) {
          showToast({
          title: "请输入邮箱",
          icon: "error",
          });
          return;
          }
          const format = type === "month" ? "YYYYMM" : "YYYYMMDD";
          let start = formDate(startTime, format);
          let end = formDate(startTime, format);
          const data = {
          title: "温湿度数据表",
          devId: devInfo.devId,
          email,
          dpExcelQuery: [
          {
          dpId: "101",
          name: "室内温度",
          handler: unit ? "temperatureC2F" : undefined,
          },
          { dpId: "102", name: "室内湿度" },
          ],
          };

          switch (type) {
          case "hour":
          data.date = start;
          break;
          case "day":
          data.startDay = start;
          data.endDay = end;
          break;
          case "month":
          data.startMonth = start;
          data.endMonth = end;
          break;
          }
          exportFn[type](data);
          }, [type, email, unit, startTime, endTime, devInfo?.devId]);

          return (
          <View>
          <List>
          <List.Item
          title="使用华氏度"
          content={<SwitchButton checked={unit} onChange={(v) => setUnit(v)} />}
          />
          <List.Item
          title="粒度"
          onClick={() => setShowList(true)}
          content={<Text>{langs[type]}</Text>}
          />
          <List.Item
          title={type === "hour" ? "时间" : "开始时间"}
          onClick={handleShowStart}
          content={
          <Text>
          {formDate(startTime, type === "month" ? "YYYYMM" : "YYYYMMDD")}
          </Text>
          }
          />
          {type !== "hour" && (
          <List.Item
          title="结束时间"
          onClick={handleShowEnd}
          content={
          <Text>
          {formDate(endTime, type === "month" ? "YYYYMM" : "YYYYMMDD")}
          </Text>
          }
          />
          )}

          <List.Item
          title="邮箱"
          content={
          <Input
          placeholder="请输入"
          value={email}
          onInput={(e) => setEmail(e.value)}
          />
          }
          />
          </List>
          <ActionSheet
          show={showList}
          header="选择粒度"
          onCancel={() => setShowList(false)}
          okText=""
          >
          <List.Row
          dataSource={Object.keys(langs).map((key) => {
          return {
          title: langs[key],
          content: type === key ? <Checkbox checked /> : null,
          onClick: () => {
          setType(key);
          setShowList(false);
          },
          };
          })}
          />
          </ActionSheet>
          <ActionSheet
          show={showTime}
          header="选择时间"
          onCancel={() => setShowTime(false)}
          onOk={() => setShowTime(false)}
          >
          <DatePicker
          onChange={handleSelectTime}
          type={type === "month" ? "year-month" : "date"}
          />
          </ActionSheet>
          <Button onClick={handleExport}>导出</Button>
          </View>
          );
          };

          export default Page;
        

API 封装

api.js 文件内容

import {
          exportStatisticsDay,
          exportStatisticsHour,
          exportStatisticsMonth,
          } from "@ray-js/ray";

          // 导出小时数据
          export const exportHour = async (params) => {
          try {
          await exportStatisticsHour({
          email: params.email,
          devId: params.devId,
          dpExcelQuery: JSON.stringify(params.dpExcelQuery),
          date: params.date,
          type: "avg",
          auto: 2,
          keepScalaPoint: true,
          lang: "cn",
          });

          // 导出成功
          } catch {
          // 导出失败
          }
          };

          // 导出天数据
          export const exportDay = async (params) => {
          try {
          await exportStatisticsDay({
          email: params.email,
          devId: params.devId,
          dpExcelQuery: JSON.stringify(params.dpExcelQuery),
          startDay: params.startDay,
          endDay: params.endDay,
          type: "avg",
          keepScalaPoint: true,
          lang: "cn",
          });

          // 导出成功
          } catch {
          // 导出失败
          }
          };

          // 导出月数据
          export const exportMonth = async (params) => {
          try {
          await exportStatisticsMonth({
          email: params.email,
          devId: params.devId,
          dpExcelQuery: JSON.stringify(params.dpExcelQuery),
          startMonth: params.startMonth,
          endMonth: params.endMonth,
          type: "avg",
          keepScalaPoint: true,
          lang: "cn",
          });

          // 导出成功
          } catch {
          // 导出失败
          }
          };
        

5. 结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IoT砖家涂拉拉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值