Skip to content

Commit

Permalink
Revert "feat: Added time series data display [PT-186741112]"
Browse files Browse the repository at this point in the history
  • Loading branch information
dougmartin authored Jun 18, 2024
1 parent 8283460 commit df84315
Show file tree
Hide file tree
Showing 16 changed files with 59 additions and 237 deletions.
4 changes: 2 additions & 2 deletions src/sensors/device-sensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ export class DeviceSensor extends Sensor {
});
}

public collectTimeSeries(measurementPeriod: number, callback: (values: IDataTableTimeData[]) => void): () => void {
public collectTimeSeries(timeSeriesCapabilities: ITimeSeriesCapabilities, callback: (values: IDataTableTimeData[]) => void): () => void {
if (this.device) {
return this.device.collectTimeSeries(measurementPeriod, callback);
return this.device.collectTimeSeries(timeSeriesCapabilities, callback);
}
return () => {
// noop
Expand Down
2 changes: 1 addition & 1 deletion src/sensors/devices/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class Device {
return undefined; // set in each device
}

public collectTimeSeries(measurementPeriod: number, callback: (values: IDataTableTimeData[]) => void): () => void {
public collectTimeSeries(options: ITimeSeriesCapabilities, callback: (values: IDataTableTimeData[]) => void): () => void {
throw new Error("collectTimeSeries() method not overridden!");
}

Expand Down
23 changes: 10 additions & 13 deletions src/sensors/devices/gdx-sensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ISensorCapabilities, ISensorValues, ITimeSeriesCapabilities } from "../
import { IDataTableTimeData } from "../../shared/components/data-table-field";

const goDirectServiceUUID = "d91714ef-28b9-4f91-ba16-f0d9a604f112";
const defaultMeasurementPeriod = 100;
const measurementPeriod = 100;

// NOTE: to add a new sensor using the existing global capabilities add the prefix to the array
// and update the mapping of the sensor name to the capability below. More work will be
Expand Down Expand Up @@ -44,31 +44,28 @@ export class GDXSensorDevice extends Device {
return this._timeSeriesCapabilities;
}

public collectTimeSeries(measurementPeriod: number, callback: (values: IDataTableTimeData[]) => void): () => void {
public collectTimeSeries(timeSeriesCapabilities: ITimeSeriesCapabilities, callback: (values: IDataTableTimeData[]) => void): () => void {
const sensor = this.gdxDevice?.sensors.find((s: any) => s.enabled);

if (!this.gdxDevice || !sensor || !this.timeSeriesCapabilities) {
if (!this.gdxDevice || !sensor) {
return () => {
// noop
};
}

let time = 0;
const delta = measurementPeriod / 1000;
const delta = timeSeriesCapabilities.measurementPeriod / 1000;
const values: IDataTableTimeData[] = [];
const capabilities = {...this.timeSeriesCapabilities, measurementPeriod};

this.gdxDevice.stop();

const handleChange = () => {
if (values.length === 0) {
values.push({time, value: sensor.value, capabilities});
} else {
values.push({time, value: sensor.value});
}
values.push({time, value: sensor.value});
callback(values);
time += delta;
};
sensor.on("value-changed", handleChange);
this.gdxDevice.start(measurementPeriod);
this.gdxDevice.start(timeSeriesCapabilities.measurementPeriod);

return () => {
sensor.off("value-changed", handleChange);
Expand Down Expand Up @@ -102,7 +99,7 @@ export class GDXSensorDevice extends Device {
const measurement: string = firstSensor.name;
const valueKey = measurement.toLowerCase();
this._timeSeriesCapabilities = {
measurementPeriod: defaultMeasurementPeriod,
measurementPeriod,
measurement,
valueKey,
units: firstSensor.unit,
Expand All @@ -114,7 +111,7 @@ export class GDXSensorDevice extends Device {
}

this.gdxDevice = gdxDevice;
this.gdxDevice.start(defaultMeasurementPeriod);
this.gdxDevice.start(measurementPeriod);

resolve();
}).catch(reject);
Expand Down
21 changes: 8 additions & 13 deletions src/sensors/mock-sensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ export class MockSensor extends Sensor {
illuminance: options.minValues?.illuminance || 0,
temperature: options.minValues?.temperature || -18,
humidity: options.minValues?.humidity || 0,
timeSeries: options.minValues?.timeSeries || -5,
timeSeries: options.minValues?.timeSeries || -50,
};
this.maxMockValues = {
illuminance: options.maxValues?.illuminance || 10000,
temperature: options.maxValues?.temperature || 38,
humidity: options.maxValues?.humidity || 90,
timeSeries: options.maxValues?.timeSeries || 5,
timeSeries: options.maxValues?.timeSeries || 50,
};
this.mockValues = {
illuminance: this.randomInRange("illuminance"),
Expand Down Expand Up @@ -132,31 +132,26 @@ export class MockSensor extends Sensor {
return Promise.resolve(values);
}

public get timeSeriesCapabilities(): ITimeSeriesCapabilities {
public get timeSeriesCapabilities(): ITimeSeriesCapabilities|undefined {
return {
measurementPeriod: 100,
measurement: "Fake Value",
valueKey: "timeSeries",
units: "N/A",
minValue: -5,
maxValue: 5,
minValue: -50,
maxValue: 50,
};
}

public collectTimeSeries(measurementPeriod: number, callback: (values: IDataTableTimeData[]) => void): () => void {
public collectTimeSeries({measurementPeriod}: ITimeSeriesCapabilities, callback: (values: IDataTableTimeData[]) => void): () => void {
let time = 0;
const delta = measurementPeriod / 1000;
const values: IDataTableTimeData[] = [];
const capabilities = {...this.timeSeriesCapabilities, measurementPeriod};

const callCallback = () => {
const value = this.mockValues.timeSeries;
this.setNextRandomMockValue({measurement: "timeSeries", increment: 0.5});
if (values.length === 0) {
values.push({time, value, capabilities});
} else {
values.push({time, value});
}
this.setNextRandomMockValue({measurement: "timeSeries", increment: 0.2});
values.push({time, value});
callback(values);
time += delta;
};
Expand Down
2 changes: 1 addition & 1 deletion src/sensors/sensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export class Sensor extends EventEmitter<SensorEvent> {
}
}

public collectTimeSeries(measurementPeriod: number, callback: (values: IDataTableTimeData[]) => void): () => void {
public collectTimeSeries(options: ITimeSeriesCapabilities, callback: (values: IDataTableTimeData[]) => void): () => void {
throw new Error("collectTimeSeries() method not overridden!");
}

Expand Down
60 changes: 27 additions & 33 deletions src/shared/components/data-table-field.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import React, { useState, useEffect, useRef, useMemo, useCallback } from "react";
import React, { useState, useEffect, useRef, useMemo } from "react";
import { FieldProps } from "react-jsonschema-form";
import { MockSensor } from "../../sensors/mock-sensor";
import { ISensorCapabilities, ISensorConnectionEventData, ITimeSeriesCapabilities, MaxNumberOfTimeSeriesValues, SensorCapabilityKey, SensorEvent } from "../../sensors/sensor";
import { ISensorCapabilities, ISensorConnectionEventData, ITimeSeriesCapabilities, SensorCapabilityKey, SensorEvent } from "../../sensors/sensor";
import { SensorComponent } from "../../mobile-app/components/sensor";
import { IVortexFormContext } from "./form";
import { getURLParam } from "../utils/get-url-param";
import { DeviceSensor } from "../../sensors/device-sensor";
import { JSONSchema7 } from "json-schema";
import { IFormUiSchema } from "../experiment-types";
import { Icon, IconName } from "./icon";
import { Icon } from "./icon";
import { useSensor } from "../../mobile-app/hooks/use-sensor";
import { tableKeyboardNav } from "../utils/table-keyboard-nav";
import { confirm, alert } from "../utils/dialogs";
import { handleSpecialValue, isFunctionSymbol } from "../utils/handle-special-value";
import css from "./data-table-field.module.scss";
import DataTableSparkGraph from "./data-table-sparkgraph";

const defPrecision = 2;

Expand Down Expand Up @@ -53,7 +52,7 @@ interface IDataTableDataSchema {
};
}

export type IDataTableTimeData = {time: number, value: number, capabilities?: ITimeSeriesCapabilities};
export type IDataTableTimeData = {time: number, value: string|number};
export type IDataTableRowData = string | number | IDataTableTimeData[] | undefined;

// Form data accepted by this component.
Expand Down Expand Up @@ -176,12 +175,6 @@ export const DataTableField: React.FC<FieldProps> = props => {
const waitForSensorIntervalRef = useRef(0);
const stopTimeSeriesFnRef = useRef<(() => void)|undefined>(undefined);
const timeSeriesRecordingRowRef = useRef<number|undefined>(undefined);
const maxNumTimeSeriesValues = useMemo(() => {
const result = isTimeSeries ? formData.reduce<number>((acc, {timeSeries}) => {
return Math.max(acc, Array.isArray(timeSeries) ? timeSeries.length : 0);
}, 0) : 0;
return result;
}, [isTimeSeries, formData]);

// listen for prop changes from uploads
useEffect(() => {
Expand Down Expand Up @@ -333,19 +326,14 @@ export const DataTableField: React.FC<FieldProps> = props => {
};

const recordTimeSeries = () => {
if (!sensor) {
if (!sensor || !timeSeriesCapabilities) {
return;
}

stopTimeSeriesFnRef.current = sensor.collectTimeSeries(100, (values) => {
stopTimeSeriesFnRef.current = sensor.collectTimeSeries(timeSeriesCapabilities, (values) => {
const newData = formData.slice();
newData[rowIdx] = {timeSeries: values};
if (values.length <= MaxNumberOfTimeSeriesValues) {
setFormData(newData);
}
if (values.length === MaxNumberOfTimeSeriesValues) {
onSensorStopTimeSeries(newData);
}
setFormData(newData);
});
timeSeriesRecordingRowRef.current = rowIdx;
};
Expand All @@ -365,13 +353,11 @@ export const DataTableField: React.FC<FieldProps> = props => {
}
};

const onSensorStopTimeSeries = (finalData: IDataTableRow[]) => {
if (stopTimeSeriesFnRef.current) {
stopTimeSeriesFnRef.current?.();
stopTimeSeriesFnRef.current = undefined;
timeSeriesRecordingRowRef.current = undefined;
saveData(finalData);
}
const onSensorStopTimeSeries = () => {
stopTimeSeriesFnRef.current?.();
stopTimeSeriesFnRef.current = undefined;
timeSeriesRecordingRowRef.current = undefined;
saveData(formData);
};

const renderRow = (row: { [k: string]: any }, rowIdx: number) => {
Expand All @@ -389,9 +375,8 @@ export const DataTableField: React.FC<FieldProps> = props => {
});
const recordingTimeSeries = stopTimeSeriesFnRef.current !== undefined;
const rowActive = recordingTimeSeries ? (sensorCanRecord && timeSeriesRecordingRowRef.current === rowIdx) : sensorCanRecord;
const showStopButton = recordingTimeSeries && timeSeriesRecordingRowRef.current === rowIdx;
const iconName: IconName = sensorFieldsBlank ? (isTimeSeries ? "recordDataTrial" : "record") : (isTimeSeries ? (showStopButton ? "stopDataTrial" : "reRecordDataTrial") : "replay");
const onClick = rowActive ? (recordingTimeSeries ? onSensorStopTimeSeries.bind(null, formData) : onSensorRecordClick.bind(null, rowIdx)) : null;
const iconName = sensorFieldsBlank ? "record" : "replay";
const onClick = rowActive ? (recordingTimeSeries ? onSensorStopTimeSeries : onSensorRecordClick.bind(null, rowIdx)) : null;
const refreshBtnCell = <td key="refreshBtn" className={`${css.refreshSensorReadingColumn} ${css.readOnly}`}>
{
anyNonFunctionSensorValues &&
Expand Down Expand Up @@ -436,6 +421,15 @@ export const DataTableField: React.FC<FieldProps> = props => {
);
};

const renderTimeSeries = (values: IDataTableTimeData[]) => {
if (values.length === 0) {
return null;
}

const lastValue = values[values.length - 1];
return <div>{lastValue.value} ({values.length})</div>;
};

const renderBasicCells = (fieldNames: string[], row: { [k: string]: any }, rowIdx: number) => {
let sensorFieldsBlank = true;
sensorFields.forEach((name: string) => {
Expand Down Expand Up @@ -470,11 +464,11 @@ export const DataTableField: React.FC<FieldProps> = props => {
}

let contents;
if (name === "timeSeries") {
contents = <DataTableSparkGraph values={value || []} maxNumTimeSeriesValues={maxNumTimeSeriesValues} />;
} else if (readOnly) {
if (readOnly) {
contents = <div className={css.valueCell}>{value}</div>;
} else if (fieldDefinition[name].type === "array") {
} else if (name === "timeSeries") {
contents = renderTimeSeries(value);
}else if (fieldDefinition[name].type === "array") {
contents = renderSelect({name, value, rowIdx, items: (fieldDefinition[name] as IDataTableArrayField).items});
} else {
const input = renderInput({ name, value, rowIdx, disabled: isFunction || (isSensorField && !manualEntryMode), error });
Expand Down
35 changes: 0 additions & 35 deletions src/shared/components/data-table-sparkgraph.module.scss

This file was deleted.

Loading

0 comments on commit df84315

Please sign in to comment.