move openmct plugin to typescript
remove unused livestream test function
This commit is contained in:
parent
13205c1668
commit
4829dd50c7
|
@ -2,7 +2,6 @@ package gotelem
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"math"
|
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -25,53 +24,6 @@ func makeEvent() skylab.BusEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// makeLiveSystem starts a process that is used to continuously stream
|
|
||||||
// data into a Broker. Every 100ms it will send either a BmsMeasurement
|
|
||||||
// or WslVelocity. The values will be static for WslVelocity (to
|
|
||||||
// make comparison easier) but will be dynamic for BmsMeasurement.
|
|
||||||
//
|
|
||||||
func liveStream(done chan bool, broker *Broker) {
|
|
||||||
bmsPkt := &skylab.BmsMeasurement{
|
|
||||||
Current: 1.23,
|
|
||||||
BatteryVoltage: 11111,
|
|
||||||
AuxVoltage: 22222,
|
|
||||||
}
|
|
||||||
wslPkt := &skylab.WslVelocity{
|
|
||||||
MotorVelocity: 0,
|
|
||||||
VehicleVelocity: 100.0,
|
|
||||||
}
|
|
||||||
var next skylab.Packet = bmsPkt
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
return
|
|
||||||
case <-time.After(100 * time.Millisecond):
|
|
||||||
// send the next packet.
|
|
||||||
if next == bmsPkt {
|
|
||||||
bmsPkt.Current = float32(math.Sin(float64(time.Now().Unix()) / 2.0))
|
|
||||||
ev := skylab.BusEvent{
|
|
||||||
Timestamp: time.Now(),
|
|
||||||
Name: next.String(),
|
|
||||||
Data: next,
|
|
||||||
}
|
|
||||||
broker.Publish("livestream", ev)
|
|
||||||
next = wslPkt
|
|
||||||
} else {
|
|
||||||
// send the wsl
|
|
||||||
ev := skylab.BusEvent{
|
|
||||||
Timestamp: time.Now(),
|
|
||||||
Name: next.String(),
|
|
||||||
Data: next,
|
|
||||||
}
|
|
||||||
broker.Publish("livestream", ev)
|
|
||||||
next = bmsPkt
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBroker(t *testing.T) {
|
func TestBroker(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
// "baseUrl": "./src",
|
|
||||||
"target": "es6",
|
|
||||||
"checkJs": true,
|
|
||||||
"allowJs": true,
|
|
||||||
"moduleResolution": "nodenext",
|
|
||||||
"module": "nodenext",
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"paths": {
|
|
||||||
"openmct": ["./node_modules/openmct/dist/openmct.d.ts"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"./dist/**/*",
|
|
||||||
"webpack.*.js"
|
|
||||||
]
|
|
||||||
}
|
|
1139
web/package-lock.json
generated
1139
web/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@
|
||||||
"name": "g1_openmct",
|
"name": "g1_openmct",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "dev environment for openmct plugins for g1 strategy tool",
|
"description": "dev environment for openmct plugins for g1 strategy tool",
|
||||||
"main": "index.js",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"build": "webpack --config webpack.prod.js",
|
"build": "webpack --config webpack.prod.js",
|
||||||
|
@ -13,19 +13,23 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv-webpack": "^8.0.1",
|
"dotenv-webpack": "^8.0.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"openmct": "^2.0.5",
|
"openmct": "^3.2.1",
|
||||||
"socket.io": "^4.6.0",
|
"socket.io": "^4.7.4",
|
||||||
"socket.io-client": "^4.6.0"
|
"socket.io-client": "^4.7.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.11.25",
|
||||||
|
"@types/webpack": "^5.28.5",
|
||||||
"copy-webpack-plugin": "^12.0.2",
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
"eslint": "^8.28.0",
|
"eslint": "^8.57.0",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.6.0",
|
||||||
"ts-loader": "^9.4.2",
|
"ts-loader": "^9.5.1",
|
||||||
"typescript": "^4.9.5",
|
"ts-node": "^10.9.2",
|
||||||
"webpack": "^5.75.0",
|
"typescript": "^5.4.2",
|
||||||
"webpack-cli": "^5.0.1",
|
"typescript-eslint": "^7.1.1",
|
||||||
"webpack-dev-server": "^4.11.1",
|
"webpack": "^5.90.3",
|
||||||
|
"webpack-cli": "^5.1.4",
|
||||||
|
"webpack-dev-server": "^5.0.2",
|
||||||
"webpack-merge": "^5.10.0"
|
"webpack-merge": "^5.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
238
web/src/app.js
238
web/src/app.js
|
@ -1,238 +0,0 @@
|
||||||
import openmct from 'openmct';
|
|
||||||
import PhoebusPlugin from "./phoebusPlugin";
|
|
||||||
openmct.setAssetPath('openmct');
|
|
||||||
openmct.install(openmct.plugins.LocalStorage());
|
|
||||||
openmct.install(openmct.plugins.MyItems());
|
|
||||||
openmct.install(openmct.plugins.Timeline());
|
|
||||||
openmct.install(openmct.plugins.UTCTimeSystem());
|
|
||||||
openmct.install(openmct.plugins.Clock({ enableClockIndicator: true }));
|
|
||||||
openmct.install(openmct.plugins.Timer());
|
|
||||||
openmct.install(openmct.plugins.Timelist());
|
|
||||||
openmct.time.clock('local', { start: -5 * 60 * 1000, end: 0 });
|
|
||||||
openmct.time.timeSystem('utc');
|
|
||||||
openmct.install(openmct.plugins.Espresso());
|
|
||||||
|
|
||||||
openmct.install(
|
|
||||||
openmct.plugins.Conductor({
|
|
||||||
menuOptions: [
|
|
||||||
{
|
|
||||||
name: 'Fixed',
|
|
||||||
timeSystem: 'utc',
|
|
||||||
bounds: {
|
|
||||||
start: Date.now() - 30000000,
|
|
||||||
end: Date.now()
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Realtime',
|
|
||||||
timeSystem: 'utc',
|
|
||||||
clock: 'local',
|
|
||||||
clockOffsets: {
|
|
||||||
start: -30000000,
|
|
||||||
end: 30000
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (process.env.BASE_URL) {
|
|
||||||
console.log("got a thing")
|
|
||||||
console.log(process.env.BASE_URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
var schemaCached = null;
|
|
||||||
function getSchema() {
|
|
||||||
if (schemaCached === null) {
|
|
||||||
return fetch(`${process.env.BASE_URL}/api/v1/schema`).then((resp) => {
|
|
||||||
const res = resp.json()
|
|
||||||
console.log("got schema, caching", res);
|
|
||||||
schemaCached = res
|
|
||||||
return res
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return Promise.resolve(schemaCached)
|
|
||||||
}
|
|
||||||
|
|
||||||
const objectProvider = {
|
|
||||||
get: function (id) {
|
|
||||||
return getSchema().then((schema) => {
|
|
||||||
if (id.key === "car") {
|
|
||||||
const comp = schema.packets.map((x) => {
|
|
||||||
return {
|
|
||||||
key: x.name,
|
|
||||||
namespace: "umnsvp"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
identifier: id,
|
|
||||||
name: "the solar car",
|
|
||||||
type: 'folder',
|
|
||||||
location: 'ROOT',
|
|
||||||
composition: comp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var pkt = schema.packets.find((x) => x.name === id.key)
|
|
||||||
if (pkt) {
|
|
||||||
// if the key matches one of the packet names,
|
|
||||||
// we know it's a field.
|
|
||||||
const comp = pkt.data.map((field) => {
|
|
||||||
return {
|
|
||||||
// we have to do this since
|
|
||||||
// we can't get the packet name otherwise.
|
|
||||||
key: `${pkt.name}.${field.name}`,
|
|
||||||
namespace: "umnsvp"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
identifier: id,
|
|
||||||
name: pkt.name,
|
|
||||||
type: 'folder',
|
|
||||||
composition: comp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// at this point it's definitely a field aka umnsvp-datum
|
|
||||||
var [pktName, fieldName] = id.key.split('.')
|
|
||||||
return {
|
|
||||||
identifier: id,
|
|
||||||
name: fieldName,
|
|
||||||
type: 'umnsvp-datum',
|
|
||||||
telemetry: {
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
key: "value",
|
|
||||||
source: "val",
|
|
||||||
name: "Value",
|
|
||||||
"format": "float",
|
|
||||||
hints: {
|
|
||||||
range: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "utc",
|
|
||||||
source: "ts",
|
|
||||||
name: "Timestamp",
|
|
||||||
format: "utc",
|
|
||||||
hints: {
|
|
||||||
domain: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const TelemHistoryProvider = {
|
|
||||||
supportsRequest: function (dObj) {
|
|
||||||
return dObj.type === 'umnsvp-datum'
|
|
||||||
},
|
|
||||||
request: function (dObj, opt) {
|
|
||||||
var [pktName, fieldName] = dObj.identifier.key.split('.')
|
|
||||||
var url = `${process.env.BASE_URL}/api/v1/packets/${pktName}/${fieldName}?`
|
|
||||||
var params = new URLSearchParams({
|
|
||||||
start: new Date(opt.start).toISOString(),
|
|
||||||
end: new Date(opt.end).toISOString(),
|
|
||||||
})
|
|
||||||
console.log((opt.end - opt.start) / opt.size)
|
|
||||||
return fetch(url + params).then((resp) => {
|
|
||||||
return resp.json()
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function TelemRealtimeProvider() {
|
|
||||||
|
|
||||||
|
|
||||||
return function (openmct) {
|
|
||||||
|
|
||||||
const url = `${process.env.BASE_URL.replace(/^http/, 'ws')}/api/v1/packets/subscribe?`
|
|
||||||
// we put our websocket connection here.
|
|
||||||
let connection = new WebSocket(url)
|
|
||||||
// connections contains name: callback mapping
|
|
||||||
let callbacks = {}
|
|
||||||
// names contains a set of *packet names*
|
|
||||||
let names = new Set()
|
|
||||||
|
|
||||||
function handleMessage(event) {
|
|
||||||
const data = JSON.parse(event.data)
|
|
||||||
for (const [key, value] of Object.entries(data.data)) {
|
|
||||||
const id = `${data.name}.${key}`
|
|
||||||
if (id in callbacks) {
|
|
||||||
// we should construct a telem point and make a callback.
|
|
||||||
callbacks[id]({
|
|
||||||
"ts": data.ts,
|
|
||||||
"val": value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateWebsocket() {
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
name: Array.from(names)
|
|
||||||
})
|
|
||||||
connection = new WebSocket(url + params)
|
|
||||||
|
|
||||||
connection.onmessage = handleMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
let provider = {
|
|
||||||
supportsSubscribe: function (dObj) {
|
|
||||||
return dObj.type === "umnsvp-datum"
|
|
||||||
},
|
|
||||||
subscribe: function (dObj, callback) {
|
|
||||||
console.log("subscribe called %s", JSON.stringify(dObj))
|
|
||||||
// identifier is packetname.fieldname. we add the packet name to the set.
|
|
||||||
const key = dObj.identifier.key
|
|
||||||
const [pktName, _] = key.split('.')
|
|
||||||
// add our callback to the dictionary,
|
|
||||||
// add the packet name to the set
|
|
||||||
callbacks[key] = callback
|
|
||||||
names.add(pktName)
|
|
||||||
// update the websocket URL with the new name.
|
|
||||||
updateWebsocket()
|
|
||||||
return function unsubscribe() {
|
|
||||||
names.delete(pktName)
|
|
||||||
delete callbacks[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
openmct.telemetry.addProvider(provider)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function GotelemPlugin() {
|
|
||||||
return function install(openmct) {
|
|
||||||
|
|
||||||
openmct.types.addType('umnsvp-datum', {
|
|
||||||
name: "UMN SVP Data Field",
|
|
||||||
description: "A data field of a packet from the car",
|
|
||||||
creatable: false,
|
|
||||||
cssClass: "icon-telemetry"
|
|
||||||
})
|
|
||||||
openmct.objects.addRoot({
|
|
||||||
namespace: "umnsvp",
|
|
||||||
key: 'car'
|
|
||||||
}, openmct.priority.HIGH)
|
|
||||||
openmct.objects.addProvider('umnsvp', objectProvider);
|
|
||||||
openmct.telemetry.addProvider(TelemHistoryProvider)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
openmct.install(GotelemPlugin())
|
|
||||||
openmct.install(TelemRealtimeProvider())
|
|
||||||
|
|
||||||
openmct.start();
|
|
|
@ -1,243 +0,0 @@
|
||||||
// import openmct from "openmct";
|
|
||||||
import {_} from "lodash";
|
|
||||||
import { io } from "socket.io-client";
|
|
||||||
// Pho
|
|
||||||
function PhoebusObjectProvider(identifier) {
|
|
||||||
// console.log("obj provider", identifier)
|
|
||||||
const board_regex = /^board\.([a-z-_]+)$/
|
|
||||||
const packet_regex = /^board\.([a-z-_]+)\.([a-z-_]+)$/
|
|
||||||
const data_field_regex = /^board\.([a-z-_]+)\.([a-z-_]+)\.([a-z-_]+)$/ // board.wavesculptor.wsl_heatsink_motor_temp.motor_temp
|
|
||||||
const data_field_regex_num = /^board\.([a-z-_]+)\.([a-z-_]+)\.([A-Za-z0-9]+)$/ // board.car_control.dashboard_system_timeout_test.flag_set0
|
|
||||||
const packet_regex_underscore_num = /^board\.([a-z-_]+)\.([a-z-_]+(_[A-Za-z0-9]+)+)$/ // board.steering.steering_press_count_1
|
|
||||||
const data_field_regex_underscore_num1 = /^board\.([a-z-_]+)\.([a-z-_]+(_[A-Za-z0-9]+)+)\.([A-Za-z0-9]+)$/ // board.steering.steering_press_count_1.button1
|
|
||||||
const data_field_regex_underscore_num2 = /^board\.([a-z-_]+)\.([a-z-_]+)\.([a-z-_]+(_[A-Za-z0-9]+)+)$/ // board.wavesculptor.wsr_status_information.error_flags_0
|
|
||||||
const data_field_regex_underscore_num3 = /^board\.([a-z-_]+)\.([a-z-_]+(_[A-Za-z0-9]+)+)\.([A-Za-z0-9]+(_[A-Za-z0-9]+)+)$/ // board.wavesculptor.wsr_15_165_voltage_rail.reference_165v
|
|
||||||
if (identifier.key === 'car') {
|
|
||||||
// get the car schema from the phoebus server
|
|
||||||
return Promise.resolve({
|
|
||||||
identifier: identifier,
|
|
||||||
name: "car!",
|
|
||||||
type: 'folder',
|
|
||||||
location: "ROOT"
|
|
||||||
})
|
|
||||||
} else if (board_regex.test(identifier.key)) {
|
|
||||||
// it's a board object. get the last word (ie board.bms -> bms)
|
|
||||||
// then use it to construct a get request
|
|
||||||
// console.log("doing board for ", identifier)
|
|
||||||
const board_name = identifier.key.match(board_regex)[1]
|
|
||||||
return fetch(`${process.env.VUE_APP_TELEM}/schema/` + board_name).then((resp) => {
|
|
||||||
return resp.json()
|
|
||||||
})
|
|
||||||
} else if (packet_regex.test(identifier.key)) {
|
|
||||||
const m = identifier.key.match(packet_regex)
|
|
||||||
const board_name = m[1]
|
|
||||||
const pkt_name = m[2]
|
|
||||||
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name].join("/")).then((resp) => {
|
|
||||||
return resp.json()
|
|
||||||
})
|
|
||||||
} else if (data_field_regex.test(identifier.key)) {
|
|
||||||
const m = identifier.key.match(data_field_regex)
|
|
||||||
const board_name = m[1]
|
|
||||||
const pkt_name = m[2]
|
|
||||||
const df_name = m[3]
|
|
||||||
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
|
||||||
return resp.json();
|
|
||||||
})
|
|
||||||
} else if (data_field_regex_num.test(identifier.key)) {
|
|
||||||
const m = identifier.key.match(data_field_regex_num)
|
|
||||||
const board_name = m[1]
|
|
||||||
const pkt_name = m[2]
|
|
||||||
const df_name = m[3]
|
|
||||||
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
|
||||||
return resp.json();
|
|
||||||
})
|
|
||||||
} else if (packet_regex_underscore_num.test(identifier.key)) {
|
|
||||||
const m = identifier.key.match(packet_regex_underscore_num)
|
|
||||||
const board_name = m[1]
|
|
||||||
const pkt_name = m[2]
|
|
||||||
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name].join("/")).then((resp) => {
|
|
||||||
return resp.json();
|
|
||||||
})
|
|
||||||
} else if (data_field_regex_underscore_num1.test(identifier.key)) {
|
|
||||||
const m = identifier.key.match(data_field_regex_underscore_num1)
|
|
||||||
const board_name = m[1]
|
|
||||||
const pkt_name = m[2]
|
|
||||||
const df_name = m[4]
|
|
||||||
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
|
||||||
return resp.json();
|
|
||||||
})
|
|
||||||
} else if (data_field_regex_underscore_num2.test(identifier.key)) {
|
|
||||||
const m = identifier.key.match(data_field_regex_underscore_num2)
|
|
||||||
const board_name = m[1]
|
|
||||||
const pkt_name = m[2]
|
|
||||||
const df_name = m[3]
|
|
||||||
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
|
||||||
return resp.json();
|
|
||||||
})
|
|
||||||
} else if (data_field_regex_underscore_num3.test(identifier.key)) {
|
|
||||||
const m = identifier.key.match(data_field_regex_underscore_num3)
|
|
||||||
const board_name = m[1]
|
|
||||||
const pkt_name = m[2]
|
|
||||||
const df_name = m[4]
|
|
||||||
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
|
||||||
return resp.json();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error("bad! no match for object.")
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSchema() {
|
|
||||||
return fetch(`${process.env.VUE_APP_TELEM}/schema`).then((resp) => {
|
|
||||||
const res = resp.json()
|
|
||||||
console.log("got schema", res)
|
|
||||||
return res
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const CarCompositionProvider = {
|
|
||||||
appliesTo: function (domainObject) {
|
|
||||||
return domainObject.identifier.namespace === "umnsvp.phoebus" &&
|
|
||||||
domainObject.identifier.key === "car"
|
|
||||||
},
|
|
||||||
load: function (domainObject) {
|
|
||||||
return getSchema()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the board composition provider takes a board type object, and gets all the telem objects for that board.
|
|
||||||
// it's like a folder.
|
|
||||||
const BoardCompositionProvider = {
|
|
||||||
appliesTo: function (domainObject) {
|
|
||||||
return domainObject.identifier.namespace === "umnsvp.phoebus" &&
|
|
||||||
domainObject.type === "umnsvp-board"
|
|
||||||
},
|
|
||||||
load: function (domainObject) {
|
|
||||||
// console.log("board comp provider for ", domainObject.packets)
|
|
||||||
return Promise.resolve(domainObject.packets)
|
|
||||||
// const board_name = domainObject.identifier.key.match(/^board\.([a-z-_]+)$/)
|
|
||||||
// return fetch("${process.env.VUE_APP_TELEM}/schema/" + board_name[1] + "/packets").then((resp) => {
|
|
||||||
// return resp.json()
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const PacketCompositionProvider = {
|
|
||||||
appliesTo: function (domainObject) {
|
|
||||||
return domainObject.identifier.namespace === "umnsvp.phoebus" && domainObject.type === "umnsvp-packet"
|
|
||||||
},
|
|
||||||
load: function (domainObject) {
|
|
||||||
// console.log("packet comp provider for ", domainObject.data_fields)
|
|
||||||
return Promise.resolve(domainObject.data_fields)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const PhoebusCompositionProviders = [
|
|
||||||
CarCompositionProvider,
|
|
||||||
BoardCompositionProvider,
|
|
||||||
PacketCompositionProvider
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
function PhoebusRealTime() {
|
|
||||||
const socket = io(`ws://localhost:${process.env.VUE_APP_TELEM_PORT}`)
|
|
||||||
let callback_list = {};
|
|
||||||
socket.on("packet", (data) => {
|
|
||||||
// if (data[0].packet_name === "wsl_bus_measurement") {
|
|
||||||
// console.log("got a wave meas packt", data[0])
|
|
||||||
// }
|
|
||||||
try {
|
|
||||||
const data_fields = data[0].data[0] // object that defines the measurement in each packet which are sent to openmct
|
|
||||||
// const key = ["board", data[0].board, data[0].packet_name].join(".")
|
|
||||||
console.log(Object.keys(data_fields))
|
|
||||||
console.log(callback_list)
|
|
||||||
// for (let i = 0; i < callback_list.length; i++) {
|
|
||||||
// if (Object.keys(data_fields).includes())
|
|
||||||
// }
|
|
||||||
Object.keys(data_fields).forEach((data_field) => {
|
|
||||||
let key = ["board", data[0].board, data[0].packet_name, data_field].join(".");
|
|
||||||
if (Object.keys(callback_list).includes(key)) {
|
|
||||||
let callBack = callback_list[key];
|
|
||||||
let timestamp = new Date().getTime();
|
|
||||||
// let realTimeData = data_fields;
|
|
||||||
let realTimeData = {}
|
|
||||||
realTimeData[data_field] = data_fields[data_field]
|
|
||||||
realTimeData.timestamp = timestamp;
|
|
||||||
realTimeData.id = key;
|
|
||||||
// console.log(realTimeData)
|
|
||||||
callBack(realTimeData);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
// do nothing
|
|
||||||
console.warn("a", e)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const provider = {
|
|
||||||
supportsSubscribe(domainObject) {
|
|
||||||
console.log("checking if supports subscribe", domainObject)
|
|
||||||
return domainObject.type === "umnsvp-data"
|
|
||||||
},
|
|
||||||
subscribe(domainObject, callback) {
|
|
||||||
console.log("subscribing for ", domainObject)
|
|
||||||
console.log("callback", callback)
|
|
||||||
// register us in the callback list
|
|
||||||
callback_list[domainObject.identifier.key] = callback
|
|
||||||
return function unsubscribe() {
|
|
||||||
delete callback_list[domainObject.identifier.key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
function PhoebusHistorical() {
|
|
||||||
return {
|
|
||||||
supportsRequest(domainObject) {
|
|
||||||
return domainObject.type === "umnsvp-packet"
|
|
||||||
},
|
|
||||||
request(domainObject, options) {
|
|
||||||
// return fetch()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function PhoebusPlugin() {
|
|
||||||
return function install(openmct) {
|
|
||||||
openmct.types.addType('umnsvp-board', {
|
|
||||||
name: "UMN SVP Board",
|
|
||||||
description: 'A board that sends telemetry packets/data',
|
|
||||||
createable: false,
|
|
||||||
cssClass: "icon-suitcase"
|
|
||||||
})
|
|
||||||
openmct.types.addType('umnsvp-packet', {
|
|
||||||
name: "UMN SVP Packet",
|
|
||||||
description: "A packet of telemetry from the car",
|
|
||||||
creatable: false,
|
|
||||||
cssClass: "icon-suitcase"
|
|
||||||
})
|
|
||||||
openmct.types.addType('umnsvp-data', {
|
|
||||||
name: "UMN SVP Data Field",
|
|
||||||
description: "A data field of a packet from the car",
|
|
||||||
creatable: false,
|
|
||||||
cssClass: "icon-telemetry"
|
|
||||||
})
|
|
||||||
openmct.objects.addRoot({
|
|
||||||
namespace: "umnsvp.phoebus",
|
|
||||||
key: 'car'
|
|
||||||
})
|
|
||||||
|
|
||||||
openmct.objects.addProvider('umnsvp.phoebus', {get:PhoebusObjectProvider})
|
|
||||||
|
|
||||||
openmct.telemetry.addProvider(PhoebusRealTime())
|
|
||||||
PhoebusCompositionProviders.forEach((provider) => {
|
|
||||||
openmct.composition.addProvider((provider))
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log("hello~!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PhoebusPlugin;
|
|
|
@ -1,10 +1,11 @@
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
import {fileURLToPath} from 'url';
|
||||||
const CopyPlugin = require("copy-webpack-plugin");
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||||
const Dotenv = require('dotenv-webpack');
|
import CopyPlugin from 'copy-webpack-plugin';
|
||||||
|
import DotenvWebpackPlugin from 'dotenv-webpack';
|
||||||
|
|
||||||
module.exports = {
|
const config = {
|
||||||
entry: './src/app.js',
|
entry: './src/app.ts',
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
|
@ -19,7 +20,7 @@ module.exports = {
|
||||||
template: 'src/index.html',
|
template: 'src/index.html',
|
||||||
filename: 'index.html',
|
filename: 'index.html',
|
||||||
}),
|
}),
|
||||||
new Dotenv(),
|
new DotenvWebpackPlugin(),
|
||||||
new CopyPlugin({
|
new CopyPlugin({
|
||||||
patterns: [
|
patterns: [
|
||||||
{ from: "**/*", to: "openmct/", context: "node_modules/openmct/dist"},
|
{ from: "**/*", to: "openmct/", context: "node_modules/openmct/dist"},
|
||||||
|
@ -34,6 +35,8 @@ module.exports = {
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'main.js',
|
filename: 'main.js',
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(path.dirname(fileURLToPath(import.meta.url)), 'dist'),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default config
|
|
@ -1,8 +1,8 @@
|
||||||
const { merge } = require('webpack-merge');
|
import {merge} from 'webpack-merge';
|
||||||
const common = require('./webpack.common.js');
|
import common from "./webpack.common.js"
|
||||||
const webpack = require('webpack');
|
import webpack from 'webpack'
|
||||||
|
|
||||||
module.exports = merge(common, {
|
const config = merge(common, {
|
||||||
mode: "development",
|
mode: "development",
|
||||||
devtool: 'inline-source-map',
|
devtool: 'inline-source-map',
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -20,3 +20,5 @@ module.exports = merge(common, {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export default config
|
|
@ -1,13 +1,16 @@
|
||||||
const { merge } = require('webpack-merge');
|
import { merge } from 'webpack-merge'
|
||||||
const common = require('./webpack.common.js');
|
import common from './webpack.common.js'
|
||||||
|
import webpack from 'webpack'
|
||||||
|
|
||||||
module.exports = merge(common, {
|
const config = merge(common, {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.EnvironmentPlugin({
|
new webpack.EnvironmentPlugin({
|
||||||
NODE_ENV: "production",
|
NODE_ENV: "production",
|
||||||
BASE_URL: "",
|
BASE_URL: "",
|
||||||
});
|
})
|
||||||
],
|
],
|
||||||
devtool: 'source-map',
|
devtool: 'source-map',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export default config
|
||||||
|
|
Loading…
Reference in a new issue