1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/web/ synced 2025-03-09 00:00:01 +01:00

Improve IC action control

This commit is contained in:
Steffen Vogel 2021-02-06 03:37:36 +01:00
parent f0c4e2adcf
commit 5231a93faf
4 changed files with 94 additions and 81 deletions

View file

@ -16,75 +16,93 @@
******************************************************************************/
import React from 'react';
import { Button, ButtonToolbar, DropdownButton, Dropdown } from 'react-bootstrap';
import TimePicker from 'react-bootstrap-time-picker'
import { Button, ButtonToolbar, DropdownButton, Dropdown, InputGroup, FormControl } from 'react-bootstrap';
class ICAction extends React.Component {
constructor(props) {
super(props);
constructor(props) {
super(props);
this.state = {
selectedAction: null,
selectedDelay: 0
};
let t = new Date()
Number.prototype.pad = function(size) {
var s = String(this);
while (s.length < (size || 2)) {s = "0" + s;}
return s;
}
static getDerivedStateFromProps(props, state){
if (state.selectedAction == null) {
if (props.actions != null && props.actions.length > 0) {
return{
selectedAction: props.actions[0]
};
}
}
return null
}
let time = new Date();
time.setMinutes(5 * Math.round(time.getMinutes() / 5 + 1))
setAction = id => {
// search action
for (let action of this.props.actions) {
if (action.id === id) {
this.setState({ selectedAction: action });
}
}
this.state = {
selectedAction: null,
time: time
};
}
setDelayForAction = time => {
// time in int format: (hours * 3600 + minutes * 60 + seconds)
this.setState({selectedDelay: time})
static getDerivedStateFromProps(props, state) {
if (state.selectedAction == null) {
if (props.actions != null && props.actions.length > 0) {
return {
selectedAction: props.actions[0]
};
}
}
return null
}
render() {
let sendCommandDisabled = this.props.runDisabled || this.state.selectedAction == null || this.state.selectedAction.id === "-1"
const actionList = this.props.actions.map(action => (
<Dropdown.Item key={action.id} eventKey={action.id} active={this.state.selectedAction === action.id}>
{action.title}
</Dropdown.Item>
));
return <div>
{"Select delay for command execution (Format hh:mm, max 1h):"}
<TimePicker
format={24}
initialValue={this.state.selectedDelay}
value={this.state.selectedDelay}
start={"00:00"}
end={"01:00"}
step={1}
onChange={this.setDelayForAction}
/>
<ButtonToolbar>
<DropdownButton title={this.state.selectedAction != null ? this.state.selectedAction.title : ''} id="action-dropdown" onSelect={this.setAction}>
{actionList}
</DropdownButton>
<Button style={{ marginLeft: '5px' }} disabled={sendCommandDisabled} onClick={() => this.props.runAction(this.state.selectedAction, this.state.selectedDelay)}>Send command</Button>
</ButtonToolbar>
</div>;
setAction = id => {
// search action
for (let action of this.props.actions) {
if (action.id === id) {
this.setState({ selectedAction: action });
}
}
};
setTimeForAction = (time) => {
this.setState({ time: new Date(time) })
}
render() {
let sendCommandDisabled = this.props.runDisabled || this.state.selectedAction == null || this.state.selectedAction.id === "-1"
let time = this.state.time.getFullYear().pad(4) + '-' +
this.state.time.getMonth().pad(2) + '-' +
this.state.time.getDay().pad(2) + 'T' +
this.state.time.getHours().pad(2) + ':' +
this.state.time.getMinutes().pad(2);
const actionList = this.props.actions.map(action => (
<Dropdown.Item key={action.id} eventKey={action.id} active={this.state.selectedAction === action.id}>
{action.title}
</Dropdown.Item>
));
return <div>
<InputGroup>
<InputGroup.Prepend>
<DropdownButton
variant="outline-secondary"
title={this.state.selectedAction != null ? this.state.selectedAction.title : ''}
id="action-dropdown"
onSelect={this.setAction}>
{actionList}
</DropdownButton>
<FormControl
type="datetime-local"
variant="outline-secondary"
value={time}
onChange={this.setTimeForAction} />
</InputGroup.Prepend>
<Button
variant="outline-secondary"
disabled={sendCommandDisabled}
onClick={() => this.props.runAction(this.state.selectedAction, this.state.time)}>Run</Button>
</InputGroup>
<small className="text-muted">Select time for synced command execution</small>
</div>;
}
}
export default ICAction;

View file

@ -24,8 +24,14 @@ class IcsDataManager extends RestDataManager {
super('ic', '/ic');
}
doActions(ic, action, token = null) {
RestAPI.post(this.makeURL(this.url + '/' + ic.id + '/action'), action, token).then(response => {
doActions(ic, actions, token = null) {
for (let action of actions) {
if (action.when)
// Send timestamp as Unix Timestamp
action.when = Math.round(action.when.getTime() / 1000);
}
RestAPI.post(this.makeURL(this.url + '/' + ic.id + '/action'), actions, token).then(response => {
AppDispatcher.dispatch({
type: 'ics/action-started',
data: response

View file

@ -136,7 +136,6 @@ class InfrastructureComponents extends Component {
}
}
closeNewModal(data) {
this.setState({ newModal : false });
@ -230,8 +229,10 @@ class InfrastructureComponents extends Component {
this.setState({ selectedICs: selectedICs });
}
runAction(action) {
runAction(action, when) {
for (let index of this.state.selectedICs) {
action.when = when;
AppDispatcher.dispatch({
type: 'ics/start-action',
ic: this.state.ics[index],
@ -251,7 +252,6 @@ class InfrastructureComponents extends Component {
}
stateLabelStyle(state, component){
var style = [ 'badge' ];
if (InfrastructureComponents.isICOutdated(component) && state !== 'shutdown') {
@ -296,7 +296,6 @@ class InfrastructureComponents extends Component {
default:
style.push('badge-default');
/* Possible states of ICs
* 'error': ['resetting', 'error'],
'idle': ['resetting', 'error', 'idle', 'starting', 'shuttingdown'],
@ -322,13 +321,11 @@ class InfrastructureComponents extends Component {
}
modifyManagedExternallyColumn(managedExternally, component){
if(managedExternally){
return <Icon icon='check' />
} else {
return ""
}
}
modifyUptimeColumn(uptime, component){
@ -336,7 +333,7 @@ class InfrastructureComponents extends Component {
let momentDurationFormatSetup = require("moment-duration-format");
momentDurationFormatSetup(moment)
let timeString = moment.duration(uptime, "seconds").format();
let timeString = moment.duration(uptime, "seconds").humanize();
return <span>{timeString}</span>
}
else{
@ -355,7 +352,6 @@ class InfrastructureComponents extends Component {
}
sendControlCommand(command,ic){
if(command === "restart"){
AppDispatcher.dispatch({
type: 'ics/restart',
@ -369,7 +365,6 @@ class InfrastructureComponents extends Component {
token: this.state.sessionToken,
});
}
}
isExternalIC(index){
@ -378,7 +373,6 @@ class InfrastructureComponents extends Component {
}
render() {
const buttonStyle = {
marginLeft: '10px'
};
@ -457,9 +451,9 @@ class InfrastructureComponents extends Component {
<div style={{float: 'left'}}>
<ICAction
runDisabled={this.state.selectedICs.length === 0}
runAction={action => this.runAction(action)}
runAction={(action, when) => this.runAction(action, when)}
actions={[
{id: '-1', title: 'Select command', data: {action: 'none'}},
{id: '-1', title: 'Action', data: {action: 'none'}},
{id: '0', title: 'Reset', data: {action: 'reset'}},
{id: '1', title: 'Shutdown', data: {action: 'shutdown'}},
]}

View file

@ -385,9 +385,7 @@ class Scenario extends React.Component {
}
runAction(action, delay) {
// delay in seconds
runAction(action, when) {
if (action.data.action === 'none') {
console.warn("No command selected. Nothing was sent.");
return;
@ -410,8 +408,7 @@ class Scenario extends React.Component {
action.data.parameters = this.state.configs[index].startParameters;
}
// Unix time stamp + delay
action.data.when = Math.round(Date.now() / 1000.0 + delay)
action.data.when = when;
console.log("Sending action: ", action.data)
@ -796,8 +793,6 @@ class Scenario extends React.Component {
scenarioID={this.state.scenario.id}
/>
{/*Component Configurations table*/}
<h2 style={tableHeadingStyle}>Component Configurations
<Button onClick={() => this.addConfig()} style={buttonStyle}><Icon icon="plus" /></Button>
@ -854,9 +849,9 @@ class Scenario extends React.Component {
<div style={{float: 'left'}}>
<ICAction
runDisabled={this.state.selectedConfigs.length === 0}
runAction={(action, delay) => this.runAction(action, delay)}
runAction={(action, when) => this.runAction(action, when)}
actions={[
{id: '-1', title: 'Select command', data: {action: 'none'}},
{id: '-1', title: 'Action', data: {action: 'none'}},
{id: '0', title: 'Start', data: {action: 'start'}},
{id: '1', title: 'Stop', data: {action: 'stop'}},
{id: '2', title: 'Pause', data: {action: 'pause'}},