Skip to content

Commit

Permalink
Record changes in track data.
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesremuscat committed Jun 11, 2024
1 parent be4c6e1 commit 06dfe5c
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/analysis/__tests__/trackData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { TrackData } from '../trackData.js';

describe('Track data', () => {
it('records changes in track data', () => {
const trackData = TrackData.create();

const oldState = {
lastUpdated: 1000,
manifest: {
trackDataSpec: ['Value A', 'Value B']
},
session: {
trackData: [
[123, 'units'],
[576, '°C']
]
}
};

const newState = {
lastUpdated: 1234,
manifest: {
trackDataSpec: ['Value A', 'Value B']
},
session: {
trackData: [
[456, 'units'],
[576, '°C']
]
}
};

trackData.update(oldState, newState);

expect(trackData.series.size).toEqual(2);
const valA = trackData.series.get('Value A');
expect(valA.data.length).toEqual(2);
expect(valA.data[1].timestamp).toEqual(new Date(1234));
expect(valA.data[1].value).toEqual(456);

expect(trackData.series.get('Value B').data.length).toEqual(1);

const nextState = {
lastUpdated: 5678,
manifest: {
trackDataSpec: ['Value A', 'Value B']
},
session: {
trackData: [
[1024, 'units'],
[576, '°C']
]
}
};

trackData.update(newState, nextState);
expect(trackData.series.get('Value A').data.length).toEqual(3);
});

it('Ignores values not given as [value, unit] pairs', () => {
const trackData = TrackData.create();

const oldState = {
lastUpdated: 1000,
manifest: {
trackDataSpec: ['Value A', 'Value B']
},
session: {
trackData: [
[123, 'units'],
'576 °C'
]
}
};

trackData.update(oldState, oldState);

expect(trackData.series.get('Value B')).toEqual(undefined);
});
});
3 changes: 3 additions & 0 deletions src/analysis/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Manifest } from './manifest.js';
import { Messages } from './messages.js';
import { Session } from './session.js';
import { State } from './state.js';
import { TrackData } from './trackData.js';

import { CURRENT_VERSION, migrateAnalysisState } from './migrate.js';

Expand All @@ -19,6 +20,7 @@ const Analyser = types.model({
session: types.optional(Session, () => Session.create()),
state: types.optional(State, () => State.create()),
manifest: types.optional(Manifest, () => Manifest.create()),
trackData: types.optional(TrackData, () => TrackData.create()),
latestTimestamp: types.optional(types.Date, () => new Date()),
version: types.optional(types.literal(CURRENT_VERSION), CURRENT_VERSION)
}).extend(
Expand All @@ -34,6 +36,7 @@ const Analyser = types.model({
self.session.update(oldState, newState);

self.state.update(oldState, newState);
self.trackData.update(oldState, newState);
self.manifest = newState.manifest;

self.latestTimestamp = timestamp || new Date();
Expand Down
9 changes: 9 additions & 0 deletions src/analysis/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ const MIGRATIONS = {
migrated.manifest.startTime = Math.floor(earliestTimestamp / 1000);
}

return migrated;
},
3: (oldState) => {
const migrated = {
...oldState,
trackData: {},
version: 4
};

return migrated;
}
};
Expand Down
85 changes: 85 additions & 0 deletions src/analysis/trackData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { types } from 'mobx-state-tree';

const Datum = types.model({
timestamp: types.Date,
value: types.union(types.number, types.string)
});

const SeriesModel = types.model({
label: types.string,
unit: types.string,
data: types.optional(types.array(Datum), [])
});

const Series = types.snapshotProcessor(SeriesModel, {
preProcessor(snapshot) {
return ({
label: snapshot.label,
unit: snapshot.unit,
data: (snapshot.data || []).map(
([t, v]) => ({
timestamp: t,
value: v
})
)
});
},
postProcessor(snapshot, node) {
return ({
label: snapshot.label,
unit: snapshot.unit,
data: node?.data?.map(d => ([d.timestamp.getTime(), d.value]))
});
}
});

export const TrackData = types.model({
series: types.optional(types.map(Series), {})
}).actions(
self => ({
update(oldState, newState) {
const labels = newState.manifest?.trackDataSpec || [];
const values = newState.session?.trackData || [];
const prevValues = oldState.session?.trackData || [];

for (let i = 0; i < values.length; i++) {
const label = labels[i];
const value = values[i];
const prevValue = prevValues[i];

if (Array.isArray(value) && value.length === 2) {
if (!self.series.get(label)) {
const series = Series.create({
label,
unit: value[1],
data: []
});
self.series.set(label, series);

if (prevValue && prevValue[0] !== null) {
series.data.push(Datum.create({
timestamp: oldState.lastUpdated,
value: prevValue[0]
}));
}
}

if (!prevValue || prevValue[0] !== value[0]) {
// Value has changed! How exciting
// console.log(label, prevValue[0], '==>', value[0]);
self.series.get(label).data.push(Datum.create({
timestamp: newState.lastUpdated,
value: value[0]
}));
}
}
}
}
})
).views(
self => ({
get toArray() {
return [...self.series.values()];
}
})
);

0 comments on commit 06dfe5c

Please sign in to comment.