UI improvements in web

This commit is contained in:
proddy
2020-07-17 14:23:41 +02:00
parent 0e417f0257
commit 5b229b16dc
28 changed files with 171 additions and 102 deletions

View File

@@ -5,10 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.0.0 alpha] ## [2.0.0 beta]
### Changed ### Changed
- everything. See README - everything. See `README.md`
## [1.9.5] 30-04-2020 ## [1.9.5] 30-04-2020

View File

@@ -1,13 +1,19 @@
# EMS-ESP version 2.0 # EMS-ESP version 2.0
## **Breaking changes**
- MQTT base has been removed. The hostname is only used.
## **New Features in v2** ## **New Features in v2**
- A new web interface using React and TypeScript that's now secure as each URL endpoint is protected by issuing a JWT which is then sent using Bearer Authentication. Using a Captive Portal in AP mode or connecting to a local wifi network. - A new web interface using React and TypeScript that's now secure as each URL endpoint is protected by issuing a JWT which is then sent using Bearer Authentication. Using a Captive Portal in AP mode or connecting to a local wifi network.
![settings](media/web_settings.PNG) <img src="media/web_settings.PNG" width=70% height=70%>
![status](media/web_status.PNG) <img src="media/web_status.PNG" width=70% height=70%>
<img src="media/web_devices.PNG" width=70% height=70%>
<img src="media/web_mqtt.PNG" width=70% height=70%>
- A new console. Like in version 1.9 it works with both Serial and Telnet but with a rich set of commands and more intuitive with behavior similar to a Linux-style shell. It supports multiple connections and commands that alter the settings or interact directly with EMS devices are secure behind an admin password. A full list of commands is below, here are the key ones: - A new console. Like in version 1.9 it works with both Serial and Telnet but with a more intuitive Linux shell like behavior. It supports multiple connections and has basic security to prevent any changes to EMS-ESP. A full list of commands is below, here are the key ones:
* `help` lists the commands and keywords * `help` lists the commands and keywords
* some commands take you into a new context, a bit like a sub-menu. e.g. `system`, `thermostat`. Use `help` to show which commands this context has and `exit` or CTRL-D to get back to the root. * some commands take you into a new context, a bit like a sub-menu. e.g. `system`, `thermostat`. Use `help` to show which commands this context has and `exit` or CTRL-D to get back to the root.
* To change a setting use the `set` command. Typing `set` shows the current settings. * To change a setting use the `set` command. Typing `set` shows the current settings.
@@ -112,43 +118,73 @@ thermostat
- See if it's easier to use timers instead of millis() based timers, using [polledTimeout](https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino). - See if it's easier to use timers instead of millis() based timers, using [polledTimeout](https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino).
- Port over to ESP-IDF. The Arduino SDK is showing its limitations - Port over to ESP-IDF. The Arduino SDK is showing its limitations
### **Features to add**
- Multi-language. German, Dutch, French
- Click on a device in the Web UI shows it's details
- Publish time can be customized per device (solar, mixing etc)
### **Customizing the Web UI** ### **Customizing the Web UI**
The Web is based off Rick's awesome [esp8266-react](https://github.com/rjwats/esp8266-react/) framework. These are the files that are modified: The Web is based off Rick's awesome [esp8266-react](https://github.com/rjwats/esp8266-react/) framework. These are the files that are modified:
**`interface:`** **`interface:`**
* `.env` (project name and project path to ems-esp) * `.env` project name and project path to ems-esp
* `.env.development` (CORS URL) * `.env.development` CORS URL
**`interface/public:`** **`interface/public:`**
* `app/manifest.json` (ems-esp name) * `app/manifest.json` ems-esp name
* `index.html` (ems-esp name) * `index.html` ems-esp name
* `app/icon.png` (256x256 PNG) * `app/icon.png` 256x256 PNG
* `favicon.ico` * `favicon.ico` replaced
**`interface/src:`** **`interface/src:`**
* `CustomMuiTheme.tsx` (colors for dark mode) * `CustomMuiTheme.tsx` colors for dark mode
* `interface/src/wifi/WifiSettingsController.tsx` (rename esp8266-react) * `interface/src/wifi/WifiSettingsController.tsx` rename esp8266-react
**`interface/src/project:`** **`interface/src/project:`**
* `ProjectRouting.tsx` (removed demo, renamed DemoProject to EMSESP) * `ProjectRouting.tsx` removed demo, added paths to ems-esp/status, ems-esp/settings and *
* `DemoProject.tsx` (remove /demo/ and changed title, renamed to EMSESP.tsx) * `DemoProject.tsx` remove /demo/ and changed title, renamed to EMSESP.tsx
* `ProjectMenu.tsx` (title) * `ProjectMenu.tsx` title change, added /ems-esp/settings
* `DemoInformation.tsx` (removed file) * `DemoInformation.tsx` removed file
* `types.ts` (add variables) * `types.ts` add variables
* added all custom files starting with EMSESP*
**`interface/src/mqtt:`**
* `types.ts` added mqtt_fails
* `MqttStatusForm.tsx` added MQTT Publish Errors
* `MqttStatus.ts` added function mqttPublishHighlight
* `MqttSettingsForm.tsx` added publish time, qos, format
**`interface/src/authentication:`**
* `AuthenticationWrapper.tsx` commented out features.security because we added version
* `AuthenticationContext.tsx` added version
* `MqttSettingsForm.tsx` added publish time, qos, format
**`interface/src/components:`**
* `MenuAppBar.tsx` added version to toolbar
**`interface/src/system:`**
* `types.ts` added uptime and free_mem
* `SystemStatusForm.tsx` added system uptime, % free mem
**`lib/framework`:** **`lib/framework`:**
* `SystemStatus.h` added #include <LittleFS.h>, #include <uuid/log.h>, #include "../../src/system.h"
* `SystemStatus.h` : added #include <LittleFS.h> * `SystemStatus.cpp` added LittleFS.info(fs_info); root["uptime"], root["free_mem"]
* `SystemStatus.cpp` : added LittleFS.info(fs_info); * Commented out all `Serial.print`'s in all files
* Commented out all `Serial.print`'s * `MqttStatus.h` added #include "../../src/mqtt.h"
* `MqttStatus.cpp` added root["mqtt_fails"]
* `SecuritySettingsService.cpp` added version to the JWT payload
* `SecuritySettingsService.h` #include "../../src/version.h"
* `features.ini`: -D FT_NTP=0 * `features.ini`: -D FT_NTP=0
* customized `platformio.ini` * `platformio.ini` using our own version
* customized `factory_settings.ini` with `ems-esp-neo` as password and `ems-esp` everywhere else * `factory_settings.ini` modified with `ems-esp-neo` as password and `ems-esp` everywhere else
Info on UI customizations: UI customization links:
* icons: https://material-ui.com/components/material-icons/ * icons: https://material-ui.com/components/material-icons/
* colors: https://material-ui.com/customization/color/ * colors: https://material-ui.com/customization/color/
* tables: https://material-ui.com/components/tables/#dense-table * tables: https://material-ui.com/components/tables/#dense-table

View File

@@ -3,6 +3,7 @@ import * as React from "react";
export interface Me { export interface Me {
username: string; username: string;
admin: boolean; admin: boolean;
version: string; // proddy added
} }
export interface AuthenticationContext { export interface AuthenticationContext {

View File

@@ -59,10 +59,11 @@ class AuthenticationWrapper extends React.Component<AuthenticationWrapperProps,
} }
refresh = () => { refresh = () => {
if (!this.props.features.security) { // proddy removed
this.setState({ initialized: true, context: { ...this.state.context, me: { admin: true, username: "admin" } } }); // if (!this.props.features.security) {
return; // this.setState({ initialized: true, context: { ...this.state.context, me: { admin: true, username: "admin" } } });
} // return;
// }
const accessToken = getStorage().getItem(ACCESS_TOKEN) const accessToken = getStorage().getItem(ACCESS_TOKEN)
if (accessToken) { if (accessToken) {
authorizedFetch(VERIFY_AUTHORIZATION_ENDPOINT) authorizedFetch(VERIFY_AUTHORIZATION_ENDPOINT)

View File

@@ -124,11 +124,18 @@ class MenuAppBar extends React.Component<MenuAppBarProps, MenuAppBarState> {
<Box display="flex"> <Box display="flex">
<img src="/app/icon.png" className={classes.toolbarImage} alt={PROJECT_NAME} /> <img src="/app/icon.png" className={classes.toolbarImage} alt={PROJECT_NAME} />
</Box> </Box>
<Typography variant="h6" color="textPrimary"> <Typography variant="h6" color="textPrimary">
{PROJECT_NAME} {PROJECT_NAME}
</Typography> </Typography>
<Typography align="right" variant="caption" color="textPrimary">
&nbsp;&nbsp;{authenticatedContext.me.version}
</Typography>
<Divider absolute /> <Divider absolute />
</Toolbar> </Toolbar>
{features.project && ( {features.project && (
<Fragment> <Fragment>
<ProjectMenu /> <ProjectMenu />

View File

@@ -44,7 +44,7 @@ export const disconnectReason = ({ disconnect_reason }: MqttStatus) => {
} }
} }
export const mqttStatusHighlight2 = ({ mqtt_fails }: MqttStatus, theme: Theme) => { export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatus, theme: Theme) => {
if (mqtt_fails === 0) if (mqtt_fails === 0)
return theme.palette.success.main; return theme.palette.success.main;
@@ -53,5 +53,4 @@ export const mqttStatusHighlight2 = ({ mqtt_fails }: MqttStatus, theme: Theme) =
return theme.palette.warning.main; return theme.palette.warning.main;
return theme.palette.success.main; return theme.palette.success.main;
} }

View File

@@ -9,7 +9,7 @@ import ReportIcon from '@material-ui/icons/Report';
import SpeakerNotesOffIcon from "@material-ui/icons/SpeakerNotesOff"; import SpeakerNotesOffIcon from "@material-ui/icons/SpeakerNotesOff";
import { RestFormProps, FormActions, FormButton, HighlightAvatar } from '../components'; import { RestFormProps, FormActions, FormButton, HighlightAvatar } from '../components';
import { mqttStatusHighlight, mqttStatus, mqttStatusHighlight2, disconnectReason } from './MqttStatus'; import { mqttStatusHighlight, mqttStatus, mqttPublishHighlight, disconnectReason } from './MqttStatus';
import { MqttStatus } from './types'; import { MqttStatus } from './types';
type MqttStatusFormProps = RestFormProps<MqttStatus> & WithTheme; type MqttStatusFormProps = RestFormProps<MqttStatus> & WithTheme;
@@ -30,7 +30,7 @@ class MqttStatusForm extends Component<MqttStatusFormProps> {
<Divider variant="inset" component="li" /> <Divider variant="inset" component="li" />
<ListItem> <ListItem>
<ListItemAvatar> <ListItemAvatar>
<HighlightAvatar color={mqttStatusHighlight2(data, theme)}> <HighlightAvatar color={mqttPublishHighlight(data, theme)}>
<SpeakerNotesOffIcon /> <SpeakerNotesOffIcon />
</HighlightAvatar> </HighlightAvatar>
</ListItemAvatar> </ListItemAvatar>

View File

@@ -9,6 +9,7 @@ import { AuthenticatedRoute } from '../authentication';
import EMSESPStatusController from './EMSESPStatusController'; import EMSESPStatusController from './EMSESPStatusController';
import EMSESPDevicesController from './EMSESPDevicesController'; import EMSESPDevicesController from './EMSESPDevicesController';
import EMSESPHelp from './EMSESPHelp';
class EMSESP extends Component<RouteComponentProps> { class EMSESP extends Component<RouteComponentProps> {
@@ -20,10 +21,12 @@ class EMSESP extends Component<RouteComponentProps> {
return ( return (
<MenuAppBar sectionTitle="Dashboard"> <MenuAppBar sectionTitle="Dashboard">
<Tabs value={this.props.match.url} onChange={this.handleTabChange} variant="fullWidth"> <Tabs value={this.props.match.url} onChange={this.handleTabChange} variant="fullWidth">
<Tab value={`/${PROJECT_PATH}/status`} label="EMS-ESP Status" /> <Tab value={`/${PROJECT_PATH}/status`} label="EMS Status" />
<Tab value={`/${PROJECT_PATH}/devices`} label="EMS Devices" /> <Tab value={`/${PROJECT_PATH}/devices`} label="EMS Devices" />
<Tab value={`/${PROJECT_PATH}/help`} label="EMS-ESP Help" />
</Tabs> </Tabs>
<Switch> <Switch>
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/help`} component={EMSESPHelp} />
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/status`} component={EMSESPStatusController} /> <AuthenticatedRoute exact path={`/${PROJECT_PATH}/status`} component={EMSESPStatusController} />
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/devices`} component={EMSESPDevicesController} /> <AuthenticatedRoute exact path={`/${PROJECT_PATH}/devices`} component={EMSESPDevicesController} />
<Redirect to={`/${PROJECT_PATH}/status`} /> <Redirect to={`/${PROJECT_PATH}/status`} />

View File

@@ -115,7 +115,7 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
( (
<Box bgcolor="error.main" color="error.contrastText" p={2} mt={2} mb={2}> <Box bgcolor="error.main" color="error.contrastText" p={2} mt={2} mb={2}>
<Typography variant="body1"> <Typography variant="body1">
No EMS devices found. Check connection and for Tx errors. Try forcing a scan. No EMS devices found. Check the connection and for possible Tx errors and try scanning for new devices.
</Typography> </Typography>
</Box> </Box>
) )
@@ -174,8 +174,9 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
render() { render() {
return ( return (
<Fragment> <Fragment>
<br></br>
{this.createTableItems()} {this.createTableItems()}
<br></br>
<Box display="flex" flexWrap="wrap"> <Box display="flex" flexWrap="wrap">
<Box flexGrow={1} padding={1}> <Box flexGrow={1} padding={1}>
<FormButton startIcon={<RefreshIcon />} variant="contained" color="secondary" onClick={this.props.loadData}> <FormButton startIcon={<RefreshIcon />} variant="contained" color="secondary" onClick={this.props.loadData}>

View File

@@ -0,0 +1,35 @@
import React, { Component } from 'react';
import { Typography, Box, Link } from '@material-ui/core';
import { SectionContent } from '../components';
class EMSESPHelp extends Component {
render() {
return (
<SectionContent title='EMS-ESP Help' titleGutter>
<Box bgcolor="info.main" border={1} p={3} mt={1} mb={0}>
<Typography variant="body1">
EMS-ESP is an open-source firmware to communicate with heating devices that support the EMS protocol, such as equipment from Bosch, Junkers, Nefit, Buderus and Worcester.
<p></p>
Please consider supporting this project via the GitHub page <Link href="https://github.com/proddy/EMS-ESP" color="primary">{'http://github.com/proddy/EMS-ESP'}</Link>.
</Typography>
</Box>
<br></br>
<Typography variant="body1" paragraph>
Check for news and updates on the <Link href="https://emsesp.github.io/docs/#/" color="primary">{'Wiki'}</Link>.
</Typography>
<Typography variant="body1" paragraph>
For live community chat go to <Link href="https://gitter.im/EMS-ESP/community#" color="primary">{'Gitter'}</Link>.
</Typography>
<Typography variant="body1" paragraph>
To report an issue or feature request go to <Link href="https://github.com/proddy/EMS-ESP/issues/new/choose" color="primary">{'the github project page'}</Link>.
</Typography>
</SectionContent>
)
}
}
export default EMSESPHelp;

View File

@@ -17,7 +17,7 @@ class EMSESPStatusController extends Component<EMSESPStatusControllerProps> {
render() { render() {
return ( return (
<SectionContent title="EMS-ESP Status"> <SectionContent title="EMS Status">
<RestFormLoader <RestFormLoader
{...this.props} {...this.props}
render={formProps => <EMSESPStatusForm {...formProps} />} render={formProps => <EMSESPStatusForm {...formProps} />}

View File

@@ -12,9 +12,6 @@ import {
ListItem, ListItem,
ListItemAvatar, ListItemAvatar,
ListItemText, ListItemText,
Typography,
Box,
Link
} from "@material-ui/core"; } from "@material-ui/core";
import RefreshIcon from "@material-ui/icons/Refresh"; import RefreshIcon from "@material-ui/icons/Refresh";
@@ -42,17 +39,7 @@ class EMSESPStatusForm extends Component<EMSESPStatusFormProps> {
const { data, theme } = this.props; const { data, theme } = this.props;
return ( return (
<Fragment> <Fragment>
<Box bgcolor="info.main" border={1} p={3} mt={1} mb={0}>
<Typography variant="body1">
Firmware Version is <b>{data.version}</b>
<br /><br />
Check for news and updates on the <Link href="https://emsesp.github.io/docs/#/" color="primary">{'Wiki'}</Link>
<br/>
For live community chat go to <Link href="https://gitter.im/EMS-ESP/community#" color="primary">{'Gitter'}</Link>
<br/>
To report issues, contribute and give kudos visit <Link href="https://github.com/proddy/EMS-ESP" color="primary">{'github.com/proddy/EMS-ESP'}</Link>
</Typography>
</Box>
<ListItem> <ListItem>
<ListItemAvatar> <ListItemAvatar>
<HighlightAvatar color={busStatusHighlight(data, theme)}> <HighlightAvatar color={busStatusHighlight(data, theme)}>

View File

@@ -16,7 +16,6 @@ export enum busConnectionStatus {
} }
export interface EMSESPStatus { export interface EMSESPStatus {
version: string;
status: busConnectionStatus; status: busConnectionStatus;
rx_received: number; rx_received: number;
tx_sent: number; tx_sent: number;

View File

@@ -2,7 +2,6 @@ import React, { Component } from 'react';
import { restController, RestControllerProps, RestFormLoader, SectionContent } from '../components'; import { restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
import WiFiSettingsForm from './WiFiSettingsForm'; import WiFiSettingsForm from './WiFiSettingsForm';
import { WiFiConnectionContext } from './WiFiConnectionContext';
import { WIFI_SETTINGS_ENDPOINT } from '../api'; import { WIFI_SETTINGS_ENDPOINT } from '../api';
import { WiFiSettings } from './types'; import { WiFiSettings } from './types';
@@ -10,39 +9,15 @@ type WiFiSettingsControllerProps = RestControllerProps<WiFiSettings>;
class WiFiSettingsController extends Component<WiFiSettingsControllerProps> { class WiFiSettingsController extends Component<WiFiSettingsControllerProps> {
static contextType = WiFiConnectionContext;
context!: React.ContextType<typeof WiFiConnectionContext>;
componentDidMount() { componentDidMount() {
const { selectedNetwork } = this.context;
if (selectedNetwork) {
const wifiSettings: WiFiSettings = {
ssid: selectedNetwork.ssid,
password: "",
hostname: "ems-esp",
static_ip_config: false,
}
this.props.setData(wifiSettings);
} else {
this.props.loadData(); this.props.loadData();
} }
}
deselectNetworkAndLoadData = () => {
this.context.deselectNetwork();
this.props.loadData();
}
componentWillUnmount() {
this.context.deselectNetwork();
}
render() { render() {
return ( return (
<SectionContent title="WiFi Settings"> <SectionContent title="WiFi Settings">
<RestFormLoader <RestFormLoader
{...this.props} {...this.props}
loadData={this.deselectNetworkAndLoadData}
render={formProps => <WiFiSettingsForm {...formProps} />} render={formProps => <WiFiSettingsForm {...formProps} />}
/> />
</SectionContent> </SectionContent>

View File

@@ -24,15 +24,39 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
static contextType = WiFiConnectionContext; static contextType = WiFiConnectionContext;
context!: React.ContextType<typeof WiFiConnectionContext>; context!: React.ContextType<typeof WiFiConnectionContext>;
constructor(props: WiFiStatusFormProps, context: WiFiConnectionContext) {
super(props);
const { selectedNetwork } = context;
if (selectedNetwork) {
const wifiSettings: WiFiSettings = {
ssid: selectedNetwork.ssid,
password: "",
hostname: props.data.hostname,
static_ip_config: false,
}
props.setData(wifiSettings);
}
}
componentWillMount() { componentWillMount() {
ValidatorForm.addValidationRule('isIP', isIP); ValidatorForm.addValidationRule('isIP', isIP);
ValidatorForm.addValidationRule('isHostname', isHostname); ValidatorForm.addValidationRule('isHostname', isHostname);
ValidatorForm.addValidationRule('isOptionalIP', optional(isIP)); ValidatorForm.addValidationRule('isOptionalIP', optional(isIP));
} }
deselectNetworkAndLoadData = () => {
this.context.deselectNetwork();
this.props.loadData();
}
componentWillUnmount() {
this.context.deselectNetwork();
}
render() { render() {
const { selectedNetwork, deselectNetwork } = this.context; const { selectedNetwork, deselectNetwork } = this.context;
const { data, handleValueChange, saveData, loadData } = this.props; const { data, handleValueChange, saveData } = this.props;
return ( return (
<ValidatorForm onSubmit={saveData} ref="WiFiSettingsForm"> <ValidatorForm onSubmit={saveData} ref="WiFiSettingsForm">
{ {
@@ -167,7 +191,7 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
<FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit"> <FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit">
Save Save
</FormButton> </FormButton>
<FormButton variant="contained" color="secondary" onClick={loadData}> <FormButton variant="contained" color="secondary" onClick={this.deselectNetworkAndLoadData}>
Reset Reset
</FormButton> </FormButton>
</FormActions> </FormActions>

View File

@@ -16,7 +16,7 @@ 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(); root["mqtt_fails"] = emsesp::Mqtt::publish_fails(); // proddy added
response->setLength(); response->setLength();
request->send(response); request->send(response);

View File

@@ -9,7 +9,7 @@
#include <ESPAsyncTCP.h> #include <ESPAsyncTCP.h>
#endif #endif
#include "../../src/mqtt.h" #include "../../src/mqtt.h" // proddy added
#include <MqttSettingsService.h> #include <MqttSettingsService.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>

View File

@@ -61,6 +61,7 @@ Authentication SecuritySettingsService::authenticate(const String& username, con
inline void populateJWTPayload(JsonObject& payload, User* user) { inline void populateJWTPayload(JsonObject& payload, User* user) {
payload["username"] = user->username; payload["username"] = user->username;
payload["admin"] = user->admin; payload["admin"] = user->admin;
payload["version"] = EMSESP_APP_VERSION; // proddy added
} }
boolean SecuritySettingsService::validatePayload(JsonObject& parsedPayload, User* user) { boolean SecuritySettingsService::validatePayload(JsonObject& parsedPayload, User* user) {

View File

@@ -6,6 +6,8 @@
#include <HttpEndpoint.h> #include <HttpEndpoint.h>
#include <FSPersistence.h> #include <FSPersistence.h>
#include "../../src/version.h" // added by proddy
#ifndef FACTORY_ADMIN_USERNAME #ifndef FACTORY_ADMIN_USERNAME
#define FACTORY_ADMIN_USERNAME "admin" #define FACTORY_ADMIN_USERNAME "admin"
#endif #endif

View File

@@ -34,13 +34,13 @@ void SystemStatus::systemStatus(AsyncWebServerRequest * request) {
root["fs_used"] = SPIFFS.usedBytes(); root["fs_used"] = SPIFFS.usedBytes();
#elif defined(ESP8266) #elif defined(ESP8266)
FSInfo fs_info; FSInfo fs_info;
LittleFS.info(fs_info); // TODO added littlefs LittleFS.info(fs_info); // // proddy added
root["fs_total"] = fs_info.totalBytes; root["fs_total"] = fs_info.totalBytes;
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["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); // proddy added
root["free_mem"] = emsesp::System::free_mem(); root["free_mem"] = emsesp::System::free_mem(); // proddy added
response->setLength(); response->setLength();
request->send(response); request->send(response);

View File

@@ -9,7 +9,7 @@
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h> #include <ESPAsyncTCP.h>
#include <FS.h> #include <FS.h>
#include <LittleFS.h> // TODO added littlefs #include <LittleFS.h> // proddy added
#endif #endif
#include <ArduinoJson.h> #include <ArduinoJson.h>
@@ -17,8 +17,8 @@
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include <SecurityManager.h> #include <SecurityManager.h>
#include <uuid/log.h> #include <uuid/log.h> // proddy added
#include "../../src/system.h" #include "../../src/system.h" // proddy added
#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"

BIN
media/web_devices.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
media/web_mqtt.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -37,7 +37,7 @@ libs_core =
[env] [env]
extra_scripts = extra_scripts =
pre:scripts/build_interface.py ; pre:scripts/build_interface.py
scripts/main_script.py scripts/main_script.py
framework = arduino framework = arduino

View File

@@ -54,8 +54,6 @@ void EMSESPStatusService::emsespStatusService(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_EMSESP_STATUS_SIZE); AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_EMSESP_STATUS_SIZE);
JsonObject root = response->getRoot(); JsonObject root = response->getRoot();
root["version"] = EMSESP_APP_VERSION;
root["status"] = EMSESP::bus_status(); // 0, 1 or 2 root["status"] = EMSESP::bus_status(); // 0, 1 or 2
root["rx_received"] = EMSESP::rxservice_.telegram_count(); root["rx_received"] = EMSESP::rxservice_.telegram_count();
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();

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "2.0.0_b4" // based off a32 #define EMSESP_APP_VERSION "2.0.0_b4"