TReK Python  5.3.2
Telemetry/Command API
ex_packet_define.py
1"""!
2This example is for a simple, completely made up packet. It has a header,
3data, and trailer with all of the packet attributes set. The 'purpose' of
4this example is to define the packet and save it to disk. Other examples
5will use the saved packet to build and extract the packet. There are other
6ways to create packet definitializeions in TReK (e.g., simple comma delimited
7files).
8
9Just for fun here is the packet definitializeion in a small table. All of the
10data is 'big endian' except for a single parameter. All sizes are listed
11in bits. The data is packed (i.e., there are no gaps). The code below will
12set the start location for parameter, but it isn't shown in the table.
13Name Data Type Size Notes
14Version unsigned integer 4 Should always be zero
15PktId unsigned integer 12 For this packet, the value is 54
16PktLen unsigned integer 16 Length of packet after this point
17PktCnt unsigned integer 8 Packet counter
18Time system time 32 A.k.a. DT_UNIX_TIME
19IntParam signed integer 16 First data parameter
20UintParam unsigned integer 32 Three consecutive values
21FloatParam double 64 Little-endian floating point
22StrParam string 800 Varible length string
23Checksum unsigned integer 32 CRC-32 checksum
24"""
25
26import trek
27
28
29def main() -> None:
30 """
31 Main Routine
32 """
33
34 try:
35 # NOTE: There is only minimal error checking shown in the code below in
36 # order to simplify the example. In general, only the first time a
37 # method is used will the error handling be in this example. You should
38 # always check the returned value when one is available to ensure proper
39 # operation of the code. Error handling for this example is to exit on
40 # error.
41 pkt = trek.Packet()
43 p = trek.Parameter()
44
45 # Need to create the 'zones' for the packet and add it to the packet.
46 # The general steps for this are:
47 #
48 # 1. initializeialize the parameter collection
49 # 2. initializeialize the parameter.
50 # 3. Set the parameter attributes as needed (data type, name, length,
51 # byte order, start bit, etc.)
52 # 4. Add the parameter to the collection.
53 # 5. Repeat steps 2, 3, and 4 until all the parameters are in the
54 # parameter collection.
55 # 6. Add the parameter collection into the correct zone.
56 #
57 # Using the above procedure as a guideline, create the header zone for
58 # the packet. This will consist of 5 parameters: Version, PktId, PktLen,
59 # PktCnt, and Time.
60 pc.initialize() # this will clear out any data in the collection
61 pc.set_name("MyHeader") # not required, but can be useful
62 p.initialize() # this will clear out any data in the parameter
63 p.set_name("Version")
64 p.set_start_bit(0)
65
66 # There are a lot of exceptions for this method. The returned error
67 # is usually self explanatory, but an attempt at explanation is made
68 # throughout the documentation.
69 p.set_data_type(trek.ParameterDataType.DT_UNSIGNED_INTEGER, 4)
70
71 p.set_modifiable_flag(False) # don't want this value changed
72
73 # If this method fails it is usually because you have a data type
74 # mismatch or the value won't fit in the data. Since this is a 4-bit
75 # unsigned integer, any value above 15 will fail.
76 p.set_value(0)
77
78 # If this fails, it's most likely because you already have a parameter
79 # with the same name.
80 pc.add_parameter(p) # add the parameter to the collection
81
82 # Time to add the rest of the header parameters...and without error
83 # checking.
84 p.initialize() # this will clear out any data in the parameter
85 p.set_name("PktId")
86 p.set_start_bit(4) # Don't forget to set this!
87 p.set_data_type(trek.ParameterDataType.DT_UNSIGNED_INTEGER, 12)
88 p.set_modifiable_flag(False) # don't want this value changed
89 pc.add_parameter(p) # add the parameter to the collection
90 p.initialize()
91 p.set_name("PktLen")
92 p.set_start_bit(16)
93 p.set_data_type(trek.ParameterDataType.DT_UNSIGNED_INTEGER, 16)
94 p.set_modifiable_flag(True) # packet length will change
95 pc.add_parameter(p)
96 p.initialize() # this will clear out any data in the parameter
97 p.set_name("PktCnt")
98 p.set_start_bit(32)
99 p.set_data_type(trek.ParameterDataType.DT_UNSIGNED_INTEGER, 8)
100 p.set_modifiable_flag(True) # sequence count will change
101 pc.add_parameter(p)
102 p.initialize() # this will clear out any data in the parameter
103 p.set_name("Time")
104 p.set_start_bit(40)
105 p.set_data_type(trek.ParameterDataType.DT_UNIX_TIME, 32)
106 p.set_modifiable_flag(True) # time will change
107 pc.add_parameter(p)
108
109 # Now all of the parameters are in the collection, add the header. The
110 # Packet will make a copy of the input, so feel free to use it again.
111 # If it fails, you probably have already added a header. Use
112 # RemoveHeader first if you really want to add a different one.
113 pkt.add_header(pc)
114
115 # Time to add the 'data zone' to the packet. Same basic procedure as the
116 # header. The start location for each parameter is relative to the
117 # collection so they will restart at zero. This makes it much easier to
118 # reuse collections and packets within other packets.
119 pc.initialize() # we're going to reuse this, so must initializeialize it again.
120 pc.set_name("MyData")
121 p.initialize() # this will clear out any data in the parameter
122 p.set_name("IntParam")
123 p.set_start_bit(0) # Don't forget to start over for a new collection
124 p.set_data_type(trek.ParameterDataType.DT_TWOS_COMPLEMENT, 16)
125 p.set_modifiable_flag(True)
126 pc.add_parameter(p) # add the parameter to the collection
127
128 # This parameter has 3 samples, you should set the number of samples and
129 # also the sample offset. The sample offset will default to 0 which is
130 # the required value in this case. The sample offset is the number of
131 # bits that are between each of the samples.
132 p.initialize()
133 p.set_name("UintParam")
134 p.set_start_bit(16)
135 p.set_data_type(trek.ParameterDataType.DT_UNSIGNED_INTEGER, 32)
136 p.set_number_of_samples(3) # the default is 1, need 3 samples
137 p.set_sample_offset(0)
138 p.set_modifiable_flag(True)
139 pc.add_parameter(p) # add the parameter to the collection
140
141 # This parameter has a little endian byte order. The default byte order
142 # when setting the data type is big endian so you must pass in an extra
143 # parameter here.
144 p.initialize()
145 p.set_name("FloatParam")
146 p.set_start_bit(112)
147 p.set_data_type(
148 trek.ParameterDataType.DT_IEEE_FLOATING_POINT,
149 64,
150 trek.ParameterByteOrderType.LITTLE_ENDIAN_BYTE_ORDER,
151 )
152 p.set_modifiable_flag(True)
153 pc.add_parameter(p) # add the parameter to the collection
154
155 # The last parameter in the data is variable length. Variable length
156 # data must always be at the end of the container. You'll need to
157 # specify the parameter is variable length when setting the data type.
158 p.initialize()
159 p.set_name("StrParam")
160 p.set_start_bit(176)
161 p.set_data_type(
162 trek.ParameterDataType.DT_NULL_TERMINATED_STRING,
163 800, # 100 byte string (as bits)
164 trek.ParameterByteOrderType.BIG_ENDIAN_BYTE_ODER,
165 True,
166 )
167 p.set_modifiable_flag(True)
168 pc.add_parameter(p) # add the parameter to the collection
169
170 # Now add the data zone to the packet.
171 pkt.add_data(pc)
172
173 # The trailer consists of a single 32-bit parameter that is used for a
174 # checksum. The type of checksum is specified in the packet attributes.
175 # You just need to create the parameter to hold it here.
176 pc.initialize()
177 p.initialize()
178 p.set_name("Checksum")
179 p.set_start_bit(0)
180 p.set_data_type(trek.ParameterDataType.DT_UNSIGNED_INTEGER, 32)
181 p.set_modifiable_flag(True) # checksum will change
182 p.set_value(0)
183 pc.add_parameter(p)
184 pkt.add_trailer(pc)
185
186 # Once all of the data is in the packet, create the packet map that will
187 # allow lookup of the parameters in the packet.
188 pkt.create_global_packet_map()
189
190 # Now it's time to set the packet attributes. None of the attributes are
191 # required, but all are used in this example.
192
193 # Add an identifier. This packet only has one, but you can have any
194 # number of identifiers as required. The "Version" of the packet could
195 # be used here to ensure that the packet header hasn't changed, but we
196 # won't use it today.
197 pkt.add_identifier(
198 "PktId",
200 zone=trek.PacketZoneType.HEADER_ZONE,
201 id_type=trek.IdentifierType.CONTENT_IDENTIFIER,
202 has_default=False,
203 has_expected=True,
204 expected=54,
205 ),
206 )
207
208 # Add the length parameter. In this case the actual length of the packet
209 # is 4 bytes longer than the value of this field.
210 pkt.set_length_parameter(
211 "PktLen", trek.LengthParameterInfo(trek.PacketZoneType.HEADER_ZONE, 4)
212 )
213
214 # Add the packet counter. Since it is a simple forward based counter,
215 # the defaults work fine.
216 pkt.set_counter_parameter(
217 "PktCnt", trek.CounterParameterInfo(zone=trek.PacketZoneType.HEADER_ZONE)
218 )
219
220 # Add the time stamp. There's no offset here, so the defaults will work.
221 pkt.set_timestamp_parameter(
222 "Time", trek.TimeStampParameterInfo(zone=trek.PacketZoneType.HEADER_ZONE)
223 )
224
225 # Add the checksum. It's a CRC-32 of all of the header and data.
226 pkt.set_checksum_parameter(
227 "Checksum",
229 trek.PacketZoneType.TRAILER_ZONE,
230 trek.PacketChecksumPointType.START_HEADER,
231 0,
232 trek.PacketChecksumPointType.END_DATA,
233 0,
234 trek.PacketChecksumType.CT_CRC32,
235 ),
236 )
237
238 # Saving this packet to a file is easy.
239 pkt.save_file("my_file.xml") # output is XML
240
241 # The definitializeion of the packet now is saved to a file. You can use this
242 # definitializeion to build a packet to send or extract a packet you receive.
243 # Examples for both are provided.
244
245 except trek.TrekError as err:
246 # Locate friendly message why it failed.
247 print(err.find_error_code())
248 print(err)
249
250
251if __name__ == "__main__":
252 main()
Checksum Parameter attributes.
Definition: trek.py:4711
Counter Parameter attributes.
Definition: trek.py:4770
Identifier parameter attributes.
Definition: trek.py:4841
Length parameter attributes.
Definition: trek.py:4913
This class describes a packet composed of one or more parameters.
Definition: trek.py:5009
This class describes a parameter collection.
Definition: trek.py:9144
This class describes a single parameter within a telemetry or command message including its value.
Definition: trek.py:6527
Timestamp Parameter Info.
Definition: trek.py:4972
The TReK C++ was designed to return error codes.
Definition: trek.py:12846