openc3 5.13.0 → 5.14.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- 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
|