Added dp for errors for thermometer

Panel mini-program development related product technical discussions, including panel mini-programs, intelligent mini-programs, React Native, Ray cross-platform framework, Panel SDK, WeChat mini-programs, mini-program development tools (IDE), and other related development technologies.


Post Reply
n0b0dy
Posts: 2

IDE 0.10.9
Smartlife 7.11.0(int)
@ray-js/cli": "1.7.55"
@ray-js/panel-sdk": "1.14.1"
Realme 8 pro, Andr. 13
Product ID: idqdrp5x
Can't read log for dp101 (1w error code), dp102 (CRC error rate)
I need the log itself, not just a display of the current value.

► Show Spoiler

Shows "Log API methods not found in SDK"

7ingyuan
Posts: 1

Re: Added dp for errors for thermometer

Hello,
To query historical DP logs reported by the device, please use the official getAnalyticsLogsStatusLog API:
View the getAnalyticsLogsStatusLog documentation
This API requires @tuya-miniapp/cloud-api version 1.0.5 or later and is not available under ty.device:

Code: Select all

import { getAnalyticsLogsStatusLog } from '@tuya-miniapp/cloud-api';

const result = await getAnalyticsLogsStatusLog({
  devId,
  dpIds: '101,102',
  offset: 0,
  limit: 50,
  startTime: String(Date.now() - 7 * 24 * 60 * 60 * 1000), // Defaults to the timestamp from 7 days ago if omitted
  endTime: String(Date.now()), // Defaults to the current timestamp if omitted
  sortType: 'DESC',
});

const logs = result?.dps ?? [];

Please note:

  • This is a cloud capability and requires authorization.
  • Cloud capabilities are not available in the Developer Tools environment; package the MiniApp or test on a real device.
  • The available history range depends on the device log storage service. The free edition supports logs from the most recent seven days. Please refer to the documentation for details.

For further questions about Ray APIs, you can also try Tuya MiniApp AI in the lower-right corner of the official documentation page : )

n0b0dy
Posts: 2

Re: Added dp for errors for thermometer

Autorized: IoT CoreAuthorization Token ManagementSmart Home Basic ServiceData Dashboard ServiceBeta APIs[Deprecate]Device Log QueryIndustry General Log ServiceIndustry Basic ServiceIdentity and Access Management
API error (6):
import React, { useEffect, useState } from 'react';
import { Text, View, ScrollView } from '@ray-js/ray';
import { Layout } from '@/components/layout';
import { useDevice } from '@ray-js/panel-sdk';
import { errorTranslations } from '@/utils/errorCodes';

declare const ty: any;

export function ErrLog() {
const devId: string = useDevice((d: any) => d.devInfo.devId) || '';


const [logs, setLogs] = useState<any[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [debugInfo, setDebugInfo] = useState<string>('Initializing...');

useEffect(() => {
const fetchLogs = async () => {
try {
setLoading(true);
setDebugInfo('Executing v2.0 API request...');


Code: Select all

    const endTimeMs: number = Date.now();
    const startTimeMs: number = endTimeMs - 7 * 24 * 60 * 60 * 1000;

    if (typeof ty !== 'undefined' && typeof ty.request === 'function') {
      ty.request({
        api: 'tuya.m.device.openapi.request', 
        v: '1.0',
        data: {
          path: `/v2.0/cloud/thing/${devId}/report-logs`,
          method: 'GET',
          param: {
            codes: 'bus_error_code',
            start_time: startTimeMs,
            end_time: endTimeMs,
            size: 20
          }
        },
        success: (res: any) => {
          console.log('=== LOGS SUCCESS ===', res);
          
          let rawLogs = [];
          let parsedRes = typeof res === 'string' ? JSON.parse(res) : res;

          // Парсим ответ строго по примеру из v2.0
          if (parsedRes && parsedRes.result && Array.isArray(parsedRes.result.logs)) {
            rawLogs = parsedRes.result.logs;
          }

          if (rawLogs.length > 0) {
            const formattedLogs = rawLogs.map((log: any) => ({
              time: log.event_time ? Number(log.event_time) : Date.now(), 
              value: log.value !== undefined ? String(log.value) : String(log.code || '')
            }));

            formattedLogs.sort((a: any, b: any) => b.time - a.time);
            setLogs(formattedLogs);
            setDebugInfo(`Loaded ${formattedLogs.length} logs successfully`);
          } else {
            setLogs([]);
            const keys = parsedRes?.result ? Object.keys(parsedRes.result).join(', ') : 'no_result';
            setDebugInfo(`No error logs found. Keys: [${keys}]`);
          }
          setLoading(false);
        },
        fail: (err: any) => {
          console.log('=== LOGS FAIL ===', err);
          const errCode = err?.code || err?.errorCode || 'N/A';
          const msg = err?.message || err?.errorMsg || JSON.stringify(err);
          setLogs([]);
          setDebugInfo(`API Error (${errCode}): ${msg}`);
          setLoading(false);
        }
      });
    } else {
      throw new Error('ty.request is not available');
    }
  } catch (err: any) {
    console.log('Execution catch error:', err);
    setLogs([]);
    setDebugInfo(`Catch: ${err.message || JSON.stringify(err)}`);
    setLoading(false);
  }
};

if (devId) {
  fetchLogs();
} else {
  setLoading(false);
  setDebugInfo('DevId is missing');
}

}, [devId]);

const formatTime = (timestamp: number): string => {
const date = new Date(timestamp);
return date.toLocaleString('en-GB', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });
};

return (
<Layout title="Err log" showBack={true}>
<ScrollView style={{ flex: 1, backgroundColor: '#f2f4f6', boxSizing: 'border-box' }}>


Code: Select all

    <View style={{ margin: '20rpx', padding: '20rpx', backgroundColor: '#222', borderRadius: '12rpx', border: '1px solid #444' }}>
      <Text style={{ color: '#0f0', fontSize: '28rpx', fontWeight: 'bold', display: 'block' }}>
        Status: {debugInfo}
      </Text>
    </View>

    <View style={{ padding: '32rpx' }}>
      
      {loading && (
        <View style={{ marginTop: '100rpx', textAlign: 'center' }}>
          <Text style={{ color: '#999', fontSize: '32rpx' }}>Loading logs...</Text>
        </View>
      )}

      {!loading && logs.length === 0 && (
        <View style={{ marginTop: '100rpx', textAlign: 'center' }}>
          <Text style={{ color: '#999', fontSize: '32rpx' }}>No logs available</Text>
        </View>
      )}

      {!loading && logs.length > 0 && (
        <View>
          {logs.map((item: any, index: number) => {
            const isError: boolean = item.value !== 'no_errors';
            return (
              <View 
                key={index} 
                style={{ 
                  backgroundColor: '#ffffff', 
                  padding: '36rpx', 
                  marginBottom: '24rpx', 
                  borderRadius: '16rpx',
                  display: 'flex',
                  flexDirection: 'row',
                  alignItems: 'center'
                }}
              >
                <View style={{ 
                  width: '20rpx', 
                  height: '20rpx', 
                  borderRadius: '50%', 
                  backgroundColor: isError ? '#ff4d4f' : '#52c41a',
                  marginRight: '28rpx'
                }} />
                <View style={{ flex: 1 }}>
                  <Text style={{ fontSize: '34rpx', fontWeight: 'bold', color: '#333', display: 'block' }}>
                    {errorTranslations[item.value] || item.value}
                  </Text>
                  <Text style={{ fontSize: '28rpx', color: '#999', marginTop: '10rpx', display: 'block' }}>
                    {formatTime(item.time)}
                  </Text>
                </View>
              </View>
            );
          })}
        </View>
      )}

    </View>
  </ScrollView>
</Layout>

);
}

export default ErrLog;

Post Reply