@ledvance/ui-biz-bundle 1.1.149 → 1.1.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/modules/history/HistoryPage.tsx +2 -0
- package/src/modules/timer/TimerPage.tsx +2 -0
- package/src/newModules/energyConsumption/EnergyConsumptionActions.ts +31 -71
- package/src/newModules/energyConsumption/EnergyConsumptionChart/LandscapeView.tsx +47 -35
- package/src/newModules/energyConsumption/EnergyConsumptionChart/styles.ts +1 -1
- package/src/newModules/energyConsumption/EnergyConsumptionChart/useEnergyData.ts +4 -2
- package/src/newModules/fixedTime/FixedTimePage.tsx +2 -0
- package/src/newModules/powerOnBehavior/LightBehaviorPage.tsx +2 -0
- package/src/newModules/powerOnBehavior/PlugBehaviorPage.tsx +2 -0
- package/src/newModules/randomTime/RandomTimePage.tsx +2 -0
- package/src/newModules/timeSchedule/TimeSchedulePage.tsx +2 -0
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import FeatureInfo from '@ledvance/base/src/components/FeatureInfo'
|
|
1
2
|
import Page from '@ledvance/base/src/components/Page'
|
|
2
3
|
import { useDeviceInfo } from '@ledvance/base/src/models/modules/NativePropsSlice'
|
|
3
4
|
import React, { useCallback, useEffect } from 'react'
|
|
@@ -187,6 +188,7 @@ const SwitchHistoryPage = (props: { theme?: ThemeType }) => {
|
|
|
187
188
|
headlineText={headlineText || I18n.getLang('history_socket_headline_text')}
|
|
188
189
|
headlineIcon={res.download_icon}
|
|
189
190
|
onHeadlineIconClick={downFile}
|
|
191
|
+
info={<FeatureInfo title={I18n.getLang('history_socket_headline_text')} content={I18n.getLang('infobutton_history')} />}
|
|
190
192
|
>
|
|
191
193
|
<View style={styles.content}>
|
|
192
194
|
<Text style={styles.titleText}>{I18n.getLang('history_contact_sensor_description_text')}</Text>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import FeatureInfo from '@ledvance/base/src/components/FeatureInfo'
|
|
1
2
|
import React, { useCallback, useEffect } from "react";
|
|
2
3
|
import { View, Text, ScrollView, TouchableOpacity, StyleSheet, Image } from "react-native"
|
|
3
4
|
import { useNavigation } from '@react-navigation/native'
|
|
@@ -216,6 +217,7 @@ const TimerPage = (props: {theme?: ThemeType}) => {
|
|
|
216
217
|
backText={devInfo.name}
|
|
217
218
|
headlineText={I18n.getLang('timer_nightplug_headline_text')}
|
|
218
219
|
onBackClick={navigation.goBack}
|
|
220
|
+
info={<FeatureInfo title={I18n.getLang('timer_nightplug_headline_text')} content={I18n.getLang('infobutton_timer')} />}
|
|
219
221
|
>
|
|
220
222
|
<ScrollView
|
|
221
223
|
nestedScrollEnabled={true}
|
|
@@ -10,10 +10,11 @@ import {
|
|
|
10
10
|
getSpecifiedTimeDpReportLogs
|
|
11
11
|
} from '@ledvance/base/src/models/TuyaApi'
|
|
12
12
|
import { exportCsvFile, localeNumber, loopsText, monthFormat, monthFormatShort } from '@ledvance/base/src/utils/common'
|
|
13
|
-
import { overDays } from '@ledvance/base/src/utils'
|
|
13
|
+
import { overDays, xLog } from '@ledvance/base/src/utils'
|
|
14
14
|
import dayjs from 'dayjs'
|
|
15
15
|
import CustomParseFormat from 'dayjs/plugin/customParseFormat'
|
|
16
16
|
import { isEmpty } from 'lodash'
|
|
17
|
+
import { TYSdk } from 'tuya-panel-kit'
|
|
17
18
|
import { DateType } from './co2Data'
|
|
18
19
|
import { EnergyData } from './component/EnergyModal'
|
|
19
20
|
import { OverviewItem } from './EnergyConsumptionPage'
|
|
@@ -39,6 +40,11 @@ export async function updatePrice(devId: string, energyData: EnergyData) {
|
|
|
39
40
|
return await NativeApi.putJson(devId, 'energiepreise', JSON.stringify(energyData))
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
export async function resetElectricity(devId) {
|
|
44
|
+
const res = await TYSdk.apiRequest('tuya.m.dp.statistics.reset', {devId}, '1.0')
|
|
45
|
+
xLog('resetElectricity res', res)
|
|
46
|
+
}
|
|
47
|
+
|
|
42
48
|
export async function getElectricity(devId: string, addEleDpCode: string, date: string, dateType: DateType): Promise<OverviewItem[]> {
|
|
43
49
|
let res: OverviewItem[] = []
|
|
44
50
|
switch (dateType) {
|
|
@@ -175,83 +181,37 @@ function createZeroPaddingPoint(timePoint: dayjs.Dayjs): PowerDataItem {
|
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
/**
|
|
178
|
-
*
|
|
184
|
+
* 获取设备功率数据
|
|
179
185
|
* @param devId 设备ID
|
|
180
186
|
* @param powerDpCode 功率数据点编码
|
|
181
187
|
* @param interval 时间区间(分钟)
|
|
182
188
|
* @returns 按时间排序的完整数据
|
|
183
189
|
*/
|
|
184
|
-
export async function getPowerData(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
[powerDpCode],
|
|
200
|
-
'ASC',
|
|
201
|
-
startTimeMs.toString(),
|
|
202
|
-
endTimeMs.toString(),
|
|
203
|
-
RETRY_CONFIG
|
|
204
|
-
);
|
|
205
|
-
const validDpResult = Array.isArray(dpResult) ? (dpResult as DpReportSataData[]) : [];
|
|
206
|
-
const actualData: PowerDataItem[] = validDpResult
|
|
207
|
-
.map((dp) => {
|
|
208
|
-
const timeMs = dp.timeStamp * 1000;
|
|
209
|
-
if (timeMs < startTimeMs || timeMs > endTimeMs) return null;
|
|
210
|
-
return {
|
|
211
|
-
key: dayjs.unix(dp.timeStamp).format('HH:mm:ss'),
|
|
212
|
-
chartTitle: dayjs.unix(dp.timeStamp).format('MM/DD/YYYY HH:mm:ss'),
|
|
213
|
-
time: timeMs,
|
|
214
|
-
value: parseFloat(dp.value) / 10,
|
|
215
|
-
};
|
|
216
|
-
})
|
|
217
|
-
.filter((item): item is PowerDataItem => item !== null);
|
|
218
|
-
// 如果没有任何真实数据,则生成完整的预设0值数据作为兜底
|
|
219
|
-
if (actualData.length === 0) {
|
|
220
|
-
const finalData: PowerDataItem[] = [];
|
|
221
|
-
let currentTime = startTime;
|
|
222
|
-
while (currentTime.valueOf() < endTimeMs) {
|
|
223
|
-
finalData.push(createZeroPaddingPoint(currentTime));
|
|
224
|
-
currentTime = currentTime.add(DATA_POINT_INTERVAL_SEC, 'second');
|
|
225
|
-
}
|
|
226
|
-
return finalData;
|
|
190
|
+
export async function getPowerData(devId: string, powerDpCode: string, interval: number): Promise<PowerDataItem[]> {
|
|
191
|
+
const now = dayjs()
|
|
192
|
+
const startTime = now.add(-1 * interval, 'minute').valueOf().toString()
|
|
193
|
+
const endTime = now.valueOf().toString()
|
|
194
|
+
const dpResult = await getSpecifiedTimeDpReportLogs(
|
|
195
|
+
devId,
|
|
196
|
+
[powerDpCode],
|
|
197
|
+
'ASC',
|
|
198
|
+
startTime,
|
|
199
|
+
endTime,
|
|
200
|
+
{
|
|
201
|
+
maxRetries: 5,
|
|
202
|
+
initialDelay: 1000,
|
|
203
|
+
maxDelay: 30000,
|
|
204
|
+
backoffFactor: 2
|
|
227
205
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
while (paddingTimeMs < currentPoint.time) {
|
|
236
|
-
finalData.push(createZeroPaddingPoint(dayjs(paddingTimeMs)));
|
|
237
|
-
paddingTimeMs += paddingIntervalMs;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// 添加当前的真实数据点
|
|
241
|
-
finalData.push(currentPoint);
|
|
242
|
-
lastTimeMs = currentPoint.time; // 更新游标
|
|
243
|
-
});
|
|
244
|
-
// 3. 填充查询末尾的空白区域(从最后一个真实数据点到查询结束时间)
|
|
245
|
-
let paddingTimeMs = lastTimeMs + paddingIntervalMs;
|
|
246
|
-
while (paddingTimeMs < endTimeMs) {
|
|
247
|
-
finalData.push(createZeroPaddingPoint(dayjs(paddingTimeMs)));
|
|
248
|
-
paddingTimeMs += paddingIntervalMs;
|
|
206
|
+
) as DpReportSataData[]
|
|
207
|
+
return dpResult.map(dp => {
|
|
208
|
+
return {
|
|
209
|
+
key: dp.timeStr,
|
|
210
|
+
chartTitle: dayjs.unix(dp.timeStamp).format('MM/DD/YYYY HH:mm:ss'),
|
|
211
|
+
time: dp.timeStamp * 1000,
|
|
212
|
+
value: parseFloat(dp.value) / 10
|
|
249
213
|
}
|
|
250
|
-
|
|
251
|
-
} catch (error) {
|
|
252
|
-
console.error(`[getPowerData] 失败:devId=${devId}, powerDpCode=${powerDpCode}`, error);
|
|
253
|
-
return [];
|
|
254
|
-
}
|
|
214
|
+
})
|
|
255
215
|
}
|
|
256
216
|
|
|
257
217
|
export const exportEnergyCsv = (values: any[][], unit: string) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import I18n from '@ledvance/base/src/i18n'
|
|
2
2
|
import res from '@ledvance/base/src/res'
|
|
3
|
-
import React from 'react'
|
|
4
|
-
import { Image, Text, TouchableOpacity, View } from 'react-native'
|
|
3
|
+
import React, { useEffect } from 'react'
|
|
4
|
+
import { BackHandler, Image, Text, TouchableOpacity, View } from 'react-native'
|
|
5
5
|
import { Utils } from 'tuya-panel-kit'
|
|
6
6
|
import { ChartType } from '../co2Data'
|
|
7
7
|
import { EnergyChartSection } from './EnergyChartSection'
|
|
@@ -9,38 +9,50 @@ import { PowerChartSection } from './PowerChartSection'
|
|
|
9
9
|
|
|
10
10
|
const { convertX: cx, width } = Utils.RatioUtils
|
|
11
11
|
|
|
12
|
-
export const LandscapeView = ({ state, actions, params, styles, theme, screenWidth, screenHeight }) =>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
export const LandscapeView = ({ state, actions, params, styles, theme, screenWidth, screenHeight }) => {
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const onBack = () => {
|
|
15
|
+
actions.toggleLandscape()
|
|
16
|
+
return true
|
|
17
|
+
}
|
|
18
|
+
BackHandler.addEventListener('hardwareBackPress', onBack)
|
|
19
|
+
return () => {
|
|
20
|
+
BackHandler.removeEventListener('hardwareBackPress', onBack)
|
|
21
|
+
}
|
|
22
|
+
}, [])
|
|
23
|
+
return (
|
|
24
|
+
<View style={[styles.landscapeContainer, { width: screenWidth, height: screenHeight }]}>
|
|
25
|
+
<View style={styles.landscapeHeader}>
|
|
26
|
+
<Text style={styles.landscapeTitle}>
|
|
27
|
+
{I18n.getLang(state.chartType === ChartType.kWh ? 'chartdisplay_energy' : 'chartdisplay_power')}
|
|
28
|
+
</Text>
|
|
29
|
+
<TouchableOpacity onPress={actions.toggleLandscape}>
|
|
30
|
+
<Image source={{ uri: res.screen_normal }} style={styles.normalScreenIcon}/>
|
|
31
|
+
</TouchableOpacity>
|
|
32
|
+
</View>
|
|
22
33
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
<View style={styles.landscapeContent}>
|
|
35
|
+
{state.chartType === ChartType.kWh ? (
|
|
36
|
+
<EnergyChartSection
|
|
37
|
+
isLandscape={true}
|
|
38
|
+
state={state}
|
|
39
|
+
actions={actions}
|
|
40
|
+
params={params}
|
|
41
|
+
styles={styles}
|
|
42
|
+
theme={theme}
|
|
43
|
+
chartHeight={screenHeight - cx(110)}
|
|
44
|
+
/>
|
|
45
|
+
) : (
|
|
46
|
+
<PowerChartSection
|
|
47
|
+
isLandscape={true}
|
|
48
|
+
state={state}
|
|
49
|
+
actions={actions}
|
|
50
|
+
styles={styles}
|
|
51
|
+
theme={theme}
|
|
52
|
+
chartHeight={screenHeight - cx(110)}
|
|
53
|
+
/>
|
|
54
|
+
)}
|
|
55
|
+
</View>
|
|
44
56
|
</View>
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
)
|
|
58
|
+
}
|
|
@@ -54,7 +54,7 @@ export const getStyles = (theme: ThemeType | undefined) => StyleSheet.create({
|
|
|
54
54
|
// width: cx(height + 20), // In landscape, width is screen height
|
|
55
55
|
// height: width, // In landscape, height is screen width
|
|
56
56
|
paddingVertical: cx(30),
|
|
57
|
-
paddingHorizontal: cx(
|
|
57
|
+
paddingHorizontal: cx(50),
|
|
58
58
|
},
|
|
59
59
|
landscapeHeader: {
|
|
60
60
|
flexDirection: 'row',
|
|
@@ -128,8 +128,10 @@ export const useEnergyData = (params: EnergyConsumptionChartProps, devId: string
|
|
|
128
128
|
state.dateType = type
|
|
129
129
|
}, []),
|
|
130
130
|
setInterval: useCallback((newInterval: number) => {
|
|
131
|
-
state.interval
|
|
132
|
-
|
|
131
|
+
if (newInterval !== state.interval) {
|
|
132
|
+
state.interval = newInterval
|
|
133
|
+
state.powerData = []
|
|
134
|
+
}
|
|
133
135
|
}, []),
|
|
134
136
|
toggleLandscape: useCallback(() => {
|
|
135
137
|
if (!state.isSupportLandscape) return
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import FeatureInfo from '@ledvance/base/src/components/FeatureInfo'
|
|
1
2
|
import React, { memo, useCallback, useMemo } from "react";
|
|
2
3
|
import { FlatList, Image, ScrollView, StyleSheet, Text, View } from 'react-native'
|
|
3
4
|
import Page from "@ledvance/base/src/components/Page";
|
|
@@ -210,6 +211,7 @@ const FixedTimePage = (props: { theme?: ThemeType }) => {
|
|
|
210
211
|
onHeadlineIconClick={() => {
|
|
211
212
|
navigateToEdit('add', newFixedTime(!!params.isPlug))
|
|
212
213
|
}}
|
|
214
|
+
info={<FeatureInfo title={I18n.getLang('fixedTimeCycle_socket_headline')} content={I18n.getLang('infobutton_fixedtimecycle')} />}
|
|
213
215
|
>
|
|
214
216
|
<ScrollView nestedScrollEnabled={true}>
|
|
215
217
|
<Text style={{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import FeatureInfo from '@ledvance/base/src/components/FeatureInfo'
|
|
1
2
|
import React from 'react'
|
|
2
3
|
import {ScrollView, StyleSheet, Text, View} from 'react-native'
|
|
3
4
|
import {useReactive, useUpdateEffect} from 'ahooks'
|
|
@@ -67,6 +68,7 @@ const LightBehaviorPage = (props: { theme?: ThemeType }) => {
|
|
|
67
68
|
<Page
|
|
68
69
|
backText={deviceInfo.name}
|
|
69
70
|
headlineText={I18n.getLang('light_sources_specific_settings_power_off')}
|
|
71
|
+
info={<FeatureInfo title={I18n.getLang('light_sources_specific_settings_power_off')} content={I18n.getLang('infobutton_poweronbehavior')} />}
|
|
70
72
|
loading={state.loading}>
|
|
71
73
|
<ScrollView style={styles.root} nestedScrollEnabled={true}>
|
|
72
74
|
<View>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import FeatureInfo from '@ledvance/base/src/components/FeatureInfo'
|
|
1
2
|
import React from 'react'
|
|
2
3
|
import {ScrollView, StyleSheet} from 'react-native'
|
|
3
4
|
import Page from '@ledvance/base/src/components/Page'
|
|
@@ -44,6 +45,7 @@ const PlugBehaviorPage = () => {
|
|
|
44
45
|
<Page
|
|
45
46
|
backText={deviceInfo.name}
|
|
46
47
|
headlineText={I18n.getLang('light_sources_specific_settings_power_off')}
|
|
48
|
+
info={<FeatureInfo title={I18n.getLang('light_sources_specific_settings_power_off')} content={I18n.getLang('infobutton_poweronbehavior')} />}
|
|
47
49
|
loading={state.loading}>
|
|
48
50
|
<ScrollView style={styles.root} nestedScrollEnabled={true}>
|
|
49
51
|
{params.powerBehaviorKeys.length > 1 && <>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import FeatureInfo from '@ledvance/base/src/components/FeatureInfo'
|
|
1
2
|
import React, { useCallback, useMemo } from 'react'
|
|
2
3
|
import { FlatList, Image, ScrollView, StyleSheet, Text, View } from 'react-native'
|
|
3
4
|
import Page from '@ledvance/base/src/components/Page'
|
|
@@ -213,6 +214,7 @@ const RandomTimePage = (props: { theme?: ThemeType }) => {
|
|
|
213
214
|
onHeadlineIconClick={() => {
|
|
214
215
|
navigateToEdit('add', newRandomTime(!!params.isPlug))
|
|
215
216
|
}}
|
|
217
|
+
info={<FeatureInfo title={I18n.getLang('randomtimecycle_sockets_headline_text')} content={I18n.getLang('infobutton_randomtimecycle')} />}
|
|
216
218
|
>
|
|
217
219
|
<ScrollView nestedScrollEnabled={true}>
|
|
218
220
|
<Text style={{
|
|
@@ -24,6 +24,7 @@ import { cloneDeep } from 'lodash';
|
|
|
24
24
|
import ThemeType from '@ledvance/base/src/config/themeType'
|
|
25
25
|
import { showDialog } from '@ledvance/base/src/utils/common';
|
|
26
26
|
import { ApplyForItem } from '@ledvance/base/src/utils/interface';
|
|
27
|
+
import FeatureInfo from "@ledvance/base/src/components/FeatureInfo"
|
|
27
28
|
|
|
28
29
|
const { convertX: cx } = Utils.RatioUtils;
|
|
29
30
|
const { withTheme } = Utils.ThemeUtils
|
|
@@ -187,6 +188,7 @@ const TimeSchedulePage = (props: { theme?: ThemeType }) => {
|
|
|
187
188
|
onHeadlineIconClick={() => {
|
|
188
189
|
navigateToEdit('add');
|
|
189
190
|
}}
|
|
191
|
+
info={<FeatureInfo title={I18n.getLang('timeschedule_overview_headline_text')} content={I18n.getLang('infobutton_timeschedule')} />}
|
|
190
192
|
loading={state.loading}
|
|
191
193
|
>
|
|
192
194
|
<ScrollView nestedScrollEnabled={true}>
|