This document is intended for developers who already know Panel miniApp. You need to fully understand what Panel miniApp is and what the DP function is.

Related information

The panel of some devices needs to provide C-side users with the ability to view device data, and the data needs to be exported so that users can further analyze it. Data such as temperature, humidity, PM2.5, etc. are generally exported here. Tuya provides related interfaces, which can export data at granularity of hours, days, months, etc., generate data into Excel files, and send them to users via email. .

Export data API at hourly granularity

Parameters

Name

Type

Required

Default

describe

email

String

yes

No value

Email address to receive exported files

devId

String

yes

No value

Device ID to be operated on

dpExcelQuery

String

yes

No value

Query conditions for specific DP points

date

String

yes

No value

Date of data to be exported, format: 20230901

type

String

yes

No value

Statistics type of DP function, supports: sum/avg/minux/min/max/count, etc.

auto

number

no

0

The type of supplementary data, 0: means that there is no data to supplement 0, 1: means that when there is no data, the data from the previous time point will be supplemented to the current time point, 2: means that there is no data to supplement #

keepScalaPoint

boolean

no

false

Whether to report the expansion multiple according to the dp point and keep decimal points

lang

String

no

No value

multi-language code

title

String

no

No value

mail title

Export data API at daily granularity

Parameters

Name

Type

Required

Default

describe

email

String

Yes

No value

Email address to receive exported

devId

String

Yes

No value

Device ID to be operated on

dpExcelQuery

String

Yes

No value

Query conditions for specific DP points

startDay

String

Yes

No value

The start date of the data to be exported, format: 20230901

endDay

String

Yes

No value

The end date of the data to be exported, format: 20230930

type

String

Yes

No value

Statistics type of DP function, supports: sum/avg/minux/min/max/count, etc.

keepScalaPoint

boolean

No

false

Whether to report the expansion multiple according to the dp point and keep decimal points

lang

String

No

No value

multi-language code

title

String

No

No value

mail title

Export data API at monthly granularity

Parameters

Name

Type

Required

Default

describe

email

String

Yes

No Value

Email address to receive exported

devId

String

Yes

No Value

Device ID to be operated on

dpExcelQuery

String

Yes

No Value

Query conditions for specific DP points

startMonth

String

Yes

No Value

The start month of the data to be exported, format:202309

endMonth

String

Yes

No Value

The end month of the data to be exported, format::202309

type

String

Yes

No Value

Statistics type of DP function, supports: sum/avg/minux/min/max/count, etc.

keepScalaPoint

boolean

No

false

Whether to report the expansion multiple according to the dp point and keep decimal points

lang

String

No

No Value

multi-language code

title

String

No

No Value

mail title

Structure of dpExcelQuery

This value is a JSON string with an array structure. The structure of the array elements is

Name

Type

Required

describe

dpId

Number

Yes

The ID of DP function

name

String

Yes

The name of DP function

handler

String

No

Temperature conversion method, the value can be temperatureF2C or temperatureC2F

Example:

[{"dpId":101,"name":"Temperature","handler":"temperatureF2C"}]

Scene: you need to export the data of two DPs of temperature (101) and humidity (102) of the device, and need to support converting the temperature unit to Fahrenheit.

Function description

UI code

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: 'Hour',
  day: 'Date',
  month: '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: 'Please input the email',
        icon: 'error',
      });
      return;
    }
    const format = type === 'month' ? 'YYYYMM' : 'YYYYMMDD';
    let start = formDate(startTime, format);
    let end = formDate(startTime, format);
    const data = {
      title: 'Temperature and humidity data sheet',
      devId: devInfo.devId,
      email,
      dpExcelQuery: [
        {
          dpId: '101',
          name: 'Temperature',
          handler: unit ? 'temperatureC2F' : undefined,
        },
        { dpId: '102', name: 'Humidity' },
      ],
    };

    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="Use Fahrenheit"
          content={<SwitchButton checked={unit} onChange={(v) => setUnit(v)} />}
        />
        <List.Item
          title="Type"
          onClick={() => setShowList(true)}
          content={<Text>{langs[type]}</Text>}
        />
        <List.Item
          title={type === 'hour' ? 'Date' : 'Start Date'}
          onClick={handleShowStart}
          content={
            <Text>
              {formDate(startTime, type === 'month' ? 'YYYYMM' : 'YYYYMMDD')}
            </Text>
          }
        />
        {type !== 'hour' && (
          <List.Item
            title="End Date"
            onClick={handleShowEnd}
            content={
              <Text>
                {formDate(endTime, type === 'month' ? 'YYYYMM' : 'YYYYMMDD')}
              </Text>
            }
          />
        )}

        <List.Item
          title="Email"
          content={
            <Input
              placeholder="please input"
              value={email}
              onInput={(e) => setEmail(e.value)}
            />
          }
        />
      </List>
      <ActionSheet
        show={showList}
        header="Select The Type"
        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="Select The Time"
        onCancel={() => setShowTime(false)}
        onOk={() => setShowTime(false)}
      >
        <DatePicker
          onChange={handleSelectTime}
          type={type === 'month' ? 'year-month' : 'date'}
        />
      </ActionSheet>
      <Button onClick={handleExport}>Export</Button>
    </View>
  );
};

export default Page;

API Code

api.js file content

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

// Export hourly data
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',
    });
    // Export successfully
  } catch {
    // Export failure
  }
};

// Export day data
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',
    });

    // Export successfully
  } catch {
    // Export failure
  }
};

// Export month data
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',
    });

    // Export successfully
  } catch {
    // Export failure
  }
};