cosmos 3.3.3 → 3.4.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.
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