openc3 5.13.0 → 5.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -3
- data/bin/openc3cli +18 -15
- data/data/config/command_modifiers.yaml +53 -1
- data/lib/openc3/accessors/accessor.rb +42 -29
- data/lib/openc3/accessors/binary_accessor.rb +11 -1
- data/lib/openc3/accessors/form_accessor.rb +11 -1
- data/lib/openc3/accessors/http_accessor.rb +38 -0
- data/lib/openc3/accessors/json_accessor.rb +15 -3
- data/lib/openc3/accessors/template_accessor.rb +150 -0
- data/lib/openc3/accessors/xml_accessor.rb +11 -1
- data/lib/openc3/accessors.rb +1 -0
- data/lib/openc3/api/limits_api.rb +3 -3
- data/lib/openc3/api/tlm_api.rb +8 -8
- data/lib/openc3/interfaces/interface.rb +9 -7
- data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +116 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +4 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +5 -0
- data/lib/openc3/interfaces.rb +1 -1
- data/lib/openc3/microservices/decom_microservice.rb +1 -0
- data/lib/openc3/microservices/interface_microservice.rb +10 -1
- data/lib/openc3/models/cvt_model.rb +16 -12
- data/lib/openc3/models/gem_model.rb +20 -3
- data/lib/openc3/models/microservice_model.rb +1 -1
- data/lib/openc3/models/plugin_model.rb +5 -1
- data/lib/openc3/models/target_model.rb +69 -8
- data/lib/openc3/packets/packet.rb +92 -4
- data/lib/openc3/packets/packet_config.rb +25 -1
- data/lib/openc3/script/api_shared.rb +11 -0
- data/lib/openc3/script/script.rb +6 -12
- data/lib/openc3/streams/tcpip_socket_stream.rb +19 -0
- data/lib/openc3/system/system.rb +13 -1
- data/lib/openc3/utilities/cli_generator.rb +15 -1
- data/lib/openc3/utilities/local_mode.rb +1 -1
- data/lib/openc3/utilities/store_queued.rb +126 -0
- data/lib/openc3/version.rb +5 -5
- data/templates/plugin/plugin.gemspec +2 -2
- data/templates/target/targets/TARGET/public/README.txt +1 -0
- data/templates/tool_angular/package.json +15 -15
- data/templates/tool_angular/yarn.lock +184 -78
- data/templates/tool_react/package.json +10 -10
- data/templates/tool_react/yarn.lock +236 -374
- data/templates/tool_svelte/package.json +13 -13
- data/templates/tool_svelte/yarn.lock +246 -235
- data/templates/tool_vue/package.json +12 -12
- data/templates/tool_vue/yarn.lock +63 -55
- data/templates/widget/package.json +11 -11
- data/templates/widget/yarn.lock +54 -46
- metadata +144 -154
- data/lib/openc3/io/openc3_snmp.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b009f636dd8566127001ad9ee48972d584fb03baaf88389646048e7231dc54b
|
4
|
+
data.tar.gz: 0ce2ff7aad089eba4794f4f15075bcf5e3087632f776eb76127c80af5256bda6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d87b341b985cca628485419b0406b449289364497e4061024d0407551920fc8f62529fb35897761a1ae471c838cf2ce38d706fcf84eea4960abdd24a7608af5
|
7
|
+
data.tar.gz: '0758dfda18babfc4c47f870efe074e5a6bbd371aee1ba2a362f3d851791f20c2f5955e7f144972198a461a314b0a2a334c02d8191c7387503c30a11d8bd53c50'
|
data/Gemfile
CHANGED
@@ -7,11 +7,11 @@ gem 'ruby-termios', '>= 0.9' if RbConfig::CONFIG['target_os'] !~ /mswin|mingw|cy
|
|
7
7
|
gemspec :name => 'openc3'
|
8
8
|
|
9
9
|
# Include the rails gems for the convenience of custom microservice plugins
|
10
|
-
gem 'rails', '~> 7.1.0'
|
11
10
|
gem 'bootsnap', '>= 1.9.3', require: false
|
11
|
+
gem 'mock_redis', '0.41'
|
12
12
|
gem 'rack-cors', '~> 2.0'
|
13
|
-
gem '
|
13
|
+
gem 'rails', '~> 7.1.0'
|
14
14
|
gem 'rspec-rails', '~> 6.0'
|
15
15
|
gem 'simplecov', '~> 0.20'
|
16
16
|
gem 'simplecov-cobertura', '~> 2.1'
|
17
|
-
gem '
|
17
|
+
gem 'tzinfo-data'
|
data/bin/openc3cli
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
# GNU Affero General Public License for more details.
|
16
16
|
|
17
17
|
# Modified by OpenC3, Inc.
|
18
|
-
# All changes Copyright
|
18
|
+
# All changes Copyright 2024, OpenC3, Inc.
|
19
19
|
# All Rights Reserved
|
20
20
|
#
|
21
21
|
# This file may also be used under the terms of a commercial license
|
@@ -232,7 +232,7 @@ def xtce_converter(args)
|
|
232
232
|
|
233
233
|
begin
|
234
234
|
option_parser.parse!(args)
|
235
|
-
rescue =>
|
235
|
+
rescue => e
|
236
236
|
abort(option_parser.to_s)
|
237
237
|
end
|
238
238
|
|
@@ -348,10 +348,13 @@ def update_plugin(plugin_file_path, plugin_name, variables: nil, plugin_txt_line
|
|
348
348
|
else
|
349
349
|
puts "No changes detected - Exiting without change"
|
350
350
|
end
|
351
|
-
rescue =>
|
352
|
-
puts
|
353
|
-
|
354
|
-
|
351
|
+
rescue => e
|
352
|
+
puts e.formatted
|
353
|
+
if plugin_model.destroyed?
|
354
|
+
plugin_model.restore
|
355
|
+
# Local mode files should still be good because restore will now reuse the old name
|
356
|
+
end
|
357
|
+
raise e
|
355
358
|
end
|
356
359
|
end
|
357
360
|
|
@@ -408,8 +411,8 @@ def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil, force: false)
|
|
408
411
|
scope_model = OpenC3::ScopeModel.new(name: scope, scope: scope)
|
409
412
|
scope_model.create
|
410
413
|
scope_model.deploy(".", {})
|
411
|
-
rescue =>
|
412
|
-
abort("Error creating scope: #{scope}: #{
|
414
|
+
rescue => e
|
415
|
+
abort("Error creating scope: #{scope}: #{e.formatted}")
|
413
416
|
end
|
414
417
|
end
|
415
418
|
|
@@ -467,8 +470,8 @@ def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil, force: false)
|
|
467
470
|
plugin_hash = OpenC3::PluginModel.install_phase2(plugin_hash, scope: scope)
|
468
471
|
OpenC3::LocalMode.update_local_plugin(plugin_file_path, plugin_hash, scope: scope)
|
469
472
|
end
|
470
|
-
rescue =>
|
471
|
-
abort("Error installing plugin: #{scope}: #{plugin_file_path}\n#{
|
473
|
+
rescue => e
|
474
|
+
abort("Error installing plugin: #{scope}: #{plugin_file_path}\n#{e.message}")
|
472
475
|
end
|
473
476
|
else
|
474
477
|
# Outside Cluster
|
@@ -496,8 +499,8 @@ def unload_plugin(plugin_name, scope:)
|
|
496
499
|
plugin_model.destroy
|
497
500
|
OpenC3::LocalMode.remove_local_plugin(plugin_name, scope: scope)
|
498
501
|
OpenC3::Logger.info("PluginModel destroyed: #{plugin_name}", scope: scope)
|
499
|
-
rescue =>
|
500
|
-
abort("Error uninstalling plugin: #{scope}: #{plugin_name}: #{
|
502
|
+
rescue => e
|
503
|
+
abort("Error uninstalling plugin: #{scope}: #{plugin_name}: #{e.formatted}")
|
501
504
|
end
|
502
505
|
else
|
503
506
|
# Outside Cluster
|
@@ -618,7 +621,7 @@ def run_bridge(filename, params)
|
|
618
621
|
raise "Invalid variable passed to bridgegem (syntax name=value): #{param}"
|
619
622
|
end
|
620
623
|
end
|
621
|
-
|
624
|
+
OpenC3::Bridge.new(filename, variables)
|
622
625
|
begin
|
623
626
|
while true
|
624
627
|
sleep(1)
|
@@ -731,7 +734,7 @@ if not ARGV[0].nil? # argument(s) given
|
|
731
734
|
when 'removebase'
|
732
735
|
# Used to remove tool base to better support enterprise upgrade
|
733
736
|
scopes = OpenC3::ScopeModel.all
|
734
|
-
scopes.each do |scope_name,
|
737
|
+
scopes.each do |scope_name, _scope|
|
735
738
|
plugins = OpenC3::PluginModel.all(scope: scope_name)
|
736
739
|
plugins.each do |plugin_name, plugin|
|
737
740
|
if plugin["name"] =~ /tool-base/ and plugin["name"] !~ /enterprise/
|
@@ -746,7 +749,7 @@ if not ARGV[0].nil? # argument(s) given
|
|
746
749
|
when 'removeenterprise'
|
747
750
|
# Used to remove enterprise plugins to better support downgrade
|
748
751
|
scopes = OpenC3::ScopeModel.all
|
749
|
-
scopes.each do |scope_name,
|
752
|
+
scopes.each do |scope_name, _scope|
|
750
753
|
plugins = OpenC3::PluginModel.all(scope: scope_name)
|
751
754
|
plugins.each do |plugin_name, plugin|
|
752
755
|
if plugin["name"] =~ /enterprise/
|
@@ -192,4 +192,56 @@ TEMPLATE_FILE:
|
|
192
192
|
required: true
|
193
193
|
description: The relative path to the template file. Filename should generally start with an underscore.
|
194
194
|
values: .+
|
195
|
-
since: 5.0.10
|
195
|
+
since: 5.0.10
|
196
|
+
RESPONSE:
|
197
|
+
summary: Indicates the expected telemetry packet response to this command
|
198
|
+
parameters:
|
199
|
+
- name: Target Name
|
200
|
+
required: true
|
201
|
+
description: Target Name of telemetry response packet
|
202
|
+
values: .+
|
203
|
+
- name: Packet Name
|
204
|
+
required: true
|
205
|
+
description: Packet Name of telemetry response packet
|
206
|
+
values: .+
|
207
|
+
since: 5.14.0
|
208
|
+
ERROR_RESPONSE:
|
209
|
+
summary: Indicates the expected telemetry packet error response to this command
|
210
|
+
parameters:
|
211
|
+
- name: Target Name
|
212
|
+
required: true
|
213
|
+
description: Target Name of telemetry error response packet
|
214
|
+
values: .+
|
215
|
+
- name: Packet Name
|
216
|
+
required: true
|
217
|
+
description: Packet Name of telemetry error response packet
|
218
|
+
values: .+
|
219
|
+
since: 5.14.0
|
220
|
+
RELATED_ITEM:
|
221
|
+
summary: Defines a related telemetry item to this command
|
222
|
+
parameters:
|
223
|
+
- name: Target Name
|
224
|
+
required: true
|
225
|
+
description: Target Name of related telemetry item
|
226
|
+
values: .+
|
227
|
+
- name: Packet Name
|
228
|
+
required: true
|
229
|
+
description: Packet Name of related telemetry item
|
230
|
+
values: .+
|
231
|
+
- name: Item Name
|
232
|
+
required: true
|
233
|
+
description: Item Name of related telemetry item
|
234
|
+
values: .+
|
235
|
+
since: 5.14.0
|
236
|
+
SCREEN:
|
237
|
+
summary: Defines a related telemetry screen to this command
|
238
|
+
parameters:
|
239
|
+
- name: Target Name
|
240
|
+
required: true
|
241
|
+
description: Target Name of related telemetry screen
|
242
|
+
values: .+
|
243
|
+
- name: Screen Name
|
244
|
+
required: true
|
245
|
+
description: Screen Name of related telemetry screen
|
246
|
+
values: .+
|
247
|
+
since: 5.14.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2023 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# This program is free software; you can modify and/or redistribute it
|
@@ -16,6 +16,8 @@
|
|
16
16
|
# This file may also be used under the terms of a commercial license
|
17
17
|
# if purchased from OpenC3, Inc.
|
18
18
|
|
19
|
+
require 'json'
|
20
|
+
|
19
21
|
module OpenC3
|
20
22
|
class Accessor
|
21
23
|
attr_accessor :packet
|
@@ -52,27 +54,37 @@ module OpenC3
|
|
52
54
|
return @args
|
53
55
|
end
|
54
56
|
|
57
|
+
# If this is set it will enforce that buffer data is encoded
|
58
|
+
# in a specific encoding
|
55
59
|
def enforce_encoding
|
56
60
|
return 'ASCII-8BIT'.freeze
|
57
61
|
end
|
58
62
|
|
63
|
+
# This affects whether the Packet class enforces the buffer
|
64
|
+
# length at all. Set to false to remove any correlation between
|
65
|
+
# buffer length and defined sizes of items in COSMOS
|
59
66
|
def enforce_length
|
60
67
|
return true
|
61
68
|
end
|
62
69
|
|
70
|
+
# This sets the short_buffer_allowed flag in the Packet class
|
71
|
+
# which allows packets that have a buffer shorter than the defined size.
|
72
|
+
# Note that the buffer is still resized to the defined length
|
63
73
|
def enforce_short_buffer_allowed
|
64
74
|
return false
|
65
75
|
end
|
66
76
|
|
67
|
-
|
77
|
+
# If this is true it will enfore that COSMOS DERIVED items must have a
|
78
|
+
# write_conversion to be written
|
79
|
+
def enforce_derived_write_conversion(_item)
|
68
80
|
return true
|
69
81
|
end
|
70
82
|
|
71
|
-
def self.read_item(
|
83
|
+
def self.read_item(_item, _buffer)
|
72
84
|
raise "Must be defined by subclass"
|
73
85
|
end
|
74
86
|
|
75
|
-
def self.write_item(
|
87
|
+
def self.write_item(_item, _value, _buffer)
|
76
88
|
raise "Must be defined by subclass"
|
77
89
|
end
|
78
90
|
|
@@ -92,33 +104,34 @@ module OpenC3
|
|
92
104
|
end
|
93
105
|
|
94
106
|
def self.convert_to_type(value, item)
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
107
|
+
case item.data_type
|
108
|
+
when :OBJECT
|
109
|
+
# Do nothing for complex object types
|
110
|
+
when :STRING, :BLOCK
|
111
|
+
if item.array_size
|
112
|
+
value = JSON.parse(value) if value.is_a? String
|
113
|
+
value = value.map { |v| v.to_s }
|
114
|
+
else
|
115
|
+
value = value.to_s
|
116
|
+
end
|
117
|
+
when :UINT, :INT
|
118
|
+
if item.array_size
|
119
|
+
value = JSON.parse(value) if value.is_a? String
|
120
|
+
value = value.map { |v| Integer(v) }
|
121
|
+
else
|
122
|
+
value = Integer(value)
|
123
|
+
end
|
124
|
+
when :FLOAT
|
125
|
+
if item.array_size
|
126
|
+
value = JSON.parse(value) if value.is_a? String
|
127
|
+
value = value.map { |v| Float(v) }
|
128
|
+
else
|
129
|
+
value = Float(value)
|
130
|
+
end
|
114
131
|
else
|
115
|
-
|
116
|
-
# Handle Unknown data types
|
117
|
-
############################
|
118
|
-
|
119
|
-
raise(ArgumentError, "data_type #{data_type} is not recognized")
|
132
|
+
raise(ArgumentError, "data_type #{item.data_type} is not recognized")
|
120
133
|
end
|
121
134
|
return value
|
122
135
|
end
|
123
136
|
end
|
124
|
-
end
|
137
|
+
end
|
@@ -1229,19 +1229,29 @@ module OpenC3
|
|
1229
1229
|
values
|
1230
1230
|
end
|
1231
1231
|
|
1232
|
+
# If this is set it will enforce that buffer data is encoded
|
1233
|
+
# in a specific encoding
|
1232
1234
|
def enforce_encoding
|
1233
1235
|
return 'ASCII-8BIT'.freeze
|
1234
1236
|
end
|
1235
1237
|
|
1238
|
+
# This affects whether the Packet class enforces the buffer
|
1239
|
+
# length at all. Set to false to remove any correlation between
|
1240
|
+
# buffer length and defined sizes of items in COSMOS
|
1236
1241
|
def enforce_length
|
1237
1242
|
return true
|
1238
1243
|
end
|
1239
1244
|
|
1245
|
+
# This sets the short_buffer_allowed flag in the Packet class
|
1246
|
+
# which allows packets that have a buffer shorter than the defined size.
|
1247
|
+
# Note that the buffer is still resized to the defined length
|
1240
1248
|
def enforce_short_buffer_allowed
|
1241
1249
|
return false
|
1242
1250
|
end
|
1243
1251
|
|
1244
|
-
|
1252
|
+
# If this is true it will enfore that COSMOS DERIVED items must have a
|
1253
|
+
# write_conversion to be written
|
1254
|
+
def enforce_derived_write_conversion(_item)
|
1245
1255
|
return true
|
1246
1256
|
end
|
1247
1257
|
end # class BinaryAccessor
|
@@ -59,19 +59,29 @@ module OpenC3
|
|
59
59
|
return value
|
60
60
|
end
|
61
61
|
|
62
|
+
# If this is set it will enforce that buffer data is encoded
|
63
|
+
# in a specific encoding
|
62
64
|
def enforce_encoding
|
63
65
|
return nil
|
64
66
|
end
|
65
67
|
|
68
|
+
# This affects whether the Packet class enforces the buffer
|
69
|
+
# length at all. Set to false to remove any correlation between
|
70
|
+
# buffer length and defined sizes of items in COSMOS
|
66
71
|
def enforce_length
|
67
72
|
return false
|
68
73
|
end
|
69
74
|
|
75
|
+
# This sets the short_buffer_allowed flag in the Packet class
|
76
|
+
# which allows packets that have a buffer shorter than the defined size.
|
77
|
+
# Note that the buffer is still resized to the defined length
|
70
78
|
def enforce_short_buffer_allowed
|
71
79
|
return true
|
72
80
|
end
|
73
81
|
|
74
|
-
|
82
|
+
# If this is true it will enfore that COSMOS DERIVED items must have a
|
83
|
+
# write_conversion to be written
|
84
|
+
def enforce_derived_write_conversion(_item)
|
75
85
|
return true
|
76
86
|
end
|
77
87
|
end
|
@@ -121,18 +121,56 @@ module OpenC3
|
|
121
121
|
return value
|
122
122
|
end
|
123
123
|
|
124
|
+
def read_items(items, buffer)
|
125
|
+
result = {}
|
126
|
+
body_items = []
|
127
|
+
items.each do |item|
|
128
|
+
if item.name[0..4] == 'HTTP_'
|
129
|
+
result[item.name] = read_item(item, buffer)
|
130
|
+
else
|
131
|
+
body_items << item
|
132
|
+
end
|
133
|
+
end
|
134
|
+
body_result = @body_accessor.read_items(body_items, buffer)
|
135
|
+
result.merge!(body_result) # Merge Body accessor read items with HTTP_ items
|
136
|
+
return result
|
137
|
+
end
|
138
|
+
|
139
|
+
def write_items(items, values, buffer)
|
140
|
+
body_items = []
|
141
|
+
items.each_with_index do |item, index|
|
142
|
+
if item.name[0..4] == 'HTTP_'
|
143
|
+
write_item(item, values[index], buffer)
|
144
|
+
else
|
145
|
+
body_items << item
|
146
|
+
end
|
147
|
+
end
|
148
|
+
@body_accessor.write_items(body_items, values, buffer)
|
149
|
+
return values
|
150
|
+
end
|
151
|
+
|
152
|
+
# If this is set it will enforce that buffer data is encoded
|
153
|
+
# in a specific encoding
|
124
154
|
def enforce_encoding
|
125
155
|
return @body_accessor.enforce_encoding
|
126
156
|
end
|
127
157
|
|
158
|
+
# This affects whether the Packet class enforces the buffer
|
159
|
+
# length at all. Set to false to remove any correlation between
|
160
|
+
# buffer length and defined sizes of items in COSMOS
|
128
161
|
def enforce_length
|
129
162
|
return @body_accessor.enforce_length
|
130
163
|
end
|
131
164
|
|
165
|
+
# This sets the short_buffer_allowed flag in the Packet class
|
166
|
+
# which allows packets that have a buffer shorter than the defined size.
|
167
|
+
# Note that the buffer is still resized to the defined length
|
132
168
|
def enforce_short_buffer_allowed
|
133
169
|
return @body_accessor.enforce_short_buffer_allowed
|
134
170
|
end
|
135
171
|
|
172
|
+
# If this is true it will enfore that COSMOS DERIVED items must have a
|
173
|
+
# write_conversion to be written
|
136
174
|
def enforce_derived_write_conversion(item)
|
137
175
|
case item.name
|
138
176
|
when 'HTTP_STATUS', 'HTTP_PATH', 'HTTP_METHOD', 'HTTP_PACKET', 'HTTP_ERROR_PACKET', /^HTTP_QUERY_/, /^HTTP_HEADER_/
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2023 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# This program is free software; you can modify and/or redistribute it
|
@@ -24,7 +24,8 @@ module OpenC3
|
|
24
24
|
class JsonAccessor < Accessor
|
25
25
|
def self.read_item(item, buffer)
|
26
26
|
return nil if item.data_type == :DERIVED
|
27
|
-
|
27
|
+
value = JsonPath.on(buffer, item.key).first
|
28
|
+
return convert_to_type(value, item)
|
28
29
|
end
|
29
30
|
|
30
31
|
def self.write_item(item, value, buffer)
|
@@ -123,6 +124,7 @@ module OpenC3
|
|
123
124
|
raise "Unsupported key/token: #{item.key} - #{token}"
|
124
125
|
end
|
125
126
|
end
|
127
|
+
value = convert_to_type(value, item)
|
126
128
|
if parent_node
|
127
129
|
parent_node[parent_key] = value
|
128
130
|
else
|
@@ -131,19 +133,29 @@ module OpenC3
|
|
131
133
|
return decoded
|
132
134
|
end
|
133
135
|
|
136
|
+
# If this is set it will enforce that buffer data is encoded
|
137
|
+
# in a specific encoding
|
134
138
|
def enforce_encoding
|
135
139
|
return nil
|
136
140
|
end
|
137
141
|
|
142
|
+
# This affects whether the Packet class enforces the buffer
|
143
|
+
# length at all. Set to false to remove any correlation between
|
144
|
+
# buffer length and defined sizes of items in COSMOS
|
138
145
|
def enforce_length
|
139
146
|
return false
|
140
147
|
end
|
141
148
|
|
149
|
+
# This sets the short_buffer_allowed flag in the Packet class
|
150
|
+
# which allows packets that have a buffer shorter than the defined size.
|
151
|
+
# Note that the buffer is still resized to the defined length
|
142
152
|
def enforce_short_buffer_allowed
|
143
153
|
return true
|
144
154
|
end
|
145
155
|
|
146
|
-
|
156
|
+
# If this is true it will enfore that COSMOS DERIVED items must have a
|
157
|
+
# write_conversion to be written
|
158
|
+
def enforce_derived_write_conversion(_item)
|
147
159
|
return true
|
148
160
|
end
|
149
161
|
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2024 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
require 'openc3/accessors/accessor'
|
20
|
+
|
21
|
+
module OpenC3
|
22
|
+
class TemplateAccessor < Accessor
|
23
|
+
def initialize(packet, left_char = '<', right_char = '>')
|
24
|
+
super(packet)
|
25
|
+
@left_char = left_char
|
26
|
+
@right_char = right_char
|
27
|
+
@configured = false
|
28
|
+
end
|
29
|
+
|
30
|
+
def configure
|
31
|
+
return if @configured
|
32
|
+
|
33
|
+
escaped_left_char = @left_char
|
34
|
+
escaped_left_char = "\\#{@left_char}" if @left_char == '('
|
35
|
+
escaped_right_char = @right_char
|
36
|
+
escaped_right_char = "\\#{@right_char}" if @right_char == ')'
|
37
|
+
|
38
|
+
# Convert the template into a Regexp for reading each item
|
39
|
+
template = @packet.template.dup
|
40
|
+
template_items = template.scan(Regexp.new("#{escaped_left_char}.*?#{escaped_right_char}"))
|
41
|
+
escaped_read_template = template
|
42
|
+
if @left_char != '('
|
43
|
+
escaped_read_template = escaped_read_template.gsub('(', '\(')
|
44
|
+
end
|
45
|
+
if @right_char != ')'
|
46
|
+
escaped_read_template = escaped_read_template.gsub(')', '\)')
|
47
|
+
end
|
48
|
+
|
49
|
+
@item_keys = []
|
50
|
+
template_items.each do |item|
|
51
|
+
@item_keys << item[1..-2]
|
52
|
+
escaped_read_template.gsub!(item, "(.*)")
|
53
|
+
end
|
54
|
+
@read_regexp = Regexp.new(escaped_read_template)
|
55
|
+
|
56
|
+
@configured = true
|
57
|
+
end
|
58
|
+
|
59
|
+
def read_item(item, buffer)
|
60
|
+
return nil if item.data_type == :DERIVED
|
61
|
+
configure()
|
62
|
+
|
63
|
+
# Scan the response for all the variables in brackets <VARIABLE>
|
64
|
+
values = buffer.scan(@read_regexp)[0]
|
65
|
+
if !values || (values.length != @item_keys.length)
|
66
|
+
raise "Unexpected number of items found in buffer: #{values ? values.length : 0}, Expected: #{@item_keys.length}"
|
67
|
+
else
|
68
|
+
values.each_with_index do |value, i|
|
69
|
+
item_key = @item_keys[i]
|
70
|
+
if item_key == item.key
|
71
|
+
return Accessor.convert_to_type(value, item)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
raise "Response does not include key #{item.key}: #{buffer}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def read_items(items, buffer)
|
80
|
+
result = {}
|
81
|
+
configure()
|
82
|
+
|
83
|
+
# Scan the response for all the variables in brackets <VARIABLE>
|
84
|
+
values = buffer.scan(@read_regexp)[0]
|
85
|
+
if !values || (values.length != @item_keys.length)
|
86
|
+
raise "Unexpected number of items found in buffer: #{values ? values.length : 0}, Expected: #{@item_keys.length}"
|
87
|
+
else
|
88
|
+
items.each do |item|
|
89
|
+
if item.data_type == :DERIVED
|
90
|
+
result[item.name] = nil
|
91
|
+
next
|
92
|
+
end
|
93
|
+
index = @item_keys.index(item.key)
|
94
|
+
if index
|
95
|
+
result[item.name] = Accessor.convert_to_type(values[index], item)
|
96
|
+
else
|
97
|
+
raise "Unknown item with key #{item.key} requested"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
return result
|
103
|
+
end
|
104
|
+
|
105
|
+
def write_item(item, value, buffer)
|
106
|
+
return nil if item.data_type == :DERIVED
|
107
|
+
configure()
|
108
|
+
|
109
|
+
success = buffer.gsub!("#{@left_char}#{item.key}#{@right_char}", value.to_s)
|
110
|
+
raise "Key #{item.key} not found in template" unless success
|
111
|
+
return value
|
112
|
+
end
|
113
|
+
|
114
|
+
def write_items(items, values, buffer)
|
115
|
+
configure()
|
116
|
+
items.each_with_index do |item, index|
|
117
|
+
next if item.data_type == :DERIVED
|
118
|
+
success = buffer.gsub!("#{@left_char}#{item.key}#{@right_char}", values[index].to_s)
|
119
|
+
raise "Key #{item.key} not found in template" unless success
|
120
|
+
end
|
121
|
+
return values
|
122
|
+
end
|
123
|
+
|
124
|
+
# If this is set it will enforce that buffer data is encoded
|
125
|
+
# in a specific encoding
|
126
|
+
def enforce_encoding
|
127
|
+
return nil
|
128
|
+
end
|
129
|
+
|
130
|
+
# This affects whether the Packet class enforces the buffer
|
131
|
+
# length at all. Set to false to remove any correlation between
|
132
|
+
# buffer length and defined sizes of items in COSMOS
|
133
|
+
def enforce_length
|
134
|
+
return false
|
135
|
+
end
|
136
|
+
|
137
|
+
# This sets the short_buffer_allowed flag in the Packet class
|
138
|
+
# which allows packets that have a buffer shorter than the defined size.
|
139
|
+
# Note that the buffer is still resized to the defined length
|
140
|
+
def enforce_short_buffer_allowed
|
141
|
+
return true
|
142
|
+
end
|
143
|
+
|
144
|
+
# If this is true it will enfore that COSMOS DERIVED items must have a
|
145
|
+
# write_conversion to be written
|
146
|
+
def enforce_derived_write_conversion(_item)
|
147
|
+
return true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -68,19 +68,29 @@ module OpenC3
|
|
68
68
|
doc.to_xml
|
69
69
|
end
|
70
70
|
|
71
|
+
# If this is set it will enforce that buffer data is encoded
|
72
|
+
# in a specific encoding
|
71
73
|
def enforce_encoding
|
72
74
|
return nil
|
73
75
|
end
|
74
76
|
|
77
|
+
# This affects whether the Packet class enforces the buffer
|
78
|
+
# length at all. Set to false to remove any correlation between
|
79
|
+
# buffer length and defined sizes of items in COSMOS
|
75
80
|
def enforce_length
|
76
81
|
return false
|
77
82
|
end
|
78
83
|
|
84
|
+
# This sets the short_buffer_allowed flag in the Packet class
|
85
|
+
# which allows packets that have a buffer shorter than the defined size.
|
86
|
+
# Note that the buffer is still resized to the defined length
|
79
87
|
def enforce_short_buffer_allowed
|
80
88
|
return true
|
81
89
|
end
|
82
90
|
|
83
|
-
|
91
|
+
# If this is true it will enfore that COSMOS DERIVED items must have a
|
92
|
+
# write_conversion to be written
|
93
|
+
def enforce_derived_write_conversion(_item)
|
84
94
|
return true
|
85
95
|
end
|
86
96
|
end
|
data/lib/openc3/accessors.rb
CHANGED
@@ -25,4 +25,5 @@ module OpenC3
|
|
25
25
|
autoload(:HttpAccessor, 'openc3/accessors/http_accessor.rb')
|
26
26
|
autoload(:JsonAccessor, 'openc3/accessors/json_accessor.rb')
|
27
27
|
autoload(:XmlAccessor, 'openc3/accessors/xml_accessor.rb')
|
28
|
+
autoload(:TemplateAccessor, 'openc3/accessors/template_accessor.rb')
|
28
29
|
end
|