mmecina / CCS

The UVIE Space Central Checkout System (CCS) and Test Specification Tool (TST)
Mozilla Public License 2.0
1 stars 0 forks source link

Accessing the Current TM Time and Display Row #14

Closed pasetti closed 2 months ago

pasetti commented 3 months ago

During testing, I see the incoming TM Packets in the PoolViewer. Each packet is displayed in a dedicated row. The row contains, among other things, a Row Number (first item in the row) and the TM Packet Time-Stamp.

Some of my tests are controlled by a script. The script sends TCs and print messages to a log file. I would like the log messages to also include the current TM Display Row Number and the latest TM Packet Time-Stamp. How can I access this information from a script?

mmecina commented 3 months ago

Interaction with a TM pool via the terminal is primarily facilitated via the SQLAlchemy ORM framework.

To access packets in a TM pool, there is the general-purpose command cfl.get_pool_rows(<pool_name>). It returns a Query object that supports interaction with the rows in the tm table of the _xxx_datastorage schema. This class provides a number of useful methods. For example, to fetch a list of DbTelemetry objects, each representing a row in the queried pool, type

cfl.get_pool_rows(<pool_name>).all()

The DbTelemetry class in turn provides direct access to the properties of the individual rows, which hold the values that are also displayed in the PoolViewer columns. Exemplarily, cfl.get_pool_rows("LIVE").all()[10].timestamp will return the timestamp of the 11th packet in the pool LIVE.

The Query also allows very efficient filtering of rows by column values before the data are actually fetched, e.g., to obtain only TM packets of service type 5:

cfl.get_pool_rows("LIVE").filter(cfl.DbTelemetry.stc==5).all()

or only rows starting from index 100:

cfl.get_pool_rows("LIVE").filter(cfl.DbTelemetry.idx>=100).all()

In case of large pools it is highly recommended to filter the Query adequately before fetching the actual data (i.e., executing the .all() call or iterating through the Query instance), since instantiating a large number of rows as DbTelemtery objects takes a while.

With that in mind, the best way of getting the row index (or, analogously, any other property) of the last packet received will be as follows:

cfl.get_pool_rows("LIVE").order_by(cfl.DbTelemetry.idx.desc()).first().idx

The .raw property will return the full packet as a byte-string.

In addition, to simply get the timestamp of the last received TM packet there is also the convenience function cfl.get_last_pckt_time(pool_name=<pool_name>, string=True), which returns the time as a string or float, depending on the value of thestring argument.

pasetti commented 3 months ago

Thanks for the detailed and clear explanation (and for the very well-designed interface!). I have tried out your suggestions and they work as expected.

Based on your explanation, it is clear how to access packet properties which are explicitly identified in the PoolViewer (e.g. row number, service type, service sub-type, packet length. etc).

Suppose now that I wanted to retrieve the value of parameter PAR in the most recent TM packet of type PCKT_TYPE (as defined by the packet service type and sub-type). I suppose that this is done in two steps: (a) retrieve the most recent packet of type PCKT_TYPE and then (b) to extract parameter PAR from it. Is this correct? And how exactly do I extract the value of parameter PAR from a given raw packet?

And, finally, suppose that I were interested in the value of a parameter in a (3,25) packet with a given SID. In this case, I suppose that I would have to proceed in 3 steps: (a) I retrieve the 10 most recent TM(3,25) packets (on the assumption that my desired SID is one of them); (b) I iterate over the 10 packets until I find the TM(3,25) packet with the desired SID: and (c) I extract the value pf parameter PAR from that packet. Is this approach correct or is there a better way of doing what I want?

mmecina commented 3 months ago

This is indeed frequently needed, so fortunately a function that does just that already exists:

cfl.get_param_values

The most relevant parameters are: param="AdcTemp" name (description) of the parameter as defined in the MIB (PCF_DESCR) hk="IASWHK_Essential" description of the containing TM packet as per MIB (PID_DESCR) pool_name="LIVE" pool to query

This returns an array of time, parametervalue pairs for every matching packet found in the pool. To limit the output to the last x occurences, set last=x. In case of text-calibrated parameters it is necessary to set mk_array=False to get the calibrated values as strings, otherwise their raw numerical values will be returned.

This function works not only for HK (3,25) packets, but also for all other fixed-length TMs.

pasetti commented 2 months ago

Thanks Marko: I have tried your suggestions and everything works as expected. I therefore close the ticket.