diff --git a/interface/src/project/EMSESP.tsx b/interface/src/project/EMSESP.tsx index c8c546576..69be47411 100644 --- a/interface/src/project/EMSESP.tsx +++ b/interface/src/project/EMSESP.tsx @@ -9,6 +9,7 @@ import { AuthenticatedRoute } from '../authentication'; import EMSESPSettingsController from './EMSESPSettingsController'; import EMSESPStatusController from './EMSESPStatusController'; +import EMSESPDevicesController from './EMSESPDevicesController'; class EMSESP extends Component { @@ -21,10 +22,12 @@ class EMSESP extends Component { + + diff --git a/interface/src/project/EMSESPDevicesController.tsx b/interface/src/project/EMSESPDevicesController.tsx new file mode 100644 index 000000000..4db6bac63 --- /dev/null +++ b/interface/src/project/EMSESPDevicesController.tsx @@ -0,0 +1,30 @@ +import React, { Component } from 'react'; + +import { restController, RestControllerProps, RestFormLoader, SectionContent } from '../components'; +import { ENDPOINT_ROOT } from '../api'; +import EMSESPDevicesForm from './EMSESPDevicesForm'; +import { EMSESPDevices } from './types'; + +export const EMSESP_DEVICES_ENDPOINT = ENDPOINT_ROOT + "emsespDevices"; + +type EMSESPDevicesControllerProps = RestControllerProps; + +class EMSESPDevicesController extends Component { + + componentDidMount() { + this.props.loadData(); + } + + render() { + return ( + + } + /> + + ) + } +} + +export default restController(EMSESP_DEVICES_ENDPOINT, EMSESPDevicesController); diff --git a/interface/src/project/EMSESPDevicesForm.tsx b/interface/src/project/EMSESPDevicesForm.tsx new file mode 100644 index 000000000..4a17bbaaa --- /dev/null +++ b/interface/src/project/EMSESPDevicesForm.tsx @@ -0,0 +1,121 @@ +import React, { Component, Fragment } from "react"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableRow, + List, + withWidth, + WithWidthProps, + isWidthDown +} from "@material-ui/core"; + +import { Box, Typography } from '@material-ui/core'; + +import RefreshIcon from "@material-ui/icons/Refresh"; + +import { withAuthenticatedContext, AuthenticatedContextProps } from '../authentication'; + +import { + RestFormProps, + FormActions, + FormButton, +} from "../components"; + +import { EMSESPDevices, Device } from "./types"; + +function compareDevices(a: Device, b: Device) { + if (a.type < b.type) { + return -1; + } + if (a.type > b.type) { + return 1; + } + return 0; +} + +type EMSESPDevicesFormProps = RestFormProps & AuthenticatedContextProps & WithWidthProps; + +class EMSESPDevicesForm extends Component { + + noData = () => { + return (this.props.data.devices.length === 0); + }; + + createListItems() { + const { width, data } = this.props; + return ( + + + + + Type + Brand + Name + Device ID + Product ID + Version + + + + {data.devices.sort(compareDevices).map(device => ( + + + {device.type} + + + {device.brand} + + + {device.name} + + + 0x{('00' + device.deviceid.toString(16).toUpperCase()).slice(-2)} + + + {device.productid} + + + {device.version} + + + ))} + +
+ {this.noData() && + ( + + + No EMS devices found. + + + ) + } +
+ ); + } + + render() { + return ( + + {this.createListItems()} + + } + variant="contained" + color="secondary" + onClick={this.props.loadData} + > + Refresh + + + + ); + } +} + +export default withAuthenticatedContext(withWidth()(EMSESPDevicesForm)); + +// export default withTheme(EMSESPDevicesForm); diff --git a/interface/src/project/EMSESPSettingsController.tsx b/interface/src/project/EMSESPSettingsController.tsx index 7bb2923ca..8385577e1 100644 --- a/interface/src/project/EMSESPSettingsController.tsx +++ b/interface/src/project/EMSESPSettingsController.tsx @@ -55,7 +55,7 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps) validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:255']} errorMessages={['TX mode is required', "Must be a number", "Must be 0 or higher", "Max value is 255"]} name="tx_mode" - label="Tx mode (0=off)" + label="Tx Mode (0=off)" fullWidth variant="outlined" value={data.tx_mode} @@ -71,10 +71,10 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps) value="system_heartbeat" /> } - label="MQTT heartbeat" + label="MQTT Heartbeat" /> - - OFF - ERR - INFO - DEBUG - + + OFF + ERR + INFO + DEBUG + {data.syslog_level !== -1 && { @@ -125,7 +125,7 @@ class EMSESPStatusForm extends Component { - (Tx) Send failures + (Tx) Send Errors {data.tx_errors} diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index 87a40a41c..1b812c17d 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -30,3 +30,17 @@ export interface EMSESPStatus { uptime: string; free_mem: number; } + +export interface Device { + type: string; + brand: string; + name: string; + deviceid: number; + productid: number; + version: string; +} + +export interface EMSESPDevices { + devices: Device[]; +} + diff --git a/src/EMSESPDevicesService.cpp b/src/EMSESPDevicesService.cpp new file mode 100644 index 000000000..0d02fa82d --- /dev/null +++ b/src/EMSESPDevicesService.cpp @@ -0,0 +1,36 @@ +#include "EMSESPDevicesService.h" +#include "emsesp.h" +#include "mqtt.h" + +namespace emsesp { + +EMSESPDevicesService::EMSESPDevicesService(AsyncWebServer * server, SecurityManager * securityManager) { + server->on(EMSESP_DEVICES_SERVICE_PATH, + HTTP_GET, + securityManager->wrapRequest(std::bind(&EMSESPDevicesService::emsespDevicesService, this, std::placeholders::_1), + AuthenticationPredicates::IS_AUTHENTICATED)); +} + +void EMSESPDevicesService::emsespDevicesService(AsyncWebServerRequest * request) { + AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_EMSESP_STATUS_SIZE); + JsonObject root = response->getRoot(); + + JsonArray devices = root.createNestedArray("devices"); + + for (const auto & emsdevice : EMSESP::emsdevices) { + if (emsdevice) { + JsonObject deviceRoot = devices.createNestedObject(); + deviceRoot["type"] = emsdevice->device_type_name(); + deviceRoot["brand"] = emsdevice->brand_to_string(); + deviceRoot["name"] = emsdevice->name(); + deviceRoot["deviceid"] = emsdevice->device_id(); + deviceRoot["productid"] = emsdevice->product_id(); + deviceRoot["version"] = emsdevice->version(); + } + + response->setLength(); + request->send(response); + } +} + +} // namespace emsesp \ No newline at end of file diff --git a/src/EMSESPDevicesService.h b/src/EMSESPDevicesService.h new file mode 100644 index 000000000..fe88b1c2d --- /dev/null +++ b/src/EMSESPDevicesService.h @@ -0,0 +1,31 @@ +#ifndef EMSESPDevicesService_h +#define EMSESPDevicesService_h + +#include +#include +#include +#include + +#include +#include +#include + +#include "EMSESPSettingsService.h" +#include "version.h" + +#define MAX_EMSESP_STATUS_SIZE 1024 +#define EMSESP_DEVICES_SERVICE_PATH "/rest/emsespDevices" + +namespace emsesp { + +class EMSESPDevicesService { + public: + EMSESPDevicesService(AsyncWebServer * server, SecurityManager * securityManager); + + private: + void emsespDevicesService(AsyncWebServerRequest * request); +}; + +} // namespace emsesp + +#endif diff --git a/src/EMSESPStatusService.cpp b/src/EMSESPStatusService.cpp index 2d59e8e68..1ae7ccbc0 100644 --- a/src/EMSESPStatusService.cpp +++ b/src/EMSESPStatusService.cpp @@ -1,6 +1,7 @@ #include "EMSESPStatusService.h" #include "emsesp.h" #include "mqtt.h" +#include "version.h" namespace emsesp { diff --git a/src/EMSESPStatusService.h b/src/EMSESPStatusService.h index 62bfbd211..318cd6bf3 100644 --- a/src/EMSESPStatusService.h +++ b/src/EMSESPStatusService.h @@ -5,14 +5,7 @@ #include #include #include - - -#include -#include -#include - -#include "EMSESPSettingsService.h" -#include "version.h" +#include #define MAX_EMSESP_STATUS_SIZE 1024 #define EMSESP_STATUS_SERVICE_PATH "/rest/emsespStatus" @@ -24,9 +17,8 @@ class EMSESPStatusService { EMSESPStatusService(AsyncWebServer * server, SecurityManager * securityManager, AsyncMqttClient * mqttClient); private: - EMSESPSettingsService * _emsespSettingsService; - void emsespStatusService(AsyncWebServerRequest * request); - AsyncMqttClient * _mqttClient; + void emsespStatusService(AsyncWebServerRequest * request); + AsyncMqttClient * _mqttClient; void init_mqtt(); };