mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
moved mqtt and system to correct web pages
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
import { TextValidator, ValidatorForm, SelectValidator } from 'react-material-ui-form-validator';
|
||||||
|
|
||||||
import { Checkbox, TextField } from '@material-ui/core';
|
import { Checkbox, TextField } from '@material-ui/core';
|
||||||
import SaveIcon from '@material-ui/icons/Save';
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
|
||||||
import { RestFormProps, FormActions, FormButton, BlockFormControlLabel, PasswordValidator } from '../components';
|
import { RestFormProps, FormActions, FormButton, BlockFormControlLabel, PasswordValidator } from '../components';
|
||||||
import { isIP, isHostname, or } from '../validators';
|
import { isIP, isHostname, or } from '../validators';
|
||||||
@@ -115,6 +116,51 @@ class MqttSettingsForm extends React.Component<MqttSettingsFormProps> {
|
|||||||
onChange={handleValueChange('max_topic_length')}
|
onChange={handleValueChange('max_topic_length')}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
checked={data.system_heartbeat}
|
||||||
|
onChange={handleValueChange('system_heartbeat')}
|
||||||
|
value="system_heartbeat"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="MQTT Heartbeat"
|
||||||
|
/>
|
||||||
|
<SelectValidator name="mqtt_format"
|
||||||
|
label="MQTT Format"
|
||||||
|
value={data.mqtt_format}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleValueChange('mqtt_format')}
|
||||||
|
margin="normal">
|
||||||
|
<MenuItem value={1}>Single</MenuItem>
|
||||||
|
<MenuItem value={2}>Nested</MenuItem>
|
||||||
|
<MenuItem value={3}>Home Assistant</MenuItem>
|
||||||
|
<MenuItem value={4}>Custom</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
|
<SelectValidator name="mqtt_qos"
|
||||||
|
label="MQTT QoS"
|
||||||
|
value={data.mqtt_qos}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleValueChange('mqtt_qos')}
|
||||||
|
margin="normal">
|
||||||
|
<MenuItem value={0}>0</MenuItem>
|
||||||
|
<MenuItem value={1}>1</MenuItem>
|
||||||
|
<MenuItem value={2}>2</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:1', 'maxNumber:65535']}
|
||||||
|
errorMessages={['Publish time is required', "Must be a number", "Must be greater than 0", "Max value is 65535"]}
|
||||||
|
name="publish_time"
|
||||||
|
label="MQTT Publish Time (seconds)"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={data.publish_time}
|
||||||
|
type="number"
|
||||||
|
onChange={handleValueChange('publish_time')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
<FormActions>
|
<FormActions>
|
||||||
<FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit">
|
<FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit">
|
||||||
Save
|
Save
|
||||||
|
|||||||
@@ -43,3 +43,15 @@ export const disconnectReason = ({ disconnect_reason }: MqttStatus) => {
|
|||||||
return "Unknown"
|
return "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const mqttStatusHighlight2 = ({ mqtt_fails }: MqttStatus, theme: Theme) => {
|
||||||
|
|
||||||
|
if (mqtt_fails === 0)
|
||||||
|
return theme.palette.success.main;
|
||||||
|
|
||||||
|
if (mqtt_fails < 10)
|
||||||
|
return theme.palette.warning.main;
|
||||||
|
|
||||||
|
return theme.palette.success.main;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,9 +6,10 @@ import { Avatar, Divider, List, ListItem, ListItemAvatar, ListItemText } from '@
|
|||||||
import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
||||||
import RefreshIcon from '@material-ui/icons/Refresh';
|
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||||
import ReportIcon from '@material-ui/icons/Report';
|
import ReportIcon from '@material-ui/icons/Report';
|
||||||
|
import SpeakerNotesOffIcon from "@material-ui/icons/SpeakerNotesOff";
|
||||||
|
|
||||||
import { RestFormProps, FormActions, FormButton, HighlightAvatar } from '../components';
|
import { RestFormProps, FormActions, FormButton, HighlightAvatar } from '../components';
|
||||||
import { mqttStatusHighlight, mqttStatus, disconnectReason } from './MqttStatus';
|
import { mqttStatusHighlight, mqttStatus, mqttStatusHighlight2, disconnectReason } from './MqttStatus';
|
||||||
import { MqttStatus } from './types';
|
import { MqttStatus } from './types';
|
||||||
|
|
||||||
type MqttStatusFormProps = RestFormProps<MqttStatus> & WithTheme;
|
type MqttStatusFormProps = RestFormProps<MqttStatus> & WithTheme;
|
||||||
@@ -16,7 +17,7 @@ type MqttStatusFormProps = RestFormProps<MqttStatus> & WithTheme;
|
|||||||
class MqttStatusForm extends Component<MqttStatusFormProps> {
|
class MqttStatusForm extends Component<MqttStatusFormProps> {
|
||||||
|
|
||||||
renderConnectionStatus() {
|
renderConnectionStatus() {
|
||||||
const { data } = this.props
|
const { data, theme } = this.props
|
||||||
if (data.connected) {
|
if (data.connected) {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@@ -27,6 +28,17 @@ class MqttStatusForm extends Component<MqttStatusFormProps> {
|
|||||||
<ListItemText primary="Client ID" secondary={data.client_id} />
|
<ListItemText primary="Client ID" secondary={data.client_id} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
|
<ListItem>
|
||||||
|
<ListItemAvatar>
|
||||||
|
<HighlightAvatar color={mqttStatusHighlight2(data, theme)}>
|
||||||
|
<SpeakerNotesOffIcon />
|
||||||
|
</HighlightAvatar>
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText
|
||||||
|
primary="MQTT Publish Errors"
|
||||||
|
secondary={data.mqtt_fails}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export interface MqttStatus {
|
|||||||
connected: boolean;
|
connected: boolean;
|
||||||
client_id: string;
|
client_id: string;
|
||||||
disconnect_reason: MqttDisconnectReason;
|
disconnect_reason: MqttDisconnectReason;
|
||||||
|
mqtt_fails: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MqttSettings {
|
export interface MqttSettings {
|
||||||
@@ -26,4 +27,8 @@ export interface MqttSettings {
|
|||||||
keep_alive: number;
|
keep_alive: number;
|
||||||
clean_session: boolean;
|
clean_session: boolean;
|
||||||
max_topic_length: number;
|
max_topic_length: number;
|
||||||
|
publish_time: number;
|
||||||
|
mqtt_format: number;
|
||||||
|
mqtt_qos: number;
|
||||||
|
system_heartbeat: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
35
interface/src/project/EMSESPSettings.tsx
Normal file
35
interface/src/project/EMSESPSettings.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import { Redirect, Switch, RouteComponentProps } from 'react-router-dom'
|
||||||
|
|
||||||
|
import { Tabs, Tab } from '@material-ui/core';
|
||||||
|
|
||||||
|
import { PROJECT_PATH } from '../api';
|
||||||
|
import { MenuAppBar } from '../components';
|
||||||
|
import { AuthenticatedRoute } from '../authentication';
|
||||||
|
|
||||||
|
import EMSESPSettingsController from './EMSESPSettingsController';
|
||||||
|
|
||||||
|
class EMSESP extends Component<RouteComponentProps> {
|
||||||
|
|
||||||
|
handleTabChange = (event: React.ChangeEvent<{}>, path: string) => {
|
||||||
|
this.props.history.push(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<MenuAppBar sectionTitle="Settings">
|
||||||
|
<Tabs value={this.props.match.url} onChange={this.handleTabChange} variant="fullWidth">
|
||||||
|
<Tab value={`/${PROJECT_PATH}/settings`} label="EMS-ESP Settings" />
|
||||||
|
</Tabs>
|
||||||
|
<Switch>
|
||||||
|
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/settings`} component={EMSESPSettingsController} />
|
||||||
|
<Redirect to={`/${PROJECT_PATH}/settings`} />
|
||||||
|
</Switch>
|
||||||
|
</MenuAppBar>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EMSESP;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import { ValidatorForm, TextValidator, SelectValidator } from 'react-material-ui-form-validator';
|
import { ValidatorForm, TextValidator, SelectValidator } from 'react-material-ui-form-validator';
|
||||||
|
|
||||||
import { Checkbox, Typography, Box } from '@material-ui/core';
|
import { Checkbox, Typography, Box, Link } from '@material-ui/core';
|
||||||
import SaveIcon from '@material-ui/icons/Save';
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
|
||||||
@@ -46,9 +46,9 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
|
|||||||
const { data, saveData, loadData, handleValueChange } = props;
|
const { data, saveData, loadData, handleValueChange } = props;
|
||||||
return (
|
return (
|
||||||
<ValidatorForm onSubmit={saveData}>
|
<ValidatorForm onSubmit={saveData}>
|
||||||
<Box bgcolor="primary.main" color="primary.contrastText" p={2} mt={2} mb={2}>
|
<Box bgcolor="info.main" p={2} mt={2} mb={2}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1">
|
||||||
Customize EMS-ESP by editing the default settings here. Refer to the <a href="https://emsesp.github.io/docs/#/">Wiki</a> for assistance.
|
Customize EMS-ESP by editing the default settings here. Refer to the <Link href="https://emsesp.github.io/docs/#/" color="primary">{'Wiki'}</Link> for descriptions of each setting.
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<TextValidator
|
<TextValidator
|
||||||
@@ -63,51 +63,6 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
|
|||||||
onChange={handleValueChange('tx_mode')}
|
onChange={handleValueChange('tx_mode')}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
<BlockFormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={data.system_heartbeat}
|
|
||||||
onChange={handleValueChange('system_heartbeat')}
|
|
||||||
value="system_heartbeat"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="MQTT Heartbeat"
|
|
||||||
/>
|
|
||||||
<SelectValidator name="mqtt_format"
|
|
||||||
label="MQTT Format"
|
|
||||||
value={data.mqtt_format}
|
|
||||||
fullWidth
|
|
||||||
variant="outlined"
|
|
||||||
onChange={handleValueChange('mqtt_format')}
|
|
||||||
margin="normal">
|
|
||||||
<MenuItem value={1}>Single</MenuItem>
|
|
||||||
<MenuItem value={2}>Nested</MenuItem>
|
|
||||||
<MenuItem value={3}>Home Assistant</MenuItem>
|
|
||||||
<MenuItem value={4}>Custom</MenuItem>
|
|
||||||
</SelectValidator>
|
|
||||||
<SelectValidator name="mqtt_qos"
|
|
||||||
label="MQTT QoS"
|
|
||||||
value={data.mqtt_qos}
|
|
||||||
fullWidth
|
|
||||||
variant="outlined"
|
|
||||||
onChange={handleValueChange('mqtt_qos')}
|
|
||||||
margin="normal">
|
|
||||||
<MenuItem value={0}>0</MenuItem>
|
|
||||||
<MenuItem value={1}>1</MenuItem>
|
|
||||||
<MenuItem value={2}>2</MenuItem>
|
|
||||||
</SelectValidator>
|
|
||||||
<TextValidator
|
|
||||||
validators={['required', 'isNumber', 'minNumber:1', 'maxNumber:65535']}
|
|
||||||
errorMessages={['Keep alive is required', "Must be a number", "Must be greater than 0", "Max value is 65535"]}
|
|
||||||
name="publish_time"
|
|
||||||
label="MQTT Publish Time (seconds)"
|
|
||||||
fullWidth
|
|
||||||
variant="outlined"
|
|
||||||
value={data.publish_time}
|
|
||||||
type="number"
|
|
||||||
onChange={handleValueChange('publish_time')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|||||||
@@ -29,15 +29,3 @@ export const busStatus = ({ status }: EMSESPStatus) => {
|
|||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mqttStatusHighlight = ({ mqtt_fails }: EMSESPStatus, theme: Theme) => {
|
|
||||||
|
|
||||||
if (mqtt_fails === 0)
|
|
||||||
return theme.palette.success.main;
|
|
||||||
|
|
||||||
if (mqtt_fails < 10)
|
|
||||||
return theme.palette.warning.main;
|
|
||||||
|
|
||||||
return theme.palette.success.main;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -7,20 +7,18 @@ import {
|
|||||||
TableCell,
|
TableCell,
|
||||||
TableHead,
|
TableHead,
|
||||||
TableRow,
|
TableRow,
|
||||||
Avatar,
|
|
||||||
Divider,
|
Divider,
|
||||||
List,
|
List,
|
||||||
ListItem,
|
ListItem,
|
||||||
ListItemAvatar,
|
ListItemAvatar,
|
||||||
ListItemText
|
ListItemText,
|
||||||
|
Typography,
|
||||||
|
Box,
|
||||||
|
Link
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
|
||||||
import BuildIcon from "@material-ui/icons/Build";
|
|
||||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
import RefreshIcon from "@material-ui/icons/Refresh";
|
||||||
import DeviceHubIcon from "@material-ui/icons/DeviceHub";
|
import DeviceHubIcon from "@material-ui/icons/DeviceHub";
|
||||||
import SpeakerNotesOffIcon from "@material-ui/icons/SpeakerNotesOff";
|
|
||||||
import TimerIcon from "@material-ui/icons/Timer";
|
|
||||||
import BatteryUnknownIcon from "@material-ui/icons/BatteryUnknown";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
RestFormProps,
|
RestFormProps,
|
||||||
@@ -28,11 +26,11 @@ import {
|
|||||||
FormButton,
|
FormButton,
|
||||||
HighlightAvatar,
|
HighlightAvatar,
|
||||||
} from "../components";
|
} from "../components";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
busStatus,
|
busStatus,
|
||||||
busStatusHighlight,
|
busStatusHighlight,
|
||||||
isConnected,
|
isConnected
|
||||||
mqttStatusHighlight,
|
|
||||||
} from "./EMSESPStatus";
|
} from "./EMSESPStatus";
|
||||||
|
|
||||||
import { EMSESPStatus } from "./EMSESPtypes";
|
import { EMSESPStatus } from "./EMSESPtypes";
|
||||||
@@ -44,55 +42,24 @@ class EMSESPStatusForm extends Component<EMSESPStatusFormProps> {
|
|||||||
const { data, theme } = this.props;
|
const { data, theme } = this.props;
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<ListItem>
|
<Box bgcolor="info.main" border={1} p={3} mt={1} mb={0}>
|
||||||
<ListItemAvatar>
|
<Typography variant="body1">
|
||||||
<Avatar>
|
Firmware Version is <b>{data.version}</b>
|
||||||
<BuildIcon />
|
<br /><br />
|
||||||
</Avatar>
|
Check for news and updates on the <Link href="https://emsesp.github.io/docs/#/" color="primary">{'Wiki'}</Link>
|
||||||
</ListItemAvatar>
|
<br/>
|
||||||
<ListItemText primary="Firmware Version" secondary={data.version} />
|
For live community chat go to <Link href="https://gitter.im/EMS-ESP/community#" color="primary">{'Gitter'}</Link>
|
||||||
</ListItem>
|
<br/>
|
||||||
<Divider variant="inset" component="li" />
|
To report issues, contribute and give kudos visit <Link href="https://github.com/proddy/EMS-ESP" color="primary">{'github.com/proddy/EMS-ESP'}</Link>
|
||||||
<ListItem>
|
</Typography>
|
||||||
<ListItemAvatar>
|
</Box>
|
||||||
<Avatar>
|
|
||||||
<TimerIcon />
|
|
||||||
</Avatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText primary="System Uptime" secondary={data.uptime} />
|
|
||||||
</ListItem>
|
|
||||||
<Divider variant="inset" component="li" />
|
|
||||||
<ListItem>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<Avatar>
|
|
||||||
<BatteryUnknownIcon />
|
|
||||||
</Avatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText
|
|
||||||
primary="Free System Memory"
|
|
||||||
secondary={data.free_mem + "%"}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
|
||||||
<Divider variant="inset" component="li" />
|
|
||||||
<ListItem>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<HighlightAvatar color={mqttStatusHighlight(data, theme)}>
|
|
||||||
<SpeakerNotesOffIcon />
|
|
||||||
</HighlightAvatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText
|
|
||||||
primary="MQTT Publish Errors"
|
|
||||||
secondary={data.mqtt_fails}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
|
||||||
<Divider variant="inset" component="li" />
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<HighlightAvatar color={busStatusHighlight(data, theme)}>
|
<HighlightAvatar color={busStatusHighlight(data, theme)}>
|
||||||
<DeviceHubIcon />
|
<DeviceHubIcon />
|
||||||
</HighlightAvatar>
|
</HighlightAvatar>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText primary="EMS Bus Status" secondary={busStatus(data)} />
|
<ListItemText primary="EMS Connection Status" secondary={busStatus(data)} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
{isConnected(data) && (
|
{isConnected(data) && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
export interface EMSESPSettings {
|
export interface EMSESPSettings {
|
||||||
tx_mode: number;
|
tx_mode: number;
|
||||||
ems_bus_id: number;
|
ems_bus_id: number;
|
||||||
system_heartbeat: boolean;
|
|
||||||
syslog_level: number;
|
syslog_level: number;
|
||||||
syslog_mark_interval: number;
|
syslog_mark_interval: number;
|
||||||
syslog_host: string;
|
syslog_host: string;
|
||||||
master_thermostat: number;
|
master_thermostat: number;
|
||||||
shower_timer: boolean;
|
shower_timer: boolean;
|
||||||
shower_alert: boolean;
|
shower_alert: boolean;
|
||||||
publish_time: number;
|
|
||||||
mqtt_format: number;
|
|
||||||
mqtt_qos: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum busConnectionStatus {
|
export enum busConnectionStatus {
|
||||||
@@ -26,9 +22,6 @@ export interface EMSESPStatus {
|
|||||||
tx_sent: number;
|
tx_sent: number;
|
||||||
crc_errors: number;
|
crc_errors: number;
|
||||||
tx_errors: number;
|
tx_errors: number;
|
||||||
mqtt_fails: number;
|
|
||||||
uptime: string;
|
|
||||||
free_mem: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Device {
|
export interface Device {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import AppsIcon from '@material-ui/icons/Apps';
|
|||||||
import PowerSettingsNewIcon from '@material-ui/icons/PowerSettingsNew';
|
import PowerSettingsNewIcon from '@material-ui/icons/PowerSettingsNew';
|
||||||
import RefreshIcon from '@material-ui/icons/Refresh';
|
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||||
import SettingsBackupRestoreIcon from '@material-ui/icons/SettingsBackupRestore';
|
import SettingsBackupRestoreIcon from '@material-ui/icons/SettingsBackupRestore';
|
||||||
|
import BatteryUnknownIcon from "@material-ui/icons/BatteryUnknown";
|
||||||
|
import TimerIcon from "@material-ui/icons/Timer";
|
||||||
|
|
||||||
import { redirectingAuthorizedFetch, AuthenticatedContextProps, withAuthenticatedContext } from '../authentication';
|
import { redirectingAuthorizedFetch, AuthenticatedContextProps, withAuthenticatedContext } from '../authentication';
|
||||||
import { RestFormProps, FormButton, ErrorButton } from '../components';
|
import { RestFormProps, FormButton, ErrorButton } from '../components';
|
||||||
@@ -53,6 +55,14 @@ class SystemStatusForm extends Component<SystemStatusFormProps, SystemStatusForm
|
|||||||
<ListItemText primary="Device (Platform / SDK)" secondary={data.esp_platform + ' / ' + data.sdk_version} />
|
<ListItemText primary="Device (Platform / SDK)" secondary={data.esp_platform + ' / ' + data.sdk_version} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
|
<ListItem>
|
||||||
|
<ListItemAvatar>
|
||||||
|
<Avatar>
|
||||||
|
<TimerIcon />
|
||||||
|
</Avatar>
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText primary="System Uptime" secondary={data.uptime} />
|
||||||
|
</ListItem>
|
||||||
<ListItem >
|
<ListItem >
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar>
|
<Avatar>
|
||||||
@@ -84,6 +94,17 @@ class SystemStatusForm extends Component<SystemStatusFormProps, SystemStatusForm
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
</Fragment>)
|
</Fragment>)
|
||||||
}
|
}
|
||||||
|
<ListItem>
|
||||||
|
<ListItemAvatar>
|
||||||
|
<Avatar>
|
||||||
|
<BatteryUnknownIcon />
|
||||||
|
</Avatar>
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText
|
||||||
|
primary="Free System Memory"
|
||||||
|
secondary={data.free_mem + "%"}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
<ListItem >
|
<ListItem >
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ interface ESPSystemStatus {
|
|||||||
flash_chip_speed: number;
|
flash_chip_speed: number;
|
||||||
fs_used: number;
|
fs_used: number;
|
||||||
fs_total: number;
|
fs_total: number;
|
||||||
|
uptime: string;
|
||||||
|
free_mem: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ESP32SystemStatus extends ESPSystemStatus {
|
export interface ESP32SystemStatus extends ESPSystemStatus {
|
||||||
|
|||||||
@@ -1,18 +1,27 @@
|
|||||||
#include <MqttSettingsService.h>
|
#include <MqttSettingsService.h>
|
||||||
|
|
||||||
|
// forward declarators
|
||||||
|
namespace emsesp {
|
||||||
|
class EMSESP {
|
||||||
|
public:
|
||||||
|
static System system_;
|
||||||
|
static Mqtt mqtt_;
|
||||||
|
};
|
||||||
|
} // namespace emsesp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retains a copy of the cstr provided in the pointer provided using dynamic allocation.
|
* Retains a copy of the cstr provided in the pointer provided using dynamic allocation.
|
||||||
*
|
*
|
||||||
* Frees the pointer before allocation and leaves it as nullptr if cstr == nullptr.
|
* Frees the pointer before allocation and leaves it as nullptr if cstr == nullptr.
|
||||||
*/
|
*/
|
||||||
static char* retainCstr(const char* cstr, char** ptr) {
|
static char * retainCstr(const char * cstr, char ** ptr) {
|
||||||
// free up previously retained value if exists
|
// free up previously retained value if exists
|
||||||
free(*ptr);
|
free(*ptr);
|
||||||
*ptr = nullptr;
|
*ptr = nullptr;
|
||||||
|
|
||||||
// dynamically allocate and copy cstr (if non null)
|
// dynamically allocate and copy cstr (if non null)
|
||||||
if (cstr != nullptr) {
|
if (cstr != nullptr) {
|
||||||
*ptr = (char*)malloc(strlen(cstr) + 1);
|
*ptr = (char *)malloc(strlen(cstr) + 1);
|
||||||
strcpy(*ptr, cstr);
|
strcpy(*ptr, cstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,32 +29,28 @@ static char* retainCstr(const char* cstr, char** ptr) {
|
|||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttSettingsService::MqttSettingsService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager) :
|
MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||||
_httpEndpoint(MqttSettings::read, MqttSettings::update, this, server, MQTT_SETTINGS_SERVICE_PATH, securityManager),
|
: _httpEndpoint(MqttSettings::read, MqttSettings::update, this, server, MQTT_SETTINGS_SERVICE_PATH, securityManager)
|
||||||
_fsPersistence(MqttSettings::read, MqttSettings::update, this, fs, MQTT_SETTINGS_FILE),
|
, _fsPersistence(MqttSettings::read, MqttSettings::update, this, fs, MQTT_SETTINGS_FILE)
|
||||||
_retainedHost(nullptr),
|
, _retainedHost(nullptr)
|
||||||
_retainedClientId(nullptr),
|
, _retainedClientId(nullptr)
|
||||||
_retainedUsername(nullptr),
|
, _retainedUsername(nullptr)
|
||||||
_retainedPassword(nullptr),
|
, _retainedPassword(nullptr)
|
||||||
_reconfigureMqtt(false),
|
, _reconfigureMqtt(false)
|
||||||
_disconnectedAt(0),
|
, _disconnectedAt(0)
|
||||||
_disconnectReason(AsyncMqttClientDisconnectReason::TCP_DISCONNECTED),
|
, _disconnectReason(AsyncMqttClientDisconnectReason::TCP_DISCONNECTED)
|
||||||
_mqttClient() {
|
, _mqttClient() {
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
WiFi.onEvent(
|
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2),
|
||||||
std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2),
|
|
||||||
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
||||||
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2),
|
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
|
||||||
WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
|
|
||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(
|
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
|
||||||
std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
|
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1));
|
||||||
_onStationModeGotIPHandler =
|
|
||||||
WiFi.onStationModeGotIP(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1));
|
|
||||||
#endif
|
#endif
|
||||||
_mqttClient.onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, std::placeholders::_1));
|
_mqttClient.onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, std::placeholders::_1));
|
||||||
_mqttClient.onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, std::placeholders::_1));
|
_mqttClient.onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, std::placeholders::_1));
|
||||||
addUpdateHandler([&](const String& originId) { onConfigUpdated(); }, false);
|
addUpdateHandler([&](const String & originId) { onConfigUpdated(); }, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttSettingsService::~MqttSettingsService() {
|
MqttSettingsService::~MqttSettingsService() {
|
||||||
@@ -74,7 +79,7 @@ bool MqttSettingsService::isConnected() {
|
|||||||
return _mqttClient.connected();
|
return _mqttClient.connected();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* MqttSettingsService::getClientId() {
|
const char * MqttSettingsService::getClientId() {
|
||||||
return _mqttClient.getClientId();
|
return _mqttClient.getClientId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +87,7 @@ AsyncMqttClientDisconnectReason MqttSettingsService::getDisconnectReason() {
|
|||||||
return _disconnectReason;
|
return _disconnectReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncMqttClient* MqttSettingsService::getMqttClient() {
|
AsyncMqttClient * MqttSettingsService::getMqttClient() {
|
||||||
return &_mqttClient;
|
return &_mqttClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,14 +129,14 @@ void MqttSettingsService::onStationModeDisconnected(WiFiEvent_t event, WiFiEvent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
void MqttSettingsService::onStationModeGotIP(const WiFiEventStationModeGotIP& event) {
|
void MqttSettingsService::onStationModeGotIP(const WiFiEventStationModeGotIP & event) {
|
||||||
if (_state.enabled) {
|
if (_state.enabled) {
|
||||||
// Serial.println(F("WiFi connection dropped, starting MQTT client."));
|
// Serial.println(F("WiFi connection dropped, starting MQTT client."));
|
||||||
onConfigUpdated();
|
onConfigUpdated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttSettingsService::onStationModeDisconnected(const WiFiEventStationModeDisconnected& event) {
|
void MqttSettingsService::onStationModeDisconnected(const WiFiEventStationModeDisconnected & event) {
|
||||||
if (_state.enabled) {
|
if (_state.enabled) {
|
||||||
// Serial.println(F("WiFi connection dropped, stopping MQTT client."));
|
// Serial.println(F("WiFi connection dropped, stopping MQTT client."));
|
||||||
onConfigUpdated();
|
onConfigUpdated();
|
||||||
@@ -148,8 +153,7 @@ void MqttSettingsService::configureMqtt() {
|
|||||||
// Serial.println(F("Connecting to MQTT..."));
|
// Serial.println(F("Connecting to MQTT..."));
|
||||||
_mqttClient.setServer(retainCstr(_state.host.c_str(), &_retainedHost), _state.port);
|
_mqttClient.setServer(retainCstr(_state.host.c_str(), &_retainedHost), _state.port);
|
||||||
if (_state.username.length() > 0) {
|
if (_state.username.length() > 0) {
|
||||||
_mqttClient.setCredentials(
|
_mqttClient.setCredentials(retainCstr(_state.username.c_str(), &_retainedUsername),
|
||||||
retainCstr(_state.username.c_str(), &_retainedUsername),
|
|
||||||
retainCstr(_state.password.length() > 0 ? _state.password.c_str() : nullptr, &_retainedPassword));
|
retainCstr(_state.password.length() > 0 ? _state.password.c_str() : nullptr, &_retainedPassword));
|
||||||
} else {
|
} else {
|
||||||
_mqttClient.setCredentials(retainCstr(nullptr, &_retainedUsername), retainCstr(nullptr, &_retainedPassword));
|
_mqttClient.setCredentials(retainCstr(nullptr, &_retainedUsername), retainCstr(nullptr, &_retainedPassword));
|
||||||
@@ -161,3 +165,57 @@ void MqttSettingsService::configureMqtt() {
|
|||||||
_mqttClient.connect();
|
_mqttClient.connect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MqttSettings::read(MqttSettings & settings, JsonObject & root) {
|
||||||
|
root["enabled"] = settings.enabled;
|
||||||
|
root["host"] = settings.host;
|
||||||
|
root["port"] = settings.port;
|
||||||
|
root["username"] = settings.username;
|
||||||
|
root["password"] = settings.password;
|
||||||
|
root["client_id"] = settings.clientId;
|
||||||
|
root["keep_alive"] = settings.keepAlive;
|
||||||
|
root["clean_session"] = settings.cleanSession;
|
||||||
|
root["max_topic_length"] = settings.maxTopicLength;
|
||||||
|
|
||||||
|
// added by proddy for EMS-ESP
|
||||||
|
root["system_heartbeat"] = settings.system_heartbeat;
|
||||||
|
root["publish_time"] = settings.publish_time;
|
||||||
|
root["mqtt_format"] = settings.mqtt_format;
|
||||||
|
root["mqtt_qos"] = settings.mqtt_qos;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & settings) {
|
||||||
|
MqttSettings newSettings = {};
|
||||||
|
|
||||||
|
newSettings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED;
|
||||||
|
newSettings.host = root["host"] | FACTORY_MQTT_HOST;
|
||||||
|
newSettings.port = root["port"] | FACTORY_MQTT_PORT;
|
||||||
|
newSettings.username = root["username"] | FACTORY_MQTT_USERNAME;
|
||||||
|
newSettings.password = root["password"] | FACTORY_MQTT_PASSWORD;
|
||||||
|
newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID;
|
||||||
|
newSettings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE;
|
||||||
|
newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION;
|
||||||
|
newSettings.maxTopicLength = root["max_topic_length"] | FACTORY_MQTT_MAX_TOPIC_LENGTH;
|
||||||
|
|
||||||
|
newSettings.system_heartbeat = root["system_heartbeat"] | EMSESP_DEFAULT_SYSTEM_HEARTBEAT;
|
||||||
|
newSettings.publish_time = root["publish_time"] | EMSESP_DEFAULT_PUBLISH_TIME;
|
||||||
|
newSettings.mqtt_format = root["mqtt_format"] | EMSESP_DEFAULT_MQTT_FORMAT;
|
||||||
|
newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS;
|
||||||
|
|
||||||
|
if (newSettings.system_heartbeat != settings.system_heartbeat) {
|
||||||
|
emsesp::EMSESP::system_.set_heartbeat(newSettings.system_heartbeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSettings.mqtt_qos != settings.mqtt_qos) {
|
||||||
|
emsesp::EMSESP::mqtt_.set_qos(newSettings.mqtt_qos);
|
||||||
|
emsesp::EMSESP::mqtt_.disconnect(); // force a disconnect & reconnect
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSettings.publish_time != settings.publish_time) {
|
||||||
|
emsesp::EMSESP::mqtt_.set_publish_time(newSettings.publish_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
settings = newSettings;
|
||||||
|
|
||||||
|
return StateUpdateResult::CHANGED;
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
#include <AsyncMqttClient.h>
|
#include <AsyncMqttClient.h>
|
||||||
#include <ESPUtils.h>
|
#include <ESPUtils.h>
|
||||||
|
|
||||||
|
#include "../../src/system.h"
|
||||||
|
#include "../../src/mqtt.h"
|
||||||
|
|
||||||
#define MQTT_RECONNECTION_DELAY 5000
|
#define MQTT_RECONNECTION_DELAY 5000
|
||||||
|
|
||||||
#define MQTT_SETTINGS_FILE "/config/mqttSettings.json"
|
#define MQTT_SETTINGS_FILE "/config/mqttSettings.json"
|
||||||
@@ -34,6 +37,13 @@
|
|||||||
|
|
||||||
#ifndef FACTORY_MQTT_CLIENT_ID
|
#ifndef FACTORY_MQTT_CLIENT_ID
|
||||||
#define FACTORY_MQTT_CLIENT_ID generateClientId()
|
#define FACTORY_MQTT_CLIENT_ID generateClientId()
|
||||||
|
static String generateClientId() {
|
||||||
|
#ifdef ESP32
|
||||||
|
return ESPUtils::defaultDeviceValue("esp32-");
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
return ESPUtils::defaultDeviceValue("esp8266-");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FACTORY_MQTT_KEEP_ALIVE
|
#ifndef FACTORY_MQTT_KEEP_ALIVE
|
||||||
@@ -48,13 +58,11 @@
|
|||||||
#define FACTORY_MQTT_MAX_TOPIC_LENGTH 128
|
#define FACTORY_MQTT_MAX_TOPIC_LENGTH 128
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static String generateClientId() {
|
#define EMSESP_DEFAULT_SYSTEM_HEARTBEAT true
|
||||||
#ifdef ESP32
|
#define EMSESP_DEFAULT_MQTT_FORMAT 2 // nested
|
||||||
return ESPUtils::defaultDeviceValue("esp32-");
|
#define EMSESP_DEFAULT_MQTT_QOS 0
|
||||||
#elif defined(ESP8266)
|
#define EMSESP_DEFAULT_PUBLISH_TIME 10
|
||||||
return ESPUtils::defaultDeviceValue("esp8266-");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
class MqttSettings {
|
class MqttSettings {
|
||||||
public:
|
public:
|
||||||
@@ -75,44 +83,28 @@ class MqttSettings {
|
|||||||
bool cleanSession;
|
bool cleanSession;
|
||||||
uint16_t maxTopicLength;
|
uint16_t maxTopicLength;
|
||||||
|
|
||||||
static void read(MqttSettings& settings, JsonObject& root) {
|
// proddy EMS-ESP specific
|
||||||
root["enabled"] = settings.enabled;
|
uint16_t publish_time; // seconds
|
||||||
root["host"] = settings.host;
|
uint8_t mqtt_format; // 1=single, 2=nested, 3=ha, 4=custom
|
||||||
root["port"] = settings.port;
|
uint8_t mqtt_qos;
|
||||||
root["username"] = settings.username;
|
bool system_heartbeat;
|
||||||
root["password"] = settings.password;
|
|
||||||
root["client_id"] = settings.clientId;
|
|
||||||
root["keep_alive"] = settings.keepAlive;
|
|
||||||
root["clean_session"] = settings.cleanSession;
|
|
||||||
root["max_topic_length"] = settings.maxTopicLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
static StateUpdateResult update(JsonObject& root, MqttSettings& settings) {
|
static void read(MqttSettings & settings, JsonObject & root);
|
||||||
settings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED;
|
static StateUpdateResult update(JsonObject & root, MqttSettings & settings);
|
||||||
settings.host = root["host"] | FACTORY_MQTT_HOST;
|
|
||||||
settings.port = root["port"] | FACTORY_MQTT_PORT;
|
|
||||||
settings.username = root["username"] | FACTORY_MQTT_USERNAME;
|
|
||||||
settings.password = root["password"] | FACTORY_MQTT_PASSWORD;
|
|
||||||
settings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID;
|
|
||||||
settings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE;
|
|
||||||
settings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION;
|
|
||||||
settings.maxTopicLength = root["max_topic_length"] | FACTORY_MQTT_MAX_TOPIC_LENGTH;
|
|
||||||
return StateUpdateResult::CHANGED;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MqttSettingsService : public StatefulService<MqttSettings> {
|
class MqttSettingsService : public StatefulService<MqttSettings> {
|
||||||
public:
|
public:
|
||||||
MqttSettingsService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager);
|
MqttSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
||||||
~MqttSettingsService();
|
~MqttSettingsService();
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void loop();
|
void loop();
|
||||||
bool isEnabled();
|
bool isEnabled();
|
||||||
bool isConnected();
|
bool isConnected();
|
||||||
const char* getClientId();
|
const char * getClientId();
|
||||||
AsyncMqttClientDisconnectReason getDisconnectReason();
|
AsyncMqttClientDisconnectReason getDisconnectReason();
|
||||||
AsyncMqttClient* getMqttClient();
|
AsyncMqttClient * getMqttClient();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onConfigUpdated();
|
void onConfigUpdated();
|
||||||
@@ -123,10 +115,10 @@ class MqttSettingsService : public StatefulService<MqttSettings> {
|
|||||||
|
|
||||||
// Pointers to hold retained copies of the mqtt client connection strings.
|
// Pointers to hold retained copies of the mqtt client connection strings.
|
||||||
// This is required as AsyncMqttClient holds references to the supplied connection strings.
|
// This is required as AsyncMqttClient holds references to the supplied connection strings.
|
||||||
char* _retainedHost;
|
char * _retainedHost;
|
||||||
char* _retainedClientId;
|
char * _retainedClientId;
|
||||||
char* _retainedUsername;
|
char * _retainedUsername;
|
||||||
char* _retainedPassword;
|
char * _retainedPassword;
|
||||||
|
|
||||||
// variable to help manage connection
|
// variable to help manage connection
|
||||||
bool _reconfigureMqtt;
|
bool _reconfigureMqtt;
|
||||||
@@ -144,8 +136,8 @@ class MqttSettingsService : public StatefulService<MqttSettings> {
|
|||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
WiFiEventHandler _onStationModeDisconnectedHandler;
|
WiFiEventHandler _onStationModeDisconnectedHandler;
|
||||||
WiFiEventHandler _onStationModeGotIPHandler;
|
WiFiEventHandler _onStationModeGotIPHandler;
|
||||||
void onStationModeGotIP(const WiFiEventStationModeGotIP& event);
|
void onStationModeGotIP(const WiFiEventStationModeGotIP & event);
|
||||||
void onStationModeDisconnected(const WiFiEventStationModeDisconnected& event);
|
void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void onMqttConnect(bool sessionPresent);
|
void onMqttConnect(bool sessionPresent);
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
#include <MqttStatus.h>
|
#include <MqttStatus.h>
|
||||||
|
|
||||||
MqttStatus::MqttStatus(AsyncWebServer* server,
|
MqttStatus::MqttStatus(AsyncWebServer * server, MqttSettingsService * mqttSettingsService, SecurityManager * securityManager)
|
||||||
MqttSettingsService* mqttSettingsService,
|
: _mqttSettingsService(mqttSettingsService) {
|
||||||
SecurityManager* securityManager) :
|
|
||||||
_mqttSettingsService(mqttSettingsService) {
|
|
||||||
server->on(MQTT_STATUS_SERVICE_PATH,
|
server->on(MQTT_STATUS_SERVICE_PATH,
|
||||||
HTTP_GET,
|
HTTP_GET,
|
||||||
securityManager->wrapRequest(std::bind(&MqttStatus::mqttStatus, this, std::placeholders::_1),
|
securityManager->wrapRequest(std::bind(&MqttStatus::mqttStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||||
AuthenticationPredicates::IS_AUTHENTICATED));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttStatus::mqttStatus(AsyncWebServerRequest* request) {
|
void MqttStatus::mqttStatus(AsyncWebServerRequest * request) {
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, MAX_MQTT_STATUS_SIZE);
|
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_MQTT_STATUS_SIZE);
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
|
|
||||||
root["enabled"] = _mqttSettingsService->isEnabled();
|
root["enabled"] = _mqttSettingsService->isEnabled();
|
||||||
@@ -19,6 +16,8 @@ void MqttStatus::mqttStatus(AsyncWebServerRequest* request) {
|
|||||||
root["client_id"] = _mqttSettingsService->getClientId();
|
root["client_id"] = _mqttSettingsService->getClientId();
|
||||||
root["disconnect_reason"] = (uint8_t)_mqttSettingsService->getDisconnectReason();
|
root["disconnect_reason"] = (uint8_t)_mqttSettingsService->getDisconnectReason();
|
||||||
|
|
||||||
|
root["mqtt_fails"] = emsesp::Mqtt::publish_fails();
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <ESPAsyncTCP.h>
|
#include <ESPAsyncTCP.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../../src/mqtt.h"
|
||||||
|
|
||||||
#include <MqttSettingsService.h>
|
#include <MqttSettingsService.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
@@ -20,12 +22,12 @@
|
|||||||
|
|
||||||
class MqttStatus {
|
class MqttStatus {
|
||||||
public:
|
public:
|
||||||
MqttStatus(AsyncWebServer* server, MqttSettingsService* mqttSettingsService, SecurityManager* securityManager);
|
MqttStatus(AsyncWebServer * server, MqttSettingsService * mqttSettingsService, SecurityManager * securityManager);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MqttSettingsService* _mqttSettingsService;
|
MqttSettingsService * _mqttSettingsService;
|
||||||
|
|
||||||
void mqttStatus(AsyncWebServerRequest* request);
|
void mqttStatus(AsyncWebServerRequest * request);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // end MqttStatus_h
|
#endif // end MqttStatus_h
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
#include <SystemStatus.h>
|
#include <SystemStatus.h>
|
||||||
|
|
||||||
SystemStatus::SystemStatus(AsyncWebServer* server, SecurityManager* securityManager) {
|
SystemStatus::SystemStatus(AsyncWebServer * server, SecurityManager * securityManager) {
|
||||||
server->on(SYSTEM_STATUS_SERVICE_PATH,
|
server->on(SYSTEM_STATUS_SERVICE_PATH,
|
||||||
HTTP_GET,
|
HTTP_GET,
|
||||||
securityManager->wrapRequest(std::bind(&SystemStatus::systemStatus, this, std::placeholders::_1),
|
securityManager->wrapRequest(std::bind(&SystemStatus::systemStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||||
AuthenticationPredicates::IS_AUTHENTICATED));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemStatus::systemStatus(AsyncWebServerRequest* request) {
|
void SystemStatus::systemStatus(AsyncWebServerRequest * request) {
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, MAX_ESP_STATUS_SIZE);
|
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_ESP_STATUS_SIZE);
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
root["esp_platform"] = "esp32";
|
root["esp_platform"] = "esp32";
|
||||||
@@ -40,6 +39,9 @@ void SystemStatus::systemStatus(AsyncWebServerRequest* request) {
|
|||||||
root["fs_used"] = fs_info.usedBytes;
|
root["fs_used"] = fs_info.usedBytes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
||||||
|
root["free_mem"] = emsesp::System::free_mem();
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,15 +17,18 @@
|
|||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <SecurityManager.h>
|
#include <SecurityManager.h>
|
||||||
|
|
||||||
|
#include <uuid/log.h>
|
||||||
|
#include "../../src/system.h"
|
||||||
|
|
||||||
#define MAX_ESP_STATUS_SIZE 1024
|
#define MAX_ESP_STATUS_SIZE 1024
|
||||||
#define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus"
|
#define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus"
|
||||||
|
|
||||||
class SystemStatus {
|
class SystemStatus {
|
||||||
public:
|
public:
|
||||||
SystemStatus(AsyncWebServer* server, SecurityManager* securityManager);
|
SystemStatus(AsyncWebServer * server, SecurityManager * securityManager);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void systemStatus(AsyncWebServerRequest* request);
|
void systemStatus(AsyncWebServerRequest * request);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // end SystemStatus_h
|
#endif // end SystemStatus_h
|
||||||
|
|||||||
@@ -11,62 +11,36 @@ EMSESPSettingsService::EMSESPSettingsService(AsyncWebServer * server, FS * fs, S
|
|||||||
void EMSESPSettings::read(EMSESPSettings & settings, JsonObject & root) {
|
void EMSESPSettings::read(EMSESPSettings & settings, JsonObject & root) {
|
||||||
root["tx_mode"] = settings.tx_mode;
|
root["tx_mode"] = settings.tx_mode;
|
||||||
root["ems_bus_id"] = settings.ems_bus_id;
|
root["ems_bus_id"] = settings.ems_bus_id;
|
||||||
root["system_heartbeat"] = settings.system_heartbeat;
|
|
||||||
root["syslog_level"] = settings.syslog_level;
|
root["syslog_level"] = settings.syslog_level;
|
||||||
root["syslog_mark_interval"] = settings.syslog_mark_interval;
|
root["syslog_mark_interval"] = settings.syslog_mark_interval;
|
||||||
root["syslog_host"] = settings.syslog_host;
|
root["syslog_host"] = settings.syslog_host;
|
||||||
|
|
||||||
root["master_thermostat"] = settings.master_thermostat;
|
root["master_thermostat"] = settings.master_thermostat;
|
||||||
root["shower_timer"] = settings.shower_timer;
|
root["shower_timer"] = settings.shower_timer;
|
||||||
root["shower_alert"] = settings.shower_alert;
|
root["shower_alert"] = settings.shower_alert;
|
||||||
root["publish_time"] = settings.publish_time;
|
|
||||||
root["mqtt_format"] = settings.mqtt_format;
|
|
||||||
root["mqtt_qos"] = settings.mqtt_qos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & settings) {
|
StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & settings) {
|
||||||
EMSESPSettings newSettings = {};
|
EMSESPSettings newSettings = {};
|
||||||
newSettings.tx_mode = root["tx_mode"] | EMSESP_DEFAULT_TX_MODE;
|
newSettings.tx_mode = root["tx_mode"] | EMSESP_DEFAULT_TX_MODE;
|
||||||
newSettings.ems_bus_id = root["ems_bus_id"] | EMSESP_DEFAULT_EMS_BUS_ID;
|
newSettings.ems_bus_id = root["ems_bus_id"] | EMSESP_DEFAULT_EMS_BUS_ID;
|
||||||
newSettings.system_heartbeat = root["system_heartbeat"] | EMSESP_DEFAULT_SYSTEM_HEARTBEAT;
|
|
||||||
newSettings.syslog_level = root["syslog_level"] | EMSESP_DEFAULT_SYSLOG_LEVEL;
|
newSettings.syslog_level = root["syslog_level"] | EMSESP_DEFAULT_SYSLOG_LEVEL;
|
||||||
newSettings.syslog_mark_interval = root["syslog_mark_interval"] | EMSESP_DEFAULT_SYSLOG_MARK_INTERVAL;
|
newSettings.syslog_mark_interval = root["syslog_mark_interval"] | EMSESP_DEFAULT_SYSLOG_MARK_INTERVAL;
|
||||||
newSettings.syslog_host = root["syslog_host"] | EMSESP_DEFAULT_SYSLOG_HOST;
|
newSettings.syslog_host = root["syslog_host"] | EMSESP_DEFAULT_SYSLOG_HOST;
|
||||||
|
|
||||||
newSettings.master_thermostat = root["master_thermostat"] | EMSESP_DEFAULT_MASTER_THERMOSTAT;
|
newSettings.master_thermostat = root["master_thermostat"] | EMSESP_DEFAULT_MASTER_THERMOSTAT;
|
||||||
newSettings.shower_timer = root["shower_timer"] | EMSESP_DEFAULT_SHOWER_TIMER;
|
newSettings.shower_timer = root["shower_timer"] | EMSESP_DEFAULT_SHOWER_TIMER;
|
||||||
newSettings.shower_alert = root["shower_alert"] | EMSESP_DEFAULT_SHOWER_ALERT;
|
newSettings.shower_alert = root["shower_alert"] | EMSESP_DEFAULT_SHOWER_ALERT;
|
||||||
newSettings.publish_time = root["publish_time"] | EMSESP_DEFAULT_PUBLISH_TIME;
|
|
||||||
newSettings.mqtt_format = root["mqtt_format"] | EMSESP_DEFAULT_MQTT_FORMAT;
|
|
||||||
newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS;
|
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
// changing master thermostat, bus ID, mqtt_format requires a reboot
|
|
||||||
if ((newSettings.master_thermostat != settings.master_thermostat) || (newSettings.ems_bus_id != settings.ems_bus_id)
|
|
||||||
|| (newSettings.mqtt_format != settings.mqtt_format)) {
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newSettings.system_heartbeat != settings.system_heartbeat) {
|
|
||||||
EMSESP::system_.set_heartbeat(newSettings.system_heartbeat);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newSettings.tx_mode != settings.tx_mode) {
|
if (newSettings.tx_mode != settings.tx_mode) {
|
||||||
EMSESP::reset_tx(newSettings.tx_mode); // reset counters
|
EMSESP::reset_tx(newSettings.tx_mode); // reset counters
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newSettings.mqtt_qos != settings.mqtt_qos) {
|
|
||||||
EMSESP::mqtt_.set_qos(newSettings.mqtt_qos);
|
|
||||||
EMSESP::mqtt_.disconnect(); // force a disconnect & reconnect
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newSettings.publish_time != settings.publish_time) {
|
|
||||||
EMSESP::mqtt_.set_publish_time(newSettings.publish_time);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((newSettings.shower_timer != settings.shower_timer) || (newSettings.shower_alert != settings.shower_alert)) {
|
if ((newSettings.shower_timer != settings.shower_timer) || (newSettings.shower_alert != settings.shower_alert)) {
|
||||||
EMSESP::shower_.start();
|
EMSESP::shower_.start();
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|||||||
@@ -9,21 +9,14 @@
|
|||||||
|
|
||||||
#define EMSESP_DEFAULT_TX_MODE 1
|
#define EMSESP_DEFAULT_TX_MODE 1
|
||||||
#define EMSESP_DEFAULT_EMS_BUS_ID 0x0B // service key
|
#define EMSESP_DEFAULT_EMS_BUS_ID 0x0B // service key
|
||||||
#define EMSESP_DEFAULT_SYSTEM_HEARTBEAT true
|
|
||||||
#define EMSESP_DEFAULT_SYSLOG_LEVEL -1
|
#define EMSESP_DEFAULT_SYSLOG_LEVEL -1
|
||||||
#define EMSESP_DEFAULT_SYSLOG_MARK_INTERVAL 0
|
#define EMSESP_DEFAULT_SYSLOG_MARK_INTERVAL 0
|
||||||
#define EMSESP_DEFAULT_SYSLOG_HOST ""
|
#define EMSESP_DEFAULT_SYSLOG_HOST ""
|
||||||
|
|
||||||
#define EMSESP_DEFAULT_MASTER_THERMOSTAT 0 // not set
|
#define EMSESP_DEFAULT_MASTER_THERMOSTAT 0 // not set
|
||||||
#define EMSESP_DEFAULT_SHOWER_TIMER false
|
#define EMSESP_DEFAULT_SHOWER_TIMER false
|
||||||
#define EMSESP_DEFAULT_SHOWER_ALERT false
|
#define EMSESP_DEFAULT_SHOWER_ALERT false
|
||||||
#define EMSESP_DEFAULT_MQTT_FORMAT 2 // nested
|
|
||||||
#define EMSESP_DEFAULT_MQTT_QOS 0
|
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
|
||||||
#define EMSESP_DEFAULT_PUBLISH_TIME 10
|
|
||||||
#else
|
|
||||||
#define EMSESP_DEFAULT_PUBLISH_TIME 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
@@ -33,16 +26,14 @@ class EMSESPSettings {
|
|||||||
public:
|
public:
|
||||||
uint8_t tx_mode;
|
uint8_t tx_mode;
|
||||||
uint8_t ems_bus_id;
|
uint8_t ems_bus_id;
|
||||||
bool system_heartbeat;
|
|
||||||
int8_t syslog_level; // uuid::log::Level
|
|
||||||
uint32_t syslog_mark_interval;
|
|
||||||
String syslog_host;
|
|
||||||
uint8_t master_thermostat;
|
uint8_t master_thermostat;
|
||||||
bool shower_timer;
|
bool shower_timer;
|
||||||
bool shower_alert;
|
bool shower_alert;
|
||||||
uint16_t publish_time; // seconds
|
|
||||||
uint8_t mqtt_format; // 1=single, 2=nested, 3=ha, 4=custom
|
// syslog
|
||||||
uint8_t mqtt_qos;
|
int8_t syslog_level; // uuid::log::Level
|
||||||
|
uint32_t syslog_mark_interval;
|
||||||
|
String syslog_host;
|
||||||
|
|
||||||
static void read(EMSESPSettings & settings, JsonObject & root);
|
static void read(EMSESPSettings & settings, JsonObject & root);
|
||||||
static StateUpdateResult update(JsonObject & root, EMSESPSettings & settings);
|
static StateUpdateResult update(JsonObject & root, EMSESPSettings & settings);
|
||||||
|
|||||||
@@ -61,9 +61,6 @@ void EMSESPStatusService::emsespStatusService(AsyncWebServerRequest * request) {
|
|||||||
root["tx_sent"] = EMSESP::txservice_.telegram_read_count() + EMSESP::txservice_.telegram_write_count();
|
root["tx_sent"] = EMSESP::txservice_.telegram_read_count() + EMSESP::txservice_.telegram_write_count();
|
||||||
root["crc_errors"] = EMSESP::rxservice_.telegram_error_count();
|
root["crc_errors"] = EMSESP::rxservice_.telegram_error_count();
|
||||||
root["tx_errors"] = EMSESP::txservice_.telegram_fail_count();
|
root["tx_errors"] = EMSESP::txservice_.telegram_fail_count();
|
||||||
root["mqtt_fails"] = Mqtt::publish_fails();
|
|
||||||
root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
|
||||||
root["free_mem"] = System::free_mem();
|
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|||||||
@@ -126,9 +126,12 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t master_thermostat;
|
uint8_t master_thermostat = 0;
|
||||||
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
||||||
master_thermostat = settings.master_thermostat; // what the user has defined
|
master_thermostat = settings.master_thermostat; // what the user has defined
|
||||||
|
});
|
||||||
|
|
||||||
|
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & settings) {
|
||||||
mqtt_format_ = settings.mqtt_format; // single, nested or ha
|
mqtt_format_ = settings.mqtt_format; // single, nested or ha
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -247,11 +247,9 @@ void Mqtt::start(AsyncMqttClient * mqttClient) {
|
|||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & wifiSettings) { hostname_ = wifiSettings.hostname.c_str(); });
|
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & wifiSettings) { hostname_ = wifiSettings.hostname.c_str(); });
|
||||||
|
|
||||||
// fetch MQTT settings
|
// fetch MQTT settings
|
||||||
// EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & mqttSettings) { mqtt_enabled_ = mqttSettings.enabled; });
|
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & mqttSettings) {
|
||||||
|
publish_time_ = mqttSettings.publish_time * 1000; // convert to milliseconds
|
||||||
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
mqtt_qos_ = mqttSettings.mqtt_qos;
|
||||||
publish_time_ = settings.publish_time * 1000; // convert to milliseconds
|
|
||||||
mqtt_qos_ = settings.mqtt_qos;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ uuid::log::Logger Sensors::logger_{F_(logger_name), uuid::log::Facility::DAEMON}
|
|||||||
|
|
||||||
void Sensors::start() {
|
void Sensors::start() {
|
||||||
// copy over values from MQTT so we don't keep on quering the filesystem
|
// copy over values from MQTT so we don't keep on quering the filesystem
|
||||||
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & settings) {
|
||||||
mqtt_format_ = settings.mqtt_format; // single, nested or ha
|
mqtt_format_ = settings.mqtt_format; // single, nested or ha
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -225,10 +225,9 @@ void System::start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fetch settings
|
// fetch settings
|
||||||
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) { tx_mode_ = settings.tx_mode; });
|
||||||
tx_mode_ = settings.tx_mode;
|
|
||||||
system_heartbeat_ = settings.system_heartbeat;
|
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & settings) { system_heartbeat_ = settings.system_heartbeat; });
|
||||||
});
|
|
||||||
|
|
||||||
syslog_init();
|
syslog_init();
|
||||||
|
|
||||||
@@ -596,7 +595,9 @@ void System::console_commands(Shell & shell, unsigned int context) {
|
|||||||
shell.print(" ");
|
shell.print(" ");
|
||||||
shell.printfln(F_(mark_interval_fmt), settings.syslog_mark_interval);
|
shell.printfln(F_(mark_interval_fmt), settings.syslog_mark_interval);
|
||||||
shell.println();
|
shell.println();
|
||||||
shell.printfln(F_(system_heartbeat_fmt), settings.system_heartbeat ? F_(enabled) : F_(disabled));
|
bool system_heartbeat;
|
||||||
|
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & settings) { system_heartbeat = settings.system_heartbeat; });
|
||||||
|
shell.printfln(F_(system_heartbeat_fmt), system_heartbeat ? F_(enabled) : F_(disabled));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user