openc3 5.13.0 → 5.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
data/lib/openc3/system/system.rb
CHANGED
@@ -60,6 +60,9 @@ module OpenC3
|
|
60
60
|
# The current limits set
|
61
61
|
@@limits_set = nil
|
62
62
|
|
63
|
+
# Callbacks to call once @@instance is created
|
64
|
+
@@post_instance_callbacks = []
|
65
|
+
|
63
66
|
# @return [Symbol] The current limits_set of the system returned from Redis
|
64
67
|
def self.limits_set
|
65
68
|
unless @@limits_set
|
@@ -72,6 +75,14 @@ module OpenC3
|
|
72
75
|
@@limits_set = value.to_s.intern
|
73
76
|
end
|
74
77
|
|
78
|
+
def self.add_post_instance_callback(callback)
|
79
|
+
if @@instance
|
80
|
+
callback.call()
|
81
|
+
else
|
82
|
+
@@post_instance_callbacks << callback
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
75
86
|
def self.setup_targets(target_names, base_dir, scope:)
|
76
87
|
# Nothing to do if there are no targets
|
77
88
|
return if target_names.nil? or target_names.length == 0
|
@@ -92,6 +103,18 @@ module OpenC3
|
|
92
103
|
zip_file.extract(entry, path) unless File.exist?(path)
|
93
104
|
end
|
94
105
|
end
|
106
|
+
|
107
|
+
# Now add any modifications in targets_modified/TARGET/cmd_tlm
|
108
|
+
# This adds support for remembering dynamically created packets
|
109
|
+
# target.txt must be configured to either use all files in cmd_tlm folder (default)
|
110
|
+
# or have a predetermined empty file like dynamic_tlm.txt
|
111
|
+
bucket_path = "#{scope}/targets_modified/#{target_name}/cmd_tlm"
|
112
|
+
dirs, files = bucket.list_files(bucket: ENV['OPENC3_CONFIG_BUCKET'], path: bucket_path)
|
113
|
+
files.each do |file|
|
114
|
+
bucket_key = File.join(bucket_path, file['name'])
|
115
|
+
local_path = "#{base_dir}/targets/#{target_name}/cmd_tlm/#{file['name']}"
|
116
|
+
bucket.get_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: bucket_key, path: local_path)
|
117
|
+
end
|
95
118
|
end
|
96
119
|
|
97
120
|
# Build System from targets
|
@@ -109,17 +132,36 @@ module OpenC3
|
|
109
132
|
raise "System.instance parameters are required on first call" unless target_names and target_config_dir
|
110
133
|
|
111
134
|
@@instance_mutex.synchronize do
|
135
|
+
return @@instance if @@instance
|
112
136
|
@@instance ||= self.new(target_names, target_config_dir)
|
137
|
+
@@post_instance_callbacks.each do |callback|
|
138
|
+
callback.call
|
139
|
+
end
|
113
140
|
return @@instance
|
114
141
|
end
|
115
142
|
end
|
116
143
|
|
144
|
+
# Dynamically add packets to the system instance
|
145
|
+
#
|
146
|
+
# @param dynamic_packets [Array of packets]
|
147
|
+
# @param cmd_or_tlm [Symbol] :COMMAND or :TELEMETRY
|
148
|
+
# @param affect_ids [Boolean] Whether to affect packet id lookup or not
|
149
|
+
def self.dynamic_update(dynamic_packets, cmd_or_tlm = :TELEMETRY, affect_ids: false)
|
150
|
+
dynamic_packets.each do |packet|
|
151
|
+
if cmd_or_tlm == :TELEMETRY
|
152
|
+
@@instance.telemetry.dynamic_add_packet(packet, affect_ids: affect_ids)
|
153
|
+
else
|
154
|
+
@@instance.commands.dynamic_add_packet(packet, affect_ids: affect_ids)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
117
159
|
# Create a new System object.
|
118
160
|
#
|
119
161
|
# @param target_names [Array of target names]
|
120
162
|
# @param target_config_dir Directory where target config folders are
|
121
163
|
def initialize(target_names, target_config_dir)
|
122
|
-
OpenC3.add_to_search_path(target_config_dir, true)
|
164
|
+
OpenC3.add_to_search_path(target_config_dir, true) if target_config_dir
|
123
165
|
@targets = {}
|
124
166
|
@packet_config = PacketConfig.new
|
125
167
|
@commands = Commands.new(@packet_config)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2024 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# This program is free software; you can modify and/or redistribute it
|
@@ -116,6 +116,20 @@ module OpenC3
|
|
116
116
|
false
|
117
117
|
end
|
118
118
|
|
119
|
+
if @@language == 'py'
|
120
|
+
# If we're using Python create a requirements.txt and list it in the gemspec
|
121
|
+
# However, don't write over an existing file they may have already created
|
122
|
+
unless File.exist?("requirements.txt")
|
123
|
+
File.open("requirements.txt", 'w') do |file|
|
124
|
+
file.puts "# Python dependencies"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
gemspec_filename = Dir['*.gemspec'][0]
|
128
|
+
gemspec = File.read(gemspec_filename)
|
129
|
+
gemspec.gsub!('plugin.txt', 'plugin.txt requirements.txt')
|
130
|
+
File.write(gemspec_filename, gemspec)
|
131
|
+
end
|
132
|
+
|
119
133
|
# Add this target to plugin.txt
|
120
134
|
File.open("plugin.txt", 'a') do |file|
|
121
135
|
file.puts <<~DOC
|
@@ -252,7 +252,7 @@ module OpenC3
|
|
252
252
|
# New install of same plugin - Leave it alone
|
253
253
|
end
|
254
254
|
else
|
255
|
-
# No
|
255
|
+
# No existing instance.json, but we found the same gem
|
256
256
|
# This shouldn't happen without users using this wrong
|
257
257
|
# We will update
|
258
258
|
found = true
|
@@ -0,0 +1,126 @@
|
|
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/utilities/store'
|
20
|
+
|
21
|
+
module OpenC3
|
22
|
+
class StoreQueued
|
23
|
+
# Variable that holds the singleton instance
|
24
|
+
@instance = nil
|
25
|
+
|
26
|
+
# Mutex used to ensure that only one instance is created
|
27
|
+
@@instance_mutex = Mutex.new
|
28
|
+
|
29
|
+
# Get the singleton instance
|
30
|
+
# Sets the update interval to 1 second by default
|
31
|
+
def self.instance(update_interval = 1) # seconds
|
32
|
+
return @instance if @instance
|
33
|
+
|
34
|
+
@@instance_mutex.synchronize do
|
35
|
+
@instance ||= self.new(update_interval)
|
36
|
+
return @instance
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Delegate all unknown class methods to delegate to the instance
|
41
|
+
def self.method_missing(message, *args, **kwargs, &)
|
42
|
+
self.instance.public_send(message, *args, **kwargs, &)
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize(update_interval)
|
46
|
+
@update_interval = update_interval
|
47
|
+
@store = store_instance()
|
48
|
+
# Queue to hold the store requests
|
49
|
+
@store_queue = Queue.new
|
50
|
+
# Sleeper used to delay update thread
|
51
|
+
@update_sleeper = Sleeper.new
|
52
|
+
|
53
|
+
at_exit() do
|
54
|
+
shutdown()
|
55
|
+
end
|
56
|
+
|
57
|
+
# Thread used to call methods on the store
|
58
|
+
@update_thread = OpenC3.safe_thread(self.class.to_s) do
|
59
|
+
store_thread_body()
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def store_thread_body
|
64
|
+
while true
|
65
|
+
start_time = Time.now
|
66
|
+
|
67
|
+
unless @store_queue.empty?
|
68
|
+
# Pipeline the requests to redis to improve performance
|
69
|
+
@store.pipelined do
|
70
|
+
while !@store_queue.empty?
|
71
|
+
action = @store_queue.pop()
|
72
|
+
@store.method_missing(action.message, *action.args, **action.kwargs, &action.block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Only check whether to update at a set interval
|
78
|
+
run_time = Time.now - start_time
|
79
|
+
sleep_time = @update_interval - run_time
|
80
|
+
sleep_time = 0 if sleep_time < 0
|
81
|
+
break if @update_sleeper.sleep(sleep_time)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def shutdown
|
86
|
+
@update_sleeper.cancel if @update_sleeper
|
87
|
+
OpenC3.kill_thread(self, @update_thread) if @update_thread
|
88
|
+
@update_thread = nil
|
89
|
+
# Drain the queue before shutdown
|
90
|
+
unless @store_queue.empty?
|
91
|
+
# Pipeline the requests to redis to improve performance
|
92
|
+
@store.pipelined do
|
93
|
+
while !@store_queue.empty?
|
94
|
+
action = @store_queue.pop()
|
95
|
+
@store.method_missing(action.message, *action.args, **action.kwargs, &action.block)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Record the message for pipelining by the thread
|
102
|
+
def method_missing(message, *args, **kwargs, &block)
|
103
|
+
o = OpenStruct.new
|
104
|
+
o.message = message
|
105
|
+
o.args = args
|
106
|
+
o.kwargs = kwargs
|
107
|
+
o.block = block
|
108
|
+
@store_queue.push(o)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns the store we're working with
|
112
|
+
def store_instance
|
113
|
+
Store.instance
|
114
|
+
end
|
115
|
+
|
116
|
+
def graceful_kill
|
117
|
+
# Do nothing
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class EphemeralStoreQueued < StoreQueued
|
122
|
+
def store_instance
|
123
|
+
EphemeralStore.instance
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/openc3/version.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
OPENC3_VERSION = '5.
|
3
|
+
OPENC3_VERSION = '5.14.1'
|
4
4
|
module OpenC3
|
5
5
|
module Version
|
6
6
|
MAJOR = '5'
|
7
|
-
MINOR = '
|
8
|
-
PATCH = '
|
7
|
+
MINOR = '14'
|
8
|
+
PATCH = '1'
|
9
9
|
OTHER = ''
|
10
|
-
BUILD = '
|
10
|
+
BUILD = '902e54e502f6070c58183746a7db21a50e7b5263'
|
11
11
|
end
|
12
|
-
VERSION = '5.
|
13
|
-
GEM_VERSION = '5.
|
12
|
+
VERSION = '5.14.1'
|
13
|
+
GEM_VERSION = '5.14.1'
|
14
14
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
3
|
# Create the overall gemspec
|
4
|
-
|
4
|
+
Gem::Specification.new do |s|
|
5
5
|
s.name = '<%= plugin_name %>'
|
6
6
|
s.summary = 'OpenC3 <%= plugin_name %> plugin'
|
7
7
|
s.description = <<-EOF
|
@@ -10,7 +10,7 @@ spec = Gem::Specification.new do |s|
|
|
10
10
|
s.license = 'MIT'
|
11
11
|
s.authors = ['Anonymous']
|
12
12
|
s.email = ['name@domain.com']
|
13
|
-
s.homepage = 'https://github.com/OpenC3/
|
13
|
+
s.homepage = 'https://github.com/OpenC3/cosmos'
|
14
14
|
s.platform = Gem::Platform::RUBY
|
15
15
|
|
16
16
|
if ENV['VERSION']
|
@@ -0,0 +1 @@
|
|
1
|
+
Put image files in this directory for use in Telemetry Viewer Canvas Image widgets such as CANVASIMAGE and CANVASIMAGEVALUE.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= tool_name %>",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.14.1",
|
4
4
|
"scripts": {
|
5
5
|
"ng": "ng",
|
6
6
|
"start": "ng serve",
|
@@ -12,23 +12,23 @@
|
|
12
12
|
},
|
13
13
|
"private": true,
|
14
14
|
"dependencies": {
|
15
|
-
"@openc3/tool-common": "5.
|
16
|
-
"@angular/animations": "^17.0.
|
17
|
-
"@angular/cdk": "^17.0.
|
18
|
-
"@angular/common": "^17.0.
|
19
|
-
"@angular/compiler": "^17.0.
|
20
|
-
"@angular/core": "^17.0.
|
21
|
-
"@angular/forms": "^17.0.
|
22
|
-
"@angular/material": "17.0.
|
23
|
-
"@angular/platform-browser": "^17.0.
|
24
|
-
"@angular/platform-browser-dynamic": "^17.0.
|
25
|
-
"@angular/router": "^17.0.
|
26
|
-
"@astrouxds/astro-web-components": "7.
|
15
|
+
"@openc3/tool-common": "5.14.1",
|
16
|
+
"@angular/animations": "^17.0.8",
|
17
|
+
"@angular/cdk": "^17.0.4",
|
18
|
+
"@angular/common": "^17.0.8",
|
19
|
+
"@angular/compiler": "^17.0.8",
|
20
|
+
"@angular/core": "^17.0.8",
|
21
|
+
"@angular/forms": "^17.0.8",
|
22
|
+
"@angular/material": "17.0.4",
|
23
|
+
"@angular/platform-browser": "^17.0.8",
|
24
|
+
"@angular/platform-browser-dynamic": "^17.0.8",
|
25
|
+
"@angular/router": "^17.0.8",
|
26
|
+
"@astrouxds/astro-web-components": "7.20.0",
|
27
27
|
"rxjs": "~7.8.0",
|
28
|
-
"single-spa": "
|
28
|
+
"single-spa": "5.9.5",
|
29
29
|
"single-spa-angular": "^9.0.1",
|
30
30
|
"tslib": "^2.6.2",
|
31
|
-
"zone.js": "~0.14.
|
31
|
+
"zone.js": "~0.14.3"
|
32
32
|
},
|
33
33
|
"devDependencies": {
|
34
34
|
"@angular-builders/custom-webpack": "17.0.0",
|