Deleted .idea/.gitignore, .idea/clion.iml, .idea/misc.xml, .idea/modules.xml, .idea/platformio.iml, .idea/serialmonitor_settings.xml, .idea/vcs.xml, .idea/watcherTasks.xml files
This commit is contained in:
120
interface/src/project/GeneralInformation.tsx
Normal file
120
interface/src/project/GeneralInformation.tsx
Normal file
@ -0,0 +1,120 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Box, List, ListItem, ListItemText} from '@material-ui/core';
|
||||
import {
|
||||
FormButton,
|
||||
restController,
|
||||
RestControllerProps,
|
||||
RestFormLoader,
|
||||
SectionContent
|
||||
} from '../components';
|
||||
import {ENDPOINT_ROOT} from "../api";
|
||||
import {GeneralInformaitonState} from "./types";
|
||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
||||
|
||||
// define api endpoint
|
||||
export const GENERALINFORMATION_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "generalinfo";
|
||||
|
||||
type GeneralInformationRestControllerProps = RestControllerProps<GeneralInformaitonState>;
|
||||
|
||||
class GeneralInformation extends Component<GeneralInformationRestControllerProps> {
|
||||
intervalhandler: number | undefined;
|
||||
|
||||
componentDidMount() {
|
||||
this.props.loadData();
|
||||
|
||||
// this.intervalhandler = window.setInterval(() => {
|
||||
// this.props.loadData();
|
||||
// console.log("refreshing data");
|
||||
// console.log(this.props.data)
|
||||
// }, 10000);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.intervalhandler);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SectionContent title='Information' titleGutter>
|
||||
<RestFormLoader
|
||||
{...this.props}
|
||||
render={props => (
|
||||
<>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Chip läuft seit:"
|
||||
secondary={this.stringifyTime(props.data.runtime)}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Zuletzt zu wenig Wasser:"
|
||||
secondary={props.data.lastWaterOutage !== 0 ? "vor " + this.stringifyTime(props.data.lastWaterOutage) : "noch nie!"}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Letzer Pumpenzyklus"
|
||||
secondary={props.data.lastpumptime !== 0 ? "vor " + this.stringifyTime(props.data.lastpumptime) : "noch nie!"}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Letze Pumpdauer:"
|
||||
secondary={props.data.lastPumpDuration !== 0 ? this.stringifyTime(props.data.lastPumpDuration) : "-"}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Temperatur/Luftfeuchtigkeit:"
|
||||
secondary={(props.data.temp !== -1 ? props.data.temp + "C" : "Auslesefehler!") + " / " + (props.data.hum !== -1 ? props.data.hum + "%" : "Auslesefehler!")}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="WasserSensor / DruckSensor"
|
||||
secondary={(props.data.watersensor ? "EIN" : "AUS!") + " / " + (props.data.pressuresensor ? "EIN" : "AUS")}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1} padding={1}>
|
||||
<FormButton startIcon={<RefreshIcon/>} variant="contained" color="secondary"
|
||||
onClick={this.props.loadData}>
|
||||
Refresh
|
||||
</FormButton>
|
||||
</Box>
|
||||
<Box flexWrap="none" padding={1} whiteSpace="nowrap">
|
||||
Version: {props.data.version}
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
</SectionContent>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* stringify seconds to a pretty format
|
||||
* @param sec number of seconds
|
||||
*/
|
||||
stringifyTime(sec: number): string {
|
||||
if (sec >= 86400) {
|
||||
// display days
|
||||
return (Math.trunc(sec / 86400) + "d " + Math.trunc((sec % 86400) / 3600) + "h " + Math.trunc((sec % 3600) / 60) + "min " + sec % 60 + "sec");
|
||||
} else if (sec >= 3600) {
|
||||
// display hours
|
||||
return (Math.trunc(sec / 3600) + "h " + Math.trunc((sec % 3600) / 60) + "min " + sec % 60 + "sec");
|
||||
} else if (sec >= 60) {
|
||||
// only seconds and minutes
|
||||
return (Math.trunc(sec / 60) + "min " + sec % 60 + "sec");
|
||||
} else {
|
||||
// only seconds
|
||||
return (sec + "sec");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default restController(GENERALINFORMATION_SETTINGS_ENDPOINT, GeneralInformation);
|
27
interface/src/project/ProjectMenu.tsx
Normal file
27
interface/src/project/ProjectMenu.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link, withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
import {List, ListItem, ListItemIcon, ListItemText} from '@material-ui/core';
|
||||
import SettingsRemoteIcon from '@material-ui/icons/SettingsRemote';
|
||||
|
||||
import { PROJECT_PATH } from '../api';
|
||||
|
||||
class ProjectMenu extends Component<RouteComponentProps> {
|
||||
|
||||
render() {
|
||||
const path = this.props.match.url;
|
||||
return (
|
||||
<List>
|
||||
<ListItem to={`/${PROJECT_PATH}/pumpe/`} selected={path.startsWith(`/${PROJECT_PATH}/pumpe/`)} button component={Link}>
|
||||
<ListItemIcon>
|
||||
<SettingsRemoteIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Pumpensteuerung" />
|
||||
</ListItem>
|
||||
</List>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default withRouter(ProjectMenu);
|
33
interface/src/project/ProjectRouting.tsx
Normal file
33
interface/src/project/ProjectRouting.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect, Switch } from 'react-router';
|
||||
|
||||
import { PROJECT_PATH } from '../api';
|
||||
import { AuthenticatedRoute } from '../authentication';
|
||||
|
||||
import PumpControl from './PumpControl';
|
||||
|
||||
class ProjectRouting extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Switch>
|
||||
{
|
||||
/*
|
||||
* Add your project page routing below.
|
||||
*/
|
||||
}
|
||||
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/pumpe/*`} component={PumpControl} />
|
||||
{
|
||||
/*
|
||||
* The redirect below caters for the default project route and redirecting invalid paths.
|
||||
* The "to" property must match one of the routes above for this to work correctly.
|
||||
*/
|
||||
}
|
||||
<Redirect to={`/${PROJECT_PATH}/pumpe/`} />
|
||||
</Switch>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ProjectRouting;
|
37
interface/src/project/PumpControl.tsx
Normal file
37
interface/src/project/PumpControl.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect, Switch, RouteComponentProps } from 'react-router-dom'
|
||||
|
||||
import { Tabs, Tab } from '@material-ui/core';
|
||||
|
||||
import { PROJECT_PATH } from '../api';
|
||||
import { MenuAppBar } from '../components';
|
||||
import { AuthenticatedRoute } from '../authentication';
|
||||
|
||||
import GeneralInformation from './GeneralInformation';
|
||||
import SettingsController from "./SettingsController";
|
||||
|
||||
class PumpControl extends Component<RouteComponentProps> {
|
||||
|
||||
handleTabChange = (event: React.ChangeEvent<{}>, path: string) => {
|
||||
this.props.history.push(path);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MenuAppBar sectionTitle="Wasserpumpensteuerung">
|
||||
<Tabs value={this.props.match.url} onChange={this.handleTabChange} variant="fullWidth">
|
||||
<Tab value={`/${PROJECT_PATH}/pumpe/information`} label="Information" />
|
||||
<Tab value={`/${PROJECT_PATH}/pumpe/settings`} label="Einstellungen" />
|
||||
</Tabs>
|
||||
<Switch>
|
||||
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/pumpe/information`} component={GeneralInformation} />
|
||||
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/pumpe/settings`} component={SettingsController} />
|
||||
<Redirect to={`/${PROJECT_PATH}/pumpe/information`} />
|
||||
</Switch>
|
||||
</MenuAppBar>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default PumpControl;
|
84
interface/src/project/SettingsController.tsx
Normal file
84
interface/src/project/SettingsController.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import React, {Component} from 'react';
|
||||
import {ValidatorForm} from 'react-material-ui-form-validator';
|
||||
|
||||
import {Typography, Box, TextField} from '@material-ui/core';
|
||||
import SaveIcon from '@material-ui/icons/Save';
|
||||
|
||||
import {ENDPOINT_ROOT} from '../api';
|
||||
import {
|
||||
restController,
|
||||
RestControllerProps,
|
||||
RestFormLoader,
|
||||
FormActions,
|
||||
FormButton,
|
||||
SectionContent,
|
||||
} from '../components';
|
||||
|
||||
import {SettingsState} from './types';
|
||||
|
||||
export const LIGHT_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "settings";
|
||||
|
||||
type LightStateRestControllerProps = RestControllerProps<SettingsState>;
|
||||
|
||||
class SettingsController extends Component<LightStateRestControllerProps> {
|
||||
|
||||
componentDidMount() {
|
||||
this.props.loadData();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SectionContent title='Einstellungen' titleGutter>
|
||||
<RestFormLoader
|
||||
{...this.props}
|
||||
render={props => {
|
||||
const {data, saveData, handleValueChange} = props;
|
||||
return (
|
||||
<ValidatorForm onSubmit={saveData}>
|
||||
<Box bgcolor="primary.main" color="primary.contrastText" p={2} mt={2} mb={2}>
|
||||
<Typography variant="body1">
|
||||
Die unten eingegebenen Werte werden nach klick des 'SAVE' Buttons übernommen und überleben einen Neustart.
|
||||
</Typography>
|
||||
</Box>
|
||||
<div>
|
||||
<TextField value={data.maxpumpduration} fullWidth={true} type='number'
|
||||
id="maxpumpduration" label="Maximale Pumpdauer [sec]"
|
||||
onChange={handleValueChange('maxpumpduration')}/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField value={data.waterOutageWaitDuration} fullWidth={true} type='number'
|
||||
id="waterOutageWaitDuration" label="Wartezeit nach Wasserausfall [sec]"
|
||||
onChange={handleValueChange('waterOutageWaitDuration')}/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField value={data.heatUp} fullWidth={true} type='number' id="heatUp"
|
||||
label="Obere Luftfeuchtigkeitsschwelle [%]"
|
||||
onChange={handleValueChange('heatUp')}/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField value={data.heatLow} fullWidth={true} type='number' id="heatLow"
|
||||
label="Untere Luftfeuchtigkeitsschwelle [%]"
|
||||
onChange={handleValueChange('heatLow')}/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField value={data.fanRuntime} fullWidth={true} type='number' id="fanRuntime"
|
||||
label="Nachlaufzeit Lüfter [sec]"
|
||||
onChange={handleValueChange('fanRuntime')}/>
|
||||
</div>
|
||||
|
||||
<FormActions>
|
||||
<FormButton startIcon={<SaveIcon/>} variant="contained" color="primary"
|
||||
type="submit">Save
|
||||
</FormButton>
|
||||
</FormActions>
|
||||
</ValidatorForm>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</SectionContent>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default restController(LIGHT_SETTINGS_ENDPOINT, SettingsController);
|
19
interface/src/project/types.ts
Normal file
19
interface/src/project/types.ts
Normal file
@ -0,0 +1,19 @@
|
||||
export interface SettingsState {
|
||||
maxpumpduration: number;
|
||||
waterOutageWaitDuration: number;
|
||||
heatUp: number;
|
||||
heatLow: number;
|
||||
fanRuntime: number;
|
||||
}
|
||||
|
||||
export interface GeneralInformaitonState {
|
||||
hum: number;
|
||||
temp: number;
|
||||
lastpumptime: number;
|
||||
lastWaterOutage: number;
|
||||
lastPumpDuration: number;
|
||||
runtime: number;
|
||||
watersensor: boolean;
|
||||
pressuresensor: boolean;
|
||||
version: string;
|
||||
}
|
Reference in New Issue
Block a user