diff --git a/interface/src/app/main/Scheduler.tsx b/interface/src/app/main/Scheduler.tsx index 827ae75ee..74f2a40b5 100644 --- a/interface/src/app/main/Scheduler.tsx +++ b/interface/src/app/main/Scheduler.tsx @@ -160,6 +160,9 @@ const Scheduler: FC = () => { setCreating(false); setSelectedScheduleItem(si); setDialogOpen(true); + if (si.o_name === undefined) { + si.o_name = si.name; + } }, []); const onDialogClose = () => { diff --git a/interface/src/app/main/Sensors.tsx b/interface/src/app/main/Sensors.tsx index 7f4a91116..039ba37bb 100644 --- a/interface/src/app/main/Sensors.tsx +++ b/interface/src/app/main/Sensors.tsx @@ -255,6 +255,7 @@ const Sensors: FC = () => { const updateTemperatureSensor = (ts: TemperatureSensor) => { if (me.admin) { + ts.o_n = ts.n; setSelectedTemperatureSensor(ts); setTemperatureDialogOpen(true); } @@ -282,6 +283,7 @@ const Sensors: FC = () => { const updateAnalogSensor = (as: AnalogSensor) => { if (me.admin) { setCreating(false); + as.o_n = as.n; setSelectedAnalogSensor(as); setAnalogDialogOpen(true); } @@ -302,7 +304,8 @@ const Sensors: FC = () => { o: 0, t: 0, f: 1, - d: false + d: false, + o_n: '' }); setAnalogDialogOpen(true); }; @@ -465,7 +468,10 @@ const Sensors: FC = () => { onClose={onTemperatureDialogClose} onSave={onTemperatureDialogSave} selectedItem={selectedTemperatureSensor} - validator={temperatureSensorItemValidation(sensorData.ts)} + validator={temperatureSensorItemValidation( + sensorData.ts, + selectedTemperatureSensor + )} /> )} {sensorData?.analog_enabled === true && ( @@ -483,6 +489,7 @@ const Sensors: FC = () => { selectedItem={selectedAnalogSensor} validator={analogSensorItemValidation( sensorData.as, + selectedAnalogSensor, creating, sensorData.platform )} diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts index 05907fcfb..f7a6edbf5 100644 --- a/interface/src/app/main/types.ts +++ b/interface/src/app/main/types.ts @@ -79,6 +79,7 @@ export interface TemperatureSensor { t?: number; // temp, optional o: number; // offset u: number; // uom + o_n?: string; } export interface AnalogSensor { @@ -91,6 +92,7 @@ export interface AnalogSensor { f: number; t: number; d: boolean; // deleted flag + o_n?: string; } export interface WriteTemperatureSensor { diff --git a/interface/src/app/main/validators.ts b/interface/src/app/main/validators.ts index b5bb94c9b..92bb00d15 100644 --- a/interface/src/app/main/validators.ts +++ b/interface/src/app/main/validators.ts @@ -241,6 +241,25 @@ export const createSettingsValidator = (settings: Settings) => { type: 'number', min: 0, max: 10, message: 'Must be between 0 and 10' } ] }), + ...(settings.modbus_enabled && { + modbus_max_clients: [ + { required: true, message: 'Max clients is required' }, + { type: 'number', min: 0, max: 50, message: 'Invalid number' } + ], + modbus_port: [ + { required: true, message: 'Port is required' }, + { type: 'number', min: 0, max: 65535, message: 'Invalid Port' } + ], + modbus_timeout: [ + { required: true, message: 'Timeout is required' }, + { + type: 'number', + min: 100, + max: 20000, + message: 'Must be between 100 and 20000' + } + ] + }), ...(settings.shower_timer && { shower_min_duration: [ { @@ -388,9 +407,16 @@ export const entityItemValidation = (entity: EntityItem[], entityItem: EntityIte ] }); -export const uniqueTemperatureNameValidator = (sensors: TemperatureSensor[]) => ({ +export const uniqueTemperatureNameValidator = ( + sensors: TemperatureSensor[], + o_name?: string +) => ({ validator(rule: InternalRuleItem, n: string, callback: (error?: string) => void) { - if (n !== '' && sensors.find((ts) => ts.n.toLowerCase() === n.toLowerCase())) { + if ( + (o_name === undefined || o_name.toLowerCase() !== n.toLowerCase()) && + n !== '' && + sensors.find((ts) => ts.n.toLowerCase() === n.toLowerCase()) + ) { callback('Name already in use'); } else { callback(); @@ -398,7 +424,10 @@ export const uniqueTemperatureNameValidator = (sensors: TemperatureSensor[]) => } }); -export const temperatureSensorItemValidation = (sensors: TemperatureSensor[]) => +export const temperatureSensorItemValidation = ( + sensors: TemperatureSensor[], + sensor: TemperatureSensor +) => new Schema({ n: [ { @@ -406,7 +435,7 @@ export const temperatureSensorItemValidation = (sensors: TemperatureSensor[]) => pattern: /^[a-zA-Z0-9_]{0,19}$/, message: "Must be <20 characters: alphanumeric or '_'" }, - ...[uniqueTemperatureNameValidator(sensors)] + ...[uniqueTemperatureNameValidator(sensors, sensor.o_n)] ] }); @@ -424,9 +453,16 @@ export const isGPIOUniqueValidator = (sensors: AnalogSensor[]) => ({ } }); -export const uniqueAnalogNameValidator = (sensors: AnalogSensor[]) => ({ +export const uniqueAnalogNameValidator = ( + sensors: AnalogSensor[], + o_name?: string +) => ({ validator(rule: InternalRuleItem, n: string, callback: (error?: string) => void) { - if (n !== '' && sensors.find((as) => as.n.toLowerCase() === n.toLowerCase())) { + if ( + (o_name === undefined || o_name.toLowerCase() !== n.toLowerCase()) && + n !== '' && + sensors.find((as) => as.n.toLowerCase() === n.toLowerCase()) + ) { callback('Name already in use'); } else { callback(); @@ -436,6 +472,7 @@ export const uniqueAnalogNameValidator = (sensors: AnalogSensor[]) => ({ export const analogSensorItemValidation = ( sensors: AnalogSensor[], + sensor: AnalogSensor, creating: boolean, platform: string ) => @@ -446,7 +483,7 @@ export const analogSensorItemValidation = ( pattern: /^[a-zA-Z0-9_]{0,19}$/, message: "Must be <20 characters: alphanumeric or '_'" }, - ...[uniqueAnalogNameValidator(sensors)] + ...[uniqueAnalogNameValidator(sensors, sensor.o_n)] ], g: [ { required: true, message: 'GPIO is required' },