openc3-cosmos-demo 6.0.2 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 231e6075158197e5c69a00c65a7104fb68adba7088dd0a9ae8c23f566a6d514f
4
- data.tar.gz: b1b38d14dbc759655936764f6a35adfbed12ae3875dedd05b5bc9b78174ec664
3
+ metadata.gz: c888a30f0d6951c4b7c2c10f8868e8c80569e09eac181b6998777c79d824b4a0
4
+ data.tar.gz: 9d7ec85c58a58937720cb368059bca004544cd1d8f6227c65c7fba83dc75d96a
5
5
  SHA512:
6
- metadata.gz: '081623a648d0e9c52127c31d8a57af6efb179d1831d7bb25635d4d88baf2cd8db4409be3395131a6e4fc81a557e23db1ce26a32962e87cec7d78dced7f155831'
7
- data.tar.gz: 32691c50f96230d8dddcd2f820ac47a05f7e00516e5f740679c19ad742ee505d69f7c4b0277b3dc7d9efe46a616a8884131a8e3bf2ff91451fa3928307431945
6
+ metadata.gz: e818d703ee7703d87cd5796da6efb4aa83b1f17a934ebd0aa25a3dc89af83640464a2193d40c45d054d82543e899291bfb3732498362dc5fed8c95f7b2f40fe3
7
+ data.tar.gz: 466106a6e5effdf51249e8ad0cd7780b66350fd94450498020331b591a8f1fc4209d9d0878b8f4045b4bfe0385238dc488065985e8ab30ea0d5e726af159b58b
@@ -97,6 +97,8 @@ COMMAND <%= target_name %> TIME_OFFSET BIG_ENDIAN "Subtract the packet time by t
97
97
  VALIDATOR inst_cmd_validator.rb
98
98
  <%= render "_ccsds_cmd.txt", locals: {id: 12} %>
99
99
  APPEND_PARAMETER SECONDS 32 UINT MIN MAX 0 "Seconds to subtract from packet time"
100
+ APPEND_PARAMETER IP_ADDRESS 32 UINT MIN MAX "127.0.0.1" "IP address"
101
+ WRITE_CONVERSION ip_write_conversion.rb
100
102
 
101
103
  COMMAND <%= target_name %> HIDDEN BIG_ENDIAN "Hidden command to bump the hidden packet"
102
104
  VALIDATOR inst_cmd_validator.rb
@@ -73,6 +73,14 @@ TELEMETRY <%= target_name %> HEALTH_STATUS BIG_ENDIAN "Health and status from th
73
73
  GENERIC_READ_CONVERSION_START FLOAT 32
74
74
  packet.read('TEMP1') * 1_000_000
75
75
  GENERIC_READ_CONVERSION_END
76
+ # Enable to test the ARRAYPLOT widget with array of array data [[x1,x2,...],[y1,y2,...]]
77
+ # ITEM POINTS 0 0 DERIVED
78
+ # GENERIC_READ_CONVERSION_START UINT 800
79
+ # return [
80
+ # Array.new(800) { |i| i * 0.1 },
81
+ # (0...800).map { |i| Math.sin(2 * Math::PI * i / 800) }
82
+ # ]
83
+ # GENERIC_READ_CONVERSION_END
76
84
  PROCESSOR TEMP1STAT statistics_processor.rb TEMP1 100
77
85
  PROCESSOR TEMP1WATER watermark_processor.rb TEMP1
78
86
 
@@ -127,6 +135,7 @@ TELEMETRY <%= target_name %> PARAMS BIG_ENDIAN "Params set by SETPARAMS command"
127
135
  STATE GOOD 0 GREEN
128
136
  STATE BAD 1 RED
129
137
  <% end %>
138
+ APPEND_ITEM IP_ADDRESS 32 UINT "Encoded IP Address"
130
139
  APPEND_ITEM P_2.2,2 32 UINT "Test weird characters"
131
140
  APPEND_ITEM P-3+3=3 32 UINT "Test weird characters"
132
141
  APPEND_ITEM P4!@#$%^&*? 32 UINT "Test weird characters"
@@ -160,6 +169,7 @@ TELEMETRY <%= target_name %> MECH BIG_ENDIAN "Mechanism status ©®"
160
169
  UNITS DEGREES DEG
161
170
  APPEND_ITEM CURRENT 32 FLOAT "Device current"
162
171
  UNITS micro-Ampères µA
172
+ APPEND_ITEM STRING 0 STRING "String"
163
173
  ITEM PACKET_TIME 0 0 DERIVED "Ruby time based on TIMESEC and TIMEUS"
164
174
  READ_CONVERSION unix_time_conversion.rb TIMESEC TIMEUS
165
175
 
@@ -22,6 +22,7 @@ class InstCmdValidator < OpenC3::CommandValidator
22
22
  def pre_check(command)
23
23
  # Record the current value of CMD_ACPT_CNT for comparison in post_check
24
24
  @cmd_acpt_cnt = tlm("<%= target_name %> HEALTH_STATUS CMD_ACPT_CNT")
25
+ @cmd_acpt_cnt ||= 0 # If the telemetry value is nil, set it to 0
25
26
  return [true, nil]
26
27
  end
27
28
 
@@ -152,6 +152,7 @@ module OpenC3
152
152
  @last_temp2 = 0
153
153
  @quiet = false
154
154
  @time_offset = 0
155
+ @ip_address = 0
155
156
  end
156
157
 
157
158
  def set_rates
@@ -238,6 +239,7 @@ module OpenC3
238
239
  when 'TIME_OFFSET'
239
240
  hs_packet.cmd_acpt_cnt += 1
240
241
  @time_offset = packet.read('seconds')
242
+ @ip_address = packet.read('ip_address')
241
243
  when 'HIDDEN'
242
244
  # Deliberately do not increment cmd_acpt_cnt
243
245
  @tlm_packets['HIDDEN'].count = packet.read('count')
@@ -378,6 +380,7 @@ module OpenC3
378
380
  packet.timesec = time.tv_sec - @time_offset
379
381
  packet.timeus = time.tv_usec
380
382
  packet.ccsdsseqcnt += 1
383
+ packet.ip_address = @ip_address
381
384
 
382
385
  when 'IMAGE'
383
386
  packet.timesec = time.tv_sec - @time_offset
@@ -1,43 +1,68 @@
1
- tl = create_timeline("Mine")
2
- puts tl #=> {"name"=>"Mine", "color"=>"#ae2d1b", "scope"=>"DEFAULT", "updated_at"=>1698763720728596964}
1
+ tl = create_timeline("RubyTL")
2
+ puts tl #=> {"name"=>"RubyTL", "color"=>"#cdce42", "execute"=>true, "shard"=>0, "scope"=>"DEFAULT", "updated_at"=>1737128664493258134}
3
3
  tls = list_timelines()
4
- check_expression("#{tls.length} == 1")
5
- puts tls[0] #=> {"name"=>"Mine", "color"=>"#ae2d1b", "scope"=>"DEFAULT", "updated_at"=>1698763720728596964}
6
- delete_timeline("Mine")
7
- check_expression("#{list_timelines().length} == 0")
4
+ names = tls.map { |tl| tl['name'] }
5
+ check_expression("#{names.include?('RubyTL')} == true")
6
+ puts tls[0] #=> {"name"=>"RubyTL", "color"=>"#cdce42", "execute"=>true, "shard"=>0, "scope"=>"DEFAULT", "updated_at"=>1737128664493258134}
8
7
 
9
- create_timeline("Mine")
10
- set_timeline_color("Mine", "#4287f5")
11
- puts get_timeline("Mine") #=> {"name"=>"Mine", "color"=>"#4287f5", "scope"=>"DEFAULT", "updated_at"=>1698763720728596964}
8
+ set_timeline_color("RubyTL", "#4287f5")
9
+ puts get_timeline("RubyTL") #=> {"name"=>"RubyTL", "color"=>"#4287f5", "execute"=>true, "shard"=>0, "scope"=>"DEFAULT", "updated_at"=>1737128689586673173}
12
10
 
13
11
  now = Time.now()
14
12
  start = now + 3600
15
- stop = start + 3600 # Stop plus 1hr
16
- act = create_timeline_activity("Mine", kind: "reserve", start: start, stop: stop)
13
+ stop = start + 3600
14
+ act1 = create_timeline_activity("RubyTL", kind: "RESERVE", start: start, stop: stop)
15
+ puts act1 #=>
16
+ # { "name"=>"RubyTL", "updated_at"=>1737128705034982375, "start"=>1737132303, "stop"=>1737135903,
17
+ # "kind"=>"reserve", "data"=>{"username"=>"operator"},
18
+ # "scope"=>"DEFAULT", "fulfillment"=>false, "uuid"=>"5f373846-eb6c-43cd-97bd-cca19a8ffb04",
19
+ # "events"=>[{"time"=>1737128705, "event"=>"created"}], "recurring"=>{}}
20
+ act2 = create_timeline_activity("RubyTL", kind: "COMMAND", start: start, stop: stop,
21
+ data: {command: "INST COLLECT with TYPE NORMAL, DURATION 5, TEMP 10"})
22
+ puts act2 #=>
23
+ # { "name"=>"RubyTL", "updated_at"=>1737128761316084471, "start"=>1737132303, "stop"=>1737135903,
24
+ # "kind"=>"command", "data"=>{"command"=>"INST COLLECT with TYPE NORMAL, DURATION 5, TEMP 10", "username"=>"operator"},
25
+ # "scope"=>"DEFAULT", "fulfillment"=>false, "uuid"=>"cdb661b4-a65b-44e7-95e2-5e1dba80c782",
26
+ # "events"=>[{"time"=>1737128761, "event"=>"created"}], "recurring"=>{}}
27
+ start = now + 7200
28
+ stop = start + 3600
29
+ act3 = create_timeline_activity("RubyTL", kind: "SCRIPT", start: start, stop: stop,
30
+ data: {environment: [{key: "USER", value: "JASON"}], script: "INST/procedures/checks.rb"})
31
+ puts act3 #=>
32
+ # { "name"=>"RubyTL", "updated_at"=>1737128791047885970, "start"=>1737135903, "stop"=>1737139503,
33
+ # "kind"=>"script", "data"=>{"environment"=>[{"key"=>"USER", "value"=>"JASON"}], "script"=>"INST/procedures/checks.rb", "username"=>"operator"},
34
+ # "scope"=>"DEFAULT", "fulfillment"=>false, "uuid"=>"70426e3d-6313-4897-b159-6e5cd94ace1d",
35
+ # "events"=>[{"time"=>1737128791, "event"=>"created"}], "recurring"=>{}}
36
+
37
+ act = get_timeline_activity("RubyTL", act2['start'], act2['uuid'])
17
38
  puts act #=>
18
- # { "name"=>"Mine", "updated_at"=>1698763721927799173, "fulfillment"=>false, "duration"=>3600,
19
- # "start"=>1698764400, "stop"=>1698768000, "kind"=>"reserve",
20
- # "events"=>[{"time"=>1698763721, "event"=>"created"}], "data"=>{"username"=>""} }
39
+ # { "name"=>"RubyTL", "updated_at"=>1737128761316084471, "start"=>1737132303, "stop"=>1737135903,
40
+ # "kind"=>"command", "data"=>{"command"=>"INST COLLECT with TYPE NORMAL, DURATION 5, TEMP 10", "username"=>"operator"},
41
+ # "scope"=>"DEFAULT", "fulfillment"=>false, "uuid"=>"cdb661b4-a65b-44e7-95e2-5e1dba80c782",
42
+ # "events"=>[{"time"=>1737128761, "event"=>"created"}], "recurring"=>{}}
43
+
21
44
  # Get activities in the past ... should be none
22
- tlas = get_timeline_activities("Mine", start: Time.now() - 3600, stop: Time.now())
45
+ tlas = get_timeline_activities("RubyTL", start: Time.now() - 3600, stop: Time.now())
23
46
  check_expression("#{tlas.length} == 0")
24
- # Get all activities
25
- tlas = get_timeline_activities("Mine")
26
- check_expression("#{tlas.length} == 1")
47
+ # Get all activities at plus and minus 1 week
48
+ tlas = get_timeline_activities("RubyTL")
49
+ check_expression("#{tlas.length} == 3")
27
50
 
28
51
  # Create and delete a new activity
29
52
  start = start + 7200
30
53
  stop = start + 300
31
- act = create_timeline_activity("Mine", kind: "reserve", start: start, stop: stop)
32
- tlas = get_timeline_activities("Mine")
33
- check_expression("#{tlas.length} == 2")
34
- delete_timeline_activity("Mine", act['start'], act['uuid'])
35
- tlas = get_timeline_activities("Mine")
36
- check_expression("#{tlas.length} == 1")
54
+ act = create_timeline_activity("RubyTL", kind: "reserve", start: start, stop: stop)
55
+ tlas = get_timeline_activities("RubyTL")
56
+ check_expression("#{tlas.length} == 4")
57
+ delete_timeline_activity("RubyTL", act['start'], act['uuid'])
58
+ tlas = get_timeline_activities("RubyTL")
59
+ check_expression("#{tlas.length} == 3")
37
60
 
38
61
  # delete fails since the timeline has activities
39
- delete_timeline("Mine") #=> RuntimeError : Failed to delete timeline due to timeline contains activities, must force remove
62
+ delete_timeline("RubyTL") #=> RuntimeError : Failed to delete timeline due to timeline contains activities, must force remove
40
63
  # Force delete since the timeline has activities
41
- delete_timeline("Mine", force: true)
64
+ delete_timeline("RubyTL", force: true)
65
+ # Verify the timeline no longer exists
42
66
  tls = list_timelines()
43
- check_expression("#{tls.length} == 0")
67
+ names = tls.map { |tl| tl['name'] }
68
+ check_expression("#{names.include?('RubyTL')} == false")
@@ -1,4 +1,4 @@
1
- # Display all environment variables
1
+ # Display the environment variables
2
2
  puts ENV.inspect
3
3
  # Print the TYPE env var which is set in the INST COMMANDING screen
4
4
  puts "ENV['TYPE']:#{ENV['TYPE']}"
@@ -17,5 +17,5 @@ wait_expression("true == false", 5)
17
17
  wait_packet("<%= target_name %>","ADCS", 2, 5)
18
18
  wait_check("<%= target_name %> ADCS BIASX == 100", 5)
19
19
  wait_check_tolerance("<%= target_name %> ADCS BIASX", 5, 0.5, 5)
20
- wait_check_expression("true == false", 5)
20
+ wait_check_expression("tlm('<%= target_name %> HEALTH_STATUS TEMP1') < 101", 5, 0.25)
21
21
  wait_check_packet("<%= target_name %>","ADCS", 2, 5)
@@ -0,0 +1,88 @@
1
+ # Helper method to check for a script to change state
2
+ def wait_for_action(id, state)
3
+ i = 0
4
+ while i < 100
5
+ script = running_script_get(id)
6
+ if script['state'] == state
7
+ check_expression("'#{script['state']}' == '#{state}'")
8
+ break
9
+ end
10
+ wait 0.1
11
+ end
12
+ check_expression("'#{script['state']}' == '#{state}'")
13
+ end
14
+
15
+ SCRIPT_NAME = "INST/procedures/new_script.rb"
16
+
17
+ # Ensure it's not already there
18
+ step_mode()
19
+ script_delete(SCRIPT_NAME)
20
+ scripts = script_list()
21
+ check_expression("#{scripts.length} > 100")
22
+ run_mode()
23
+
24
+ contents = "puts('bad"
25
+ script_create(SCRIPT_NAME, contents)
26
+ body = script_body(SCRIPT_NAME)
27
+ result = script_syntax_check(body)
28
+ check_expression("#{result['success']} == false")
29
+
30
+ # Create a valid script that doesn't complete
31
+ contents = "set_line_delay(1)\nputs 'Hello from Ruby'\nputs('.')\nputs('.')\nwhile true\nputs Time.now\nwait 0.5\nwait 0.5\nend"
32
+ script_create(SCRIPT_NAME, contents)
33
+ scripts = script_list()
34
+ check_expression("#{scripts.include?(SCRIPT_NAME)} == true")
35
+
36
+ script = script_instrumented(contents)
37
+ check_expression("#{script.include?('RunningScript')} == true")
38
+
39
+ id = script_run(SCRIPT_NAME)
40
+ check_expression("#{id.to_i} > 0")
41
+ wait_for_action(id, 'running')
42
+
43
+ list = running_script_list()
44
+ started = list.select {|script| script["id"] == id}[0]
45
+ check_expression("'#{started['name']}' == SCRIPT_NAME")
46
+ script = running_script_get(id)
47
+ check_expression("'#{script['name']}' == SCRIPT_NAME")
48
+
49
+ running_script_pause(id)
50
+ wait_for_action(id, 'paused')
51
+ running_script_step(id)
52
+ wait_for_action(id, 'paused')
53
+ running_script_retry(id)
54
+ wait_for_action(id, 'paused')
55
+ running_script_go(id)
56
+ wait_for_action(id, 'running')
57
+ running_script_stop(id)
58
+ wait 1
59
+
60
+ list = running_script_list()
61
+ script = list.select {|script| script["id"] == id}[0]
62
+ # Script is stopped so it should NOT be in the running list
63
+ check_expression("#{script.nil?} == true")
64
+
65
+ list = completed_script_list()
66
+ script = list.select {|script| script["id"] == id}[0]
67
+ # Script is completed so it should be in the completed list
68
+ check_expression("#{script.nil?} == false")
69
+
70
+ id = script_run(SCRIPT_NAME)
71
+ wait_for_action(id, 'running')
72
+ running_script_delete(id) # Stop and completely remove the script
73
+ wait 1
74
+
75
+ list = running_script_list()
76
+ script = list.select {|script| script["id"] == id}[0]
77
+ # Script is deleted, so it should NOT be in the running list
78
+ check_expression("#{script.nil?} == true")
79
+ list = completed_script_list()
80
+ # Script is deleted so it should be in the completed list
81
+ script = list.select {|script| script["id"] == id}[0]
82
+ check_expression("#{script.nil?} == false")
83
+
84
+ script_lock(SCRIPT_NAME)
85
+ script_unlock(SCRIPT_NAME)
86
+ script_delete(SCRIPT_NAME)
87
+ scripts = script_list()
88
+ check_expression("#{scripts.include?(SCRIPT_NAME)} == false")
@@ -1,27 +1,32 @@
1
1
  SCREEN AUTO AUTO 1.0
2
2
 
3
- VERTICAL
4
- TITLE "<%= target_name %> Instrument Graphs"
3
+ TITLE "<%= target_name %> Instrument Graphs"
5
4
 
6
- MATRIXBYCOLUMNS 2
7
- SPARKLINE <%= target_name %> HEALTH_STATUS TEMP1
8
- SETTING SIZE 400 50
9
- SETTING HISTORY 30s
10
- SPARKLINE <%= target_name %> HEALTH_STATUS TEMP2
11
- SETTING SIZE 400 50
12
- SETTING HISTORY 30s
13
- LABELSPARKLINE <%= target_name %> HEALTH_STATUS TEMP3
14
- LABELSPARKLINE <%= target_name %> HEALTH_STATUS TEMP4
15
- LINEGRAPH <%= target_name %> HEALTH_STATUS TEMP1
16
- SETTING ITEM <%= target_name %> ADCS Q1
17
- LINEGRAPH <%= target_name %> HEALTH_STATUS TEMP2 RAW
18
- SETTING SECONDSGRAPHED 60
19
- SETTING POINTSSAVED 600
20
- SETTING POINTSGRAPHED 60
21
- LINEGRAPH <%= target_name %> HEALTH_STATUS TEMP3 CONVERTED REDUCED_MINUTE MIN
22
- SETTING SIZE 600 500 # width height
23
- SETTING HISTORY 1h
24
- LINEGRAPH <%= target_name %> HEALTH_STATUS TEMP4
25
- SETTING HISTORY 30m
26
- END
5
+ MATRIXBYCOLUMNS 2
6
+ SPARKLINE <%= target_name %> HEALTH_STATUS TEMP1
7
+ SETTING SIZE 400 50
8
+ SETTING HISTORY 30s
9
+ SPARKLINE <%= target_name %> HEALTH_STATUS TEMP2
10
+ SETTING SIZE 400 50
11
+ SETTING HISTORY 30s
12
+ LABELSPARKLINE <%= target_name %> HEALTH_STATUS TEMP3
13
+ LABELSPARKLINE <%= target_name %> HEALTH_STATUS TEMP4
14
+ LINEGRAPH <%= target_name %> HEALTH_STATUS TEMP1
15
+ SETTING ITEM <%= target_name %> ADCS Q1
16
+ LINEGRAPH <%= target_name %> HEALTH_STATUS TEMP2 RAW
17
+ SETTING SECONDSGRAPHED 60
18
+ SETTING POINTSSAVED 600
19
+ SETTING POINTSGRAPHED 60
20
+ LINEGRAPH <%= target_name %> HEALTH_STATUS TEMP3 CONVERTED REDUCED_MINUTE MIN
21
+ SETTING SIZE 600 500 # width height
22
+ SETTING HISTORY 1h
23
+ LINEGRAPH <%= target_name %> HEALTH_STATUS TEMP4
24
+ SETTING HISTORY 30m
27
25
  END
26
+
27
+ ARRAYPLOT
28
+ SETTING TITLE "Array Data"
29
+ SETTING ITEM INST HEALTH_STATUS ARY
30
+ SETTING ITEM INST HEALTH_STATUS ARY2
31
+ SETTING SIZE 600 400
32
+ SETTING X_AXIS 10 10
@@ -29,9 +29,11 @@ COMMAND <%= target_name %> SETPARAMS BIG_ENDIAN "Sets numbered parameters"
29
29
  <%= render "_ccsds_cmd.txt", locals: {id: 4} %>
30
30
  # ERB syntax:
31
31
  <% (1..5).each do |i| %>
32
- APPEND_PARAMETER VALUE<%= i %> 16 UINT 0 5 1 "Value <%= i %> setting"
32
+ # The packet is BIG_ENDIAN (CCSDS) but these fields are LITTLE_ENDIAN
33
+ APPEND_PARAMETER VALUE<%= i %> 16 UINT 0 5 1 "Value <%= i %> setting" LITTLE_ENDIAN
33
34
  RELATED_ITEM <%= target_name %> PARAMS VALUE<%= i %>
34
35
  <% end %>
36
+ SCREEN <%= target_name %> PARAMS
35
37
 
36
38
  SELECT_PARAMETER VALUE5
37
39
  POLY_WRITE_CONVERSION 0 2
@@ -95,6 +97,8 @@ COMMAND <%= target_name %> TIME_OFFSET BIG_ENDIAN "Subtract the packet time by t
95
97
  VALIDATOR inst2_cmd_validator.py
96
98
  <%= render "_ccsds_cmd.txt", locals: {id: 12} %>
97
99
  APPEND_PARAMETER SECONDS 32 UINT MIN MAX 0 "Seconds to subtract from packet time"
100
+ APPEND_PARAMETER IP_ADDRESS 32 UINT MIN MAX "127.0.0.1" "IP address"
101
+ WRITE_CONVERSION openc3/conversions/ip_write_conversion.py
98
102
 
99
103
  COMMAND <%= target_name %> HIDDEN BIG_ENDIAN "Hidden command to bump the hidden packet"
100
104
  VALIDATOR inst2_cmd_validator.py
@@ -65,6 +65,14 @@ TELEMETRY <%= target_name %> HEALTH_STATUS BIG_ENDIAN "Health and status from th
65
65
  READ_CONVERSION openc3/conversions/processor_conversion.py TEMP1STAT MEAN
66
66
  ITEM TEMP1STDDEV 0 0 DERIVED "Stddev of most recent 100 samples for TEMP1"
67
67
  READ_CONVERSION openc3/conversions/processor_conversion.py TEMP1STAT STDDEV
68
+ ITEM TEMP1_MICRO 0 0 DERIVED
69
+ GENERIC_READ_CONVERSION_START FLOAT 32
70
+ packet.read('TEMP1') / 1_000_000
71
+ GENERIC_READ_CONVERSION_END
72
+ ITEM TEMP1_MEGA 0 0 DERIVED
73
+ GENERIC_READ_CONVERSION_START FLOAT 32
74
+ packet.read('TEMP1') * 1_000_000
75
+ GENERIC_READ_CONVERSION_END
68
76
  PROCESSOR TEMP1STAT openc3/processors/statistics_processor.py TEMP1 100
69
77
  PROCESSOR TEMP1WATER openc3/processors/watermark_processor.py TEMP1
70
78
 
@@ -119,6 +127,7 @@ TELEMETRY <%= target_name %> PARAMS BIG_ENDIAN "Params set by SETPARAMS command"
119
127
  STATE GOOD 0 GREEN
120
128
  STATE BAD 1 RED
121
129
  <% end %>
130
+ APPEND_ITEM IP_ADDRESS 32 UINT "Encoded IP Address"
122
131
  APPEND_ITEM P_2.2,2 32 UINT "Test weird characters"
123
132
  APPEND_ITEM P-3+3=3 32 UINT "Test weird characters"
124
133
  APPEND_ITEM P4!@#$%^&*? 32 UINT "Test weird characters"
@@ -137,7 +146,7 @@ TELEMETRY <%= target_name %> IMAGE BIG_ENDIAN "Packet with image data"
137
146
  ITEM PACKET_TIME 0 0 DERIVED "Python time based on TIMESEC and TIMEUS"
138
147
  READ_CONVERSION openc3/conversions/unix_time_conversion.py TIMESEC TIMEUS
139
148
 
140
- TELEMETRY <%= target_name %> MECH BIG_ENDIAN "Mechanism status"
149
+ TELEMETRY <%= target_name %> MECH BIG_ENDIAN "Mechanism status ©®"
141
150
  <%= render "_ccsds_tlm.txt", locals: {apid: 5} %>
142
151
  APPEND_ITEM EXTRA 32 FLOAT "Extra item to be deleted"
143
152
  APPEND_ITEM SLRPNL1 32 FLOAT "Solar panel 1 angle"
@@ -148,6 +148,7 @@ class SimInst(SimulatedTarget):
148
148
  self.last_temp2 = 0
149
149
  self.quiet = False
150
150
  self.time_offset = 0
151
+ self.ip_address = 0
151
152
 
152
153
  def set_rates(self):
153
154
  self.set_rate("ADCS", 10)
@@ -213,6 +214,7 @@ class SimInst(SimulatedTarget):
213
214
  case "TIME_OFFSET":
214
215
  hs_packet.write("cmd_acpt_cnt", hs_packet.read("cmd_acpt_cnt") + 1)
215
216
  self.time_offset = packet.read("seconds")
217
+ self.ip_address = packet.read("ip_address")
216
218
  case "HIDDEN":
217
219
  # Deliberately do not increment cmd_acpt_cnt
218
220
  self.tlm_packets["HIDDEN"].count = packet.read("count")
@@ -382,6 +384,7 @@ class SimInst(SimulatedTarget):
382
384
  packet.write("timesec", int(time - self.time_offset))
383
385
  packet.write("timeus", int((time % 1) * 1000000))
384
386
  packet.write("ccsdsseqcnt", packet.read("ccsdsseqcnt") + 1)
387
+ packet.write("ip_address", self.ip_address)
385
388
 
386
389
  case "IMAGE":
387
390
  packet.write("timesec", int(time - self.time_offset))
@@ -1,57 +1,72 @@
1
1
  from datetime import datetime, timezone, timedelta
2
2
 
3
- tl = create_timeline("Mine")
4
- print(
5
- tl
6
- ) # => {"name":"Mine", "color":"#ae2d1b", "scope":"DEFAULT", "updated_at":1698763720728596964}
3
+ tl = create_timeline("PythonTL", color="#FF0000")
4
+ print(tl) #=> {'name': 'PythonTL', 'color': '#FF0000', 'execute': True, 'shard': 0, 'scope': 'DEFAULT', 'updated_at': 1737129062249843763}
7
5
  tls = list_timelines()
8
- print(tls)
9
- print(type(tls))
10
- check_expression(f"{len(tls)} == 1")
11
- print(
12
- tls[0]
13
- ) # => {"name":"Mine", "color":"#ae2d1b", "scope":"DEFAULT", "updated_at":1698763720728596964}
14
- delete_timeline("Mine")
15
- check_expression(f"{len(list_timelines())} == 0")
6
+ print(tls) #=> [{'name': 'PythonTL', 'color': '#FF0000', 'execute': True, 'shard': 0, 'scope': 'DEFAULT', 'updated_at': 1737129062249843763}]
7
+ names = [tl["name"] for tl in tls]
8
+ check_expression(f"{'PythonTL' in names} == True")
9
+ print(tls[0]) #=> {'name': 'PythonTL', 'color': '#FF0000', 'execute': True, 'shard': 0, 'scope': 'DEFAULT', 'updated_at': 1737129436186473255}
16
10
 
17
- create_timeline("Mine")
18
- set_timeline_color("Mine", "#4287f5")
19
- print(
20
- get_timeline("Mine")
21
- ) # => {"name":"Mine", "color":"#4287f5", "scope":"DEFAULT", "updated_at":1698763720728596964}
11
+ set_timeline_color("PythonTL", "#4287f5")
12
+ print(get_timeline("PythonTL")) #=> {'name': 'PythonTL', 'color': '#4287f5', 'execute': True, 'shard': 0, 'scope': 'DEFAULT', 'updated_at': 1737129508391137136}
22
13
 
23
14
  now = datetime.now(timezone.utc)
24
15
  start = now + timedelta(hours=1)
25
- stop = start + timedelta(hours=1) # Stop plus 1hr
26
- act = create_timeline_activity("Mine", kind="reserve", start=start, stop=stop)
27
- print(act) # =>
28
- # { "name"=>"Mine", "updated_at"=>1698763721927799173, "fulfillment"=>false, "duration"=>3600,
29
- # "start"=>1698764400, "stop"=>1698768000, "kind"=>"reserve",
30
- # "events"=>[{"time"=>1698763721, "event"=>"created"}], "data"=>{"username"=>""} }
16
+ stop = start + timedelta(hours=1)
17
+ act1 = create_timeline_activity("PythonTL", kind="reserve", start=start, stop=stop)
18
+ print(act1) # =>
19
+ # {'name': 'PythonTL', 'updated_at': 1737129305507111708, 'start': 1737132902, 'stop': 1737136502,
20
+ # 'kind': 'reserve', 'data': {'username': 'operator'},
21
+ # 'scope': 'DEFAULT', 'fulfillment': False, 'uuid': '46328378-ed78-4719-ad70-e84951a196fd',
22
+ # 'events': [{'time': 1737129305, 'event': 'created'}], 'recurring': {}}
23
+ act2 = create_timeline_activity("PythonTL", kind="COMMAND", start=start, stop=stop,
24
+ data={'command': "INST COLLECT with TYPE NORMAL, DURATION 5, TEMP 10"})
25
+ print(act2) #=>
26
+ # {'name': 'PythonTL', 'updated_at': 1737129508886643928, 'start': 1737133108, 'stop': 1737136708,
27
+ # 'kind': 'command', 'data': {'command': 'INST COLLECT with TYPE NORMAL, DURATION 5, TEMP 10', 'username': 'operator'},
28
+ # 'scope': 'DEFAULT', 'fulfillment': False, 'uuid': 'cddbf034-ccdd-4c36-91c2-2653a39b06a5',
29
+ # 'events': [{'time': 1737129508, 'event': 'created'}], 'recurring': {}}
30
+ start = now + timedelta(hours=2)
31
+ stop = start + timedelta(hours=1)
32
+ act3 = create_timeline_activity("PythonTL", kind="SCRIPT", start=start, stop=stop,
33
+ data={'environment': [{'key': "USER", 'value': "JASON"}], 'script': "INST2/procedures/checks.py"})
34
+ print(act3) #=>
35
+ # {'name': 'PythonTL', 'updated_at': 1737129509288571345, 'start': 1737136708, 'stop': 1737140308,
36
+ # 'kind': 'script', 'data': {'environment': [{'key': 'USER', 'value': 'JASON'}], 'script': 'INST2/procedures/checks.py', 'username': 'operator'},
37
+ # 'scope': 'DEFAULT', 'fulfillment': False, 'uuid': '4f8d791b-b138-4383-b5ec-85c28b2bea20',
38
+ # 'events': [{'time': 1737129509, 'event': 'created'}], 'recurring': {}}
39
+
40
+ act = get_timeline_activity("PythonTL", act2['start'], act2['uuid'])
41
+ print(act) #=>
42
+ # { "name"=>"RubyTL", "updated_at"=>1737128761316084471, "start"=>1737132303, "stop"=>1737135903,
43
+ # "kind"=>"command", "data"=>{"command"=>"INST COLLECT with TYPE NORMAL, DURATION 5, TEMP 10", "username"=>"operator"},
44
+ # "scope"=>"DEFAULT", "fulfillment"=>false, "uuid"=>"cdb661b4-a65b-44e7-95e2-5e1dba80c782",
45
+ # "events"=>[{"time"=>1737128761, "event"=>"created"}], "recurring"=>{}}
46
+
31
47
  # Get activities in the past ... should be none
32
- tlas = get_timeline_activities("Mine", start=start - timedelta(hours=2), stop=now)
48
+ tlas = get_timeline_activities("PythonTL", start=now - timedelta(hours=2), stop=now)
33
49
  print(tlas)
34
50
  print(type(tlas))
35
51
  check_expression(f"{len(tlas)} == 0")
36
- # Get all activities
37
- tlas = get_timeline_activities("Mine")
38
- check_expression(f"{len(tlas)} == 1")
52
+ # Get all activities at plus and minus 1 week
53
+ tlas = get_timeline_activities("PythonTL")
54
+ check_expression(f"{len(tlas)} == 3")
39
55
 
40
56
  # Create and delete a new activity
41
57
  start = start + timedelta(hours=2)
42
58
  stop = start + timedelta(minutes=30)
43
- act = create_timeline_activity("Mine", kind="reserve", start=start, stop=stop)
44
- tlas = get_timeline_activities("Mine")
45
- check_expression(f"{len(tlas)} == 2")
46
- delete_timeline_activity("Mine", act["start"], act["uuid"])
47
- tlas = get_timeline_activities("Mine")
48
- check_expression(f"{len(tlas)} == 1")
59
+ act = create_timeline_activity("PythonTL", kind="reserve", start=start, stop=stop)
60
+ tlas = get_timeline_activities("PythonTL")
61
+ check_expression(f"{len(tlas)} == 4")
62
+ delete_timeline_activity("PythonTL", act["start"], act["uuid"])
63
+ tlas = get_timeline_activities("PythonTL")
64
+ check_expression(f"{len(tlas)} == 3")
49
65
 
50
66
  # delete fails since the timeline has activities
51
- delete_timeline(
52
- "Mine"
53
- ) #: RuntimeError : Failed to delete timeline due to timeline contains activities, must force remove
67
+ delete_timeline("PythonTL")
54
68
  # Force delete since the timeline has activities
55
- delete_timeline("Mine", force=True)
69
+ delete_timeline("PythonTL", force=True)
56
70
  tls = list_timelines()
57
- check_expression(f"{len(tls)} == 0")
71
+ names = [tl["name"] for tl in tls]
72
+ check_expression(f"{'PythonTL' in names} == False")
@@ -17,5 +17,5 @@ wait_expression("True == False", 5)
17
17
  wait_packet("<%= target_name %>", "ADCS", 2, 5)
18
18
  wait_check("<%= target_name %> ADCS BIASX == 100", 5)
19
19
  wait_check_tolerance("<%= target_name %> ADCS BIASX", 5, 0.5, 5)
20
- wait_check_expression("True == False", 5)
20
+ wait_check_expression(f"tlm('<%= target_name %> HEALTH_STATUS TEMP1') < 101", 5, 0.25, globals())
21
21
  wait_check_packet("<%= target_name %>", "ADCS", 2, 5)
@@ -0,0 +1,84 @@
1
+ # Helper method to check for a script to change state
2
+ def wait_for_action(id, state):
3
+ i = 0
4
+ while i < 100:
5
+ script = running_script_get(id)
6
+ if script['state'] == state:
7
+ check_expression(f"'{script['state']}' == '{state}'")
8
+ break
9
+ wait(0.1)
10
+ check_expression(f"'{script['state']}' == '{state}'")
11
+
12
+ SCRIPT_NAME = "INST2/procedures/new_script.py"
13
+
14
+ # Ensure it's not already there
15
+ step_mode()
16
+ script_delete(SCRIPT_NAME)
17
+ scripts = script_list()
18
+ check_expression(f"{len(scripts)} > 100")
19
+ run_mode()
20
+
21
+ contents = "print('bad"
22
+ script_create(SCRIPT_NAME, contents)
23
+ body = script_body(SCRIPT_NAME)
24
+ result = script_syntax_check(body)
25
+ check_expression(f"{result['success']} == False")
26
+
27
+ contents = 'set_line_delay(1)\nprint("Hello from Python")\nprint(".")\nprint(".")\nwhile True:\n print(".")\n wait(0.5)\n wait(0.5)\n'
28
+ result = script_create(SCRIPT_NAME, contents)
29
+ scripts = script_list()
30
+ check_expression(f"{SCRIPT_NAME in scripts} == True")
31
+
32
+ script = script_instrumented(contents)
33
+ check_expression(f"{'RunningScript.instance' in script} == True")
34
+
35
+ id = script_run(SCRIPT_NAME)
36
+ check_expression(f"{int(id)} > 0")
37
+ wait_for_action(id, 'running')
38
+
39
+ list = running_script_list()
40
+ started = [script for script in list if script["id"] == id][0]
41
+ check_expression(f"'{started['name']}' == '{SCRIPT_NAME}'")
42
+ script = running_script_get(id)
43
+ check_expression(f"'{script['name']}' == '{SCRIPT_NAME}'")
44
+
45
+ running_script_pause(id)
46
+ wait_for_action(id, 'paused')
47
+ running_script_step(id)
48
+ wait_for_action(id, 'paused')
49
+ running_script_retry(id)
50
+ wait_for_action(id, 'paused')
51
+ running_script_go(id)
52
+ wait_for_action(id, 'running')
53
+ running_script_stop(id)
54
+ wait(1)
55
+
56
+ list = running_script_list()
57
+ script = [script for script in list if script["id"] == id]
58
+ # Script is stopped so it should NOT be in the running list
59
+ check_expression(f"{len(script)} == 0")
60
+
61
+ list = completed_script_list()
62
+ script = [script for script in list if script["id"] == id]
63
+ # Script is completed so it should be in the completed list
64
+ check_expression(f"{len(script)} == 1")
65
+
66
+ id = script_run(SCRIPT_NAME)
67
+ wait_for_action(id, 'running')
68
+ running_script_delete(id) # Stop and completely remove the script
69
+ wait(1)
70
+
71
+ list = running_script_list()
72
+ script = [script for script in list if script["id"] == id]
73
+ # Script is deleted, so it should NOT be in the running list
74
+ check_expression(f"{len(script)} == 0")
75
+ list = completed_script_list()
76
+ # Script is deleted so it should be in the completed list
77
+ script = [script for script in list if script["id"] == id]
78
+ check_expression(f"{len(script)} == 1")
79
+
80
+ script_lock(SCRIPT_NAME)
81
+ script_unlock(SCRIPT_NAME)
82
+ script_delete(SCRIPT_NAME)
83
+ scripts = script_list()
84
+ check_expression(f"{SCRIPT_NAME not in scripts} == True")