Sync tool status across all clients
This commit is contained in:
parent
a1c80c70cb
commit
0c59652222
|
@ -4,29 +4,62 @@ import Category from './Category';
|
||||||
import Tool from './Tool';
|
import Tool from './Tool';
|
||||||
import { Container, Dimmer, Dropdown, Header, Icon, Item, Loader, Menu, Segment, Input } from 'semantic-ui-react';
|
import { Container, Dimmer, Dropdown, Header, Icon, Item, Loader, Menu, Segment, Input } from 'semantic-ui-react';
|
||||||
import { Link, Route } from 'react-router-dom';
|
import { Link, Route } from 'react-router-dom';
|
||||||
|
import io from 'socket.io-client';
|
||||||
|
|
||||||
|
// Move to env var
|
||||||
|
const SERVER_URL = "http://localhost:8080";
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this.socket = io(SERVER_URL);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
user: null,
|
user: null,
|
||||||
toolData: null,
|
toolData: null,
|
||||||
|
toolStatus: null,
|
||||||
|
connected: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
fetch('http://localhost:8080/api/tooldata')
|
fetch(SERVER_URL + '/api/tooldata')
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => this.setState({ toolData: data }));
|
.then(data => this.setState({ toolData: data }));
|
||||||
fetch('http://localhost:8080/api/user')
|
fetch(SERVER_URL + '/api/user')
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => this.setState({ user: data }));
|
.then(data => this.setState({ user: data }));
|
||||||
|
|
||||||
|
this.socket.on('toolStatus', toolStatus =>
|
||||||
|
this.setState({ toolStatus: toolStatus })
|
||||||
|
);
|
||||||
|
|
||||||
|
this.socket.on('connect', toolStatus =>
|
||||||
|
this.setState({ connected: true })
|
||||||
|
);
|
||||||
|
|
||||||
|
this.socket.on('disconnect', toolStatus =>
|
||||||
|
this.setState({ toolStatus: null, connected: false })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.socket.removeAllListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
requestInterlock = change => {
|
||||||
|
this.socket.emit('requestInterlock', {
|
||||||
|
username: this.state.user.username,
|
||||||
|
change: change,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const toolData = this.state.toolData;
|
const toolData = this.state.toolData;
|
||||||
|
const toolStatus = this.state.toolStatus;
|
||||||
const user = this.state.user;
|
const user = this.state.user;
|
||||||
|
const connected = this.state.connected;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -37,6 +70,9 @@ class App extends Component {
|
||||||
<Menu.Item as={Link} to='/'>
|
<Menu.Item as={Link} to='/'>
|
||||||
<Icon name='home' size='big' />
|
<Icon name='home' size='big' />
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
<Icon name='circle' color={connected ? 'green' : 'red'} />
|
||||||
|
</Menu.Item>
|
||||||
<Menu.Menu position='right'>
|
<Menu.Menu position='right'>
|
||||||
<Menu.Item position='right'>
|
<Menu.Item position='right'>
|
||||||
<Input transparent inverted placeholder='Search...' icon='search' />
|
<Input transparent inverted placeholder='Search...' icon='search' />
|
||||||
|
@ -49,7 +85,7 @@ class App extends Component {
|
||||||
{toolData && user ?
|
{toolData && user ?
|
||||||
<div>
|
<div>
|
||||||
<Route exact path='/' render={props =>
|
<Route exact path='/' render={props =>
|
||||||
<Categories {...props} data={toolData} user={user} />
|
<Categories {...props} data={toolData} />
|
||||||
} />
|
} />
|
||||||
|
|
||||||
<Route exact path='/:category' render={props =>
|
<Route exact path='/:category' render={props =>
|
||||||
|
@ -57,7 +93,12 @@ class App extends Component {
|
||||||
} />
|
} />
|
||||||
|
|
||||||
<Route exact path='/:category/:id' render={props =>
|
<Route exact path='/:category/:id' render={props =>
|
||||||
<Tool {...props} data={toolData} user={user} />
|
<Tool {...props}
|
||||||
|
data={toolData}
|
||||||
|
user={user}
|
||||||
|
toolStatus={toolStatus}
|
||||||
|
requestInterlock={this.requestInterlock}
|
||||||
|
/>
|
||||||
} />
|
} />
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Category extends Component {
|
||||||
const user = this.props.user;
|
const user = this.props.user;
|
||||||
const match = this.props.match;
|
const match = this.props.match;
|
||||||
|
|
||||||
const category = data.categories.find((x) =>
|
const category = data.categories.find(x =>
|
||||||
x.slug === match.params.category
|
x.slug === match.params.category
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,41 @@ import { Breadcrumb, Button, Container, Dropdown, Header, Icon, Image, Item, Lab
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
class Tool extends Component {
|
class Tool extends Component {
|
||||||
|
decodeStatus = status => {
|
||||||
|
if (status === null) {
|
||||||
|
return { msg: 'Unknown! Connection error?', canArm: false, canDisarm: false, };
|
||||||
|
} else if (!status.armed && !status.on) {
|
||||||
|
return { msg: 'Off', canArm: true, canDisarm: false, };
|
||||||
|
} else if (status.armed && !status.on) {
|
||||||
|
return { msg: 'Armed', canArm: false, canDisarm: true, };
|
||||||
|
} else if (status.armed && status.on) {
|
||||||
|
return { msg: 'On', canArm: false, canDisarm: true, };
|
||||||
|
} else if (!status.armed && status.on) {
|
||||||
|
return { msg: 'Error: Impossible state!', canArm: false, canDisarm: false, };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const data = this.props.data;
|
const data = this.props.data;
|
||||||
const user = this.props.user;
|
const user = this.props.user;
|
||||||
const match = this.props.match;
|
const match = this.props.match;
|
||||||
|
const toolStatus = this.props.toolStatus || [];
|
||||||
|
const requestInterlock = this.props.requestInterlock;
|
||||||
|
|
||||||
const category = data.categories.find((x) =>
|
const category = data.categories.find(x =>
|
||||||
x.slug === match.params.category
|
x.slug === match.params.category
|
||||||
);
|
);
|
||||||
|
|
||||||
const tool = category.tools.find((x) =>
|
const tool = category.tools.find(x =>
|
||||||
x.id.toString() === match.params.id
|
x.id.toString() === match.params.id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const status = toolStatus.find(x =>
|
||||||
|
x.id.toString() === match.params.id
|
||||||
|
) || null;
|
||||||
|
const decodedStatus = this.decodeStatus(status);
|
||||||
|
console.log(decodedStatus);
|
||||||
|
|
||||||
const approved = user.authorizedTools.includes(tool.id);
|
const approved = user.authorizedTools.includes(tool.id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -32,12 +54,18 @@ class Tool extends Component {
|
||||||
<Segment>
|
<Segment>
|
||||||
<Image src={tool.photo} size='medium' centered rounded />
|
<Image src={tool.photo} size='medium' centered rounded />
|
||||||
<Segment textAlign='center' basic>
|
<Segment textAlign='center' basic>
|
||||||
<p>Status: Off</p>
|
<p> Status: {decodedStatus.msg}</p>
|
||||||
<div>
|
<div>
|
||||||
<Button color='green' disabled={!approved}>
|
<Button color='green'
|
||||||
|
disabled={!approved || !decodedStatus.canArm}
|
||||||
|
onClick={() => requestInterlock({toolId: tool.id, action: 'arm',})}
|
||||||
|
>
|
||||||
<Icon name='lightning' /> Arm
|
<Icon name='lightning' /> Arm
|
||||||
</Button>
|
</Button>
|
||||||
<Button color='red' disabled={!approved}>
|
<Button color='red'
|
||||||
|
disabled={!approved || !decodedStatus.canDisarm}
|
||||||
|
onClick={() => requestInterlock({toolId: tool.id, action: 'disarm',})}
|
||||||
|
>
|
||||||
<Icon name='stop' /> Disarm
|
<Icon name='stop' /> Disarm
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
246
webserver/package-lock.json
generated
246
webserver/package-lock.json
generated
|
@ -13,11 +13,54 @@
|
||||||
"negotiator": "0.6.1"
|
"negotiator": "0.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"after": {
|
||||||
|
"version": "0.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
|
||||||
|
"integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
|
||||||
|
},
|
||||||
"array-flatten": {
|
"array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||||
},
|
},
|
||||||
|
"arraybuffer.slice": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
|
||||||
|
"integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
|
||||||
|
},
|
||||||
|
"async-limiter": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
|
||||||
|
},
|
||||||
|
"backo2": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
|
||||||
|
},
|
||||||
|
"base64-arraybuffer": {
|
||||||
|
"version": "0.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
|
||||||
|
"integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
|
||||||
|
},
|
||||||
|
"base64id": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY="
|
||||||
|
},
|
||||||
|
"better-assert": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
|
||||||
|
"requires": {
|
||||||
|
"callsite": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"blob": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
|
||||||
|
"integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE="
|
||||||
|
},
|
||||||
"body-parser": {
|
"body-parser": {
|
||||||
"version": "1.18.2",
|
"version": "1.18.2",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
|
||||||
|
@ -40,6 +83,26 @@
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||||
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
|
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
|
||||||
},
|
},
|
||||||
|
"callsite": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
|
||||||
|
},
|
||||||
|
"component-bind": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
|
||||||
|
},
|
||||||
|
"component-emitter": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||||
|
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
|
||||||
|
},
|
||||||
|
"component-inherit": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
|
||||||
|
},
|
||||||
"content-disposition": {
|
"content-disposition": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
|
||||||
|
@ -88,6 +151,61 @@
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||||
},
|
},
|
||||||
|
"engine.io": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.4.tgz",
|
||||||
|
"integrity": "sha1-PQIRtwpVLOhB/8fahiezAamkFi4=",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "1.3.3",
|
||||||
|
"base64id": "1.0.0",
|
||||||
|
"cookie": "0.3.1",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"engine.io-parser": "2.1.2",
|
||||||
|
"uws": "0.14.5",
|
||||||
|
"ws": "3.3.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
|
||||||
|
"integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
|
||||||
|
"requires": {
|
||||||
|
"mime-types": "2.1.17",
|
||||||
|
"negotiator": "0.6.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"engine.io-client": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.4.tgz",
|
||||||
|
"integrity": "sha1-T88TcLRxY70s6b4nM5ckMDUNTqE=",
|
||||||
|
"requires": {
|
||||||
|
"component-emitter": "1.2.1",
|
||||||
|
"component-inherit": "0.0.3",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"engine.io-parser": "2.1.2",
|
||||||
|
"has-cors": "1.1.0",
|
||||||
|
"indexof": "0.0.1",
|
||||||
|
"parseqs": "0.0.5",
|
||||||
|
"parseuri": "0.0.5",
|
||||||
|
"ws": "3.3.3",
|
||||||
|
"xmlhttprequest-ssl": "1.5.5",
|
||||||
|
"yeast": "0.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"engine.io-parser": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==",
|
||||||
|
"requires": {
|
||||||
|
"after": "0.8.2",
|
||||||
|
"arraybuffer.slice": "0.0.7",
|
||||||
|
"base64-arraybuffer": "0.1.5",
|
||||||
|
"blob": "0.0.4",
|
||||||
|
"has-binary2": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"escape-html": {
|
"escape-html": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
@ -159,6 +277,19 @@
|
||||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||||
},
|
},
|
||||||
|
"has-binary2": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=",
|
||||||
|
"requires": {
|
||||||
|
"isarray": "2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-cors": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
|
||||||
|
},
|
||||||
"http-errors": {
|
"http-errors": {
|
||||||
"version": "1.6.2",
|
"version": "1.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
|
||||||
|
@ -187,6 +318,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
||||||
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
||||||
},
|
},
|
||||||
|
"indexof": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
|
||||||
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
@ -197,6 +333,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
|
||||||
"integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
|
"integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
|
||||||
},
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
@ -240,6 +381,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
|
||||||
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
|
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
|
||||||
},
|
},
|
||||||
|
"object-component": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
|
||||||
|
},
|
||||||
"on-finished": {
|
"on-finished": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||||
|
@ -248,6 +394,22 @@
|
||||||
"ee-first": "1.1.1"
|
"ee-first": "1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"parseqs": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
|
||||||
|
"integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
|
||||||
|
"requires": {
|
||||||
|
"better-assert": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parseuri": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
|
||||||
|
"integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
|
||||||
|
"requires": {
|
||||||
|
"better-assert": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"parseurl": {
|
"parseurl": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||||
|
@ -329,11 +491,64 @@
|
||||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
|
||||||
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
|
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
|
||||||
},
|
},
|
||||||
|
"socket.io": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz",
|
||||||
|
"integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"engine.io": "3.1.4",
|
||||||
|
"socket.io-adapter": "1.1.1",
|
||||||
|
"socket.io-client": "2.0.4",
|
||||||
|
"socket.io-parser": "3.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-adapter": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs="
|
||||||
|
},
|
||||||
|
"socket.io-client": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz",
|
||||||
|
"integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=",
|
||||||
|
"requires": {
|
||||||
|
"backo2": "1.0.2",
|
||||||
|
"base64-arraybuffer": "0.1.5",
|
||||||
|
"component-bind": "1.0.0",
|
||||||
|
"component-emitter": "1.2.1",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"engine.io-client": "3.1.4",
|
||||||
|
"has-cors": "1.1.0",
|
||||||
|
"indexof": "0.0.1",
|
||||||
|
"object-component": "0.0.3",
|
||||||
|
"parseqs": "0.0.5",
|
||||||
|
"parseuri": "0.0.5",
|
||||||
|
"socket.io-parser": "3.1.2",
|
||||||
|
"to-array": "0.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-parser": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.2.tgz",
|
||||||
|
"integrity": "sha1-28IoIVH8T6675Aru3Ady66YZ9/I=",
|
||||||
|
"requires": {
|
||||||
|
"component-emitter": "1.2.1",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"has-binary2": "1.0.2",
|
||||||
|
"isarray": "2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
|
||||||
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
|
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
|
||||||
},
|
},
|
||||||
|
"to-array": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
|
||||||
|
"integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
|
||||||
|
},
|
||||||
"type-is": {
|
"type-is": {
|
||||||
"version": "1.6.15",
|
"version": "1.6.15",
|
||||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
|
||||||
|
@ -343,6 +558,11 @@
|
||||||
"mime-types": "2.1.17"
|
"mime-types": "2.1.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ultron": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
|
||||||
|
},
|
||||||
"unpipe": {
|
"unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
@ -353,10 +573,36 @@
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||||
},
|
},
|
||||||
|
"uws": {
|
||||||
|
"version": "0.14.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/uws/-/uws-0.14.5.tgz",
|
||||||
|
"integrity": "sha1-Z6rzPEaypYel9mZtAPdpEyjxSdw=",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"vary": {
|
"vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "3.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
|
||||||
|
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
|
||||||
|
"requires": {
|
||||||
|
"async-limiter": "1.0.0",
|
||||||
|
"safe-buffer": "5.1.1",
|
||||||
|
"ultron": "1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xmlhttprequest-ssl": {
|
||||||
|
"version": "1.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
|
||||||
|
"integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
|
||||||
|
},
|
||||||
|
"yeast": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.16.2"
|
"express": "^4.16.2",
|
||||||
|
"socket.io": "^2.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
|
// Hardcoded data - can only be changed by admin
|
||||||
const toolData = {
|
const toolData = {
|
||||||
categories: [
|
categories: [
|
||||||
{
|
{
|
||||||
|
@ -50,30 +51,60 @@ const toolData = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const user = {
|
// Hardcoded data - can only be changed by admin
|
||||||
|
const users = [
|
||||||
|
{
|
||||||
username: "protospace",
|
username: "protospace",
|
||||||
name: "Protospace User",
|
name: "Protospace User",
|
||||||
authorizedTools: [1, 2],
|
authorizedTools: [1, 2],
|
||||||
}
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Hardcoded data - can only be changed by admin
|
||||||
const lockoutData = {
|
const lockoutData = {
|
||||||
lockouts: [
|
lockouts: [
|
||||||
{
|
{
|
||||||
|
id: 0,
|
||||||
|
mac: 'ABCDEF000000',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
mac: '2C3AE843A15F',
|
mac: '2C3AE843A15F',
|
||||||
relayOn: false,
|
},
|
||||||
ledOn: true,
|
{
|
||||||
date: '2018-02-01',
|
id: 2,
|
||||||
|
mac: 'ABCDEF000002',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
mac: 'ABCDEF000003',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Derived data - changes through use of system
|
||||||
|
let toolStatus = lockoutData.lockouts.map(x => (
|
||||||
|
{
|
||||||
|
id: x.id,
|
||||||
|
on: false,
|
||||||
|
armed: false,
|
||||||
|
user: null,
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
console.log(toolStatus);
|
||||||
|
|
||||||
const server = app.listen(8080, function () {
|
const server = app.listen(8080, function () {
|
||||||
console.log('Example app listening on port 8080!');
|
console.log('Example app listening on port 8080!');
|
||||||
});
|
});
|
||||||
|
const io = require('socket.io')(server);
|
||||||
|
|
||||||
|
// Express http server stuff:
|
||||||
|
|
||||||
|
// TODO : remove on prod
|
||||||
app.use(function(req, res, next) {
|
app.use(function(req, res, next) {
|
||||||
res.header("Access-Control-Allow-Origin", "*");
|
res.header('Access-Control-Allow-Origin', '*');
|
||||||
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -90,7 +121,7 @@ app.get('/api/user', function (req, res) {
|
||||||
console.log('Request for user data');
|
console.log('Request for user data');
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.send(user);
|
res.send(users[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/api/lockout/:mac', function (req, res) {
|
app.get('/api/lockout/:mac', function (req, res) {
|
||||||
|
@ -106,3 +137,39 @@ app.get('/api/lockout/:mac', function (req, res) {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.send(JSON.stringify(data));
|
res.send(JSON.stringify(data));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Socket.io websocket stuff:
|
||||||
|
|
||||||
|
// TODO : remove on prod
|
||||||
|
io.origins('*:*');
|
||||||
|
|
||||||
|
io.on('connection', socket => {
|
||||||
|
socket.emit('toolStatus', toolStatus);
|
||||||
|
|
||||||
|
socket.on('requestInterlock', data => {
|
||||||
|
console.log('Interlock change requested: ' + data.toString());
|
||||||
|
|
||||||
|
const user = users.find(x => x.username === data.username);
|
||||||
|
const toolId = data.change.toolId;
|
||||||
|
const action = data.change.action;
|
||||||
|
|
||||||
|
// TODO ; Make this part prettier
|
||||||
|
if (user) {
|
||||||
|
if (user.authorizedTools.includes(data.change.toolId)) {
|
||||||
|
const toolIndex = toolStatus.findIndex(x => x.id === toolId);
|
||||||
|
let tool = toolStatus[toolIndex];
|
||||||
|
|
||||||
|
if (action === 'arm' && !tool.armed && !tool.on) {
|
||||||
|
tool.armed = true;
|
||||||
|
} else if (action === 'disarm' && tool.armed) {
|
||||||
|
tool.armed = false;
|
||||||
|
tool.on = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
toolStatus[toolIndex] = tool;
|
||||||
|
console.log(toolStatus);
|
||||||
|
io.sockets.emit('toolStatus', toolStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user