Skip to content

Commit

Permalink
integrate sensor position schema detection and parsing (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampsonj authored Dec 12, 2022
1 parent fed76af commit 322190a
Show file tree
Hide file tree
Showing 17 changed files with 962 additions and 226 deletions.
27 changes: 18 additions & 9 deletions lib/components/TimeSeriesViewer/TimeSeriesViewerContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ var _NeonApi = _interopRequireDefault(require("../NeonApi/NeonApi"));
var _NeonGraphQL = _interopRequireDefault(require("../NeonGraphQL/NeonGraphQL"));
var _NeonEnvironment = _interopRequireDefault(require("../NeonEnvironment/NeonEnvironment"));
var _rxUtil = require("../../util/rxUtil");
var _typeUtil = require("../../util/typeUtil");
var _parseTimeSeriesData = _interopRequireDefault(require("../../workers/parseTimeSeriesData"));
var _DataPackageParser = _interopRequireDefault(require("../../parser/DataPackageParser"));
var _NeonSignInButtonState = _interopRequireDefault(require("../NeonSignInButton/NeonSignInButtonState"));
var _StateStorageService = _interopRequireDefault(require("../../service/StateStorageService"));
var _StateStorageConverter = require("./StateStorageConverter");
Expand Down Expand Up @@ -614,6 +616,10 @@ var parseSiteVariables = function parseSiteVariables(previousVariables, siteCode
variablesObject: newStateVariables
};
};
var parsePosition = function parsePosition(position) {
if (!(0, _typeUtil.exists)(position)) return position;
return _DataPackageParser.default.parseSensorPosition(position);
};

/**
* Build an object for state.product.sites[{site}] from a product/site positions fetch response
Expand All @@ -627,22 +633,25 @@ var parseSitePositions = function parseSitePositions(site, csv) {
var newSite = _extends({}, site);
var positions = parseCSV(csv, true); // Duplicated lines have been unintentionally seen here!
positions.data.forEach(function (position) {
var posId = position['HOR.VER'];
if (!newSite.positions[posId]) {
newSite.positions[posId] = {
data: {},
history: []
};
var parsedPosition = parsePosition(position);
if ((0, _typeUtil.exists)(parsedPosition)) {
var posId = parsedPosition.horVer;
if (!newSite.positions[posId]) {
newSite.positions[posId] = {
data: {},
history: []
};
}
newSite.positions[posId].history.push(parsedPosition);
}
newSite.positions[posId].history.push(position);
});
// Sort position history by start/end time descending
Object.keys(newSite.positions).forEach(function (posId) {
newSite.positions[posId].history.sort(function (a, b) {
if (!a.end) {
if (!a.sensorEndDateTime) {
return 1;
}
return a.end < b.start ? -1 : 1;
return a.sensorEndDateTime < b.sensorStartDateTime ? -1 : 1;
});
});
return newSite;
Expand Down
28 changes: 14 additions & 14 deletions lib/components/TimeSeriesViewer/TimeSeriesViewerSites.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,20 @@ declare namespace PositionHistoryButton {
const position: PropTypes.Validator<string>;
const fullWidth: PropTypes.Requireable<boolean>;
const history: PropTypes.Validator<(PropTypes.InferProps<{
'HOR.VER': PropTypes.Validator<string>;
azimuth: PropTypes.Validator<string>;
pitch: PropTypes.Validator<string>;
roll: PropTypes.Validator<string>;
start: PropTypes.Requireable<string>;
end: PropTypes.Requireable<string>;
xOffset: PropTypes.Validator<string>;
yOffset: PropTypes.Validator<string>;
zOffset: PropTypes.Validator<string>;
referenceStart: PropTypes.Requireable<string>;
referenceEnd: PropTypes.Requireable<string>;
referenceLatitude: PropTypes.Validator<string>;
referenceLongitude: PropTypes.Validator<string>;
referenceElevation: PropTypes.Validator<string>;
horVer: PropTypes.Validator<string>;
azimuth: PropTypes.Requireable<number>;
pitch: PropTypes.Requireable<number>;
roll: PropTypes.Requireable<number>;
sensorStartDateTime: PropTypes.Requireable<string>;
sensorEndDateTime: PropTypes.Requireable<string>;
xOffset: PropTypes.Requireable<number>;
yOffset: PropTypes.Requireable<number>;
zOffset: PropTypes.Requireable<number>;
referenceLocationStartDateTime: PropTypes.Requireable<string>;
referenceLocationEndDateTime: PropTypes.Requireable<string>;
referenceLocationLatitude: PropTypes.Requireable<number>;
referenceLocationLongitude: PropTypes.Requireable<number>;
referenceLocationElevation: PropTypes.Requireable<number>;
}> | null | undefined)[]>;
}
namespace defaultProps {
Expand Down
124 changes: 66 additions & 58 deletions lib/components/TimeSeriesViewer/TimeSeriesViewerSites.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,52 +386,59 @@ function PositionHistoryButton(props) {
}, "z"), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
align: "right"
}, "Elevation"))), /*#__PURE__*/_react.default.createElement(_TableBody.default, null, history.map(function (row, idx) {
var _row$start = row.start,
start = _row$start === void 0 ? '' : _row$start,
_row$end = row.end,
rawEnd = _row$end === void 0 ? '' : _row$end,
var _row$sensorStartDateT = row.sensorStartDateTime,
sensorStartDateTime = _row$sensorStartDateT === void 0 ? '' : _row$sensorStartDateT,
_row$sensorEndDateTim = row.sensorEndDateTime,
rawEnd = _row$sensorEndDateTim === void 0 ? '' : _row$sensorEndDateTim,
xOffset = row.xOffset,
yOffset = row.yOffset,
zOffset = row.zOffset,
referenceElevation = row.referenceElevation;
var hasReferenceElevation = (0, _typeUtil.exists)(referenceElevation) && referenceElevation !== '';
var hasZOffset = (0, _typeUtil.exists)(zOffset) && zOffset !== '';
var parsedReferenceElevation = hasReferenceElevation ? parseFloat(referenceElevation, 10) : NaN;
var parsedZOffset = hasZOffset ? parseFloat(zOffset, 10) : NaN;
referenceLocationElevation = row.referenceLocationElevation;
var hasReferenceElevation = (0, _typeUtil.exists)(referenceLocationElevation) && !isNaN(referenceLocationElevation);
var hasXOffset = (0, _typeUtil.exists)(xOffset) && !isNaN(xOffset);
var hasYOffset = (0, _typeUtil.exists)(yOffset) && !isNaN(yOffset);
var hasZOffset = (0, _typeUtil.exists)(zOffset) && !isNaN(zOffset);
var parsedReferenceElevation = hasReferenceElevation ? referenceLocationElevation : NaN;
var parsedXOffset = hasXOffset ? xOffset : NaN;
var parsedYOffset = hasYOffset ? yOffset : NaN;
var parsedZOffset = hasZOffset ? zOffset : NaN;
var elevation = 'unknown';
if (!isNaN(parsedReferenceElevation)) {
if (!isNaN(hasZOffset)) {
if (!isNaN(parsedZOffset)) {
elevation = "".concat((parsedReferenceElevation + parsedZOffset).toFixed(2).toString(), "m");
} else {
elevation = "".concat(parsedReferenceElevation, "m");
}
}
var displayXOffset = hasXOffset ? "".concat(xOffset, "m") : '--';
var displayYOffset = hasYOffset ? "".concat(yOffset, "m") : '--';
var displayZOffset = hasZOffset ? "".concat(zOffset, "m") : '--';
var end = rawEnd === '' ? 'Current' : rawEnd;
var cellStyle = idx !== history.length - 1 ? {} : {
fontWeight: '600',
borderBottom: 'none'
};
var key = "".concat(start).concat(end).concat(xOffset).concat(yOffset).concat(zOffset);
var key = "".concat(sensorStartDateTime).concat(end).concat(parsedXOffset).concat(parsedYOffset).concat(parsedZOffset);
return /*#__PURE__*/_react.default.createElement(_TableRow.default, {
key: key
}, /*#__PURE__*/_react.default.createElement(_TableCell.default, {
component: "th",
scope: "row",
style: cellStyle
}, start), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
}, sensorStartDateTime), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
component: "th",
scope: "row",
style: cellStyle
}, end), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
align: "right",
style: cellStyle
}, "".concat(xOffset, "m")), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
}, displayXOffset), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
align: "right",
style: cellStyle
}, "".concat(yOffset, "m")), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
}, displayYOffset), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
align: "right",
style: cellStyle
}, "".concat(zOffset, "m")), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
}, displayZOffset), /*#__PURE__*/_react.default.createElement(_TableCell.default, {
align: "right",
style: cellStyle
}, elevation));
Expand All @@ -448,20 +455,20 @@ PositionHistoryButton.propTypes = {
position: _propTypes.default.string.isRequired,
fullWidth: _propTypes.default.bool,
history: _propTypes.default.arrayOf(_propTypes.default.shape({
'HOR.VER': _propTypes.default.string.isRequired,
azimuth: _propTypes.default.string.isRequired,
pitch: _propTypes.default.string.isRequired,
roll: _propTypes.default.string.isRequired,
start: _propTypes.default.string,
end: _propTypes.default.string,
xOffset: _propTypes.default.string.isRequired,
yOffset: _propTypes.default.string.isRequired,
zOffset: _propTypes.default.string.isRequired,
referenceStart: _propTypes.default.string,
referenceEnd: _propTypes.default.string,
referenceLatitude: _propTypes.default.string.isRequired,
referenceLongitude: _propTypes.default.string.isRequired,
referenceElevation: _propTypes.default.string.isRequired
horVer: _propTypes.default.string.isRequired,
azimuth: _propTypes.default.number,
pitch: _propTypes.default.number,
roll: _propTypes.default.number,
sensorStartDateTime: _propTypes.default.string,
sensorEndDateTime: _propTypes.default.string,
xOffset: _propTypes.default.number,
yOffset: _propTypes.default.number,
zOffset: _propTypes.default.number,
referenceLocationStartDateTime: _propTypes.default.string,
referenceLocationEndDateTime: _propTypes.default.string,
referenceLocationLatitude: _propTypes.default.number,
referenceLocationLongitude: _propTypes.default.number,
referenceLocationElevation: _propTypes.default.number
})).isRequired
};
PositionHistoryButton.defaultProps = {
Expand Down Expand Up @@ -532,25 +539,26 @@ function PositionDetail(props) {
var history = state.product.sites[siteCode].positions[position].history;
var current = history.length - 1 || 0;
var _ref2 = history[current] || {},
name = _ref2.name,
description = _ref2.description,
referenceName = _ref2.referenceName,
referenceDescription = _ref2.referenceDescription,
_ref2$referenceElevat = _ref2.referenceElevation,
referenceElevation = _ref2$referenceElevat === void 0 ? '--' : _ref2$referenceElevat,
_ref2$xOffset = _ref2.xOffset,
xOffset = _ref2$xOffset === void 0 ? '--' : _ref2$xOffset,
_ref2$yOffset = _ref2.yOffset,
yOffset = _ref2$yOffset === void 0 ? '--' : _ref2$yOffset,
_ref2$zOffset = _ref2.zOffset,
zOffset = _ref2$zOffset === void 0 ? '--' : _ref2$zOffset;
var hasReferenceElevation = (0, _typeUtil.exists)(referenceElevation) && referenceElevation !== '';
var hasZOffset = (0, _typeUtil.exists)(zOffset) && zOffset !== '' && zOffset !== '--';
var parsedReferenceElevation = hasReferenceElevation ? parseFloat(referenceElevation, 10) : NaN;
var parsedZOffset = hasZOffset ? parseFloat(zOffset, 10) : NaN;
sensorName = _ref2.sensorName,
sensorDescription = _ref2.sensorDescription,
referenceLocationName = _ref2.referenceLocationName,
referenceLocationDescription = _ref2.referenceLocationDescription,
referenceLocationElevation = _ref2.referenceLocationElevation,
xOffset = _ref2.xOffset,
yOffset = _ref2.yOffset,
zOffset = _ref2.zOffset;
var hasReferenceElevation = (0, _typeUtil.exists)(referenceLocationElevation) && !isNaN(referenceLocationElevation);
var hasXOffset = (0, _typeUtil.exists)(xOffset) && !isNaN(xOffset);
var hasYOffset = (0, _typeUtil.exists)(yOffset) && !isNaN(yOffset);
var hasZOffset = (0, _typeUtil.exists)(zOffset) && !isNaN(zOffset);
var parsedReferenceElevation = hasReferenceElevation ? referenceLocationElevation : NaN;
var parsedZOffset = hasZOffset ? zOffset : NaN;
var displayXOffset = hasXOffset ? "".concat(xOffset, "m") : '--';
var displayYOffset = hasYOffset ? "".concat(yOffset, "m") : '--';
var displayZOffset = hasZOffset ? "".concat(zOffset, "m") : '--';
var elevation = '--';
if (!isNaN(parsedReferenceElevation)) {
if (!isNaN(hasZOffset)) {
if (!isNaN(parsedZOffset)) {
elevation = "".concat((parsedReferenceElevation + parsedZOffset).toFixed(2).toString(), "m");
} else {
elevation = "".concat(parsedReferenceElevation, "m");
Expand All @@ -564,15 +572,15 @@ function PositionDetail(props) {
fontWeight: 600
};
var renderDescription = function renderDescription() {
var hasName = (0, _typeUtil.isStringNonEmpty)(name);
var hasDescription = (0, _typeUtil.isStringNonEmpty)(description);
var hasReferenceName = (0, _typeUtil.isStringNonEmpty)(referenceName);
var hasReferenceDescription = (0, _typeUtil.isStringNonEmpty)(referenceDescription);
var appliedName = hasName ? name : 'N/A';
var appliedDescription = hasDescription ? description : 'N/A';
var hasName = (0, _typeUtil.isStringNonEmpty)(sensorName);
var hasDescription = (0, _typeUtil.isStringNonEmpty)(sensorDescription);
var hasReferenceName = (0, _typeUtil.isStringNonEmpty)(referenceLocationName);
var hasReferenceDescription = (0, _typeUtil.isStringNonEmpty)(referenceLocationDescription);
var appliedName = hasName ? sensorName : 'N/A';
var appliedDescription = hasDescription ? sensorDescription : 'N/A';
var includeReference = hasReferenceName || hasReferenceDescription;
var appliedReferenceName = hasReferenceName ? referenceName : 'N/A';
var appliedReferenceDescription = hasReferenceDescription ? referenceDescription : 'N/A';
var appliedReferenceName = hasReferenceName ? referenceLocationName : 'N/A';
var appliedReferenceDescription = hasReferenceDescription ? referenceLocationDescription : 'N/A';
return wide ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
className: classes.startFlex,
style: _extends({}, fadeStyle, {
Expand Down Expand Up @@ -681,7 +689,7 @@ function PositionDetail(props) {
variant: "body2"
}, /*#__PURE__*/_react.default.createElement("span", {
style: _extends({}, axisStyle)
}, "x / y / z:"), "".concat(xOffset, "m / ").concat(yOffset, "m / ").concat(zOffset, "m"))), renderDescription()) : /*#__PURE__*/_react.default.createElement("div", {
}, "x / y / z:"), "".concat(displayXOffset, " / ").concat(displayYOffset, " / ").concat(displayZOffset))), renderDescription()) : /*#__PURE__*/_react.default.createElement("div", {
ref: containerRef,
className: classes.startFlex,
style: positionContainerStyle
Expand Down Expand Up @@ -725,11 +733,11 @@ function PositionDetail(props) {
variant: "body2"
}, /*#__PURE__*/_react.default.createElement("span", {
style: _extends({}, axisStyle)
}, "x:"), "".concat(xOffset, "m"), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("span", {
}, "x:"), "".concat(displayXOffset), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("span", {
style: _extends({}, axisStyle)
}, "y:"), "".concat(yOffset, "m"), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("span", {
}, "y:"), "".concat(displayYOffset), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("span", {
style: _extends({}, axisStyle)
}, "z:"), "".concat(zOffset, "m")))), renderDescription()), /*#__PURE__*/_react.default.createElement("div", {
}, "z:"), "".concat(displayZOffset)))), renderDescription()), /*#__PURE__*/_react.default.createElement("div", {
style: historyButtonContainerStyle
}, /*#__PURE__*/_react.default.createElement(PositionHistoryButton, {
siteCode: siteCode,
Expand Down
13 changes: 13 additions & 0 deletions lib/parser/DataPackageParser.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Nullable, UnknownRecord } from '../types/core';
import { SensorPosition } from '../types/internal';
export interface IDataPackageParser {
/**
* Parse a data package sensor position record into an
* internal shape based on detected schema version.
* @param position The position to parse
* @returns The parsed position to an internal, normalized shape.
*/
parseSensorPosition: (position: Nullable<UnknownRecord>) => Nullable<SensorPosition>;
}
declare const DataPackageParser: IDataPackageParser;
export default DataPackageParser;
83 changes: 83 additions & 0 deletions lib/parser/DataPackageParser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _typeUtil = require("../util/typeUtil");
var _neonDataPackage = require("../types/neonDataPackage");
var DataPackageParser = {
parseSensorPosition: function parseSensorPosition(position) {
if (!(0, _typeUtil.exists)(position)) {
return null;
}
var result = null;
var resultV2 = _neonDataPackage.sensorPositionV2Schema.safeParse(position);
if (!resultV2.success) {
// Check for v1 schema
var resultV1 = _neonDataPackage.sensorPositionV1Schema.safeParse(position);
if (!resultV1.success) {
var v2ErrorFormat = resultV2.error.format();
var v1ErrorFormat = resultV1.error.format();
// eslint-disable-next-line no-console
console.error('Failed to detect sensor position schema', v2ErrorFormat, v1ErrorFormat);
} else {
var parsedV1 = resultV1.data;
result = {
horVer: parsedV1['HOR.VER'],
sensorName: (0, _typeUtil.isStringNonEmpty)(parsedV1.name) ? parsedV1.name : 'N/A',
sensorDescription: parsedV1.description,
sensorStartDateTime: parsedV1.start,
sensorEndDateTime: parsedV1.end,
referenceLocationName: parsedV1.referenceName,
referenceLocationDescription: parsedV1.referenceDescription,
referenceLocationStartDateTime: parsedV1.referenceStart,
referenceLocationEndDateTime: parsedV1.referenceEnd,
xOffset: parsedV1.xOffset,
yOffset: parsedV1.yOffset,
zOffset: parsedV1.zOffset,
pitch: parsedV1.pitch,
roll: parsedV1.roll,
azimuth: parsedV1.azimuth,
referenceLocationLatitude: parsedV1.referenceLatitude,
referenceLocationLongitude: parsedV1.referenceLongitude,
referenceLocationElevation: parsedV1.referenceElevation,
eastOffset: parsedV1.eastOffset,
northOffset: parsedV1.northOffset,
xAzimuth: parsedV1.xAzimuth,
yAzimuth: parsedV1.yAzimuth
};
}
} else {
var parsedV2 = resultV2.data;
result = {
horVer: parsedV2['HOR.VER'],
sensorName: parsedV2.sensorLocationID,
sensorDescription: parsedV2.sensorLocationDescription,
sensorStartDateTime: parsedV2.positionStartDateTime,
sensorEndDateTime: parsedV2.positionEndDateTime,
referenceLocationName: parsedV2.referenceLocationID,
referenceLocationDescription: parsedV2.referenceLocationIDDescription,
referenceLocationStartDateTime: parsedV2.referenceLocationIDStartDateTime,
referenceLocationEndDateTime: parsedV2.referenceLocationIDEndDateTime,
xOffset: parsedV2.xOffset,
yOffset: parsedV2.yOffset,
zOffset: parsedV2.zOffset,
pitch: parsedV2.pitch,
roll: parsedV2.roll,
azimuth: parsedV2.azimuth,
referenceLocationLatitude: parsedV2.locationReferenceLatitude,
referenceLocationLongitude: parsedV2.locationReferenceLongitude,
referenceLocationElevation: parsedV2.locationReferenceElevation,
eastOffset: parsedV2.eastOffset,
northOffset: parsedV2.northOffset,
xAzimuth: parsedV2.xAzimuth,
yAzimuth: parsedV2.yAzimuth
};
}
return result;
}
};
Object.freeze(DataPackageParser);
var _default = DataPackageParser;
exports.default = _default;
Loading

0 comments on commit 322190a

Please sign in to comment.