add check for min/max when sending device values

This commit is contained in:
proddy
2023-04-30 09:53:10 +02:00
parent ceb63fa09f
commit 8a02f2a27a
5 changed files with 31 additions and 29 deletions

View File

@@ -35,7 +35,7 @@ import DashboarDevicesDialog from './DashboardDevicesDialog';
import DeviceIcon from './DeviceIcon'; import DeviceIcon from './DeviceIcon';
import * as EMSESP from './api'; import * as EMSESP from './api';
import { formatValue, isNumberUOM } from './deviceValue'; import { formatValue } from './deviceValue';
import { DeviceValueUOM_s, DeviceEntityMask } from './types'; import { DeviceValueUOM_s, DeviceEntityMask } from './types';
import { deviceValueItemValidation } from './validators'; import { deviceValueItemValidation } from './validators';
@@ -186,12 +186,10 @@ const DashboardDevices: FC = () => {
); );
const fetchDeviceData = async (id: number) => { const fetchDeviceData = async (id: number) => {
if (!deviceValueDialogOpen) { try {
try { setDeviceData((await EMSESP.readDeviceData({ id })).data);
setDeviceData((await EMSESP.readDeviceData({ id })).data); } catch (error) {
} catch (error) { toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING()));
toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING()));
}
} }
}; };
@@ -208,6 +206,9 @@ const DashboardDevices: FC = () => {
}, [fetchCoreData]); }, [fetchCoreData]);
const refreshData = () => { const refreshData = () => {
if (deviceValueDialogOpen) {
return;
}
if (selectedDevice) { if (selectedDevice) {
void fetchDeviceData(selectedDevice); void fetchDeviceData(selectedDevice);
} else { } else {
@@ -288,9 +289,10 @@ const DashboardDevices: FC = () => {
}); });
const deviceValueDialogSave = async (dv: DeviceValue) => { const deviceValueDialogSave = async (dv: DeviceValue) => {
const selectedDeviceID = Number(device_select.state.id);
try { try {
const response = await EMSESP.writeDeviceValue({ const response = await EMSESP.writeDeviceValue({
id: Number(device_select.state.id), id: selectedDeviceID,
devicevalue: dv devicevalue: dv
}); });
if (response.status === 204) { if (response.status === 204) {
@@ -304,8 +306,8 @@ const DashboardDevices: FC = () => {
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING())); toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
} finally { } finally {
setDeviceValueDialogOpen(false); setDeviceValueDialogOpen(false);
await fetchDeviceData(selectedDeviceID);
setSelectedDeviceValue(undefined); setSelectedDeviceValue(undefined);
refreshData();
} }
}; };
@@ -515,7 +517,7 @@ const DashboardDevices: FC = () => {
onClose={deviceValueDialogClose} onClose={deviceValueDialogClose}
onSave={deviceValueDialogSave} onSave={deviceValueDialogSave}
selectedItem={selectedDeviceValue} selectedItem={selectedDeviceValue}
validator={deviceValueItemValidation(isNumberUOM(selectedDeviceValue.u))} validator={deviceValueItemValidation(selectedDeviceValue)}
/> />
)} )}

View File

@@ -76,10 +76,3 @@ export const formatValueNoUOM = (value: any, uom: number) => {
return value; return value;
} }
}; };
export function isNumberUOM(uom: number) {
if (uom === DeviceValueUOM.NONE) {
return false;
}
return true;
}

View File

@@ -128,9 +128,9 @@ export interface DeviceValue {
c?: string; // command, optional c?: string; // command, optional
l?: string[]; // list, optional l?: string[]; // list, optional
h?: string; // help text, optional h?: string; // help text, optional
s?: string; // steps for up/down, optional s?: number; // steps for up/down, optional
m?: string; // min, optional m?: number; // min, optional
x?: string; // max, optional x?: number; // max, optional
} }
export interface DeviceData { export interface DeviceData {

View File

@@ -1,5 +1,6 @@
import Schema from 'async-validator'; import Schema from 'async-validator';
import type { AnalogSensor, Settings } from './types'; import { DeviceValueUOM } from './types';
import type { AnalogSensor, DeviceValue, Settings } from './types';
import type { InternalRuleItem } from 'async-validator'; import type { InternalRuleItem } from 'async-validator';
import { IP_OR_HOSTNAME_VALIDATOR } from 'validators/shared'; import { IP_OR_HOSTNAME_VALIDATOR } from 'validators/shared';
@@ -162,16 +163,20 @@ export const analogSensorItemValidation = (sensors: AnalogSensor[], creating: bo
] ]
}); });
export const deviceValueItemValidation = (isNumber: boolean) => export const deviceValueItemValidation = (dv: DeviceValue) =>
new Schema({ new Schema({
v: [ v: [
{ required: true, message: 'Value is required' }, { required: true, message: 'Value is required' },
{ {
validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) {
if (isNumber && isNaN(+value)) { if (dv.u !== DeviceValueUOM.NONE && isNaN(+value)) {
callback('Not a valid number'); // not a number
dv.m && dv.x ? callback('Must be a number between ' + dv.m + ' and ' + dv.x) : callback('Must be a number');
} }
callback(); // is a number
(dv.m && Number(value) < dv.m) || (dv.x && Number(value) > dv.x)
? callback('Must be between ' + dv.m + ' and ' + dv.x)
: callback();
} }
} }
] ]

View File

@@ -474,10 +474,12 @@ const emsesp_devicedata_1 = {
id: '00date/time' id: '00date/time'
}, },
{ {
v: 18, v: 18.2,
u: 1, u: 1,
id: '00hc1 selected room temperature', id: '00Chosen Room Temperature',
c: 'hc1/seltemp' c: 'hc1/seltemp',
m: 5,
x: 52
}, },
{ {
v: 22.6, v: 22.6,
@@ -693,7 +695,7 @@ const emsesp_deviceentities_1 = [
}, },
{ {
v: 18.2, v: 18.2,
n: 'hc1 selected room temperature', n: 'Chosen Room Temperature',
id: 'hc1/seltemp', id: 'hc1/seltemp',
m: 0, m: 0,
mi: 5, mi: 5,