openc3 6.0.2 → 6.1.0
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.
- checksums.yaml +4 -4
- data/bin/pipinstall +1 -1
- data/bin/pipuninstall +10 -0
- data/data/config/parameter_modifiers.yaml +11 -0
- data/data/config/widgets.yaml +38 -1
- data/lib/openc3/api/settings_api.rb +35 -2
- data/lib/openc3/api/tlm_api.rb +11 -2
- data/lib/openc3/config/config_parser.rb +4 -2
- data/lib/openc3/io/json_api_object.rb +4 -4
- data/lib/openc3/microservices/interface_decom_common.rb +4 -0
- data/lib/openc3/microservices/periodic_microservice.rb +26 -1
- data/lib/openc3/migrations/20250108060000_news_feed.rb +15 -0
- data/lib/openc3/models/activity_model.rb +11 -4
- data/lib/openc3/models/news_model.rb +38 -0
- data/lib/openc3/models/python_package_model.rb +2 -1
- data/lib/openc3/models/scope_model.rb +3 -1
- data/lib/openc3/models/timeline_model.rb +3 -6
- data/lib/openc3/packets/commands.rb +2 -1
- data/lib/openc3/packets/packet.rb +1 -1
- data/lib/openc3/script/calendar.rb +21 -18
- data/lib/openc3/script/plugins.rb +10 -2
- data/lib/openc3/script/script.rb +11 -6
- data/lib/openc3/script/script_runner.rb +22 -11
- data/lib/openc3/script/storage.rb +3 -3
- data/lib/openc3/script/tables.rb +49 -0
- data/lib/openc3/script/web_socket_api.rb +2 -2
- data/lib/openc3/utilities/local_mode.rb +13 -2
- data/lib/openc3/utilities/target_file.rb +10 -2
- data/lib/openc3/version.rb +6 -6
- data/templates/tool_angular/package.json +2 -2
- data/templates/tool_react/package.json +1 -1
- data/templates/tool_svelte/package.json +1 -1
- data/templates/tool_vue/package.json +3 -3
- data/templates/widget/package.json +2 -2
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be3485e674a1fe4a236e3a71b57aff4d7d7398a0638a21d8069994739a53edab
|
4
|
+
data.tar.gz: 911ee7331cc9100dc1dfbb7abe3e7f38baaa5b201be2974d882f0ef01701e9da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eafafaac4ae90e0bb594446fefdfc7b9e6eb96be4b08c5798d827d60a2377fad9252bca9d2e4495b8d4073283aa957d89fab0214d998bd9c4bbbb5d9174000cc
|
7
|
+
data.tar.gz: ea90586ba1347a74964c3cbb181810463caf507bb22c88bed8253b2fc9164b7f1648300d35163aba95f9e96f29f31ccb6f4406063dfefa7d33fd8057acddc416
|
data/bin/pipinstall
CHANGED
data/bin/pipuninstall
ADDED
@@ -71,6 +71,17 @@ WRITE_CONVERSION:
|
|
71
71
|
factor is applied to the value entered by the user before it is written into
|
72
72
|
the binary command packet and sent.
|
73
73
|
|
74
|
+
When applying a write_conversion sometimes the data type changes,
|
75
|
+
e.g. creating a UINT from an input STRING (for an example of this see
|
76
|
+
[ip_write_conversion.rb](https://github.com/OpenC3/cosmos/blob/main/openc3/lib/openc3/conversions/ip_write_conversion.rb)
|
77
|
+
or [ip_write_conversion.py](https://github.com/OpenC3/cosmos/blob/main/openc3/python/openc3/conversions/ip_write_conversion.py)).
|
78
|
+
In this case, the command definition data type is UINT and the min, max values don't matter
|
79
|
+
(but must be given) so are typically set to MIN MAX. The default value is important
|
80
|
+
and should be specified as a string. For a full example see the IP_ADDRESS parameter
|
81
|
+
in the TIME_OFFSET command definition of the COSMOS Demo
|
82
|
+
[INST inst_cmds.txt](https://github.com/OpenC3/cosmos/blob/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST/cmd_tlm/inst_cmds.txt)
|
83
|
+
or [INST2 inst_cmds.txt](https://github.com/OpenC3/cosmos/blob/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/cmd_tlm/inst_cmds.txt).
|
84
|
+
|
74
85
|
:::info Multiple write conversions on command parameters
|
75
86
|
When a command is built, each item gets written (and write conversions are run)
|
76
87
|
to set the default value. Then items are written (again write conversions are run)
|
data/data/config/widgets.yaml
CHANGED
@@ -245,6 +245,40 @@ Telemetry Widgets:
|
|
245
245
|
example: |
|
246
246
|
ARRAY INST HEALTH_STATUS ARY 250 80 "0x%x" 6 FORMATTED
|
247
247
|
ARRAY INST HEALTH_STATUS ARY2 200 100 nil 4 WITH_UNITS
|
248
|
+
ARRAYPLOT:
|
249
|
+
summary: Plot an array of values.
|
250
|
+
description:
|
251
|
+
The item can either be a simple array or a 2D array of x values and y values, e.g. [[x1, x2, x3], [y1, y2, y3]].
|
252
|
+
If the X_AXIS setting is not specified, the X axis starts with 0 and increments by 1.
|
253
|
+
If the X_AXIS setting is used the x values of a 2D array will be ignored.
|
254
|
+
settings:
|
255
|
+
TITLE:
|
256
|
+
summary: Title of the plot
|
257
|
+
parameters:
|
258
|
+
- name: Title
|
259
|
+
required: true
|
260
|
+
description: Title of the plot
|
261
|
+
values: .+
|
262
|
+
X_AXIS:
|
263
|
+
summary: Define the x-axis parameters for the plot
|
264
|
+
parameters:
|
265
|
+
- name: Start
|
266
|
+
required: true
|
267
|
+
description: Start value for the x-axis
|
268
|
+
values: .+
|
269
|
+
- name: Step
|
270
|
+
required: true
|
271
|
+
description: Step value for the x-axis
|
272
|
+
values: .+
|
273
|
+
# Inject the graph settings
|
274
|
+
<%= MetaConfigParser.load('graph_settings.yaml').to_meta_config_yaml(8) %>
|
275
|
+
example: |
|
276
|
+
ARRAYPLOT
|
277
|
+
SETTING TITLE "Array Data"
|
278
|
+
SETTING ITEM INST HEALTH_STATUS ARY
|
279
|
+
SETTING ITEM INST HEALTH_STATUS ARY2
|
280
|
+
SETTING SIZE 600 400
|
281
|
+
SETTING X_AXIS 10 10
|
248
282
|
BLOCK:
|
249
283
|
summary: Displays BLOCK data organized into rows and space separated
|
250
284
|
parameters:
|
@@ -372,6 +406,7 @@ Telemetry Widgets:
|
|
372
406
|
FORMATVALUE INST LATEST TEMP1 %.2f CONVERTED 20
|
373
407
|
LABELLED:
|
374
408
|
summary: Displays a LABEL followed by a LED
|
409
|
+
description: See the LED widget for more information
|
375
410
|
parameters:
|
376
411
|
- name: Target name
|
377
412
|
required: true
|
@@ -688,6 +723,7 @@ Telemetry Widgets:
|
|
688
723
|
Additional values can be added by using the LED_COLOR setting. For example
|
689
724
|
LED INST PARAMS VALUE3 RAW can be followed by SETTING LED_COLOR 0 GREEN,
|
690
725
|
SETTING LED_COLOR 1 RED, and SETTING LED_COLOR ANY ORANGE.
|
726
|
+
See LIMITSCOLOR for a widget that displays a circle depicting the limits color of an item.
|
691
727
|
parameters:
|
692
728
|
- name: Target name
|
693
729
|
required: true
|
@@ -791,7 +827,8 @@ Telemetry Widgets:
|
|
791
827
|
LIMITSCOLUMN INST HEALTH_STATUS TEMP1 CONVERTED 50 200
|
792
828
|
LIMITSCOLUMN INST HEALTH_STATUS TEMP1
|
793
829
|
LIMITSCOLOR:
|
794
|
-
summary: Displays a circle depicting the limits color of an item
|
830
|
+
summary: Displays a circle depicting the limits color of an item.
|
831
|
+
See LED for a widget that displays a circle which changes to an arbitrary color based on telemetry values.
|
795
832
|
parameters:
|
796
833
|
- name: Target name
|
797
834
|
required: true
|
@@ -14,13 +14,23 @@
|
|
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 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
|
+
begin
|
24
|
+
require 'openc3-enterprise/version'
|
25
|
+
VERSION = OPENC3_ENTERPRISE_VERSION
|
26
|
+
ENTERPRISE = true
|
27
|
+
rescue LoadError
|
28
|
+
require 'openc3/version'
|
29
|
+
VERSION = OPENC3_VERSION
|
30
|
+
ENTERPRISE = false
|
31
|
+
end
|
23
32
|
require 'openc3/models/setting_model'
|
33
|
+
require 'openc3/models/news_model'
|
24
34
|
|
25
35
|
module OpenC3
|
26
36
|
module Api
|
@@ -31,7 +41,8 @@ module OpenC3
|
|
31
41
|
'get_setting',
|
32
42
|
'get_settings',
|
33
43
|
'set_setting',
|
34
|
-
'save_setting' # DEPRECATED
|
44
|
+
'save_setting', # DEPRECATED
|
45
|
+
'update_news',
|
35
46
|
])
|
36
47
|
|
37
48
|
def list_settings(manual: false, scope: $openc3_scope, token: $openc3_token)
|
@@ -68,5 +79,27 @@ module OpenC3
|
|
68
79
|
end
|
69
80
|
# save_setting is DEPRECATED
|
70
81
|
alias save_setting set_setting
|
82
|
+
|
83
|
+
# Update the news feed on demand to respond to frontend setting changes
|
84
|
+
def update_news(manual: false, scope: $openc3_scope, token: $openc3_token)
|
85
|
+
authorize(permission: 'admin', manual: manual, scope: scope, token: token)
|
86
|
+
conn = Faraday.new(
|
87
|
+
url: 'https://news.openc3.com',
|
88
|
+
params: {version: VERSION, enterprise: ENTERPRISE},
|
89
|
+
)
|
90
|
+
response = conn.get('/news')
|
91
|
+
if response.success?
|
92
|
+
NewsModel.set(response.body)
|
93
|
+
else
|
94
|
+
NewsModel.news_error(response)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Test code to update the news feed with a dummy message
|
98
|
+
# data = NewsModel.all()
|
99
|
+
# json = JSON.parse(data)
|
100
|
+
# json.unshift( { date: Time.now.utc.iso8601, title: "News at #{Time.now}", body: "The news feed has been updated at #{Time.now}." })
|
101
|
+
# json.pop if json.length > 5
|
102
|
+
# NewsModel.set(json.to_json)
|
103
|
+
end
|
71
104
|
end
|
72
105
|
end
|
data/lib/openc3/api/tlm_api.rb
CHANGED
@@ -35,7 +35,7 @@ module OpenC3
|
|
35
35
|
'tlm_raw',
|
36
36
|
'tlm_formatted',
|
37
37
|
'tlm_with_units',
|
38
|
-
'tlm_variable',
|
38
|
+
'tlm_variable', # DEPRECATED
|
39
39
|
'set_tlm',
|
40
40
|
'inject_tlm',
|
41
41
|
'override_tlm',
|
@@ -131,7 +131,16 @@ module OpenC3
|
|
131
131
|
if item_hash
|
132
132
|
item_hash = item_hash.transform_keys(&:upcase)
|
133
133
|
# Check that the items exist ... exceptions are raised if not
|
134
|
-
TargetModel.packet_items(target_name, packet_name, item_hash.keys, scope: scope)
|
134
|
+
items = TargetModel.packet_items(target_name, packet_name, item_hash.keys, scope: scope)
|
135
|
+
if type == :CONVERTED
|
136
|
+
# If the type is converted, check that the item states are valid
|
137
|
+
item_hash.each do |item_name, item_value|
|
138
|
+
item = items.find { |i| i['name'] == item_name.to_s.upcase }
|
139
|
+
if item['states'] && !item['states'][item_value]
|
140
|
+
raise "Unknown state '#{item_value}' for #{item['name']}, must be one of #{item['states'].keys.join(', ')}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
135
144
|
else
|
136
145
|
# Check that the packet exists ... exceptions are raised if not
|
137
146
|
TargetModel.packet(target_name, packet_name, scope: scope)
|
@@ -380,9 +380,11 @@ module OpenC3
|
|
380
380
|
return Float::INFINITY
|
381
381
|
when 'NEG_INFINITY'
|
382
382
|
return -Float::INFINITY
|
383
|
-
else
|
384
|
-
raise ArgumentError, "Could not convert constant: #{value}"
|
385
383
|
end
|
384
|
+
# NOTE: No else case because of the following scenario:
|
385
|
+
# If the value type is a UINT but they have a WRITE_CONVERSION that takes a string
|
386
|
+
# then the default value will be a string. In that case we just want to return the string.
|
387
|
+
# For example, the IP_ADDRESS parameter in the TIME_OFFSET command in the Demo plugin.
|
386
388
|
end
|
387
389
|
return value
|
388
390
|
end
|
@@ -67,6 +67,7 @@ module OpenC3
|
|
67
67
|
@authentication = authentication.nil? ? generate_auth() : authentication
|
68
68
|
@timeout = timeout
|
69
69
|
@shutdown = false
|
70
|
+
# JsonDRb.debug = true # Enable for debugging
|
70
71
|
end
|
71
72
|
|
72
73
|
# generate the auth object
|
@@ -179,12 +180,11 @@ module OpenC3
|
|
179
180
|
# NOTE: This is a helper method and should not be called directly
|
180
181
|
def _generate_data(kwargs)
|
181
182
|
data = kwargs[:data]
|
182
|
-
|
183
|
-
|
184
|
-
elsif data.is_a?(Hash) == false and data.is_a?(String) == false
|
183
|
+
# data can be nil but otherwise must be a Hash or String
|
184
|
+
if !data.nil? and !data.is_a?(Hash) and !data.is_a?(String)
|
185
185
|
raise JsonApiError, "incorrect type for keyword 'data' MUST be Hash or String: #{data}"
|
186
186
|
end
|
187
|
-
return kwargs[:json] ? JSON.generate(
|
187
|
+
return kwargs[:json] ? JSON.generate(data) : data
|
188
188
|
end
|
189
189
|
|
190
190
|
# NOTE: This is a helper method and should not be called directly
|
@@ -36,6 +36,10 @@ module OpenC3
|
|
36
36
|
packet.received_count += 1
|
37
37
|
packet.received_time = Time.now.sys
|
38
38
|
TelemetryTopic.write_packet(packet, scope: @scope)
|
39
|
+
# If the inject_tlm parameters are bad we rescue so
|
40
|
+
# interface_microservice and decom_microservice can continue
|
41
|
+
rescue => e
|
42
|
+
@logger.error "inject_tlm error due to #{e.message}"
|
39
43
|
end
|
40
44
|
|
41
45
|
def handle_build_cmd(build_cmd_json, msg_id)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# This program is free software; you can modify and/or redistribute it
|
@@ -18,15 +18,39 @@
|
|
18
18
|
|
19
19
|
require 'openc3/microservices/microservice'
|
20
20
|
require 'openc3/models/offline_access_model'
|
21
|
+
require 'openc3/models/news_model'
|
22
|
+
# The VERSION and ENTERPRISE constants are set by settings_api.rb
|
23
|
+
require 'openc3/api/settings_api'
|
21
24
|
|
22
25
|
module OpenC3
|
23
26
|
class PeriodicMicroservice < Microservice
|
27
|
+
include Api
|
28
|
+
|
24
29
|
STARTUP_DELAY_SECONDS = 2 * 60 # Two Minutes
|
25
30
|
SLEEP_PERIOD_SECONDS = 24 * 60 * 60 # Run once per day
|
26
31
|
|
27
32
|
def initialize(*args)
|
28
33
|
super(*args)
|
29
34
|
@metric.set(name: 'periodic_total', value: @count, type: 'counter')
|
35
|
+
@conn = nil # Faraday connection set by get_news
|
36
|
+
get_news()
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_news
|
40
|
+
if get_setting('news_feed', scope: @scope)
|
41
|
+
unless @conn
|
42
|
+
@conn = Faraday.new(
|
43
|
+
url: 'https://news.openc3.com',
|
44
|
+
params: {version: VERSION, enterprise: ENTERPRISE},
|
45
|
+
)
|
46
|
+
end
|
47
|
+
response = @conn.get('/news')
|
48
|
+
if response.success?
|
49
|
+
NewsModel.set(response.body)
|
50
|
+
else
|
51
|
+
NewsModel.news_error(response)
|
52
|
+
end
|
53
|
+
end
|
30
54
|
end
|
31
55
|
|
32
56
|
def run
|
@@ -52,6 +76,7 @@ module OpenC3
|
|
52
76
|
@metric.set(name: 'periodic_total', value: @count, type: 'counter')
|
53
77
|
break if @cancel_thread
|
54
78
|
break if @run_sleeper.sleep(SLEEP_PERIOD_SECONDS)
|
79
|
+
get_news()
|
55
80
|
end
|
56
81
|
end
|
57
82
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'openc3/utilities/migration'
|
2
|
+
require 'openc3/models/scope_model'
|
3
|
+
require 'openc3/models/setting_model'
|
4
|
+
|
5
|
+
module OpenC3
|
6
|
+
class NewsFeed < Migration
|
7
|
+
def self.run
|
8
|
+
SettingModel.set({ name: 'news_feed', data: true }, scope: 'DEFAULT')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
unless ENV['OPENC3_NO_MIGRATE']
|
14
|
+
OpenC3::NewsFeed.run
|
15
|
+
end
|
@@ -66,10 +66,17 @@ module OpenC3
|
|
66
66
|
end
|
67
67
|
|
68
68
|
# @return [String|nil] String of the saved json or nil if score not found under primary_key
|
69
|
-
def self.score(name:, score:, scope:)
|
70
|
-
|
71
|
-
if
|
72
|
-
|
69
|
+
def self.score(name:, score:, scope:, uuid: nil)
|
70
|
+
values = Store.zrangebyscore("#{scope}#{PRIMARY_KEY}__#{name}", score, score)
|
71
|
+
if values and values.length > 0
|
72
|
+
if uuid
|
73
|
+
values.each do |value|
|
74
|
+
activity = ActivityModel.from_json(value, name: name, scope: scope)
|
75
|
+
return activity if activity.uuid == uuid
|
76
|
+
end
|
77
|
+
else
|
78
|
+
return ActivityModel.from_json(values[0], name: name, scope: scope)
|
79
|
+
end
|
73
80
|
end
|
74
81
|
return nil
|
75
82
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2025 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/models/model'
|
20
|
+
require 'openc3/utilities/store'
|
21
|
+
|
22
|
+
module OpenC3
|
23
|
+
class NewsModel < Model
|
24
|
+
PRIMARY_KEY = 'openc3_news'
|
25
|
+
|
26
|
+
def self.set(news)
|
27
|
+
Store.set(PRIMARY_KEY, news)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.all()
|
31
|
+
Store.get(PRIMARY_KEY)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.news_error(response)
|
35
|
+
Store.set(PRIMARY_KEY, [{ date: Time.now.utc.iso8601, title: 'News Error', body: "Error contacting OpenC3 news feed (status: #{response.status})" }].to_json)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -104,7 +104,8 @@ module OpenC3
|
|
104
104
|
def self.destroy(name, scope:)
|
105
105
|
package_name, version = self.extract_name_and_version(name)
|
106
106
|
Logger.info "Uninstalling package: #{name}"
|
107
|
-
|
107
|
+
pip_args = ["-y", package_name]
|
108
|
+
result = OpenC3::ProcessManager.instance.spawn(["/openc3/bin/pipuninstall"] + pip_args, "package_uninstall", name, Time.now + 3600.0, scope: scope)
|
108
109
|
return result.name
|
109
110
|
end
|
110
111
|
|
@@ -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 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -400,6 +400,8 @@ module OpenC3
|
|
400
400
|
SettingModel.set({ name: 'rubygems_url', data: ENV['RUBYGEMS_URL'] || 'https://rubygems.org' }, scope: @scope) unless setting
|
401
401
|
setting = SettingModel.get(name: 'pypi_url')
|
402
402
|
SettingModel.set({ name: 'pypi_url', data: ENV['PYPI_URL'] || 'https://pypi.org' }, scope: @scope) unless setting
|
403
|
+
# Set the news feed to true by default, don't bother checking if it's already set
|
404
|
+
SettingModel.set({ name: 'news_feed', data: true }, scope: @scope)
|
403
405
|
end
|
404
406
|
end
|
405
407
|
end
|
@@ -94,13 +94,10 @@ module OpenC3
|
|
94
94
|
if color.nil?
|
95
95
|
color = '#%06x' % (rand * 0xffffff)
|
96
96
|
end
|
97
|
-
|
98
|
-
|
99
|
-
raise RuntimeError.new "invalid color but in hex format. #FF0000"
|
100
|
-
end
|
101
|
-
unless color.start_with?('#')
|
102
|
-
color = "##{color}"
|
97
|
+
unless color =~ /#?([0-9a-fA-F]{6})/
|
98
|
+
raise TimelineInputError.new "invalid color, must be in hex format, e.g. #FF0000"
|
103
99
|
end
|
100
|
+
color = "##{color}" unless color.start_with?('#')
|
104
101
|
@color = color
|
105
102
|
end
|
106
103
|
|
@@ -326,7 +326,8 @@ module OpenC3
|
|
326
326
|
end
|
327
327
|
|
328
328
|
range = item.range
|
329
|
-
|
329
|
+
# Don't range check a string default value
|
330
|
+
if range and !item.default.is_a?(String)
|
330
331
|
# Perform Range Check on command parameter
|
331
332
|
if not range.include?(range_check_value)
|
332
333
|
range_check_value = "'#{range_check_value}'" if String === range_check_value
|
@@ -756,7 +756,7 @@ module OpenC3
|
|
756
756
|
super(item, value, :RAW, buffer)
|
757
757
|
rescue ArgumentError => e
|
758
758
|
if item.states and String === value and e.message =~ /invalid value for/
|
759
|
-
raise "Unknown state #{value} for #{item.name}, must be one of #{item.states.keys.join(', ')}"
|
759
|
+
raise "Unknown state '#{value}' for #{item.name}, must be one of #{item.states.keys.join(', ')}"
|
760
760
|
else
|
761
761
|
raise e
|
762
762
|
end
|
@@ -23,12 +23,12 @@ module OpenC3
|
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
|
-
def list_timelines(scope: $openc3_scope
|
26
|
+
def list_timelines(scope: $openc3_scope)
|
27
27
|
response = $api_server.request('get', "/openc3-api/timeline", scope: scope)
|
28
28
|
return _handle_response(response, 'Failed to list timelines')
|
29
29
|
end
|
30
30
|
|
31
|
-
def create_timeline(name, color: nil, scope: $openc3_scope
|
31
|
+
def create_timeline(name, color: nil, scope: $openc3_scope)
|
32
32
|
data = {}
|
33
33
|
data['name'] = name
|
34
34
|
data['color'] = color if color
|
@@ -36,19 +36,19 @@ module OpenC3
|
|
36
36
|
return _handle_response(response, 'Failed to create timeline')
|
37
37
|
end
|
38
38
|
|
39
|
-
def get_timeline(name, scope: $openc3_scope
|
39
|
+
def get_timeline(name, scope: $openc3_scope)
|
40
40
|
response = $api_server.request('get', "/openc3-api/timeline/#{name}", scope: scope)
|
41
41
|
return _handle_response(response, 'Failed to get timeline')
|
42
42
|
end
|
43
43
|
|
44
|
-
def set_timeline_color(name, color, scope: $openc3_scope
|
44
|
+
def set_timeline_color(name, color, scope: $openc3_scope)
|
45
45
|
post_data = {}
|
46
46
|
post_data['color'] = color
|
47
47
|
response = $api_server.request('post', "/openc3-api/timeline/#{name}/color", data: post_data, json: true, scope: scope)
|
48
48
|
return _handle_response(response, 'Failed to set timeline color')
|
49
49
|
end
|
50
50
|
|
51
|
-
def delete_timeline(name, force: false, scope: $openc3_scope
|
51
|
+
def delete_timeline(name, force: false, scope: $openc3_scope)
|
52
52
|
url = "/openc3-api/timeline/#{name}"
|
53
53
|
if force
|
54
54
|
url += "?force=true"
|
@@ -57,16 +57,7 @@ module OpenC3
|
|
57
57
|
return _handle_response(response, 'Failed to delete timeline')
|
58
58
|
end
|
59
59
|
|
60
|
-
def
|
61
|
-
url = "/openc3-api/timeline/#{name}/activities"
|
62
|
-
if start and stop
|
63
|
-
url += "?start=#{start}&stop=#{stop}"
|
64
|
-
end
|
65
|
-
response = $api_server.request('get', url, scope: scope)
|
66
|
-
return _handle_response(response, 'Failed to get timeline activities')
|
67
|
-
end
|
68
|
-
|
69
|
-
def create_timeline_activity(name, kind:, start:, stop:, data: {}, scope: $openc3_scope, token: $openc3_token)
|
60
|
+
def create_timeline_activity(name, kind:, start:, stop:, data: {}, scope: $openc3_scope)
|
70
61
|
kind = kind.to_s.downcase()
|
71
62
|
kinds = %w(command script reserve)
|
72
63
|
unless kinds.include?(kind)
|
@@ -81,12 +72,24 @@ module OpenC3
|
|
81
72
|
return _handle_response(response, 'Failed to create timeline activity')
|
82
73
|
end
|
83
74
|
|
84
|
-
def get_timeline_activity(name, start
|
85
|
-
response = $api_server.request('get', "/openc3-api/timeline/#{name}/activity/#{start}", scope: scope)
|
75
|
+
def get_timeline_activity(name, start, uuid, scope: $openc3_scope)
|
76
|
+
response = $api_server.request('get', "/openc3-api/timeline/#{name}/activity/#{start}/#{uuid}", scope: scope)
|
86
77
|
return _handle_response(response, 'Failed to get timeline activity')
|
87
78
|
end
|
88
79
|
|
89
|
-
def
|
80
|
+
def get_timeline_activities(name, start: nil, stop: nil, limit: nil, scope: $openc3_scope)
|
81
|
+
url = "/openc3-api/timeline/#{name}/activities"
|
82
|
+
if start and stop
|
83
|
+
url += "?start=#{start}&stop=#{stop}"
|
84
|
+
end
|
85
|
+
if limit
|
86
|
+
url += "?limit=#{limit}"
|
87
|
+
end
|
88
|
+
response = $api_server.request('get', url, scope: scope)
|
89
|
+
return _handle_response(response, 'Failed to get timeline activities')
|
90
|
+
end
|
91
|
+
|
92
|
+
def delete_timeline_activity(name, start, uuid, scope: $openc3_scope)
|
90
93
|
response = $api_server.request('delete', "/openc3-api/timeline/#{name}/activity/#{start}/#{uuid}", scope: scope)
|
91
94
|
return _handle_response(response, 'Failed to delete timeline activity')
|
92
95
|
end
|
@@ -20,7 +20,7 @@ module OpenC3
|
|
20
20
|
module Script
|
21
21
|
private
|
22
22
|
|
23
|
-
def plugin_list(scope: $openc3_scope)
|
23
|
+
def plugin_list(default: false, scope: $openc3_scope)
|
24
24
|
response_body = nil
|
25
25
|
begin
|
26
26
|
endpoint = "/openc3-api/plugins?scope=#{scope}"
|
@@ -35,7 +35,15 @@ module OpenC3
|
|
35
35
|
http.request(request) do |response|
|
36
36
|
response_body = response.body
|
37
37
|
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
38
|
-
|
38
|
+
plugins = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
39
|
+
if default
|
40
|
+
return plugins
|
41
|
+
else
|
42
|
+
return plugins.select do |plugin|
|
43
|
+
!plugin.include?('openc3-cosmos-tool-') and !plugin.include?('openc3-tool-base') and
|
44
|
+
!plugin.include?('openc3-cosmos-enterprise-tool-') and !plugin.include?('openc3-enterprise-tool-base')
|
45
|
+
end
|
46
|
+
end
|
39
47
|
end
|
40
48
|
end
|
41
49
|
rescue => e
|
data/lib/openc3/script/script.rb
CHANGED
@@ -25,18 +25,23 @@ require 'openc3/api/api'
|
|
25
25
|
require 'openc3/io/json_drb_object'
|
26
26
|
require 'openc3/script/api_shared'
|
27
27
|
require 'openc3/script/calendar'
|
28
|
-
require 'openc3/script/metadata'
|
29
28
|
require 'openc3/script/commands'
|
30
|
-
require 'openc3/script/
|
31
|
-
require 'openc3/script/limits'
|
29
|
+
require 'openc3/script/critical_cmd'
|
32
30
|
require 'openc3/script/exceptions'
|
31
|
+
# openc3/script/extract is just helper methods
|
32
|
+
require 'openc3/script/limits'
|
33
|
+
require 'openc3/script/metadata'
|
34
|
+
require 'openc3/script/packages'
|
35
|
+
require 'openc3/script/plugins'
|
33
36
|
require 'openc3/script/screen'
|
34
37
|
require 'openc3/script/script_runner'
|
35
38
|
require 'openc3/script/storage'
|
39
|
+
# openc3/script/suite_results and suite_runner are used by
|
40
|
+
# running_script.rb and the script_runner_api
|
41
|
+
# openc3/script/suite is used by end user SR Suites
|
42
|
+
require 'openc3/script/tables'
|
43
|
+
require 'openc3/script/telemetry'
|
36
44
|
require 'openc3/script/web_socket_api'
|
37
|
-
require 'openc3/script/packages'
|
38
|
-
require 'openc3/script/plugins'
|
39
|
-
require 'openc3/script/critical_cmd'
|
40
45
|
require 'openc3/utilities/authentication'
|
41
46
|
|
42
47
|
$api_server = nil
|
@@ -34,22 +34,29 @@ module OpenC3
|
|
34
34
|
if response.nil? || response.status != 200
|
35
35
|
_script_response_error(response, "Script list request failed", scope: scope)
|
36
36
|
else
|
37
|
-
|
37
|
+
scripts = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
38
|
+
# Remove the '*' from the script names
|
39
|
+
return scripts.each { |script| script.gsub!(/\*$/, '') }
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
43
|
def script_syntax_check(script, scope: $openc3_scope)
|
42
|
-
endpoint = "/script-api/scripts/syntax"
|
43
|
-
|
44
|
+
endpoint = "/script-api/scripts/temp.rb/syntax"
|
45
|
+
# Explicitly set the headers to plain/text so the request.body is set correctly
|
46
|
+
headers = {
|
47
|
+
'Content-Type': 'plain/text',
|
48
|
+
}
|
49
|
+
response = $script_runner_api_server.request('post', endpoint, headers: headers, data: script, scope: scope)
|
44
50
|
if response.nil? || response.status != 200
|
45
51
|
_script_response_error(response, "Script syntax check request failed", scope: scope)
|
46
52
|
else
|
47
53
|
result = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
48
54
|
if result['title'] == "Syntax Check Successful"
|
49
|
-
|
55
|
+
result['success'] = true
|
50
56
|
else
|
51
|
-
|
57
|
+
result['success'] = false
|
52
58
|
end
|
59
|
+
return result
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
@@ -59,8 +66,8 @@ module OpenC3
|
|
59
66
|
if response.nil? || response.status != 200
|
60
67
|
_script_response_error(response, "Failed to get #{filename}", scope: scope)
|
61
68
|
else
|
62
|
-
|
63
|
-
return
|
69
|
+
result = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
70
|
+
return result['contents']
|
64
71
|
end
|
65
72
|
end
|
66
73
|
|
@@ -120,9 +127,13 @@ module OpenC3
|
|
120
127
|
end
|
121
128
|
end
|
122
129
|
|
123
|
-
def script_instrumented(
|
124
|
-
endpoint = "/script-api/scripts
|
125
|
-
|
130
|
+
def script_instrumented(script, scope: $openc3_scope)
|
131
|
+
endpoint = "/script-api/scripts/temp.rb/instrumented"
|
132
|
+
# Explicitly set the headers to plain/text so the request.body is set correctly
|
133
|
+
headers = {
|
134
|
+
'Content-Type': 'plain/text',
|
135
|
+
}
|
136
|
+
response = $script_runner_api_server.request('post', endpoint, headers: headers, data: script, scope: scope)
|
126
137
|
if response.nil? || response.status != 200
|
127
138
|
_script_response_error(response, "Script instrumented request failed", scope: scope)
|
128
139
|
else
|
@@ -178,7 +189,7 @@ module OpenC3
|
|
178
189
|
|
179
190
|
def _running_script_action(id, action_name, scope: $openc3_scope)
|
180
191
|
endpoint = "/script-api/running-script/#{id}/#{action_name}"
|
181
|
-
response = $script_runner_api_server.request('post', endpoint, scope: scope)
|
192
|
+
response = $script_runner_api_server.request('post', endpoint, json: true, scope: scope)
|
182
193
|
if response.nil? || response.status != 200
|
183
194
|
_script_response_error(response, "Running script #{action_name} request failed", scope: scope)
|
184
195
|
else
|
@@ -127,7 +127,9 @@ module OpenC3
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
-
|
130
|
+
# These are helper methods ... should not be used directly
|
131
|
+
|
132
|
+
def _get_download_url(path, scope: $openc3_scope)
|
131
133
|
targets = "targets_modified" # First try targets_modified
|
132
134
|
response = $api_server.request('get', "/openc3-api/storage/exists/#{scope}/#{targets}/#{path}", query: { bucket: 'OPENC3_CONFIG_BUCKET' }, scope: scope)
|
133
135
|
if response.status != 200
|
@@ -143,8 +145,6 @@ module OpenC3
|
|
143
145
|
return result['url']
|
144
146
|
end
|
145
147
|
|
146
|
-
# These are helper methods ... should not be used directly
|
147
|
-
|
148
148
|
def _get_storage_file(path, scope: $openc3_scope)
|
149
149
|
# Create Tempfile to store data
|
150
150
|
file = Tempfile.new('target', binmode: true)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2025 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
|
+
module OpenC3
|
20
|
+
module Script
|
21
|
+
private
|
22
|
+
|
23
|
+
def table_create_binary(definition, scope: $openc3_scope)
|
24
|
+
post_data = {}
|
25
|
+
post_data['definition'] = definition
|
26
|
+
response = $api_server.request('post', '/openc3-api/tables/generate', json: true, data: post_data, scope: scope)
|
27
|
+
return _handle_response(response, 'Failed to create binary')
|
28
|
+
end
|
29
|
+
|
30
|
+
def table_create_report(filename, definition, table_name: nil, scope: $openc3_scope)
|
31
|
+
post_data = {}
|
32
|
+
post_data['binary'] = filename
|
33
|
+
post_data['definition'] = definition
|
34
|
+
post_data['table_name'] = table_name if table_name
|
35
|
+
response = $api_server.request('post', '/openc3-api/tables/report', json: true, data: post_data, scope: scope)
|
36
|
+
return _handle_response(response, 'Failed to create report')
|
37
|
+
end
|
38
|
+
|
39
|
+
# Helper method to handle the response
|
40
|
+
def _handle_response(response, error_message)
|
41
|
+
return nil if response.nil?
|
42
|
+
if response.status >= 400
|
43
|
+
result = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
44
|
+
raise "#{error_message} due to #{result['message']}"
|
45
|
+
end
|
46
|
+
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -182,7 +182,7 @@ module OpenC3
|
|
182
182
|
def generate_url
|
183
183
|
schema = ENV['OPENC3_API_SCHEMA'] || 'http'
|
184
184
|
hostname = ENV['OPENC3_API_HOSTNAME'] || (ENV['OPENC3_DEVEL'] ? '127.0.0.1' : 'openc3-cosmos-cmd-tlm-api')
|
185
|
-
port = ENV['OPENC3_API_PORT'] || '
|
185
|
+
port = ENV['OPENC3_API_CABLE_PORT'] || ENV['OPENC3_API_PORT'] || '3901'
|
186
186
|
port = port.to_i
|
187
187
|
return "#{schema}://#{hostname}:#{port}/openc3-api/cable"
|
188
188
|
end
|
@@ -198,7 +198,7 @@ module OpenC3
|
|
198
198
|
def generate_url
|
199
199
|
schema = ENV['OPENC3_SCRIPT_API_SCHEMA'] || 'http'
|
200
200
|
hostname = ENV['OPENC3_SCRIPT_API_HOSTNAME'] || (ENV['OPENC3_DEVEL'] ? '127.0.0.1' : 'openc3-cosmos-script-runner-api')
|
201
|
-
port = ENV['OPENC3_SCRIPT_API_PORT'] || '
|
201
|
+
port = ENV['OPENC3_SCRIPT_API_CABLE_PORT'] || ENV['OPENC3_SCRIPT_API_PORT'] || '3902'
|
202
202
|
port = port.to_i
|
203
203
|
return "#{schema}://#{hostname}:#{port}/script-api/cable"
|
204
204
|
end
|
@@ -380,6 +380,7 @@ module OpenC3
|
|
380
380
|
|
381
381
|
def self.put_target_file(path, io_or_string, scope:)
|
382
382
|
full_folder_path = "#{OPENC3_LOCAL_MODE_PATH}/#{path}"
|
383
|
+
return unless File.expand_path(full_folder_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
383
384
|
FileUtils.mkdir_p(File.dirname(full_folder_path))
|
384
385
|
File.open(full_folder_path, 'wb') do |file|
|
385
386
|
if String === io_or_string
|
@@ -393,7 +394,10 @@ module OpenC3
|
|
393
394
|
|
394
395
|
def self.open_local_file(path, scope:)
|
395
396
|
full_path = "#{OPENC3_LOCAL_MODE_PATH}/#{scope}/targets_modified/#{path}"
|
396
|
-
|
397
|
+
if File.expand_path(full_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
398
|
+
return File.open(full_path, 'rb')
|
399
|
+
end
|
400
|
+
nil
|
397
401
|
rescue Errno::ENOENT
|
398
402
|
nil
|
399
403
|
end
|
@@ -446,6 +450,7 @@ module OpenC3
|
|
446
450
|
def self.save_tool_config(scope, tool, name, data)
|
447
451
|
json = JSON.parse(data, :allow_nan => true, :create_additions => true)
|
448
452
|
config_path = "#{OPENC3_LOCAL_MODE_PATH}/#{scope}/tool_config/#{tool}/#{name}.json"
|
453
|
+
return unless File.expand_path(config_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
449
454
|
FileUtils.mkdir_p(File.dirname(config_path))
|
450
455
|
File.open(config_path, 'w') do |file|
|
451
456
|
file.write(JSON.pretty_generate(json, :allow_nan => true))
|
@@ -453,7 +458,9 @@ module OpenC3
|
|
453
458
|
end
|
454
459
|
|
455
460
|
def self.delete_tool_config(scope, tool, name)
|
456
|
-
|
461
|
+
config_path = "#{OPENC3_LOCAL_MODE_PATH}/#{scope}/tool_config/#{tool}/#{name}.json"
|
462
|
+
return unless File.expand_path(config_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
463
|
+
FileUtils.rm_f(config_path)
|
457
464
|
end
|
458
465
|
|
459
466
|
def self.sync_settings()
|
@@ -471,6 +478,7 @@ module OpenC3
|
|
471
478
|
|
472
479
|
def self.save_setting(scope, name, data)
|
473
480
|
config_path = "#{OPENC3_LOCAL_MODE_PATH}/#{scope}/settings/#{name}.json"
|
481
|
+
return unless File.expand_path(config_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
474
482
|
FileUtils.mkdir_p(File.dirname(config_path))
|
475
483
|
# Anything can be stored as a setting so write it out directly
|
476
484
|
File.write(config_path, data)
|
@@ -480,12 +488,14 @@ module OpenC3
|
|
480
488
|
|
481
489
|
def self.sync_remote_to_local(bucket, key)
|
482
490
|
local_path = "#{OPENC3_LOCAL_MODE_PATH}/#{key}"
|
491
|
+
return unless File.expand_path(local_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
483
492
|
FileUtils.mkdir_p(File.dirname(local_path))
|
484
493
|
bucket.get_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: key, path: local_path)
|
485
494
|
end
|
486
495
|
|
487
496
|
def self.sync_local_to_remote(bucket, key)
|
488
497
|
local_path = "#{OPENC3_LOCAL_MODE_PATH}/#{key}"
|
498
|
+
return unless File.expand_path(local_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
489
499
|
File.open(local_path, 'rb') do |read_file|
|
490
500
|
bucket.put_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: key, body: read_file)
|
491
501
|
end
|
@@ -493,6 +503,7 @@ module OpenC3
|
|
493
503
|
|
494
504
|
def self.delete_local(key)
|
495
505
|
local_path = "#{OPENC3_LOCAL_MODE_PATH}/#{key}"
|
506
|
+
return unless File.expand_path(local_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
496
507
|
File.delete(local_path) if File.exist?(local_path)
|
497
508
|
nil
|
498
509
|
end
|
@@ -94,7 +94,13 @@ module OpenC3
|
|
94
94
|
# First try opening a potentially modified version by looking for the modified target
|
95
95
|
if ENV['OPENC3_LOCAL_MODE']
|
96
96
|
local_file = OpenC3::LocalMode.open_local_file(name, scope: scope)
|
97
|
-
|
97
|
+
if local_file
|
98
|
+
if File.extname(name) == ".bin"
|
99
|
+
return local_file.read
|
100
|
+
else
|
101
|
+
return local_file.read.force_encoding('UTF-8')
|
102
|
+
end
|
103
|
+
end
|
98
104
|
end
|
99
105
|
|
100
106
|
bucket = Bucket.getClient()
|
@@ -106,8 +112,10 @@ module OpenC3
|
|
106
112
|
if resp && resp.body
|
107
113
|
if File.extname(name) == ".bin"
|
108
114
|
resp.body.binmode
|
115
|
+
return resp.body.read
|
116
|
+
else
|
117
|
+
return resp.body.read.force_encoding('UTF-8')
|
109
118
|
end
|
110
|
-
resp.body.read
|
111
119
|
else
|
112
120
|
nil
|
113
121
|
end
|
data/lib/openc3/version.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
OPENC3_VERSION = '6.0
|
3
|
+
OPENC3_VERSION = '6.1.0'
|
4
4
|
module OpenC3
|
5
5
|
module Version
|
6
6
|
MAJOR = '6'
|
7
|
-
MINOR = '
|
8
|
-
PATCH = '
|
7
|
+
MINOR = '1'
|
8
|
+
PATCH = '0'
|
9
9
|
OTHER = ''
|
10
|
-
BUILD = '
|
10
|
+
BUILD = '4db8ce5a1e1178bf7272dab85bd71299e5d6c3b7'
|
11
11
|
end
|
12
|
-
VERSION = '6.0
|
13
|
-
GEM_VERSION = '6.0
|
12
|
+
VERSION = '6.1.0'
|
13
|
+
GEM_VERSION = '6.1.0'
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= tool_name %>",
|
3
|
-
"version": "6.0
|
3
|
+
"version": "6.1.0",
|
4
4
|
"scripts": {
|
5
5
|
"ng": "ng",
|
6
6
|
"start": "ng serve",
|
@@ -23,7 +23,7 @@
|
|
23
23
|
"@angular/platform-browser-dynamic": "^18.2.6",
|
24
24
|
"@angular/router": "^18.2.6",
|
25
25
|
"@astrouxds/astro-web-components": "^7.24.0",
|
26
|
-
"@openc3/js-common": "6.0
|
26
|
+
"@openc3/js-common": "6.1.0",
|
27
27
|
"rxjs": "~7.8.0",
|
28
28
|
"single-spa": "^5.9.5",
|
29
29
|
"single-spa-angular": "^9.2.0",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= tool_name %>",
|
3
|
-
"version": "6.0
|
3
|
+
"version": "6.1.0",
|
4
4
|
"private": true,
|
5
5
|
"type": "module",
|
6
6
|
"scripts": {
|
@@ -11,8 +11,8 @@
|
|
11
11
|
},
|
12
12
|
"dependencies": {
|
13
13
|
"@astrouxds/astro-web-components": "^7.24.0",
|
14
|
-
"@openc3/js-common": "6.0
|
15
|
-
"@openc3/vue-common": "6.0
|
14
|
+
"@openc3/js-common": "6.1.0",
|
15
|
+
"@openc3/vue-common": "6.1.0",
|
16
16
|
"axios": "^1.7.7",
|
17
17
|
"date-fns": "^4.1.0",
|
18
18
|
"lodash": "^4.17.21",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= widget_name %>",
|
3
|
-
"version": "6.0
|
3
|
+
"version": "6.1.0",
|
4
4
|
"private": true,
|
5
5
|
"type": "module",
|
6
6
|
"scripts": {
|
@@ -8,7 +8,7 @@
|
|
8
8
|
},
|
9
9
|
"dependencies": {
|
10
10
|
"@astrouxds/astro-web-components": "^7.24.0",
|
11
|
-
"@openc3/vue-common": "6.0
|
11
|
+
"@openc3/vue-common": "6.1.0",
|
12
12
|
"vuetify": "^3.7.1"
|
13
13
|
},
|
14
14
|
"devDependencies": {
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openc3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0
|
4
|
+
version: 6.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Melton
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2025-
|
12
|
+
date: 2025-02-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -791,6 +791,7 @@ files:
|
|
791
791
|
- bin/cstol_converter
|
792
792
|
- bin/openc3cli
|
793
793
|
- bin/pipinstall
|
794
|
+
- bin/pipuninstall
|
794
795
|
- bin/rubysloc
|
795
796
|
- data/config/_array_params.yaml
|
796
797
|
- data/config/_canvas_values.yaml
|
@@ -993,6 +994,7 @@ files:
|
|
993
994
|
- lib/openc3/migrations/20231022000000_tlm_viewer_config.rb
|
994
995
|
- lib/openc3/migrations/20241208080000_no_critical_cmd.rb
|
995
996
|
- lib/openc3/migrations/20241208080001_no_trigger_group.rb
|
997
|
+
- lib/openc3/migrations/20250108060000_news_feed.rb
|
996
998
|
- lib/openc3/models/activity_model.rb
|
997
999
|
- lib/openc3/models/auth_model.rb
|
998
1000
|
- lib/openc3/models/cvt_model.rb
|
@@ -1007,6 +1009,7 @@ files:
|
|
1007
1009
|
- lib/openc3/models/microservice_status_model.rb
|
1008
1010
|
- lib/openc3/models/migration_model.rb
|
1009
1011
|
- lib/openc3/models/model.rb
|
1012
|
+
- lib/openc3/models/news_model.rb
|
1010
1013
|
- lib/openc3/models/note_model.rb
|
1011
1014
|
- lib/openc3/models/offline_access_model.rb
|
1012
1015
|
- lib/openc3/models/ping_model.rb
|
@@ -1075,6 +1078,7 @@ files:
|
|
1075
1078
|
- lib/openc3/script/suite.rb
|
1076
1079
|
- lib/openc3/script/suite_results.rb
|
1077
1080
|
- lib/openc3/script/suite_runner.rb
|
1081
|
+
- lib/openc3/script/tables.rb
|
1078
1082
|
- lib/openc3/script/telemetry.rb
|
1079
1083
|
- lib/openc3/script/web_socket_api.rb
|
1080
1084
|
- lib/openc3/streams/mqtt_stream.rb
|