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.

121 lines
3.6 KiB

  1. import React, { Component } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { SCAN_NETWORKS_ENDPOINT, LIST_NETWORKS_ENDPOINT } from '../constants/Endpoints';
  4. import SectionContent from '../components/SectionContent';
  5. import WiFiNetworkSelector from '../forms/WiFiNetworkSelector';
  6. import {withNotifier} from '../components/SnackbarNotification';
  7. const NUM_POLLS = 10
  8. const POLLING_FREQUENCY = 500
  9. const RETRY_EXCEPTION_TYPE = "retry"
  10. class WiFiNetworkScanner extends Component {
  11. constructor(props) {
  12. super(props);
  13. this.pollCount = 0;
  14. this.state = {
  15. scanningForNetworks: true,
  16. errorMessage:null,
  17. networkList: null
  18. };
  19. this.pollNetworkList = this.pollNetworkList.bind(this);
  20. this.requestNetworkScan = this.requestNetworkScan.bind(this);
  21. }
  22. componentDidMount() {
  23. this.scanNetworks();
  24. }
  25. requestNetworkScan() {
  26. const { scanningForNetworks } = this.state;
  27. if (!scanningForNetworks) {
  28. this.scanNetworks();
  29. }
  30. }
  31. scanNetworks() {
  32. this.pollCount = 0;
  33. this.setState({scanningForNetworks:true, networkList: null, errorMessage:null});
  34. fetch(SCAN_NETWORKS_ENDPOINT).then(response => {
  35. if (response.status === 202) {
  36. this.schedulePollTimeout();
  37. return;
  38. }
  39. throw Error("Scanning for networks returned unexpected response code: " + response.status);
  40. }).catch(error => {
  41. this.props.raiseNotification("Problem scanning: " + error.message);
  42. this.setState({scanningForNetworks:false, networkList: null, errorMessage:error.message});
  43. });
  44. }
  45. schedulePollTimeout() {
  46. setTimeout(this.pollNetworkList, POLLING_FREQUENCY);
  47. }
  48. retryError() {
  49. return {
  50. name:RETRY_EXCEPTION_TYPE,
  51. message:"Network list not ready, will retry in " + POLLING_FREQUENCY + "ms."
  52. };
  53. }
  54. compareNetworks(network1,network2) {
  55. if (network1.rssi < network2.rssi)
  56. return 1;
  57. if (network1.rssi > network2.rssi)
  58. return -1;
  59. return 0;
  60. }
  61. pollNetworkList() {
  62. fetch(LIST_NETWORKS_ENDPOINT)
  63. .then(response => {
  64. if (response.status === 200) {
  65. return response.json();
  66. }
  67. if (response.status === 202) {
  68. if (++this.pollCount < NUM_POLLS){
  69. this.schedulePollTimeout();
  70. throw this.retryError();
  71. }else{
  72. throw Error("Device did not return network list in timely manner.");
  73. }
  74. }
  75. throw Error("Device returned unexpected response code: " + response.status);
  76. })
  77. .then(json => {
  78. json.networks.sort(this.compareNetworks)
  79. this.setState({scanningForNetworks:false, networkList: json, errorMessage:null})
  80. })
  81. .catch(error => {
  82. console.log(error.message);
  83. if (error.name !== RETRY_EXCEPTION_TYPE) {
  84. this.props.raiseNotification("Problem scanning: " + error.message);
  85. this.setState({scanningForNetworks:false, networkList: null, errorMessage:error.message});
  86. }
  87. });
  88. }
  89. render() {
  90. const { scanningForNetworks, networkList, errorMessage } = this.state;
  91. return (
  92. <SectionContent title="Network Scanner">
  93. <WiFiNetworkSelector scanningForNetworks={scanningForNetworks}
  94. networkList={networkList}
  95. errorMessage={errorMessage}
  96. requestNetworkScan={this.requestNetworkScan}
  97. selectNetwork={this.props.selectNetwork}
  98. />
  99. </SectionContent>
  100. )
  101. }
  102. }
  103. WiFiNetworkScanner.propTypes = {
  104. selectNetwork: PropTypes.func.isRequired
  105. };
  106. export default withNotifier(WiFiNetworkScanner);