Really messy diagnostic checker. Needs refactored.

pull/469/head
Rick Carlino 2017-09-26 10:26:42 -05:00
parent fc1168c739
commit 2bf9d7b713
2 changed files with 23 additions and 144 deletions

View File

@ -1,76 +0,0 @@
import * as React from "react";
import { Widget, WidgetHeader, WidgetBody, Row, Col } from "../ui/index";
import { t } from "i18next";
import { CowardlyDictionary } from "../util";
interface Props {
rowData: StatusRowProps[];
}
interface State {
}
export class ConnectivityPanel extends React.Component<Props, State> {
state: State = {};
render() {
return <Widget className="device-widget">
<WidgetHeader
title={t("Connectivity")}
helpText={t("Diagnose connectivity issues with FarmBot and the browser.")} />
<WidgetBody>
<ConnectivityRow from="from" to="to" />
{this
.props
.rowData
.map((x, y) => <ConnectivityRow {...x} key={y} />)}
<Row>
<Col xs={12}>
<h3>Diagnosis</h3>
<p>
We will interpret results and stuff here.
</p>
</Col>
</Row>
</WidgetBody>
</Widget>;
}
}
/** Data model for a single row within the <ConnectivityPanel /> */
export interface StatusRowProps {
connectionStatus?: boolean | undefined;
from: string;
to: string;
children?: React.ReactChild;
}
const iconLookup: CowardlyDictionary<string> = {
true: "fa fa-thumbs-up",
false: "fa fa-thumbs-down"
};
function ConnectivityRow(props: StatusRowProps) {
const className = iconLookup["" + props.connectionStatus] || "fa fa-question";
return <Row>
<Col xs={1}>
<i className={className}></i>
</Col>
<Col xs={1}>
<p>
{props.from}
</p>
</Col>
<Col xs={1}>
<p>
{props.to}
</p>
</Col>
<Col xs={9}>
<p>
{props.children}
</p>
</Col>
</Row>;
}

View File

@ -5,23 +5,31 @@ import { FarmbotOsSettings } from "./components/farmbot_os_settings";
import { Page, Col, Row } from "../ui";
import { mapStateToProps } from "./state_to_props";
import { Props } from "./interfaces";
import { ConnectivityPanel, StatusRowProps } from "./connectivity_panel";
import * as moment from "moment";
import { isUndefined } from "lodash";
import { StatusRowProps, ConnectivityPanel } from "./connectivity/index";
import { botToMQTT, botToAPI, browserToMQTT } from "./connectivity/status_checks";
import { Diagnosis, DiagnosisProps } from "./connectivity/diagnosis";
@connect(mapStateToProps)
export class Devices extends React.Component<Props, {}> {
state = { online: navigator.onLine };
get rowData(): StatusRowProps[] {
/** A record of all the things we know about connectivity right now. */
get flags(): Record<keyof DiagnosisProps, StatusRowProps> {
const mqttUrl = this.props.auth && this.props.auth.token.unencoded.mqtt;
const mqttConnected = this.props.bot.connectedToMQTT;
const lastSeen = this.props.deviceAccount.body.last_seen;
const timstmp = this.props.bot.hardware.user_env["LAST_CLIENT_CONNECTED"];
return [
botToMQTT(timstmp),
botToAPI(lastSeen ? moment(lastSeen) : undefined, moment()),
browserToMQTT(mqttUrl, mqttConnected)
];
const timstamp = this.props.bot.hardware.user_env["LAST_CLIENT_CONNECTED"];
return {
botMQTT: botToMQTT(timstamp),
botAPI: botToAPI(lastSeen ? moment(lastSeen) : undefined, moment()),
userMQTT: browserToMQTT(mqttUrl, mqttConnected)
};
}
/** Shuffle these around to change the ordering of the status table. */
get rowData(): StatusRowProps[] {
return [this.flags.botMQTT, this.flags.botAPI, this.flags.userMQTT];
}
render() {
@ -44,7 +52,12 @@ export class Devices extends React.Component<Props, {}> {
</Row>
<Row>
<Col xs={12} sm={6}>
<ConnectivityPanel rowData={this.rowData} />
<ConnectivityPanel rowData={this.rowData}>
<Diagnosis
botMQTT={!!this.flags.botMQTT.connectionStatus}
botAPI={!!this.flags.botAPI.connectionStatus}
userMQTT={!!this.flags.userMQTT.connectionStatus} />
</ConnectivityPanel>
</Col>
</Row>
</Page>;
@ -53,61 +66,3 @@ export class Devices extends React.Component<Props, {}> {
}
}
}
const HOUR = 1000 * 60 * 60;
const TWO_HOURS = HOUR * 2;
function botToAPI(lastSeen: moment.Moment | undefined,
now = moment()): StatusRowProps {
// TODO: Complexity is getting high on this one.
// Refactor if more business requirements are added.
const diff = lastSeen && now.diff(lastSeen);
const ago = moment(lastSeen).fromNow();
const status: StatusRowProps = {
from: "Bot",
to: "API",
connectionStatus: undefined,
children: "?"
};
if (isUndefined(diff)) {
status.connectionStatus = false;
status.children = "We have not seen messages from FarmBot yet.";
}
if (diff && (diff > TWO_HOURS)) {
status.connectionStatus = false;
status.children =
`Have not heard from bot in ${ago}.`;
} else {
status.connectionStatus = true;
status.children = `Last seen ${ago}.`;
}
return status;
}
function botToMQTT(lastSeen: string | undefined): StatusRowProps {
const output: StatusRowProps = {
from: "Bot",
to: "MQTT",
connectionStatus: false,
children: "We are not seeing any realtime messages from the bot right now."
};
if (lastSeen) {
output.connectionStatus = true;
output.children = `Connected ${moment(new Date(JSON.parse(lastSeen))).fromNow()}`;
}
return output;
}
function browserToMQTT(mqttUrl: string | undefined, online?: boolean): StatusRowProps {
const url = `mqtt://${mqttUrl}`;
return {
from: "Browser",
to: "MQTT",
children: online ? ("Connected to " + url) : "Unable to connect",
connectionStatus: online
};
}