moved mqtt and system to correct web pages

This commit is contained in:
proddy
2020-07-16 22:34:13 +02:00
parent 5271f59187
commit a65c3ac96f
24 changed files with 484 additions and 428 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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>
); );
} }

View File

@@ -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;
} }

View 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;

View File

@@ -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>&nbsp;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

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);
} }

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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
}); });

View File

@@ -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

View File

@@ -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
}); });

View File

@@ -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));
}); });
} }
}); });