Fork of the excellent esp8266-react - https://github.com/rjwats/esp8266-react
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

125 lines
3.7 KiB

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { SCAN_NETWORKS_ENDPOINT, LIST_NETWORKS_ENDPOINT } from '../constants/Endpoints';
import SectionContent from '../components/SectionContent';
import WiFiNetworkSelector from '../forms/WiFiNetworkSelector';
import { withSnackbar } from 'notistack';
import { redirectingAuthorizedFetch } from '../authentication/Authentication';
const NUM_POLLS = 10
const POLLING_FREQUENCY = 500
const RETRY_EXCEPTION_TYPE = "retry"
class WiFiNetworkScanner extends Component {
constructor(props) {
super(props);
this.pollCount = 0;
this.state = {
scanningForNetworks: true,
errorMessage: null,
networkList: null
};
this.pollNetworkList = this.pollNetworkList.bind(this);
this.requestNetworkScan = this.requestNetworkScan.bind(this);
}
componentDidMount() {
this.scanNetworks();
}
requestNetworkScan() {
const { scanningForNetworks } = this.state;
if (!scanningForNetworks) {
this.scanNetworks();
}
}
scanNetworks() {
this.pollCount = 0;
this.setState({ scanningForNetworks: true, networkList: null, errorMessage: null });
redirectingAuthorizedFetch(SCAN_NETWORKS_ENDPOINT).then(response => {
if (response.status === 202) {
this.schedulePollTimeout();
return;
}
throw Error("Scanning for networks returned unexpected response code: " + response.status);
}).catch(error => {
this.props.enqueueSnackbar("Problem scanning: " + error.message, {
variant: 'error',
});
this.setState({ scanningForNetworks: false, networkList: null, errorMessage: error.message });
});
}
schedulePollTimeout() {
setTimeout(this.pollNetworkList, POLLING_FREQUENCY);
}
retryError() {
return {
name: RETRY_EXCEPTION_TYPE,
message: "Network list not ready, will retry in " + POLLING_FREQUENCY + "ms."
};
}
compareNetworks(network1, network2) {
if (network1.rssi < network2.rssi)
return 1;
if (network1.rssi > network2.rssi)
return -1;
return 0;
}
pollNetworkList() {
redirectingAuthorizedFetch(LIST_NETWORKS_ENDPOINT)
.then(response => {
if (response.status === 200) {
return response.json();
}
if (response.status === 202) {
if (++this.pollCount < NUM_POLLS) {
this.schedulePollTimeout();
throw this.retryError();
} else {
throw Error("Device did not return network list in timely manner.");
}
}
throw Error("Device returned unexpected response code: " + response.status);
})
.then(json => {
json.networks.sort(this.compareNetworks)
this.setState({ scanningForNetworks: false, networkList: json, errorMessage: null })
})
.catch(error => {
if (error.name !== RETRY_EXCEPTION_TYPE) {
this.props.enqueueSnackbar("Problem scanning: " + error.message, {
variant: 'error',
});
this.setState({ scanningForNetworks: false, networkList: null, errorMessage: error.message });
}
});
}
render() {
const { scanningForNetworks, networkList, errorMessage } = this.state;
return (
<SectionContent title="Network Scanner">
<WiFiNetworkSelector scanningForNetworks={scanningForNetworks}
networkList={networkList}
errorMessage={errorMessage}
requestNetworkScan={this.requestNetworkScan}
selectNetwork={this.props.selectNetwork}
/>
</SectionContent>
)
}
}
WiFiNetworkScanner.propTypes = {
selectNetwork: PropTypes.func.isRequired
};
export default withSnackbar(WiFiNetworkScanner);