cosmos 3.3.3 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.travis.yml +2 -1
  4. data/Gemfile +4 -3
  5. data/Manifest.txt +22 -0
  6. data/autohotkey/tools/handbook_creator.ahk +9 -0
  7. data/autohotkey/tools/packet_viewer.ahk +4 -0
  8. data/bin/exchndl20-x64.dll +0 -0
  9. data/bin/exchndl20.dll +0 -0
  10. data/bin/exchndl21-x64.dll +0 -0
  11. data/bin/exchndl21.dll +0 -0
  12. data/bin/exchndl22-x64.dll +0 -0
  13. data/bin/exchndl22.dll +0 -0
  14. data/bin/mgwhelp-x64.dll +0 -0
  15. data/bin/mgwhelp.dll +0 -0
  16. data/cosmos.gemspec +1 -0
  17. data/data/crc.txt +30 -24
  18. data/demo/config/data/crc.txt +3 -3
  19. data/demo/config/tools/handbook_creator/templates/command_packets.html.erb +3 -1
  20. data/demo/config/tools/handbook_creator/templates/telemetry_packets.html.erb +3 -1
  21. data/demo/procedures/cosmos_api_test.rb +1 -1
  22. data/ext/cosmos/ext/low_fragmentation_array/low_fragmentation_array.c +4 -0
  23. data/ext/cosmos/ext/platform/platform.c +22 -2
  24. data/ext/cosmos/ext/structure/structure.c +631 -104
  25. data/ext/cosmos/ext/telemetry/telemetry.c +3 -2
  26. data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +71 -92
  27. data/lib/cosmos/gui/line_graph/overview_graph.rb +1 -1
  28. data/lib/cosmos/gui/qt.rb +38 -24
  29. data/lib/cosmos/gui/text/ruby_editor.rb +1 -1
  30. data/lib/cosmos/packets/binary_accessor.rb +1 -288
  31. data/lib/cosmos/packets/telemetry.rb +2 -1
  32. data/lib/cosmos/script/cmd_tlm_server.rb +110 -0
  33. data/lib/cosmos/script/commands.rb +166 -0
  34. data/lib/cosmos/script/extract.rb +2 -2
  35. data/lib/cosmos/script/limits.rb +108 -0
  36. data/lib/cosmos/script/script.rb +28 -1487
  37. data/lib/cosmos/script/scripting.rb +889 -0
  38. data/lib/cosmos/script/telemetry.rb +174 -0
  39. data/lib/cosmos/script/tools.rb +138 -0
  40. data/lib/cosmos/streams/stream_protocol.rb +9 -6
  41. data/lib/cosmos/system/target.rb +55 -38
  42. data/lib/cosmos/tools/cmd_tlm_server/api.rb +6 -3
  43. data/lib/cosmos/tools/cmd_tlm_server/connections.rb +0 -1
  44. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +17 -7
  45. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +15 -4
  46. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +15 -8
  47. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +41 -13
  48. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +18 -1
  49. data/lib/cosmos/tools/tlm_viewer/widgets/canvasline_widget.rb +1 -1
  50. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslinevalue_widget.rb +1 -1
  51. data/lib/cosmos/tools/tlm_viewer/widgets/limitsbar_widget.rb +1 -1
  52. data/lib/cosmos/tools/tlm_viewer/widgets/rangebar_widget.rb +1 -1
  53. data/lib/cosmos/top_level.rb +1 -1
  54. data/lib/cosmos/utilities/ruby_lex_utils.rb +1 -1
  55. data/lib/cosmos/version.rb +5 -5
  56. data/spec/gui/line_graph/line_clip_spec.rb +6 -6
  57. data/spec/gui/qt_spec.rb +102 -0
  58. data/spec/interfaces/interface_spec.rb +9 -9
  59. data/spec/interfaces/linc_interface_spec.rb +72 -15
  60. data/spec/interfaces/serial_interface_spec.rb +9 -9
  61. data/spec/interfaces/simulated_target_interface_spec.rb +7 -7
  62. data/spec/interfaces/stream_interface_spec.rb +4 -4
  63. data/spec/interfaces/tcpip_client_interface_spec.rb +8 -8
  64. data/spec/interfaces/tcpip_server_interface_spec.rb +9 -9
  65. data/spec/interfaces/udp_interface_spec.rb +20 -20
  66. data/spec/io/json_drb_spec.rb +4 -4
  67. data/spec/io/raw_logger_pair_spec.rb +20 -20
  68. data/spec/io/raw_logger_spec.rb +3 -3
  69. data/spec/io/tcpip_server_spec.rb +9 -9
  70. data/spec/io/udp_sockets_spec.rb +2 -2
  71. data/spec/io/win32_serial_driver_spec.rb +2 -2
  72. data/spec/packets/binary_accessor_spec.rb +143 -6
  73. data/spec/packets/commands_spec.rb +5 -5
  74. data/spec/packets/limits_spec.rb +15 -15
  75. data/spec/packets/packet_config_spec.rb +19 -19
  76. data/spec/packets/packet_item_limits_spec.rb +3 -3
  77. data/spec/packets/packet_item_spec.rb +4 -4
  78. data/spec/packets/packet_spec.rb +33 -33
  79. data/spec/packets/structure_item_spec.rb +19 -19
  80. data/spec/packets/telemetry_spec.rb +6 -6
  81. data/spec/script/cmd_tlm_server_spec.rb +110 -0
  82. data/spec/script/commands_disconnect_spec.rb +270 -0
  83. data/spec/script/commands_spec.rb +288 -0
  84. data/spec/script/limits_spec.rb +153 -0
  85. data/spec/script/script_spec.rb +32 -696
  86. data/spec/script/scripting_spec.rb +436 -0
  87. data/spec/script/telemetry_spec.rb +130 -0
  88. data/spec/script/tools_spec.rb +117 -0
  89. data/spec/spec_helper.rb +10 -5
  90. data/spec/streams/preidentified_stream_protocol_spec.rb +4 -4
  91. data/spec/streams/serial_stream_spec.rb +8 -8
  92. data/spec/streams/stream_protocol_spec.rb +4 -4
  93. data/spec/streams/tcpip_client_stream_spec.rb +3 -3
  94. data/spec/streams/tcpip_socket_stream_spec.rb +7 -7
  95. data/spec/streams/template_stream_protocol_spec.rb +1 -1
  96. data/spec/system/system_spec.rb +6 -6
  97. data/spec/system/target_spec.rb +2 -0
  98. data/spec/tools/cmd_tlm_server/api_spec.rb +17 -17
  99. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +5 -5
  100. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +3 -3
  101. data/spec/top_level/top_level_spec.rb +8 -8
  102. data/spec/utilities/csv_spec.rb +3 -3
  103. data/spec/utilities/message_log_spec.rb +3 -3
  104. data/spec/utilities/ruby_lex_utils_spec.rb +7 -7
  105. data/test/performance/config/tools/launcher/launcher_threads.txt +8 -1
  106. data/test/performance/tools/CmdTlmServerMemProf +1 -1
  107. data/test/performance/tools/TlmGrapherMemProf +19 -0
  108. data/test/performance/tools/TlmGrapherMemProf.bat +59 -0
  109. metadata +38 -2
@@ -238,7 +238,8 @@ module Cosmos
238
238
  # an array of symbols can be passed to control how each item is
239
239
  # converted.
240
240
  # @return [Array, Array, Array] The first array contains the item values and the
241
- # second their limits state, and the third their limits settings
241
+ # second their limits state, and the third their limits settings which includes
242
+ # the red, yellow, and green (if given) limits values.
242
243
  # def values_and_limits_states(item_array, value_types = :CONVERTED)
243
244
 
244
245
  # Iterates through all the telemetry packets and marks them stale if they
@@ -0,0 +1,110 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+
11
+ module Cosmos
12
+
13
+ module Script
14
+ private
15
+
16
+ def get_interface_names
17
+ return $cmd_tlm_server.get_interface_names
18
+ end
19
+
20
+ def connect_interface(interface_name, *params)
21
+ return $cmd_tlm_server.connect_interface(interface_name, *params)
22
+ end
23
+
24
+ def disconnect_interface(interface_name)
25
+ return $cmd_tlm_server.disconnect_interface(interface_name)
26
+ end
27
+
28
+ def interface_state(interface_name)
29
+ return $cmd_tlm_server.interface_state(interface_name)
30
+ end
31
+
32
+ def map_target_to_interface(target_name, interface_name)
33
+ return $cmd_tlm_server.map_target_to_interface(target_name, interface_name)
34
+ end
35
+
36
+ def get_router_names
37
+ return $cmd_tlm_server.get_router_names
38
+ end
39
+
40
+ def connect_router(router_name, *params)
41
+ return $cmd_tlm_server.connect_router(router_name, *params)
42
+ end
43
+
44
+ def disconnect_router(router_name)
45
+ return $cmd_tlm_server.disconnect_router(router_name)
46
+ end
47
+
48
+ def router_state(router_name)
49
+ return $cmd_tlm_server.router_state(router_name)
50
+ end
51
+
52
+ def get_cmd_log_filename(packet_log_writer_name = 'DEFAULT')
53
+ return $cmd_tlm_server.get_cmd_log_filename(packet_log_writer_name)
54
+ end
55
+
56
+ def get_tlm_log_filename(packet_log_writer_name = 'DEFAULT')
57
+ return $cmd_tlm_server.get_tlm_log_filename(packet_log_writer_name)
58
+ end
59
+
60
+ def start_logging(packet_log_writer_name = 'ALL', label = nil)
61
+ return $cmd_tlm_server.start_logging(packet_log_writer_name, label)
62
+ end
63
+
64
+ def stop_logging(packet_log_writer_name = 'ALL')
65
+ return $cmd_tlm_server.stop_logging(packet_log_writer_name)
66
+ end
67
+
68
+ def start_cmd_log(packet_log_writer_name = 'ALL', label = nil)
69
+ return $cmd_tlm_server.start_cmd_log(packet_log_writer_name, label)
70
+ end
71
+
72
+ def start_tlm_log(packet_log_writer_name = 'ALL', label = nil)
73
+ return $cmd_tlm_server.start_tlm_log(packet_log_writer_name, label)
74
+ end
75
+
76
+ def stop_cmd_log(packet_log_writer_name = 'ALL')
77
+ return $cmd_tlm_server.stop_cmd_log(packet_log_writer_name)
78
+ end
79
+
80
+ def stop_tlm_log(packet_log_writer_name = 'ALL')
81
+ return $cmd_tlm_server.stop_tlm_log(packet_log_writer_name)
82
+ end
83
+
84
+ def start_raw_logging_interface(interface_name = 'ALL')
85
+ return $cmd_tlm_server.start_raw_logging_interface(interface_name)
86
+ end
87
+
88
+ def stop_raw_logging_interface(interface_name = 'ALL')
89
+ return $cmd_tlm_server.stop_raw_logging_interface(interface_name)
90
+ end
91
+
92
+ def start_raw_logging_router(router_name = 'ALL')
93
+ return $cmd_tlm_server.start_raw_logging_router(router_name)
94
+ end
95
+
96
+ def stop_raw_logging_router(router_name = 'ALL')
97
+ return $cmd_tlm_server.stop_raw_logging_router(router_name)
98
+ end
99
+
100
+ def get_server_message_log_filename
101
+ return $cmd_tlm_server.get_server_message_log_filename
102
+ end
103
+
104
+ def start_new_server_message_log
105
+ return $cmd_tlm_server.start_new_server_message_log
106
+ end
107
+
108
+ end # module Script
109
+
110
+ end # module Cosmos
@@ -0,0 +1,166 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+
11
+ module Cosmos
12
+
13
+ module Script
14
+ private
15
+
16
+ # Log any warnings about disabling checks and log the command itself
17
+ # NOTE: This is a helper method and should not be called directly
18
+ def _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
19
+ if no_range
20
+ Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
21
+ end
22
+ if no_hazardous
23
+ Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring hazardous warnings"
24
+ end
25
+ Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, raw)
26
+ end
27
+
28
+ # Send the command and log the results
29
+ # NOTE: This is a helper method and should not be called directly
30
+ def _cmd(cmd, cmd_no_hazardous, *args)
31
+ raw = cmd.include?('raw')
32
+ no_range = cmd.include?('no_range') || cmd.include?('no_checks')
33
+ no_hazardous = cmd.include?('no_hazardous') || cmd.include?('no_checks')
34
+
35
+ begin
36
+ if $cmd_tlm_disconnect
37
+ # In disconnect mode we call API methods directly on the server
38
+ target_name, cmd_name, cmd_params = $cmd_tlm_server.send(cmd, *args)
39
+ else
40
+ # In connected mode we forward method calls through the JsonDrb object
41
+ # so we must call method_missing
42
+ target_name, cmd_name, cmd_params = $cmd_tlm_server.method_missing(cmd, *args)
43
+ end
44
+ _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
45
+ rescue HazardousError => e
46
+ ok_to_proceed = prompt_for_hazardous(e.target_name,
47
+ e.cmd_name,
48
+ e.hazardous_description)
49
+ if ok_to_proceed
50
+ if $cmd_tlm_disconnect
51
+ target_name, cmd_name, cmd_params = $cmd_tlm_server.send(cmd_no_hazardous, *args)
52
+ else
53
+ target_name, cmd_name, cmd_params = $cmd_tlm_server.method_missing(cmd_no_hazardous, *args)
54
+ end
55
+ _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
56
+ else
57
+ retry unless prompt_for_script_abort()
58
+ end
59
+ end
60
+ end
61
+
62
+ # Send a command to the specified target
63
+ # Usage:
64
+ # cmd(target_name, cmd_name, cmd_params = {})
65
+ # or
66
+ # cmd('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
67
+ def cmd(*args)
68
+ _cmd('cmd', 'cmd_no_hazardous_check', *args)
69
+ end
70
+
71
+ # Send a command to the specified target without range checking parameters
72
+ # Usage:
73
+ # cmd_no_range_check(target_name, cmd_name, cmd_params = {})
74
+ # or
75
+ # cmd_no_range_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
76
+ def cmd_no_range_check(*args)
77
+ _cmd('cmd_no_range_check', 'cmd_no_checks', *args)
78
+ end
79
+
80
+ # Send a command to the specified target without hazardous checks
81
+ # Usage:
82
+ # cmd_no_hazardous_check(target_name, cmd_name, cmd_params = {})
83
+ # or
84
+ # cmd_no_hazardous_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
85
+ def cmd_no_hazardous_check(*args)
86
+ _cmd('cmd_no_hazardous_check', nil, *args)
87
+ end
88
+
89
+ # Send a command to the specified target without range checking or hazardous checks
90
+ # Usage:
91
+ # cmd_no_checks(target_name, cmd_name, cmd_params = {})
92
+ # or
93
+ # cmd_no_checks('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
94
+ def cmd_no_checks(*args)
95
+ _cmd('cmd_no_checks', nil, *args)
96
+ end
97
+
98
+ # Send a command to the specified target without running conversions
99
+ # Usage:
100
+ # cmd_raw(target_name, cmd_name, cmd_params = {})
101
+ # or
102
+ # cmd_raw('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
103
+ def cmd_raw(*args)
104
+ _cmd('cmd_raw', 'cmd_raw_no_hazardous_check', *args)
105
+ end
106
+
107
+ # Send a command to the specified target without range checking parameters or running conversions
108
+ # Usage:
109
+ # cmd_raw_no_range_check(target_name, cmd_name, cmd_params = {})
110
+ # or
111
+ # cmd_raw_no_range_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
112
+ def cmd_raw_no_range_check(*args)
113
+ _cmd('cmd_raw_no_range_check', 'cmd_raw_no_checks', *args)
114
+ end
115
+
116
+ # Send a command to the specified target without hazardous checks or running conversions
117
+ # Usage:
118
+ # cmd_raw_no_hazardous_check(target_name, cmd_name, cmd_params = {})
119
+ # or
120
+ # cmd_raw_no_hazardous_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
121
+ def cmd_raw_no_hazardous_check(*args)
122
+ _cmd('cmd_raw_no_hazardous_check', nil, *args)
123
+ end
124
+
125
+ # Send a command to the specified target without range checking or hazardous checks or running conversions
126
+ # Usage:
127
+ # cmd_raw_no_checks(target_name, cmd_name, cmd_params = {})
128
+ # or
129
+ # cmd_raw_no_checks('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
130
+ def cmd_raw_no_checks(*args)
131
+ _cmd('cmd_raw_no_checks', nil, *args)
132
+ end
133
+
134
+ # Sends raw data through an interface
135
+ def send_raw(interface_name, data)
136
+ return $cmd_tlm_server.send_raw(interface_name, data)
137
+ end
138
+
139
+ # Sends raw data through an interface from a file
140
+ def send_raw_file(interface_name, filename)
141
+ data = nil
142
+ File.open(filename, 'rb') {|file| data = file.read}
143
+ return $cmd_tlm_server.send_raw(interface_name, data)
144
+ end
145
+
146
+ # Returns all the target commands as an array of arrays listing the command
147
+ # name and description.
148
+ def get_cmd_list(target_name)
149
+ return $cmd_tlm_server.get_cmd_list(target_name)
150
+ end
151
+
152
+ # Returns all the parameters for given command as an array of arrays
153
+ # containing the parameter name, default value, states, description, units
154
+ # full name, units abbreviation, and whether it is required.
155
+ def get_cmd_param_list(target_name, cmd_name)
156
+ return $cmd_tlm_server.get_cmd_param_list(target_name, cmd_name)
157
+ end
158
+
159
+ # Returns whether a command is hazardous (true or false)
160
+ def get_cmd_hazardous(target_name, cmd_name, cmd_params = {})
161
+ return $cmd_tlm_server.get_cmd_hazardous(target_name, cmd_name, cmd_params)
162
+ end
163
+
164
+ end
165
+ end
166
+
@@ -76,7 +76,7 @@ module Cosmos
76
76
  return [target_name, cmd_name, cmd_params]
77
77
  end
78
78
 
79
- def extract_fields_from_tlm_text (text)
79
+ def extract_fields_from_tlm_text(text)
80
80
  split_string = text.split
81
81
  raise "ERROR: Telemetry Item must be specified as 'TargetName PacketName ItemName' : #{text}" if split_string.length != 3
82
82
  target_name = split_string[0]
@@ -96,7 +96,7 @@ module Cosmos
96
96
  return [target_name, packet_name, item_name, value]
97
97
  end
98
98
 
99
- def extract_fields_from_check_text (text)
99
+ def extract_fields_from_check_text(text)
100
100
  split_string = text.split
101
101
  raise "ERROR: Check improperly specified: #{text}" if split_string.length < 3
102
102
  target_name = split_string[0]
@@ -0,0 +1,108 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+
11
+ module Cosmos
12
+
13
+ module Script
14
+ private
15
+
16
+ def get_out_of_limits
17
+ result = $cmd_tlm_server.get_out_of_limits
18
+ result.each do |entry|
19
+ entry[3] = entry[3].to_s.intern if entry[3]
20
+ end
21
+ result
22
+ end
23
+
24
+ def get_overall_limits_state(ignored_items = nil)
25
+ return $cmd_tlm_server.get_overall_limits_state(ignored_items).to_s.intern
26
+ end
27
+
28
+ def limits_enabled?(*args)
29
+ return $cmd_tlm_server.limits_enabled?(*args)
30
+ end
31
+
32
+ def enable_limits(*args)
33
+ return $cmd_tlm_server.enable_limits(*args)
34
+ end
35
+
36
+ def disable_limits(*args)
37
+ return $cmd_tlm_server.disable_limits(*args)
38
+ end
39
+
40
+ def get_limits(target_name, packet_name, item_name, limits_set = nil)
41
+ results = $cmd_tlm_server.get_limits(target_name, packet_name, item_name, limits_set)
42
+ results[0] = results[0].to_s.intern if results[0]
43
+ return results
44
+ end
45
+
46
+ def set_limits(target_name, packet_name, item_name, red_low, yellow_low, yellow_high, red_high, green_low = nil, green_high = nil, limits_set = :CUSTOM, persistence = nil, enabled = true)
47
+ results = $cmd_tlm_server.set_limits(target_name, packet_name, item_name, red_low, yellow_low, yellow_high, red_high, green_low, green_high, limits_set, persistence, enabled)
48
+ results[0] = results[0].to_s.intern if results[0]
49
+ return results
50
+ end
51
+
52
+ def get_limits_groups
53
+ return $cmd_tlm_server.get_limits_groups
54
+ end
55
+
56
+ def enable_limits_group(group_name)
57
+ return $cmd_tlm_server.enable_limits_group(group_name)
58
+ end
59
+
60
+ def disable_limits_group(group_name)
61
+ return $cmd_tlm_server.disable_limits_group(group_name)
62
+ end
63
+
64
+ def get_limits_sets
65
+ result = $cmd_tlm_server.get_limits_sets
66
+ result.each_with_index do |limits_set, index|
67
+ result[index] = limits_set.to_s.intern
68
+ end
69
+ return result
70
+ end
71
+
72
+ def set_limits_set(limits_set)
73
+ return $cmd_tlm_server.set_limits_set(limits_set)
74
+ end
75
+
76
+ def get_limits_set
77
+ result = $cmd_tlm_server.get_limits_set
78
+ # Limits sets are always represented as symbols
79
+ result.to_s.intern
80
+ end
81
+
82
+ def subscribe_limits_events(queue_size = CmdTlmServer::DEFAULT_LIMITS_EVENT_QUEUE_SIZE)
83
+ return $cmd_tlm_server.subscribe_limits_events(queue_size)
84
+ end
85
+
86
+ def unsubscribe_limits_events(id)
87
+ return $cmd_tlm_server.unsubscribe_limits_events(id)
88
+ end
89
+
90
+ def get_limits_event(id, non_block = false)
91
+ result = $cmd_tlm_server.get_limits_event(id, non_block)
92
+ if result
93
+ result[0] = result[0].to_s.intern
94
+ if result[0] == :LIMITS_CHANGE
95
+ result[1][3] = result[1][3].to_s.intern if result[1][3]
96
+ result[1][4] = result[1][4].to_s.intern if result[1][4]
97
+ elsif result[0] == :LIMITS_SETTINGS
98
+ result[1][3] = result[1][3].to_s.intern if result[1][3]
99
+ else
100
+ result[1] = result[1].to_s.intern
101
+ end
102
+ end
103
+ result
104
+ end
105
+
106
+ end
107
+ end
108
+
@@ -11,7 +11,12 @@
11
11
  require 'cosmos'
12
12
  require 'cosmos/io/json_drb_object'
13
13
  require 'cosmos/tools/cmd_tlm_server/cmd_tlm_server'
14
- require 'cosmos/script/extract'
14
+ require 'cosmos/script/cmd_tlm_server'
15
+ require 'cosmos/script/commands'
16
+ require 'cosmos/script/telemetry'
17
+ require 'cosmos/script/limits'
18
+ require 'cosmos/script/scripting'
19
+ require 'cosmos/script/tools'
15
20
 
16
21
  $cmd_tlm_server = nil
17
22
  $cmd_tlm_disconnect = false
@@ -22,1479 +27,36 @@ module Cosmos
22
27
  class SkipTestCase < StandardError; end
23
28
 
24
29
  module Script
25
- DEFAULT_TLM_POLLING_RATE = 0.25
26
-
30
+ # All methods are private so they can only be called by themselves and not
31
+ # on another object. This is important for the JsonDrbObject class which we
32
+ # use to communicate with the server. JsonDrbObject implements method_missing
33
+ # to forward calls to the remote service. If these methods were not private,
34
+ # they would be included on the $cmd_tlm_server global and would be
35
+ # called directly instead of being forwarded over the JsonDrb connection to
36
+ # the real server.
27
37
  private
28
38
 
29
- include Extract
30
-
31
- #######################################
32
- # Methods accessing cmd_tlm_server
33
- #######################################
34
-
35
- #
36
- # Methods involving commands
37
- #
38
-
39
- # Send a command to the specified target
40
- # Supports two signatures:
41
- # cmd(target_name, cmd_name, cmd_params = {})
42
- # or
43
- # cmd('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
44
- def cmd(*args)
45
- begin
46
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd(*args)
47
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params)
48
- rescue HazardousError => e
49
- ok_to_proceed = prompt_for_hazardous(e.target_name,
50
- e.cmd_name,
51
- e.hazardous_description)
52
- if ok_to_proceed
53
- target_name, cmd_name, cmd_params =
54
- $cmd_tlm_server.cmd_no_hazardous_check(*args)
55
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params)
56
- else
57
- retry unless prompt_for_script_abort()
58
- end
59
- end
60
- end
61
-
62
- # Send a command to the specified target without range checking parameters
63
- # Supports two signatures:
64
- # cmd_no_range_check(target_name, cmd_name, cmd_params = {})
65
- # or
66
- # cmd_no_range_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
67
- def cmd_no_range_check(*args)
68
- begin
69
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_no_range_check(*args)
70
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
71
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params)
72
- rescue HazardousError => e
73
- ok_to_proceed = prompt_for_hazardous(e.target_name,
74
- e.cmd_name,
75
- e.hazardous_description)
76
- if ok_to_proceed
77
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_no_checks(*args)
78
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
79
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params)
80
- else
81
- retry unless prompt_for_script_abort()
82
- end
83
- end
84
- end
85
-
86
- # Send a command to the specified target without hazardous checks
87
- # Supports two signatures:
88
- # cmd_no_hazardous_check(target_name, cmd_name, cmd_params = {})
89
- # or
90
- # cmd_no_hazardous_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
91
- def cmd_no_hazardous_check(*args)
92
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_no_hazardous_check(*args)
93
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring hazardous warnings"
94
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params)
95
- end
96
-
97
- # Send a command to the specified target without range checking or hazardous checks
98
- # Supports two signatures:
99
- # cmd_no_checks(target_name, cmd_name, cmd_params = {})
100
- # or
101
- # cmd_no_checks('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
102
- def cmd_no_checks(*args)
103
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_no_checks(*args)
104
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
105
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring hazardous warnings"
106
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params)
107
- end
108
-
109
- # Send a command to the specified target without running conversions
110
- # Supports two signatures:
111
- # cmd_raw(target_name, cmd_name, cmd_params = {})
112
- # or
113
- # cmd_raw('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
114
- def cmd_raw(*args)
115
- begin
116
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_raw(*args)
117
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, true)
118
- rescue HazardousError => e
119
- ok_to_proceed = prompt_for_hazardous(e.target_name,
120
- e.cmd_name,
121
- e.hazardous_description)
122
- if ok_to_proceed
123
- target_name, cmd_name, cmd_params =
124
- $cmd_tlm_server.cmd_raw_no_hazardous_check(*args)
125
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, true)
126
- else
127
- retry unless prompt_for_script_abort()
128
- end
129
- end
130
- end
131
-
132
- # Send a command to the specified target without range checking parameters or running conversions
133
- # Supports two signatures:
134
- # cmd_raw_no_range_check(target_name, cmd_name, cmd_params = {})
135
- # or
136
- # cmd_raw_no_range_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
137
- def cmd_raw_no_range_check(*args)
138
- begin
139
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_raw_no_range_check(*args)
140
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
141
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, true)
142
- rescue HazardousError => e
143
- ok_to_proceed = prompt_for_hazardous(e.target_name,
144
- e.cmd_name,
145
- e.hazardous_description)
146
- if ok_to_proceed
147
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_raw_no_checks(*args)
148
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
149
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, true)
150
- else
151
- retry unless prompt_for_script_abort()
152
- end
153
- end
154
- end
155
-
156
- # Send a command to the specified target without hazardous checks or running conversions
157
- # Supports two signatures:
158
- # cmd_raw_no_hazardous_check(target_name, cmd_name, cmd_params = {})
159
- # or
160
- # cmd_raw_no_hazardous_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
161
- def cmd_raw_no_hazardous_check(*args)
162
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_raw_no_hazardous_check(*args)
163
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring hazardous warnings"
164
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, true)
165
- end
166
-
167
- # Send a command to the specified target without range checking or hazardous checks or running conversions
168
- # Supports two signatures:
169
- # cmd_raw_no_checks(target_name, cmd_name, cmd_params = {})
170
- # or
171
- # cmd_raw_no_checks('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
172
- def cmd_raw_no_checks(*args)
173
- target_name, cmd_name, cmd_params = $cmd_tlm_server.cmd_raw_no_checks(*args)
174
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
175
- Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring hazardous warnings"
176
- Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, true)
177
- end
178
-
179
- # Sends raw data through an interface
180
- def send_raw(interface_name, data)
181
- return $cmd_tlm_server.send_raw(interface_name, data)
182
- end
183
-
184
- # Sends raw data through an interface from a file
185
- def send_raw_file(interface_name, filename)
186
- data = nil
187
- File.open(filename, 'rb') {|file| data = file.read}
188
- return $cmd_tlm_server.send_raw(interface_name, data)
189
- end
190
-
191
- def get_cmd_list(target_name)
192
- return $cmd_tlm_server.get_cmd_list(target_name)
193
- end
194
-
195
- def get_cmd_param_list(target_name, cmd_name)
196
- return $cmd_tlm_server.get_cmd_param_list(target_name, cmd_name)
197
- end
198
-
199
- def get_cmd_hazardous(target_name, cmd_name, cmd_params = {})
200
- return $cmd_tlm_server.get_cmd_hazardous(target_name, cmd_name, cmd_params)
201
- end
202
-
203
- #
204
- # Methods involving telemetry
205
- #
206
-
207
- # Poll for the converted value of a telemetry item
208
- # Supports two signatures:
209
- # tlm(target_name, packet_name, item_name)
210
- # or
211
- # tlm('target_name packet_name item_name')
212
- def tlm(*args)
213
- return $cmd_tlm_server.tlm(*args)
214
- end
215
-
216
- # Poll for the raw value of a telemetry item
217
- # Supports two signatures:
218
- # tlm_raw(target_name, packet_name, item_name)
219
- # or
220
- # tlm_raw('target_name packet_name item_name')
221
- def tlm_raw(*args)
222
- return $cmd_tlm_server.tlm_raw(*args)
223
- end
224
-
225
- # Poll for the formatted value of a telemetry item
226
- # Supports two signatures:
227
- # tlm_formatted(target_name, packet_name, item_name)
228
- # or
229
- # tlm_formatted('target_name packet_name item_name')
230
- def tlm_formatted(*args)
231
- return $cmd_tlm_server.tlm_formatted(*args)
232
- end
233
-
234
- # Poll for the formatted with units value of a telemetry item
235
- # Supports two signatures:
236
- # tlm_with_units(target_name, packet_name, item_name)
237
- # or
238
- # tlm_with_units('target_name packet_name item_name')
239
- def tlm_with_units(*args)
240
- return $cmd_tlm_server.tlm_with_units(*args)
241
- end
242
-
243
- def tlm_variable(*args)
244
- return $cmd_tlm_server.tlm_variable(*args)
245
- end
246
-
247
- # Set a telemetry point
248
- def set_tlm(*args)
249
- return $cmd_tlm_server.set_tlm(*args)
250
- end
251
-
252
- # Set the raw value of a telemetry point
253
- def set_tlm_raw(*args)
254
- return $cmd_tlm_server.set_tlm_raw(*args)
255
- end
256
-
257
- def get_tlm_packet(target_name, packet_name, value_types = :CONVERTED)
258
- result = $cmd_tlm_server.get_tlm_packet(target_name, packet_name, value_types)
259
- result.each do |entry|
260
- entry[2] = entry[2].to_s.intern if entry[2]
261
- end
262
- result
263
- end
264
-
265
- def get_tlm_values(items, value_types = :CONVERTED)
266
- result = $cmd_tlm_server.get_tlm_values(items, value_types)
267
- result[1].length.times do |index|
268
- result[1][index] = result[1][index].to_s.intern if result[1][index]
269
- end
270
- result[3] = result[3].to_s.intern
271
- result
272
- end
273
-
274
- def get_tlm_list(target_name)
275
- return $cmd_tlm_server.get_tlm_list(target_name)
276
- end
277
-
278
- def get_tlm_item_list(target_name, packet_name)
279
- return $cmd_tlm_server.get_tlm_item_list(target_name, packet_name)
280
- end
281
-
282
- def get_tlm_details(items)
283
- $cmd_tlm_server.get_tlm_details(items)
284
- end
285
-
286
- def get_out_of_limits
287
- result = $cmd_tlm_server.get_out_of_limits
288
- result.each do |entry|
289
- entry[3] = entry[3].to_s.intern if entry[3]
290
- end
291
- result
292
- end
293
-
294
- def get_overall_limits_state (ignored_items = nil)
295
- return $cmd_tlm_server.get_overall_limits_state(ignored_items).to_s.intern
296
- end
297
-
298
- def limits_enabled?(*args)
299
- return $cmd_tlm_server.limits_enabled?(*args)
300
- end
301
-
302
- def enable_limits(*args)
303
- return $cmd_tlm_server.enable_limits(*args)
304
- end
305
-
306
- def disable_limits(*args)
307
- return $cmd_tlm_server.disable_limits(*args)
308
- end
309
-
310
- def get_limits(target_name, packet_name, item_name, limits_set = nil)
311
- results = $cmd_tlm_server.get_limits(target_name, packet_name, item_name, limits_set)
312
- results[0] = results[0].to_s.intern if results[0]
313
- return results
314
- end
315
-
316
- def set_limits(target_name, packet_name, item_name, red_low, yellow_low, yellow_high, red_high, green_low = nil, green_high = nil, limits_set = :CUSTOM, persistence = nil, enabled = true)
317
- results = $cmd_tlm_server.set_limits(target_name, packet_name, item_name, red_low, yellow_low, yellow_high, red_high, green_low, green_high, limits_set, persistence, enabled)
318
- results[0] = results[0].to_s.intern if results[0]
319
- return results
320
- end
321
-
322
- def get_limits_groups
323
- return $cmd_tlm_server.get_limits_groups
324
- end
325
-
326
- def enable_limits_group(group_name)
327
- return $cmd_tlm_server.enable_limits_group(group_name)
328
- end
329
-
330
- def disable_limits_group(group_name)
331
- return $cmd_tlm_server.disable_limits_group(group_name)
332
- end
333
-
334
- def get_limits_sets
335
- result = $cmd_tlm_server.get_limits_sets
336
- result.each_with_index do |limits_set, index|
337
- result[index] = limits_set.to_s.intern
338
- end
339
- return result
340
- end
341
-
342
- def set_limits_set(limits_set)
343
- return $cmd_tlm_server.set_limits_set(limits_set)
344
- end
345
-
346
- def get_limits_set
347
- result = $cmd_tlm_server.get_limits_set
348
- # Limits sets are always represented as symbols
349
- result.to_s.intern
350
- end
351
-
352
- #
353
- # General Purpose Methods
354
- #
355
-
356
- def get_target_list
357
- return $cmd_tlm_server.get_target_list
358
- end
359
-
360
- def subscribe_limits_events(queue_size = CmdTlmServer::DEFAULT_LIMITS_EVENT_QUEUE_SIZE)
361
- return $cmd_tlm_server.subscribe_limits_events(queue_size)
362
- end
363
-
364
- def unsubscribe_limits_events(id)
365
- return $cmd_tlm_server.unsubscribe_limits_events(id)
366
- end
367
-
368
- def get_limits_event(id, non_block = false)
369
- result = $cmd_tlm_server.get_limits_event(id, non_block)
370
- if result
371
- result[0] = result[0].to_s.intern
372
- if result[0] == :LIMITS_CHANGE
373
- result[1][3] = result[1][3].to_s.intern if result[1][3]
374
- result[1][4] = result[1][4].to_s.intern if result[1][4]
375
- elsif result[0] == :LIMITS_SETTINGS
376
- result[1][3] = result[1][3].to_s.intern if result[1][3]
377
- else
378
- result[1] = result[1].to_s.intern
379
- end
380
- end
381
- result
382
- end
383
-
384
- def subscribe_packet_data(packets, queue_size = CmdTlmServer::DEFAULT_PACKET_DATA_QUEUE_SIZE)
385
- result = $cmd_tlm_server.subscribe_packet_data(packets, queue_size)
386
- result
387
- end
388
-
389
- def unsubscribe_packet_data(id)
390
- result = $cmd_tlm_server.unsubscribe_packet_data(id)
391
- result
392
- end
393
-
394
- def get_packet_data(id, non_block = false)
395
- results = $cmd_tlm_server.get_packet_data(id, non_block)
396
- if Array === results and results[3] and results[4]
397
- results[3] = Time.at(results[3], results[4])
398
- results.delete_at(4)
399
- end
400
- results
401
- end
402
-
403
- def get_packet(id, non_block = false)
404
- packet = nil
405
- buffer, target_name, packet_name, received_time, received_count = get_packet_data(id, non_block)
406
- if buffer
407
- packet = System.telemetry.packet(target_name, packet_name).clone
408
- packet.buffer = buffer
409
- packet.received_time = received_time
410
- packet.received_count = received_count
411
- end
412
- packet
413
- end
414
-
415
- #
416
- # Methods for scripting
417
- #
418
-
419
- def play_wav_file(wav_filename)
420
- if defined? Qt
421
- Qt.execute_in_main_thread(true) do
422
- if Qt::CoreApplication.instance and Qt::Sound.isAvailable
423
- Cosmos.set_working_dir do
424
- Qt::Sound.play(wav_filename.to_s)
425
- end
426
- end
427
- end
428
- end
429
- end
430
-
431
- def status_bar(message)
432
- script_runner = nil
433
- ObjectSpace.each_object {|object| if ScriptRunner === object then script_runner = object; break; end}
434
- script_runner.script_set_status(message) if script_runner
435
- end
436
-
437
- def ask_string(question, blank_or_default = false, password = false)
438
- answer = ''
439
- default = ''
440
- if blank_or_default != true && blank_or_default != false
441
- question << " (default = #{blank_or_default})"
442
- allow_blank = true
443
- else
444
- allow_blank = blank_or_default
445
- end
446
- while answer.empty?
447
- print question + " "
448
- answer = gets
449
- answer.chomp!
450
- break if allow_blank
451
- end
452
- answer = default if answer.empty? and !default.empty?
453
- return answer
454
- end
455
-
456
- def ask(question, blank_or_default = false, password = false)
457
- string = ask_string(question, blank_or_default, password)
458
- value = string.convert_to_value
459
- return value
460
- end
461
-
462
- def prompt(string)
463
- prompt_to_continue(string)
464
- end
465
-
466
- def message_box(string, *buttons)
467
- prompt_message_box(string, buttons)
468
- end
469
-
470
- def _check(*args)
471
- target_name, packet_name, item_name, comparison_to_eval =
472
- check_process_args(args, 'check')
473
- value = yield(target_name, packet_name, item_name)
474
- if comparison_to_eval
475
- check_eval(target_name, packet_name, item_name, comparison_to_eval, value)
476
- else
477
- Logger.info "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} == #{value}"
478
- end
479
- end
480
-
481
- # Check the converted value of a telmetry item against a condition
482
- # Always print the value of the telemetry item to STDOUT
483
- # If the condition check fails, raise an error
484
- # Supports two signatures:
485
- # check(target_name, packet_name, item_name, comparison_to_eval)
486
- # or
487
- # check('target_name packet_name item_name > 1')
488
- def check(*args)
489
- _check(*args) {|tgt,pkt,item| tlm(tgt,pkt,item) }
490
- end
491
-
492
- # Check the formatted value of a telmetry item against a condition
493
- # Always print the value of the telemetry item to STDOUT
494
- # If the condition check fails, raise an error
495
- # Supports two signatures:
496
- # check(target_name, packet_name, item_name, comparison_to_eval)
497
- # or
498
- # check('target_name packet_name item_name > 1')
499
- def check_formatted(*args)
500
- _check(*args) {|tgt,pkt,item| tlm_formatted(tgt,pkt,item) }
501
- end
502
-
503
- # Check the formatted with units value of a telmetry item against a condition
504
- # Always print the value of the telemetry item to STDOUT
505
- # If the condition check fails, raise an error
506
- # Supports two signatures:
507
- # check(target_name, packet_name, item_name, comparison_to_eval)
508
- # or
509
- # check('target_name packet_name item_name > 1')
510
- def check_with_units(*args)
511
- _check(*args) {|tgt,pkt,item| tlm_with_units(tgt,pkt,item) }
512
- end
513
-
514
- # Check the raw value of a telmetry item against a condition
515
- # Always print the value of the telemetry item to STDOUT
516
- # If the condition check fails, raise an error
517
- # Supports two signatures:
518
- # check(target_name, packet_name, item_name, comparison_to_eval)
519
- # or
520
- # check('target_name packet_name item_name > 1')
521
- def check_raw(*args)
522
- _check(*args) {|tgt,pkt,item| tlm_raw(tgt,pkt,item) }
523
- end
524
-
525
- def _check_tolerance(*args)
526
- target_name, packet_name, item_name, expected_value, tolerance =
527
- check_tolerance_process_args(args, 'check_tolerance')
528
- value = yield(target_name, packet_name, item_name)
529
- range = (expected_value - tolerance)..(expected_value + tolerance)
530
- if range.include?(value)
531
- Logger.info "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} was within range #{range.first} to #{range.last} with value == #{value}"
532
- else
533
- message = "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} failed to be within range #{range.first} to #{range.last} with value == #{value}"
534
- if $cmd_tlm_disconnect
535
- Logger.error message
536
- else
537
- raise CheckError, message
538
- end
539
- end
540
- end
541
-
542
- # Check the converted value of a telmetry item against an expected value with a tolerance
543
- # Always print the value of the telemetry item to STDOUT
544
- # If the condition check fails, raise an error
545
- # Supports two signatures:
546
- # check_tolerance(target_name, packet_name, item_name, expected_value, tolerance)
547
- # or
548
- # check_tolerance('target_name packet_name item_name', expected_value, tolerance)
549
- def check_tolerance(*args)
550
- _check_tolerance(*args) {|tgt,pkt,item| tlm(tgt,pkt,item) }
551
- end
552
-
553
- # Check the raw value of a telmetry item against an expected value with a tolerance
554
- # Always print the value of the telemetry item to STDOUT
555
- # If the condition check fails, raise an error
556
- # Supports two signatures:
557
- # check_tolerance_raw(target_name, packet_name, item_name, expected_value, tolerance)
558
- # or
559
- # check_tolerance_raw('target_name packet_name item_name', expected_value, tolerance)
560
- def check_tolerance_raw(*args)
561
- _check_tolerance(*args) {|tgt,pkt,item| tlm_raw(tgt,pkt,item) }
562
- end
563
-
564
- # Check to see if an expression is true without waiting. If the expression
565
- # is not true, the script will pause.
566
- def check_expression(exp_to_eval, context = nil)
567
- success = cosmos_script_wait_implementation_expression(exp_to_eval, 0, DEFAULT_TLM_POLLING_RATE, context)
568
- if success
569
- Logger.info "CHECK: #{exp_to_eval} is TRUE"
570
- else
571
- message = "CHECK: #{exp_to_eval} is FALSE"
572
- if $cmd_tlm_disconnect
573
- Logger.error message
574
- else
575
- raise CheckError, message
576
- end
577
- end
578
- end
579
-
580
- # Wait on an expression to be true. On a timeout, the script will continue.
581
- # Supports multiple signatures:
582
- # wait(time)
583
- # wait('target_name packet_name item_name > 1', timeout, polling_rate)
584
- # wait('target_name', 'packet_name', 'item_name', comparison_to_eval, timeout, polling_rate)
585
- def wait(*args)
586
- wait_process_args(args, 'wait', :CONVERTED)
587
- end
588
-
589
- # Wait on an expression to be true. On a timeout, the script will continue.
590
- # Supports multiple signatures:
591
- # wait(time)
592
- # wait_raw('target_name packet_name item_name > 1', timeout, polling_rate)
593
- # wait_raw('target_name', 'packet_name', 'item_name', comparison_to_eval, timeout, polling_rate)
594
- def wait_raw(*args)
595
- wait_process_args(args, 'wait_raw', :RAW)
596
- end
597
-
598
- def _wait_tolerance(raw, *args)
599
- type = (raw ? :RAW : :CONVERTED)
600
- type_string = 'wait_tolerance'
601
- type_string << '_raw' if raw
602
- target_name, packet_name, item_name, expected_value, tolerance, timeout, polling_rate = wait_tolerance_process_args(args, type_string)
603
- start_time = Time.now
604
- success, value = cosmos_script_wait_implementation_tolerance(target_name, packet_name, item_name, type, expected_value, tolerance, timeout, polling_rate)
605
- time = Time.now - start_time
606
- range = (expected_value - tolerance)..(expected_value + tolerance)
607
- if success
608
- Logger.info "WAIT: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} was within range #{range.first} to #{range.last} with value == #{value} after waiting #{time} seconds"
609
- else
610
- Logger.warn "WAIT: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} failed to be within range #{range.first} to #{range.last} with value == #{value} after waiting #{time} seconds"
611
- end
612
- time
613
- end
614
-
615
- # Wait on an expression to be true. On a timeout, the script will continue.
616
- # Supports multiple signatures:
617
- # wait_tolerance('target_name packet_name item_name', expected_value, tolerance, timeout, polling_rate)
618
- # wait_tolerance('target_name', 'packet_name', 'item_name', expected_value, tolerance, timeout, polling_rate)
619
- def wait_tolerance(*args)
620
- _wait_tolerance(false, *args)
621
- end
622
-
623
- # Wait on an expression to be true. On a timeout, the script will continue.
624
- # Supports multiple signatures:
625
- # wait_tolerance_raw('target_name packet_name item_name', expected_value, tolerance, timeout, polling_rate)
626
- # wait_tolerance_raw('target_name', 'packet_name', 'item_name', expected_value, tolerance, timeout, polling_rate)
627
- def wait_tolerance_raw(*args)
628
- _wait_tolerance(true, *args)
629
- end
630
-
631
- # Wait on a custom expression to be true
632
- def wait_expression(exp_to_eval, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, context = nil)
633
- start_time = Time.now
634
- success = cosmos_script_wait_implementation_expression(exp_to_eval, timeout, polling_rate, context)
635
- time = Time.now - start_time
636
- if success
637
- Logger.info "WAIT: #{exp_to_eval} is TRUE after waiting #{time} seconds"
638
- else
639
- Logger.warn "WAIT: #{exp_to_eval} is FALSE after waiting #{time} seconds"
640
- end
641
- time
642
- end
643
-
644
- def _wait_check(raw, *args)
645
- type = (raw ? :RAW : :CONVERTED)
646
- target_name, packet_name, item_name, comparison_to_eval, timeout, polling_rate = wait_check_process_args(args, 'wait_check')
647
- start_time = Time.now
648
- success, value = cosmos_script_wait_implementation(target_name, packet_name, item_name, type, comparison_to_eval, timeout, polling_rate)
649
- time = Time.now - start_time
650
- if success
651
- Logger.info "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} #{comparison_to_eval} success with value == #{value} after waiting #{time} seconds"
652
- else
653
- message = "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} #{comparison_to_eval} failed with value == #{value} after waiting #{time} seconds"
654
- if $cmd_tlm_disconnect
655
- Logger.error message
656
- else
657
- raise CheckError, message
658
- end
659
- end
660
- time
661
- end
662
-
663
- # Wait for the converted value of a telmetry item against a condition or for a timeout
664
- # and then check against the condition
665
- # Supports two signatures:
666
- # wait_check(target_name, packet_name, item_name, comparison_to_eval, timeout, polling_rate)
667
- # or
668
- # wait_check('target_name packet_name item_name > 1', timeout, polling_rate)
669
- def wait_check(*args)
670
- _wait_check(false, *args)
671
- end
672
-
673
- # Wait for the raw value of a telmetry item against a condition or for a timeout
674
- # and then check against the condition
675
- # Supports two signatures:
676
- # wait_check_raw(target_name, packet_name, item_name, comparison_to_eval, timeout, polling_rate)
677
- # or
678
- # wait_check_raw('target_name packet_name item_name > 1', timeout, polling_rate)
679
- def wait_check_raw(*args)
680
- _wait_check(true, *args)
681
- end
682
-
683
- def _wait_check_tolerance(raw, *args)
684
- type_string = 'wait_check_tolerance'
685
- type_string << '_raw' if raw
686
- type = (raw ? :RAW : :CONVERTED)
687
- target_name, packet_name, item_name, expected_value, tolerance, timeout, polling_rate = wait_tolerance_process_args(args, type_string)
688
- start_time = Time.now
689
- success, value = cosmos_script_wait_implementation_tolerance(target_name, packet_name, item_name, type, expected_value, tolerance, timeout, polling_rate)
690
- time = Time.now - start_time
691
- range = (expected_value - tolerance)..(expected_value + tolerance)
692
- if success
693
- Logger.info "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} was within range #{range.first} to #{range.last} with value == #{value} after waiting #{time} seconds"
694
- else
695
- message = "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} failed to be within range #{range.first} to #{range.last} with value == #{value} after waiting #{time} seconds"
696
- if $cmd_tlm_disconnect
697
- Logger.error message
698
- else
699
- raise CheckError, message
700
- end
701
- end
702
- time
703
- end
704
-
705
- def wait_check_tolerance(*args)
706
- _wait_check_tolerance(false, *args)
707
- end
708
-
709
- def wait_check_tolerance_raw(*args)
710
- _wait_check_tolerance(true, *args)
711
- end
712
-
713
- # Wait on an expression to be true. On a timeout, the script will pause.
714
- def wait_check_expression(exp_to_eval,
715
- timeout,
716
- polling_rate = DEFAULT_TLM_POLLING_RATE,
717
- context = nil)
718
- start_time = Time.now
719
- success = cosmos_script_wait_implementation_expression(exp_to_eval,
720
- timeout,
721
- polling_rate,
722
- context)
723
- time = Time.now - start_time
724
- if success
725
- Logger.info "CHECK: #{exp_to_eval} is TRUE after waiting #{time} seconds"
726
- else
727
- message = "CHECK: #{exp_to_eval} is FALSE after waiting #{time} seconds"
728
- if $cmd_tlm_disconnect
729
- Logger.error message
730
- else
731
- raise CheckError, message
732
- end
733
- end
734
- time
735
- end
736
- alias wait_expression_stop_on_timeout wait_check_expression
737
-
738
- # Wait for a telemetry packet to be received a certain number of times or timeout
739
- def _wait_packet(check,
740
- target_name,
741
- packet_name,
742
- num_packets,
743
- timeout,
744
- polling_rate = DEFAULT_TLM_POLLING_RATE)
745
- type = (check ? 'CHECK' : 'WAIT')
746
- initial_count = tlm(target_name, packet_name, 'RECEIVED_COUNT')
747
- start_time = Time.now
748
- success, value = cosmos_script_wait_implementation(target_name,
749
- packet_name,
750
- 'RECEIVED_COUNT',
751
- :CONVERTED,
752
- ">= #{initial_count + num_packets}",
753
- timeout,
754
- polling_rate)
755
- time = Time.now - start_time
756
- if success
757
- Logger.info "#{type}: #{target_name.upcase} #{packet_name.upcase} received #{value - initial_count} times after waiting #{time} seconds"
758
- else
759
- message = "#{type}: #{target_name.upcase} #{packet_name.upcase} expected to be received #{num_packets} times but only received #{value - initial_count} times after waiting #{time} seconds"
760
- if check
761
- if $cmd_tlm_disconnect
762
- Logger.error message
763
- else
764
- raise CheckError, message
765
- end
766
- else
767
- Logger.warn message
768
- end
769
- end
770
- time
771
- end
772
-
773
- def wait_packet(target_name,
774
- packet_name,
775
- num_packets,
776
- timeout,
777
- polling_rate = DEFAULT_TLM_POLLING_RATE)
778
- _wait_packet(false, target_name, packet_name, num_packets, timeout, polling_rate)
779
- end
780
-
781
- # Wait for a telemetry packet to be received a certain number of times or timeout and raise an error
782
- def wait_check_packet(target_name,
783
- packet_name,
784
- num_packets,
785
- timeout,
786
- polling_rate = DEFAULT_TLM_POLLING_RATE)
787
- _wait_packet(true, target_name, packet_name, num_packets, timeout, polling_rate)
788
- end
789
-
790
- def get_interface_names
791
- return $cmd_tlm_server.get_interface_names
792
- end
793
-
794
- def connect_interface(interface_name, *params)
795
- return $cmd_tlm_server.connect_interface(interface_name, *params)
796
- end
797
-
798
- def disconnect_interface(interface_name)
799
- return $cmd_tlm_server.disconnect_interface(interface_name)
800
- end
801
-
802
- def interface_state(interface_name)
803
- return $cmd_tlm_server.interface_state(interface_name)
804
- end
805
-
806
- def map_target_to_interface(target_name, interface_name)
807
- return $cmd_tlm_server.map_target_to_interface(target_name, interface_name)
808
- end
809
-
810
- def get_router_names
811
- return $cmd_tlm_server.get_router_names
812
- end
813
-
814
- def connect_router(router_name, *params)
815
- return $cmd_tlm_server.connect_router(router_name, *params)
816
- end
817
-
818
- def disconnect_router(router_name)
819
- return $cmd_tlm_server.disconnect_router(router_name)
820
- end
821
-
822
- def router_state(router_name)
823
- return $cmd_tlm_server.router_state(router_name)
824
- end
825
-
826
- def get_cmd_log_filename(packet_log_writer_name = 'DEFAULT')
827
- return $cmd_tlm_server.get_cmd_log_filename(packet_log_writer_name)
828
- end
829
-
830
- def get_tlm_log_filename(packet_log_writer_name = 'DEFAULT')
831
- return $cmd_tlm_server.get_tlm_log_filename(packet_log_writer_name)
832
- end
833
-
834
- def start_logging(packet_log_writer_name = 'ALL', label = nil)
835
- return $cmd_tlm_server.start_logging(packet_log_writer_name, label)
836
- end
837
-
838
- def stop_logging(packet_log_writer_name = 'ALL')
839
- return $cmd_tlm_server.stop_logging(packet_log_writer_name)
840
- end
841
-
842
- def start_cmd_log(packet_log_writer_name = 'ALL', label = nil)
843
- return $cmd_tlm_server.start_cmd_log(packet_log_writer_name, label)
844
- end
845
-
846
- def start_tlm_log(packet_log_writer_name = 'ALL', label = nil)
847
- return $cmd_tlm_server.start_tlm_log(packet_log_writer_name, label)
848
- end
849
-
850
- def stop_cmd_log(packet_log_writer_name = 'ALL')
851
- return $cmd_tlm_server.stop_cmd_log(packet_log_writer_name)
852
- end
853
-
854
- def stop_tlm_log(packet_log_writer_name = 'ALL')
855
- return $cmd_tlm_server.stop_tlm_log(packet_log_writer_name)
856
- end
857
-
858
- def start_raw_logging_interface(interface_name = 'ALL')
859
- return $cmd_tlm_server.start_raw_logging_interface(interface_name)
860
- end
861
-
862
- def stop_raw_logging_interface(interface_name = 'ALL')
863
- return $cmd_tlm_server.stop_raw_logging_interface(interface_name)
864
- end
865
-
866
- def start_raw_logging_router(router_name = 'ALL')
867
- return $cmd_tlm_server.start_raw_logging_router(router_name)
868
- end
869
-
870
- def stop_raw_logging_router(router_name = 'ALL')
871
- return $cmd_tlm_server.stop_raw_logging_router(router_name)
872
- end
873
-
874
- def get_server_message_log_filename
875
- return $cmd_tlm_server.get_server_message_log_filename
876
- end
877
-
878
- def start_new_server_message_log
879
- return $cmd_tlm_server.start_new_server_message_log
880
- end
881
-
882
- #######################################
883
- # Methods accessing tlm_viewer
884
- #######################################
885
-
886
- def display(display_name, x_pos = nil, y_pos = nil)
887
- tlm_viewer = JsonDRbObject.new "localhost", System.ports['TLMVIEWER_API']
888
- begin
889
- tlm_viewer.display(display_name, x_pos, y_pos)
890
- tlm_viewer.disconnect
891
- rescue DRb::DRbConnError
892
- # No Listening Tlm Viewer - So Start One
893
- if Kernel.is_windows?
894
- Cosmos.run_process('rubyw "' + File.join(Cosmos::USERPATH, 'tools', 'TlmViewer') + '"' + " --system #{File.basename(System.initial_filename)}")
895
- elsif Kernel.is_mac? and File.exist?(File.join(Cosmos::USERPATH, 'tools', 'mac', 'TlmViewer.app'))
896
- Cosmos.run_process('open "' + File.join(Cosmos::USERPATH, 'tools', 'mac', 'TlmViewer.app') + '"' + " --args --system #{File.basename(System.initial_filename)}")
897
- else
898
- Cosmos.run_process('ruby "' + File.join(Cosmos::USERPATH, 'tools', 'TlmViewer') + '"' + " --system #{File.basename(System.initial_filename)}")
899
- end
900
- sleep(5)
901
- begin
902
- tlm_viewer.display(display_name, x_pos, y_pos)
903
- tlm_viewer.disconnect
904
- rescue DRb::DRbConnError
905
- raise "Unable to Successfully Start Listening Telemetry Viewer: #{display_name} could not be displayed"
906
- rescue Errno::ENOENT
907
- raise "Display Screen File: #{display_name}.txt does not exist"
908
- end
909
- rescue Errno::ENOENT
910
- raise "Display Screen File: #{display_name}.txt does not exist"
911
- end
912
- end
913
-
914
- def clear(display_name)
915
- tlm_viewer = JsonDRbObject.new "localhost", System.ports['TLMVIEWER_API']
916
- begin
917
- tlm_viewer.clear(display_name)
918
- tlm_viewer.disconnect
919
- rescue DRb::DRbConnError
920
- # No Listening Tlm Viewer - So Start One
921
- if Kernel.is_windows?
922
- Cosmos.run_process('rubyw "' + File.join(Cosmos::USERPATH, 'tools', 'TlmViewer') + '"' + " --system #{File.basename(System.initial_filename)}")
923
- elsif Kernel.is_mac? and File.exist?(File.join(Cosmos::USERPATH, 'tools', 'mac', 'TlmViewer.app'))
924
- Cosmos.run_process('open "' + File.join(Cosmos::USERPATH, 'tools', 'mac', 'TlmViewer.app') + '"' + " --args --system #{File.basename(System.initial_filename)}")
925
- else
926
- Cosmos.run_process('ruby "' + File.join(Cosmos::USERPATH, 'tools', 'TlmViewer') + '"' + " --system #{File.basename(System.initial_filename)}")
927
- end
928
- sleep(5)
929
- begin
930
- tlm_viewer.clear(display_name)
931
- tlm_viewer.disconnect
932
- rescue DRb::DRbConnError
933
- raise "Unable to Successfully Start Listening Telemetry Viewer: #{display_name} could not be cleared"
934
- rescue Errno::ENOENT
935
- raise "Display Screen File: #{display_name}.txt does not exist"
936
- end
937
- rescue Errno::ENOENT
938
- raise "Display Screen File: #{display_name}.txt does not exist"
939
- end
940
- end
941
-
942
- #######################################
943
- # Methods accessing script runner
944
- #######################################
945
-
946
- def set_line_delay(delay)
947
- if defined? ScriptRunnerFrame
948
- ScriptRunnerFrame.line_delay = delay if delay >= 0.0
949
- end
950
- end
951
-
952
- def get_line_delay
953
- if defined? ScriptRunnerFrame
954
- ScriptRunnerFrame.line_delay
955
- end
956
- end
957
-
958
- def get_scriptrunner_message_log_filename
959
- filename = nil
960
- if defined? ScriptRunnerFrame
961
- filename = ScriptRunnerFrame.instance.message_log.filename if ScriptRunnerFrame.instance and ScriptRunnerFrame.instance.message_log
962
- end
963
- return filename
964
- end
965
-
966
- def start_new_scriptrunner_message_log
967
- if defined? ScriptRunnerFrame
968
- # A new log will be created at the next message
969
- ScriptRunnerFrame.instance.stop_message_log if ScriptRunnerFrame.instance
970
- end
971
- end
972
-
973
- def disable_instrumentation
974
- if defined? ScriptRunnerFrame and ScriptRunnerFrame.instance
975
- ScriptRunnerFrame.instance.use_instrumentation = false
976
- begin
977
- yield
978
- ensure
979
- ScriptRunnerFrame.instance.use_instrumentation = true
980
- end
981
- else
982
- yield
983
- end
984
- end
985
-
986
- def set_stdout_max_lines(max_lines)
987
- if defined? ScriptRunnerFrame and ScriptRunnerFrame.instance
988
- ScriptRunnerFrame.instance.stdout_max_lines = max_lines
989
- end
990
- end
991
-
992
- #######################################
993
- # Methods for debugging
994
- #######################################
995
-
996
- def insert_return(*params)
997
- if defined? ScriptRunnerFrame
998
- if ScriptRunnerFrame.instance
999
- ScriptRunnerFrame.instance.inline_return = true
1000
- ScriptRunnerFrame.instance.inline_return_params = params
1001
- end
1002
- end
1003
- end
1004
-
1005
- def step_mode
1006
- if defined? ScriptRunnerFrame
1007
- ScriptRunnerFrame.step_mode = true
1008
- end
1009
- end
1010
-
1011
- def run_mode
1012
- if defined? ScriptRunnerFrame
1013
- ScriptRunnerFrame.step_mode = false
1014
- end
1015
- end
1016
-
1017
- def show_backtrace(value = true)
1018
- if defined? ScriptRunnerFrame
1019
- ScriptRunnerFrame.show_backtrace = value
1020
- end
1021
- end
1022
-
1023
- ##########################################
1024
- # End Methods accessing other systems
1025
- ##########################################
1026
-
1027
- def start(procedure_name)
1028
- # Handle not-giving an extension
1029
- procedure_name_with_extension = nil
1030
- procedure_name_with_extension = procedure_name + '.rb' if File.extname(procedure_name).empty?
1031
-
1032
- file_text = ''
1033
- path = nil
1034
-
1035
- # Find filename in search path
1036
- ($:).each do |directory|
1037
- if File.exist?(directory + '/' + procedure_name) and not File.directory?(directory + '/' + procedure_name)
1038
- path = directory + '/' + procedure_name
1039
- break
1040
- end
1041
-
1042
- if procedure_name_with_extension and File.exist?(directory + '/' + procedure_name_with_extension)
1043
- procedure_name = procedure_name_with_extension
1044
- path = directory + '/' + procedure_name
1045
- break
1046
- end
1047
- end
1048
-
1049
- # Handle absolute path
1050
- path = procedure_name if !path and File.exist?(procedure_name)
1051
- path = procedure_name_with_extension if !path and procedure_name_with_extension and File.exist?(procedure_name_with_extension)
1052
-
1053
- raise "Procedure not found : #{procedure_name}" unless path
1054
-
1055
- if defined? ScriptRunnerFrame and ScriptRunnerFrame.instance
1056
- result = false
1057
- md5 = nil
1058
- begin
1059
- md5 = Cosmos.md5_files([path]).hexdigest
1060
- rescue Exception => error
1061
- raise "Error calculating md5 on procedure file : #{path}"
1062
- end
1063
-
1064
- # Check RAM based instrumented cache
1065
- instrumented_cache = ScriptRunnerFrame.instrumented_cache[path]
1066
- instrumented_script = nil
1067
- if instrumented_cache and md5 == instrumented_cache[1]
1068
- # Use cached instrumentation
1069
- instrumented_script = instrumented_cache[0]
1070
- else
1071
- use_file_cache = true
1072
- cache_filename = nil
1073
- flat_path = nil
1074
-
1075
- # Check for cache directory existence
1076
- Cosmos.set_working_dir do
1077
- cache_path = File.join(System.paths['TMP'], 'script_runner')
1078
- unless File.directory?(cache_path)
1079
- # Try to create .cache directory
1080
- begin
1081
- Dir.mkdir(cache_path)
1082
- rescue
1083
- use_file_cache = false
1084
- end
1085
- end
1086
-
1087
- if use_file_cache
1088
- # Check file based instrumented cache
1089
- flat_path = path.tr("/", "_").gsub("\\", "_").tr(":", "_").tr(" ", "_")
1090
- flat_path_with_md5 = flat_path + '_' + md5
1091
- cache_filename = File.join(cache_path, flat_path_with_md5)
1092
- end
1093
-
1094
- if use_file_cache and File.exist?(cache_filename)
1095
- # Use file cached instrumentation
1096
- File.open(cache_filename, 'r') {|file| instrumented_script = file.read}
1097
- else
1098
- # Have to instrument
1099
- result = true
1100
-
1101
- # Build instrumentation
1102
- begin
1103
- file_text = File.read(path)
1104
- rescue Exception => error
1105
- raise "Error reading procedure file : #{path}"
1106
- end
1107
-
1108
- instrumented_script = ScriptRunnerFrame.instrument_script(file_text, path, true)
1109
-
1110
- # Cache instrumentation into file
1111
- if use_file_cache
1112
- begin
1113
- File.open(cache_filename, 'w') {|file| file.write(instrumented_script)}
1114
- rescue
1115
- # Oh well, failed to write cache file
1116
- end
1117
- end
1118
- end
1119
- end
1120
-
1121
- # Cache instrumentation into RAM
1122
- ScriptRunnerFrame.instrumented_cache[path] = [instrumented_script, md5]
1123
- end
1124
-
1125
- Object.class_eval(instrumented_script, path, 1)
1126
- else # No ScriptRunnerFrame so just start it locally
1127
- result = true
1128
-
1129
- begin
1130
- Kernel::load(path)
1131
- rescue LoadError => error
1132
- raise RuntimeError.new("Error loading : #{procedure_name} : #{error.message}")
1133
- end
1134
- end
1135
- result
1136
- end
1137
-
1138
- # Require an additional ruby file
1139
- def load_utility(procedure_name)
1140
- result = false
1141
- if defined? ScriptRunnerFrame and ScriptRunnerFrame.instance
1142
- saved = ScriptRunnerFrame.instance.use_instrumentation
1143
- begin
1144
- ScriptRunnerFrame.instance.use_instrumentation = false
1145
- result = start(procedure_name)
1146
- ensure
1147
- ScriptRunnerFrame.instance.use_instrumentation = saved
1148
- end
1149
- else # Just call start
1150
- result = start(procedure_name)
1151
- end
1152
- result
1153
- end
1154
- alias require_utility load_utility
1155
-
1156
- ##########################################
1157
- # Protected Methods
1158
- ##########################################
1159
-
1160
- def check_process_args(args, function_name)
1161
- case args.length
1162
- when 1
1163
- target_name, packet_name, item_name, comparison_to_eval = extract_fields_from_check_text(args[0])
1164
- when 4
1165
- target_name = args[0]
1166
- packet_name = args[1]
1167
- item_name = args[2]
1168
- comparison_to_eval = args[3]
1169
- else
1170
- # Invalid number of arguments
1171
- raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{function_name}()"
1172
- end
1173
- return [target_name, packet_name, item_name, comparison_to_eval]
1174
- end
1175
-
1176
- def check_tolerance_process_args(args, function_name)
1177
- case args.length
1178
- when 3
1179
- target_name, packet_name, item_name = extract_fields_from_tlm_text(args[0])
1180
- expected_value = args[1]
1181
- tolerance = args[2]
1182
- when 5
1183
- target_name = args[0]
1184
- packet_name = args[1]
1185
- item_name = args[2]
1186
- expected_value = args[3]
1187
- tolerance = args[4]
1188
- else
1189
- # Invalid number of arguments
1190
- raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{function_name}()"
1191
- end
1192
- return [target_name, packet_name, item_name, expected_value, tolerance]
1193
- end
1194
-
1195
- def wait_process_args(args, function_name, value_type)
1196
- time = nil
1197
-
1198
- case args.length
1199
- when 0
1200
- start_time = Time.now
1201
- cosmos_script_sleep()
1202
- time = Time.now - start_time
1203
- Logger.info("WAIT: Indefinite for actual time of #{time} seconds")
1204
- when 1
1205
- if args[0].kind_of? Numeric
1206
- start_time = Time.now
1207
- cosmos_script_sleep(args[0])
1208
- time = Time.now - start_time
1209
- Logger.info("WAIT: #{args[0]} seconds with actual time of #{time} seconds")
1210
- else
1211
- raise "Non-numeric wait time specified"
1212
- end
1213
- when 2, 3
1214
- target_name, packet_name, item_name, comparison_to_eval = extract_fields_from_check_text(args[0])
1215
- timeout = args[1]
1216
- if args.length == 3
1217
- polling_rate = args[2]
1218
- else
1219
- polling_rate = DEFAULT_TLM_POLLING_RATE
1220
- end
1221
- start_time = Time.now
1222
- success, value = cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, comparison_to_eval, timeout, polling_rate)
1223
- time = Time.now - start_time
1224
- if success
1225
- Logger.info "WAIT: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} #{comparison_to_eval} success with value == #{value} after waiting #{time} seconds"
1226
- else
1227
- Logger.warn "WAIT: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} #{comparison_to_eval} failed with value == #{value} after waiting #{time} seconds"
1228
- end
1229
- when 5, 6
1230
- target_name = args[0]
1231
- packet_name = args[1]
1232
- item_name = args[2]
1233
- comparison_to_eval = args[3]
1234
- timeout = args[4]
1235
- if args.length == 6
1236
- polling_rate = args[5]
1237
- else
1238
- polling_rate = DEFAULT_TLM_POLLING_RATE
1239
- end
1240
- start_time = Time.now
1241
- success, value = cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, comparison_to_eval, timeout, polling_rate)
1242
- time = Time.now - start_time
1243
- if success
1244
- Logger.info "WAIT: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} #{comparison_to_eval} success with value == #{value} after waiting #{time} seconds"
1245
- else
1246
- Logger.warn "WAIT: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} #{comparison_to_eval} failed with value == #{value} after waiting #{time} seconds"
1247
- end
1248
- else
1249
- # Invalid number of arguments
1250
- raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{function_name}()"
1251
- end
1252
- time
1253
- end
1254
-
1255
- def wait_tolerance_process_args(args, function_name)
1256
- case args.length
1257
- when 4, 5
1258
- target_name, packet_name, item_name = extract_fields_from_tlm_text(args[0])
1259
- expected_value = args[1]
1260
- tolerance = args[2]
1261
- timeout = args[3]
1262
- if args.length == 5
1263
- polling_rate = args[4]
1264
- else
1265
- polling_rate = DEFAULT_TLM_POLLING_RATE
1266
- end
1267
- when 6, 7
1268
- target_name = args[0]
1269
- packet_name = args[1]
1270
- item_name = args[2]
1271
- expected_value = args[3]
1272
- tolerance = args[4]
1273
- timeout = args[5]
1274
- if args.length == 7
1275
- polling_rate = args[6]
1276
- else
1277
- polling_rate = DEFAULT_TLM_POLLING_RATE
1278
- end
1279
- else
1280
- # Invalid number of arguments
1281
- raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{function_name}()"
1282
- end
1283
- return [target_name, packet_name, item_name, expected_value, tolerance, timeout, polling_rate]
1284
- end
1285
-
1286
- def wait_check_process_args(args, function_name)
1287
- case args.length
1288
- when 2,3
1289
- target_name, packet_name, item_name, comparison_to_eval = extract_fields_from_check_text(args[0])
1290
- timeout = args[1]
1291
- if args.length == 3
1292
- polling_rate = args[2]
1293
- else
1294
- polling_rate = DEFAULT_TLM_POLLING_RATE
1295
- end
1296
- when 5,6
1297
- target_name = args[0]
1298
- packet_name = args[1]
1299
- item_name = args[2]
1300
- comparison_to_eval = args[3]
1301
- timeout = args[4]
1302
- if args.length == 6
1303
- polling_rate = args[5]
1304
- else
1305
- polling_rate = DEFAULT_TLM_POLLING_RATE
1306
- end
1307
- else
1308
- # Invalid number of arguments
1309
- raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{function_name}()"
1310
- end
1311
- return [target_name, packet_name, item_name, comparison_to_eval, timeout, polling_rate]
1312
- end
1313
-
1314
- # sleep in a script - returns true if canceled mid sleep
1315
- def cosmos_script_sleep(sleep_time = nil)
1316
- return false if $cmd_tlm_disconnect
1317
- if defined? ScriptRunnerFrame and ScriptRunnerFrame.instance
1318
- sleep_time = 30000000 unless sleep_time # Handle infinite wait
1319
- if sleep_time > 0.0
1320
- end_time = Time.now + sleep_time
1321
- until (Time.now >= end_time)
1322
- sleep(0.01)
1323
- if ScriptRunnerFrame.instance.pause?
1324
- ScriptRunnerFrame.instance.perform_pause
1325
- return true
1326
- end
1327
- return true if ScriptRunnerFrame.instance.go?
1328
- raise StopScript if ScriptRunnerFrame.instance.stop?
1329
- end
1330
- end
1331
- else
1332
- if sleep_time
1333
- sleep(sleep_time)
1334
- else
1335
- print 'Infinite Wait - Press Enter to Continue: '
1336
- gets()
1337
- end
1338
- end
1339
- return false
1340
- end
1341
-
1342
- def _cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate)
1343
- end_time = Time.now + timeout
1344
- exp_to_eval = yield
1345
-
1346
- while true
1347
- work_start = Time.now
1348
- value = tlm_variable(target_name, packet_name, item_name, value_type)
1349
- if eval(exp_to_eval)
1350
- return true, value
1351
- end
1352
- break if Time.now >= end_time || $cmd_tlm_disconnect
1353
-
1354
- delta = Time.now - work_start
1355
- sleep_time = polling_rate - delta
1356
- end_delta = end_time - Time.now
1357
- sleep_time = end_delta if end_delta < sleep_time
1358
- sleep_time = 0 if sleep_time < 0
1359
- canceled = cosmos_script_sleep(sleep_time)
1360
-
1361
- if canceled
1362
- value = tlm_variable(target_name, packet_name, item_name, value_type)
1363
- if eval(exp_to_eval)
1364
- return true, value
1365
- else
1366
- return false, value
1367
- end
1368
- end
1369
- end
1370
-
1371
- return false, value
1372
- end
1373
-
1374
- # Wait for a converted telemetry item to pass a comparison
1375
- def cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, comparison_to_eval, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE)
1376
- _cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate) do
1377
- "value " + comparison_to_eval
1378
- end
1379
- end
1380
-
1381
- def cosmos_script_wait_implementation_tolerance(target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE)
1382
- _cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate) do
1383
- "((#{expected_value} - #{tolerance})..(#{expected_value} + #{tolerance})).include? value"
1384
- end
1385
- end
1386
-
1387
- # Wait on an expression to be true.
1388
- def cosmos_script_wait_implementation_expression(exp_to_eval, timeout, polling_rate, context)
1389
- end_time = Time.now + timeout
1390
- context = ScriptRunnerFrame.instance.script_binding if !context and defined? ScriptRunnerFrame and ScriptRunnerFrame.instance
1391
-
1392
- while true
1393
- work_start = Time.now
1394
- if eval(exp_to_eval, context)
1395
- return true
1396
- end
1397
- break if Time.now >= end_time
1398
-
1399
- delta = Time.now - work_start
1400
- sleep_time = polling_rate - delta
1401
- end_delta = end_time - Time.now
1402
- sleep_time = end_delta if end_delta < sleep_time
1403
- sleep_time = 0 if sleep_time < 0
1404
- canceled = cosmos_script_sleep(sleep_time)
1405
-
1406
- if canceled
1407
- if eval(exp_to_eval, context)
1408
- return true
1409
- else
1410
- return nil
1411
- end
1412
- end
1413
- end
1414
-
1415
- return nil
1416
- end
1417
-
1418
- def check_eval(target_name, packet_name, item_name, comparison_to_eval, value)
1419
- string = "value " + comparison_to_eval
1420
- if eval(string)
1421
- Logger.info "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} #{comparison_to_eval} success with value == #{value}"
1422
- else
1423
- message = "CHECK: #{target_name.upcase} #{packet_name.upcase} #{item_name.upcase} #{comparison_to_eval} failed with value == #{value}"
1424
- if $cmd_tlm_disconnect
1425
- Logger.error message
1426
- else
1427
- raise CheckError, message
1428
- end
1429
- end
1430
- end
1431
-
1432
- def build_cmd_output_string(target_name, cmd_name, cmd_params, raw = false)
1433
- if raw
1434
- output_string = 'cmd_raw("'
1435
- else
1436
- output_string = 'cmd("'
1437
- end
1438
- output_string << target_name + ' ' + cmd_name
1439
- if cmd_params.nil? or cmd_params.empty?
1440
- output_string << '")'
1441
- else
1442
- params = []
1443
- cmd_params.each do |key, value|
1444
- if value.class == String
1445
- if value.convert_to_value.class == String
1446
- value = value.inspect
1447
- if value.length > 256
1448
- value = value[0..255] + "...'"
1449
- end
1450
- value.tr!('"',"'")
1451
- end
1452
- end
1453
- params << "#{key} #{value}"
1454
- end
1455
- params = params.join(", ")
1456
- output_string << ' with ' + params + '")'
1457
- end
1458
- return output_string
1459
- end
1460
-
1461
- def prompt_for_hazardous(target_name, cmd_name, hazardous_description)
1462
- message = "Warning: Command #{target_name} #{cmd_name} is Hazardous. "
1463
- message << "\n#{hazardous_description}\n" if hazardous_description
1464
- message << "Send? (y,n): "
1465
- print message
1466
- answer = gets.chomp
1467
- if answer.downcase == 'y'
1468
- return true
1469
- else
1470
- return false
1471
- end
39
+ # Called when this module is mixed in using "include Cosmos::Script"
40
+ def self.included(base)
41
+ $cmd_tlm_disconnect = false
42
+ $cmd_tlm_server = nil
43
+ initialize_script_module()
1472
44
  end
1473
45
 
1474
- def prompt_for_script_abort
1475
- print "Stop running script? (y,n): "
1476
- answer = gets.chomp
1477
- if answer.downcase == 'y'
1478
- exit
46
+ def initialize_script_module(config_file = CmdTlmServer::DEFAULT_CONFIG_FILE)
47
+ if $cmd_tlm_disconnect
48
+ # Start up a standalone CTS in disconnected mode
49
+ $cmd_tlm_server = CmdTlmServer.new(config_file, false, true)
1479
50
  else
1480
- return false # Not aborted - Retry
51
+ # Start a Json connect to the real CTS server
52
+ $cmd_tlm_server = JsonDRbObject.new('127.0.0.1', System.ports['CTS_API'])
1481
53
  end
1482
54
  end
1483
55
 
1484
- def prompt_to_continue(string)
1485
- print "#{string}: "
1486
- gets.chomp
1487
- end
1488
-
1489
- def prompt_message_box(string, buttons)
1490
- print "#{string} (#{buttons.join(", ")}): "
1491
- gets.chomp
56
+ def shutdown_cmd_tlm
57
+ $cmd_tlm_server.shutdown if $cmd_tlm_server && !$cmd_tlm_disconnect
1492
58
  end
1493
59
 
1494
- ################################
1495
- # Module setup and config
1496
- ################################
1497
-
1498
60
  def set_cmd_tlm_disconnect(disconnect = false, config_file = CmdTlmServer::DEFAULT_CONFIG_FILE)
1499
61
  if disconnect != $cmd_tlm_disconnect
1500
62
  $cmd_tlm_disconnect = disconnect
@@ -1506,30 +68,9 @@ module Cosmos
1506
68
  return $cmd_tlm_disconnect
1507
69
  end
1508
70
 
1509
- def initialize_script_module(config_file = CmdTlmServer::DEFAULT_CONFIG_FILE)
1510
- if $cmd_tlm_disconnect
1511
- # Start up a standalone CTS in disconnected mode
1512
- $cmd_tlm_server = CmdTlmServer.new(config_file, false, true)
1513
- else
1514
- # Start a Json connect to the real CTS server
1515
- $cmd_tlm_server = JsonDRbObject.new('127.0.0.1', System.ports['CTS_API'])
1516
- end
1517
- end
1518
-
1519
- def self.included(base)
1520
- $cmd_tlm_disconnect = false
1521
- $cmd_tlm_server = nil
1522
- initialize_script_module()
1523
- end
1524
-
1525
71
  def script_disconnect
1526
72
  $cmd_tlm_server.disconnect if $cmd_tlm_server && !$cmd_tlm_disconnect
1527
73
  end
1528
74
 
1529
- def shutdown_cmd_tlm
1530
- $cmd_tlm_server.shutdown if $cmd_tlm_server && !$cmd_tlm_disconnect
1531
- end
1532
-
1533
- end # module Script
1534
-
1535
- end # module Cosmos
75
+ end
76
+ end