mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
add Ethernet
This commit is contained in:
@@ -5,6 +5,7 @@ See https://github.com/proddy/EMS-ESP/issues/632
|
|||||||
### Added
|
### Added
|
||||||
- Power settings for ESP32
|
- Power settings for ESP32
|
||||||
- Rx and Tx counts to Heartbeat MQTT payload
|
- Rx and Tx counts to Heartbeat MQTT payload
|
||||||
|
- Ethernet support (ESP32)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- telegrams matched to masterthermostat 0x18
|
- telegrams matched to masterthermostat 0x18
|
||||||
|
|||||||
@@ -1,28 +1,21 @@
|
|||||||
; ESP32 with debugger
|
|
||||||
; do not build web
|
|
||||||
; builds with DEBUG and TEST
|
|
||||||
|
|
||||||
[platformio]
|
|
||||||
default_envs = esp32
|
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
upload_port = COM3
|
; upload_port = COM3
|
||||||
|
|
||||||
; upload_protocol = espota
|
|
||||||
; upload_flags =
|
|
||||||
; --port=8266
|
|
||||||
; --auth=ems-esp-neo
|
|
||||||
; upload_port = ems-esp.local
|
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
debug_flags = -DEMSESP_DEBUG -DEMSESP_TEST -DEMSESP_FORCE_SERIAL
|
; debug_flags = -DENABLE_CORS -DEMSESP_DEBUG -DEMSESP_TEST
|
||||||
|
debug_flags = -DEMSESP_DEBUG -DEMSESP_TEST
|
||||||
|
; debug_flags = -DEMSESP_TEST
|
||||||
|
|
||||||
|
upload_protocol = espota
|
||||||
|
upload_flags =
|
||||||
|
--port=8266
|
||||||
|
--auth=ems-esp-neo
|
||||||
|
upload_port = ems-esp.local
|
||||||
|
|
||||||
[env:esp32]
|
[env:esp32]
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
debug_tool = esp-prog
|
debug_tool = esp-prog
|
||||||
debug_init_break = tbreak setup
|
debug_init_break = tbreak setup
|
||||||
build_type = debug
|
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
; pre:scripts/build_interface.py
|
; pre:scripts/build_interface.py
|
||||||
scripts/rename_fw.py
|
scripts/rename_fw.py
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
; ESP8266
|
|
||||||
; local example the does not build the web UI
|
|
||||||
|
|
||||||
[platformio]
|
|
||||||
default_envs = esp8266
|
|
||||||
|
|
||||||
[common]
|
|
||||||
; debug_flags = -DENABLE_CORS -DEMSESP_TEST
|
|
||||||
|
|
||||||
[env]
|
|
||||||
; upload_port = COM3
|
|
||||||
|
|
||||||
upload_protocol = espota
|
|
||||||
upload_flags =
|
|
||||||
--port=8266
|
|
||||||
--auth=ems-esp-neo
|
|
||||||
upload_port = ems-esp.local
|
|
||||||
|
|
||||||
[env:esp8266]
|
|
||||||
extra_scripts =
|
|
||||||
; pre:scripts/build_interface.py
|
|
||||||
scripts/main_script.py
|
|
||||||
scripts/rename_fw.py
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
# Remember to also enable CORS in platformio.ini before uploading the code to the device.
|
# Remember to also enable CORS in platformio.ini before uploading the code to the device.
|
||||||
|
|
||||||
# ESP32 dev
|
# ESP32 dev
|
||||||
REACT_APP_HTTP_ROOT=http://10.10.10.194
|
REACT_APP_HTTP_ROOT=http://192.168.1.32
|
||||||
REACT_APP_WEB_SOCKET_ROOT=ws://10.10.10.194
|
REACT_APP_WEB_SOCKET_ROOT=ws://192.168.1.32
|
||||||
|
|
||||||
# ESP8266 dev
|
# ESP8266 dev
|
||||||
#REACT_APP_HTTP_ROOT=http://10.10.10.140
|
#REACT_APP_HTTP_ROOT=http://10.10.10.140
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import AuthenticatedRoute from './authentication/AuthenticatedRoute';
|
|||||||
|
|
||||||
import SignIn from './SignIn';
|
import SignIn from './SignIn';
|
||||||
import ProjectRouting from './project/ProjectRouting';
|
import ProjectRouting from './project/ProjectRouting';
|
||||||
import WiFiConnection from './wifi/WiFiConnection';
|
import NetworkConnection from './network/NetworkConnection';
|
||||||
import AccessPoint from './ap/AccessPoint';
|
import AccessPoint from './ap/AccessPoint';
|
||||||
import NetworkTime from './ntp/NetworkTime';
|
import NetworkTime from './ntp/NetworkTime';
|
||||||
import Security from './security/Security';
|
import Security from './security/Security';
|
||||||
@@ -19,8 +19,7 @@ import Mqtt from './mqtt/Mqtt';
|
|||||||
import { withFeatures, WithFeaturesProps } from './features/FeaturesContext';
|
import { withFeatures, WithFeaturesProps } from './features/FeaturesContext';
|
||||||
import { Features } from './features/types';
|
import { Features } from './features/types';
|
||||||
|
|
||||||
export const getDefaultRoute = (features: Features) => features.project ? `/${PROJECT_PATH}/` : "/wifi/";
|
export const getDefaultRoute = (features: Features) => features.project ? `/${PROJECT_PATH}/` : "/network/";
|
||||||
|
|
||||||
class AppRouting extends Component<WithFeaturesProps> {
|
class AppRouting extends Component<WithFeaturesProps> {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -38,10 +37,10 @@ class AppRouting extends Component<WithFeaturesProps> {
|
|||||||
{features.project && (
|
{features.project && (
|
||||||
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/*`} component={ProjectRouting} />
|
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/*`} component={ProjectRouting} />
|
||||||
)}
|
)}
|
||||||
<AuthenticatedRoute exact path="/wifi/*" component={WiFiConnection} />
|
<AuthenticatedRoute exact path="/network/*" component={NetworkConnection} />
|
||||||
<AuthenticatedRoute exact path="/ap/*" component={AccessPoint} />
|
<AuthenticatedRoute exact path="/ap/*" component={AccessPoint} />
|
||||||
{features.ntp && (
|
{features.ntp && (
|
||||||
<AuthenticatedRoute exact path="/ntp/*" component={NetworkTime} />
|
<AuthenticatedRoute exact path="/ntp/*" component={NetworkTime} />
|
||||||
)}
|
)}
|
||||||
{features.mqtt && (
|
{features.mqtt && (
|
||||||
<AuthenticatedRoute exact path="/mqtt/*" component={Mqtt} />
|
<AuthenticatedRoute exact path="/mqtt/*" component={Mqtt} />
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ export const AP_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "apSettings";
|
|||||||
export const AP_STATUS_ENDPOINT = ENDPOINT_ROOT + "apStatus";
|
export const AP_STATUS_ENDPOINT = ENDPOINT_ROOT + "apStatus";
|
||||||
export const SCAN_NETWORKS_ENDPOINT = ENDPOINT_ROOT + "scanNetworks";
|
export const SCAN_NETWORKS_ENDPOINT = ENDPOINT_ROOT + "scanNetworks";
|
||||||
export const LIST_NETWORKS_ENDPOINT = ENDPOINT_ROOT + "listNetworks";
|
export const LIST_NETWORKS_ENDPOINT = ENDPOINT_ROOT + "listNetworks";
|
||||||
export const WIFI_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "wifiSettings";
|
export const NETWORK_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "networkSettings";
|
||||||
export const WIFI_STATUS_ENDPOINT = ENDPOINT_ROOT + "wifiStatus";
|
export const NETWORK_STATUS_ENDPOINT = ENDPOINT_ROOT + "networkStatus";
|
||||||
export const OTA_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "otaSettings";
|
export const OTA_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "otaSettings";
|
||||||
export const UPLOAD_FIRMWARE_ENDPOINT = ENDPOINT_ROOT + "uploadFirmware";
|
export const UPLOAD_FIRMWARE_ENDPOINT = ENDPOINT_ROOT + "uploadFirmware";
|
||||||
export const MQTT_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "mqttSettings";
|
export const MQTT_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "mqttSettings";
|
||||||
|
|||||||
@@ -144,11 +144,11 @@ class MenuAppBar extends React.Component<MenuAppBarProps, MenuAppBarState> {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<List>
|
<List>
|
||||||
<ListItem to='/wifi/' selected={path.startsWith('/wifi/')} button component={Link}>
|
<ListItem to='/network/' selected={path.startsWith('/network/')} button component={Link}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<WifiIcon />
|
<WifiIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary="WiFi Connection" />
|
<ListItemText primary="Network Connection" />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem to='/ap/' selected={path.startsWith('/ap/')} button component={Link}>
|
<ListItem to='/ap/' selected={path.startsWith('/ap/')} button component={Link}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
|
|||||||
62
interface/src/network/NetworkConnection.tsx
Normal file
62
interface/src/network/NetworkConnection.tsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import { Redirect, Switch, RouteComponentProps } from 'react-router-dom'
|
||||||
|
|
||||||
|
import { Tabs, Tab } from '@material-ui/core';
|
||||||
|
|
||||||
|
import { withAuthenticatedContext, AuthenticatedContextProps, AuthenticatedRoute } from '../authentication';
|
||||||
|
import { MenuAppBar } from '../components';
|
||||||
|
|
||||||
|
import NetworkStatusController from './NetworkStatusController';
|
||||||
|
import NetworkSettingsController from './NetworkSettingsController';
|
||||||
|
import WiFiNetworkScanner from './WiFiNetworkScanner';
|
||||||
|
import { NetworkConnectionContext } from './NetworkConnectionContext';
|
||||||
|
import { WiFiNetwork } from './types';
|
||||||
|
|
||||||
|
type NetworkConnectionProps = AuthenticatedContextProps & RouteComponentProps;
|
||||||
|
|
||||||
|
class NetworkConnection extends Component<NetworkConnectionProps, NetworkConnectionContext> {
|
||||||
|
|
||||||
|
constructor(props: NetworkConnectionProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
selectNetwork: this.selectNetwork,
|
||||||
|
deselectNetwork: this.deselectNetwork
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
selectNetwork = (network: WiFiNetwork) => {
|
||||||
|
this.setState({ selectedNetwork: network });
|
||||||
|
this.props.history.push('/network/settings');
|
||||||
|
}
|
||||||
|
|
||||||
|
deselectNetwork = () => {
|
||||||
|
this.setState({ selectedNetwork: undefined });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTabChange = (event: React.ChangeEvent<{}>, path: string) => {
|
||||||
|
this.props.history.push(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { authenticatedContext } = this.props;
|
||||||
|
return (
|
||||||
|
<NetworkConnectionContext.Provider value={this.state}>
|
||||||
|
<MenuAppBar sectionTitle="Network Connection">
|
||||||
|
<Tabs value={this.props.match.url} onChange={this.handleTabChange} variant="fullWidth">
|
||||||
|
<Tab value="/network/status" label="Network Status" />
|
||||||
|
<Tab value="/network/scan" label="Scan Networks" disabled={!authenticatedContext.me.admin} />
|
||||||
|
<Tab value="/network/settings" label="Network Settings" disabled={!authenticatedContext.me.admin} />
|
||||||
|
</Tabs>
|
||||||
|
<Switch>
|
||||||
|
<AuthenticatedRoute exact path="/network/status" component={NetworkStatusController} />
|
||||||
|
<AuthenticatedRoute exact path="/network/scan" component={WiFiNetworkScanner} />
|
||||||
|
<AuthenticatedRoute exact path="/network/settings" component={NetworkSettingsController} />
|
||||||
|
<Redirect to="/network/status" />
|
||||||
|
</Switch>
|
||||||
|
</MenuAppBar>
|
||||||
|
</NetworkConnectionContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withAuthenticatedContext(NetworkConnection);
|
||||||
13
interface/src/network/NetworkConnectionContext.tsx
Normal file
13
interface/src/network/NetworkConnectionContext.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { WiFiNetwork } from './types';
|
||||||
|
|
||||||
|
export interface NetworkConnectionContext {
|
||||||
|
selectedNetwork?: WiFiNetwork;
|
||||||
|
selectNetwork: (network: WiFiNetwork) => void;
|
||||||
|
deselectNetwork: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetworkConnectionContextDefaultValue = {} as NetworkConnectionContext
|
||||||
|
export const NetworkConnectionContext = React.createContext(
|
||||||
|
NetworkConnectionContextDefaultValue
|
||||||
|
);
|
||||||
29
interface/src/network/NetworkSettingsController.tsx
Normal file
29
interface/src/network/NetworkSettingsController.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import { restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
|
||||||
|
import NetworkSettingsForm from './NetworkSettingsForm';
|
||||||
|
import { NETWORK_SETTINGS_ENDPOINT } from '../api';
|
||||||
|
import { NetworkSettings } from './types';
|
||||||
|
|
||||||
|
type NetworkSettingsControllerProps = RestControllerProps<NetworkSettings>;
|
||||||
|
|
||||||
|
class NetworkSettingsController extends Component<NetworkSettingsControllerProps> {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<SectionContent title="Network Settings">
|
||||||
|
<RestFormLoader
|
||||||
|
{...this.props}
|
||||||
|
render={formProps => <NetworkSettingsForm {...formProps} />}
|
||||||
|
/>
|
||||||
|
</SectionContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default restController(NETWORK_SETTINGS_ENDPOINT, NetworkSettingsController);
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
import { TextValidator, SelectValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||||
|
|
||||||
import { Checkbox, List, ListItem, ListItemText, ListItemAvatar, ListItemSecondaryAction } from '@material-ui/core';
|
import { Checkbox, List, ListItem, ListItemText, ListItemAvatar, ListItemSecondaryAction } from '@material-ui/core';
|
||||||
|
|
||||||
@@ -9,33 +9,35 @@ import LockIcon from '@material-ui/icons/Lock';
|
|||||||
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
||||||
import DeleteIcon from '@material-ui/icons/Delete';
|
import DeleteIcon from '@material-ui/icons/Delete';
|
||||||
import SaveIcon from '@material-ui/icons/Save';
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
|
||||||
import { RestFormProps, PasswordValidator, BlockFormControlLabel, FormActions, FormButton } from '../components';
|
import { RestFormProps, PasswordValidator, BlockFormControlLabel, FormActions, FormButton } from '../components';
|
||||||
import { isIP, isHostname, optional } from '../validators';
|
import { isIP, isHostname, optional } from '../validators';
|
||||||
|
|
||||||
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
import { NetworkConnectionContext } from './NetworkConnectionContext';
|
||||||
import { isNetworkOpen, networkSecurityMode } from './WiFiSecurityModes';
|
import { isNetworkOpen, networkSecurityMode } from './WiFiSecurityModes';
|
||||||
import { WiFiSettings } from './types';
|
import { NetworkSettings } from './types';
|
||||||
|
|
||||||
type WiFiStatusFormProps = RestFormProps<WiFiSettings>;
|
type NetworkStatusFormProps = RestFormProps<NetworkSettings>;
|
||||||
|
|
||||||
class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
|
class NetworkSettingsForm extends React.Component<NetworkStatusFormProps> {
|
||||||
|
|
||||||
static contextType = WiFiConnectionContext;
|
static contextType = NetworkConnectionContext;
|
||||||
context!: React.ContextType<typeof WiFiConnectionContext>;
|
context!: React.ContextType<typeof NetworkConnectionContext>;
|
||||||
|
|
||||||
constructor(props: WiFiStatusFormProps, context: WiFiConnectionContext) {
|
constructor(props: NetworkStatusFormProps, context: NetworkConnectionContext) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const { selectedNetwork } = context;
|
const { selectedNetwork } = context;
|
||||||
if (selectedNetwork) {
|
if (selectedNetwork) {
|
||||||
const wifiSettings: WiFiSettings = {
|
const networkSettings: NetworkSettings = {
|
||||||
ssid: selectedNetwork.ssid,
|
ssid: selectedNetwork.ssid,
|
||||||
password: "",
|
password: "",
|
||||||
hostname: props.data.hostname,
|
hostname: props.data.hostname,
|
||||||
|
ethernet_profile: 0,
|
||||||
static_ip_config: false,
|
static_ip_config: false,
|
||||||
}
|
}
|
||||||
props.setData(wifiSettings);
|
props.setData(networkSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +60,7 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
|
|||||||
const { selectedNetwork, deselectNetwork } = this.context;
|
const { selectedNetwork, deselectNetwork } = this.context;
|
||||||
const { data, handleValueChange, saveData } = this.props;
|
const { data, handleValueChange, saveData } = this.props;
|
||||||
return (
|
return (
|
||||||
<ValidatorForm onSubmit={saveData} ref="WiFiSettingsForm">
|
<ValidatorForm onSubmit={saveData} ref="NetworkSettingsForm">
|
||||||
{
|
{
|
||||||
selectedNetwork ?
|
selectedNetwork ?
|
||||||
<List>
|
<List>
|
||||||
@@ -117,6 +119,17 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
|
|||||||
onChange={handleValueChange('hostname')}
|
onChange={handleValueChange('hostname')}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
|
<SelectValidator name="ems_bus_id"
|
||||||
|
label="Ethernet Profile"
|
||||||
|
value={data.ethernet_profile}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleValueChange('ethernet_profile')}
|
||||||
|
margin="normal">
|
||||||
|
<MenuItem value={0}>None (wifi only)</MenuItem>
|
||||||
|
<MenuItem value={1}>Profile 1 (LAN8720)</MenuItem>
|
||||||
|
<MenuItem value={2}>Profile 2 (TLK110)</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -197,4 +210,4 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WiFiSettingsForm;
|
export default NetworkSettingsForm;
|
||||||
48
interface/src/network/NetworkStatus.ts
Normal file
48
interface/src/network/NetworkStatus.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { Theme } from '@material-ui/core';
|
||||||
|
import { NetworkStatus, NetworkConnectionStatus } from './types';
|
||||||
|
|
||||||
|
export const isConnected = ({ status }: NetworkStatus) => {
|
||||||
|
return ((status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED) || (status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isWiFi = ({ status }: NetworkStatus) => (status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED)
|
||||||
|
|
||||||
|
export const networkStatusHighlight = ({ status }: NetworkStatus, theme: Theme) => {
|
||||||
|
switch (status) {
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_IDLE:
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED:
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD:
|
||||||
|
return theme.palette.info.main;
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECTED:
|
||||||
|
case NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED:
|
||||||
|
return theme.palette.success.main;
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECT_FAILED:
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECTION_LOST:
|
||||||
|
return theme.palette.error.main;
|
||||||
|
default:
|
||||||
|
return theme.palette.warning.main;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const networkStatus = ({ status }: NetworkStatus) => {
|
||||||
|
switch (status) {
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD:
|
||||||
|
return "Inactive";
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_IDLE:
|
||||||
|
return "Idle";
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_NO_SSID_AVAIL:
|
||||||
|
return "No SSID Available";
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECTED:
|
||||||
|
return "Connected (WiFi)";
|
||||||
|
case NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED:
|
||||||
|
return "Connected (Ethernet)";
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECT_FAILED:
|
||||||
|
return "Connection Failed";
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECTION_LOST:
|
||||||
|
return "Connection Lost";
|
||||||
|
case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED:
|
||||||
|
return "Disconnected";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
29
interface/src/network/NetworkStatusController.tsx
Normal file
29
interface/src/network/NetworkStatusController.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import {restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
|
||||||
|
import NetworkStatusForm from './NetworkStatusForm';
|
||||||
|
import { NETWORK_STATUS_ENDPOINT } from '../api';
|
||||||
|
import { NetworkStatus } from './types';
|
||||||
|
|
||||||
|
type NetworkStatusControllerProps = RestControllerProps<NetworkStatus>;
|
||||||
|
|
||||||
|
class NetworkStatusController extends Component<NetworkStatusControllerProps> {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<SectionContent title="Network Status">
|
||||||
|
<RestFormLoader
|
||||||
|
{...this.props}
|
||||||
|
render={formProps => <NetworkStatusForm {...formProps} />}
|
||||||
|
/>
|
||||||
|
</SectionContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default restController(NETWORK_STATUS_ENDPOINT, NetworkStatusController);
|
||||||
@@ -11,14 +11,14 @@ import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
|||||||
import RefreshIcon from '@material-ui/icons/Refresh';
|
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||||
|
|
||||||
import { RestFormProps, FormActions, FormButton, HighlightAvatar } from '../components';
|
import { RestFormProps, FormActions, FormButton, HighlightAvatar } from '../components';
|
||||||
import { wifiStatus, wifiStatusHighlight, isConnected } from './WiFiStatus';
|
import { networkStatus, networkStatusHighlight, isConnected, isWiFi } from './NetworkStatus';
|
||||||
import { WiFiStatus } from './types';
|
import { NetworkStatus } from './types';
|
||||||
|
|
||||||
type WiFiStatusFormProps = RestFormProps<WiFiStatus> & WithTheme;
|
type NetworkStatusFormProps = RestFormProps<NetworkStatus> & WithTheme;
|
||||||
|
|
||||||
class WiFiStatusForm extends Component<WiFiStatusFormProps> {
|
class NetworkStatusForm extends Component<NetworkStatusFormProps> {
|
||||||
|
|
||||||
dnsServers(status: WiFiStatus) {
|
dnsServers(status: NetworkStatus) {
|
||||||
if (!status.dns_ip_1) {
|
if (!status.dns_ip_1) {
|
||||||
return "none";
|
return "none";
|
||||||
}
|
}
|
||||||
@@ -31,15 +31,15 @@ class WiFiStatusForm extends Component<WiFiStatusFormProps> {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<HighlightAvatar color={wifiStatusHighlight(data, theme)}>
|
<HighlightAvatar color={networkStatusHighlight(data, theme)}>
|
||||||
<WifiIcon />
|
<WifiIcon />
|
||||||
</HighlightAvatar>
|
</HighlightAvatar>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText primary="Status" secondary={wifiStatus(data)} />
|
<ListItemText primary="Status" secondary={networkStatus(data)} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
{
|
{
|
||||||
isConnected(data) &&
|
isWiFi(data) &&
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
@@ -50,6 +50,10 @@ class WiFiStatusForm extends Component<WiFiStatusFormProps> {
|
|||||||
<ListItemText primary="SSID" secondary={data.ssid} />
|
<ListItemText primary="SSID" secondary={data.ssid} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
{ isConnected(data) &&
|
||||||
|
<Fragment>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar>IP</Avatar>
|
<Avatar>IP</Avatar>
|
||||||
@@ -114,4 +118,4 @@ class WiFiStatusForm extends Component<WiFiStatusFormProps> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(WiFiStatusForm);
|
export default withTheme(NetworkStatusForm);
|
||||||
@@ -8,7 +8,7 @@ import LockIcon from '@material-ui/icons/Lock';
|
|||||||
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
||||||
|
|
||||||
import { isNetworkOpen, networkSecurityMode } from './WiFiSecurityModes';
|
import { isNetworkOpen, networkSecurityMode } from './WiFiSecurityModes';
|
||||||
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
import { NetworkConnectionContext } from './NetworkConnectionContext';
|
||||||
import { WiFiNetwork, WiFiNetworkList } from './types';
|
import { WiFiNetwork, WiFiNetworkList } from './types';
|
||||||
|
|
||||||
interface WiFiNetworkSelectorProps {
|
interface WiFiNetworkSelectorProps {
|
||||||
@@ -17,8 +17,8 @@ interface WiFiNetworkSelectorProps {
|
|||||||
|
|
||||||
class WiFiNetworkSelector extends Component<WiFiNetworkSelectorProps> {
|
class WiFiNetworkSelector extends Component<WiFiNetworkSelectorProps> {
|
||||||
|
|
||||||
static contextType = WiFiConnectionContext;
|
static contextType = NetworkConnectionContext;
|
||||||
context!: React.ContextType<typeof WiFiConnectionContext>;
|
context!: React.ContextType<typeof NetworkConnectionContext>;
|
||||||
|
|
||||||
renderNetwork = (network: WiFiNetwork) => {
|
renderNetwork = (network: WiFiNetwork) => {
|
||||||
return (
|
return (
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
export enum WiFiConnectionStatus {
|
export enum NetworkConnectionStatus {
|
||||||
WIFI_STATUS_IDLE = 0,
|
WIFI_STATUS_IDLE = 0,
|
||||||
WIFI_STATUS_NO_SSID_AVAIL = 1,
|
WIFI_STATUS_NO_SSID_AVAIL = 1,
|
||||||
WIFI_STATUS_CONNECTED = 3,
|
WIFI_STATUS_CONNECTED = 3,
|
||||||
WIFI_STATUS_CONNECT_FAILED = 4,
|
WIFI_STATUS_CONNECT_FAILED = 4,
|
||||||
WIFI_STATUS_CONNECTION_LOST = 5,
|
WIFI_STATUS_CONNECTION_LOST = 5,
|
||||||
WIFI_STATUS_DISCONNECTED = 6,
|
WIFI_STATUS_DISCONNECTED = 6,
|
||||||
|
ETHERNET_STATUS_CONNECTED = 10,
|
||||||
WIFI_STATUS_NO_SHIELD = 255
|
WIFI_STATUS_NO_SHIELD = 255
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,8 +18,8 @@ export enum WiFiEncryptionType {
|
|||||||
WIFI_AUTH_WPA2_ENTERPRISE = 5
|
WIFI_AUTH_WPA2_ENTERPRISE = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WiFiStatus {
|
export interface NetworkStatus {
|
||||||
status: WiFiConnectionStatus;
|
status: NetworkConnectionStatus;
|
||||||
local_ip: string;
|
local_ip: string;
|
||||||
mac_address: string;
|
mac_address: string;
|
||||||
rssi: number;
|
rssi: number;
|
||||||
@@ -31,10 +32,11 @@ export interface WiFiStatus {
|
|||||||
dns_ip_2: string;
|
dns_ip_2: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WiFiSettings {
|
export interface NetworkSettings {
|
||||||
ssid: string;
|
ssid: string;
|
||||||
password: string;
|
password: string;
|
||||||
hostname: string;
|
hostname: string;
|
||||||
|
ethernet_profile: number;
|
||||||
static_ip_config: boolean;
|
static_ip_config: boolean;
|
||||||
local_ip?: string;
|
local_ip?: string;
|
||||||
gateway_ip?: string;
|
gateway_ip?: string;
|
||||||
@@ -6,14 +6,11 @@ import { List, ListItem, ListItemAvatar, ListItemText } from '@material-ui/core'
|
|||||||
import DevicesIcon from '@material-ui/icons/Devices';
|
import DevicesIcon from '@material-ui/icons/Devices';
|
||||||
import MemoryIcon from '@material-ui/icons/Memory';
|
import MemoryIcon from '@material-ui/icons/Memory';
|
||||||
import ShowChartIcon from '@material-ui/icons/ShowChart';
|
import ShowChartIcon from '@material-ui/icons/ShowChart';
|
||||||
import SdStorageIcon from '@material-ui/icons/SdStorage';
|
|
||||||
import FolderIcon from '@material-ui/icons/Folder';
|
import FolderIcon from '@material-ui/icons/Folder';
|
||||||
import DataUsageIcon from '@material-ui/icons/DataUsage';
|
|
||||||
import AppsIcon from '@material-ui/icons/Apps';
|
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 TimerIcon from "@material-ui/icons/Timer";
|
||||||
|
|
||||||
import { redirectingAuthorizedFetch, AuthenticatedContextProps, withAuthenticatedContext } from '../authentication';
|
import { redirectingAuthorizedFetch, AuthenticatedContextProps, withAuthenticatedContext } from '../authentication';
|
||||||
@@ -96,24 +93,6 @@ class SystemStatusForm extends Component<SystemStatusFormProps, SystemStatusForm
|
|||||||
</Fragment>)
|
</Fragment>)
|
||||||
}
|
}
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
<ListItem >
|
|
||||||
<ListItemAvatar>
|
|
||||||
<Avatar>
|
|
||||||
<DataUsageIcon />
|
|
||||||
</Avatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText primary="Sketch (Size / Free)" secondary={formatNumber(data.sketch_size) + ' / ' + formatNumber(data.free_sketch_space) + ' bytes'} />
|
|
||||||
</ListItem>
|
|
||||||
<Divider variant="inset" component="li" />
|
|
||||||
<ListItem >
|
|
||||||
<ListItemAvatar>
|
|
||||||
<Avatar>
|
|
||||||
<SdStorageIcon />
|
|
||||||
</Avatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText primary="Flash Chip (Size / Speed)" secondary={formatNumber(data.flash_chip_size) + ' bytes / ' + (data.flash_chip_speed / 1000000).toFixed(0) + ' MHz'} />
|
|
||||||
</ListItem>
|
|
||||||
<Divider variant="inset" component="li" />
|
|
||||||
<ListItem >
|
<ListItem >
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar>
|
<Avatar>
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ interface ESPSystemStatus {
|
|||||||
max_alloc_heap: number;
|
max_alloc_heap: number;
|
||||||
cpu_freq_mhz: number;
|
cpu_freq_mhz: number;
|
||||||
free_heap: number;
|
free_heap: number;
|
||||||
sketch_size: number;
|
|
||||||
free_sketch_space: number;
|
|
||||||
sdk_version: string;
|
sdk_version: string;
|
||||||
flash_chip_size: number;
|
flash_chip_size: number;
|
||||||
flash_chip_speed: number;
|
flash_chip_speed: number;
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
import { Redirect, Switch, RouteComponentProps } from 'react-router-dom'
|
|
||||||
|
|
||||||
import { Tabs, Tab } from '@material-ui/core';
|
|
||||||
|
|
||||||
import { withAuthenticatedContext, AuthenticatedContextProps, AuthenticatedRoute } from '../authentication';
|
|
||||||
import { MenuAppBar } from '../components';
|
|
||||||
|
|
||||||
import WiFiStatusController from './WiFiStatusController';
|
|
||||||
import WiFiSettingsController from './WiFiSettingsController';
|
|
||||||
import WiFiNetworkScanner from './WiFiNetworkScanner';
|
|
||||||
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
|
||||||
import { WiFiNetwork } from './types';
|
|
||||||
|
|
||||||
type WiFiConnectionProps = AuthenticatedContextProps & RouteComponentProps;
|
|
||||||
|
|
||||||
class WiFiConnection extends Component<WiFiConnectionProps, WiFiConnectionContext> {
|
|
||||||
|
|
||||||
constructor(props: WiFiConnectionProps) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
selectNetwork: this.selectNetwork,
|
|
||||||
deselectNetwork: this.deselectNetwork
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
selectNetwork = (network: WiFiNetwork) => {
|
|
||||||
this.setState({ selectedNetwork: network });
|
|
||||||
this.props.history.push('/wifi/settings');
|
|
||||||
}
|
|
||||||
|
|
||||||
deselectNetwork = () => {
|
|
||||||
this.setState({ selectedNetwork: undefined });
|
|
||||||
}
|
|
||||||
|
|
||||||
handleTabChange = (event: React.ChangeEvent<{}>, path: string) => {
|
|
||||||
this.props.history.push(path);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { authenticatedContext } = this.props;
|
|
||||||
return (
|
|
||||||
<WiFiConnectionContext.Provider value={this.state}>
|
|
||||||
<MenuAppBar sectionTitle="WiFi Connection">
|
|
||||||
<Tabs value={this.props.match.url} onChange={this.handleTabChange} variant="fullWidth">
|
|
||||||
<Tab value="/wifi/status" label="WiFi Status" />
|
|
||||||
<Tab value="/wifi/scan" label="Scan Networks" disabled={!authenticatedContext.me.admin} />
|
|
||||||
<Tab value="/wifi/settings" label="WiFi Settings" disabled={!authenticatedContext.me.admin} />
|
|
||||||
</Tabs>
|
|
||||||
<Switch>
|
|
||||||
<AuthenticatedRoute exact path="/wifi/status" component={WiFiStatusController} />
|
|
||||||
<AuthenticatedRoute exact path="/wifi/scan" component={WiFiNetworkScanner} />
|
|
||||||
<AuthenticatedRoute exact path="/wifi/settings" component={WiFiSettingsController} />
|
|
||||||
<Redirect to="/wifi/status" />
|
|
||||||
</Switch>
|
|
||||||
</MenuAppBar>
|
|
||||||
</WiFiConnectionContext.Provider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withAuthenticatedContext(WiFiConnection);
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { WiFiNetwork } from './types';
|
|
||||||
|
|
||||||
export interface WiFiConnectionContext {
|
|
||||||
selectedNetwork?: WiFiNetwork;
|
|
||||||
selectNetwork: (network: WiFiNetwork) => void;
|
|
||||||
deselectNetwork: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const WiFiConnectionContextDefaultValue = {} as WiFiConnectionContext
|
|
||||||
export const WiFiConnectionContext = React.createContext(
|
|
||||||
WiFiConnectionContextDefaultValue
|
|
||||||
);
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import { restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
|
|
||||||
import WiFiSettingsForm from './WiFiSettingsForm';
|
|
||||||
import { WIFI_SETTINGS_ENDPOINT } from '../api';
|
|
||||||
import { WiFiSettings } from './types';
|
|
||||||
|
|
||||||
type WiFiSettingsControllerProps = RestControllerProps<WiFiSettings>;
|
|
||||||
|
|
||||||
class WiFiSettingsController extends Component<WiFiSettingsControllerProps> {
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.props.loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<SectionContent title="WiFi Settings">
|
|
||||||
<RestFormLoader
|
|
||||||
{...this.props}
|
|
||||||
render={formProps => <WiFiSettingsForm {...formProps} />}
|
|
||||||
/>
|
|
||||||
</SectionContent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default restController(WIFI_SETTINGS_ENDPOINT, WiFiSettingsController);
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { Theme } from '@material-ui/core';
|
|
||||||
import { WiFiStatus, WiFiConnectionStatus } from './types';
|
|
||||||
|
|
||||||
export const isConnected = ({ status }: WiFiStatus) => status === WiFiConnectionStatus.WIFI_STATUS_CONNECTED;
|
|
||||||
|
|
||||||
export const wifiStatusHighlight = ({ status }: WiFiStatus, theme: Theme) => {
|
|
||||||
switch (status) {
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_IDLE:
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_DISCONNECTED:
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_NO_SHIELD:
|
|
||||||
return theme.palette.info.main;
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_CONNECTED:
|
|
||||||
return theme.palette.success.main;
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_CONNECT_FAILED:
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_CONNECTION_LOST:
|
|
||||||
return theme.palette.error.main;
|
|
||||||
default:
|
|
||||||
return theme.palette.warning.main;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const wifiStatus = ({ status }: WiFiStatus) => {
|
|
||||||
switch (status) {
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_NO_SHIELD:
|
|
||||||
return "Inactive";
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_IDLE:
|
|
||||||
return "Idle";
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_NO_SSID_AVAIL:
|
|
||||||
return "No SSID Available";
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_CONNECTED:
|
|
||||||
return "Connected";
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_CONNECT_FAILED:
|
|
||||||
return "Connection Failed";
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_CONNECTION_LOST:
|
|
||||||
return "Connection Lost";
|
|
||||||
case WiFiConnectionStatus.WIFI_STATUS_DISCONNECTED:
|
|
||||||
return "Disconnected";
|
|
||||||
default:
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import {restController, RestControllerProps, RestFormLoader, SectionContent } from '../components';
|
|
||||||
import WiFiStatusForm from './WiFiStatusForm';
|
|
||||||
import { WIFI_STATUS_ENDPOINT } from '../api';
|
|
||||||
import { WiFiStatus } from './types';
|
|
||||||
|
|
||||||
type WiFiStatusControllerProps = RestControllerProps<WiFiStatus>;
|
|
||||||
|
|
||||||
class WiFiStatusController extends Component<WiFiStatusControllerProps> {
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.props.loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<SectionContent title="WiFi Status">
|
|
||||||
<RestFormLoader
|
|
||||||
{...this.props}
|
|
||||||
render={formProps => <WiFiStatusForm {...formProps} />}
|
|
||||||
/>
|
|
||||||
</SectionContent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default restController(WIFI_STATUS_ENDPOINT, WiFiStatusController);
|
|
||||||
@@ -20,6 +20,10 @@ void APSettingsService::reconfigureAP() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void APSettingsService::loop() {
|
void APSettingsService::loop() {
|
||||||
|
// if we have an ETH connection, quit
|
||||||
|
if (ETH.linkUp()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
unsigned long currentMillis = uuid::get_uptime();
|
unsigned long currentMillis = uuid::get_uptime();
|
||||||
unsigned long manageElapsed = (uint32_t)(currentMillis - _lastManaged);
|
unsigned long manageElapsed = (uint32_t)(currentMillis - _lastManaged);
|
||||||
if (manageElapsed >= MANAGE_NETWORK_DELAY) {
|
if (manageElapsed >= MANAGE_NETWORK_DELAY) {
|
||||||
@@ -42,13 +46,13 @@ void APSettingsService::manageAP() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void APSettingsService::startAP() {
|
void APSettingsService::startAP() {
|
||||||
// Serial.println(F("Starting software access point"));
|
Serial.println(F("Starting software access point"));
|
||||||
WiFi.softAPConfig(_state.localIP, _state.gatewayIP, _state.subnetMask);
|
WiFi.softAPConfig(_state.localIP, _state.gatewayIP, _state.subnetMask);
|
||||||
WiFi.softAP(_state.ssid.c_str(), _state.password.c_str());
|
WiFi.softAP(_state.ssid.c_str(), _state.password.c_str());
|
||||||
if (!_dnsServer) {
|
if (!_dnsServer) {
|
||||||
IPAddress apIp = WiFi.softAPIP();
|
IPAddress apIp = WiFi.softAPIP();
|
||||||
// Serial.print(F("Starting captive portal on "));
|
Serial.print(F("Starting captive portal on "));
|
||||||
// Serial.println(apIp);
|
Serial.println(apIp);
|
||||||
_dnsServer = new DNSServer;
|
_dnsServer = new DNSServer;
|
||||||
_dnsServer->start(DNS_PORT, "*", apIp);
|
_dnsServer->start(DNS_PORT, "*", apIp);
|
||||||
}
|
}
|
||||||
@@ -56,12 +60,12 @@ void APSettingsService::startAP() {
|
|||||||
|
|
||||||
void APSettingsService::stopAP() {
|
void APSettingsService::stopAP() {
|
||||||
if (_dnsServer) {
|
if (_dnsServer) {
|
||||||
// Serial.println(F("Stopping captive portal"));
|
Serial.println(F("Stopping captive portal"));
|
||||||
_dnsServer->stop();
|
_dnsServer->stop();
|
||||||
delete _dnsServer;
|
delete _dnsServer;
|
||||||
_dnsServer = nullptr;
|
_dnsServer = nullptr;
|
||||||
}
|
}
|
||||||
// Serial.println(F("Stopping software access point"));
|
Serial.println(F("Stopping software access point"));
|
||||||
WiFi.softAPdisconnect(true);
|
WiFi.softAPdisconnect(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,10 @@
|
|||||||
|
|
||||||
#include <DNSServer.h>
|
#include <DNSServer.h>
|
||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
#include <uuid/common.h>
|
|
||||||
|
|
||||||
|
#include <ETH.h>
|
||||||
|
|
||||||
|
#include <uuid/common.h>
|
||||||
|
|
||||||
#define MANAGE_NETWORK_DELAY 10000
|
#define MANAGE_NETWORK_DELAY 10000
|
||||||
|
|
||||||
@@ -111,7 +113,7 @@ class APSettingsService : public StatefulService<APSettings> {
|
|||||||
// for the captive portal
|
// for the captive portal
|
||||||
DNSServer * _dnsServer;
|
DNSServer * _dnsServer;
|
||||||
|
|
||||||
// for the mangement delay loop
|
// for the management delay loop
|
||||||
volatile unsigned long _lastManaged;
|
volatile unsigned long _lastManaged;
|
||||||
volatile boolean _reconfigureAp;
|
volatile boolean _reconfigureAp;
|
||||||
|
|
||||||
|
|||||||
@@ -3,35 +3,19 @@
|
|||||||
ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs)
|
ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs)
|
||||||
: _featureService(server)
|
: _featureService(server)
|
||||||
, _securitySettingsService(server, fs)
|
, _securitySettingsService(server, fs)
|
||||||
, _wifiSettingsService(server, fs, &_securitySettingsService)
|
, _networkSettingsService(server, fs, &_securitySettingsService)
|
||||||
, _wifiScanner(server, &_securitySettingsService)
|
, _wifiScanner(server, &_securitySettingsService)
|
||||||
, _wifiStatus(server, &_securitySettingsService)
|
, _networkStatus(server, &_securitySettingsService)
|
||||||
, _apSettingsService(server, fs, &_securitySettingsService)
|
, _apSettingsService(server, fs, &_securitySettingsService)
|
||||||
, _apStatus(server, &_securitySettingsService, &_apSettingsService)
|
, _apStatus(server, &_securitySettingsService, &_apSettingsService)
|
||||||
,
|
, _ntpSettingsService(server, fs, &_securitySettingsService)
|
||||||
#if FT_ENABLED(FT_NTP)
|
|
||||||
_ntpSettingsService(server, fs, &_securitySettingsService)
|
|
||||||
, _ntpStatus(server, &_securitySettingsService)
|
, _ntpStatus(server, &_securitySettingsService)
|
||||||
,
|
, _otaSettingsService(server, fs, &_securitySettingsService)
|
||||||
#endif
|
, _uploadFirmwareService(server, &_securitySettingsService)
|
||||||
#if FT_ENABLED(FT_OTA)
|
, _mqttSettingsService(server, fs, &_securitySettingsService)
|
||||||
_otaSettingsService(server, fs, &_securitySettingsService)
|
|
||||||
,
|
|
||||||
#endif
|
|
||||||
#if FT_ENABLED(FT_UPLOAD_FIRMWARE)
|
|
||||||
_uploadFirmwareService(server, &_securitySettingsService)
|
|
||||||
,
|
|
||||||
#endif
|
|
||||||
#if FT_ENABLED(FT_MQTT)
|
|
||||||
_mqttSettingsService(server, fs, &_securitySettingsService)
|
|
||||||
, _mqttStatus(server, &_mqttSettingsService, &_securitySettingsService)
|
, _mqttStatus(server, &_mqttSettingsService, &_securitySettingsService)
|
||||||
,
|
, _authenticationService(server, &_securitySettingsService)
|
||||||
#endif
|
, _restartService(server, &_securitySettingsService)
|
||||||
#if FT_ENABLED(FT_SECURITY)
|
|
||||||
_authenticationService(server, &_securitySettingsService)
|
|
||||||
,
|
|
||||||
#endif
|
|
||||||
_restartService(server, &_securitySettingsService)
|
|
||||||
, _factoryResetService(server, fs, &_securitySettingsService)
|
, _factoryResetService(server, fs, &_securitySettingsService)
|
||||||
, _systemStatus(server, &_securitySettingsService) {
|
, _systemStatus(server, &_securitySettingsService) {
|
||||||
#ifdef PROGMEM_WWW
|
#ifdef PROGMEM_WWW
|
||||||
@@ -91,29 +75,17 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266React::begin() {
|
void ESP8266React::begin() {
|
||||||
_wifiSettingsService.begin();
|
_networkSettingsService.begin();
|
||||||
_apSettingsService.begin();
|
_apSettingsService.begin();
|
||||||
#if FT_ENABLED(FT_NTP)
|
|
||||||
_ntpSettingsService.begin();
|
_ntpSettingsService.begin();
|
||||||
#endif
|
|
||||||
#if FT_ENABLED(FT_OTA)
|
|
||||||
_otaSettingsService.begin();
|
_otaSettingsService.begin();
|
||||||
#endif
|
|
||||||
#if FT_ENABLED(FT_MQTT)
|
|
||||||
_mqttSettingsService.begin();
|
_mqttSettingsService.begin();
|
||||||
#endif
|
|
||||||
#if FT_ENABLED(FT_SECURITY)
|
|
||||||
_securitySettingsService.begin();
|
_securitySettingsService.begin();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266React::loop() {
|
void ESP8266React::loop() {
|
||||||
_wifiSettingsService.loop();
|
_networkSettingsService.loop();
|
||||||
_apSettingsService.loop();
|
_apSettingsService.loop();
|
||||||
#if FT_ENABLED(FT_OTA)
|
|
||||||
_otaSettingsService.loop();
|
_otaSettingsService.loop();
|
||||||
#endif
|
|
||||||
#if FT_ENABLED(FT_MQTT)
|
|
||||||
_mqttSettingsService.loop();
|
_mqttSettingsService.loop();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,9 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
#include <AsyncTCP.h>
|
#include <AsyncTCP.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#elif defined(ESP8266)
|
#include <ETH.h>
|
||||||
#include <ESP8266WiFi.h>
|
|
||||||
#include <ESPAsyncTCP.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <FeaturesService.h>
|
#include <FeaturesService.h>
|
||||||
#include <APSettingsService.h>
|
#include <APSettingsService.h>
|
||||||
@@ -26,8 +22,8 @@
|
|||||||
#include <SecuritySettingsService.h>
|
#include <SecuritySettingsService.h>
|
||||||
#include <SystemStatus.h>
|
#include <SystemStatus.h>
|
||||||
#include <WiFiScanner.h>
|
#include <WiFiScanner.h>
|
||||||
#include <WiFiSettingsService.h>
|
#include <NetworkSettingsService.h>
|
||||||
#include <WiFiStatus.h>
|
#include <NetworkStatus.h>
|
||||||
|
|
||||||
#ifdef PROGMEM_WWW
|
#ifdef PROGMEM_WWW
|
||||||
#include <WWWData.h>
|
#include <WWWData.h>
|
||||||
@@ -44,33 +40,26 @@ class ESP8266React {
|
|||||||
return &_securitySettingsService;
|
return &_securitySettingsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FT_ENABLED(FT_SECURITY)
|
|
||||||
StatefulService<SecuritySettings> * getSecuritySettingsService() {
|
StatefulService<SecuritySettings> * getSecuritySettingsService() {
|
||||||
return &_securitySettingsService;
|
return &_securitySettingsService;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
StatefulService<WiFiSettings> * getWiFiSettingsService() {
|
StatefulService<NetworkSettings> * getNetworkSettingsService() {
|
||||||
return &_wifiSettingsService;
|
return &_networkSettingsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
StatefulService<APSettings> * getAPSettingsService() {
|
StatefulService<APSettings> * getAPSettingsService() {
|
||||||
return &_apSettingsService;
|
return &_apSettingsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FT_ENABLED(FT_NTP)
|
|
||||||
StatefulService<NTPSettings> * getNTPSettingsService() {
|
StatefulService<NTPSettings> * getNTPSettingsService() {
|
||||||
return &_ntpSettingsService;
|
return &_ntpSettingsService;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if FT_ENABLED(FT_OTA)
|
|
||||||
StatefulService<OTASettings> * getOTASettingsService() {
|
StatefulService<OTASettings> * getOTASettingsService() {
|
||||||
return &_otaSettingsService;
|
return &_otaSettingsService;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if FT_ENABLED(FT_MQTT)
|
|
||||||
StatefulService<MqttSettings> * getMqttSettingsService() {
|
StatefulService<MqttSettings> * getMqttSettingsService() {
|
||||||
return &_mqttSettingsService;
|
return &_mqttSettingsService;
|
||||||
}
|
}
|
||||||
@@ -78,7 +67,6 @@ class ESP8266React {
|
|||||||
AsyncMqttClient * getMqttClient() {
|
AsyncMqttClient * getMqttClient() {
|
||||||
return _mqttSettingsService.getMqttClient();
|
return _mqttSettingsService.getMqttClient();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void factoryReset() {
|
void factoryReset() {
|
||||||
_factoryResetService.factoryReset();
|
_factoryResetService.factoryReset();
|
||||||
@@ -87,31 +75,21 @@ class ESP8266React {
|
|||||||
private:
|
private:
|
||||||
FeaturesService _featureService;
|
FeaturesService _featureService;
|
||||||
SecuritySettingsService _securitySettingsService;
|
SecuritySettingsService _securitySettingsService;
|
||||||
WiFiSettingsService _wifiSettingsService;
|
NetworkSettingsService _networkSettingsService;
|
||||||
WiFiScanner _wifiScanner;
|
WiFiScanner _wifiScanner;
|
||||||
WiFiStatus _wifiStatus;
|
NetworkStatus _networkStatus;
|
||||||
APSettingsService _apSettingsService;
|
APSettingsService _apSettingsService;
|
||||||
APStatus _apStatus;
|
APStatus _apStatus;
|
||||||
#if FT_ENABLED(FT_NTP)
|
NTPSettingsService _ntpSettingsService;
|
||||||
NTPSettingsService _ntpSettingsService;
|
NTPStatus _ntpStatus;
|
||||||
NTPStatus _ntpStatus;
|
OTASettingsService _otaSettingsService;
|
||||||
#endif
|
UploadFirmwareService _uploadFirmwareService;
|
||||||
#if FT_ENABLED(FT_OTA)
|
MqttSettingsService _mqttSettingsService;
|
||||||
OTASettingsService _otaSettingsService;
|
MqttStatus _mqttStatus;
|
||||||
#endif
|
AuthenticationService _authenticationService;
|
||||||
#if FT_ENABLED(FT_UPLOAD_FIRMWARE)
|
RestartService _restartService;
|
||||||
UploadFirmwareService _uploadFirmwareService;
|
FactoryResetService _factoryResetService;
|
||||||
#endif
|
SystemStatus _systemStatus;
|
||||||
#if FT_ENABLED(FT_MQTT)
|
|
||||||
MqttSettingsService _mqttSettingsService;
|
|
||||||
MqttStatus _mqttStatus;
|
|
||||||
#endif
|
|
||||||
#if FT_ENABLED(FT_SECURITY)
|
|
||||||
AuthenticationService _authenticationService;
|
|
||||||
#endif
|
|
||||||
RestartService _restartService;
|
|
||||||
FactoryResetService _factoryResetService;
|
|
||||||
SystemStatus _systemStatus;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,13 +40,8 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur
|
|||||||
, _disconnectedAt(0)
|
, _disconnectedAt(0)
|
||||||
, _disconnectReason(AsyncMqttClientDisconnectReason::TCP_DISCONNECTED)
|
, _disconnectReason(AsyncMqttClientDisconnectReason::TCP_DISCONNECTED)
|
||||||
, _mqttClient() {
|
, _mqttClient() {
|
||||||
#ifdef ESP32
|
|
||||||
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
||||||
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
|
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
|
||||||
#elif defined(ESP8266)
|
|
||||||
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
|
|
||||||
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1));
|
|
||||||
#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);
|
||||||
|
|||||||
@@ -140,16 +140,8 @@ class MqttSettingsService : public StatefulService<MqttSettings> {
|
|||||||
// the MQTT client instance
|
// the MQTT client instance
|
||||||
AsyncMqttClient _mqttClient;
|
AsyncMqttClient _mqttClient;
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
#elif defined(ESP8266)
|
|
||||||
WiFiEventHandler _onStationModeDisconnectedHandler;
|
|
||||||
WiFiEventHandler _onStationModeGotIPHandler;
|
|
||||||
void onStationModeGotIP(const WiFiEventStationModeGotIP & event);
|
|
||||||
void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void onMqttConnect(bool sessionPresent);
|
void onMqttConnect(bool sessionPresent);
|
||||||
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
|
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
|
||||||
void configureMqtt();
|
void configureMqtt();
|
||||||
|
|||||||
@@ -3,20 +3,13 @@
|
|||||||
NTPSettingsService::NTPSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
NTPSettingsService::NTPSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||||
: _httpEndpoint(NTPSettings::read, NTPSettings::update, this, server, NTP_SETTINGS_SERVICE_PATH, securityManager)
|
: _httpEndpoint(NTPSettings::read, NTPSettings::update, this, server, NTP_SETTINGS_SERVICE_PATH, securityManager)
|
||||||
, _fsPersistence(NTPSettings::read, NTPSettings::update, this, fs, NTP_SETTINGS_FILE)
|
, _fsPersistence(NTPSettings::read, NTPSettings::update, this, fs, NTP_SETTINGS_FILE)
|
||||||
, _timeHandler(TIME_PATH,
|
, _timeHandler(TIME_PATH, securityManager->wrapCallback(std::bind(&NTPSettingsService::configureTime, this, std::placeholders::_1, std::placeholders::_2), AuthenticationPredicates::IS_ADMIN)) {
|
||||||
securityManager->wrapCallback(std::bind(&NTPSettingsService::configureTime, this, std::placeholders::_1, std::placeholders::_2),
|
|
||||||
AuthenticationPredicates::IS_ADMIN)) {
|
|
||||||
_timeHandler.setMethod(HTTP_POST);
|
_timeHandler.setMethod(HTTP_POST);
|
||||||
_timeHandler.setMaxContentLength(MAX_TIME_SIZE);
|
_timeHandler.setMaxContentLength(MAX_TIME_SIZE);
|
||||||
server->addHandler(&_timeHandler);
|
server->addHandler(&_timeHandler);
|
||||||
#ifdef ESP32
|
|
||||||
WiFi.onEvent(std::bind(&NTPSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2),
|
WiFi.onEvent(std::bind(&NTPSettingsService::WiFiEvent, this, std::placeholders::_1));
|
||||||
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
|
||||||
WiFi.onEvent(std::bind(&NTPSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&NTPSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
|
|
||||||
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(std::bind(&NTPSettingsService::onStationModeGotIP, this, std::placeholders::_1));
|
|
||||||
#endif
|
|
||||||
addUpdateHandler([&](const String & originId) { configureNTP(); }, false);
|
addUpdateHandler([&](const String & originId) { configureNTP(); }, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,43 +18,36 @@ void NTPSettingsService::begin() {
|
|||||||
configureNTP();
|
configureNTP();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESP32
|
// handles both WiFI and Ethernet
|
||||||
void NTPSettingsService::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
void NTPSettingsService::WiFiEvent(WiFiEvent_t event) {
|
||||||
// Serial.println(F("Got IP address, starting NTP Synchronization"));
|
switch (event) {
|
||||||
configureNTP();
|
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||||
}
|
// Serial.println(F("WiFi connection dropped, stopping NTP."));
|
||||||
|
connected_ = false;
|
||||||
|
configureNTP();
|
||||||
|
break;
|
||||||
|
|
||||||
void NTPSettingsService::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
|
case SYSTEM_EVENT_STA_GOT_IP:
|
||||||
// Serial.println(F("WiFi connection dropped, stopping NTP."));
|
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||||
configureNTP();
|
// Serial.println(F("Got IP address, starting NTP Synchronization"));
|
||||||
}
|
connected_ = true;
|
||||||
#elif defined(ESP8266)
|
configureNTP();
|
||||||
void NTPSettingsService::onStationModeGotIP(const WiFiEventStationModeGotIP & event) {
|
break;
|
||||||
// Serial.println(F("Got IP address, starting NTP Synchronization"));
|
|
||||||
configureNTP();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NTPSettingsService::onStationModeDisconnected(const WiFiEventStationModeDisconnected & event) {
|
|
||||||
// Serial.println(F("WiFi connection dropped, stopping NTP."));
|
|
||||||
configureNTP();
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void NTPSettingsService::configureNTP() {
|
void NTPSettingsService::configureNTP() {
|
||||||
if (WiFi.isConnected() && _state.enabled) {
|
if (connected_ && _state.enabled) {
|
||||||
// Serial.println(F("Starting NTP..."));
|
// Serial.println(F("Starting NTP..."));
|
||||||
#ifdef ESP32
|
|
||||||
configTzTime(_state.tzFormat.c_str(), _state.server.c_str());
|
configTzTime(_state.tzFormat.c_str(), _state.server.c_str());
|
||||||
#elif defined(ESP8266)
|
|
||||||
configTime(_state.tzFormat.c_str(), _state.server.c_str());
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
#ifdef ESP32
|
|
||||||
setenv("TZ", _state.tzFormat.c_str(), 1);
|
setenv("TZ", _state.tzFormat.c_str(), 1);
|
||||||
tzset();
|
tzset();
|
||||||
#elif defined(ESP8266)
|
|
||||||
setTZ(_state.tzFormat.c_str());
|
|
||||||
#endif
|
|
||||||
sntp_stop();
|
sntp_stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,8 @@
|
|||||||
#include <FSPersistence.h>
|
#include <FSPersistence.h>
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifdef ESP32
|
|
||||||
#include <lwip/apps/sntp.h>
|
#include <lwip/apps/sntp.h>
|
||||||
#elif defined(ESP8266)
|
#include <ETH.h>
|
||||||
#include <sntp.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FACTORY_NTP_ENABLED
|
#ifndef FACTORY_NTP_ENABLED
|
||||||
#define FACTORY_NTP_ENABLED true
|
#define FACTORY_NTP_ENABLED true
|
||||||
@@ -67,16 +64,8 @@ class NTPSettingsService : public StatefulService<NTPSettings> {
|
|||||||
FSPersistence<NTPSettings> _fsPersistence;
|
FSPersistence<NTPSettings> _fsPersistence;
|
||||||
AsyncCallbackJsonWebHandler _timeHandler;
|
AsyncCallbackJsonWebHandler _timeHandler;
|
||||||
|
|
||||||
#ifdef ESP32
|
bool connected_ = false;
|
||||||
void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
void WiFiEvent(WiFiEvent_t event);
|
||||||
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
WiFiEventHandler _onStationModeDisconnectedHandler;
|
|
||||||
WiFiEventHandler _onStationModeGotIPHandler;
|
|
||||||
|
|
||||||
void onStationModeGotIP(const WiFiEventStationModeGotIP & event);
|
|
||||||
void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
|
|
||||||
#endif
|
|
||||||
void configureNTP();
|
void configureNTP();
|
||||||
void configureTime(AsyncWebServerRequest * request, JsonVariant & json);
|
void configureTime(AsyncWebServerRequest * request, JsonVariant & json);
|
||||||
};
|
};
|
||||||
|
|||||||
90
lib/framework/NetworkSettingsService.cpp
Normal file
90
lib/framework/NetworkSettingsService.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include <NetworkSettingsService.h>
|
||||||
|
|
||||||
|
NetworkSettingsService::NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||||
|
: _httpEndpoint(NetworkSettings::read, NetworkSettings::update, this, server, NETWORK_SETTINGS_SERVICE_PATH, securityManager)
|
||||||
|
, _fsPersistence(NetworkSettings::read, NetworkSettings::update, this, fs, NETWORK_SETTINGS_FILE)
|
||||||
|
, _lastConnectionAttempt(0) {
|
||||||
|
// We want the device to come up in opmode=0 (WIFI_OFF), when erasing the flash this is not the default.
|
||||||
|
// If needed, we save opmode=0 before disabling persistence so the device boots with WiFi disabled in the future.
|
||||||
|
if (WiFi.getMode() != WIFI_OFF) {
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable WiFi config persistance and auto reconnect
|
||||||
|
WiFi.persistent(false);
|
||||||
|
WiFi.setAutoReconnect(false);
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_MODE_MAX);
|
||||||
|
WiFi.mode(WIFI_MODE_NULL);
|
||||||
|
|
||||||
|
WiFi.onEvent(std::bind(&NetworkSettingsService::WiFiEvent, this, std::placeholders::_1));
|
||||||
|
|
||||||
|
addUpdateHandler([&](const String & originId) { reconfigureWiFiConnection(); }, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkSettingsService::begin() {
|
||||||
|
_fsPersistence.readFromFS();
|
||||||
|
reconfigureWiFiConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkSettingsService::reconfigureWiFiConnection() {
|
||||||
|
// reset last connection attempt to force loop to reconnect immediately
|
||||||
|
_lastConnectionAttempt = 0;
|
||||||
|
|
||||||
|
// disconnect and de-configure wifi
|
||||||
|
if (WiFi.disconnect(true)) {
|
||||||
|
_stopping = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkSettingsService::loop() {
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
if (!_lastConnectionAttempt || (uint32_t)(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) {
|
||||||
|
_lastConnectionAttempt = currentMillis;
|
||||||
|
manageSTA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkSettingsService::manageSTA() {
|
||||||
|
// Abort if already connected, or if we have no SSID
|
||||||
|
if (WiFi.isConnected() || _state.ssid.length() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect or reconnect as required
|
||||||
|
if ((WiFi.getMode() & WIFI_STA) == 0) {
|
||||||
|
if (_state.staticIPConfig) {
|
||||||
|
WiFi.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2); // configure for static IP
|
||||||
|
} else {
|
||||||
|
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); // configure for DHCP
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFi.setHostname(_state.hostname.c_str()); // set hostname
|
||||||
|
WiFi.begin(_state.ssid.c_str(), _state.password.c_str()); // attempt to connect to the network
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handles both WiFI and Ethernet
|
||||||
|
void NetworkSettingsService::WiFiEvent(WiFiEvent_t event) {
|
||||||
|
switch (event) {
|
||||||
|
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||||
|
WiFi.disconnect(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSTEM_EVENT_STA_STOP:
|
||||||
|
if (_stopping) {
|
||||||
|
_lastConnectionAttempt = 0;
|
||||||
|
_stopping = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSTEM_EVENT_ETH_START:
|
||||||
|
if (_state.staticIPConfig) {
|
||||||
|
ETH.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2); // configure for static IP
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
#ifndef WiFiSettingsService_h
|
#ifndef NetworkSettingsService_h
|
||||||
#define WiFiSettingsService_h
|
#define NetworkSettingsService_h
|
||||||
|
|
||||||
#include <StatefulService.h>
|
#include <StatefulService.h>
|
||||||
#include <FSPersistence.h>
|
#include <FSPersistence.h>
|
||||||
#include <HttpEndpoint.h>
|
#include <HttpEndpoint.h>
|
||||||
#include <JsonUtils.h>
|
#include <JsonUtils.h>
|
||||||
|
|
||||||
#define WIFI_SETTINGS_FILE "/config/wifiSettings.json"
|
#include <ETH.h>
|
||||||
#define WIFI_SETTINGS_SERVICE_PATH "/rest/wifiSettings"
|
|
||||||
|
#define NETWORK_SETTINGS_FILE "/config/networkSettings.json"
|
||||||
|
#define NETWORK_SETTINGS_SERVICE_PATH "/rest/networkSettings"
|
||||||
#define WIFI_RECONNECTION_DELAY 1000 * 30
|
#define WIFI_RECONNECTION_DELAY 1000 * 30
|
||||||
|
|
||||||
#ifndef FACTORY_WIFI_SSID
|
#ifndef FACTORY_WIFI_SSID
|
||||||
@@ -22,13 +24,14 @@
|
|||||||
#define FACTORY_WIFI_HOSTNAME ""
|
#define FACTORY_WIFI_HOSTNAME ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class WiFiSettings {
|
class NetworkSettings {
|
||||||
public:
|
public:
|
||||||
// core wifi configuration
|
// core wifi configuration
|
||||||
String ssid;
|
String ssid;
|
||||||
String password;
|
String password;
|
||||||
String hostname;
|
String hostname;
|
||||||
bool staticIPConfig;
|
bool staticIPConfig;
|
||||||
|
uint8_t ethernet_profile;
|
||||||
|
|
||||||
// optional configuration for static IP address
|
// optional configuration for static IP address
|
||||||
IPAddress localIP;
|
IPAddress localIP;
|
||||||
@@ -37,12 +40,13 @@ class WiFiSettings {
|
|||||||
IPAddress dnsIP1;
|
IPAddress dnsIP1;
|
||||||
IPAddress dnsIP2;
|
IPAddress dnsIP2;
|
||||||
|
|
||||||
static void read(WiFiSettings & settings, JsonObject & root) {
|
static void read(NetworkSettings & settings, JsonObject & root) {
|
||||||
// connection settings
|
// connection settings
|
||||||
root["ssid"] = settings.ssid;
|
root["ssid"] = settings.ssid;
|
||||||
root["password"] = settings.password;
|
root["password"] = settings.password;
|
||||||
root["hostname"] = settings.hostname;
|
root["hostname"] = settings.hostname;
|
||||||
root["static_ip_config"] = settings.staticIPConfig;
|
root["static_ip_config"] = settings.staticIPConfig;
|
||||||
|
root["ethernet_profile"] = settings.ethernet_profile;
|
||||||
|
|
||||||
// extended settings
|
// extended settings
|
||||||
JsonUtils::writeIP(root, "local_ip", settings.localIP);
|
JsonUtils::writeIP(root, "local_ip", settings.localIP);
|
||||||
@@ -52,11 +56,12 @@ class WiFiSettings {
|
|||||||
JsonUtils::writeIP(root, "dns_ip_2", settings.dnsIP2);
|
JsonUtils::writeIP(root, "dns_ip_2", settings.dnsIP2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static StateUpdateResult update(JsonObject & root, WiFiSettings & settings) {
|
static StateUpdateResult update(JsonObject & root, NetworkSettings & settings) {
|
||||||
settings.ssid = root["ssid"] | FACTORY_WIFI_SSID;
|
settings.ssid = root["ssid"] | FACTORY_WIFI_SSID;
|
||||||
settings.password = root["password"] | FACTORY_WIFI_PASSWORD;
|
settings.password = root["password"] | FACTORY_WIFI_PASSWORD;
|
||||||
settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME;
|
settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME;
|
||||||
settings.staticIPConfig = root["static_ip_config"] | false;
|
settings.staticIPConfig = root["static_ip_config"] | false;
|
||||||
|
settings.ethernet_profile = root["ethernet_profile"] | 0; // no ethernet
|
||||||
|
|
||||||
// extended settings
|
// extended settings
|
||||||
JsonUtils::readIP(root, "local_ip", settings.localIP);
|
JsonUtils::readIP(root, "local_ip", settings.localIP);
|
||||||
@@ -77,33 +82,28 @@ class WiFiSettings {
|
|||||||
if (settings.staticIPConfig && (settings.localIP == INADDR_NONE || settings.gatewayIP == INADDR_NONE || settings.subnetMask == INADDR_NONE)) {
|
if (settings.staticIPConfig && (settings.localIP == INADDR_NONE || settings.gatewayIP == INADDR_NONE || settings.subnetMask == INADDR_NONE)) {
|
||||||
settings.staticIPConfig = false;
|
settings.staticIPConfig = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class WiFiSettingsService : public StatefulService<WiFiSettings> {
|
class NetworkSettingsService : public StatefulService<NetworkSettings> {
|
||||||
public:
|
public:
|
||||||
WiFiSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HttpEndpoint<WiFiSettings> _httpEndpoint;
|
HttpEndpoint<NetworkSettings> _httpEndpoint;
|
||||||
FSPersistence<WiFiSettings> _fsPersistence;
|
FSPersistence<NetworkSettings> _fsPersistence;
|
||||||
unsigned long _lastConnectionAttempt;
|
unsigned long _lastConnectionAttempt;
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
bool _stopping;
|
bool _stopping;
|
||||||
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
void WiFiEvent(WiFiEvent_t event);
|
||||||
void onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info);
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
WiFiEventHandler _onStationModeDisconnectedHandler;
|
|
||||||
void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void reconfigureWiFiConnection();
|
void reconfigureWiFiConnection();
|
||||||
void manageSTA();
|
void manageSTA();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // end WiFiSettingsService_h
|
#endif
|
||||||
57
lib/framework/NetworkStatus.cpp
Normal file
57
lib/framework/NetworkStatus.cpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#include <NetworkStatus.h>
|
||||||
|
|
||||||
|
NetworkStatus::NetworkStatus(AsyncWebServer * server, SecurityManager * securityManager) {
|
||||||
|
server->on(NETWORK_STATUS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&NetworkStatus::networkStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkStatus::networkStatus(AsyncWebServerRequest * request) {
|
||||||
|
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_NETWORK_STATUS_SIZE);
|
||||||
|
JsonObject root = response->getRoot();
|
||||||
|
|
||||||
|
bool ethernet_connected = ETH.linkUp();
|
||||||
|
wl_status_t wifi_status = WiFi.status();
|
||||||
|
|
||||||
|
// see if Ethernet is connected
|
||||||
|
if (ethernet_connected) {
|
||||||
|
root["status"] = 10; // custom code #10 - ETHERNET_STATUS_CONNECTED
|
||||||
|
} else {
|
||||||
|
root["status"] = (uint8_t)wifi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for Wifi
|
||||||
|
if (wifi_status == WL_CONNECTED) {
|
||||||
|
root["local_ip"] = WiFi.localIP().toString();
|
||||||
|
root["mac_address"] = WiFi.macAddress();
|
||||||
|
root["rssi"] = WiFi.RSSI();
|
||||||
|
root["ssid"] = WiFi.SSID();
|
||||||
|
root["bssid"] = WiFi.BSSIDstr();
|
||||||
|
root["channel"] = WiFi.channel();
|
||||||
|
root["subnet_mask"] = WiFi.subnetMask().toString();
|
||||||
|
root["gateway_ip"] = WiFi.gatewayIP().toString();
|
||||||
|
IPAddress dnsIP1 = WiFi.dnsIP(0);
|
||||||
|
IPAddress dnsIP2 = WiFi.dnsIP(1);
|
||||||
|
if (dnsIP1 != INADDR_NONE) {
|
||||||
|
root["dns_ip_1"] = dnsIP1.toString();
|
||||||
|
}
|
||||||
|
if (dnsIP2 != INADDR_NONE) {
|
||||||
|
root["dns_ip_2"] = dnsIP2.toString();
|
||||||
|
}
|
||||||
|
} else if (ETH.linkUp()) {
|
||||||
|
// Ethernet
|
||||||
|
root["local_ip"] = ETH.localIP().toString();
|
||||||
|
root["mac_address"] = ETH.macAddress();
|
||||||
|
root["subnet_mask"] = ETH.subnetMask().toString();
|
||||||
|
root["gateway_ip"] = ETH.gatewayIP().toString();
|
||||||
|
IPAddress dnsIP1 = ETH.dnsIP(0);
|
||||||
|
IPAddress dnsIP2 = ETH.dnsIP(1);
|
||||||
|
if (dnsIP1 != INADDR_NONE) {
|
||||||
|
root["dns_ip_1"] = dnsIP1.toString();
|
||||||
|
}
|
||||||
|
if (dnsIP2 != INADDR_NONE) {
|
||||||
|
root["dns_ip_2"] = dnsIP2.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response->setLength();
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
25
lib/framework/NetworkStatus.h
Normal file
25
lib/framework/NetworkStatus.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef NetworkStatus_h
|
||||||
|
#define NetworkStatus_h
|
||||||
|
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <ETH.h>
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <AsyncJson.h>
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <IPAddress.h>
|
||||||
|
#include <SecurityManager.h>
|
||||||
|
|
||||||
|
#define MAX_NETWORK_STATUS_SIZE 1024
|
||||||
|
#define NETWORK_STATUS_SERVICE_PATH "/rest/networkStatus"
|
||||||
|
|
||||||
|
class NetworkStatus {
|
||||||
|
public:
|
||||||
|
NetworkStatus(AsyncWebServer * server, SecurityManager * securityManager);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void networkStatus(AsyncWebServerRequest * request);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,44 +1,25 @@
|
|||||||
#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, securityManager->wrapRequest(std::bind(&SystemStatus::systemStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||||
HTTP_GET,
|
|
||||||
securityManager->wrapRequest(std::bind(&SystemStatus::systemStatus, this, std::placeholders::_1), 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
|
root["esp_platform"] = "esp32";
|
||||||
root["esp_platform"] = "esp32";
|
root["max_alloc_heap"] = ESP.getMaxAllocHeap();
|
||||||
root["max_alloc_heap"] = ESP.getMaxAllocHeap();
|
root["psram_size"] = ESP.getPsramSize();
|
||||||
root["psram_size"] = ESP.getPsramSize();
|
root["free_psram"] = ESP.getFreePsram();
|
||||||
root["free_psram"] = ESP.getFreePsram();
|
root["cpu_freq_mhz"] = ESP.getCpuFreqMHz();
|
||||||
#elif defined(ESP8266)
|
root["free_heap"] = ESP.getFreeHeap();
|
||||||
root["esp_platform"] = "esp8266";
|
root["sdk_version"] = ESP.getSdkVersion();
|
||||||
root["max_alloc_heap"] = ESP.getMaxFreeBlockSize();
|
root["flash_chip_size"] = ESP.getFlashChipSize();
|
||||||
root["heap_fragmentation"] = ESP.getHeapFragmentation();
|
root["flash_chip_speed"] = ESP.getFlashChipSpeed();
|
||||||
#endif
|
|
||||||
root["cpu_freq_mhz"] = ESP.getCpuFreqMHz();
|
|
||||||
root["free_heap"] = ESP.getFreeHeap();
|
|
||||||
root["sketch_size"] = ESP.getSketchSize();
|
|
||||||
root["free_sketch_space"] = ESP.getFreeSketchSpace();
|
|
||||||
root["sdk_version"] = ESP.getSdkVersion();
|
|
||||||
root["flash_chip_size"] = ESP.getFlashChipSize();
|
|
||||||
root["flash_chip_speed"] = ESP.getFlashChipSpeed();
|
|
||||||
|
|
||||||
// ESP8266 and ESP32 do not have feature parity in FS.h which currently makes that difficult.
|
|
||||||
#ifdef ESP32
|
|
||||||
root["fs_total"] = SPIFFS.totalBytes();
|
root["fs_total"] = SPIFFS.totalBytes();
|
||||||
root["fs_used"] = SPIFFS.usedBytes();
|
root["fs_used"] = SPIFFS.usedBytes();
|
||||||
#elif defined(ESP8266)
|
root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
||||||
FSInfo fs_info;
|
|
||||||
LittleFS.info(fs_info); // // proddy added
|
|
||||||
root["fs_total"] = fs_info.totalBytes;
|
|
||||||
root["fs_used"] = fs_info.usedBytes;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); // proddy added
|
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
#include <WiFiScanner.h>
|
#include <WiFiScanner.h>
|
||||||
|
|
||||||
WiFiScanner::WiFiScanner(AsyncWebServer * server, SecurityManager * securityManager) {
|
WiFiScanner::WiFiScanner(AsyncWebServer * server, SecurityManager * securityManager) {
|
||||||
server->on(SCAN_NETWORKS_SERVICE_PATH,
|
server->on(SCAN_NETWORKS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WiFiScanner::scanNetworks, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
|
||||||
HTTP_GET,
|
server->on(LIST_NETWORKS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WiFiScanner::listNetworks, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
|
||||||
securityManager->wrapRequest(std::bind(&WiFiScanner::scanNetworks, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
|
|
||||||
server->on(LIST_NETWORKS_SERVICE_PATH,
|
|
||||||
HTTP_GET,
|
|
||||||
securityManager->wrapRequest(std::bind(&WiFiScanner::listNetworks, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void WiFiScanner::scanNetworks(AsyncWebServerRequest * request) {
|
void WiFiScanner::scanNetworks(AsyncWebServerRequest * request) {
|
||||||
@@ -24,16 +20,12 @@ void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
|
|||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
JsonArray networks = root.createNestedArray("networks");
|
JsonArray networks = root.createNestedArray("networks");
|
||||||
for (int i = 0; i < numNetworks; i++) {
|
for (int i = 0; i < numNetworks; i++) {
|
||||||
JsonObject network = networks.createNestedObject();
|
JsonObject network = networks.createNestedObject();
|
||||||
network["rssi"] = WiFi.RSSI(i);
|
network["rssi"] = WiFi.RSSI(i);
|
||||||
network["ssid"] = WiFi.SSID(i);
|
network["ssid"] = WiFi.SSID(i);
|
||||||
network["bssid"] = WiFi.BSSIDstr(i);
|
network["bssid"] = WiFi.BSSIDstr(i);
|
||||||
network["channel"] = WiFi.channel(i);
|
network["channel"] = WiFi.channel(i);
|
||||||
#ifdef ESP32
|
|
||||||
network["encryption_type"] = (uint8_t)WiFi.encryptionType(i);
|
network["encryption_type"] = (uint8_t)WiFi.encryptionType(i);
|
||||||
#elif defined(ESP8266)
|
|
||||||
network["encryption_type"] = convertEncryptionType(WiFi.encryptionType(i));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
@@ -43,26 +35,3 @@ void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
|
|||||||
scanNetworks(request);
|
scanNetworks(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESP8266
|
|
||||||
/*
|
|
||||||
* Convert encryption type to standard used by ESP32 rather than the translated form which the esp8266 libaries expose.
|
|
||||||
*
|
|
||||||
* This allows us to use a single set of mappings in the UI.
|
|
||||||
*/
|
|
||||||
uint8_t WiFiScanner::convertEncryptionType(uint8_t encryptionType) {
|
|
||||||
switch (encryptionType) {
|
|
||||||
case ENC_TYPE_NONE:
|
|
||||||
return AUTH_OPEN;
|
|
||||||
case ENC_TYPE_WEP:
|
|
||||||
return AUTH_WEP;
|
|
||||||
case ENC_TYPE_TKIP:
|
|
||||||
return AUTH_WPA_PSK;
|
|
||||||
case ENC_TYPE_CCMP:
|
|
||||||
return AUTH_WPA2_PSK;
|
|
||||||
case ENC_TYPE_AUTO:
|
|
||||||
return AUTH_WPA_WPA2_PSK;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
#include <WiFiSettingsService.h>
|
|
||||||
|
|
||||||
WiFiSettingsService::WiFiSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
|
||||||
: _httpEndpoint(WiFiSettings::read, WiFiSettings::update, this, server, WIFI_SETTINGS_SERVICE_PATH, securityManager)
|
|
||||||
, _fsPersistence(WiFiSettings::read, WiFiSettings::update, this, fs, WIFI_SETTINGS_FILE)
|
|
||||||
, _lastConnectionAttempt(0) {
|
|
||||||
// We want the device to come up in opmode=0 (WIFI_OFF), when erasing the flash this is not the default.
|
|
||||||
// If needed, we save opmode=0 before disabling persistence so the device boots with WiFi disabled in the future.
|
|
||||||
if (WiFi.getMode() != WIFI_OFF) {
|
|
||||||
WiFi.mode(WIFI_OFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable WiFi config persistance and auto reconnect
|
|
||||||
WiFi.persistent(false);
|
|
||||||
WiFi.setAutoReconnect(false);
|
|
||||||
#ifdef ESP32
|
|
||||||
// Init the wifi driver on ESP32
|
|
||||||
WiFi.mode(WIFI_MODE_MAX);
|
|
||||||
WiFi.mode(WIFI_MODE_NULL);
|
|
||||||
WiFi.onEvent(std::bind(&WiFiSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2),
|
|
||||||
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
|
||||||
WiFi.onEvent(std::bind(&WiFiSettingsService::onStationModeStop, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_STOP);
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
|
|
||||||
// proddy added
|
|
||||||
#if defined(ESP8266)
|
|
||||||
// WiFi.setSleepMode(WIFI_NONE_SLEEP); // added to possibly fix wifi dropouts in arduino core 2.5.0
|
|
||||||
// ref: https://github.com/esp8266/Arduino/issues/6471
|
|
||||||
// ref: https://github.com/esp8266/Arduino/issues/6366
|
|
||||||
// high tx power causing weird behavior, slightly lowering from 20.5 to 20.0 may help stability
|
|
||||||
// WiFi.setOutputPower(20.0); // in dBm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&WiFiSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
addUpdateHandler([&](const String & originId) { reconfigureWiFiConnection(); }, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiSettingsService::begin() {
|
|
||||||
_fsPersistence.readFromFS();
|
|
||||||
reconfigureWiFiConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiSettingsService::reconfigureWiFiConnection() {
|
|
||||||
// reset last connection attempt to force loop to reconnect immediately
|
|
||||||
_lastConnectionAttempt = 0;
|
|
||||||
|
|
||||||
// disconnect and de-configure wifi
|
|
||||||
#ifdef ESP32
|
|
||||||
if (WiFi.disconnect(true)) {
|
|
||||||
_stopping = true;
|
|
||||||
}
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
WiFi.disconnect(true);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiSettingsService::loop() {
|
|
||||||
unsigned long currentMillis = millis();
|
|
||||||
if (!_lastConnectionAttempt || (uint32_t)(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) {
|
|
||||||
_lastConnectionAttempt = currentMillis;
|
|
||||||
manageSTA();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiSettingsService::manageSTA() {
|
|
||||||
// Abort if already connected, or if we have no SSID
|
|
||||||
if (WiFi.isConnected() || _state.ssid.length() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Connect or reconnect as required
|
|
||||||
if ((WiFi.getMode() & WIFI_STA) == 0) {
|
|
||||||
// Serial.println(F("Connecting to WiFi."));
|
|
||||||
if (_state.staticIPConfig) {
|
|
||||||
// configure for static IP
|
|
||||||
WiFi.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2);
|
|
||||||
} else {
|
|
||||||
// configure for DHCP
|
|
||||||
#ifdef ESP32
|
|
||||||
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
WiFi.config(INADDR_ANY, INADDR_ANY, INADDR_ANY);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// set hostname
|
|
||||||
#ifdef ESP32
|
|
||||||
WiFi.setHostname(_state.hostname.c_str());
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
WiFi.hostname(_state.hostname);
|
|
||||||
#endif
|
|
||||||
// attempt to connect to the network
|
|
||||||
WiFi.begin(_state.ssid.c_str(), _state.password.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
void WiFiSettingsService::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|
||||||
WiFi.disconnect(true);
|
|
||||||
}
|
|
||||||
void WiFiSettingsService::onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|
||||||
if (_stopping) {
|
|
||||||
_lastConnectionAttempt = 0;
|
|
||||||
_stopping = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
void WiFiSettingsService::onStationModeDisconnected(const WiFiEventStationModeDisconnected & event) {
|
|
||||||
WiFi.disconnect(true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#include <WiFiStatus.h>
|
|
||||||
|
|
||||||
WiFiStatus::WiFiStatus(AsyncWebServer * server, SecurityManager * securityManager) {
|
|
||||||
server->on(WIFI_STATUS_SERVICE_PATH,
|
|
||||||
HTTP_GET,
|
|
||||||
securityManager->wrapRequest(std::bind(&WiFiStatus::wifiStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
|
|
||||||
#ifdef ESP32
|
|
||||||
WiFi.onEvent(onStationModeConnected, WiFiEvent_t::SYSTEM_EVENT_STA_CONNECTED);
|
|
||||||
WiFi.onEvent(onStationModeDisconnected, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
|
||||||
WiFi.onEvent(onStationModeGotIP, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
_onStationModeConnectedHandler = WiFi.onStationModeConnected(onStationModeConnected);
|
|
||||||
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(onStationModeDisconnected);
|
|
||||||
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(onStationModeGotIP);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
void WiFiStatus::onStationModeConnected(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|
||||||
// Serial.println(F("WiFi Connected."));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiStatus::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|
||||||
// Serial.print(F("WiFi Disconnected. Reason code="));
|
|
||||||
// Serial.println(info.disconnected.reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiStatus::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|
||||||
// Serial.printf_P(PSTR("WiFi Got IP. localIP=%s, hostName=%s\r\n"), WiFi.localIP().toString().c_str(), WiFi.getHostname());
|
|
||||||
}
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
void WiFiStatus::onStationModeConnected(const WiFiEventStationModeConnected & event) {
|
|
||||||
// Serial.print(F("WiFi Connected. SSID="));
|
|
||||||
// Serial.println(event.ssid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiStatus::onStationModeDisconnected(const WiFiEventStationModeDisconnected & event) {
|
|
||||||
// Serial.print(F("WiFi Disconnected. Reason code="));
|
|
||||||
// Serial.println(event.reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiStatus::onStationModeGotIP(const WiFiEventStationModeGotIP & event) {
|
|
||||||
// Serial.printf_P(PSTR("WiFi Got IP. localIP=%s, hostName=%s\r\n"), event.ip.toString().c_str(), WiFi.hostname().c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void WiFiStatus::wifiStatus(AsyncWebServerRequest * request) {
|
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_WIFI_STATUS_SIZE);
|
|
||||||
JsonObject root = response->getRoot();
|
|
||||||
wl_status_t status = WiFi.status();
|
|
||||||
root["status"] = (uint8_t)status;
|
|
||||||
if (status == WL_CONNECTED) {
|
|
||||||
root["local_ip"] = WiFi.localIP().toString();
|
|
||||||
root["mac_address"] = WiFi.macAddress();
|
|
||||||
root["rssi"] = WiFi.RSSI();
|
|
||||||
root["ssid"] = WiFi.SSID();
|
|
||||||
root["bssid"] = WiFi.BSSIDstr();
|
|
||||||
root["channel"] = WiFi.channel();
|
|
||||||
root["subnet_mask"] = WiFi.subnetMask().toString();
|
|
||||||
root["gateway_ip"] = WiFi.gatewayIP().toString();
|
|
||||||
IPAddress dnsIP1 = WiFi.dnsIP(0);
|
|
||||||
IPAddress dnsIP2 = WiFi.dnsIP(1);
|
|
||||||
if (dnsIP1 != INADDR_NONE) {
|
|
||||||
root["dns_ip_1"] = dnsIP1.toString();
|
|
||||||
}
|
|
||||||
if (dnsIP2 != INADDR_NONE) {
|
|
||||||
root["dns_ip_2"] = dnsIP2.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response->setLength();
|
|
||||||
request->send(response);
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
#ifndef WiFiStatus_h
|
|
||||||
#define WiFiStatus_h
|
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
#include <WiFi.h>
|
|
||||||
#include <AsyncTCP.h>
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
#include <ESP8266WiFi.h>
|
|
||||||
#include <ESPAsyncTCP.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
#include <AsyncJson.h>
|
|
||||||
#include <ESPAsyncWebServer.h>
|
|
||||||
#include <IPAddress.h>
|
|
||||||
#include <SecurityManager.h>
|
|
||||||
|
|
||||||
#define MAX_WIFI_STATUS_SIZE 1024
|
|
||||||
#define WIFI_STATUS_SERVICE_PATH "/rest/wifiStatus"
|
|
||||||
|
|
||||||
class WiFiStatus {
|
|
||||||
public:
|
|
||||||
WiFiStatus(AsyncWebServer * server, SecurityManager * securityManager);
|
|
||||||
|
|
||||||
private:
|
|
||||||
#ifdef ESP32
|
|
||||||
// static functions for logging WiFi events to the UART
|
|
||||||
static void onStationModeConnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
|
||||||
static void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
|
||||||
static void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
// handler refrences for logging important WiFi events over serial
|
|
||||||
WiFiEventHandler _onStationModeConnectedHandler;
|
|
||||||
WiFiEventHandler _onStationModeDisconnectedHandler;
|
|
||||||
WiFiEventHandler _onStationModeGotIPHandler;
|
|
||||||
// static functions for logging WiFi events to the UART
|
|
||||||
static void onStationModeConnected(const WiFiEventStationModeConnected & event);
|
|
||||||
static void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
|
|
||||||
static void onStationModeGotIP(const WiFiEventStationModeGotIP & event);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void wifiStatus(AsyncWebServerRequest * request);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // end WiFiStatus_h
|
|
||||||
@@ -21,8 +21,13 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <Network.h>
|
||||||
|
|
||||||
NativeConsole Serial;
|
NativeConsole Serial;
|
||||||
|
|
||||||
|
ETHClass ETH;
|
||||||
|
WiFiClass WiFi;
|
||||||
|
|
||||||
/* millis() on C++ native could be
|
/* millis() on C++ native could be
|
||||||
for non-Arduino
|
for non-Arduino
|
||||||
millis():
|
millis():
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ int digitalRead(uint8_t pin);
|
|||||||
|
|
||||||
#define PROGMEM
|
#define PROGMEM
|
||||||
#define PGM_P const char *
|
#define PGM_P const char *
|
||||||
#define PSTR(s) \
|
#define PSTR(s) \
|
||||||
(__extension__({ \
|
(__extension__({ \
|
||||||
static const char __c[] = (s); \
|
static const char __c[] = (s); \
|
||||||
&__c[0]; \
|
&__c[0]; \
|
||||||
}))
|
}))
|
||||||
|
|
||||||
class __FlashStringHelper;
|
class __FlashStringHelper;
|
||||||
@@ -193,7 +193,11 @@ class NativeConsole : public Stream {
|
|||||||
unsigned char peek_data_;
|
unsigned char peek_data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <Network.h>
|
||||||
|
|
||||||
extern NativeConsole Serial;
|
extern NativeConsole Serial;
|
||||||
|
extern ETHClass ETH;
|
||||||
|
extern WiFiClass WiFi;
|
||||||
|
|
||||||
unsigned long millis();
|
unsigned long millis();
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ struct AsyncMqttClientMessageProperties {
|
|||||||
|
|
||||||
namespace AsyncMqttClientInternals {
|
namespace AsyncMqttClientInternals {
|
||||||
|
|
||||||
typedef std::function<void(bool sessionPresent)> OnConnectUserCallback;
|
typedef std::function<void(bool sessionPresent)> OnConnectUserCallback;
|
||||||
typedef std::function<void(AsyncMqttClientDisconnectReason reason)> OnDisconnectUserCallback;
|
typedef std::function<void(AsyncMqttClientDisconnectReason reason)> OnDisconnectUserCallback;
|
||||||
typedef std::function<void(uint16_t packetId, uint8_t qos)> OnSubscribeUserCallback;
|
typedef std::function<void(uint16_t packetId, uint8_t qos)> OnSubscribeUserCallback;
|
||||||
typedef std::function<void(uint16_t packetId)> OnUnsubscribeUserCallback;
|
typedef std::function<void(uint16_t packetId)> OnUnsubscribeUserCallback;
|
||||||
typedef std::function<void(char * topic, char * payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)> OnMessageUserCallback;
|
typedef std::function<void(char * topic, char * payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)> OnMessageUserCallback;
|
||||||
typedef std::function<void(uint16_t packetId)> OnPublishUserCallback;
|
typedef std::function<void(uint16_t packetId)> OnPublishUserCallback;
|
||||||
}; // namespace AsyncMqttClientInternals
|
}; // namespace AsyncMqttClientInternals
|
||||||
|
|
||||||
class AsyncMqttClient {
|
class AsyncMqttClient {
|
||||||
@@ -115,4 +115,4 @@ class AsyncMqttClient {
|
|||||||
bool _willRetain;
|
bool _willRetain;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <SecurityManager.h>
|
#include <SecurityManager.h>
|
||||||
#include <SecuritySettingsService.h>
|
#include <SecuritySettingsService.h>
|
||||||
#include <StatefulService.h>
|
#include <StatefulService.h>
|
||||||
|
#include <Network.h>
|
||||||
|
|
||||||
class DummySettings {
|
class DummySettings {
|
||||||
public:
|
public:
|
||||||
@@ -44,6 +45,7 @@ class DummySettings {
|
|||||||
String staticIPConfig = "";
|
String staticIPConfig = "";
|
||||||
String dnsIP1 = "";
|
String dnsIP1 = "";
|
||||||
String dnsIP2 = "";
|
String dnsIP2 = "";
|
||||||
|
uint8_t ethernet_profile = 0;
|
||||||
uint16_t publish_time_boiler = 10;
|
uint16_t publish_time_boiler = 10;
|
||||||
uint16_t publish_time_thermostat = 10;
|
uint16_t publish_time_thermostat = 10;
|
||||||
uint16_t publish_time_solar = 10;
|
uint16_t publish_time_solar = 10;
|
||||||
@@ -66,11 +68,9 @@ class DummySettingsService : public StatefulService<DummySettings> {
|
|||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WiFiSettings DummySettings
|
#define NetworkSettings DummySettings
|
||||||
#define SecuritySettings DummySettings
|
#define SecuritySettings DummySettings
|
||||||
#define MqttSettings DummySettings
|
#define MqttSettings DummySettings
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ class ESP8266React {
|
|||||||
return _mqttClient;
|
return _mqttClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
StatefulService<DummySettings> * getWiFiSettingsService() {
|
StatefulService<DummySettings> * getNetworkSettingsService() {
|
||||||
return &_settings;
|
return &_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,10 +113,7 @@ class ESP8266React {
|
|||||||
class EMSESPSettingsService {
|
class EMSESPSettingsService {
|
||||||
public:
|
public:
|
||||||
EMSESPSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
EMSESPSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class JsonUtils {
|
class JsonUtils {
|
||||||
|
|||||||
@@ -33,5 +33,4 @@
|
|||||||
#define FT_UPLOAD_FIRMWARE 0
|
#define FT_UPLOAD_FIRMWARE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
180
lib_standalone/Network.h
Normal file
180
lib_standalone/Network.h
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
#ifndef Network_h
|
||||||
|
#define Network_h
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#define WiFiMode_t wifi_mode_t
|
||||||
|
#define WIFI_OFF WIFI_MODE_NULL
|
||||||
|
#define WIFI_STA WIFI_MODE_STA
|
||||||
|
#define WIFI_AP WIFI_MODE_AP
|
||||||
|
#define WIFI_AP_STA WIFI_MODE_APSTA
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SYSTEM_EVENT_WIFI_READY = 0, /**< ESP32 WiFi ready */
|
||||||
|
SYSTEM_EVENT_SCAN_DONE, /**< ESP32 finish scanning AP */
|
||||||
|
SYSTEM_EVENT_STA_START, /**< ESP32 station start */
|
||||||
|
SYSTEM_EVENT_STA_STOP, /**< ESP32 station stop */
|
||||||
|
SYSTEM_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */
|
||||||
|
SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */
|
||||||
|
SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP32 station changed */
|
||||||
|
SYSTEM_EVENT_STA_GOT_IP, /**< ESP32 station got IP from connected AP */
|
||||||
|
SYSTEM_EVENT_STA_LOST_IP, /**< ESP32 station lost IP and the IP is reset to 0 */
|
||||||
|
SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /**< ESP32 station wps succeeds in enrollee mode */
|
||||||
|
SYSTEM_EVENT_STA_WPS_ER_FAILED, /**< ESP32 station wps fails in enrollee mode */
|
||||||
|
SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP32 station wps timeout in enrollee mode */
|
||||||
|
SYSTEM_EVENT_STA_WPS_ER_PIN, /**< ESP32 station wps pin code in enrollee mode */
|
||||||
|
SYSTEM_EVENT_STA_WPS_ER_PBC_OVERLAP, /*!< ESP32 station wps overlap in enrollee mode */
|
||||||
|
SYSTEM_EVENT_AP_START, /**< ESP32 soft-AP start */
|
||||||
|
SYSTEM_EVENT_AP_STOP, /**< ESP32 soft-AP stop */
|
||||||
|
SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */
|
||||||
|
SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */
|
||||||
|
SYSTEM_EVENT_AP_STAIPASSIGNED, /**< ESP32 soft-AP assign an IP to a connected station */
|
||||||
|
SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */
|
||||||
|
SYSTEM_EVENT_GOT_IP6, /**< ESP32 station or ap or ethernet interface v6IP addr is preferred */
|
||||||
|
SYSTEM_EVENT_ETH_START, /**< ESP32 ethernet start */
|
||||||
|
SYSTEM_EVENT_ETH_STOP, /**< ESP32 ethernet stop */
|
||||||
|
SYSTEM_EVENT_ETH_CONNECTED, /**< ESP32 ethernet phy link up */
|
||||||
|
SYSTEM_EVENT_ETH_DISCONNECTED, /**< ESP32 ethernet phy link down */
|
||||||
|
SYSTEM_EVENT_ETH_GOT_IP, /**< ESP32 ethernet got IP from connected AP */
|
||||||
|
SYSTEM_EVENT_MAX
|
||||||
|
} system_event_id_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WIFI_AUTH_OPEN = 0, /**< authenticate mode : open */
|
||||||
|
WIFI_AUTH_WEP, /**< authenticate mode : WEP */
|
||||||
|
WIFI_AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */
|
||||||
|
WIFI_AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */
|
||||||
|
WIFI_AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */
|
||||||
|
WIFI_AUTH_WPA2_ENTERPRISE, /**< authenticate mode : WPA2_ENTERPRISE */
|
||||||
|
WIFI_AUTH_MAX
|
||||||
|
} wifi_auth_mode_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t status; /**< status of scanning APs */
|
||||||
|
uint8_t number;
|
||||||
|
uint8_t scan_id;
|
||||||
|
} system_event_sta_scan_done_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t ssid[32]; /**< SSID of connected AP */
|
||||||
|
uint8_t ssid_len; /**< SSID length of connected AP */
|
||||||
|
uint8_t bssid[6]; /**< BSSID of connected AP*/
|
||||||
|
uint8_t channel; /**< channel of connected AP*/
|
||||||
|
wifi_auth_mode_t authmode;
|
||||||
|
} system_event_sta_connected_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t ssid[32]; /**< SSID of disconnected AP */
|
||||||
|
uint8_t ssid_len; /**< SSID length of disconnected AP */
|
||||||
|
uint8_t bssid[6]; /**< BSSID of disconnected AP */
|
||||||
|
uint8_t reason; /**< reason of disconnection */
|
||||||
|
} system_event_sta_disconnected_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
wifi_auth_mode_t old_mode; /**< the old auth mode of AP */
|
||||||
|
wifi_auth_mode_t new_mode; /**< the new auth mode of AP */
|
||||||
|
} system_event_sta_authmode_change_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */
|
||||||
|
} system_event_sta_wps_er_pin_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t mac[6]; /**< MAC address of the station connected to ESP32 soft-AP */
|
||||||
|
uint8_t aid; /**< the aid that ESP32 soft-AP gives to the station connected to */
|
||||||
|
} system_event_ap_staconnected_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t mac[6]; /**< MAC address of the station disconnects to ESP32 soft-AP */
|
||||||
|
uint8_t aid; /**< the aid that ESP32 soft-AP gave to the station disconnects to */
|
||||||
|
} system_event_ap_stadisconnected_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int rssi; /**< Received probe request signal strength */
|
||||||
|
uint8_t mac[6]; /**< MAC address of the station which send probe request */
|
||||||
|
} system_event_ap_probe_req_rx_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WPS_FAIL_REASON_NORMAL = 0, /**< ESP32 WPS normal fail reason */
|
||||||
|
WPS_FAIL_REASON_RECV_M2D, /**< ESP32 WPS receive M2D frame */
|
||||||
|
WPS_FAIL_REASON_MAX
|
||||||
|
} system_event_sta_wps_fail_reason_t;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
system_event_sta_connected_t connected; /**< ESP32 station connected to AP */
|
||||||
|
system_event_sta_disconnected_t disconnected; /**< ESP32 station disconnected to AP */
|
||||||
|
system_event_sta_scan_done_t scan_done; /**< ESP32 station scan (APs) done */
|
||||||
|
system_event_sta_authmode_change_t auth_change; /**< the auth mode of AP ESP32 station connected to changed */
|
||||||
|
system_event_sta_wps_fail_reason_t sta_er_fail_reason; /**< ESP32 station WPS enrollee mode failed reason code received */
|
||||||
|
system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP32 soft-AP */
|
||||||
|
system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP32 soft-AP */
|
||||||
|
system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP32 soft-AP receive probe request packet */
|
||||||
|
} system_event_info_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
system_event_id_t event_id; /**< event ID */
|
||||||
|
system_event_info_t event_info; /**< event information */
|
||||||
|
} system_event_t;
|
||||||
|
|
||||||
|
#define WiFiEvent_t system_event_id_t
|
||||||
|
#define WiFiEventInfo_t system_event_info_t
|
||||||
|
#define WiFiEventId_t wifi_event_id_t
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
|
||||||
|
WL_IDLE_STATUS = 0,
|
||||||
|
WL_NO_SSID_AVAIL = 1,
|
||||||
|
WL_SCAN_COMPLETED = 2,
|
||||||
|
WL_CONNECTED = 3,
|
||||||
|
WL_CONNECT_FAILED = 4,
|
||||||
|
WL_CONNECTION_LOST = 5,
|
||||||
|
WL_DISCONNECTED = 6
|
||||||
|
} wl_status_t;
|
||||||
|
|
||||||
|
typedef void (*WiFiEventCb)(system_event_id_t event);
|
||||||
|
typedef std::function<void(system_event_id_t event, system_event_info_t info)> WiFiEventFuncCb;
|
||||||
|
typedef void (*WiFiEventSysCb)(system_event_t * event);
|
||||||
|
typedef size_t wifi_event_id_t;
|
||||||
|
|
||||||
|
class WiFiClass {
|
||||||
|
public:
|
||||||
|
wifi_event_id_t onEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX) {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX) {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX) {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
char * getHostname() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
char * localIP() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ETHClass {
|
||||||
|
public:
|
||||||
|
bool begin() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setHostname(const char * s){};
|
||||||
|
char * getHostname() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
char * localIP() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
int linkSpeed() {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -56,7 +56,6 @@ inline bool operator==(const std::string & lhs, const ::String & rhs) {
|
|||||||
return lhs == rhs.c_str();
|
return lhs == rhs.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize);
|
size_t strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize);
|
||||||
size_t strlcat(char * dst, const char * src, size_t siz);
|
size_t strlcat(char * dst, const char * src, size_t siz);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
; PlatformIO Project Configuration File for EMS-ESP
|
; PlatformIO Project Configuration File for EMS-ESP
|
||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
; default_envs = esp8266
|
|
||||||
default_envs = esp32
|
default_envs = esp32
|
||||||
|
|
||||||
# override any settings with your own local ones in pio_local.ini
|
# override any settings with your own local ones in pio_local.ini
|
||||||
@@ -15,20 +14,11 @@ core_build_flags = -Wno-deprecated-declarations
|
|||||||
-Wreturn-type
|
-Wreturn-type
|
||||||
-DCORE_DEBUG_LEVEL=0
|
-DCORE_DEBUG_LEVEL=0
|
||||||
-DNDEBUG
|
-DNDEBUG
|
||||||
|
|
||||||
esp8266_build_flags = -free
|
|
||||||
-mtarget-align
|
|
||||||
-fipa-pta
|
|
||||||
-Wreturn-type
|
|
||||||
-DFP_IN_IROM
|
|
||||||
-DBEARSSL_SSL_BASIC
|
|
||||||
-DVTABLES_IN_FLASH
|
|
||||||
-DPSTR_ALIGN=1 ; remove the 4-bytes alignment for PSTR()
|
|
||||||
-std=c17 -std=c++17 -std=gnu++17
|
|
||||||
|
|
||||||
esp32_build_flags = -DARDUINO_ARCH_ESP32=1
|
esp32_build_flags = -DARDUINO_ARCH_ESP32=1
|
||||||
-DESP32=1
|
-DESP32=1
|
||||||
-DBOARD_HAS_PSRAM
|
-DBOARD_HAS_PSRAM
|
||||||
|
; -std=c17 -std=c++17 -std=gnu++17
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.core_build_flags}
|
${common.core_build_flags}
|
||||||
@@ -48,9 +38,8 @@ build_flags =
|
|||||||
build_unflags = -Wall
|
build_unflags = -Wall
|
||||||
-Wdeprecated-declarations
|
-Wdeprecated-declarations
|
||||||
|
|
||||||
esp8266_build_unflags = -std=gnu++11
|
|
||||||
|
|
||||||
esp32_build_unflags =
|
esp32_build_unflags =
|
||||||
|
; -std=gnu++11
|
||||||
|
|
||||||
debug_flags =
|
debug_flags =
|
||||||
; -D EMSESP_DEBUG
|
; -D EMSESP_DEBUG
|
||||||
@@ -73,18 +62,6 @@ check_flags =
|
|||||||
cppcheck: --std=c++11 -v
|
cppcheck: --std=c++11 -v
|
||||||
clangtidy: --checks=-*,clang-analyzer-*,performance-*
|
clangtidy: --checks=-*,clang-analyzer-*,performance-*
|
||||||
|
|
||||||
; build for GitHub Actions CI
|
|
||||||
[env:esp8266-ci]
|
|
||||||
extra_scripts =
|
|
||||||
scripts/main_script.py
|
|
||||||
scripts/rename_fw.py
|
|
||||||
board = esp12e
|
|
||||||
platform = espressif8266
|
|
||||||
board_build.filesystem = littlefs
|
|
||||||
board_build.f_cpu = 160000000L
|
|
||||||
build_flags = ${common.build_flags} ${common.esp8266_build_flags}
|
|
||||||
build_unflags = ${common.build_unflags} ${common.esp8266_build_unflags}
|
|
||||||
|
|
||||||
; build for GitHub Actions CI
|
; build for GitHub Actions CI
|
||||||
[env:esp32-ci]
|
[env:esp32-ci]
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
@@ -95,30 +72,6 @@ board_build.partitions = min_spiffs.csv
|
|||||||
build_flags = ${common.build_flags} ${common.esp32_build_flags}
|
build_flags = ${common.build_flags} ${common.esp32_build_flags}
|
||||||
build_unflags = ${common.build_unflags} ${common.esp32_build_unflags}
|
build_unflags = ${common.build_unflags} ${common.esp32_build_unflags}
|
||||||
|
|
||||||
[env:esp8266]
|
|
||||||
extra_scripts =
|
|
||||||
pre:scripts/build_interface.py
|
|
||||||
scripts/main_script.py
|
|
||||||
scripts/rename_fw.py
|
|
||||||
board = esp12e ; https://github.com/platformio/platform-espressif8266/tree/master/boards
|
|
||||||
platform = espressif8266 ; https://github.com/platformio/platform-espressif8266/releases
|
|
||||||
platform_packages = platformio/framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git
|
|
||||||
; toolchain-xtensa @ ~2.100100.200706
|
|
||||||
; toolchain-xtensa @ 2.40802.200502
|
|
||||||
; toolchain-xtensa @ https://github.com/earlephilhower/esp-quick-toolchain/releases/download/3.0.0-gnu12/x86_64-linux-gnu.xtensa-lx106-elf-0474ae9.200706.tar.gz
|
|
||||||
; platformio/tool-esptool @ 1.413.0
|
|
||||||
; platformio/tool-esptoolpy @ ~1.30000.0
|
|
||||||
mcspr/toolchain-xtensa @ 5.100200.201223
|
|
||||||
board_build.filesystem = littlefs
|
|
||||||
board_build.f_cpu = 160000000L ; 160MHz
|
|
||||||
; eagle.flash.4m1m.ld = 1019 KB sketch, 1000 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 2052 KB OTA & buffer
|
|
||||||
; eagle.flash.4m2m.ld = 1019 KB sketch, 2024 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 1028 KB OTA & buffer
|
|
||||||
; board_build.ldscript = eagle.flash.4m2m.ld
|
|
||||||
build_flags = ${common.build_flags} ${common.esp8266_build_flags} ${common.debug_flags}
|
|
||||||
build_unflags = ${common.build_unflags} ${common.esp8266_build_unflags}
|
|
||||||
lib_ignore =
|
|
||||||
AsyncTCP
|
|
||||||
|
|
||||||
[env:esp32]
|
[env:esp32]
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
pre:scripts/build_interface.py
|
pre:scripts/build_interface.py
|
||||||
|
|||||||
@@ -22,39 +22,81 @@ namespace emsesp {
|
|||||||
|
|
||||||
WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) {
|
WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) {
|
||||||
// rest endpoint for web page
|
// rest endpoint for web page
|
||||||
server->on(EMSESP_STATUS_SERVICE_PATH,
|
server->on(EMSESP_STATUS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebStatusService::webStatusService, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||||
HTTP_GET,
|
WiFi.onEvent(std::bind(&WebStatusService::WiFiEvent, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
securityManager->wrapRequest(std::bind(&WebStatusService::webStatusService, this, std::placeholders::_1),
|
|
||||||
AuthenticationPredicates::IS_AUTHENTICATED));
|
|
||||||
|
|
||||||
// trigger on wifi connects/disconnects
|
|
||||||
#ifdef ESP32
|
|
||||||
WiFi.onEvent(onStationModeDisconnected, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
|
||||||
WiFi.onEvent(onStationModeGotIP, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(onStationModeDisconnected);
|
|
||||||
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(onStationModeGotIP);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESP32
|
// handles both WiFI and Ethernet
|
||||||
void WebStatusService::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
|
void WebStatusService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||||
EMSESP::logger().info(F("WiFi Disconnected. Reason code=%d"), info.disconnected.reason);
|
switch (event) {
|
||||||
}
|
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||||
void WebStatusService::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
EMSESP::logger().info(F("WiFi Disconnected. Reason code=%d"), info.disconnected.reason);
|
||||||
EMSESP::logger().info(F("WiFi Connected with IP=%s, hostname=%s"), WiFi.localIP().toString().c_str(), WiFi.getHostname());
|
|
||||||
EMSESP::system_.init_wifi(); // send out heartbeat MQTT as soon as we have a connection
|
break;
|
||||||
}
|
|
||||||
#elif defined(ESP8266)
|
case SYSTEM_EVENT_STA_GOT_IP:
|
||||||
void WebStatusService::onStationModeDisconnected(const WiFiEventStationModeDisconnected & event) {
|
#ifndef EMSESP_STANDALONE
|
||||||
EMSESP::logger().info(F("WiFi Disconnected. Reason code=%d"), event.reason);
|
EMSESP::logger().info(F("WiFi Connected with IP=%s, hostname=%s"), WiFi.localIP().toString().c_str(), WiFi.getHostname());
|
||||||
}
|
|
||||||
void WebStatusService::onStationModeGotIP(const WiFiEventStationModeGotIP & event) {
|
|
||||||
EMSESP::logger().info(F("WiFi Connected with IP=%s, hostname=%s"), event.ip.toString().c_str(), WiFi.hostname().c_str());
|
|
||||||
EMSESP::system_.init_wifi(); // send out heartbeat MQTT as soon as we have a connection
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Lower WiFi tx power to free up current for bus-powered
|
||||||
|
/*
|
||||||
|
WIFI_POWER_19_5dBm = 78,// 19.5dBm <-- default
|
||||||
|
WIFI_POWER_19dBm = 76,// 19dBm
|
||||||
|
WIFI_POWER_18_5dBm = 74,// 18.5dBm
|
||||||
|
WIFI_POWER_17dBm = 68,// 17dBm
|
||||||
|
WIFI_POWER_15dBm = 60,// 15dBm
|
||||||
|
WIFI_POWER_13dBm = 52,// 13dBm
|
||||||
|
WIFI_POWER_11dBm = 44,// 11dBm
|
||||||
|
WIFI_POWER_8_5dBm = 34,// 8.5dBm
|
||||||
|
WIFI_POWER_7dBm = 28,// 7dBm
|
||||||
|
WIFI_POWER_5dBm = 20,// 5dBm
|
||||||
|
WIFI_POWER_2dBm = 8,// 2dBm
|
||||||
|
WIFI_POWER_MINUS_1dBm = -4// -1dBm
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
wifi_power_t a1 = WiFi.getTxPower();
|
||||||
|
// bool ok = WiFi.setTxPower(WIFI_POWER_17dBm); // lower power
|
||||||
|
bool ok = WiFi.setTxPower(WIFI_POWER_19_5dBm);
|
||||||
|
wifi_power_t a2 = WiFi.getTxPower();
|
||||||
|
LOG_INFO("Adjusting Wifi Tx power from %d to %d (%s)", a1, a2, ok ? "ok" : "failed");
|
||||||
|
*/
|
||||||
|
|
||||||
|
EMSESP::system_.init_network(); // send out heartbeat MQTT as soon as we have a connection
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSTEM_EVENT_ETH_START:
|
||||||
|
EMSESP::logger().info(F("Ethernet Started"));
|
||||||
|
ETH.setHostname(emsesp::System::hostname().c_str());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||||
|
// prevent double calls
|
||||||
|
if (!connected_) {
|
||||||
|
#ifndef EMSESP_STANDALONE
|
||||||
|
EMSESP::logger().info(F("Ethernet Connected with IP=%s, speed %d Mbps"), ETH.localIP().toString().c_str(), ETH.linkSpeed());
|
||||||
|
#endif
|
||||||
|
EMSESP::system_.init_network(); // send out heartbeat MQTT as soon as we have a connection
|
||||||
|
connected_ = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||||
|
EMSESP::logger().info(F("Ethernet Disconnected"));
|
||||||
|
connected_ = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSTEM_EVENT_ETH_STOP:
|
||||||
|
EMSESP::logger().info(F("Ethernet Stopped"));
|
||||||
|
connected_ = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WebStatusService::webStatusService(AsyncWebServerRequest * request) {
|
void WebStatusService::webStatusService(AsyncWebServerRequest * request) {
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_MEDIUM_DYN);
|
AsyncJsonResponse * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_MEDIUM_DYN);
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
|
|||||||
@@ -34,18 +34,9 @@ class WebStatusService {
|
|||||||
WebStatusService(AsyncWebServer * server, SecurityManager * securityManager);
|
WebStatusService(AsyncWebServer * server, SecurityManager * securityManager);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool connected_ = false;
|
||||||
void webStatusService(AsyncWebServerRequest * request);
|
void webStatusService(AsyncWebServerRequest * request);
|
||||||
|
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
#ifdef ESP32
|
|
||||||
static void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
|
||||||
static void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
|
||||||
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
WiFiEventHandler _onStationModeDisconnectedHandler;
|
|
||||||
WiFiEventHandler _onStationModeGotIPHandler;
|
|
||||||
static void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
|
|
||||||
static void onStationModeGotIP(const WiFiEventStationModeGotIP & event);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ void EMSESPShell::display_banner() {
|
|||||||
println();
|
println();
|
||||||
|
|
||||||
// set console name
|
// set console name
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & wifiSettings) { console_hostname_ = wifiSettings.hostname.c_str(); });
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { console_hostname_ = networkSettings.hostname.c_str(); });
|
||||||
|
|
||||||
if (console_hostname_.empty()) {
|
if (console_hostname_.empty()) {
|
||||||
console_hostname_.resize(16, '\0');
|
console_hostname_.resize(16, '\0');
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
* Lightweight queue & array
|
* Lightweight queue & array
|
||||||
* Based ideas from https://github.com/muwerk/ustd
|
* Based ideas from https://github.com/muwerk/ustd
|
||||||
* Limits to max 255 entries
|
* Limits to max 255 entries
|
||||||
|
* Was used in testing with ESP8266 to overcome heap memory issues - no longer used
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EMSESP_CONTAINERS_H
|
#ifndef EMSESP_CONTAINERS_H
|
||||||
|
|||||||
@@ -31,9 +31,6 @@ AsyncWebServer webServer(80);
|
|||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
ESP8266React EMSESP::esp8266React(&webServer, &SPIFFS);
|
ESP8266React EMSESP::esp8266React(&webServer, &SPIFFS);
|
||||||
WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, &SPIFFS, EMSESP::esp8266React.getSecurityManager());
|
WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, &SPIFFS, EMSESP::esp8266React.getSecurityManager());
|
||||||
#elif defined(ESP8266)
|
|
||||||
ESP8266React EMSESP::esp8266React(&webServer, &LittleFS);
|
|
||||||
WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
|
||||||
#elif defined(EMSESP_STANDALONE)
|
#elif defined(EMSESP_STANDALONE)
|
||||||
FS dummyFS;
|
FS dummyFS;
|
||||||
ESP8266React EMSESP::esp8266React(&webServer, &dummyFS);
|
ESP8266React EMSESP::esp8266React(&webServer, &dummyFS);
|
||||||
@@ -1027,11 +1024,9 @@ void EMSESP::send_raw_telegram(const char * data) {
|
|||||||
// start all the core services
|
// start all the core services
|
||||||
// the services must be loaded in the correct order
|
// the services must be loaded in the correct order
|
||||||
void EMSESP::start() {
|
void EMSESP::start() {
|
||||||
// start the file system. We use LittleFS for ESP8266.
|
// start the file system
|
||||||
#ifdef ESP32
|
#ifndef EMSESP_STANDALONE
|
||||||
SPIFFS.begin(true);
|
SPIFFS.begin(true);
|
||||||
#elif defined(ESP8266)
|
|
||||||
LittleFS.begin();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
esp8266React.begin(); // loads system settings (wifi, mqtt, etc)
|
esp8266React.begin(); // loads system settings (wifi, mqtt, etc)
|
||||||
@@ -1039,25 +1034,11 @@ void EMSESP::start() {
|
|||||||
|
|
||||||
system_.check_upgrade(); // do any upgrades
|
system_.check_upgrade(); // do any upgrades
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
// Load our library of known devices into stack mem. Names are stored in Flash memory (take about 960bytes)
|
||||||
#ifndef EMSESP_STANDALONE
|
|
||||||
uint32_t tbefore = ESP.getFreeHeap();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Load our library of known devices into stack mem. Names are stored in Flash memory
|
|
||||||
// Still it takes up about 960bytes
|
|
||||||
device_library_.reserve(80);
|
|
||||||
device_library_ = {
|
device_library_ = {
|
||||||
#include "device_library.h"
|
#include "device_library.h"
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
|
||||||
#ifndef EMSESP_STANDALONE
|
|
||||||
uint32_t tafter = ESP.getFreeHeap();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
console_.start(); // telnet and serial console
|
console_.start(); // telnet and serial console
|
||||||
mqtt_.start(); // mqtt init
|
mqtt_.start(); // mqtt init
|
||||||
system_.start(heap_start); // starts syslog, uart, sets version, initializes LED. Requires pre-loaded settings.
|
system_.start(heap_start); // starts syslog, uart, sets version, initializes LED. Requires pre-loaded settings.
|
||||||
@@ -1069,13 +1050,6 @@ void EMSESP::start() {
|
|||||||
|
|
||||||
LOG_INFO(F("EMS Device library loaded with %d records"), device_library_.size());
|
LOG_INFO(F("EMS Device library loaded with %d records"), device_library_.size());
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
|
||||||
#ifndef EMSESP_STANDALONE
|
|
||||||
LOG_INFO(F("Used %d mem for devices"), tbefore - tafter);
|
|
||||||
System::show_mem("after start()");
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(EMSESP_STANDALONE)
|
#if defined(EMSESP_STANDALONE)
|
||||||
Mqtt::on_connect(); // simulate an MQTT connection
|
Mqtt::on_connect(); // simulate an MQTT connection
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
#include "WebSettingsService.h"
|
#include "WebSettingsService.h"
|
||||||
#include "WebAPIService.h"
|
#include "WebAPIService.h"
|
||||||
|
|
||||||
// #include "containers.h"
|
|
||||||
#include "emsdevice.h"
|
#include "emsdevice.h"
|
||||||
#include "emsfactory.h"
|
#include "emsfactory.h"
|
||||||
#include "telegram.h"
|
#include "telegram.h"
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ MAKE_PSTR_WORD(unknown)
|
|||||||
MAKE_PSTR(EMSESP, "EMS-ESP")
|
MAKE_PSTR(EMSESP, "EMS-ESP")
|
||||||
MAKE_PSTR(master_thermostat_fmt, "Master Thermostat Device ID = %s")
|
MAKE_PSTR(master_thermostat_fmt, "Master Thermostat Device ID = %s")
|
||||||
MAKE_PSTR(host_fmt, "Host = %s")
|
MAKE_PSTR(host_fmt, "Host = %s")
|
||||||
MAKE_PSTR(hostname_fmt, "WiFi Hostname = %s")
|
MAKE_PSTR(hostname_fmt, "Hostname = %s")
|
||||||
MAKE_PSTR(mark_interval_fmt, "Mark interval = %lus")
|
MAKE_PSTR(mark_interval_fmt, "Mark interval = %lus")
|
||||||
MAKE_PSTR(wifi_ssid_fmt, "WiFi SSID = %s")
|
MAKE_PSTR(wifi_ssid_fmt, "WiFi SSID = %s")
|
||||||
MAKE_PSTR(wifi_password_fmt, "WiFi Password = %S")
|
MAKE_PSTR(wifi_password_fmt, "WiFi Password = %S")
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ void Mqtt::start() {
|
|||||||
mqttClient_ = EMSESP::esp8266React.getMqttClient();
|
mqttClient_ = EMSESP::esp8266React.getMqttClient();
|
||||||
|
|
||||||
// get the hostname, which we'll use to prefix to all topics
|
// get the hostname, which we'll use to prefix to all topics
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & wifiSettings) { hostname_ = wifiSettings.hostname.c_str(); });
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { hostname_ = networkSettings.hostname.c_str(); });
|
||||||
|
|
||||||
// fetch MQTT settings, to see if MQTT is enabled
|
// fetch MQTT settings, to see if MQTT is enabled
|
||||||
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & mqttSettings) {
|
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & mqttSettings) {
|
||||||
|
|||||||
165
src/system.cpp
165
src/system.cpp
@@ -107,9 +107,9 @@ void System::restart() {
|
|||||||
void System::wifi_reconnect() {
|
void System::wifi_reconnect() {
|
||||||
LOG_INFO(F("Wifi reconnecting..."));
|
LOG_INFO(F("Wifi reconnecting..."));
|
||||||
Shell::loop_all();
|
Shell::loop_all();
|
||||||
delay(1000); // wait a second
|
delay(1000); // wait a second
|
||||||
EMSESP::webSettingsService.save(); // local settings
|
EMSESP::webSettingsService.save(); // local settings
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->callUpdateHandlers("local"); // in case we've changed ssid or password
|
EMSESP::esp8266React.getNetworkSettingsService()->callUpdateHandlers("local"); // in case we've changed ssid or password
|
||||||
}
|
}
|
||||||
|
|
||||||
// format fs
|
// format fs
|
||||||
@@ -164,7 +164,7 @@ void System::syslog_init() {
|
|||||||
syslog_.log_level((uuid::log::Level)syslog_level_);
|
syslog_.log_level((uuid::log::Level)syslog_level_);
|
||||||
syslog_.mark_interval(syslog_mark_interval_);
|
syslog_.mark_interval(syslog_mark_interval_);
|
||||||
syslog_.destination(addr);
|
syslog_.destination(addr);
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & wifiSettings) { syslog_.hostname(wifiSettings.hostname.c_str()); });
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { syslog_.hostname(networkSettings.hostname.c_str()); });
|
||||||
|
|
||||||
EMSESP::logger().info(F("Syslog started"));
|
EMSESP::logger().info(F("Syslog started"));
|
||||||
#endif
|
#endif
|
||||||
@@ -182,7 +182,7 @@ void System::start(uint32_t heap_start) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// print boot message
|
// print boot message
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & wifiSettings) { LOG_INFO(F("System %s booted (EMS-ESP version %s)"), wifiSettings.hostname.c_str(), EMSESP_APP_VERSION); });
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { LOG_INFO(F("System %s booted (EMS-ESP version %s)"), networkSettings.hostname.c_str(), EMSESP_APP_VERSION); });
|
||||||
|
|
||||||
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
||||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||||
@@ -198,6 +198,42 @@ void System::start(uint32_t heap_start) {
|
|||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// check ethernet profile, if we're using exclusive Ethernet then disabled wifi and AP/captive portal
|
||||||
|
uint8_t ethernet_profile;
|
||||||
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & settings) { ethernet_profile = settings.ethernet_profile; });
|
||||||
|
|
||||||
|
#ifndef EMSESP_STANDALONE
|
||||||
|
uint8_t phy_addr = 0; // I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
|
||||||
|
int power = -1; // Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
|
||||||
|
int mdc = 23; // Pin# of the I²C clock signal for the Ethernet PHY
|
||||||
|
int mdio = 18; // Pin# of the I²C IO signal for the Ethernet PHY
|
||||||
|
eth_phy_type_t type = ETH_PHY_LAN8720; // Type of the Ethernet PHY (LAN8720 or TLK110)
|
||||||
|
eth_clock_mode_t clock_mode = ETH_CLOCK_GPIO0_IN; // ETH_CLOCK_GPIO0_IN or ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT for 50Hz inverted clock
|
||||||
|
|
||||||
|
// see if we can start it using default settings
|
||||||
|
if (!ETH.begin(phy_addr, power, mdc, mdio, type, clock_mode)) {
|
||||||
|
// it failed. Now try again based on profile. 0 is the same as 1. 2 is for TLK110
|
||||||
|
if (ethernet_profile == 2) {
|
||||||
|
if (ETH.begin(31, power, mdc, mdio, ETH_PHY_TLK110, clock_mode)) {
|
||||||
|
EMSESP::esp8266React.getNetworkSettingsService()->update(
|
||||||
|
[&](NetworkSettings & settings) {
|
||||||
|
settings.ssid == ""; // remove SSID
|
||||||
|
return StateUpdateResult::CHANGED;
|
||||||
|
},
|
||||||
|
"local");
|
||||||
|
|
||||||
|
EMSESP::esp8266React.getAPSettingsService()->update(
|
||||||
|
[&](APSettings & settings) {
|
||||||
|
settings.provisionMode = AP_MODE_NEVER;
|
||||||
|
return StateUpdateResult::CHANGED;
|
||||||
|
},
|
||||||
|
"local");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// continue with init'ing services
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,9 +253,9 @@ void System::init() {
|
|||||||
|
|
||||||
syslog_init(); // init SysLog
|
syslog_init(); // init SysLog
|
||||||
|
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & settings) { hostname(settings.hostname.c_str()); });
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & settings) { hostname(settings.hostname.c_str()); });
|
||||||
|
|
||||||
#if defined(ESP32)
|
#ifndef EMSESP_STANDALONE
|
||||||
// setCpuFrequencyMhz(160); // default is 240
|
// setCpuFrequencyMhz(160); // default is 240
|
||||||
|
|
||||||
// disable bluetooth
|
// disable bluetooth
|
||||||
@@ -288,7 +324,7 @@ void System::loop() {
|
|||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
static uint32_t last_memcheck_ = 0;
|
static uint32_t last_memcheck_ = 0;
|
||||||
if (currentMillis - last_memcheck_ > 5000) { // 5 seconds
|
if (currentMillis - last_memcheck_ > 10000) { // 10 seconds
|
||||||
last_memcheck_ = currentMillis;
|
last_memcheck_ = currentMillis;
|
||||||
show_mem("core");
|
show_mem("core");
|
||||||
}
|
}
|
||||||
@@ -391,32 +427,9 @@ void System::set_led_speed(uint32_t speed) {
|
|||||||
led_monitor();
|
led_monitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::init_wifi() {
|
void System::init_network() {
|
||||||
last_system_check_ = 0; // force the LED to go from fast flash to pulse
|
last_system_check_ = 0; // force the LED to go from fast flash to pulse
|
||||||
send_heartbeat();
|
send_heartbeat();
|
||||||
|
|
||||||
#if defined(ESP32)
|
|
||||||
// TODO wifi tx power
|
|
||||||
/*
|
|
||||||
WIFI_POWER_19_5dBm = 78,// 19.5dBm
|
|
||||||
WIFI_POWER_19dBm = 76,// 19dBm
|
|
||||||
WIFI_POWER_18_5dBm = 74,// 18.5dBm
|
|
||||||
WIFI_POWER_17dBm = 68,// 17dBm
|
|
||||||
WIFI_POWER_15dBm = 60,// 15dBm
|
|
||||||
WIFI_POWER_13dBm = 52,// 13dBm
|
|
||||||
WIFI_POWER_11dBm = 44,// 11dBm
|
|
||||||
WIFI_POWER_8_5dBm = 34,// 8.5dBm
|
|
||||||
WIFI_POWER_7dBm = 28,// 7dBm
|
|
||||||
WIFI_POWER_5dBm = 20,// 5dBm
|
|
||||||
WIFI_POWER_2dBm = 8,// 2dBm
|
|
||||||
WIFI_POWER_MINUS_1dBm = -4// -1dBm
|
|
||||||
*/
|
|
||||||
// wifi_power_t a1 = WiFi.getTxPower();
|
|
||||||
// // bool ok = WiFi.setTxPower(WIFI_POWER_17dBm);
|
|
||||||
// bool ok = true;
|
|
||||||
// wifi_power_t a2 = WiFi.getTxPower();
|
|
||||||
// LOG_INFO("Wifi Tx power was %d, is now %d, ok=%s", a1, a2, ok ? "ok" : "failed");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check health of system, done every few seconds
|
// check health of system, done every few seconds
|
||||||
@@ -512,28 +525,9 @@ void System::show_system(uuid::console::Shell & shell) {
|
|||||||
shell.printfln(F("Uptime: %s"), uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3).c_str());
|
shell.printfln(F("Uptime: %s"), uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3).c_str());
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
#if defined(ESP8266)
|
|
||||||
shell.printfln(F("Chip ID: 0x%08x"), ESP.getChipId());
|
|
||||||
shell.printfln(F("SDK version: %s"), ESP.getSdkVersion());
|
|
||||||
shell.printfln(F("Core version: %s"), ESP.getCoreVersion().c_str());
|
|
||||||
shell.printfln(F("Full version: %s"), ESP.getFullVersion().c_str());
|
|
||||||
shell.printfln(F("Boot version: %u"), ESP.getBootVersion());
|
|
||||||
shell.printfln(F("Boot mode: %u"), ESP.getBootMode());
|
|
||||||
shell.printfln(F("CPU frequency: %u MHz"), ESP.getCpuFreqMHz());
|
|
||||||
shell.printfln(F("Flash chip: 0x%08X (%u bytes)"), ESP.getFlashChipId(), ESP.getFlashChipRealSize());
|
|
||||||
shell.printfln(F("Reset reason: %s"), ESP.getResetReason().c_str());
|
|
||||||
shell.printfln(F("Reset info: %s"), ESP.getResetInfo().c_str());
|
|
||||||
#elif defined(ESP32)
|
|
||||||
shell.printfln(F("SDK version: %s"), ESP.getSdkVersion());
|
shell.printfln(F("SDK version: %s"), ESP.getSdkVersion());
|
||||||
shell.printfln(F("CPU frequency: %u MHz"), ESP.getCpuFreqMHz());
|
shell.printfln(F("CPU frequency: %u MHz"), ESP.getCpuFreqMHz());
|
||||||
#endif
|
|
||||||
shell.printfln(F("Sketch size: %u bytes (%u bytes free)"), ESP.getSketchSize(), ESP.getFreeSketchSpace());
|
|
||||||
shell.printfln(F("Free heap: %lu bytes"), (uint32_t)ESP.getFreeHeap());
|
shell.printfln(F("Free heap: %lu bytes"), (uint32_t)ESP.getFreeHeap());
|
||||||
#if defined(ESP8266)
|
|
||||||
shell.printfln(F("Heap fragmentation: %u %%"), ESP.getHeapFragmentation());
|
|
||||||
shell.printfln(F("Maximum free block size: %lu bytes"), (uint32_t)ESP.getMaxFreeBlockSize());
|
|
||||||
shell.printfln(F("Free continuations stack: %lu bytes"), (uint32_t)ESP.getFreeContStack());
|
|
||||||
#endif
|
|
||||||
shell.println();
|
shell.println();
|
||||||
|
|
||||||
switch (WiFi.status()) {
|
switch (WiFi.status()) {
|
||||||
@@ -555,12 +549,7 @@ void System::show_system(uuid::console::Shell & shell) {
|
|||||||
shell.printfln(F("BSSID: %s"), WiFi.BSSIDstr().c_str());
|
shell.printfln(F("BSSID: %s"), WiFi.BSSIDstr().c_str());
|
||||||
shell.printfln(F("RSSI: %d dBm (%d %%)"), WiFi.RSSI(), wifi_quality());
|
shell.printfln(F("RSSI: %d dBm (%d %%)"), WiFi.RSSI(), wifi_quality());
|
||||||
shell.printfln(F("MAC address: %s"), WiFi.macAddress().c_str());
|
shell.printfln(F("MAC address: %s"), WiFi.macAddress().c_str());
|
||||||
|
|
||||||
#if defined(ESP8266)
|
|
||||||
shell.printfln(F("Hostname: %s"), WiFi.hostname().c_str());
|
|
||||||
#elif defined(ESP32)
|
|
||||||
shell.printfln(F("Hostname: %s"), WiFi.getHostname());
|
shell.printfln(F("Hostname: %s"), WiFi.getHostname());
|
||||||
#endif
|
|
||||||
shell.printfln(F("IPv4 address: %s/%s"), uuid::printable_to_string(WiFi.localIP()).c_str(), uuid::printable_to_string(WiFi.subnetMask()).c_str());
|
shell.printfln(F("IPv4 address: %s/%s"), uuid::printable_to_string(WiFi.localIP()).c_str(), uuid::printable_to_string(WiFi.subnetMask()).c_str());
|
||||||
shell.printfln(F("IPv4 gateway: %s"), uuid::printable_to_string(WiFi.gatewayIP()).c_str());
|
shell.printfln(F("IPv4 gateway: %s"), uuid::printable_to_string(WiFi.gatewayIP()).c_str());
|
||||||
shell.printfln(F("IPv4 nameserver: %s"), uuid::printable_to_string(WiFi.dnsIP()).c_str());
|
shell.printfln(F("IPv4 nameserver: %s"), uuid::printable_to_string(WiFi.dnsIP()).c_str());
|
||||||
@@ -584,6 +573,20 @@ void System::show_system(uuid::console::Shell & shell) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shell.println();
|
||||||
|
|
||||||
|
// show Ethernet
|
||||||
|
if (ETH.linkUp()) {
|
||||||
|
shell.printfln(F("Ethernet: Connected"));
|
||||||
|
shell.printfln(F("MAC address: %s"), ETH.macAddress().c_str());
|
||||||
|
shell.printfln(F("Hostname: %s"), ETH.getHostname());
|
||||||
|
shell.printfln(F("IPv4 address: %s/%s"), uuid::printable_to_string(ETH.localIP()).c_str(), uuid::printable_to_string(ETH.subnetMask()).c_str());
|
||||||
|
shell.printfln(F("IPv4 gateway: %s"), uuid::printable_to_string(ETH.gatewayIP()).c_str());
|
||||||
|
shell.printfln(F("IPv4 nameserver: %s"), uuid::printable_to_string(ETH.dnsIP()).c_str());
|
||||||
|
} else {
|
||||||
|
shell.printfln(F("Ethernet: disconnected"));
|
||||||
|
}
|
||||||
|
|
||||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||||
shell.println();
|
shell.println();
|
||||||
|
|
||||||
@@ -658,15 +661,15 @@ void System::console_commands(Shell & shell, unsigned int context) {
|
|||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::SYSTEM,
|
EMSESPShell::commands->add_command(ShellContext::SYSTEM,
|
||||||
CommandFlags::ADMIN,
|
CommandFlags::ADMIN,
|
||||||
flash_string_vector{F_(set), F_(wifi), F_(hostname)},
|
flash_string_vector{F_(set), F_(hostname)},
|
||||||
flash_string_vector{F_(name_mandatory)},
|
flash_string_vector{F_(name_mandatory)},
|
||||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||||
shell.println("The wifi connection will be reset...");
|
shell.println("The network connection will be reset...");
|
||||||
Shell::loop_all();
|
Shell::loop_all();
|
||||||
delay(1000); // wait a second
|
delay(1000); // wait a second
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->update(
|
EMSESP::esp8266React.getNetworkSettingsService()->update(
|
||||||
[&](WiFiSettings & wifiSettings) {
|
[&](NetworkSettings & networkSettings) {
|
||||||
wifiSettings.hostname = arguments.front().c_str();
|
networkSettings.hostname = arguments.front().c_str();
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
},
|
},
|
||||||
"local");
|
"local");
|
||||||
@@ -677,8 +680,8 @@ void System::console_commands(Shell & shell, unsigned int context) {
|
|||||||
flash_string_vector{F_(set), F_(wifi), F_(ssid)},
|
flash_string_vector{F_(set), F_(wifi), F_(ssid)},
|
||||||
flash_string_vector{F_(name_mandatory)},
|
flash_string_vector{F_(name_mandatory)},
|
||||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->updateWithoutPropagation([&](WiFiSettings & wifiSettings) {
|
EMSESP::esp8266React.getNetworkSettingsService()->updateWithoutPropagation([&](NetworkSettings & networkSettings) {
|
||||||
wifiSettings.ssid = arguments.front().c_str();
|
networkSettings.ssid = arguments.front().c_str();
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
});
|
});
|
||||||
shell.println("Use `wifi reconnect` to apply the new settings");
|
shell.println("Use `wifi reconnect` to apply the new settings");
|
||||||
@@ -690,8 +693,8 @@ void System::console_commands(Shell & shell, unsigned int context) {
|
|||||||
shell.enter_password(F_(new_password_prompt2), [password1](Shell & shell, bool completed, const std::string & password2) {
|
shell.enter_password(F_(new_password_prompt2), [password1](Shell & shell, bool completed, const std::string & password2) {
|
||||||
if (completed) {
|
if (completed) {
|
||||||
if (password1 == password2) {
|
if (password1 == password2) {
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->updateWithoutPropagation([&](WiFiSettings & wifiSettings) {
|
EMSESP::esp8266React.getNetworkSettingsService()->updateWithoutPropagation([&](NetworkSettings & networkSettings) {
|
||||||
wifiSettings.password = password2.c_str();
|
networkSettings.password = password2.c_str();
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
});
|
});
|
||||||
shell.println("Use `wifi reconnect` to apply the new settings");
|
shell.println("Use `wifi reconnect` to apply the new settings");
|
||||||
@@ -705,16 +708,16 @@ void System::console_commands(Shell & shell, unsigned int context) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::SYSTEM, CommandFlags::USER, flash_string_vector{F_(set)}, [](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
EMSESPShell::commands->add_command(ShellContext::SYSTEM, CommandFlags::USER, flash_string_vector{F_(set)}, [](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & wifiSettings) {
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) {
|
||||||
shell.print(F(" "));
|
shell.print(F(" "));
|
||||||
shell.printfln(F_(hostname_fmt), wifiSettings.hostname.isEmpty() ? uuid::read_flash_string(F_(unset)).c_str() : wifiSettings.hostname.c_str());
|
shell.printfln(F_(hostname_fmt), networkSettings.hostname.isEmpty() ? uuid::read_flash_string(F_(unset)).c_str() : networkSettings.hostname.c_str());
|
||||||
});
|
});
|
||||||
|
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & wifiSettings) {
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) {
|
||||||
shell.print(F(" "));
|
shell.print(F(" "));
|
||||||
shell.printfln(F_(wifi_ssid_fmt), wifiSettings.ssid.isEmpty() ? uuid::read_flash_string(F_(unset)).c_str() : wifiSettings.ssid.c_str());
|
shell.printfln(F_(wifi_ssid_fmt), networkSettings.ssid.isEmpty() ? uuid::read_flash_string(F_(unset)).c_str() : networkSettings.ssid.c_str());
|
||||||
shell.print(F(" "));
|
shell.print(F(" "));
|
||||||
shell.printfln(F_(wifi_password_fmt), wifiSettings.ssid.isEmpty() ? F_(unset) : F_(asterisks));
|
shell.printfln(F_(wifi_password_fmt), networkSettings.ssid.isEmpty() ? F_(unset) : F_(asterisks));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -802,17 +805,17 @@ bool System::check_upgrade() {
|
|||||||
EMSESP::esp8266React.begin();
|
EMSESP::esp8266React.begin();
|
||||||
EMSESP::webSettingsService.begin();
|
EMSESP::webSettingsService.begin();
|
||||||
|
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->update(
|
EMSESP::esp8266React.getNetworkSettingsService()->update(
|
||||||
[&](WiFiSettings & wifiSettings) {
|
[&](NetworkSettings & networkSettings) {
|
||||||
wifiSettings.hostname = general["hostname"] | FACTORY_WIFI_HOSTNAME;
|
networkSettings.hostname = general["hostname"] | FACTORY_WIFI_HOSTNAME;
|
||||||
wifiSettings.ssid = network["ssid"] | FACTORY_WIFI_SSID;
|
networkSettings.ssid = network["ssid"] | FACTORY_WIFI_SSID;
|
||||||
wifiSettings.password = network["password"] | FACTORY_WIFI_PASSWORD;
|
networkSettings.password = network["password"] | FACTORY_WIFI_PASSWORD;
|
||||||
|
|
||||||
wifiSettings.staticIPConfig = false;
|
networkSettings.staticIPConfig = false;
|
||||||
JsonUtils::readIP(network, "staticip", wifiSettings.localIP);
|
JsonUtils::readIP(network, "staticip", networkSettings.localIP);
|
||||||
JsonUtils::readIP(network, "dnsip", wifiSettings.dnsIP1);
|
JsonUtils::readIP(network, "dnsip", networkSettings.dnsIP1);
|
||||||
JsonUtils::readIP(network, "gatewayip", wifiSettings.gatewayIP);
|
JsonUtils::readIP(network, "gatewayip", networkSettings.gatewayIP);
|
||||||
JsonUtils::readIP(network, "nmask", wifiSettings.subnetMask);
|
JsonUtils::readIP(network, "nmask", networkSettings.subnetMask);
|
||||||
|
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
},
|
},
|
||||||
@@ -922,7 +925,7 @@ bool System::check_upgrade() {
|
|||||||
// e.g. http://ems-esp/api?device=system&cmd=settings
|
// e.g. http://ems-esp/api?device=system&cmd=settings
|
||||||
// value and id are ignored
|
// value and id are ignored
|
||||||
bool System::command_settings(const char * value, const int8_t id, JsonObject & json) {
|
bool System::command_settings(const char * value, const int8_t id, JsonObject & json) {
|
||||||
EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & settings) {
|
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & settings) {
|
||||||
JsonObject node = json.createNestedObject("WIFI");
|
JsonObject node = json.createNestedObject("WIFI");
|
||||||
node["ssid"] = settings.ssid;
|
node["ssid"] = settings.ssid;
|
||||||
// node["password"] = settings.password;
|
// node["password"] = settings.password;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class System {
|
|||||||
static void upload_status(bool in_progress);
|
static void upload_status(bool in_progress);
|
||||||
static bool upload_status();
|
static bool upload_status();
|
||||||
static void show_mem(const char * note);
|
static void show_mem(const char * note);
|
||||||
void init_wifi();
|
void init_network();
|
||||||
static void init();
|
static void init();
|
||||||
static void led_init();
|
static void led_init();
|
||||||
static void syslog_init();
|
static void syslog_init();
|
||||||
|
|||||||
Reference in New Issue
Block a user