2020-12-04 18:10:33 +00:00
|
|
|
/**
|
|
|
|
* @author Martin Karkowski
|
|
|
|
* @email m.karkowski@zema.de
|
|
|
|
* @create date 2020-12-03 11:57:29
|
|
|
|
* @modify date 2020-12-03 11:57:29
|
|
|
|
* @desc [description]
|
|
|
|
*/
|
|
|
|
|
|
|
|
import { faHashtag, faHome } from "@fortawesome/free-solid-svg-icons";
|
|
|
|
import React from "react";
|
|
|
|
import {
|
|
|
|
Alert,
|
|
|
|
Card,
|
|
|
|
Col,
|
|
|
|
Container,
|
|
|
|
Row,
|
|
|
|
Spinner,
|
|
|
|
Table
|
|
|
|
} from "react-bootstrap";
|
|
|
|
import { INopeDispatcher } from "../../lib/types/nope/nopeDispatcher.interface";
|
|
|
|
import { INopeModule } from "../../lib/types/nope/nopeModule.interface";
|
|
|
|
import { INopeObserver } from "../../lib/types/nope/nopeObservable.interface";
|
2020-12-31 12:18:24 +00:00
|
|
|
import { IReadableIos } from "../../modules/generic-plc/type/interfaces";
|
2020-12-04 18:10:33 +00:00
|
|
|
import { IBeckhoffPLC } from "../../modules/mod-Beckhoff-PLC-Interface/type/interfaces";
|
|
|
|
import Toolbar from "../../resources/ui/layout/toolbar";
|
|
|
|
|
|
|
|
class BeckhoffComponent extends React.Component<
|
|
|
|
{ instance: IBeckhoffPLC & INopeModule },
|
|
|
|
{
|
|
|
|
intialized: boolean;
|
|
|
|
connected: boolean;
|
|
|
|
remote;
|
2020-12-31 12:18:24 +00:00
|
|
|
inputs: IReadableIos[];
|
|
|
|
outputs: IReadableIos[];
|
2020-12-04 18:10:33 +00:00
|
|
|
}
|
|
|
|
> {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
connected: false,
|
|
|
|
intialized: false,
|
|
|
|
remote: "unkown",
|
|
|
|
inputs: [],
|
|
|
|
outputs: []
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
observers: INopeObserver[] = [];
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
if (this.props.instance) {
|
2020-12-31 12:18:24 +00:00
|
|
|
const _this = this;
|
|
|
|
|
|
|
|
// Subscribe to the Oberservers
|
|
|
|
// which will influence the visuals.
|
2020-12-04 18:10:33 +00:00
|
|
|
this.observers.push(
|
|
|
|
this.props.instance.connected.subscribe((connected) => {
|
|
|
|
_this.setState({ connected });
|
|
|
|
})
|
|
|
|
);
|
|
|
|
this.observers.push(
|
2020-12-31 12:18:24 +00:00
|
|
|
// Wait for the System to Initialize.
|
|
|
|
// If done, define the Remote-String.
|
2020-12-04 18:10:33 +00:00
|
|
|
this.props.instance.initialized.subscribe((intialized) => {
|
|
|
|
_this.setState({
|
|
|
|
intialized,
|
|
|
|
remote:
|
|
|
|
_this.props.instance.adsOptions.getContent()?.host +
|
|
|
|
":" +
|
|
|
|
_this.props.instance.adsOptions.getContent()?.port
|
|
|
|
});
|
|
|
|
})
|
|
|
|
);
|
2020-12-31 12:18:24 +00:00
|
|
|
// Initially define the Remote.
|
2020-12-04 18:10:33 +00:00
|
|
|
this.setState({
|
|
|
|
remote:
|
|
|
|
this.props.instance.adsOptions.getContent()?.host +
|
|
|
|
":" +
|
|
|
|
this.props.instance.adsOptions.getContent()?.port
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<Card border={this.state.connected ? "success" : "danger"}>
|
|
|
|
<Card.Header>
|
|
|
|
<b>PLC: </b>
|
|
|
|
<code>{this.props.instance.identifier}</code>{" "}
|
|
|
|
</Card.Header>
|
|
|
|
<Card.Body>
|
|
|
|
{!this.state.intialized ? (
|
|
|
|
<Alert variant="warning">
|
|
|
|
<Alert.Heading>
|
|
|
|
<Spinner animation="border" /> Grabbing Configuration
|
|
|
|
</Alert.Heading>
|
|
|
|
<p>Trying to extract the Configuration online.</p>
|
|
|
|
</Alert>
|
|
|
|
) : (
|
|
|
|
<Table striped bordered hover>
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Module</th>
|
|
|
|
<th>Port</th>
|
|
|
|
<th>Value</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{this.state.inputs.map((io, idx) => (
|
|
|
|
<tr key={idx}>
|
|
|
|
<td>{io.orginalName}</td>
|
|
|
|
<td>{io.dataType}</td>
|
2020-12-31 12:18:24 +00:00
|
|
|
<td>{io.currentValue}</td>
|
2020-12-04 18:10:33 +00:00
|
|
|
</tr>
|
|
|
|
))}
|
|
|
|
</tbody>
|
|
|
|
</Table>
|
|
|
|
)}
|
|
|
|
</Card.Body>
|
|
|
|
{this.state.connected ? (
|
|
|
|
""
|
|
|
|
) : (
|
|
|
|
<Card.Footer>
|
|
|
|
Waiting for the plc to accept the connection. Host of the PLC is{" "}
|
|
|
|
<code>{this.state.remote}</code>
|
|
|
|
</Card.Footer>
|
|
|
|
)}
|
|
|
|
</Card>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class BeckhoffOverviewComponent extends React.Component<
|
|
|
|
{ dispatcher: INopeDispatcher },
|
|
|
|
{ instances: (IBeckhoffPLC & INopeModule)[]; connected: boolean }
|
|
|
|
> {
|
|
|
|
private _observer: INopeObserver[] = [];
|
|
|
|
|
|
|
|
private async __refresh() {
|
|
|
|
const connected = this.props.dispatcher.communicator.connected.getContent();
|
|
|
|
const modules = this.props.dispatcher.availableInstances
|
|
|
|
.getContent()
|
|
|
|
.filter((mod) => mod.type == "BeckhoffPlc");
|
|
|
|
|
|
|
|
const plcs: (IBeckhoffPLC & INopeModule)[] = [];
|
|
|
|
for (const plc of modules) {
|
|
|
|
const mod = await this.props.dispatcher.generateInstance<
|
|
|
|
IBeckhoffPLC & INopeModule
|
|
|
|
>({
|
|
|
|
identifier: plc.identifier,
|
|
|
|
type: plc.type
|
|
|
|
});
|
|
|
|
|
|
|
|
plcs.push(mod);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dispose the old instances
|
|
|
|
for (const plc of this.state.instances || []) {
|
|
|
|
await plc.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
instances: plcs,
|
|
|
|
connected
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function will be called if the Item has been rendered sucessfully.
|
|
|
|
*/
|
|
|
|
componentDidMount() {
|
|
|
|
if (this.props.dispatcher) {
|
|
|
|
// Subscribe to the Instances.
|
|
|
|
|
|
|
|
this.__refresh();
|
|
|
|
|
|
|
|
const _this = this;
|
|
|
|
|
|
|
|
this._observer.push(
|
|
|
|
this.props.dispatcher.availableInstances.subscribe(() => {
|
|
|
|
_this.__refresh().catch(console.error);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
this._observer.push(
|
|
|
|
this.props.dispatcher.communicator.connected.subscribe(() => {
|
|
|
|
_this.__refresh().catch(console.error);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function, that will be called before the network fails.
|
|
|
|
*/
|
|
|
|
componentWillUnmount() {
|
|
|
|
// Call the unmount
|
|
|
|
for (const _observer of this._observer) {
|
|
|
|
_observer.unsubscribe();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
instances: [],
|
|
|
|
connected: false
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
public render() {
|
|
|
|
const idx = 0;
|
|
|
|
return (
|
|
|
|
<Container>
|
|
|
|
<Toolbar<undefined>
|
|
|
|
toolbar={{
|
|
|
|
items: [
|
|
|
|
{
|
|
|
|
icon: faHome,
|
|
|
|
label: "root",
|
|
|
|
ref: "/",
|
|
|
|
type: "link"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "link",
|
|
|
|
ref: "/docs",
|
|
|
|
label: "docs",
|
|
|
|
icon: faHashtag
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}}
|
|
|
|
generateData={() => undefined}
|
|
|
|
brand={{
|
|
|
|
ref: "",
|
|
|
|
type: "link",
|
|
|
|
icon:
|
|
|
|
"https://upload.wikimedia.org/wikipedia/commons/thumb/1/13/Beckhoff_Logo.svg/1024px-Beckhoff_Logo.svg.png",
|
|
|
|
label: ""
|
|
|
|
}}
|
|
|
|
></Toolbar>
|
|
|
|
<Row>
|
|
|
|
<Col>
|
|
|
|
{this.state.connected ? (
|
|
|
|
<Alert variant={"success"}>Backend online</Alert>
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
<Alert variant={"danger"}>
|
|
|
|
Not able to connect to the Backend <b>:'(</b>
|
|
|
|
</Alert>
|
|
|
|
<p>
|
|
|
|
Please start a Nope-Backend with the following command:{" "}
|
|
|
|
<code>
|
|
|
|
node .\dist\lib\cli\runNopeBackend.js -c io-server
|
|
|
|
</code>
|
|
|
|
</p>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Row>
|
|
|
|
<Col>
|
|
|
|
{/* Available PLCs */}
|
|
|
|
<Table striped bordered hover>
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>PLC-Module-Name</th>
|
|
|
|
<th>Type</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{this.state.instances.map((instance, idx) => {
|
|
|
|
return (
|
|
|
|
<tr key={idx++}>
|
|
|
|
<td>{instance.identifier}</td>
|
|
|
|
<td>
|
|
|
|
<code>{instance.type}</code>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</tbody>
|
|
|
|
</Table>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
{this.state.instances.map((instance, idx) => {
|
|
|
|
return (
|
|
|
|
<Row key={idx} style={{ paddingTop: "1rem" }}>
|
|
|
|
<Col>
|
|
|
|
<BeckhoffComponent instance={instance}></BeckhoffComponent>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</Container>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default BeckhoffOverviewComponent;
|