openc3 6.8.1 → 6.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/bin/openc3cli +5 -5
- data/data/config/command_modifiers.yaml +9 -1
- data/data/config/screen.yaml +1 -1
- data/lib/openc3/accessors/json_accessor.rb +5 -5
- data/lib/openc3/api/interface_api.rb +71 -4
- data/lib/openc3/api/router_api.rb +98 -8
- data/lib/openc3/api/stash_api.rb +3 -3
- data/lib/openc3/api/tlm_api.rb +1 -1
- data/lib/openc3/bridge/bridge_config.rb +1 -1
- data/lib/openc3/interfaces/file_interface.rb +18 -0
- data/lib/openc3/interfaces/http_client_interface.rb +11 -0
- data/lib/openc3/interfaces/http_server_interface.rb +8 -0
- data/lib/openc3/interfaces/interface.rb +90 -21
- data/lib/openc3/interfaces/mqtt_interface.rb +19 -0
- data/lib/openc3/interfaces/mqtt_stream_interface.rb +20 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +16 -0
- data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +18 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +19 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +17 -1
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +14 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +25 -1
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +16 -3
- data/lib/openc3/interfaces/protocols/protocol.rb +79 -1
- data/lib/openc3/interfaces/protocols/slip_protocol.rb +23 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +38 -0
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +14 -1
- data/lib/openc3/interfaces/serial_interface.rb +14 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +1 -1
- data/lib/openc3/interfaces/tcpip_client_interface.rb +16 -2
- data/lib/openc3/interfaces/tcpip_server_interface.rb +11 -1
- data/lib/openc3/interfaces/udp_interface.rb +14 -0
- data/lib/openc3/io/json_api_object.rb +1 -1
- data/lib/openc3/io/json_drb.rb +1 -1
- data/lib/openc3/io/json_drb_object.rb +1 -1
- data/lib/openc3/io/json_rpc.rb +5 -4
- data/lib/openc3/logs/packet_log_reader.rb +1 -1
- data/lib/openc3/logs/packet_log_writer.rb +6 -6
- data/lib/openc3/microservices/decom_microservice.rb +5 -1
- data/lib/openc3/microservices/interface_microservice.rb +103 -38
- data/lib/openc3/microservices/microservice.rb +4 -4
- data/lib/openc3/microservices/queue_microservice.rb +14 -21
- data/lib/openc3/microservices/reducer_microservice.rb +1 -1
- data/lib/openc3/microservices/router_microservice.rb +28 -25
- data/lib/openc3/models/activity_model.rb +18 -17
- data/lib/openc3/models/cvt_model.rb +12 -9
- data/lib/openc3/models/interface_model.rb +70 -12
- data/lib/openc3/models/metadata_model.rb +2 -2
- data/lib/openc3/models/microservice_model.rb +1 -1
- data/lib/openc3/models/microservice_status_model.rb +2 -2
- data/lib/openc3/models/model.rb +4 -4
- data/lib/openc3/models/note_model.rb +2 -2
- data/lib/openc3/models/plugin_model.rb +9 -4
- data/lib/openc3/models/queue_model.rb +25 -25
- data/lib/openc3/models/reaction_model.rb +6 -6
- data/lib/openc3/models/script_engine_model.rb +1 -1
- data/lib/openc3/models/script_status_model.rb +3 -3
- data/lib/openc3/models/sorted_model.rb +5 -5
- data/lib/openc3/models/target_model.rb +11 -11
- data/lib/openc3/models/timeline_model.rb +2 -2
- data/lib/openc3/models/tool_model.rb +1 -1
- data/lib/openc3/models/trigger_group_model.rb +3 -3
- data/lib/openc3/models/trigger_model.rb +6 -6
- data/lib/openc3/models/widget_model.rb +1 -1
- data/lib/openc3/operators/operator.rb +2 -2
- data/lib/openc3/packets/json_packet.rb +1 -1
- data/lib/openc3/packets/packet.rb +1 -1
- data/lib/openc3/script/calendar.rb +2 -2
- data/lib/openc3/script/metadata.rb +4 -4
- data/lib/openc3/script/queue.rb +13 -5
- data/lib/openc3/script/script_runner.rb +9 -9
- data/lib/openc3/script/storage.rb +1 -1
- data/lib/openc3/script/tables.rb +2 -2
- data/lib/openc3/script/web_socket_api.rb +7 -7
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +0 -12
- data/lib/openc3/tools/table_manager/table_manager_core.rb +1 -1
- data/lib/openc3/topics/command_decom_topic.rb +3 -3
- data/lib/openc3/topics/command_topic.rb +1 -1
- data/lib/openc3/topics/interface_topic.rb +45 -5
- data/lib/openc3/topics/limits_event_topic.rb +8 -8
- data/lib/openc3/topics/router_topic.rb +42 -3
- data/lib/openc3/topics/system_events_topic.rb +1 -1
- data/lib/openc3/topics/telemetry_decom_topic.rb +1 -1
- data/lib/openc3/utilities/authentication.rb +1 -1
- data/lib/openc3/utilities/cosmos_rails_formatter.rb +2 -3
- data/lib/openc3/utilities/local_mode.rb +8 -8
- data/lib/openc3/utilities/logger.rb +3 -3
- data/lib/openc3/utilities/running_script.rb +7 -8
- data/lib/openc3/version.rb +5 -5
- data/templates/plugin/README.md +3 -3
- data/templates/plugin/Rakefile +3 -3
- data/templates/plugin/plugin.gemspec +1 -0
- data/templates/tool_angular/.gitignore +1 -1
- data/templates/tool_angular/package.json +2 -48
- data/templates/tool_react/.gitignore +1 -2
- data/templates/tool_react/package.json +1 -51
- data/templates/tool_svelte/.gitignore +1 -2
- data/templates/tool_svelte/package.json +1 -49
- data/templates/tool_vue/package.json +3 -36
- data/templates/widget/Rakefile +1 -1
- data/templates/widget/package.json +2 -28
- metadata +9 -9
@@ -34,7 +34,7 @@ module OpenC3
|
|
34
34
|
if response.nil? || response.status != 200
|
35
35
|
_script_response_error(response, "Script list request failed", scope: scope)
|
36
36
|
else
|
37
|
-
scripts = JSON.parse(response.body, :
|
37
|
+
scripts = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
38
38
|
# Remove the '*' from the script names
|
39
39
|
return scripts.each { |script| script.gsub!(/\*$/, '') }
|
40
40
|
end
|
@@ -50,7 +50,7 @@ module OpenC3
|
|
50
50
|
if response.nil? || response.status != 200
|
51
51
|
_script_response_error(response, "Script syntax check request failed", scope: scope)
|
52
52
|
else
|
53
|
-
result = JSON.parse(response.body, :
|
53
|
+
result = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
54
54
|
if result['title'] == "Syntax Check Successful"
|
55
55
|
result['success'] = true
|
56
56
|
else
|
@@ -66,7 +66,7 @@ module OpenC3
|
|
66
66
|
if response.nil? || response.status != 200
|
67
67
|
_script_response_error(response, "Failed to get #{filename}", scope: scope)
|
68
68
|
else
|
69
|
-
result = JSON.parse(response.body, :
|
69
|
+
result = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
70
70
|
return result['contents']
|
71
71
|
end
|
72
72
|
end
|
@@ -142,9 +142,9 @@ module OpenC3
|
|
142
142
|
if response.nil? || response.status != 200
|
143
143
|
_script_response_error(response, "Script instrumented request failed", scope: scope)
|
144
144
|
else
|
145
|
-
result = JSON.parse(response.body, :
|
145
|
+
result = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
146
146
|
if result['title'] == "Instrumented Script"
|
147
|
-
parsed = JSON.parse(result['description'], :
|
147
|
+
parsed = JSON.parse(result['description'], allow_nan: true, create_additions: true)
|
148
148
|
return parsed.join("\n")
|
149
149
|
else
|
150
150
|
raise result.inspect
|
@@ -158,7 +158,7 @@ module OpenC3
|
|
158
158
|
if response.nil? || response.status != 200
|
159
159
|
_script_response_error(response, "Script create request failed", scope: scope)
|
160
160
|
else
|
161
|
-
return JSON.parse(response.body, :
|
161
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
@@ -178,7 +178,7 @@ module OpenC3
|
|
178
178
|
if response.nil? || response.status != 200
|
179
179
|
_script_response_error(response, "Running script list request failed", scope: scope)
|
180
180
|
else
|
181
|
-
return JSON.parse(response.body, :
|
181
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)['items']
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
@@ -188,7 +188,7 @@ module OpenC3
|
|
188
188
|
if response.nil? || response.status != 200
|
189
189
|
_script_response_error(response, "Running script show request failed", scope: scope)
|
190
190
|
else
|
191
|
-
return JSON.parse(response.body, :
|
191
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
192
192
|
end
|
193
193
|
end
|
194
194
|
alias running_script_get script_get # Deprecated alias for compatibility
|
@@ -275,7 +275,7 @@ module OpenC3
|
|
275
275
|
if response.nil? || response.status != 200
|
276
276
|
_script_response_error(response, "Completed script list request failed", scope: scope)
|
277
277
|
else
|
278
|
-
return JSON.parse(response.body, :
|
278
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)['items']
|
279
279
|
end
|
280
280
|
end
|
281
281
|
end
|
@@ -199,7 +199,7 @@ module OpenC3
|
|
199
199
|
if response.nil? || response.status != 201
|
200
200
|
raise "Failed to get presigned URL for #{endpoint}"
|
201
201
|
end
|
202
|
-
JSON.parse(response.body, :
|
202
|
+
JSON.parse(response.body, allow_nan: true, create_additions: true)
|
203
203
|
end
|
204
204
|
end
|
205
205
|
end
|
data/lib/openc3/script/tables.rb
CHANGED
@@ -40,10 +40,10 @@ module OpenC3
|
|
40
40
|
def _tables_handle_response(response, error_message)
|
41
41
|
return nil if response.nil?
|
42
42
|
if response.status >= 400
|
43
|
-
result = JSON.parse(response.body, :
|
43
|
+
result = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
44
44
|
raise "#{error_message} due to #{result['message']}"
|
45
45
|
end
|
46
|
-
return JSON.parse(response.body, :
|
46
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -91,8 +91,8 @@ module OpenC3
|
|
91
91
|
unless @subscribed
|
92
92
|
json_hash = {}
|
93
93
|
json_hash['command'] = 'subscribe'
|
94
|
-
json_hash['identifier'] = JSON.generate(@identifier)
|
95
|
-
@stream.write(JSON.generate(json_hash))
|
94
|
+
json_hash['identifier'] = JSON.generate(@identifier, allow_nan: true)
|
95
|
+
@stream.write(JSON.generate(json_hash, allow_nan: true))
|
96
96
|
@subscribed = true
|
97
97
|
end
|
98
98
|
end
|
@@ -102,8 +102,8 @@ module OpenC3
|
|
102
102
|
if @subscribed
|
103
103
|
json_hash = {}
|
104
104
|
json_hash['command'] = 'unsubscribe'
|
105
|
-
json_hash['identifier'] = JSON.generate(@identifier)
|
106
|
-
@stream.write(JSON.generate(json_hash))
|
105
|
+
json_hash['identifier'] = JSON.generate(@identifier, allow_nan: true)
|
106
|
+
@stream.write(JSON.generate(json_hash, allow_nan: true))
|
107
107
|
@subscribed = false
|
108
108
|
end
|
109
109
|
end
|
@@ -112,9 +112,9 @@ module OpenC3
|
|
112
112
|
def write_action(data_hash)
|
113
113
|
json_hash = {}
|
114
114
|
json_hash['command'] = 'message'
|
115
|
-
json_hash['identifier'] = JSON.generate(@identifier)
|
116
|
-
json_hash['data'] = JSON.generate(data_hash)
|
117
|
-
write(JSON.generate(json_hash))
|
115
|
+
json_hash['identifier'] = JSON.generate(@identifier, allow_nan: true)
|
116
|
+
json_hash['data'] = JSON.generate(data_hash, allow_nan: true)
|
117
|
+
write(JSON.generate(json_hash, allow_nan: true))
|
118
118
|
end
|
119
119
|
|
120
120
|
# General write to the websocket
|
@@ -210,18 +210,6 @@ module OpenC3
|
|
210
210
|
rescue => e
|
211
211
|
Logger.error "Problem writing to router #{router.name} - #{e.class}:#{e.message}"
|
212
212
|
end
|
213
|
-
|
214
|
-
# Write to packet log writers
|
215
|
-
if packet.stored and !@interface.stored_packet_log_writer_pairs.empty?
|
216
|
-
@interface.stored_packet_log_writer_pairs.each do |packet_log_writer_pair|
|
217
|
-
packet_log_writer_pair.tlm_log_writer.write(packet)
|
218
|
-
end
|
219
|
-
else
|
220
|
-
@interface.packet_log_writer_pairs.each do |packet_log_writer_pair|
|
221
|
-
# Write errors are handled by the log writer
|
222
|
-
packet_log_writer_pair.tlm_log_writer.write(packet)
|
223
|
-
end
|
224
|
-
end
|
225
213
|
end
|
226
214
|
|
227
215
|
def handle_connection_failed(connect_error)
|
@@ -39,8 +39,8 @@ module OpenC3
|
|
39
39
|
json_hash[item.name + "__F"] = packet.read_item(item, :FORMATTED) if item.format_string
|
40
40
|
json_hash[item.name + "__U"] = packet.read_item(item, :WITH_UNITS) if item.units
|
41
41
|
end
|
42
|
-
json_hash['extra'] = JSON.generate(packet.extra.as_json
|
43
|
-
msg_hash['json_data'] = JSON.generate(json_hash.as_json
|
42
|
+
json_hash['extra'] = JSON.generate(packet.extra.as_json, allow_nan: true)
|
43
|
+
msg_hash['json_data'] = JSON.generate(json_hash.as_json, allow_nan: true)
|
44
44
|
EphemeralStoreQueued.write_topic(topic, msg_hash)
|
45
45
|
end
|
46
46
|
|
@@ -51,7 +51,7 @@ module OpenC3
|
|
51
51
|
msg_hash['received_count'].to_i
|
52
52
|
else
|
53
53
|
json = msg_hash['json_data']
|
54
|
-
hash = JSON.parse(json, :
|
54
|
+
hash = JSON.parse(json, allow_nan: true, create_additions: true)
|
55
55
|
# Start from the most complex down to the basic raw value
|
56
56
|
value = hash["#{param_name}__U"]
|
57
57
|
return value if value && type == :WITH_UNITS
|
@@ -47,7 +47,7 @@ module OpenC3
|
|
47
47
|
Topic.update_topic_offsets([ack_topic])
|
48
48
|
# Save the existing cmd_params Hash and JSON generate before writing to the topic
|
49
49
|
cmd_params = command['cmd_params']
|
50
|
-
command['cmd_params'] = JSON.generate(command['cmd_params'].as_json
|
50
|
+
command['cmd_params'] = JSON.generate(command['cmd_params'].as_json, allow_nan: true)
|
51
51
|
OpenC3.inject_context(command)
|
52
52
|
cmd_id = Topic.write_topic("{#{scope}__CMD}TARGET__#{command['target_name']}", command, '*', 100)
|
53
53
|
command["cmd_params"] = cmd_params # Restore the original cmd_params Hash
|
@@ -42,10 +42,13 @@ module OpenC3
|
|
42
42
|
while true
|
43
43
|
Topic.read_topics(InterfaceTopic.topics(interface, scope: scope)) do |topic, msg_id, msg_hash, redis|
|
44
44
|
result = yield topic, msg_id, msg_hash, redis
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
if result
|
46
|
+
# Only ack if we intend to - Disabled targets will not ack
|
47
|
+
ack_topic = topic.split("__")
|
48
|
+
ack_topic[1] = 'ACK' + ack_topic[1]
|
49
|
+
ack_topic = ack_topic.join("__")
|
50
|
+
Topic.write_topic(ack_topic, { 'result' => result, 'id' => msg_id }, '*', 100)
|
51
|
+
end
|
49
52
|
end
|
50
53
|
end
|
51
54
|
end
|
@@ -75,7 +78,7 @@ module OpenC3
|
|
75
78
|
|
76
79
|
def self.connect_interface(interface_name, *interface_params, scope:)
|
77
80
|
if interface_params && !interface_params.empty?
|
78
|
-
Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'connect' => 'true', 'params' => JSON.generate(interface_params) }, '*', 100)
|
81
|
+
Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'connect' => 'true', 'params' => JSON.generate(interface_params, allow_nan: true) }, '*', 100)
|
79
82
|
else
|
80
83
|
Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'connect' => 'true' }, '*', 100)
|
81
84
|
end
|
@@ -121,5 +124,42 @@ module OpenC3
|
|
121
124
|
data['type'] = type
|
122
125
|
Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'inject_tlm' => JSON.generate(data, allow_nan: true) }, '*', 100)
|
123
126
|
end
|
127
|
+
|
128
|
+
def self.interface_target_enable(interface_name, target_name, cmd_only: false, tlm_only: false, scope:)
|
129
|
+
data = {}
|
130
|
+
data['target_name'] = target_name.to_s.upcase
|
131
|
+
data['cmd_only'] = cmd_only
|
132
|
+
data['tlm_only'] = tlm_only
|
133
|
+
data['action'] = 'enable'
|
134
|
+
Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'target_control' => JSON.generate(data, allow_nan: true) }, '*', 100)
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.interface_target_disable(interface_name, target_name, cmd_only: false, tlm_only: false, scope:)
|
138
|
+
data = {}
|
139
|
+
data['target_name'] = target_name.to_s.upcase
|
140
|
+
data['cmd_only'] = cmd_only
|
141
|
+
data['tlm_only'] = tlm_only
|
142
|
+
data['action'] = 'disable'
|
143
|
+
Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'target_control' => JSON.generate(data, allow_nan: true) }, '*', 100)
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.interface_details(interface_name, timeout: nil, scope:)
|
147
|
+
interface_name = interface_name.upcase
|
148
|
+
|
149
|
+
timeout = COMMAND_ACK_TIMEOUT_S unless timeout
|
150
|
+
ack_topic = "{#{scope}__ACKCMD}INTERFACE__#{interface_name}"
|
151
|
+
Topic.update_topic_offsets([ack_topic])
|
152
|
+
|
153
|
+
cmd_id = Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'interface_details' => 'true' }, '*', 100)
|
154
|
+
time = Time.now
|
155
|
+
while (Time.now - time) < timeout
|
156
|
+
Topic.read_topics([ack_topic]) do |_topic, _msg_id, msg_hash, _redis|
|
157
|
+
if msg_hash["id"] == cmd_id
|
158
|
+
return JSON.parse(msg_hash["result"], :allow_nan => true, :create_additions => true)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
raise "Timeout of #{timeout}s waiting for cmd ack"
|
163
|
+
end
|
124
164
|
end
|
125
165
|
end
|
@@ -47,7 +47,7 @@ module OpenC3
|
|
47
47
|
field = "#{event[:target_name]}__#{event[:packet_name]}__#{event[:item_name]}"
|
48
48
|
limits_settings = Store.hget("#{scope}__current_limits_settings", field)
|
49
49
|
if limits_settings
|
50
|
-
limits_settings = JSON.parse(limits_settings, :
|
50
|
+
limits_settings = JSON.parse(limits_settings, allow_nan: true, create_additions: true)
|
51
51
|
else
|
52
52
|
limits_settings = {}
|
53
53
|
end
|
@@ -61,18 +61,18 @@ module OpenC3
|
|
61
61
|
limits_settings[event[:limits_set]] = limits
|
62
62
|
limits_settings['persistence_setting'] = event[:persistence] if event[:persistence]
|
63
63
|
limits_settings['enabled'] = event[:enabled] if not event[:enabled].nil?
|
64
|
-
Store.hset("#{scope}__current_limits_settings", field, JSON.generate(limits_settings, :
|
64
|
+
Store.hset("#{scope}__current_limits_settings", field, JSON.generate(limits_settings, allow_nan: true))
|
65
65
|
|
66
66
|
when :LIMITS_ENABLE_STATE
|
67
67
|
field = "#{event[:target_name]}__#{event[:packet_name]}__#{event[:item_name]}"
|
68
68
|
limits_settings = Store.hget("#{scope}__current_limits_settings", field)
|
69
69
|
if limits_settings
|
70
|
-
limits_settings = JSON.parse(limits_settings, :
|
70
|
+
limits_settings = JSON.parse(limits_settings, allow_nan: true, create_additions: true)
|
71
71
|
else
|
72
72
|
limits_settings = {}
|
73
73
|
end
|
74
74
|
limits_settings['enabled'] = event[:enabled]
|
75
|
-
Store.hset("#{scope}__current_limits_settings", field, JSON.generate(limits_settings, :
|
75
|
+
Store.hset("#{scope}__current_limits_settings", field, JSON.generate(limits_settings, allow_nan: true))
|
76
76
|
|
77
77
|
when :LIMITS_SET
|
78
78
|
sets = sets(scope: scope)
|
@@ -86,7 +86,7 @@ module OpenC3
|
|
86
86
|
raise "Invalid limits event type '#{event[:type]}'"
|
87
87
|
end
|
88
88
|
|
89
|
-
Topic.write_topic("#{scope}__openc3_limits_events", {event: JSON.generate(event, :
|
89
|
+
Topic.write_topic("#{scope}__openc3_limits_events", {event: JSON.generate(event, allow_nan: true)}, '*', 1000)
|
90
90
|
end
|
91
91
|
|
92
92
|
# Remove the JSON encoding to return hashes directly
|
@@ -106,7 +106,7 @@ module OpenC3
|
|
106
106
|
end
|
107
107
|
parsed_result = []
|
108
108
|
final_result.each do |offset, hash|
|
109
|
-
parsed_result << [offset, JSON.parse(hash['event'], :
|
109
|
+
parsed_result << [offset, JSON.parse(hash['event'], allow_nan: true, create_additions: true)]
|
110
110
|
end
|
111
111
|
return parsed_result
|
112
112
|
end
|
@@ -175,7 +175,7 @@ module OpenC3
|
|
175
175
|
if target
|
176
176
|
packet = target[packet_name]
|
177
177
|
if packet
|
178
|
-
limits_settings = JSON.parse(limits_settings, :
|
178
|
+
limits_settings = JSON.parse(limits_settings, allow_nan: true, create_additions: true)
|
179
179
|
enabled = limits_settings['enabled']
|
180
180
|
persistence = limits_settings['persistence_setting']
|
181
181
|
limits_settings.each do |limits_set, settings|
|
@@ -199,7 +199,7 @@ module OpenC3
|
|
199
199
|
telemetry = System.telemetry.all
|
200
200
|
topics = ["#{scope}__openc3_limits_events"]
|
201
201
|
Topic.read_topics(topics, nil, block_ms) do |_topic, _msg_id, event, _redis|
|
202
|
-
event = JSON.parse(event['event'], :
|
202
|
+
event = JSON.parse(event['event'], allow_nan: true, create_additions: true)
|
203
203
|
case event['type']
|
204
204
|
when 'LIMITS_CHANGE'
|
205
205
|
# Ignore
|
@@ -24,6 +24,8 @@ require 'openc3/topics/topic'
|
|
24
24
|
|
25
25
|
module OpenC3
|
26
26
|
class RouterTopic < Topic
|
27
|
+
COMMAND_ACK_TIMEOUT_S = 30
|
28
|
+
|
27
29
|
# Generate a list of topics for this router. This includes the router itself
|
28
30
|
# and all the targets which are assigned to this router.
|
29
31
|
def self.topics(router, scope:)
|
@@ -41,11 +43,11 @@ module OpenC3
|
|
41
43
|
while true
|
42
44
|
Topic.read_topics(RouterTopic.topics(router, scope: scope)) do |topic, msg_id, msg_hash, redis|
|
43
45
|
result = yield topic, msg_id, msg_hash, redis
|
44
|
-
if /CMD}ROUTER/.match?(topic)
|
46
|
+
if result and /CMD}ROUTER/.match?(topic)
|
45
47
|
ack_topic = topic.split("__")
|
46
48
|
ack_topic[1] = 'ACK' + ack_topic[1]
|
47
49
|
ack_topic = ack_topic.join("__")
|
48
|
-
Topic.write_topic(ack_topic, { 'result' => result }, msg_id, 100)
|
50
|
+
Topic.write_topic(ack_topic, { 'result' => result, 'id' => msg_id }, msg_id, 100)
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
@@ -65,7 +67,7 @@ module OpenC3
|
|
65
67
|
|
66
68
|
def self.connect_router(router_name, *router_params, scope:)
|
67
69
|
if router_params && !router_params.empty?
|
68
|
-
Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'connect' => 'true', 'params' => JSON.generate(router_params) }, '*', 100)
|
70
|
+
Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'connect' => 'true', 'params' => JSON.generate(router_params, allow_nan: true) }, '*', 100)
|
69
71
|
else
|
70
72
|
Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'connect' => 'true' }, '*', 100)
|
71
73
|
end
|
@@ -102,5 +104,42 @@ module OpenC3
|
|
102
104
|
data['index'] = index
|
103
105
|
Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'protocol_cmd' => JSON.generate(data, allow_nan: true) }, '*', 100)
|
104
106
|
end
|
107
|
+
|
108
|
+
def self.router_target_enable(router_name, target_name, cmd_only: false, tlm_only: false, scope:)
|
109
|
+
data = {}
|
110
|
+
data['target_name'] = target_name.to_s.upcase
|
111
|
+
data['cmd_only'] = cmd_only
|
112
|
+
data['tlm_only'] = tlm_only
|
113
|
+
data['action'] = 'enable'
|
114
|
+
Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'target_control' => JSON.generate(data, allow_nan: true) }, '*', 100)
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.router_target_disable(router_name, target_name, cmd_only: false, tlm_only: false, scope:)
|
118
|
+
data = {}
|
119
|
+
data['target_name'] = target_name.to_s.upcase
|
120
|
+
data['cmd_only'] = cmd_only
|
121
|
+
data['tlm_only'] = tlm_only
|
122
|
+
data['action'] = 'disable'
|
123
|
+
Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'target_control' => JSON.generate(data, allow_nan: true) }, '*', 100)
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.router_details(router_name, timeout: nil, scope:)
|
127
|
+
router_name = router_name.upcase
|
128
|
+
|
129
|
+
timeout = COMMAND_ACK_TIMEOUT_S unless timeout
|
130
|
+
ack_topic = "{#{scope}__ACKCMD}ROUTER__#{router_name}"
|
131
|
+
Topic.update_topic_offsets([ack_topic])
|
132
|
+
|
133
|
+
cmd_id = Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'router_details' => 'true' }, '*', 100)
|
134
|
+
time = Time.now
|
135
|
+
while (Time.now - time) < timeout
|
136
|
+
Topic.read_topics([ack_topic]) do |_topic, _msg_id, msg_hash, _redis|
|
137
|
+
if msg_hash["id"] == cmd_id
|
138
|
+
return JSON.parse(msg_hash["result"], :allow_nan => true, :create_additions => true)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
raise "Timeout of #{timeout}s waiting for cmd ack"
|
143
|
+
end
|
105
144
|
end
|
106
145
|
end
|
@@ -28,7 +28,7 @@ module OpenC3
|
|
28
28
|
|
29
29
|
def self.write(type, event)
|
30
30
|
event['type'] = type
|
31
|
-
Topic.write_topic(PRIMARY_KEY, {event: JSON.generate(event)}, '*', 1000)
|
31
|
+
Topic.write_topic(PRIMARY_KEY, {event: JSON.generate(event, allow_nan: true)}, '*', 1000)
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.read()
|
@@ -42,7 +42,7 @@ module OpenC3
|
|
42
42
|
:target_name => packet.target_name,
|
43
43
|
:packet_name => packet.packet_name,
|
44
44
|
:received_count => packet.received_count,
|
45
|
-
:json_data => JSON.generate(json_hash.as_json
|
45
|
+
:json_data => JSON.generate(json_hash.as_json, allow_nan: true),
|
46
46
|
}
|
47
47
|
Topic.write_topic("#{scope}__DECOM__{#{packet.target_name}}__#{packet.packet_name}", msg_hash, id)
|
48
48
|
|
@@ -161,7 +161,7 @@ module OpenC3
|
|
161
161
|
@log[1] = "response status: #{resp.status} header: #{resp.headers} body: #{resp.body}"
|
162
162
|
STDOUT.puts @log[1] if JsonDRb.debug?
|
163
163
|
if resp.status >= 200 && resp.status <= 299
|
164
|
-
return JSON.parse(resp.body, :
|
164
|
+
return JSON.parse(resp.body, allow_nan: true, create_additions: true)
|
165
165
|
elsif resp.status >= 500 && resp.status <= 599
|
166
166
|
raise OpenC3AuthenticationRetryableError, "authentication request retryable #{@log[0]} ::: #{@log[1]}"
|
167
167
|
else
|
@@ -50,11 +50,10 @@ module OpenC3
|
|
50
50
|
other[:exception_backtrace] = payload[:exception_object].backtrace.as_json
|
51
51
|
end
|
52
52
|
end
|
53
|
-
# This happens for a separate exception log entry which we want to not include the backtrace a second time
|
54
53
|
if log.exception
|
55
|
-
message = "Exception was raised - #{log.exception.class}:#{log.exception.message}" unless message
|
54
|
+
message = "Exception was raised - #{log.exception.class}:#{log.exception.message}:#{log.exception.backtrace.join(":")}" unless message
|
56
55
|
end
|
57
|
-
return OpenC3::Logger.build_log_data(log.level.to_s.upcase, message, user: username, type: OpenC3::Logger::LOG, url: nil, other: other).as_json(
|
56
|
+
return OpenC3::Logger.build_log_data(log.level.to_s.upcase, message, user: username, type: OpenC3::Logger::LOG, url: nil, other: other).as_json().to_json(allow_nan: true)
|
58
57
|
end
|
59
58
|
end
|
60
59
|
end
|
@@ -170,7 +170,7 @@ module OpenC3
|
|
170
170
|
if gem_name == local_gem_name
|
171
171
|
# Gems match - Do the names match?
|
172
172
|
data = File.read(plugin_instance)
|
173
|
-
json = JSON.parse(data, :
|
173
|
+
json = JSON.parse(data, allow_nan: true, create_additions: true)
|
174
174
|
|
175
175
|
found = false
|
176
176
|
found_models.each do |name, _model_details|
|
@@ -221,7 +221,7 @@ module OpenC3
|
|
221
221
|
if plugin_file_path =~ Regexp.new("^#{OPENC3_LOCAL_MODE_PATH}/#{scope}/")
|
222
222
|
# From local init - Always just update the exact one
|
223
223
|
File.open(File.join(File.dirname(plugin_file_path), 'plugin_instance.json'), 'wb') do |file|
|
224
|
-
file.write(JSON.pretty_generate(plugin_hash, :
|
224
|
+
file.write(JSON.pretty_generate(plugin_hash, allow_nan: true))
|
225
225
|
end
|
226
226
|
else
|
227
227
|
# From online install / update
|
@@ -247,7 +247,7 @@ module OpenC3
|
|
247
247
|
if old_plugin_name
|
248
248
|
# And we're updating a plugin
|
249
249
|
data = File.read(plugin_instance)
|
250
|
-
json = JSON.parse(data, :
|
250
|
+
json = JSON.parse(data, allow_nan: true, create_additions: true)
|
251
251
|
if json["name"] == old_plugin_name
|
252
252
|
# Found plugin to update
|
253
253
|
found = true
|
@@ -301,7 +301,7 @@ module OpenC3
|
|
301
301
|
file.write(data)
|
302
302
|
end
|
303
303
|
File.open(File.join(full_folder_path, 'plugin_instance.json'), 'wb') do |file|
|
304
|
-
file.write(JSON.pretty_generate(plugin_hash, :
|
304
|
+
file.write(JSON.pretty_generate(plugin_hash, allow_nan: true))
|
305
305
|
end
|
306
306
|
ensure
|
307
307
|
FileUtils.remove_entry_secure(temp_dir, true)
|
@@ -317,7 +317,7 @@ module OpenC3
|
|
317
317
|
plugin_instance = details[:plugin_instance]
|
318
318
|
if gems.length == 1 and plugin_instance
|
319
319
|
data = File.read(plugin_instance)
|
320
|
-
json = JSON.parse(data, :
|
320
|
+
json = JSON.parse(data, allow_nan: true, create_additions: true)
|
321
321
|
instance_name = json['name']
|
322
322
|
if plugin_name == instance_name
|
323
323
|
puts "Removing local plugin files: #{full_folder_path}"
|
@@ -443,7 +443,7 @@ module OpenC3
|
|
443
443
|
data = File.read(config)
|
444
444
|
begin
|
445
445
|
# Parse just to ensure we have valid JSON
|
446
|
-
JSON.parse(data, :
|
446
|
+
JSON.parse(data, allow_nan: true, create_additions: true)
|
447
447
|
# Only save if the parse was successful
|
448
448
|
ToolConfigModel.save_config(parts[-2], File.basename(config, '.json'), data, scope: scope, local_mode: false)
|
449
449
|
rescue JSON::ParserError => e
|
@@ -454,12 +454,12 @@ module OpenC3
|
|
454
454
|
end
|
455
455
|
|
456
456
|
def self.save_tool_config(scope, tool, name, data)
|
457
|
-
json = JSON.parse(data, :
|
457
|
+
json = JSON.parse(data, allow_nan: true, create_additions: true)
|
458
458
|
config_path = "#{OPENC3_LOCAL_MODE_PATH}/#{scope}/tool_config/#{tool}/#{name}.json"
|
459
459
|
return unless File.expand_path(config_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
460
460
|
FileUtils.mkdir_p(File.dirname(config_path))
|
461
461
|
File.open(config_path, 'w') do |file|
|
462
|
-
file.write(JSON.pretty_generate(json, :
|
462
|
+
file.write(JSON.pretty_generate(json, allow_nan: true))
|
463
463
|
end
|
464
464
|
end
|
465
465
|
|
@@ -204,14 +204,14 @@ module OpenC3
|
|
204
204
|
case log_level
|
205
205
|
when WARN_LEVEL, ERROR_LEVEL, FATAL_LEVEL
|
206
206
|
if ENV['OPENC3_LOG_STDERR']
|
207
|
-
$stderr.puts data.as_json(
|
207
|
+
$stderr.puts data.as_json().to_json(allow_nan: true)
|
208
208
|
$stderr.flush
|
209
209
|
else
|
210
|
-
$stdout.puts data.as_json(
|
210
|
+
$stdout.puts data.as_json().to_json(allow_nan: true)
|
211
211
|
$stdout.flush
|
212
212
|
end
|
213
213
|
else
|
214
|
-
$stdout.puts data.as_json(
|
214
|
+
$stdout.puts data.as_json().to_json(allow_nan: true)
|
215
215
|
$stdout.flush
|
216
216
|
end
|
217
217
|
end
|
@@ -51,13 +51,13 @@ SCRIPT_API = 'script-api'
|
|
51
51
|
|
52
52
|
def running_script_publish(channel_name, data)
|
53
53
|
stream_name = [SCRIPT_API, channel_name].compact.join(":")
|
54
|
-
OpenC3::Store.publish(stream_name, JSON.generate(data))
|
54
|
+
OpenC3::Store.publish(stream_name, JSON.generate(data, allow_nan: true))
|
55
55
|
end
|
56
56
|
|
57
57
|
def running_script_anycable_publish(channel_name, data)
|
58
58
|
stream_name = [SCRIPT_API, channel_name].compact.join(":")
|
59
|
-
stream_data = {"stream" => stream_name, "data" => JSON.generate(data)}
|
60
|
-
OpenC3::Store.publish("__anycable__", JSON.generate(stream_data))
|
59
|
+
stream_data = {"stream" => stream_name, "data" => JSON.generate(data, allow_nan: true)}
|
60
|
+
OpenC3::Store.publish("__anycable__", JSON.generate(stream_data, allow_nan: true))
|
61
61
|
end
|
62
62
|
|
63
63
|
module OpenC3
|
@@ -458,8 +458,8 @@ class RunningScript
|
|
458
458
|
start_time: start_time, # Time the script started ISO format
|
459
459
|
end_time: nil, # Time the script ended ISO format
|
460
460
|
disconnect: disconnect, # Disconnect is set to true if the script is running in a disconnected mode
|
461
|
-
environment: status_environment
|
462
|
-
suite_runner: suite_runner ? suite_runner
|
461
|
+
environment: status_environment, # hash of environment variables set for the script
|
462
|
+
suite_runner: suite_runner ? suite_runner : nil, # current suite information if any
|
463
463
|
errors: nil, # array of errors that occurred during the script run
|
464
464
|
pid: nil, # pid of the script process - set by the script itself when it starts
|
465
465
|
script_engine: script_engine, # script engine filename
|
@@ -770,7 +770,6 @@ class RunningScript
|
|
770
770
|
|
771
771
|
def run
|
772
772
|
if @script_status.suite_runner
|
773
|
-
@script_status.suite_runner = JSON.parse(@script_status.suite_runner, :allow_nan => true, :create_additions => true) # Convert to hash
|
774
773
|
if @script_status.suite_runner['options']
|
775
774
|
parse_options(@script_status.suite_runner['options'])
|
776
775
|
else
|
@@ -1050,7 +1049,7 @@ class RunningScript
|
|
1050
1049
|
line_count = 0
|
1051
1050
|
string.each_line(chomp: true) do |out_line|
|
1052
1051
|
begin
|
1053
|
-
json = JSON.parse(out_line, :
|
1052
|
+
json = JSON.parse(out_line, allow_nan: true, create_additions: true)
|
1054
1053
|
time_formatted = Time.parse(json["@timestamp"]).sys.formatted if json["@timestamp"]
|
1055
1054
|
if json["log"]
|
1056
1055
|
out_line = json["log"]
|
@@ -1082,7 +1081,7 @@ class RunningScript
|
|
1082
1081
|
else
|
1083
1082
|
published_lines = lines_to_write
|
1084
1083
|
end
|
1085
|
-
running_script_anycable_publish("running-script-channel:#{@script_status.id}", { type: :output, line: published_lines.as_json(
|
1084
|
+
running_script_anycable_publish("running-script-channel:#{@script_status.id}", { type: :output, line: published_lines.as_json(), color: color })
|
1086
1085
|
# Add to the message log
|
1087
1086
|
message_log.write(lines_to_write)
|
1088
1087
|
end
|
data/lib/openc3/version.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
OPENC3_VERSION = '6.
|
3
|
+
OPENC3_VERSION = '6.9.1'
|
4
4
|
module OpenC3
|
5
5
|
module Version
|
6
6
|
MAJOR = '6'
|
7
|
-
MINOR = '
|
7
|
+
MINOR = '9'
|
8
8
|
PATCH = '1'
|
9
9
|
OTHER = ''
|
10
|
-
BUILD = '
|
10
|
+
BUILD = 'e1529f7b88799a9f85f31378db40a48b6c106899'
|
11
11
|
end
|
12
|
-
VERSION = '6.
|
13
|
-
GEM_VERSION = '6.
|
12
|
+
VERSION = '6.9.1'
|
13
|
+
GEM_VERSION = '6.9.1'
|
14
14
|
end
|
data/templates/plugin/README.md
CHANGED
@@ -15,9 +15,9 @@ Update this comment with your own description.
|
|
15
15
|
- VERSION is required
|
16
16
|
- gem file will be built locally
|
17
17
|
|
18
|
-
## Building tool / widget plugins using a local Ruby/Node/
|
18
|
+
## Building tool / widget plugins using a local Ruby/Node/pnpm/Rake Environment
|
19
19
|
|
20
|
-
1.
|
20
|
+
1. pnpm install --frozen-lockfile --ignore-scripts
|
21
21
|
1. rake build VERSION=1.0.0
|
22
22
|
|
23
23
|
## Building tool / widget plugins using Docker and the openc3-node container
|
@@ -36,7 +36,7 @@ Windows:
|
|
36
36
|
docker run -it -v %cd%:/openc3/local -w /openc3/local docker.io/openc3inc/openc3-node sh
|
37
37
|
```
|
38
38
|
|
39
|
-
1.
|
39
|
+
1. pnpm install --frozen-lockfile --ignore-scripts
|
40
40
|
1. rake build VERSION=1.0.0
|
41
41
|
|
42
42
|
## Installing into OpenC3 COSMOS
|