openc3 6.8.1 → 6.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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 +11 -1
- 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_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 +1 -1
- 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 +2 -2
- 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 +8 -8
- data/lib/openc3/version.rb +6 -6
- 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
@@ -88,7 +88,7 @@ module OpenC3
|
|
88
88
|
if r.nil?
|
89
89
|
nil
|
90
90
|
else
|
91
|
-
JSON.parse(r, :
|
91
|
+
JSON.parse(r, allow_nan: true, create_additions: true)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
return result
|
@@ -113,7 +113,7 @@ module OpenC3
|
|
113
113
|
if r.nil?
|
114
114
|
nil
|
115
115
|
else
|
116
|
-
JSON.parse(r, :
|
116
|
+
JSON.parse(r, allow_nan: true, create_additions: true)
|
117
117
|
end
|
118
118
|
end
|
119
119
|
return result
|
@@ -204,7 +204,7 @@ module OpenC3
|
|
204
204
|
else
|
205
205
|
write_store = self.class.store
|
206
206
|
end
|
207
|
-
write_store.hset(@primary_key, @name, JSON.generate(self.as_json(
|
207
|
+
write_store.hset(@primary_key, @name, JSON.generate(self.as_json(), allow_nan: true))
|
208
208
|
|
209
209
|
# Also add to ordered set on create
|
210
210
|
write_store.zadd(@primary_key + "__LIST", @name.to_i, @name) if not update
|
@@ -50,14 +50,14 @@ module OpenC3
|
|
50
50
|
# @return [String|nil] String of the saved json or nil if start not found
|
51
51
|
def self.get(start:, scope:)
|
52
52
|
result = Store.zrangebyscore(self.pk(scope), start, start)
|
53
|
-
return JSON.parse(result[0], :
|
53
|
+
return JSON.parse(result[0], allow_nan: true, create_additions: true) unless result.empty?
|
54
54
|
nil
|
55
55
|
end
|
56
56
|
|
57
57
|
# @return [Array<Hash>] Array up to the limit of the models (as Hash objects) stored under the primary key
|
58
58
|
def self.all(scope:, limit: 100)
|
59
59
|
result = Store.zrevrangebyscore(self.pk(scope), '+inf', '-inf', limit: [0, limit])
|
60
|
-
return result.map { |item| JSON.parse(item, :
|
60
|
+
return result.map { |item| JSON.parse(item, allow_nan: true, create_additions: true) }
|
61
61
|
end
|
62
62
|
|
63
63
|
# @return [String|nil] json or nil if metadata empty
|
@@ -76,7 +76,7 @@ module OpenC3
|
|
76
76
|
raise SortedInputError.new "start: #{start} must be before stop: #{stop}"
|
77
77
|
end
|
78
78
|
result = Store.zrangebyscore(self.pk(scope), start, stop, limit: [0, limit])
|
79
|
-
return result.map { |item| JSON.parse(item, :
|
79
|
+
return result.map { |item| JSON.parse(item, allow_nan: true, create_additions: true) }
|
80
80
|
end
|
81
81
|
|
82
82
|
# @return [Integer] count of the members stored under the primary key
|
@@ -132,7 +132,7 @@ module OpenC3
|
|
132
132
|
validate_start(update: update)
|
133
133
|
@updated_at = Time.now.to_nsec_from_epoch
|
134
134
|
SortedModel.destroy(scope: @scope, start: update) if update
|
135
|
-
Store.zadd(@primary_key, @start, JSON.generate(as_json
|
135
|
+
Store.zadd(@primary_key, @start, JSON.generate(as_json, allow_nan: true))
|
136
136
|
if update
|
137
137
|
notify(kind: 'updated')
|
138
138
|
else
|
@@ -156,7 +156,7 @@ module OpenC3
|
|
156
156
|
# @return [] update the redis stream / timeline topic that something has changed
|
157
157
|
def notify(kind:, extra: nil)
|
158
158
|
notification = {
|
159
|
-
'data' => JSON.generate(as_json
|
159
|
+
'data' => JSON.generate(as_json, allow_nan: true),
|
160
160
|
'kind' => kind,
|
161
161
|
'type' => 'calendar',
|
162
162
|
}
|
@@ -207,7 +207,7 @@ module OpenC3
|
|
207
207
|
json = Store.hget("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name)
|
208
208
|
raise "Packet '#{target_name} #{packet_name}' does not exist" if json.nil?
|
209
209
|
|
210
|
-
JSON.parse(json, :
|
210
|
+
JSON.parse(json, allow_nan: true, create_additions: true)
|
211
211
|
end
|
212
212
|
|
213
213
|
# @return [Array<Hash>] All packet hashes under the target_name
|
@@ -218,7 +218,7 @@ module OpenC3
|
|
218
218
|
result = []
|
219
219
|
packets = Store.hgetall("#{scope}__openc3#{type.to_s.downcase}__#{target_name}")
|
220
220
|
packets.sort.each do |_packet_name, packet_json|
|
221
|
-
result << JSON.parse(packet_json, :
|
221
|
+
result << JSON.parse(packet_json, allow_nan: true, create_additions: true)
|
222
222
|
end
|
223
223
|
result
|
224
224
|
end
|
@@ -232,7 +232,7 @@ module OpenC3
|
|
232
232
|
raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
|
233
233
|
|
234
234
|
begin
|
235
|
-
Store.hset("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name, JSON.generate(packet.as_json
|
235
|
+
Store.hset("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name, JSON.generate(packet.as_json, allow_nan: true))
|
236
236
|
rescue JSON::GeneratorError => e
|
237
237
|
Logger.error("Invalid text present in #{target_name} #{packet_name} #{type.to_s.downcase} packet")
|
238
238
|
raise e
|
@@ -289,7 +289,7 @@ module OpenC3
|
|
289
289
|
def self.limits_groups(scope:)
|
290
290
|
groups = Store.hgetall("#{scope}__limits_groups")
|
291
291
|
if groups
|
292
|
-
groups.map { |group, items| [group, JSON.parse(items, :
|
292
|
+
groups.map { |group, items| [group, JSON.parse(items, allow_nan: true, create_additions: true)] }.to_h
|
293
293
|
else
|
294
294
|
{}
|
295
295
|
end
|
@@ -302,10 +302,10 @@ module OpenC3
|
|
302
302
|
target_name = target_name.upcase
|
303
303
|
json_data = Store.get(item_map_key)
|
304
304
|
if json_data
|
305
|
-
item_map = JSON.parse(json_data, :
|
305
|
+
item_map = JSON.parse(json_data, allow_nan: true, create_additions: true)
|
306
306
|
else
|
307
307
|
item_map = build_item_to_packet_map(target_name, scope: scope)
|
308
|
-
Store.set(item_map_key, JSON.generate(item_map, :
|
308
|
+
Store.set(item_map_key, JSON.generate(item_map, allow_nan: true))
|
309
309
|
end
|
310
310
|
@@item_map_cache[target_name] = [Time.now, item_map]
|
311
311
|
return item_map
|
@@ -462,7 +462,7 @@ module OpenC3
|
|
462
462
|
'reduced_day_log_retain_time' => @reduced_day_log_retain_time,
|
463
463
|
'cleanup_poll_time' => @cleanup_poll_time,
|
464
464
|
'needs_dependencies' => @needs_dependencies,
|
465
|
-
'target_microservices' => @target_microservices.as_json(
|
465
|
+
'target_microservices' => @target_microservices.as_json(),
|
466
466
|
'reducer_disable' => @reducer_disable,
|
467
467
|
'reducer_max_cpu_utilization' => @reducer_max_cpu_utilization,
|
468
468
|
'disable_erb' => @disable_erb,
|
@@ -802,7 +802,7 @@ module OpenC3
|
|
802
802
|
packets.each do |packet_name, packet|
|
803
803
|
Logger.debug "Configuring tlm packet: #{target_name} #{packet_name}"
|
804
804
|
begin
|
805
|
-
Store.hset("#{@scope}__openc3tlm__#{target_name}", packet_name, JSON.generate(packet.as_json
|
805
|
+
Store.hset("#{@scope}__openc3tlm__#{target_name}", packet_name, JSON.generate(packet.as_json, allow_nan: true))
|
806
806
|
rescue JSON::GeneratorError => e
|
807
807
|
Logger.error("Invalid text present in #{target_name} #{packet_name} tlm packet")
|
808
808
|
raise e
|
@@ -826,7 +826,7 @@ module OpenC3
|
|
826
826
|
packets.each do |packet_name, packet|
|
827
827
|
Logger.debug "Configuring cmd packet: #{target_name} #{packet_name}"
|
828
828
|
begin
|
829
|
-
Store.hset("#{@scope}__openc3cmd__#{target_name}", packet_name, JSON.generate(packet.as_json
|
829
|
+
Store.hset("#{@scope}__openc3cmd__#{target_name}", packet_name, JSON.generate(packet.as_json, allow_nan: true))
|
830
830
|
rescue JSON::GeneratorError => e
|
831
831
|
Logger.error("Invalid text present in #{target_name} #{packet_name} cmd packet")
|
832
832
|
raise e
|
@@ -838,7 +838,7 @@ module OpenC3
|
|
838
838
|
def update_store_limits_groups(system)
|
839
839
|
system.limits.groups.each do |group, items|
|
840
840
|
begin
|
841
|
-
Store.hset("#{@scope}__limits_groups", group, JSON.generate(items))
|
841
|
+
Store.hset("#{@scope}__limits_groups", group, JSON.generate(items, allow_nan: true))
|
842
842
|
rescue JSON::GeneratorError => e
|
843
843
|
Logger.error("Invalid text present in #{group} limits group")
|
844
844
|
raise e
|
@@ -859,7 +859,7 @@ module OpenC3
|
|
859
859
|
# Create item_map
|
860
860
|
item_map_key = "#{@scope}__#{@name}__item_to_packet_map"
|
861
861
|
item_map = self.class.build_item_to_packet_map(@name, scope: @scope)
|
862
|
-
Store.set(item_map_key, JSON.generate(item_map, :
|
862
|
+
Store.set(item_map_key, JSON.generate(item_map, allow_nan: true))
|
863
863
|
@@item_map_cache[@name] = [Time.now, item_map]
|
864
864
|
end
|
865
865
|
|
@@ -72,7 +72,7 @@ module OpenC3
|
|
72
72
|
|
73
73
|
# @return [TimelineModel] Model generated from the passed JSON
|
74
74
|
def self.from_json(json, name:, scope:)
|
75
|
-
json = JSON.parse(json, :
|
75
|
+
json = JSON.parse(json, allow_nan: true, create_additions: true) if String === json
|
76
76
|
raise "json data is nil" if json.nil?
|
77
77
|
self.new(**json.transform_keys(&:to_sym), name: name, scope: scope)
|
78
78
|
end
|
@@ -120,7 +120,7 @@ module OpenC3
|
|
120
120
|
# @return [] update the redis stream / timeline topic that something has changed
|
121
121
|
def notify(kind:)
|
122
122
|
notification = {
|
123
|
-
'data' => JSON.generate(as_json
|
123
|
+
'data' => JSON.generate(as_json, allow_nan: true),
|
124
124
|
'kind' => kind,
|
125
125
|
'type' => 'timeline',
|
126
126
|
'timeline' => @timeline_name
|
@@ -298,7 +298,7 @@ module OpenC3
|
|
298
298
|
def self.unordered_all(scope: nil)
|
299
299
|
tools = Store.hgetall("#{scope}__#{PRIMARY_KEY}")
|
300
300
|
tools.each do |key, value|
|
301
|
-
tools[key] = JSON.parse(value, :
|
301
|
+
tools[key] = JSON.parse(value, allow_nan: true, create_additions: true)
|
302
302
|
end
|
303
303
|
return tools
|
304
304
|
end
|
@@ -101,19 +101,19 @@ module OpenC3
|
|
101
101
|
|
102
102
|
# @return [TriggerGroupModel] Model generated from the passed JSON
|
103
103
|
def self.from_json(json, name:, scope:)
|
104
|
-
json = JSON.parse(json, :
|
104
|
+
json = JSON.parse(json, allow_nan: true, create_additions: true) if String === json
|
105
105
|
raise "json data is nil" if json.nil?
|
106
106
|
self.new(**json.transform_keys(&:to_sym), name: name, scope: scope)
|
107
107
|
end
|
108
108
|
|
109
109
|
# @return [] update the redis stream / trigger topic that something has changed
|
110
110
|
def notify(kind:, error: nil)
|
111
|
-
data = as_json(
|
111
|
+
data = as_json()
|
112
112
|
data['error'] = error unless error.nil?
|
113
113
|
notification = {
|
114
114
|
'kind' => kind,
|
115
115
|
'type' => 'group',
|
116
|
-
'data' => JSON.generate(data),
|
116
|
+
'data' => JSON.generate(data, allow_nan: true),
|
117
117
|
}
|
118
118
|
AutonomicTopic.write_notification(notification, scope: @scope)
|
119
119
|
end
|
@@ -200,21 +200,21 @@ module OpenC3
|
|
200
200
|
end
|
201
201
|
verify_triggers()
|
202
202
|
@updated_at = Time.now.to_nsec_from_epoch
|
203
|
-
Store.hset(@primary_key, @name, JSON.generate(as_json
|
203
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json, allow_nan: true))
|
204
204
|
notify(kind: 'created')
|
205
205
|
end
|
206
206
|
|
207
207
|
def update
|
208
208
|
verify_triggers()
|
209
209
|
@updated_at = Time.now.to_nsec_from_epoch
|
210
|
-
Store.hset(@primary_key, @name, JSON.generate(as_json
|
210
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json, allow_nan: true))
|
211
211
|
# No notification as this is only called via trigger_controller which already notifies
|
212
212
|
end
|
213
213
|
|
214
214
|
def state=(value)
|
215
215
|
@state = value
|
216
216
|
@updated_at = Time.now.to_nsec_from_epoch
|
217
|
-
Store.hset(@primary_key, @name, JSON.generate(as_json
|
217
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json, allow_nan: true))
|
218
218
|
notify(kind: @state.to_s)
|
219
219
|
end
|
220
220
|
|
@@ -232,7 +232,7 @@ module OpenC3
|
|
232
232
|
def disable
|
233
233
|
notify_disable()
|
234
234
|
@updated_at = Time.now.to_nsec_from_epoch
|
235
|
-
Store.hset(@primary_key, @name, JSON.generate(as_json
|
235
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json, allow_nan: true))
|
236
236
|
end
|
237
237
|
|
238
238
|
# ["#{@scope}__DECOM__{#{@target}}__#{@packet}"]
|
@@ -278,7 +278,7 @@ module OpenC3
|
|
278
278
|
|
279
279
|
# @return [TriggerModel] Model generated from the passed JSON
|
280
280
|
def self.from_json(json, name:, scope:)
|
281
|
-
json = JSON.parse(json, :
|
281
|
+
json = JSON.parse(json, allow_nan: true, create_additions: true) if String === json
|
282
282
|
raise "json data is nil" if json.nil?
|
283
283
|
self.new(**json.transform_keys(&:to_sym), name: name, scope: scope)
|
284
284
|
end
|
@@ -288,7 +288,7 @@ module OpenC3
|
|
288
288
|
notification = {
|
289
289
|
'kind' => kind,
|
290
290
|
'type' => 'trigger',
|
291
|
-
'data' => JSON.generate(as_json
|
291
|
+
'data' => JSON.generate(as_json, allow_nan: true),
|
292
292
|
}
|
293
293
|
AutonomicTopic.write_notification(notification, scope: @scope)
|
294
294
|
end
|
@@ -54,7 +54,7 @@ module OpenC3
|
|
54
54
|
def self.all(scope: nil)
|
55
55
|
tools = Store.hgetall("#{scope}__#{PRIMARY_KEY}")
|
56
56
|
tools.each do |key, value|
|
57
|
-
tools[key] = JSON.parse(value, :
|
57
|
+
tools[key] = JSON.parse(value, allow_nan: true, create_additions: true)
|
58
58
|
end
|
59
59
|
return tools
|
60
60
|
end
|
@@ -196,13 +196,13 @@ module OpenC3
|
|
196
196
|
stdout = @process.io.stdout.extract
|
197
197
|
if stdout.length > 0
|
198
198
|
message = "STDOUT #{stdout.length} bytes from #{cmd_line()}:"
|
199
|
-
STDOUT.puts Logger.build_log_data(Logger::INFO_LEVEL, message, user: nil, type: OpenC3::Logger::LOG, url: nil).as_json(
|
199
|
+
STDOUT.puts Logger.build_log_data(Logger::INFO_LEVEL, message, user: nil, type: OpenC3::Logger::LOG, url: nil).as_json().to_json(allow_nan: true)
|
200
200
|
STDOUT.puts stdout
|
201
201
|
end
|
202
202
|
stderr = @process.io.stderr.extract
|
203
203
|
if stderr.length > 0
|
204
204
|
message = "STDERR #{stderr.length} bytes from #{cmd_line()}:"
|
205
|
-
STDERR.puts Logger.build_log_data(Logger::ERROR_LEVEL, message, user: nil, type: OpenC3::Logger::LOG, url: nil).as_json(
|
205
|
+
STDERR.puts Logger.build_log_data(Logger::ERROR_LEVEL, message, user: nil, type: OpenC3::Logger::LOG, url: nil).as_json().to_json(allow_nan: true)
|
206
206
|
STDERR.puts stderr
|
207
207
|
end
|
208
208
|
end
|
@@ -48,7 +48,7 @@ module OpenC3
|
|
48
48
|
end
|
49
49
|
@extra = extra
|
50
50
|
@json_hash = json_data
|
51
|
-
@json_hash = JSON.parse(json_data, :
|
51
|
+
@json_hash = JSON.parse(json_data, allow_nan: true, create_additions: true) if String === json_data
|
52
52
|
if key_map
|
53
53
|
uncompressed = {}
|
54
54
|
@json_hash.each do |key, value|
|
@@ -1054,7 +1054,7 @@ module OpenC3
|
|
1054
1054
|
end
|
1055
1055
|
end
|
1056
1056
|
packet.instance_variable_set("@read_conversion_cache".freeze, nil)
|
1057
|
-
packet.extra = JSON.parse(packet.extra.as_json(
|
1057
|
+
packet.extra = JSON.parse(packet.extra.as_json().to_json(allow_nan: true), allow_nan: true, create_additions: true) if packet.extra # Deep copy using JSON
|
1058
1058
|
packet
|
1059
1059
|
end
|
1060
1060
|
alias dup clone
|
@@ -98,10 +98,10 @@ module OpenC3
|
|
98
98
|
def _cal_handle_response(response, error_message)
|
99
99
|
return nil if response.nil?
|
100
100
|
if response.status >= 400
|
101
|
-
result = JSON.parse(response.body, :
|
101
|
+
result = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
102
102
|
raise "#{error_message} due to #{result['message']}"
|
103
103
|
end
|
104
|
-
return JSON.parse(response.body, :
|
104
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
@@ -36,7 +36,7 @@ module OpenC3
|
|
36
36
|
response = $api_server.request('get', "/openc3-api/metadata", query: { limit: limit }, scope: scope)
|
37
37
|
# Non-existent just returns nil
|
38
38
|
return nil if response.nil? || response.status != 200
|
39
|
-
return JSON.parse(response.body, :
|
39
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
40
40
|
end
|
41
41
|
alias all_metadata metadata_all
|
42
42
|
|
@@ -51,7 +51,7 @@ module OpenC3
|
|
51
51
|
end
|
52
52
|
# Non-existent just returns nil
|
53
53
|
return nil if response.nil? || response.status != 200
|
54
|
-
return JSON.parse(response.body, :
|
54
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
55
55
|
end
|
56
56
|
alias get_metadata metadata_get
|
57
57
|
|
@@ -76,7 +76,7 @@ module OpenC3
|
|
76
76
|
elsif response.status != 201
|
77
77
|
raise "Failed to set metadata due to #{response.status}"
|
78
78
|
end
|
79
|
-
return JSON.parse(response.body, :
|
79
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
80
80
|
end
|
81
81
|
alias set_metadata metadata_set
|
82
82
|
|
@@ -104,7 +104,7 @@ module OpenC3
|
|
104
104
|
if response.nil? || response.status != 200
|
105
105
|
raise "Failed to update metadata"
|
106
106
|
end
|
107
|
-
return JSON.parse(response.body, :
|
107
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
108
108
|
end
|
109
109
|
alias update_metadata metadata_update
|
110
110
|
|
data/lib/openc3/script/queue.rb
CHANGED
@@ -30,10 +30,10 @@ module OpenC3
|
|
30
30
|
if response.nil?
|
31
31
|
raise "Failed to #{action}. No response from server."
|
32
32
|
elsif response.status != 200 and response.status != 201
|
33
|
-
result = JSON.parse(response.body, :
|
33
|
+
result = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
34
34
|
raise "Failed to #{action} due to #{result['message']}"
|
35
35
|
end
|
36
|
-
return JSON.parse(response.body, :
|
36
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
37
37
|
end
|
38
38
|
|
39
39
|
def queue_all(scope: $openc3_scope)
|
@@ -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
|