好的。但我在\src\composeLayout.tsx中看到了初始化 devices.common.init();具体代码,我展示在上面了,想问一下在这里不算成功初始化了吗?而且我在添加了下方的初始化,依然没能删除和禁用
Code: Select all
// 创建一个 alarm 实例
const Alarm = new SmartAlarmAbility();
// 在调用方法之前必须调用 init()
await Alarm.init();
好的。但我在\src\composeLayout.tsx中看到了初始化 devices.common.init();具体代码,我展示在上面了,想问一下在这里不算成功初始化了吗?而且我在添加了下方的初始化,依然没能删除和禁用
Code: Select all
// 创建一个 alarm 实例
const Alarm = new SmartAlarmAbility();
// 在调用方法之前必须调用 init()
await Alarm.init();
可以参考下以下 Demo 示例,我们规划会在 2-3 月左右开源 Demo,现阶段可先简单参考下(基于 https://github.com/Tuya-Community/tuya- ... dmTemplate 修改):
Code: Select all
import { SmartDeviceSchema } from '@/typings/sdm';
import {
SmartAlarmAbility,
SmartDeviceModel,
SmartDeviceModelOptions,
SmartGroupModel,
} from '@ray-js/panel-sdk';
import { createDpKit } from '@ray-js/panel-sdk/lib/sdm/interceptors/dp-kit';
import { getLaunchOptionsSync } from '@ray-js/ray';
import { protocols } from '@/devices/protocols';
const isGroupDevice = !!getLaunchOptionsSync()?.query?.groupId;
export const dpKit = createDpKit<SmartDeviceSchema>({ protocols });
const options = {
abilities: [new SmartAlarmAbility()],
interceptors: dpKit.interceptors,
} as SmartDeviceModelOptions;
/**
* SmartDevices 定义来自于 typings/sdm.d.ts,非 TypeScript 开发者可忽略
* The SmartDevices definition comes from typings/sdm.d.ts and can be ignored by non-TypeScript developers
*/
export const devices = {
/**
* 此处建议以智能设备的名称作为键名赋值
* It is recommended to assign the name of the smart device as the key name.
*/
// common: new SmartDeviceModel<SmartDeviceSchema>(options),
common: isGroupDevice
? new SmartGroupModel<SmartDeviceSchema>()
: new SmartDeviceModel<SmartDeviceSchema, { alarm: SmartAlarmAbility }>(options),
};
src/pages/home/index.tsx
Code: Select all
import React from 'react';
import { showToast, View } from '@ray-js/ray';
import { useCustomAlarm, useDevice } from '@ray-js/panel-sdk';
import { NavBar, Button, Slider, Switch, CellGroup, Cell } from '@ray-js/smart-ui';
import styles from './index.module.less';
const Section = ({ title, children }) => {
return (
<View className={styles.section}>
<View className={styles.title}>{title}</View>
{children}
</View>
);
};
export function Home() {
const tempCurrentDpId = useDevice(device => device.devInfo.codeIds.temp_current);
const tempCurrentSchema = useDevice(device => device.dpSchema.temp_current);
const {
data,
loading,
addCustomAlarm,
getCustomAlarmList,
setCustomAlarmStatus,
deleteCustomAlarm,
} = useCustomAlarm();
const handleValueChange = React.useCallback(evt => {
const [start, end] = evt.detail;
addCustomAlarm({
name: `${start}~${end}`,
condition: [
[tempCurrentDpId, '<', start],
[tempCurrentDpId, '>=', end],
],
})
.then(data => {
console.log('🚀 ~ addCustomAlarm ~ success:', data);
showToast({ title: '温度上下限告警设置成功', icon: 'none' });
})
.catch(err => {
console.log('🚀 ~ addCustomAlarm ~ failed:', err);
showToast({ title: '温度上下限告警设置失败', icon: 'error' });
});
}, []);
const handleStatusChange = React.useCallback(
evt => {
const bindId = data?.[0]?.bindId;
if (typeof bindId === 'undefined') {
showToast({ title: '当前不存在可切换状态的告警', icon: 'error' });
return;
}
setCustomAlarmStatus({ bindId, enable: evt.detail })
.then(data => {
console.log('🚀 ~ setCustomAlarmStatus ~ success:', data);
showToast({ title: '温度上下限告警切换状态成功', icon: 'none' });
})
.catch(err => {
console.log('🚀 ~ setCustomAlarmStatus ~ failed:', err);
showToast({ title: '温度上下限告警切换状态失败', icon: 'error' });
});
},
[data]
);
const handleDelete = React.useCallback(
evt => {
const bindId = data?.[0]?.bindId;
if (typeof bindId === 'undefined') {
showToast({ title: '当前不存在可删除的告警', icon: 'error' });
return;
}
deleteCustomAlarm({ bindId })
.then(data => {
console.log('🚀 ~ deleteCustomAlarm ~ success:', data);
showToast({ title: '温度上下限告警删除成功', icon: 'none' });
})
.catch(err => {
console.log('🚀 ~ deleteCustomAlarm ~ failed:', err);
showToast({ title: '温度上下限告警删除失败', icon: 'error' });
});
},
[data]
);
React.useEffect(() => {
getCustomAlarmList();
}, []);
const conds = data?.[0]?.triggerRuleVO?.conditions;
const checked = data?.[0]?.triggerRuleVO?.enabled;
const tempRangeValue = [conds?.[0]?.expr?.[0]?.[2] ?? 0, conds?.[1]?.expr?.[0]?.[2] ?? 10];
return (
<>
<NavBar leftText="Home" leftTextType="home" />
<View className={styles.view}>
<View className={styles.content}>
<Section title="查看">
<CellGroup>
{data.map(d => {
const name = d?.triggerRuleVO?.name;
const conds = d?.triggerRuleVO?.conditions;
return (
<Cell
key={d.bindId}
title={name || `bindId: ${d.bindId}`}
label={`下限: ${conds?.[0]?.expr?.[0]?.[2]}; 上限: ${conds?.[1]?.expr?.[0]?.[2]}`}
// @ts-ignore
value={d.enable ? '启用' : '禁用'}
isLink={false}
/>
);
})}
</CellGroup>
</Section>
<Section title="新增/修改">
<View className={styles['slider-wrapper']}>
<Slider.RangeSlider
min={tempCurrentSchema.property.min ?? 0}
max={tempCurrentSchema.property.max ?? 100}
barHeight="4px"
value={tempRangeValue.map(v => +v)}
inActiveColor="#000000"
activeColor="#007AFF"
onChange={handleValueChange}
/>
</View>
</Section>
<Section title="启用/禁用">
<Switch checked={checked} onChange={handleStatusChange} />
</Section>
<Section title="删除">
<Button type="danger" onClick={handleDelete}>
点击删除温度上下限告警
</Button>
</Section>
</View>
</View>
</>
);
}
export default Home;
Code: Select all
.view {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
width: 100%;
height: 100%;
background-color: #efefef;
}
.content {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
width: 100%;
padding: 32rpx;
}
.section {
margin: 16px 0;
width: 100%;
}
.title {
margin-bottom: 12px;
text-align: left;
font-size: 38rpx;
font-weight: 500;
color: #000;
}
.slider-wrapper {
--slider-inactive-background-color: #ffffff;
width: 300px;
margin-top: 32px;
}
实际的执行效果见附件,另外请务必注意以下环境要求:
传感/环境/温湿度传感器
,且必须存在 temp_current 功能点。(当然该 API 不限制品类,如果要运行该 Demo 则必须满足该要求)