Skip to content

Commit

Permalink
Merge pull request #191 from NASA-AMMOS/issue-189
Browse files Browse the repository at this point in the history
Issue #189 - Update diff handling of complex types and human readable values
  • Loading branch information
MJJoyce authored Jan 25, 2021
2 parents 0af0c88 + 138ccec commit 10bd4d0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 40 deletions.
37 changes: 31 additions & 6 deletions ait/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def addTelemetry (self, uid, packet):
pkt_defn = getPacketDefn(uid)
pkt_name = pkt_defn.name
delta, dntoeus = get_packet_delta(pkt_defn, packet)
delta = replace_datetimes(delta)
dntoeus = replace_datetimes(dntoeus)

for session in self.values():
counter = session.updateCounter(pkt_name)
Expand Down Expand Up @@ -748,9 +748,24 @@ def get_packet_delta(pkt_defn, packet):
packet_states[pkt_defn.name]['raw'] = raw_fields
delta = raw_fields

# get converted fields
# get converted fields / complex fields
packet_states[pkt_defn.name]['dntoeu'] = {}
dntoeus = {f.name: getattr(ait_pkt, f.name) for f in pkt_defn.fields if f.dntoeu is not None}
dntoeus = {}
for f in pkt_defn.fields:
if f.dntoeu is not None or f.enum is not None or f.type.name in dtype.ComplexTypeMap.keys():
try:
val = getattr(ait_pkt, f.name)
except ValueError:
if isinstance(f.type, dtype.CmdType):
val = "Unidentified Cmd"
else:
val = getattr(ait_pkt.raw, f.name)

if isinstance(val, cmd.CmdDefn) or isinstance(val, evr.EVRDefn):
val = val.name

dntoeus[f.name] = val


# get derivations
packet_states[pkt_defn.name]['raw'].update({f.name: getattr(ait_pkt.raw, f.name) for f in pkt_defn.derivations})
Expand All @@ -768,8 +783,18 @@ def get_packet_delta(pkt_defn, packet):
delta[field.name] = new_value
packet_states[pkt_defn.name]['raw'][field.name] = new_value

if field.dntoeu is not None:
dntoeu_val = getattr(ait_pkt, field.name)
if field.dntoeu is not None or field.enum is not None or field.type.name in dtype.ComplexTypeMap.keys():
try:
dntoeu_val = getattr(ait_pkt, field.name)
except ValueError:
if isinstance(field.type, dtype.CmdType):
dntoeu_val = "Unidentified Cmd"
else:
dntoeu_val = getattr(ait_pkt.raw, field.name)

if isinstance(dntoeu_val, cmd.CmdDefn) or isinstance(dntoeu_val, evr.EVRDefn):
dntoeu_val = dntoeu_val.name

dntoeus[field.name] = dntoeu_val
packet_states[pkt_defn.name]['dntoeu'][field.name] = dntoeu_val

Expand Down Expand Up @@ -837,7 +862,7 @@ def handle():
def handle():
"""Return latest telemetry packet to client"""
for pkt_type, state in packet_states.items():
packet_states[pkt_type]['raw'] = replace_datetimes(state['raw'])
packet_states[pkt_type]['dntoeu'] = replace_datetimes(state['dntoeu'])

with Sessions.current() as session:
counters = session.tlm_counters
Expand Down
27 changes: 14 additions & 13 deletions ait/gui/static/js/ait/dtype.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,24 +197,17 @@ class Time8Type extends TimeType

class Time32Type extends TimeType
{
decode (view, offset=0) {
if (!inBounds(view, 4, offset)) return null

const tv_sec = view.getUint32(offset, false)
return new Date(GPSEpoch + (tv_sec * 1000))
decode (raw) {
return new Date(GPSEpoch + (raw * 1000))
}
}


class Time64Type extends TimeType
{
decode (view, offset=0) {
if (!inBounds(view, 8, offset)) return null

const tv_sec = view.getUint32(offset, false)
const tv_nsec = view.getUint32(offset + 4, false)

return new Date(GPSEpoch + (tv_sec * 1000) + (tv_nsec / 1e6))
decode (raw) {
const parts = String(raw).split('.').map(x => parseInt(x))
return new Date(GPSEpoch + (parts[0] * 1000) + (parts[1] / 1e6))
}
}

Expand Down Expand Up @@ -273,5 +266,13 @@ function get (typename) {
return type
}

function isComplexType(typeName) {
return typeName === 'CMD16' ||
typeName === 'EVR16' ||
typeName === 'TIME8' ||
typeName === 'TIME32' ||
typeName === 'TIME64'
}


export { PrimitiveType, get }
export { PrimitiveType, get, isComplexType }
33 changes: 12 additions & 21 deletions ait/gui/static/js/ait/gui/Field.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {sprintf} from 'sprintf-js'
import * as strftime from 'strftime'

import { CommandDefinition } from '../cmd.js'
import { isComplexType } from '../dtype.js'
import { EVRDefinition } from '../evr.js'

/**
Expand Down Expand Up @@ -303,32 +304,22 @@ const Field =
if (value === undefined || value === null) {
value = 'N/A'
}
else if (value instanceof CommandDefinition) {
value = value.name ? value.name : (value.opcode ? value.opcode : 'Unidentified Cmd')
}
else if (value instanceof EVRDefinition) {
value = value.name ? value.name : (value.code ? value.code : 'Unidentified EVR')
}
else if(Array.isArray(value)) {
// If we're handling an array value that means the field is a ArrayType.
// ArrayType elements are displayed as separate hex dumps of their contents.
let elemSize = 2 * this._fieldDefn.type._nbytes / this._fieldDefn.type._num_elems
let valAcc = ''
let format = `0x%0${elemSize}X `
for (let i of value) {
valAcc += sprintf(format, i)
}

value = valAcc
}
else {
if (vnode.attrs.format) {
const defn = ait.tlm.dict[this._pname]._fields[this._fname]
const type = defn && defn.type

value = (type && type.isTime) ?
strftime.utc()(vnode.attrs.format, value) :
sprintf(vnode.attrs.format, value)
if (this._raw === false && isComplexType(type._name) ||
typeof(value) !== "number") {
value = this.getValue(packet, true)
}

if (type && type.isTime) {
value = type.decode(value)
value = strftime.utc()(vnode.attrs.format, value)
} else {
value = sprintf(vnode.attrs.format, value)
}
} else {
// If the Field doesn't have a format specified and is
// displaying a float we default to 5 digits after the
Expand Down

0 comments on commit 10bd4d0

Please sign in to comment.