From 76e4a32ef2fa2a6e0b42a192a26bfabac90d2fa5 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 6 Jul 2020 22:35:57 +0200 Subject: [PATCH] added scan devices button to web - (v2) New Web UI #421 --- interface/src/project/EMSESPDevicesForm.tsx | 99 +++++++++++++++++---- src/EMSESPDevicesService.h | 7 +- src/EMSESPScanDevicesService.cpp | 20 +++++ src/EMSESPScanDevicesService.h | 21 +++++ src/console.cpp | 2 +- src/emsesp.cpp | 2 + src/emsesp.h | 14 +-- 7 files changed, 137 insertions(+), 28 deletions(-) create mode 100644 src/EMSESPScanDevicesService.cpp create mode 100644 src/EMSESPScanDevicesService.h diff --git a/interface/src/project/EMSESPDevicesForm.tsx b/interface/src/project/EMSESPDevicesForm.tsx index 4a17bbaaa..5ad32f2c0 100644 --- a/interface/src/project/EMSESPDevicesForm.tsx +++ b/interface/src/project/EMSESPDevicesForm.tsx @@ -9,23 +9,25 @@ import { List, withWidth, WithWidthProps, - isWidthDown + isWidthDown, + Button, + DialogTitle, DialogContent, DialogActions, Box, Dialog, Typography } from "@material-ui/core"; -import { Box, Typography } from '@material-ui/core'; - import RefreshIcon from "@material-ui/icons/Refresh"; -import { withAuthenticatedContext, AuthenticatedContextProps } from '../authentication'; +import { redirectingAuthorizedFetch, withAuthenticatedContext, AuthenticatedContextProps } from '../authentication'; import { RestFormProps, - FormActions, FormButton, } from "../components"; import { EMSESPDevices, Device } from "./types"; +import { ENDPOINT_ROOT } from '../api'; +export const SCANDEVICES_ENDPOINT = ENDPOINT_ROOT + "scanDevices"; + function compareDevices(a: Device, b: Device) { if (a.type < b.type) { return -1; @@ -36,9 +38,19 @@ function compareDevices(a: Device, b: Device) { return 0; } +interface EMSESPDevicesFormState { + confirmScanDevices: boolean; + processing: boolean; +} + type EMSESPDevicesFormProps = RestFormProps & AuthenticatedContextProps & WithWidthProps; -class EMSESPDevicesForm extends Component { +class EMSESPDevicesForm extends Component { + + state: EMSESPDevicesFormState = { + confirmScanDevices: false, + processing: false + } noData = () => { return (this.props.data.devices.length === 0); @@ -97,25 +109,76 @@ class EMSESPDevicesForm extends Component { ); } + renderScanDevicesDialog() { + return ( + + Confirm Scan Devices + + Are you sure you want to scan the EMS bus for all new devices? + + + + + + + ) + } + + onScanDevices = () => { + this.setState({ confirmScanDevices: true }); + } + + onScanDevicesRejected = () => { + this.setState({ confirmScanDevices: false }); + } + + onScanDevicesConfirmed = () => { + this.setState({ processing: true }); + redirectingAuthorizedFetch(SCANDEVICES_ENDPOINT, { method: 'POST' }) + .then(response => { + if (response.status === 200) { + this.props.enqueueSnackbar("Device scan is starting...", { variant: 'info' }); + this.setState({ processing: false, confirmScanDevices: false }); + } else { + throw Error("Invalid status code: " + response.status); + } + }) + .catch(error => { + this.props.enqueueSnackbar(error.message || "Problem with scan", { variant: 'error' }); + this.setState({ processing: false, confirmScanDevices: false }); + }); + } + render() { return ( {this.createListItems()} - - } - variant="contained" - color="secondary" - onClick={this.props.loadData} - > - Refresh - - + + + + } variant="contained" color="secondary" onClick={this.props.loadData}> + Refresh + + + + + } variant="contained" color="primary" onClick={this.onScanDevices}> + Scan Devices + + + + {this.renderScanDevicesDialog()} ); } + } export default withAuthenticatedContext(withWidth()(EMSESPDevicesForm)); - -// export default withTheme(EMSESPDevicesForm); diff --git a/src/EMSESPDevicesService.h b/src/EMSESPDevicesService.h index fe88b1c2d..02f7187f1 100644 --- a/src/EMSESPDevicesService.h +++ b/src/EMSESPDevicesService.h @@ -6,11 +6,10 @@ #include #include -#include -#include -#include +// #include +// #include +// #include -#include "EMSESPSettingsService.h" #include "version.h" #define MAX_EMSESP_STATUS_SIZE 1024 diff --git a/src/EMSESPScanDevicesService.cpp b/src/EMSESPScanDevicesService.cpp new file mode 100644 index 000000000..0abb917be --- /dev/null +++ b/src/EMSESPScanDevicesService.cpp @@ -0,0 +1,20 @@ +#include + +#include "emsesp.h" + +namespace emsesp { + +EMSESPScanDevicesService::EMSESPScanDevicesService(AsyncWebServer * server, SecurityManager * securityManager) { + server->on(SCAN_DEVICES_SERVICE_PATH, + HTTP_POST, + securityManager->wrapRequest(std::bind(&EMSESPScanDevicesService::scan_devices, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN)); +} + +void EMSESPScanDevicesService::scan_devices(AsyncWebServerRequest * request) { + request->onDisconnect([]() { + EMSESP::send_read_request(EMSdevice::EMS_TYPE_UBADevices, EMSdevice::EMS_DEVICE_ID_BOILER); + }); + request->send(200); +} + +} // namespace emsesp diff --git a/src/EMSESPScanDevicesService.h b/src/EMSESPScanDevicesService.h new file mode 100644 index 000000000..0b3a873e4 --- /dev/null +++ b/src/EMSESPScanDevicesService.h @@ -0,0 +1,21 @@ +#ifndef EMSESPScanDevicesService_h +#define EMSESPScanDevicesService_h + +#include +#include + +#define SCAN_DEVICES_SERVICE_PATH "/rest/scanDevices" + +namespace emsesp { + +class EMSESPScanDevicesService { + public: + EMSESPScanDevicesService(AsyncWebServer * server, SecurityManager * securityManager); + + private: + void scan_devices(AsyncWebServerRequest * request); +}; + +} // namespace emsesp + +#endif diff --git a/src/console.cpp b/src/console.cpp index e5358d81b..5d84061f7 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -196,7 +196,7 @@ void EMSESPShell::add_console_commands() { if (arguments.size() == 0) { EMSESP::send_read_request(EMSdevice::EMS_TYPE_UBADevices, EMSdevice::EMS_DEVICE_ID_BOILER); } else { - shell.printfln(F("Performing a deep scan by pinging our device library...")); + shell.printfln(F("Performing a deep scan...")); std::vector Device_Ids; Device_Ids.push_back(0x08); // Boilers - 0x08 diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 638c2b92e..f7a957dce 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -40,6 +40,8 @@ EMSESPStatusService EMSESP::emsespStatusService = EMSESPDevicesService EMSESP::emsespDevicesService = EMSESPDevicesService(&webServer, EMSESP::esp8266React.getSecurityManager()); +EMSESPScanDevicesService EMSESP::emsespScanDevicesService = EMSESPScanDevicesService(&webServer, EMSESP::esp8266React.getSecurityManager()); + std::vector> EMSESP::emsdevices; // array of all the detected EMS devices std::vector EMSESP::device_library_; // libary of all our known EMS devices so far diff --git a/src/emsesp.h b/src/emsesp.h index 50c8f5bb1..145f2c43f 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -37,6 +37,7 @@ #include "EMSESPStatusService.h" #include "EMSESPDevicesService.h" #include "EMSESPSettingsService.h" +#include "EMSESPScanDevicesService.h" #include "emsdevice.h" #include "emsfactory.h" @@ -136,6 +137,7 @@ class EMSESP { static std::vector> emsdevices; + // services static Mqtt mqtt_; static System system_; static Sensors sensors_; @@ -144,10 +146,12 @@ class EMSESP { static RxService rxservice_; static TxService txservice_; - static ESP8266React esp8266React; - static EMSESPSettingsService emsespSettingsService; - static EMSESPStatusService emsespStatusService; - static EMSESPDevicesService emsespDevicesService; + // web controllers + static ESP8266React esp8266React; + static EMSESPSettingsService emsespSettingsService; + static EMSESPStatusService emsespStatusService; + static EMSESPDevicesService emsespDevicesService; + static EMSESPScanDevicesService emsespScanDevicesService; private: EMSESP() = delete; @@ -169,7 +173,7 @@ class EMSESP { uint8_t flags; }; - static std::vector device_library_; + static std::vector device_library_; static uint8_t actual_master_thermostat_; static uint16_t watch_id_;