Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #189 - Update diff handling of complex types and human readable values #191

Merged
merged 2 commits into from
Jan 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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