openc3 6.8.0 → 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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/bin/openc3cli +10 -7
  4. data/data/config/command_modifiers.yaml +9 -1
  5. data/data/config/screen.yaml +1 -1
  6. data/lib/openc3/accessors/json_accessor.rb +5 -5
  7. data/lib/openc3/api/interface_api.rb +71 -4
  8. data/lib/openc3/api/router_api.rb +98 -8
  9. data/lib/openc3/api/stash_api.rb +3 -3
  10. data/lib/openc3/api/tlm_api.rb +1 -1
  11. data/lib/openc3/bridge/bridge_config.rb +1 -1
  12. data/lib/openc3/interfaces/file_interface.rb +18 -0
  13. data/lib/openc3/interfaces/http_client_interface.rb +11 -0
  14. data/lib/openc3/interfaces/http_server_interface.rb +8 -0
  15. data/lib/openc3/interfaces/interface.rb +90 -21
  16. data/lib/openc3/interfaces/mqtt_interface.rb +19 -0
  17. data/lib/openc3/interfaces/mqtt_stream_interface.rb +20 -0
  18. data/lib/openc3/interfaces/protocols/burst_protocol.rb +16 -0
  19. data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +18 -0
  20. data/lib/openc3/interfaces/protocols/crc_protocol.rb +19 -0
  21. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +17 -1
  22. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +14 -0
  23. data/lib/openc3/interfaces/protocols/length_protocol.rb +25 -1
  24. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +16 -3
  25. data/lib/openc3/interfaces/protocols/protocol.rb +79 -1
  26. data/lib/openc3/interfaces/protocols/slip_protocol.rb +23 -0
  27. data/lib/openc3/interfaces/protocols/template_protocol.rb +38 -0
  28. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +14 -1
  29. data/lib/openc3/interfaces/serial_interface.rb +14 -0
  30. data/lib/openc3/interfaces/simulated_target_interface.rb +1 -1
  31. data/lib/openc3/interfaces/tcpip_client_interface.rb +16 -2
  32. data/lib/openc3/interfaces/tcpip_server_interface.rb +11 -1
  33. data/lib/openc3/interfaces/udp_interface.rb +14 -0
  34. data/lib/openc3/io/json_api_object.rb +1 -1
  35. data/lib/openc3/io/json_drb.rb +1 -1
  36. data/lib/openc3/io/json_drb_object.rb +1 -1
  37. data/lib/openc3/io/json_rpc.rb +5 -4
  38. data/lib/openc3/logs/packet_log_reader.rb +1 -1
  39. data/lib/openc3/logs/packet_log_writer.rb +6 -6
  40. data/lib/openc3/microservices/decom_microservice.rb +5 -1
  41. data/lib/openc3/microservices/interface_microservice.rb +103 -38
  42. data/lib/openc3/microservices/microservice.rb +4 -4
  43. data/lib/openc3/microservices/queue_microservice.rb +11 -1
  44. data/lib/openc3/microservices/reducer_microservice.rb +1 -1
  45. data/lib/openc3/microservices/router_microservice.rb +28 -25
  46. data/lib/openc3/models/activity_model.rb +18 -17
  47. data/lib/openc3/models/cvt_model.rb +12 -9
  48. data/lib/openc3/models/interface_model.rb +70 -12
  49. data/lib/openc3/models/metadata_model.rb +2 -2
  50. data/lib/openc3/models/microservice_status_model.rb +2 -2
  51. data/lib/openc3/models/model.rb +4 -4
  52. data/lib/openc3/models/note_model.rb +2 -2
  53. data/lib/openc3/models/plugin_model.rb +9 -4
  54. data/lib/openc3/models/queue_model.rb +1 -1
  55. data/lib/openc3/models/reaction_model.rb +6 -6
  56. data/lib/openc3/models/script_engine_model.rb +1 -1
  57. data/lib/openc3/models/script_status_model.rb +3 -3
  58. data/lib/openc3/models/sorted_model.rb +5 -5
  59. data/lib/openc3/models/target_model.rb +11 -11
  60. data/lib/openc3/models/timeline_model.rb +2 -2
  61. data/lib/openc3/models/tool_model.rb +1 -1
  62. data/lib/openc3/models/trigger_group_model.rb +3 -3
  63. data/lib/openc3/models/trigger_model.rb +6 -6
  64. data/lib/openc3/models/widget_model.rb +1 -1
  65. data/lib/openc3/operators/operator.rb +2 -2
  66. data/lib/openc3/packets/json_packet.rb +1 -1
  67. data/lib/openc3/packets/packet.rb +1 -1
  68. data/lib/openc3/script/calendar.rb +2 -2
  69. data/lib/openc3/script/metadata.rb +4 -4
  70. data/lib/openc3/script/queue.rb +2 -2
  71. data/lib/openc3/script/script_runner.rb +9 -9
  72. data/lib/openc3/script/storage.rb +1 -1
  73. data/lib/openc3/script/tables.rb +2 -2
  74. data/lib/openc3/script/web_socket_api.rb +7 -7
  75. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +0 -12
  76. data/lib/openc3/tools/table_manager/table_manager_core.rb +1 -1
  77. data/lib/openc3/topics/command_decom_topic.rb +3 -3
  78. data/lib/openc3/topics/command_topic.rb +1 -1
  79. data/lib/openc3/topics/interface_topic.rb +45 -5
  80. data/lib/openc3/topics/limits_event_topic.rb +8 -8
  81. data/lib/openc3/topics/router_topic.rb +42 -3
  82. data/lib/openc3/topics/system_events_topic.rb +1 -1
  83. data/lib/openc3/topics/telemetry_decom_topic.rb +1 -1
  84. data/lib/openc3/utilities/authentication.rb +1 -1
  85. data/lib/openc3/utilities/cosmos_rails_formatter.rb +2 -3
  86. data/lib/openc3/utilities/local_mode.rb +8 -8
  87. data/lib/openc3/utilities/logger.rb +3 -3
  88. data/lib/openc3/utilities/running_script.rb +8 -8
  89. data/lib/openc3/version.rb +5 -5
  90. data/templates/plugin/README.md +3 -3
  91. data/templates/plugin/Rakefile +3 -3
  92. data/templates/plugin/plugin.gemspec +1 -0
  93. data/templates/tool_angular/.gitignore +1 -1
  94. data/templates/tool_angular/package.json +2 -48
  95. data/templates/tool_react/.gitignore +1 -2
  96. data/templates/tool_react/package.json +1 -51
  97. data/templates/tool_svelte/.gitignore +1 -2
  98. data/templates/tool_svelte/package.json +1 -49
  99. data/templates/tool_vue/package.json +3 -36
  100. data/templates/widget/Rakefile +1 -1
  101. data/templates/widget/package.json +2 -28
  102. metadata +9 -9
@@ -88,7 +88,7 @@ module OpenC3
88
88
  if r.nil?
89
89
  nil
90
90
  else
91
- JSON.parse(r, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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(:allow_nan => true), :allow_nan => true))
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], :allow_nan => true, :create_additions => true) unless result.empty?
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, :allow_nan => true, :create_additions => true) }
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, :allow_nan => true, :create_additions => true) }
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(:allow_nan => true)))
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(:allow_nan => true)),
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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(:allow_nan => true)))
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, :allow_nan => true, :create_additions => true)] }.to_h
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true))
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(:allow_nan => true),
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(:allow_nan => true)))
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(:allow_nan => true)))
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, :allow_nan => true))
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, :allow_nan => true, :create_additions => true) if String === 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(:allow_nan => true)),
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true) if String === 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(:allow_nan => true)
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(:allow_nan => true)))
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(:allow_nan => true)))
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(:allow_nan => true)))
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(:allow_nan => true)))
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, :allow_nan => true, :create_additions => true) if String === 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(:allow_nan => true)),
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, :allow_nan => true, :create_additions => true)
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(:allow_nan => true).to_json(:allow_nan => true)
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(:allow_nan => true).to_json(:allow_nan => true)
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, :allow_nan => true, :create_additions => true) if String === 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(:allow_nan => true).to_json(:allow_nan => true), :allow_nan => true, :create_additions => true) if packet.extra # Deep copy using 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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
107
+ return JSON.parse(response.body, allow_nan: true, create_additions: true)
108
108
  end
109
109
  alias update_metadata metadata_update
110
110
 
@@ -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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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'], :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)['items']
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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)['items']
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, :allow_nan => true, :create_additions => true)
202
+ JSON.parse(response.body, allow_nan: true, create_additions: true)
203
203
  end
204
204
  end
205
205
  end
@@ -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, :allow_nan => true, :create_additions => true)
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, :allow_nan => true, :create_additions => true)
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)
@@ -191,7 +191,7 @@ module OpenC3
191
191
  end
192
192
  end
193
193
  end
194
- json.as_json(:allow_nan => true)
194
+ json.as_json()
195
195
  end
196
196
 
197
197
  def self.load_binary(config, data)
@@ -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(:allow_nan => true))
43
- msg_hash['json_data'] = JSON.generate(json_hash.as_json(:allow_nan => true))
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, :allow_nan => true, :create_additions => true)
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(:allow_nan => true))
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
- ack_topic = topic.split("__")
46
- ack_topic[1] = 'ACK' + ack_topic[1]
47
- ack_topic = ack_topic.join("__")
48
- Topic.write_topic(ack_topic, { 'result' => result, 'id' => msg_id }, '*', 100)
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