Files
EMS-ESP32/interface/src/framework/mqtt/MqttSettingsForm.tsx
2022-04-08 11:58:48 +02:00

336 lines
11 KiB
TypeScript

import { FC, useState } from 'react';
import { ValidateFieldsError } from 'async-validator';
import { Button, Checkbox, MenuItem, Grid, Typography } from '@mui/material';
import SaveIcon from '@mui/icons-material/Save';
import { MQTT_SETTINGS_VALIDATOR, validate } from '../../validators';
import {
BlockFormControlLabel,
ButtonRow,
FormLoader,
SectionContent,
ValidatedPasswordField,
ValidatedTextField
} from '../../components';
import { MqttSettings } from '../../types';
import { numberValue, updateValue, useRest } from '../../utils';
import * as MqttApi from '../../api/mqtt';
const MqttSettingsForm: FC = () => {
const { loadData, saving, data, setData, saveData, errorMessage } = useRest<MqttSettings>({
read: MqttApi.readMqttSettings,
update: MqttApi.updateMqttSettings
});
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const updateFormValue = updateValue(setData);
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
}
const validateAndSubmit = async () => {
try {
setFieldErrors(undefined);
await validate(MQTT_SETTINGS_VALIDATOR, data);
saveData();
} catch (errors: any) {
setFieldErrors(errors);
}
};
return (
<>
<BlockFormControlLabel
control={<Checkbox name="enabled" checked={data.enabled} onChange={updateFormValue} />}
label="Enable MQTT"
/>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={6}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="host"
label="Host"
fullWidth
variant="outlined"
value={data.host}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={6}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="port"
label="Port"
fullWidth
variant="outlined"
value={numberValue(data.port)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
</Grid>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={6}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="base"
label="Bsse"
fullWidth
variant="outlined"
value={data.base}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={6}>
<ValidatedTextField
name="client_id"
label="Client ID (optional)"
fullWidth
variant="outlined"
value={data.client_id}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
</Grid>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={6}>
<ValidatedTextField
name="username"
label="Username"
fullWidth
variant="outlined"
value={data.username}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={6}>
<ValidatedPasswordField
name="password"
label="Password"
fullWidth
variant="outlined"
value={data.password}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
</Grid>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={6}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="keep_alive"
label="Keep Alive (seconds)"
fullWidth
variant="outlined"
value={numberValue(data.keep_alive)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={6}>
<ValidatedTextField
name="mqtt_qos"
label="QoS"
value={data.mqtt_qos}
fullWidth
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={0}>0 (default)</MenuItem>
<MenuItem value={1}>1</MenuItem>
<MenuItem value={2}>2</MenuItem>
</ValidatedTextField>
</Grid>
</Grid>
<BlockFormControlLabel
control={<Checkbox name="clean_session" checked={data.clean_session} onChange={updateFormValue} />}
label="Set Clean Session"
/>
<BlockFormControlLabel
control={<Checkbox name="mqtt_retain" checked={data.mqtt_retain} onChange={updateFormValue} />}
label="Always use Retain Flag"
/>
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
Formatting
</Typography>
<ValidatedTextField
name="nested_format"
label="Topic/Payload Format"
value={data.nested_format}
fullWidth
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={1}>Nested in a single topic</MenuItem>
<MenuItem value={2}>As individual topics</MenuItem>
</ValidatedTextField>
<BlockFormControlLabel
control={<Checkbox name="send_response" checked={data.send_response} onChange={updateFormValue} />}
label="Publish command output to a 'response' topic"
/>
{!data.ha_enabled && (
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item>
<BlockFormControlLabel
control={<Checkbox name="publish_single" checked={data.publish_single} onChange={updateFormValue} />}
label="Publish single value topics on change"
/>
</Grid>
{data.publish_single && (
<Grid item>
<BlockFormControlLabel
control={
<Checkbox name="publish_single2cmd" checked={data.publish_single2cmd} onChange={updateFormValue} />
}
label="Publish to command topics (ioBroker)"
/>
</Grid>
)}
</Grid>
)}
{!data.publish_single && (
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item>
<BlockFormControlLabel
control={<Checkbox name="ha_enabled" checked={data.ha_enabled} onChange={updateFormValue} />}
label="Enable MQTT Discovery (Home Assistant, Domoticz)"
/>
</Grid>
{data.ha_enabled && (
<Grid item xs={6}>
<ValidatedTextField
name="discovery_prefix"
label="Prefix for the Discovery topics"
fullWidth
variant="outlined"
value={data.discovery_prefix}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
)}
</Grid>
)}
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
Publish Intervals (in seconds, 0=automatic)
</Typography>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={4}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="publish_time_boiler"
label="Boilers and Heat Pumps"
fullWidth
variant="outlined"
value={numberValue(data.publish_time_boiler)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={4}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="publish_time_thermostat"
label="Thermostats"
fullWidth
variant="outlined"
value={numberValue(data.publish_time_thermostat)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={4}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="publish_time_solar"
label="Solar Modules"
fullWidth
variant="outlined"
value={numberValue(data.publish_time_solar)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={4}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="publish_time_mixer"
label="Mixer Modules"
fullWidth
variant="outlined"
value={numberValue(data.publish_time_mixer)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={4}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="publish_time_sensor"
label="Temperature Sensors"
fullWidth
variant="outlined"
value={numberValue(data.publish_time_sensor)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={4}>
<ValidatedTextField
fieldErrors={fieldErrors}
name="publish_time_other"
label="Default"
fullWidth
variant="outlined"
value={numberValue(data.publish_time_other)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
</Grid>
<ButtonRow>
<Button
startIcon={<SaveIcon />}
disabled={saving}
variant="outlined"
color="primary"
type="submit"
onClick={validateAndSubmit}
>
Save
</Button>
</ButtonRow>
</>
);
};
return (
<SectionContent title="MQTT Settings" titleGutter>
{content()}
</SectionContent>
);
};
export default MqttSettingsForm;