openc3 5.11.3 → 5.13.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 +2 -2
- data/bin/openc3cli +29 -15
- data/data/config/_id_items.yaml +6 -4
- data/data/config/_id_params.yaml +9 -6
- data/data/config/_items.yaml +6 -4
- data/data/config/_params.yaml +3 -2
- data/data/config/graph_settings.yaml +1 -1
- data/data/config/interface_modifiers.yaml +1 -1
- data/data/config/item_modifiers.yaml +1 -2
- data/data/config/microservice.yaml +10 -1
- data/data/config/parameter_modifiers.yaml +13 -14
- data/data/config/plugins.yaml +13 -3
- data/data/config/screen.yaml +1 -2
- data/data/config/target.yaml +9 -0
- data/data/config/target_config.yaml +14 -6
- data/data/config/tool.yaml +12 -3
- data/lib/openc3/api/api.rb +1 -1
- data/lib/openc3/api/cmd_api.rb +123 -59
- data/lib/openc3/api/config_api.rb +12 -12
- data/lib/openc3/api/limits_api.rb +4 -3
- data/lib/openc3/api/settings_api.rb +5 -2
- data/lib/openc3/api/tlm_api.rb +70 -34
- data/lib/openc3/conversions/unix_time_conversion.rb +8 -6
- data/lib/openc3/interfaces/mqtt_interface.rb +11 -9
- data/lib/openc3/interfaces/mqtt_stream_interface.rb +78 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +0 -7
- data/lib/openc3/io/json_drb.rb +3 -2
- data/lib/openc3/io/json_rpc.rb +6 -6
- data/lib/openc3/logs/buffered_packet_log_writer.rb +4 -2
- data/lib/openc3/logs/packet_log_reader.rb +2 -2
- data/lib/openc3/logs/packet_log_writer.rb +22 -7
- data/lib/openc3/logs/text_log_writer.rb +3 -2
- data/lib/openc3/microservices/cleanup_microservice.rb +8 -1
- data/lib/openc3/microservices/decom_microservice.rb +1 -1
- data/lib/openc3/microservices/interface_microservice.rb +2 -2
- data/lib/openc3/microservices/microservice.rb +5 -2
- data/lib/openc3/microservices/reaction_microservice.rb +1 -0
- data/lib/openc3/microservices/timeline_microservice.rb +7 -5
- data/lib/openc3/microservices/trigger_group_microservice.rb +2 -1
- data/lib/openc3/migrations/20231022000000_tlm_viewer_config.rb +22 -0
- data/lib/openc3/models/activity_model.rb +21 -3
- data/lib/openc3/models/cvt_model.rb +2 -1
- data/lib/openc3/models/gem_model.rb +4 -1
- data/lib/openc3/models/interface_model.rb +11 -5
- data/lib/openc3/models/metadata_model.rb +11 -0
- data/lib/openc3/models/microservice_model.rb +16 -3
- data/lib/openc3/models/model.rb +18 -0
- data/lib/openc3/models/note_model.rb +11 -0
- data/lib/openc3/models/plugin_model.rb +56 -4
- data/lib/openc3/models/python_package_model.rb +104 -0
- data/lib/openc3/models/scope_model.rb +2 -0
- data/lib/openc3/models/sorted_model.rb +17 -8
- data/lib/openc3/models/target_model.rb +53 -18
- data/lib/openc3/models/tool_config_model.rb +9 -3
- data/lib/openc3/models/tool_model.rb +22 -7
- data/lib/openc3/models/widget_model.rb +19 -3
- data/lib/openc3/operators/microservice_operator.rb +2 -0
- data/lib/openc3/packets/json_packet.rb +46 -15
- data/lib/openc3/packets/limits.rb +6 -18
- data/lib/openc3/packets/packet.rb +1 -0
- data/lib/openc3/packets/packet_config.rb +2 -1
- data/lib/openc3/packets/parsers/format_string_parser.rb +4 -4
- data/lib/openc3/packets/parsers/limits_parser.rb +4 -4
- data/lib/openc3/packets/parsers/limits_response_parser.rb +5 -5
- data/lib/openc3/packets/parsers/processor_parser.rb +4 -4
- data/lib/openc3/packets/parsers/state_parser.rb +3 -3
- data/lib/openc3/packets/parsers/xtce_parser.rb +5 -1
- data/lib/openc3/script/api_shared.rb +81 -63
- data/lib/openc3/script/calendar.rb +109 -0
- data/lib/openc3/script/commands.rb +18 -19
- data/lib/openc3/script/limits.rb +1 -1
- data/lib/openc3/script/{gems.rb → packages.rb} +20 -16
- data/lib/openc3/script/script.rb +49 -38
- data/lib/openc3/script/storage.rb +4 -4
- data/lib/openc3/script/web_socket_api.rb +2 -2
- data/lib/openc3/streams/mqtt_stream.rb +109 -0
- data/lib/openc3/system/system.rb +2 -0
- data/lib/openc3/system/target.rb +10 -1
- data/lib/openc3/top_level.rb +2 -2
- data/lib/openc3/utilities/aws_bucket.rb +3 -2
- data/lib/openc3/utilities/bucket_file_cache.rb +1 -1
- data/lib/openc3/utilities/cli_generator.rb +33 -20
- data/lib/openc3/utilities/local_mode.rb +5 -3
- data/lib/openc3/utilities/logger.rb +18 -17
- data/lib/openc3/utilities/process_manager.rb +1 -1
- data/lib/openc3/utilities/ruby_lex_utils.rb +0 -8
- data/lib/openc3/version.rb +6 -6
- data/templates/conversion/conversion.py +28 -0
- data/templates/conversion/conversion.rb +1 -18
- data/templates/limits_response/response.py +37 -0
- data/templates/limits_response/response.rb +0 -17
- data/templates/microservice/microservices/TEMPLATE/microservice.py +54 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +0 -7
- data/templates/plugin/.gitignore +1 -0
- data/templates/target/targets/TARGET/lib/target.py +9 -0
- data/templates/target/targets/TARGET/procedures/procedure.py +3 -0
- data/templates/tool_angular/package.json +22 -21
- data/templates/tool_angular/yarn.lock +2319 -3156
- data/templates/tool_react/package.json +16 -16
- data/templates/tool_react/yarn.lock +763 -645
- data/templates/tool_svelte/package.json +15 -14
- data/templates/tool_svelte/src/services/openc3-api.js +33 -82
- data/templates/tool_svelte/yarn.lock +748 -538
- data/templates/tool_vue/package.json +15 -14
- data/templates/tool_vue/yarn.lock +150 -64
- data/templates/widget/package.json +14 -13
- data/templates/widget/yarn.lock +133 -58
- metadata +60 -7
@@ -14,7 +14,7 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2023, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -78,6 +78,7 @@ module OpenC3
|
|
78
78
|
attr_accessor :needs_dependencies
|
79
79
|
attr_accessor :target_microservices
|
80
80
|
attr_accessor :children
|
81
|
+
attr_accessor :disable_erb
|
81
82
|
|
82
83
|
# NOTE: The following three class methods are used by the ModelController
|
83
84
|
# and are reimplemented to enable various Model class methods to work
|
@@ -349,6 +350,7 @@ module OpenC3
|
|
349
350
|
target_microservices: {'REDUCER' => [[]]},
|
350
351
|
reducer_disable: false,
|
351
352
|
reducer_max_cpu_utilization: 30.0,
|
353
|
+
disable_erb: nil,
|
352
354
|
scope:
|
353
355
|
)
|
354
356
|
super("#{scope}__#{PRIMARY_KEY}", name: name, plugin: plugin, updated_at: updated_at,
|
@@ -396,6 +398,7 @@ module OpenC3
|
|
396
398
|
@target_microservices = target_microservices
|
397
399
|
@reducer_disable = reducer_disable
|
398
400
|
@reducer_max_cpu_utilization = reducer_max_cpu_utilization
|
401
|
+
@disable_erb = disable_erb
|
399
402
|
@bucket = Bucket.getClient()
|
400
403
|
@children = []
|
401
404
|
end
|
@@ -435,7 +438,8 @@ module OpenC3
|
|
435
438
|
'needs_dependencies' => @needs_dependencies,
|
436
439
|
'target_microservices' => @target_microservices.as_json(:allow_nan => true),
|
437
440
|
'reducer_disable' => @reducer_disable,
|
438
|
-
'reducer_max_cpu_utilization' => @reducer_max_cpu_utilization
|
441
|
+
'reducer_max_cpu_utilization' => @reducer_max_cpu_utilization,
|
442
|
+
'disable_erb' => @disable_erb
|
439
443
|
}
|
440
444
|
end
|
441
445
|
|
@@ -544,6 +548,12 @@ module OpenC3
|
|
544
548
|
else
|
545
549
|
raise ConfigParser::Error.new(parser, "PACKET cannot be used without a TARGET_MICROSERVICE")
|
546
550
|
end
|
551
|
+
when 'DISABLE_ERB'
|
552
|
+
# 0 to unlimited parameters
|
553
|
+
@disable_erb ||= []
|
554
|
+
if parameters
|
555
|
+
@disable_erb.concat(parameters)
|
556
|
+
end
|
547
557
|
else
|
548
558
|
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Target: #{keyword} #{parameters.join(" ")}")
|
549
559
|
end
|
@@ -567,10 +577,13 @@ module OpenC3
|
|
567
577
|
# Load target files
|
568
578
|
@filename = filename # For render
|
569
579
|
data = File.read(filename, mode: "rb")
|
580
|
+
erb_disabled = check_disable_erb(filename)
|
570
581
|
begin
|
571
|
-
|
572
|
-
|
573
|
-
|
582
|
+
unless erb_disabled
|
583
|
+
OpenC3.set_working_dir(File.dirname(filename)) do
|
584
|
+
if ERB_EXTENSIONS.include?(File.extname(filename).downcase) and File.basename(filename)[0] != '_'
|
585
|
+
data = ERB.new(data.force_encoding("UTF-8").comment_erb(), trim_mode: "-").result(binding.set_variables(variables))
|
586
|
+
end
|
574
587
|
end
|
575
588
|
end
|
576
589
|
rescue => error
|
@@ -679,9 +692,15 @@ module OpenC3
|
|
679
692
|
path = File.join(File.dirname(@filename), template_name)
|
680
693
|
end
|
681
694
|
|
695
|
+
data = File.read(path, mode: "rb")
|
696
|
+
erb_disabled = check_disable_erb(path)
|
682
697
|
begin
|
683
|
-
|
684
|
-
return
|
698
|
+
if erb_disabled
|
699
|
+
return data
|
700
|
+
else
|
701
|
+
OpenC3.set_working_dir(File.dirname(path)) do
|
702
|
+
return ERB.new(data.force_encoding("UTF-8").comment_erb(), trim_mode: "-").result(b)
|
703
|
+
end
|
685
704
|
end
|
686
705
|
rescue => error
|
687
706
|
raise "ERB error parsing: #{path}: #{error.formatted}"
|
@@ -692,14 +711,14 @@ module OpenC3
|
|
692
711
|
target_files = []
|
693
712
|
Find.find(target_folder) { |file| target_files << file }
|
694
713
|
target_files.sort!
|
695
|
-
|
696
|
-
File.open(File.join(target_folder, 'target_id.txt'), 'wb') { |file| file.write(
|
714
|
+
@id = OpenC3.hash_files(target_files, nil, 'SHA256').hexdigest
|
715
|
+
File.open(File.join(target_folder, 'target_id.txt'), 'wb') { |file| file.write(@id) }
|
697
716
|
key = "#{@scope}/targets/#{@name}/target_id.txt"
|
698
|
-
@bucket.put_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: key, body:
|
717
|
+
@bucket.put_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: key, body: @id)
|
699
718
|
|
700
719
|
# Create target archive zip file
|
701
720
|
prefix = File.dirname(target_folder) + '/'
|
702
|
-
output_file = File.join(temp_dir, @name + '_' +
|
721
|
+
output_file = File.join(temp_dir, @name + '_' + @id + '.zip')
|
703
722
|
Zip.continue_on_exists_proc = true
|
704
723
|
Zip::File.open(output_file, Zip::File::CREATE) do |zipfile|
|
705
724
|
target_files.each do |target_file|
|
@@ -718,7 +737,7 @@ module OpenC3
|
|
718
737
|
@bucket.put_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: bucket_key, body: file)
|
719
738
|
end
|
720
739
|
File.open(output_file, 'rb') do |file|
|
721
|
-
bucket_key = key = "#{@scope}/target_archives/#{@name}/#{@name}_#{
|
740
|
+
bucket_key = key = "#{@scope}/target_archives/#{@name}/#{@name}_#{@id}.zip"
|
722
741
|
@bucket.put_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: bucket_key, body: file)
|
723
742
|
end
|
724
743
|
end
|
@@ -733,7 +752,6 @@ module OpenC3
|
|
733
752
|
@cmd_tlm_files = target.cmd_tlm_files
|
734
753
|
@cmd_unique_id_mode = target.cmd_unique_id_mode
|
735
754
|
@tlm_unique_id_mode = target.tlm_unique_id_mode
|
736
|
-
@id = target.id
|
737
755
|
@limits_groups = system.limits.groups.keys
|
738
756
|
update()
|
739
757
|
|
@@ -897,13 +915,21 @@ module OpenC3
|
|
897
915
|
Logger.info "Configured microservice #{microservice_name}"
|
898
916
|
end
|
899
917
|
|
900
|
-
def deploy_decom_microservice(gem_path, variables, topics, instance = nil, parent = nil)
|
918
|
+
def deploy_decom_microservice(target, gem_path, variables, topics, instance = nil, parent = nil)
|
901
919
|
microservice_name = "#{@scope}__DECOM#{instance}__#{@name}"
|
920
|
+
# Assume Ruby initially
|
921
|
+
filename = 'decom_microservice.rb'
|
922
|
+
work_dir = '/openc3/lib/openc3/microservices'
|
923
|
+
if target.language == 'python'
|
924
|
+
filename = 'decom_microservice.py'
|
925
|
+
work_dir.sub!('openc3/lib', 'openc3/python')
|
926
|
+
parent = nil
|
927
|
+
end
|
902
928
|
microservice = MicroserviceModel.new(
|
903
929
|
name: microservice_name,
|
904
930
|
folder_name: @folder_name,
|
905
|
-
cmd: [
|
906
|
-
work_dir:
|
931
|
+
cmd: [target.language, filename, microservice_name],
|
932
|
+
work_dir: work_dir,
|
907
933
|
topics: topics,
|
908
934
|
target_names: [@name],
|
909
935
|
plugin: @plugin,
|
@@ -963,7 +989,6 @@ module OpenC3
|
|
963
989
|
name: microservice_name,
|
964
990
|
cmd: ["ruby", "multi_microservice.rb", *@children],
|
965
991
|
work_dir: '/openc3/lib/openc3/microservices',
|
966
|
-
target_names: [@name],
|
967
992
|
plugin: @plugin,
|
968
993
|
scope: @scope
|
969
994
|
)
|
@@ -976,9 +1001,14 @@ module OpenC3
|
|
976
1001
|
def deploy_target_microservices(type, base_topic_list, topic_prefix)
|
977
1002
|
target_microservices = @target_microservices[type]
|
978
1003
|
if target_microservices
|
1004
|
+
# These are stand alone microservice(s) ... not part of MULTI
|
979
1005
|
if base_topic_list
|
1006
|
+
# Only create the microservice if there are topics
|
1007
|
+
# This prevents creation of DECOM with no TLM Packets (for example)
|
980
1008
|
deploy_count = 0
|
981
1009
|
all_topics = base_topic_list.dup
|
1010
|
+
|
1011
|
+
# Figure out if there are individual packets assigned to this microservice
|
982
1012
|
target_microservices.sort! {|a, b| a.length <=> b.length}
|
983
1013
|
target_microservices.each_with_index do |packet_names, index|
|
984
1014
|
topics = []
|
@@ -996,15 +1026,19 @@ module OpenC3
|
|
996
1026
|
end
|
997
1027
|
end
|
998
1028
|
end
|
1029
|
+
# If there are any topics (packets) left over that haven't been
|
1030
|
+
# explictly handled above, spawn another microservice
|
999
1031
|
if all_topics.length > 0
|
1000
1032
|
instance = nil
|
1001
1033
|
instance = deploy_count unless deploy_count == 0
|
1002
1034
|
yield all_topics, instance, nil
|
1003
1035
|
end
|
1004
1036
|
else
|
1037
|
+
# Do not spawn the microservice
|
1005
1038
|
yield nil, nil, nil
|
1006
1039
|
end
|
1007
1040
|
else
|
1041
|
+
# Not a stand alone microservice ... part of MULTI
|
1008
1042
|
yield base_topic_list, nil, @parent if not base_topic_list or base_topic_list.length > 0
|
1009
1043
|
end
|
1010
1044
|
end
|
@@ -1068,11 +1102,12 @@ module OpenC3
|
|
1068
1102
|
|
1069
1103
|
# Decommutation Microservice
|
1070
1104
|
deploy_target_microservices('DECOM', packet_topic_list, "#{@scope}__TELEMETRY__{#{@name}}") do |topics, instance, parent|
|
1071
|
-
deploy_decom_microservice(gem_path, variables, topics, instance, parent)
|
1105
|
+
deploy_decom_microservice(system.targets[@name], gem_path, variables, topics, instance, parent)
|
1072
1106
|
end
|
1073
1107
|
|
1074
1108
|
# Reducer Microservice
|
1075
1109
|
unless @reducer_disable
|
1110
|
+
# TODO: Does Reducer even need a topic list?
|
1076
1111
|
deploy_target_microservices('REDUCER', decom_topic_list, "#{@scope}__DECOM__{#{@name}}") do |topics, instance, parent|
|
1077
1112
|
deploy_reducer_microservice(gem_path, variables, topics, instance, parent)
|
1078
1113
|
end
|
@@ -24,6 +24,12 @@ require 'openc3/utilities/local_mode'
|
|
24
24
|
|
25
25
|
module OpenC3
|
26
26
|
class ToolConfigModel
|
27
|
+
def self.config_tool_names(scope: $openc3_scope)
|
28
|
+
cursor, keys = Store.scan(0, match: "#{scope}__config__*", type: 'hash', count: 100)
|
29
|
+
# Just return the tool name that is used in the other APIs
|
30
|
+
return keys.map! { |key| key.split('__')[2] }.sort
|
31
|
+
end
|
32
|
+
|
27
33
|
def self.list_configs(tool, scope: $openc3_scope)
|
28
34
|
Store.hkeys("#{scope}__config__#{tool}")
|
29
35
|
end
|
@@ -32,14 +38,14 @@ module OpenC3
|
|
32
38
|
Store.hget("#{scope}__config__#{tool}", name)
|
33
39
|
end
|
34
40
|
|
35
|
-
def self.save_config(tool, name, data,
|
41
|
+
def self.save_config(tool, name, data, local_mode: true, scope: $openc3_scope)
|
36
42
|
Store.hset("#{scope}__config__#{tool}", name, data)
|
37
43
|
LocalMode.save_tool_config(scope, tool, name, data) if local_mode
|
38
44
|
end
|
39
45
|
|
40
|
-
def self.delete_config(tool, name, scope: $openc3_scope)
|
46
|
+
def self.delete_config(tool, name, local_mode: true, scope: $openc3_scope)
|
41
47
|
Store.hdel("#{scope}__config__#{tool}", name)
|
42
|
-
LocalMode.delete_tool_config(scope, tool, name)
|
48
|
+
LocalMode.delete_tool_config(scope, tool, name) if local_mode
|
43
49
|
end
|
44
50
|
end
|
45
51
|
end
|
@@ -39,6 +39,7 @@ module OpenC3
|
|
39
39
|
attr_accessor :shown
|
40
40
|
attr_accessor :position
|
41
41
|
attr_accessor :needs_dependencies
|
42
|
+
attr_accessor :disable_erb
|
42
43
|
|
43
44
|
# NOTE: The following three class methods are used by the ModelController
|
44
45
|
# and are reimplemented to enable various Model class methods to work
|
@@ -135,6 +136,7 @@ module OpenC3
|
|
135
136
|
updated_at: nil,
|
136
137
|
plugin: nil,
|
137
138
|
needs_dependencies: false,
|
139
|
+
disable_erb: nil,
|
138
140
|
scope:
|
139
141
|
)
|
140
142
|
super("#{scope}__#{PRIMARY_KEY}", name: name, plugin: plugin, updated_at: updated_at, scope: scope)
|
@@ -152,6 +154,7 @@ module OpenC3
|
|
152
154
|
@url = "/tools/#{folder_name}" unless @url
|
153
155
|
end
|
154
156
|
@needs_dependencies = needs_dependencies
|
157
|
+
@disable_erb = disable_erb
|
155
158
|
end
|
156
159
|
|
157
160
|
def create(update: false, force: false)
|
@@ -159,9 +162,11 @@ module OpenC3
|
|
159
162
|
|
160
163
|
# Make sure a tool with this folder_name doesn't already exist
|
161
164
|
unless update
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
+
if @folder_name
|
166
|
+
tools.each do |_tool_name, tool|
|
167
|
+
if tool['folder_name'] == @folder_name
|
168
|
+
raise "Tool with folder_name #{@folder_name} already exists at create"
|
169
|
+
end
|
165
170
|
end
|
166
171
|
end
|
167
172
|
end
|
@@ -193,6 +198,7 @@ module OpenC3
|
|
193
198
|
'updated_at' => @updated_at,
|
194
199
|
'plugin' => @plugin,
|
195
200
|
'needs_dependencies' => @needs_dependencies,
|
201
|
+
'disable_erb' => @disable_erb
|
196
202
|
}
|
197
203
|
end
|
198
204
|
|
@@ -203,14 +209,14 @@ module OpenC3
|
|
203
209
|
@url = parameters[0]
|
204
210
|
when 'INLINE_URL'
|
205
211
|
parser.verify_num_parameters(1, 1, "INLINE_URL <URL>")
|
206
|
-
@inline_url = parameters[0]
|
212
|
+
@inline_url = ConfigParser.handle_nil(parameters[0])
|
207
213
|
when 'ICON'
|
208
214
|
parser.verify_num_parameters(1, 1, "ICON <ICON Name>")
|
209
215
|
@icon = parameters[0]
|
210
216
|
when 'WINDOW'
|
211
|
-
parser.verify_num_parameters(1, 1, "WINDOW <INLINE | IFRAME | NEW>")
|
217
|
+
parser.verify_num_parameters(1, 1, "WINDOW <INLINE | IFRAME | SAME | NEW>")
|
212
218
|
@window = parameters[0].to_s.upcase
|
213
|
-
raise ConfigParser::Error.new(parser, "Invalid WINDOW setting: #{@window}") unless ['INLINE', 'IFRAME', 'NEW'].include?(@window)
|
219
|
+
raise ConfigParser::Error.new(parser, "Invalid WINDOW setting: #{@window}") unless ['INLINE', 'IFRAME', 'SAME', 'NEW'].include?(@window)
|
214
220
|
when 'CATEGORY'
|
215
221
|
parser.verify_num_parameters(1, 1, "CATEGORY <Category Name>")
|
216
222
|
@category = parameters[0].to_s
|
@@ -220,6 +226,12 @@ module OpenC3
|
|
220
226
|
when 'POSITION'
|
221
227
|
parser.verify_num_parameters(1, 1, "POSITION <value>")
|
222
228
|
@position = parameters[0].to_i
|
229
|
+
when 'DISABLE_ERB'
|
230
|
+
# 0 to unlimited parameters
|
231
|
+
@disable_erb ||= []
|
232
|
+
if parameters
|
233
|
+
@disable_erb.concat(parameters)
|
234
|
+
end
|
223
235
|
else
|
224
236
|
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Tool: #{keyword} #{parameters.join(" ")}")
|
225
237
|
end
|
@@ -240,7 +252,10 @@ module OpenC3
|
|
240
252
|
|
241
253
|
# Load tool files
|
242
254
|
data = File.read(filename, mode: "rb")
|
243
|
-
|
255
|
+
erb_disabled = check_disable_erb(filename)
|
256
|
+
unless erb_disabled
|
257
|
+
data = ERB.new(data.comment_erb(), trim_mode: "-").result(binding.set_variables(variables)) if data.is_printable?
|
258
|
+
end
|
244
259
|
unless validate_only
|
245
260
|
client = Bucket.getClient()
|
246
261
|
cache_control = BucketUtilities.get_cache_control(filename)
|
@@ -35,6 +35,7 @@ module OpenC3
|
|
35
35
|
attr_accessor :filename
|
36
36
|
attr_accessor :bucket_key
|
37
37
|
attr_accessor :needs_dependencies
|
38
|
+
attr_accessor :disable_erb
|
38
39
|
|
39
40
|
# NOTE: The following three class methods are used by the ModelController
|
40
41
|
# and are reimplemented to enable various Model class methods to work
|
@@ -87,6 +88,7 @@ module OpenC3
|
|
87
88
|
plugin: nil,
|
88
89
|
label: nil,
|
89
90
|
needs_dependencies: false,
|
91
|
+
disable_erb: nil,
|
90
92
|
scope:
|
91
93
|
)
|
92
94
|
super("#{scope}__#{PRIMARY_KEY}", name: name, plugin: plugin, updated_at: updated_at, scope: scope)
|
@@ -95,6 +97,7 @@ module OpenC3
|
|
95
97
|
@bucket_key = 'widgets/' + @full_name + '/' + @filename
|
96
98
|
@label = label
|
97
99
|
@needs_dependencies = needs_dependencies
|
100
|
+
@disable_erb = disable_erb
|
98
101
|
end
|
99
102
|
|
100
103
|
def as_json(*a)
|
@@ -104,11 +107,21 @@ module OpenC3
|
|
104
107
|
'plugin' => @plugin,
|
105
108
|
'label' => @label,
|
106
109
|
'needs_dependencies' => @needs_dependencies,
|
110
|
+
'disable_erb' => @disable_erb
|
107
111
|
}
|
108
112
|
end
|
109
113
|
|
110
114
|
def handle_config(parser, keyword, parameters)
|
111
|
-
|
115
|
+
case keyword
|
116
|
+
when 'DISABLE_ERB'
|
117
|
+
# 0 to unlimited parameters
|
118
|
+
@disable_erb ||= []
|
119
|
+
if parameters
|
120
|
+
@disable_erb.concat(parameters)
|
121
|
+
end
|
122
|
+
else
|
123
|
+
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Widget: #{keyword} #{parameters.join(" ")}")
|
124
|
+
end
|
112
125
|
end
|
113
126
|
|
114
127
|
def deploy(gem_path, variables, validate_only: false)
|
@@ -123,8 +136,11 @@ module OpenC3
|
|
123
136
|
|
124
137
|
# Load widget file
|
125
138
|
data = File.read(filename, mode: "rb")
|
126
|
-
|
127
|
-
|
139
|
+
erb_disabled = check_disable_erb(filename)
|
140
|
+
unless erb_disabled
|
141
|
+
OpenC3.set_working_dir(File.dirname(filename)) do
|
142
|
+
data = ERB.new(data.comment_erb(), trim_mode: "-").result(binding.set_variables(variables)) if data.is_printable?
|
143
|
+
end
|
128
144
|
end
|
129
145
|
unless validate_only
|
130
146
|
cache_control = BucketUtilities.get_cache_control(@filename)
|
@@ -50,8 +50,10 @@ module OpenC3
|
|
50
50
|
env = microservice_config["env"].dup
|
51
51
|
if microservice_config["needs_dependencies"]
|
52
52
|
env['GEM_HOME'] = '/gems'
|
53
|
+
env['PYTHONUSERBASE'] = '/gems/python_packages'
|
53
54
|
else
|
54
55
|
env['GEM_HOME'] = nil
|
56
|
+
env['PYTHONUSERBASE'] = nil
|
55
57
|
end
|
56
58
|
env['OPENC3_MICROSERVICE_NAME'] = microservice_name
|
57
59
|
container = microservice_config["container"]
|
@@ -65,66 +65,97 @@ module OpenC3
|
|
65
65
|
# @param name [String] Name of the item to read - Should already by upcase
|
66
66
|
# @param value_type (see #read_item)
|
67
67
|
def read(name, value_type = :CONVERTED, reduced_type = nil)
|
68
|
+
value = nil
|
69
|
+
array_index = nil
|
70
|
+
if name[-1] == ']'
|
71
|
+
open_bracket_index = name.index('[')
|
72
|
+
if open_bracket_index
|
73
|
+
array_index = name[(open_bracket_index + 1)..-2].to_i
|
74
|
+
name = name[0..(open_bracket_index - 1)]
|
75
|
+
end
|
76
|
+
end
|
68
77
|
if reduced_type
|
69
78
|
raise "Reduced types only support RAW or CONVERTED value types: #{value_type} unsupported" if value_type == :WITH_UNITS or value_type == :FORMATTED
|
70
79
|
if value_type == :CONVERTED
|
71
80
|
case reduced_type
|
72
81
|
when :AVG
|
73
82
|
value = @json_hash["#{name}__CA"]
|
74
|
-
return value if value
|
75
83
|
when :STDDEV
|
76
84
|
value = @json_hash["#{name}__CS"]
|
77
|
-
return value if value
|
78
85
|
when :MIN
|
79
86
|
value = @json_hash["#{name}__CN"]
|
80
|
-
return value if value
|
81
87
|
when :MAX
|
82
88
|
value = @json_hash["#{name}__CX"]
|
83
|
-
|
89
|
+
end
|
90
|
+
if value
|
91
|
+
value = value[array_index] if array_index
|
92
|
+
return value
|
84
93
|
end
|
85
94
|
end
|
86
95
|
case reduced_type
|
87
96
|
when :AVG
|
88
97
|
value = @json_hash["#{name}__A"]
|
89
|
-
return value if value
|
90
98
|
when :STDDEV
|
91
99
|
value = @json_hash["#{name}__S"]
|
92
|
-
return value if value
|
93
100
|
when :MIN
|
94
101
|
value = @json_hash["#{name}__N"]
|
95
|
-
return value if value
|
96
102
|
when :MAX
|
97
103
|
value = @json_hash["#{name}__X"]
|
98
|
-
|
104
|
+
end
|
105
|
+
if value
|
106
|
+
value = value[array_index] if array_index
|
107
|
+
return value
|
99
108
|
end
|
100
109
|
end
|
101
110
|
if value_type == :WITH_UNITS
|
102
111
|
value = @json_hash["#{name}__U"]
|
103
|
-
|
112
|
+
if value
|
113
|
+
value = value[array_index] if array_index
|
114
|
+
return value
|
115
|
+
end
|
104
116
|
end
|
105
117
|
if value_type == :WITH_UNITS or value_type == :FORMATTED
|
106
118
|
value = @json_hash["#{name}__F"]
|
107
|
-
|
119
|
+
if value
|
120
|
+
value = value[array_index] if array_index
|
121
|
+
return value
|
122
|
+
end
|
108
123
|
|
109
124
|
value = @json_hash["#{name}__C"]
|
110
|
-
|
125
|
+
if value
|
126
|
+
value = value[array_index] if array_index
|
127
|
+
return value.to_s
|
128
|
+
end
|
111
129
|
|
112
130
|
value = @json_hash[name]
|
113
|
-
|
131
|
+
if value
|
132
|
+
value = value[array_index] if array_index
|
133
|
+
return value.to_s
|
134
|
+
end
|
114
135
|
|
115
136
|
return nil
|
116
137
|
end
|
117
138
|
if value_type == :CONVERTED
|
118
139
|
value = @json_hash["#{name}__C"]
|
119
|
-
|
140
|
+
if value
|
141
|
+
value = value[array_index] if array_index
|
142
|
+
return value
|
143
|
+
end
|
120
144
|
end
|
121
|
-
|
145
|
+
value = @json_hash[name]
|
146
|
+
if value
|
147
|
+
value = value[array_index] if array_index
|
148
|
+
return value
|
149
|
+
end
|
150
|
+
return nil
|
122
151
|
end
|
123
152
|
|
124
153
|
def read_with_limits_state(name, value_type = :CONVERTED, reduced_type = nil)
|
125
154
|
value = read(name, value_type, reduced_type)
|
126
155
|
limits_state = @json_hash["#{name}__L"]
|
127
|
-
|
156
|
+
if limits_state
|
157
|
+
limits_state = limits_state.intern
|
158
|
+
end
|
128
159
|
return [value, limits_state]
|
129
160
|
end
|
130
161
|
|
@@ -73,21 +73,21 @@ module OpenC3
|
|
73
73
|
# @param packet_name [String] The packet name. Must be a defined packet name and not 'LATEST'.
|
74
74
|
# @param item_name [String] The item name
|
75
75
|
def enabled?(target_name, packet_name, item_name)
|
76
|
-
|
76
|
+
_get_packet(target_name, packet_name).get_item(item_name).limits.enabled
|
77
77
|
end
|
78
78
|
|
79
79
|
# Enables limit checking for the specified item
|
80
80
|
#
|
81
81
|
# @param (see #enabled?)
|
82
82
|
def enable(target_name, packet_name, item_name)
|
83
|
-
|
83
|
+
_get_packet(target_name, packet_name).enable_limits(item_name)
|
84
84
|
end
|
85
85
|
|
86
86
|
# Disables limit checking for the specified item
|
87
87
|
#
|
88
88
|
# @param (see #enabled?)
|
89
89
|
def disable(target_name, packet_name, item_name)
|
90
|
-
|
90
|
+
_get_packet(target_name, packet_name).disable_limits(item_name)
|
91
91
|
end
|
92
92
|
|
93
93
|
# Get the limits for a telemetry item
|
@@ -98,7 +98,7 @@ module OpenC3
|
|
98
98
|
# @param limits_set [String or Symbol or nil] Desired Limits set. nil = current limits set
|
99
99
|
# @return [Array<limits_set, persistence, enabled, red_low, yellow_low, red_high, yellow_high, green_low (optional), green_high (optional)] Limits information
|
100
100
|
def get(target_name, packet_name, item_name, limits_set = nil)
|
101
|
-
limits =
|
101
|
+
limits = _get_packet(target_name, packet_name).get_item(item_name).limits
|
102
102
|
if limits.values
|
103
103
|
if limits_set
|
104
104
|
limits_set = limits_set.to_s.upcase.intern
|
@@ -132,7 +132,7 @@ module OpenC3
|
|
132
132
|
# @param enabled [Boolean] If limits monitoring is enabled for this item
|
133
133
|
# @return [Array<limits_set, persistence, enabled, red_low, yellow_low, red_high, yellow_high, green_low (optional), green_high (optional)] Limits information
|
134
134
|
def set(target_name, packet_name, item_name, red_low, yellow_low, yellow_high, red_high, green_low = nil, green_high = nil, limits_set = :CUSTOM, persistence = nil, enabled = true)
|
135
|
-
packet =
|
135
|
+
packet = _get_packet(target_name, packet_name)
|
136
136
|
item = packet.get_item(item_name)
|
137
137
|
limits = item.limits
|
138
138
|
if limits_set
|
@@ -172,7 +172,7 @@ module OpenC3
|
|
172
172
|
|
173
173
|
protected
|
174
174
|
|
175
|
-
def
|
175
|
+
def _get_packet(target_name, packet_name)
|
176
176
|
raise "LATEST packet not valid" if packet_name.upcase == LATEST_PACKET_NAME
|
177
177
|
|
178
178
|
packets = @config.telemetry[target_name.to_s.upcase]
|
@@ -183,17 +183,5 @@ module OpenC3
|
|
183
183
|
|
184
184
|
return packet
|
185
185
|
end
|
186
|
-
|
187
|
-
def includes_item?(ignored_items, target_name, packet_name, item_name)
|
188
|
-
ignored_items.each do |array_target_name, array_packet_name, array_item_name|
|
189
|
-
if (array_target_name == target_name) &&
|
190
|
-
(array_packet_name == packet_name) &&
|
191
|
-
# If the item name is nil we're ignoring an entire packet
|
192
|
-
(array_item_name == item_name || array_item_name.nil?)
|
193
|
-
return true
|
194
|
-
end
|
195
|
-
end
|
196
|
-
return false
|
197
|
-
end
|
198
186
|
end
|
199
187
|
end
|
@@ -1061,6 +1061,7 @@ module OpenC3
|
|
1061
1061
|
config['accessor'] = @accessor.class.to_s
|
1062
1062
|
config['accessor_args'] = @accessor.args
|
1063
1063
|
config['template'] = Base64.encode64(@template) if @template
|
1064
|
+
config['config_name'] = self.config_name
|
1064
1065
|
|
1065
1066
|
if @processors
|
1066
1067
|
processors = []
|
@@ -119,7 +119,8 @@ module OpenC3
|
|
119
119
|
# an xtce file to automatically determine the target name.
|
120
120
|
def process_file(filename, process_target_name)
|
121
121
|
# Handle .xtce files
|
122
|
-
|
122
|
+
extension = File.extname(filename).to_s.downcase
|
123
|
+
if extension == ".xtce" or extension == ".xml"
|
123
124
|
XtceParser.process(@commands, @telemetry, @warnings, filename, process_target_name)
|
124
125
|
return
|
125
126
|
end
|
@@ -17,7 +17,7 @@
|
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
module OpenC3
|
@@ -25,9 +25,9 @@ module OpenC3
|
|
25
25
|
# @param parser [ConfigParser] Configuration parser
|
26
26
|
# @param item [Packet] The current item
|
27
27
|
def self.parse(parser, item)
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
parser = FormatStringParser.new(parser)
|
29
|
+
parser.verify_parameters()
|
30
|
+
parser.create_format_string(item)
|
31
31
|
end
|
32
32
|
|
33
33
|
# @param parser [ConfigParser] Configuration parser
|
@@ -17,7 +17,7 @@
|
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
module OpenC3
|
@@ -31,9 +31,9 @@ module OpenC3
|
|
31
31
|
def self.parse(parser, packet, cmd_or_tlm, item, warnings)
|
32
32
|
raise parser.error("Items with STATE can't define LIMITS") if item.states
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
parser = LimitsParser.new(parser)
|
35
|
+
parser.verify_parameters(cmd_or_tlm)
|
36
|
+
parser.create_limits(packet, item, warnings)
|
37
37
|
end
|
38
38
|
|
39
39
|
def initialize(parser)
|
@@ -14,10 +14,10 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2023, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
module OpenC3
|
@@ -26,9 +26,9 @@ module OpenC3
|
|
26
26
|
# @param item [Packet] The current item
|
27
27
|
# @param cmd_or_tlm [String] Whether this is a command or telemetry packet
|
28
28
|
def self.parse(parser, item, cmd_or_tlm)
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
parser = LimitsResponseParser.new(parser)
|
30
|
+
parser.verify_parameters(cmd_or_tlm)
|
31
|
+
parser.create_limits_response(item)
|
32
32
|
end
|
33
33
|
|
34
34
|
# @param parser [ConfigParser] Configuration parser
|