import { useCallback, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; import CancelIcon from '@mui/icons-material/Cancel'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; import WarningIcon from '@mui/icons-material/Warning'; import { Box, Button, Checkbox, Grid, InputAdornment, MenuItem, TextField, Typography } from '@mui/material'; import * as MqttApi from 'api/mqtt'; import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, BlockNavigation, ButtonRow, FormLoader, SectionContent, ValidatedPasswordField, ValidatedTextField, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { MqttSettingsType } from 'types'; import { numberValue, updateValueDirty, useRest } from 'utils'; import { createMqttSettingsValidator, validate } from 'validators'; import { callAction } from '../../api/app'; const MqttSettings = () => { const { loadData, saving, data, updateDataValue, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } = useRest({ read: MqttApi.readMqttSettings, update: MqttApi.updateMqttSettings }); const { LL } = useI18nContext(); useLayoutTitle('MQTT'); const [fieldErrors, setFieldErrors] = useState(); const sendResetMQTT = useCallback(() => { void callAction({ action: 'resetMQTT' }) .then(() => { toast.success('MQTT ' + LL.REFRESH() + ' successful'); }) .catch((error) => { toast.error(String(error.error?.message || 'An error occurred')); }); }, []); const updateFormValue = useMemo( () => updateValueDirty( origData as unknown as Record, dirtyFlags, setDirtyFlags, updateDataValue as (value: unknown) => void ), [origData, dirtyFlags, setDirtyFlags, updateDataValue] ); const SecondsInputProps = useMemo( () => ({ endAdornment: {LL.SECONDS()} }), [LL] ); const emptyFieldErrors = useMemo(() => ({}), []); const validateAndSubmit = useCallback(async () => { if (!data) return; try { setFieldErrors(undefined); await validate(createMqttSettingsValidator(data), data); await saveData(); } catch (error) { setFieldErrors(error as ValidateFieldsError); } }, [data, saveData]); const publishIntervalFields = useMemo( () => [ { name: 'publish_time_heartbeat', label: 'Heartbeat', validated: true }, { name: 'publish_time_boiler', label: LL.MQTT_INT_BOILER(), validated: false }, { name: 'publish_time_thermostat', label: LL.MQTT_INT_THERMOSTATS(), validated: false }, { name: 'publish_time_solar', label: LL.MQTT_INT_SOLAR(), validated: false }, { name: 'publish_time_mixer', label: LL.MQTT_INT_MIXER(), validated: false }, { name: 'publish_time_water', label: LL.MQTT_INT_WATER(), validated: false }, { name: 'publish_time_sensor', label: LL.SENSORS(), validated: false }, { name: 'publish_time_other', label: LL.DEFAULT(0), validated: false } ], [LL] ); if (!data) { return ( {blocker ? : null} ); } return ( {blocker ? : null} <> } label={LL.ENABLE_MQTT()} /> {data.enabled && ( )} 0 1 2 {data.enableTLS !== undefined && ( } label={LL.ENABLE_TLS()} /> )} {data.enableTLS === true && ( )} } label={LL.MQTT_CLEAN_SESSION()} /> } label={LL.MQTT_RETAIN_FLAG()} /> {LL.FORMATTING()} {LL.MQTT_NEST_1()} {LL.MQTT_NEST_2()} } label={LL.MQTT_RESPONSE()} /> } label={LL.MQTT_PUBLISH_TEXT_1()} /> {data.publish_single && ( } label={LL.MQTT_PUBLISH_TEXT_2()} /> )} } label={LL.MQTT_PUBLISH_TEXT_3()} /> {data.ha_enabled && ( Home Assistant Domoticz Domoticz (latest) {LL.MQTT_ENTITY_FORMAT_0()} {LL.MQTT_ENTITY_FORMAT_1()} (v3.5) {LL.MQTT_ENTITY_FORMAT_2()} (v3.5) {LL.MQTT_ENTITY_FORMAT_1()} (latest) {LL.MQTT_ENTITY_FORMAT_2()} (latest) )} {LL.MQTT_PUBLISH_INTERVALS()} (0=auto) {publishIntervalFields.map((field) => ( {field.validated ? ( ) : ( )} ))} {dirtyFlags && dirtyFlags.length !== 0 && ( )} ); }; export default MqttSettings;