Adds files to read from Meshify and display channel data

This commit is contained in:
Patrick McDonagh
2017-08-11 17:57:23 -05:00
parent 44f3318ca2
commit f56e48fc94
14 changed files with 28713 additions and 0 deletions

1
.babelrc Normal file
View File

@@ -0,0 +1 @@
{ presets: ['react']}

9
app/components/App.js Normal file
View File

@@ -0,0 +1,9 @@
import React from 'react';
import {DeviceListContainer} from './DeviceListContainer';
export class App extends React.Component {
render(){
return <DeviceListContainer />;
}
}

15
app/components/Channel.js Normal file
View File

@@ -0,0 +1,15 @@
import React from 'react';
export class Channel extends React.Component {
render(){
const timestamp = new Date(this.props.timestamp * 1000);
return (
<tr>
<td>{this.props.name}</td>
<td>{this.props.value}</td>
<td>{timestamp.toLocaleString()}</td>
</tr>
);
}
}

108
app/components/Device.js Normal file
View File

@@ -0,0 +1,108 @@
import React from 'react';
import {auth, baseURL} from './Meshify';
import {Channel} from './Channel';
export class Device extends React.Component {
constructor(props){
super(props);
this.state = {channels: []};
this.getChannels = this.getChannels.bind(this);
this.showChannels = this.showChannels.bind(this);
this.hideChannels = this.hideChannels.bind(this);
}
getChannels(){
let t = this;
const deviceId = this.props.deviceId;
$.ajax({
type: "GET",
dataType: 'json',
url: baseURL + 'devices/' + deviceId + '/values',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", auth.authType + " " + auth.token);
},
success: function(data){
let channels = [];
for (var c in data){
let newChan = {};
newChan.name = c;
newChan.timestamp = data[c].timestamp;
newChan.value = data[c].value;
channels.push(newChan);
}
t.setState({channels: channels});
}
})
}
hideChannels(){
this.setState({
channels: []
})
}
showChannels(){
this.getChannels();
}
render(){
const deviceName = this.props.name;
const deviceType = this.props.deviceType;
const deviceId = this.props.deviceId;
const channelList = this.state.channels.map(function(ch, i){
return <Channel key={deviceId + "_channel_" + i}
name={ch.name}
timestamp={ch.timestamp}
value={ch.value} />
});
const deviceDisplay = (
<h3 className="ui header">{deviceName} [{deviceType}]</h3>
)
const channelHideButton = <button className="ui button" onClick={this.hideChannels}>Hide Channels</button>;
const channelTable = (
<table className="ui celled table">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
{channelList}
</tbody>
</table>
);
const channelShowButton = <button className="ui primary button" onClick={this.showChannels}>Fetch and Show Channels</button>;
if (this.state.channels.length > 0){
return (
<div className="ui row">
<div className="ui column">
{deviceDisplay}
{channelHideButton}
{channelTable}
</div>
</div>
);
} else {
return (
<div className="ui row">
<div className="ui column">
{deviceDisplay}
{channelShowButton}
</div>
</div>
);
}
}
}

View File

@@ -0,0 +1,93 @@
import React from 'react';
import {auth, baseURL} from './Meshify';
import {Device} from './Device';
const hiddenDevices = ["M1", "Gateway"];
export class DeviceList extends React.Component {
constructor(props){
super(props);
this.getDeviceData = this.getDeviceData.bind(this);
this.state = {devices: {}, deviceTypes: []};
}
componentDidMount() {
this.getDeviceData();
}
getDeviceData(){
let t = this;
// Start by getting all device types
$.ajax({
type: "GET",
dataType: 'json',
url: baseURL + 'devicetypes',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", auth.authType + " " + auth.token);
},
success: function(data){
let deviceTypes = {};
for (let i = 0; i < data.length; i++){
deviceTypes[data[i].id] = data[i]
t.setState((previousState) => {
previousState.devices[data[i].vanityName] = [];
return previousState;
})
}
t.setState({deviceTypes: deviceTypes});
// Once all device types have been stored, get devices and map them into
// their respective devices.<type> array
$.ajax({
type: "GET",
dataType: 'json',
url: baseURL + 'devices',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", auth.authType + " " + auth.token);
},
success: function(data){
for (let i = 0; i < data.length; i++){
t.setState((previousState) => {
const typeVanityName = t.state.deviceTypes[data[i].deviceTypeId].vanityName;
previousState.devices[typeVanityName].push(data[i]);
return previousState;
})
}
}
})
}
})
}
rDeviceType(arrOfDevices, deviceTypeName){
if ((arrOfDevices.length > 0) && (hiddenDevices.indexOf(deviceTypeName) === -1)){
let devices = arrOfDevices.map((dev, i) => {
return (
<Device key={"device_" + i} deviceId={dev.id}
deviceType={deviceTypeName}
name={dev.vanityName} />
);
});
return(
<div>
<h2 className="ui dividing header">{deviceTypeName}</h2>
<div className="ui grid">{devices}</div>
</div>
)
}
}
render(){
let devices = [];
for (let i in this.state.devices){
devices.push(this.rDeviceType(this.state.devices[i], i))
}
return (
<div className="ui container">
<h1 className="ui dividing header">All Devices</h1>
{devices}
</div>
);
}
}

View File

@@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';
import {DeviceList} from './DeviceList';
export class DeviceListContainer extends React.Component {
render(){
return <DeviceList />;
}
}

14
app/components/Meshify.js Normal file
View File

@@ -0,0 +1,14 @@
const authType = "Basic"
const username = "api@henry-pump.com";
const password = "HenryPump@1903"
const authToken = btoa(username + ":" + password);
export const auth = {
username: username,
authType: authType,
token: authToken
}
export const baseURL = "https://henrypump.meshify.com/api/v3/";

9
app/index.html Normal file
View File

@@ -0,0 +1,9 @@
<html>
<head>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.11/semantic.min.css"></link>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>

10
app/index.js Normal file
View File

@@ -0,0 +1,10 @@
// var React = require('react');
// var ReactDOM = require('react-dom');
// var App = require('./components/App');
// var $ = require("jquery");
import React from 'react';
import ReactDOM from 'react-dom';
import {App} from './components/App'
ReactDOM.render(<App />, document.getElementById('app'));

9
build/index.html Normal file
View File

@@ -0,0 +1,9 @@
<html>
<head>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.11/semantic.min.css"></link>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="transformed.js"></script></body>
</html>

22767
build/transformed.js Normal file

File diff suppressed because it is too large Load Diff

5617
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "react-test",
"version": "1.0.0",
"description": "Test of ReactJS",
"main": "index.js",
"scripts": {
"build": "webpack",
"start": "webpack-dev-server"
},
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.2.1",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"semantic-ui-react": "^0.71.4"
},
"devDependencies": {
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-react": "^6.24.1",
"html-webpack-plugin": "^2.30.1",
"webpack": "^3.5.3",
"webpack-dev-server": "^2.7.1"
}
}

24
webpack.config.js Normal file
View File

@@ -0,0 +1,24 @@
var HTMLWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HTMLWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: __dirname + '/app/index.js',
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
output: {
filename: 'transformed.js',
path: __dirname + '/build'
},
plugins: [HTMLWebpackPluginConfig]
};