Skip to content

Commit 504c410

Browse files
authored
Merge pull request #2474 from OpenC3/subpackets
Subpackets
2 parents eebbd39 + ecf501c commit 504c410

File tree

59 files changed

+2244
-743
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2244
-743
lines changed

openc3-cosmos-cmd-tlm-api/app/controllers/script_autocomplete_controller.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ def build_autocomplete_data(type, scope)
9292
OpenC3::TargetModel.packets(target_name, type: type.upcase.intern, scope: scope).each do |packet|
9393
packet_to_autocomplete_hashes(autocomplete_data, packet, target_info, type)
9494
end
95+
if type.upcase.intern == :TLM
96+
items = OpenC3::TargetModel.all_item_names(target_name, type: :TLM, scope: scope)
97+
items.each do |item|
98+
autocomplete_data <<
99+
{
100+
:caption => "#{target_name} LATEST #{item}",
101+
:snippet => "#{target_name} LATEST #{item}",
102+
:meta => 'telemetry',
103+
}
104+
end
105+
end
95106
end
96107
autocomplete_data.sort_by { |packet| packet[:caption] }
97108
end

openc3-cosmos-init/plugins/packages/openc3-cosmos-tool-limitsmonitor/src/tools/LimitsMonitor/LimitsControl.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ export default {
212212
items: [],
213213
itemList: [],
214214
screenItems: [],
215+
availableItems: [],
215216
screenValues: {},
216217
updateCounter: 0,
217218
itemsPerPage: 25,
@@ -508,8 +509,8 @@ export default {
508509
}
509510
},
510511
update() {
511-
if (this.screenItems.length !== 0) {
512-
this.api.get_tlm_values(this.screenItems).then((data) => {
512+
if (this.availableItems.length !== 0) {
513+
this.api.get_tlm_values(this.availableItems).then((data) => {
513514
this.updateValues(data)
514515
})
515516
}
@@ -522,11 +523,15 @@ export default {
522523
}
523524
},
524525
addItem: function (valueId) {
525-
this.screenItems.push(valueId)
526-
this.screenValues[valueId] = [null, null, 0]
526+
this.api.get_tlm_available([valueId]).then((available) => {
527+
this.screenItems.push(valueId)
528+
this.availableItems.push(available[0])
529+
this.screenValues[available[0]] = [null, null, 0]
530+
})
527531
},
528532
deleteItem: function (valueId) {
529533
let index = this.screenItems.indexOf(valueId)
534+
this.availableItems.splice(index, 1)
530535
this.screenItems.splice(index, 1)
531536
},
532537
@@ -596,5 +601,4 @@ export default {
596601
font-weight: bold;
597602
background-color: var(--color-background-base-default);
598603
}
599-
600604
</style>

openc3-cosmos-init/plugins/packages/openc3-cosmos-tool-packetviewer/src/tools/PacketViewer/PacketViewer.vue

Lines changed: 199 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<target-packet-item-chooser
2929
:initial-target-name="$route.params.target"
3030
:initial-packet-name="$route.params.packet"
31+
show-latest
3132
@on-set="packetChanged($event)"
3233
/>
3334
</div>
@@ -252,6 +253,8 @@ export default {
252253
itemName: '',
253254
x: 0,
254255
y: 0,
256+
latestAvailable: null,
257+
latestItems: null,
255258
}
256259
},
257260
computed: {
@@ -503,19 +506,34 @@ export default {
503506
}
504507
},
505508
packetChanged(event) {
506-
this.api
507-
.get_target(event.targetName)
508-
.then((target) => {
509+
// Handle LATEST packet specially
510+
if (event.packetName === 'LATEST') {
511+
this.api.get_target(event.targetName).then((target) => {
509512
if (target) {
510513
this.ignoredItems = target.ignored_items
514+
// For LATEST, we can't get specific packet derived items
515+
this.derivedItems = []
511516
512-
return this.api.get_packet_derived_items(
513-
event.targetName,
514-
event.packetName,
515-
)
517+
this.targetName = event.targetName
518+
this.packetName = event.packetName
519+
const currentTarget = this.$route.params.target?.toUpperCase()
520+
const currentPacket = this.$route.params.packet?.toUpperCase()
521+
if (
522+
currentTarget !== event.targetName ||
523+
currentPacket !== event.packetName
524+
) {
525+
this.saveDefaultConfig(this.currentConfig)
526+
this.$router.push({
527+
name: 'PackerViewer',
528+
params: {
529+
target: this.targetName,
530+
packet: this.packetName,
531+
},
532+
})
533+
}
534+
this.changeUpdater(true)
516535
} else {
517536
// Probably got here from an old config or URL params that point to something that no longer exists
518-
// (e.g. the plugin that defined this target was deleted). Unset these to avoid API errors.
519537
this.targetName = null
520538
this.packetName = null
521539
this.$router.push({
@@ -524,28 +542,93 @@ export default {
524542
})
525543
}
526544
})
527-
.then((derived) => {
528-
if (derived) {
529-
this.derivedItems = derived
545+
} else {
546+
// Regular packet handling
547+
this.api
548+
.get_target(event.targetName)
549+
.then((target) => {
550+
if (target) {
551+
this.ignoredItems = target.ignored_items
530552
531-
this.targetName = event.targetName
532-
this.packetName = event.packetName
533-
if (
534-
this.$route.params.target !== event.targetName ||
535-
this.$route.params.packet !== event.packetName
536-
) {
537-
this.saveDefaultConfig(this.currentConfig)
553+
return this.api.get_packet_derived_items(
554+
event.targetName,
555+
event.packetName,
556+
)
557+
} else {
558+
// Probably got here from an old config or URL params that point to something that no longer exists
559+
// (e.g. the plugin that defined this target was deleted). Unset these to avoid API errors.
560+
this.targetName = null
561+
this.packetName = null
538562
this.$router.push({
539563
name: 'PackerViewer',
540-
params: {
541-
target: this.targetName,
542-
packet: this.packetName,
543-
},
564+
params: {},
565+
})
566+
}
567+
})
568+
.then((derived) => {
569+
if (derived) {
570+
this.derivedItems = derived
571+
572+
this.targetName = event.targetName
573+
this.packetName = event.packetName
574+
const currentTarget = this.$route.params.target?.toUpperCase()
575+
const currentPacket = this.$route.params.packet?.toUpperCase()
576+
if (
577+
currentTarget !== event.targetName ||
578+
currentPacket !== event.packetName
579+
) {
580+
this.saveDefaultConfig(this.currentConfig)
581+
this.$router.push({
582+
name: 'PackerViewer',
583+
params: {
584+
target: this.targetName,
585+
packet: this.packetName,
586+
},
587+
})
588+
}
589+
this.changeUpdater(true)
590+
}
591+
})
592+
}
593+
},
594+
latestGetTlmValues(values) {
595+
if (values != null && values.length > 0) {
596+
this.counter += 1
597+
let derived = []
598+
let other = []
599+
this.latestItemNames.forEach((itemName, index) => {
600+
if (!this.showIgnored && this.ignoredItems.includes(itemName)) {
601+
return
602+
}
603+
const itemValue = values[index]
604+
if (itemValue) {
605+
if (this.derivedItems.includes(itemName)) {
606+
derived.push({
607+
name: itemName,
608+
value: itemValue[0],
609+
limitsState: itemValue[1],
610+
derived: true,
611+
counter: this.counter,
612+
pinned: this.isPinned(itemName),
613+
})
614+
} else {
615+
other.push({
616+
name: itemName,
617+
value: itemValue[0],
618+
limitsState: itemValue[1],
619+
derived: false,
620+
counter: this.counter,
621+
pinned: this.isPinned(itemName),
544622
})
545623
}
546-
this.changeUpdater(true)
547624
}
548625
})
626+
if (this.derivedLast) {
627+
this.rows = other.concat(derived)
628+
} else {
629+
this.rows = derived.concat(other)
630+
}
631+
}
549632
},
550633
changeUpdater(clearExisting) {
551634
if (this.updater != null) {
@@ -554,62 +637,107 @@ export default {
554637
}
555638
if (clearExisting) {
556639
this.rows = []
640+
this.latestAvailable = null
641+
this.latestItems = null
557642
}
558643
this.updater = setInterval(() => {
559644
if (!this.targetName || !this.packetName) {
560645
return // noop if target/packet aren't set
561646
}
562-
this.api
563-
.get_tlm_packet(
564-
this.targetName,
565-
this.packetName,
566-
this.valueType,
567-
this.staleLimit,
568-
)
569-
.then((data) => {
570-
// Make sure data isn't null or undefined. Note this is the only valid use of == or !=
571-
if (data != null) {
572-
this.counter += 1
573-
let derived = []
574-
let other = []
575-
data.forEach((value) => {
576-
if (!this.showIgnored && this.ignoredItems.includes(value[0])) {
577-
return
578-
}
579-
if (this.derivedItems.includes(value[0])) {
580-
derived.push({
581-
name: value[0],
582-
value: value[1],
583-
limitsState: value[2],
584-
derived: true,
585-
counter: this.counter,
586-
pinned: this.isPinned(value[0]),
587-
})
647+
648+
// Handle LATEST packet using get_tlm_values
649+
if (this.packetName === 'LATEST') {
650+
if (this.latestAvailable) {
651+
this.api
652+
.get_tlm_values(this.latestAvailable, this.staleLimit)
653+
.then((values) => {
654+
this.latestGetTlmValues(values)
655+
})
656+
.catch((error) => {
657+
// eslint-disable-next-line
658+
console.log(error)
659+
})
660+
} else {
661+
this.api
662+
.get_all_tlm_item_names(this.targetName)
663+
.then((itemNames) => {
664+
this.latestItemNames = itemNames
665+
// Build items array in format TGT__LATEST__ITEM__TYPE
666+
const items = itemNames.map(
667+
(item) =>
668+
`${this.targetName}__LATEST__${item}__${this.valueType}`,
669+
)
670+
return this.api.get_tlm_available(items)
671+
})
672+
.then((available) => {
673+
this.latestAvailable = available
674+
return this.api.get_tlm_values(available, this.staleLimit)
675+
})
676+
.then((values) => {
677+
this.latestGetTlmValues(values)
678+
})
679+
.catch((error) => {
680+
// eslint-disable-next-line
681+
console.log(error)
682+
})
683+
}
684+
} else {
685+
// Regular packet handling using get_tlm_packet
686+
this.api
687+
.get_tlm_packet(
688+
this.targetName,
689+
this.packetName,
690+
this.valueType,
691+
this.staleLimit,
692+
)
693+
.then((data) => {
694+
// Make sure data isn't null or undefined. Note this is the only valid use of == or !=
695+
if (data != null) {
696+
this.counter += 1
697+
let derived = []
698+
let other = []
699+
data.forEach((value) => {
700+
if (
701+
!this.showIgnored &&
702+
this.ignoredItems.includes(value[0])
703+
) {
704+
return
705+
}
706+
if (this.derivedItems.includes(value[0])) {
707+
derived.push({
708+
name: value[0],
709+
value: value[1],
710+
limitsState: value[2],
711+
derived: true,
712+
counter: this.counter,
713+
pinned: this.isPinned(value[0]),
714+
})
715+
} else {
716+
other.push({
717+
name: value[0],
718+
value: value[1],
719+
limitsState: value[2],
720+
derived: false,
721+
counter: this.counter,
722+
pinned: this.isPinned(value[0]),
723+
})
724+
}
725+
})
726+
if (this.derivedLast) {
727+
this.rows = other.concat(derived)
588728
} else {
589-
other.push({
590-
name: value[0],
591-
value: value[1],
592-
limitsState: value[2],
593-
derived: false,
594-
counter: this.counter,
595-
pinned: this.isPinned(value[0]),
596-
})
729+
this.rows = derived.concat(other)
597730
}
598-
})
599-
if (this.derivedLast) {
600-
this.rows = other.concat(derived)
601-
} else {
602-
this.rows = derived.concat(other)
603731
}
604-
}
605-
})
606-
// Catch errors but just log to the console
607-
// We don't clear the updater because errors can happen on upgrade
608-
// and we want to continue updating once the new plugin comes online
609-
.catch((error) => {
610-
// eslint-disable-next-line
611-
console.log(error)
612-
})
732+
})
733+
// Catch errors but just log to the console
734+
// We don't clear the updater because errors can happen on upgrade
735+
// and we want to continue updating once the new plugin comes online
736+
.catch((error) => {
737+
// eslint-disable-next-line
738+
console.log(error)
739+
})
740+
}
613741
}, this.refreshInterval)
614742
},
615743
resetConfig: function () {

0 commit comments

Comments
 (0)