diff --git a/interface/src/project/DashboardDevices.tsx b/interface/src/project/DashboardDevices.tsx index 8a337d8ac..e3a9f8701 100644 --- a/interface/src/project/DashboardDevices.tsx +++ b/interface/src/project/DashboardDevices.tsx @@ -35,7 +35,7 @@ import DashboarDevicesDialog from './DashboardDevicesDialog'; import DeviceIcon from './DeviceIcon'; import * as EMSESP from './api'; -import { formatValue, isNumberUOM } from './deviceValue'; +import { formatValue } from './deviceValue'; import { DeviceValueUOM_s, DeviceEntityMask } from './types'; import { deviceValueItemValidation } from './validators'; @@ -186,12 +186,10 @@ const DashboardDevices: FC = () => { ); const fetchDeviceData = async (id: number) => { - if (!deviceValueDialogOpen) { - try { - setDeviceData((await EMSESP.readDeviceData({ id })).data); - } catch (error) { - toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING())); - } + try { + setDeviceData((await EMSESP.readDeviceData({ id })).data); + } catch (error) { + toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING())); } }; @@ -208,6 +206,9 @@ const DashboardDevices: FC = () => { }, [fetchCoreData]); const refreshData = () => { + if (deviceValueDialogOpen) { + return; + } if (selectedDevice) { void fetchDeviceData(selectedDevice); } else { @@ -288,9 +289,10 @@ const DashboardDevices: FC = () => { }); const deviceValueDialogSave = async (dv: DeviceValue) => { + const selectedDeviceID = Number(device_select.state.id); try { const response = await EMSESP.writeDeviceValue({ - id: Number(device_select.state.id), + id: selectedDeviceID, devicevalue: dv }); if (response.status === 204) { @@ -304,8 +306,8 @@ const DashboardDevices: FC = () => { toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING())); } finally { setDeviceValueDialogOpen(false); + await fetchDeviceData(selectedDeviceID); setSelectedDeviceValue(undefined); - refreshData(); } }; @@ -515,7 +517,7 @@ const DashboardDevices: FC = () => { onClose={deviceValueDialogClose} onSave={deviceValueDialogSave} selectedItem={selectedDeviceValue} - validator={deviceValueItemValidation(isNumberUOM(selectedDeviceValue.u))} + validator={deviceValueItemValidation(selectedDeviceValue)} /> )} diff --git a/interface/src/project/deviceValue.ts b/interface/src/project/deviceValue.ts index 0c1088349..825269c8c 100644 --- a/interface/src/project/deviceValue.ts +++ b/interface/src/project/deviceValue.ts @@ -76,10 +76,3 @@ export const formatValueNoUOM = (value: any, uom: number) => { return value; } }; - -export function isNumberUOM(uom: number) { - if (uom === DeviceValueUOM.NONE) { - return false; - } - return true; -} diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index af7e86bd9..8397e5d1f 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -128,9 +128,9 @@ export interface DeviceValue { c?: string; // command, optional l?: string[]; // list, optional h?: string; // help text, optional - s?: string; // steps for up/down, optional - m?: string; // min, optional - x?: string; // max, optional + s?: number; // steps for up/down, optional + m?: number; // min, optional + x?: number; // max, optional } export interface DeviceData { diff --git a/interface/src/project/validators.ts b/interface/src/project/validators.ts index d9b65bf8a..de3ae8ee3 100644 --- a/interface/src/project/validators.ts +++ b/interface/src/project/validators.ts @@ -1,5 +1,6 @@ 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 { 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({ v: [ { required: true, message: 'Value is required' }, { validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { - if (isNumber && isNaN(+value)) { - callback('Not a valid number'); + if (dv.u !== DeviceValueUOM.NONE && isNaN(+value)) { + // 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(); } } ] diff --git a/mock-api/server.js b/mock-api/server.js index 6a94db470..f18627608 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -474,10 +474,12 @@ const emsesp_devicedata_1 = { id: '00date/time' }, { - v: 18, + v: 18.2, u: 1, - id: '00hc1 selected room temperature', - c: 'hc1/seltemp' + id: '00Chosen Room Temperature', + c: 'hc1/seltemp', + m: 5, + x: 52 }, { v: 22.6, @@ -693,7 +695,7 @@ const emsesp_deviceentities_1 = [ }, { v: 18.2, - n: 'hc1 selected room temperature', + n: 'Chosen Room Temperature', id: 'hc1/seltemp', m: 0, mi: 5,