import React, { Component, Fragment } from "react"; import { withStyles, Theme, createStyles } from "@material-ui/core/styles"; import { Table, TableBody, TableCell, TableHead, TableRow, TableContainer, withWidth, WithWidthProps, isWidthDown, Button, Tooltip, DialogTitle, DialogContent, DialogActions, Box, Dialog, Typography, } from "@material-ui/core"; import RefreshIcon from "@material-ui/icons/Refresh"; import ListIcon from "@material-ui/icons/List"; import { redirectingAuthorizedFetch, withAuthenticatedContext, AuthenticatedContextProps, } from "../authentication"; import { RestFormProps, FormButton } from "../components"; import { EMSESPDevices, EMSESPDeviceData, Device } from "./EMSESPtypes"; import { ENDPOINT_ROOT } from "../api"; export const SCANDEVICES_ENDPOINT = ENDPOINT_ROOT + "scanDevices"; export const DEVICE_DATA_ENDPOINT = ENDPOINT_ROOT + "deviceData"; const StyledTableCell = withStyles((theme: Theme) => createStyles({ head: { backgroundColor: theme.palette.common.black, color: theme.palette.common.white, }, body: { fontSize: 14, }, }) )(TableCell); function compareDevices(a: Device, b: Device) { if (a.type < b.type) { return -1; } if (a.type > b.type) { return 1; } return 0; } interface EMSESPDevicesFormState { confirmScanDevices: boolean; processing: boolean; deviceData?: EMSESPDeviceData; } type EMSESPDevicesFormProps = RestFormProps & AuthenticatedContextProps & WithWidthProps; function formatTemp(t: string) { if (t == null) { return "(not available)"; } return t + " °C"; } class EMSESPDevicesForm extends Component< EMSESPDevicesFormProps, EMSESPDevicesFormState > { state: EMSESPDevicesFormState = { confirmScanDevices: false, processing: false, }; noDevices = () => { return this.props.data.devices.length === 0; }; noSensors = () => { return this.props.data.sensors.length === 0; }; noDeviceData = () => { return (this.state.deviceData?.deviceData || []).length === 0; }; createDeviceItems() { const { width, data } = this.props; return ( EMS Devices

{!this.noDevices() && ( Type Brand Model Device ID Product ID Version {data.devices.sort(compareDevices).map((device) => ( this.handleRowClick(device.id)} > {device.brand} {device.name} 0x {("00" + device.deviceid.toString(16).toUpperCase()).slice( -2 )} {device.productid} {device.version} ))}
)} {this.noDevices() && ( No EMS devices found. Check the connections and for possible Tx errors. )}
); } createSensorItems() { const { data } = this.props; return (

Dallas Sensors {!this.noSensors() && ( Sensor # ID Temperature {data.sensors.map((sensorData) => ( {sensorData.no} {sensorData.id} {formatTemp(sensorData.temp)} ))}
)} {this.noSensors() && ( There are no external temperature sensors connected )}
); } renderScanDevicesDialog() { return ( Confirm Scan Devices Are you sure you want to initiate a scan on 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) .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 }); }); }; handleRowClick = (id: any) => { this.setState({ deviceData: undefined }); redirectingAuthorizedFetch(DEVICE_DATA_ENDPOINT, { method: "POST", body: JSON.stringify({ id: id }), headers: { "Content-Type": "application/json", }, }) .then((response) => { if (response.status === 200) { return response.json(); // this.setState({ errorMessage: undefined }, this.props.loadData); } throw Error("Unexpected response code: " + response.status); }) .then((json) => { this.setState({ deviceData: json }); }) .catch((error) => { this.props.enqueueSnackbar( error.message || "Problem getting device data", { variant: "error" } ); this.setState({ deviceData: undefined }); }); }; renderDeviceData() { const { deviceData } = this.state; const { width } = this.props; if (this.noDevices()) { return; } if (!deviceData) { return; } return (

{deviceData.deviceName} {!this.noDeviceData() && ( {deviceData.deviceData.map((deviceData) => ( {deviceData.n} {deviceData.v} ))}
)} {this.noDeviceData() && ( No data available for this device )}
); } render() { return (

{this.createDeviceItems()} {this.renderDeviceData()} {this.createSensorItems()}

} 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));