openc3 5.13.0 → 5.14.1
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 +5 -2
- data/lib/openc3/microservices/interface_microservice.rb +10 -1
- data/lib/openc3/microservices/log_microservice.rb +6 -1
- data/lib/openc3/microservices/microservice.rb +28 -0
- 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 +6 -2
- data/lib/openc3/models/plugin_model.rb +6 -2
- data/lib/openc3/models/target_model.rb +105 -12
- data/lib/openc3/operators/microservice_operator.rb +23 -21
- data/lib/openc3/packets/commands.rb +4 -0
- data/lib/openc3/packets/packet.rb +92 -4
- data/lib/openc3/packets/packet_config.rb +62 -8
- data/lib/openc3/packets/telemetry.rb +4 -0
- 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 +43 -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 +6 -6
- 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
@@ -742,7 +742,7 @@ module OpenC3
|
|
742
742
|
end
|
743
743
|
end
|
744
744
|
|
745
|
-
def
|
745
|
+
def update_target_model(system)
|
746
746
|
target = system.targets[@name]
|
747
747
|
|
748
748
|
# Add in the information from the target and update
|
@@ -754,10 +754,11 @@ module OpenC3
|
|
754
754
|
@tlm_unique_id_mode = target.tlm_unique_id_mode
|
755
755
|
@limits_groups = system.limits.groups.keys
|
756
756
|
update()
|
757
|
+
end
|
757
758
|
|
758
|
-
|
759
|
-
|
760
|
-
Store.del("#{@scope}__openc3tlm__#{target_name}")
|
759
|
+
def update_store_telemetry(packet_hash, clear_old: true)
|
760
|
+
packet_hash.each do |target_name, packets|
|
761
|
+
Store.del("#{@scope}__openc3tlm__#{target_name}") if clear_old
|
761
762
|
packets.each do |packet_name, packet|
|
762
763
|
Logger.info "Configuring tlm packet: #{target_name} #{packet_name}"
|
763
764
|
begin
|
@@ -773,8 +774,11 @@ module OpenC3
|
|
773
774
|
CvtModel.set(json_hash, target_name: packet.target_name, packet_name: packet.packet_name, scope: @scope)
|
774
775
|
end
|
775
776
|
end
|
776
|
-
|
777
|
-
|
777
|
+
end
|
778
|
+
|
779
|
+
def update_store_commands(packet_hash, clear_old: true)
|
780
|
+
packet_hash.each do |target_name, packets|
|
781
|
+
Store.del("#{@scope}__openc3cmd__#{target_name}") if clear_old
|
778
782
|
packets.each do |packet_name, packet|
|
779
783
|
Logger.info "Configuring cmd packet: #{target_name} #{packet_name}"
|
780
784
|
begin
|
@@ -785,7 +789,9 @@ module OpenC3
|
|
785
789
|
end
|
786
790
|
end
|
787
791
|
end
|
788
|
-
|
792
|
+
end
|
793
|
+
|
794
|
+
def update_store_limits_groups(system)
|
789
795
|
system.limits.groups.each do |group, items|
|
790
796
|
begin
|
791
797
|
Store.hset("#{@scope}__limits_groups", group, JSON.generate(items))
|
@@ -794,23 +800,113 @@ module OpenC3
|
|
794
800
|
raise err
|
795
801
|
end
|
796
802
|
end
|
797
|
-
|
803
|
+
end
|
804
|
+
|
805
|
+
def update_store_limits_sets(system)
|
798
806
|
sets = Store.hgetall("#{@scope}__limits_sets")
|
799
807
|
sets ||= {}
|
800
808
|
system.limits.sets.each do |set|
|
801
809
|
sets[set.to_s] = "false" unless sets.key?(set.to_s)
|
802
810
|
end
|
803
811
|
Store.hmset("#{@scope}__limits_sets", *sets)
|
812
|
+
end
|
804
813
|
|
814
|
+
def update_store_item_map
|
805
815
|
# Create item_map
|
806
816
|
item_map_key = "#{@scope}__#{@name}__item_to_packet_map"
|
807
817
|
item_map = self.class.build_item_to_packet_map(@name, scope: @scope)
|
808
818
|
Store.set(item_map_key, JSON.generate(item_map, :allow_nan => true))
|
809
819
|
@@item_map_cache[@name] = [Time.now, item_map]
|
820
|
+
end
|
810
821
|
|
822
|
+
def update_store(system, clear_old: true)
|
823
|
+
update_target_model(system)
|
824
|
+
update_store_telemetry(system.telemetry.all, clear_old: clear_old)
|
825
|
+
update_store_commands(system.commands.all, clear_old: clear_old)
|
826
|
+
update_store_limits_groups(system)
|
827
|
+
update_store_limits_sets(system)
|
828
|
+
update_store_item_map()
|
811
829
|
return system
|
812
830
|
end
|
813
831
|
|
832
|
+
def dynamic_update(packets, cmd_or_tlm = :TELEMETRY, filename = "dynamic_tlm.txt")
|
833
|
+
# Build hash of targets/packets
|
834
|
+
packet_hash = {}
|
835
|
+
packets.each do |packet|
|
836
|
+
target_name = packet.target_name.upcase
|
837
|
+
packet_hash[target_name] ||= {}
|
838
|
+
packet_name = packet.packet_name.upcase
|
839
|
+
packet_hash[target_name][packet_name] = packet
|
840
|
+
end
|
841
|
+
|
842
|
+
# Update Redis
|
843
|
+
if cmd_or_tlm == :TELEMETRY
|
844
|
+
update_store_telemetry(packet_hash, clear_old: false)
|
845
|
+
update_store_item_map()
|
846
|
+
else
|
847
|
+
update_store_commands(packet_hash, clear_old: false)
|
848
|
+
end
|
849
|
+
|
850
|
+
# Build dynamic file for cmd_tlm
|
851
|
+
configs = {}
|
852
|
+
packets.each do |packet|
|
853
|
+
target_name = packet.target_name.upcase
|
854
|
+
configs[target_name] ||= ""
|
855
|
+
config = configs[target_name]
|
856
|
+
config << packet.to_config(cmd_or_tlm)
|
857
|
+
config << "\n"
|
858
|
+
end
|
859
|
+
configs.each do |target_name, config|
|
860
|
+
begin
|
861
|
+
bucket_key = "#{@scope}/targets_modified/#{target_name}/cmd_tlm/#{filename}"
|
862
|
+
client = Bucket.getClient()
|
863
|
+
client.put_object(
|
864
|
+
# Use targets_modified to save modifications
|
865
|
+
# This keeps the original target clean (read-only)
|
866
|
+
bucket: ENV['OPENC3_CONFIG_BUCKET'],
|
867
|
+
key: bucket_key,
|
868
|
+
body: config
|
869
|
+
)
|
870
|
+
end
|
871
|
+
end
|
872
|
+
|
873
|
+
# Inform microservices of new topics
|
874
|
+
# Need to tell loggers to log, and decom to decom
|
875
|
+
# We do this for no downtime
|
876
|
+
raw_topics = []
|
877
|
+
decom_topics = []
|
878
|
+
packets.each do |packet|
|
879
|
+
if cmd_or_tlm == :TELEMETRY
|
880
|
+
raw_topics << "#{@scope}__TELEMETRY__{#{@name}}__#{packet.packet_name.upcase}"
|
881
|
+
decom_topics << "#{@scope}__DECOM__{#{@name}}__#{packet.packet_name.upcase}"
|
882
|
+
else
|
883
|
+
raw_topics << "#{@scope}__COMMAND__{#{@name}}__#{packet.packet_name.upcase}"
|
884
|
+
decom_topics << "#{@scope}__DECOMCMD__{#{@name}}__#{packet.packet_name.upcase}"
|
885
|
+
end
|
886
|
+
end
|
887
|
+
if cmd_or_tlm == :TELEMETRY
|
888
|
+
Topic.write_topic("MICROSERVICE__#{@scope}__PACKETLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
|
889
|
+
add_topics_to_microservice("#{@scope}__PACKETLOG__#{@name}", raw_topics)
|
890
|
+
Topic.write_topic("MICROSERVICE__#{@scope}__DECOMLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
|
891
|
+
add_topics_to_microservice("#{@scope}__DECOMLOG__#{@name}", decom_topics)
|
892
|
+
Topic.write_topic("MICROSERVICE__#{@scope}__DECOM__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
|
893
|
+
add_topics_to_microservice("#{@scope}__DECOM__#{@name}", raw_topics)
|
894
|
+
else
|
895
|
+
Topic.write_topic("MICROSERVICE__#{@scope}__COMMANDLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
|
896
|
+
add_topics_to_microservice("#{@scope}__COMMANDLOG__#{@name}", raw_topics)
|
897
|
+
Topic.write_topic("MICROSERVICE__#{@scope}__DECOMCMDLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
|
898
|
+
add_topics_to_microservice("#{@scope}__DECOMCMDLOG__#{@name}", decom_topics)
|
899
|
+
end
|
900
|
+
end
|
901
|
+
|
902
|
+
def add_topics_to_microservice(microservice_name, topics)
|
903
|
+
model = MicroserviceModel.get_model(name: microservice_name, scope: @scope)
|
904
|
+
model.topics.concat(topics)
|
905
|
+
model.topics.uniq!
|
906
|
+
model.ignore_changes = true # Don't restart the microservice right now
|
907
|
+
model.update
|
908
|
+
end
|
909
|
+
|
814
910
|
def deploy_commmandlog_microservice(gem_path, variables, topics, instance = nil, parent = nil)
|
815
911
|
microservice_name = "#{@scope}__COMMANDLOG#{instance}__#{@name}"
|
816
912
|
microservice = MicroserviceModel.new(
|
@@ -990,6 +1086,7 @@ module OpenC3
|
|
990
1086
|
cmd: ["ruby", "multi_microservice.rb", *@children],
|
991
1087
|
work_dir: '/openc3/lib/openc3/microservices',
|
992
1088
|
plugin: @plugin,
|
1089
|
+
needs_dependencies: @needs_dependencies,
|
993
1090
|
scope: @scope
|
994
1091
|
)
|
995
1092
|
microservice.create
|
@@ -1048,7 +1145,6 @@ module OpenC3
|
|
1048
1145
|
decom_command_topic_list = []
|
1049
1146
|
packet_topic_list = []
|
1050
1147
|
decom_topic_list = []
|
1051
|
-
reduced_topic_list = []
|
1052
1148
|
begin
|
1053
1149
|
system.commands.packets(@name).each do |packet_name, packet|
|
1054
1150
|
command_topic_list << "#{@scope}__COMMAND__{#{@name}}__#{packet_name}"
|
@@ -1061,9 +1157,6 @@ module OpenC3
|
|
1061
1157
|
system.telemetry.packets(@name).each do |packet_name, packet|
|
1062
1158
|
packet_topic_list << "#{@scope}__TELEMETRY__{#{@name}}__#{packet_name}"
|
1063
1159
|
decom_topic_list << "#{@scope}__DECOM__{#{@name}}__#{packet_name}"
|
1064
|
-
reduced_topic_list << "#{@scope}__REDUCED_MINUTE__{#{@name}}__#{packet_name}"
|
1065
|
-
reduced_topic_list << "#{@scope}__REDUCED_HOUR__{#{@name}}__#{packet_name}"
|
1066
|
-
reduced_topic_list << "#{@scope}__REDUCED_DAY__{#{@name}}__#{packet_name}"
|
1067
1160
|
end
|
1068
1161
|
rescue
|
1069
1162
|
# No telemetry packets for this target
|
@@ -98,28 +98,30 @@ module OpenC3
|
|
98
98
|
previous_parent = @previous_microservices[microservice_name]['parent']
|
99
99
|
if @previous_microservices[microservice_name] != microservice_config
|
100
100
|
# CHANGED
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
if parent
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
#
|
117
|
-
|
118
|
-
|
101
|
+
if not microservice_config['ignore_changes']
|
102
|
+
scope = microservice_name.split("__")[0]
|
103
|
+
Logger.info("Changed microservice detected: #{microservice_name}\nWas: #{@previous_microservices[microservice_name]}\nIs: #{microservice_config}", scope: scope)
|
104
|
+
if parent or previous_parent
|
105
|
+
if parent == previous_parent
|
106
|
+
# Same Parent - Respawn parent
|
107
|
+
@changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
|
108
|
+
elsif parent and previous_parent
|
109
|
+
# Parent changed - Respawn both parents
|
110
|
+
@changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
|
111
|
+
@changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
|
112
|
+
elsif parent
|
113
|
+
# Moved under a parent - Respawn parent and kill standalone
|
114
|
+
@changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
|
115
|
+
@removed_microservices[microservice_name] = microservice_config
|
116
|
+
else # previous_parent
|
117
|
+
# Moved to standalone - Respawn previous parent and make new
|
118
|
+
@changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
|
119
|
+
@new_microservices[microservice_name] = microservice_config
|
120
|
+
end
|
121
|
+
else
|
122
|
+
# Respawn regular microservice
|
123
|
+
@changed_microservices[microservice_name] = microservice_config
|
119
124
|
end
|
120
|
-
else
|
121
|
-
# Respawn regular microservice
|
122
|
-
@changed_microservices[microservice_name] = microservice_config
|
123
125
|
end
|
124
126
|
end
|
125
127
|
else
|
@@ -303,6 +303,10 @@ module OpenC3
|
|
303
303
|
@config.commands
|
304
304
|
end
|
305
305
|
|
306
|
+
def dynamic_add_packet(packet, affect_ids: false)
|
307
|
+
@config.dynamic_add_packet(packet, :COMMAND, affect_ids: affect_ids)
|
308
|
+
end
|
309
|
+
|
306
310
|
protected
|
307
311
|
|
308
312
|
def set_parameters(command, params, range_checking)
|
@@ -89,6 +89,18 @@ module OpenC3
|
|
89
89
|
# @return [String] Base data for building packet
|
90
90
|
attr_reader :template
|
91
91
|
|
92
|
+
# @return [Array<Target Name, Packet Name>] Related response packet
|
93
|
+
attr_accessor :response
|
94
|
+
|
95
|
+
# @return [Array<Target Name, Packet Name>] Related error response packet
|
96
|
+
attr_accessor :error_response
|
97
|
+
|
98
|
+
# @return [Array<Target Name, Screen Name>] Related telemetry screen
|
99
|
+
attr_accessor :screen
|
100
|
+
|
101
|
+
# @return [Array<Array<Target Name, Packet Name, Item Name>>] Related items
|
102
|
+
attr_accessor :related_items
|
103
|
+
|
92
104
|
# Valid format types
|
93
105
|
VALUE_TYPES = [:RAW, :CONVERTED, :FORMATTED, :WITH_UNITS]
|
94
106
|
|
@@ -297,6 +309,10 @@ module OpenC3
|
|
297
309
|
@config_name
|
298
310
|
end
|
299
311
|
|
312
|
+
def clear_config_name
|
313
|
+
@config_name = nil
|
314
|
+
end
|
315
|
+
|
300
316
|
# (see Structure#buffer=)
|
301
317
|
def buffer=(buffer)
|
302
318
|
synchronize() do
|
@@ -306,7 +322,6 @@ module OpenC3
|
|
306
322
|
Logger.instance.error "#{@target_name} #{@packet_name} received with actual packet length of #{buffer.length} but defined length of #{@defined_length}"
|
307
323
|
end
|
308
324
|
@read_conversion_cache.clear if @read_conversion_cache
|
309
|
-
process()
|
310
325
|
end
|
311
326
|
end
|
312
327
|
|
@@ -861,6 +876,33 @@ module OpenC3
|
|
861
876
|
item.description = 'OpenC3 packet received count'
|
862
877
|
end
|
863
878
|
|
879
|
+
# Reset the packet to just derived items
|
880
|
+
def clear_all_non_derived_items
|
881
|
+
@defined_length = 0
|
882
|
+
@defined_length_bits = 0
|
883
|
+
@pos_bit_size = 0
|
884
|
+
@neg_bit_size = 0
|
885
|
+
@fixed_size = true
|
886
|
+
@short_buffer_allowed = false
|
887
|
+
@id_items = nil
|
888
|
+
@limits_items = nil
|
889
|
+
new_items = {}
|
890
|
+
new_sorted_items = []
|
891
|
+
@items.each do |name, item|
|
892
|
+
if item.data_type == :DERIVED
|
893
|
+
new_items[name] = item
|
894
|
+
end
|
895
|
+
end
|
896
|
+
@sorted_items.each do |item|
|
897
|
+
if item.data_type == :DERIVED
|
898
|
+
new_sorted_items << item
|
899
|
+
end
|
900
|
+
end
|
901
|
+
@items = new_items
|
902
|
+
@sorted_items = new_sorted_items
|
903
|
+
clear_config_name()
|
904
|
+
end
|
905
|
+
|
864
906
|
# Enable limits on an item by name
|
865
907
|
#
|
866
908
|
# @param name [String] Name of the item to enable limits
|
@@ -1008,6 +1050,13 @@ module OpenC3
|
|
1008
1050
|
else
|
1009
1051
|
config << "COMMAND #{@target_name.to_s.quote_if_necessary} #{@packet_name.to_s.quote_if_necessary} #{@default_endianness} \"#{@description}\"\n"
|
1010
1052
|
end
|
1053
|
+
if @accessor.class.to_s != 'OpenC3::BinaryAccessor'
|
1054
|
+
config << " ACCESSOR #{@accessor.class.to_s} #{@accessor.args.map { |a| a.to_s.quote_if_necessary }.join(" ")}\n"
|
1055
|
+
end
|
1056
|
+
# TODO: Add TEMPLATE_ENCODED so this can always be done inline regardless of content
|
1057
|
+
if @template
|
1058
|
+
config << " TEMPLATE '#{@template}'"
|
1059
|
+
end
|
1011
1060
|
config << " ALLOW_SHORT\n" if @short_buffer_allowed
|
1012
1061
|
config << " HAZARDOUS #{@hazardous_description.to_s.quote_if_necessary}\n" if @hazardous
|
1013
1062
|
config << " DISABLE_MESSAGES\n" if @messages_disabled
|
@@ -1025,7 +1074,7 @@ module OpenC3
|
|
1025
1074
|
|
1026
1075
|
if @meta
|
1027
1076
|
@meta.each do |key, values|
|
1028
|
-
config << " META #{key.to_s.quote_if_necessary} #{values.map { |a| a
|
1077
|
+
config << " META #{key.to_s.quote_if_necessary} #{values.map { |a| a.to_s.quote_if_necessary }.join(" ")}\n"
|
1029
1078
|
end
|
1030
1079
|
end
|
1031
1080
|
|
@@ -1043,6 +1092,20 @@ module OpenC3
|
|
1043
1092
|
end
|
1044
1093
|
end
|
1045
1094
|
|
1095
|
+
if @response
|
1096
|
+
config << " RESPONSE #{@response[0].to_s.quote_if_necessary} #{@response[1].to_s.quote_if_necessary}"
|
1097
|
+
end
|
1098
|
+
if @error_response
|
1099
|
+
config << " ERROR_RESPONSE #{@error_response[0].to_s.quote_if_necessary} #{@error_response[1].to_s.quote_if_necessary}"
|
1100
|
+
end
|
1101
|
+
if @screen
|
1102
|
+
config << " SCREEN #{@screen[0].to_s.quote_if_necessary} #{@screen[1].to_s.quote_if_necessary}"
|
1103
|
+
end
|
1104
|
+
if @related_items
|
1105
|
+
@related_items.each do |target_name, packet_name, item_name|
|
1106
|
+
config << " RELATED_ITEM #{target_name.to_s.quote_if_necessary} #{packet_name.to_s.quote_if_necessary} #{item_name.to_s.quote_if_necessary}"
|
1107
|
+
end
|
1108
|
+
end
|
1046
1109
|
config
|
1047
1110
|
end
|
1048
1111
|
|
@@ -1086,6 +1149,18 @@ module OpenC3
|
|
1086
1149
|
items << item.as_json(*a)
|
1087
1150
|
end
|
1088
1151
|
end
|
1152
|
+
if @response
|
1153
|
+
config['response'] = @response
|
1154
|
+
end
|
1155
|
+
if @error_response
|
1156
|
+
config['error_response'] = @error_response
|
1157
|
+
end
|
1158
|
+
if @screen
|
1159
|
+
config['screen'] = @screen
|
1160
|
+
end
|
1161
|
+
if @related_items
|
1162
|
+
config['related_items'] = @related_items
|
1163
|
+
end
|
1089
1164
|
|
1090
1165
|
config
|
1091
1166
|
end
|
@@ -1117,6 +1192,19 @@ module OpenC3
|
|
1117
1192
|
hash['items'].each do |item|
|
1118
1193
|
packet.define(PacketItem.from_json(item))
|
1119
1194
|
end
|
1195
|
+
if hash['response']
|
1196
|
+
packet.response = hash['response']
|
1197
|
+
end
|
1198
|
+
if hash['error_response']
|
1199
|
+
packet.error_response = hash['error_response']
|
1200
|
+
end
|
1201
|
+
if hash['screen']
|
1202
|
+
packet.screen = hash['screen']
|
1203
|
+
end
|
1204
|
+
if hash['related_items']
|
1205
|
+
packet.related_items = hash['related_items']
|
1206
|
+
end
|
1207
|
+
|
1120
1208
|
packet
|
1121
1209
|
end
|
1122
1210
|
|
@@ -1144,8 +1232,6 @@ module OpenC3
|
|
1144
1232
|
json_hash
|
1145
1233
|
end
|
1146
1234
|
|
1147
|
-
protected
|
1148
|
-
|
1149
1235
|
# Performs packet specific processing on the packet.
|
1150
1236
|
# Intended to only be run once for each packet received
|
1151
1237
|
def process(buffer = @buffer)
|
@@ -1156,6 +1242,8 @@ module OpenC3
|
|
1156
1242
|
end
|
1157
1243
|
end
|
1158
1244
|
|
1245
|
+
protected
|
1246
|
+
|
1159
1247
|
def handle_limits_states(item, value)
|
1160
1248
|
# Retrieve limits state for the given value
|
1161
1249
|
limits_state = item.state_colors[value]
|
@@ -214,7 +214,8 @@ module OpenC3
|
|
214
214
|
'PARAMETER', 'ID_ITEM', 'ID_PARAMETER', 'ARRAY_ITEM', 'ARRAY_PARAMETER', 'APPEND_ITEM',\
|
215
215
|
'APPEND_PARAMETER', 'APPEND_ID_ITEM', 'APPEND_ID_PARAMETER', 'APPEND_ARRAY_ITEM',\
|
216
216
|
'APPEND_ARRAY_PARAMETER', 'ALLOW_SHORT', 'HAZARDOUS', 'PROCESSOR', 'META',\
|
217
|
-
'DISABLE_MESSAGES', 'HIDDEN', 'DISABLED', 'ACCESSOR', 'TEMPLATE', 'TEMPLATE_FILE'
|
217
|
+
'DISABLE_MESSAGES', 'HIDDEN', 'DISABLED', 'ACCESSOR', 'TEMPLATE', 'TEMPLATE_FILE',\
|
218
|
+
'RESPONSE', 'ERROR_RESPONSE', 'SCREEN', 'RELATED_ITEM'
|
218
219
|
raise parser.error("No current packet for #{keyword}") unless @current_packet
|
219
220
|
|
220
221
|
process_current_packet(parser, keyword, params)
|
@@ -314,30 +315,60 @@ module OpenC3
|
|
314
315
|
hash = @cmd_id_value_hash[@current_packet.target_name]
|
315
316
|
hash = {} unless hash
|
316
317
|
@cmd_id_value_hash[@current_packet.target_name] = hash
|
317
|
-
update_id_value_hash(hash)
|
318
|
+
update_id_value_hash(@current_packet, hash)
|
318
319
|
else
|
319
320
|
@telemetry[@current_packet.target_name][@current_packet.packet_name] = @current_packet
|
320
321
|
hash = @tlm_id_value_hash[@current_packet.target_name]
|
321
322
|
hash = {} unless hash
|
322
323
|
@tlm_id_value_hash[@current_packet.target_name] = hash
|
323
|
-
update_id_value_hash(hash)
|
324
|
+
update_id_value_hash(@current_packet, hash)
|
324
325
|
end
|
325
326
|
@current_packet = nil
|
326
327
|
@current_item = nil
|
327
328
|
end
|
328
329
|
end
|
329
330
|
|
331
|
+
def dynamic_add_packet(packet, cmd_or_tlm = :TELEMETRY, affect_ids: false)
|
332
|
+
if cmd_or_tlm == :COMMAND
|
333
|
+
@commands[packet.target_name][packet.packet_name] = packet
|
334
|
+
|
335
|
+
if affect_ids
|
336
|
+
hash = @cmd_id_value_hash[packet.target_name]
|
337
|
+
hash = {} unless hash
|
338
|
+
@cmd_id_value_hash[packet.target_name] = hash
|
339
|
+
update_id_value_hash(packet, hash)
|
340
|
+
end
|
341
|
+
else
|
342
|
+
@telemetry[packet.target_name][packet.packet_name] = packet
|
343
|
+
|
344
|
+
# Update latest_data lookup for telemetry
|
345
|
+
packet.sorted_items.each do |item|
|
346
|
+
target_latest_data = @latest_data[packet.target_name]
|
347
|
+
target_latest_data[item.name] ||= []
|
348
|
+
latest_data_packets = target_latest_data[item.name]
|
349
|
+
latest_data_packets << packet unless latest_data_packets.include?(packet)
|
350
|
+
end
|
351
|
+
|
352
|
+
if affect_ids
|
353
|
+
hash = @tlm_id_value_hash[packet.target_name]
|
354
|
+
hash = {} unless hash
|
355
|
+
@tlm_id_value_hash[packet.target_name] = hash
|
356
|
+
update_id_value_hash(packet, hash)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
330
361
|
protected
|
331
362
|
|
332
|
-
def update_id_value_hash(hash)
|
333
|
-
if
|
363
|
+
def update_id_value_hash(packet, hash)
|
364
|
+
if packet.id_items.length > 0
|
334
365
|
key = []
|
335
|
-
|
366
|
+
packet.id_items.each do |item|
|
336
367
|
key << item.id_value
|
337
368
|
end
|
338
|
-
hash[key] =
|
369
|
+
hash[key] = packet
|
339
370
|
else
|
340
|
-
hash['CATCHALL'.freeze] =
|
371
|
+
hash['CATCHALL'.freeze] = packet
|
341
372
|
end
|
342
373
|
end
|
343
374
|
|
@@ -460,7 +491,30 @@ module OpenC3
|
|
460
491
|
rescue Exception => err
|
461
492
|
raise parser.error(err)
|
462
493
|
end
|
494
|
+
|
495
|
+
when 'RESPONSE'
|
496
|
+
usage = "#{keyword} <Target Name> <Packet Name>"
|
497
|
+
parser.verify_num_parameters(2, 2, usage)
|
498
|
+
@current_packet.response = [params[0].upcase, params[1].upcase]
|
499
|
+
|
500
|
+
when 'ERROR_RESPONSE'
|
501
|
+
usage = "#{keyword} <Target Name> <Packet Name>"
|
502
|
+
parser.verify_num_parameters(2, 2, usage)
|
503
|
+
@current_packet.error_response = [params[0].upcase, params[1].upcase]
|
504
|
+
|
505
|
+
when 'SCREEN'
|
506
|
+
usage = "#{keyword} <Target Name> <Screen Name>"
|
507
|
+
parser.verify_num_parameters(2, 2, usage)
|
508
|
+
@current_packet.screen = [params[0].upcase, params[1].upcase]
|
509
|
+
|
510
|
+
when 'RELATED_ITEM'
|
511
|
+
usage = "#{keyword} <Target Name> <Packet Name> <Item Name>"
|
512
|
+
parser.verify_num_parameters(3, 3, usage)
|
513
|
+
@current_packet.related_items ||= []
|
514
|
+
@current_packet.related_items << [params[0].upcase, params[1].upcase, params[2].upcase]
|
515
|
+
|
463
516
|
end
|
517
|
+
|
464
518
|
end
|
465
519
|
|
466
520
|
def process_current_item(parser, keyword, params)
|
@@ -525,6 +525,17 @@ module OpenC3
|
|
525
525
|
# Private implementation details
|
526
526
|
###########################################################################
|
527
527
|
|
528
|
+
# This must be here for custom microservices that might block.
|
529
|
+
# Overriden by running_script.rb for script sleep
|
530
|
+
def openc3_script_sleep(sleep_time = nil)
|
531
|
+
if sleep_time
|
532
|
+
sleep(sleep_time)
|
533
|
+
else
|
534
|
+
prompt("Press any key to continue...")
|
535
|
+
end
|
536
|
+
return false
|
537
|
+
end
|
538
|
+
|
528
539
|
# Creates a string with the parameters upcased
|
529
540
|
def _upcase(target_name, packet_name, item_name)
|
530
541
|
"#{target_name.upcase} #{packet_name.upcase} #{item_name.upcase}"
|
data/lib/openc3/script/script.rb
CHANGED
@@ -93,17 +93,8 @@ module OpenC3
|
|
93
93
|
$script_runner_api_server = nil
|
94
94
|
end
|
95
95
|
|
96
|
-
# This isn't part of the public API because users should use wait()
|
97
|
-
def openc3_script_sleep(sleep_time = nil)
|
98
|
-
if sleep_time
|
99
|
-
sleep(sleep_time)
|
100
|
-
else
|
101
|
-
prompt("Press any key to continue...")
|
102
|
-
end
|
103
|
-
return false
|
104
|
-
end
|
105
|
-
|
106
96
|
# Internal method used in scripts when encountering a hazardous command
|
97
|
+
# Not part of public APIs but must be implemented here
|
107
98
|
def prompt_for_hazardous(target_name, cmd_name, hazardous_description)
|
108
99
|
loop do
|
109
100
|
message = "Warning: Command #{target_name} #{cmd_name} is Hazardous. "
|
@@ -140,6 +131,7 @@ module OpenC3
|
|
140
131
|
default = ''
|
141
132
|
if blank_or_default != true && blank_or_default != false
|
142
133
|
question << " (default = #{blank_or_default})"
|
134
|
+
default = blank_or_default.to_s
|
143
135
|
allow_blank = true
|
144
136
|
else
|
145
137
|
allow_blank = blank_or_default
|
@@ -150,7 +142,9 @@ module OpenC3
|
|
150
142
|
answer.chomp!
|
151
143
|
break if allow_blank
|
152
144
|
end
|
153
|
-
|
145
|
+
if answer.empty? and !default.empty?
|
146
|
+
answer = default
|
147
|
+
end
|
154
148
|
return answer
|
155
149
|
end
|
156
150
|
|
@@ -162,7 +156,7 @@ module OpenC3
|
|
162
156
|
|
163
157
|
def message_box(string, *buttons, **options)
|
164
158
|
print "#{string} (#{buttons.join(", ")}): "
|
165
|
-
print "Details: #{details}\n" if details
|
159
|
+
print "Details: #{details}\n" if options['details']
|
166
160
|
gets.chomp
|
167
161
|
end
|
168
162
|
|
@@ -160,5 +160,24 @@ module OpenC3
|
|
160
160
|
@pipe_writer.write('.')
|
161
161
|
@connected = false
|
162
162
|
end
|
163
|
+
|
164
|
+
def set_option(option_name, option_values)
|
165
|
+
option_name_upcase = option_name.upcase
|
166
|
+
|
167
|
+
case option_name_upcase
|
168
|
+
when 'KEEPALIVE'
|
169
|
+
@write_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
170
|
+
@read_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
171
|
+
when 'KEEPCNT'
|
172
|
+
@write_socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPCNT, Integer(option_values[0]))
|
173
|
+
@read_socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPCNT, Integer(option_values[0]))
|
174
|
+
when 'KEEPIDLE'
|
175
|
+
@write_socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE, Integer(option_values[0]))
|
176
|
+
@read_socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE, Integer(option_values[0]))
|
177
|
+
when 'KEEPINTVL'
|
178
|
+
@write_socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL, Integer(option_values[0]))
|
179
|
+
@read_socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL, Integer(option_values[0]))
|
180
|
+
end
|
181
|
+
end
|
163
182
|
end
|
164
183
|
end
|