openc3 6.4.1 → 6.5.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/openc3cli +172 -97
- data/data/config/_graph_params.yaml +4 -4
- data/data/config/conversions.yaml +274 -0
- data/data/config/item_modifiers.yaml +8 -70
- data/data/config/parameter_modifiers.yaml +9 -69
- data/data/config/plugins.yaml +14 -1
- data/data/config/processors.yaml +51 -0
- data/data/config/telemetry_modifiers.yaml +1 -0
- data/lib/openc3/api/api.rb +1 -1
- data/lib/openc3/api/tlm_api.rb +10 -5
- data/lib/openc3/conversions/unix_time_conversion.rb +2 -2
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +3 -3
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +3 -3
- data/lib/openc3/core_ext/time.rb +2 -9
- data/lib/openc3/microservices/cleanup_microservice.rb +2 -2
- data/lib/openc3/microservices/decom_microservice.rb +2 -2
- data/lib/openc3/microservices/interface_microservice.rb +18 -12
- data/lib/openc3/microservices/log_microservice.rb +4 -2
- data/lib/openc3/microservices/multi_microservice.rb +2 -2
- data/lib/openc3/microservices/periodic_microservice.rb +2 -2
- data/lib/openc3/microservices/reducer_microservice.rb +2 -2
- data/lib/openc3/microservices/router_microservice.rb +2 -2
- data/lib/openc3/microservices/scope_cleanup_microservice.rb +2 -2
- data/lib/openc3/microservices/text_log_microservice.rb +19 -6
- data/lib/openc3/models/plugin_model.rb +5 -4
- data/lib/openc3/models/scope_model.rb +87 -57
- data/lib/openc3/models/script_engine_model.rb +93 -0
- data/lib/openc3/models/script_status_model.rb +26 -4
- data/lib/openc3/models/target_model.rb +33 -5
- data/lib/openc3/packets/packet_config.rb +1 -1
- data/lib/openc3/script/autonomic.rb +359 -0
- data/lib/openc3/script/script.rb +6 -1
- data/lib/openc3/script_engines/script_engine.rb +118 -0
- data/lib/openc3/topics/interface_topic.rb +23 -3
- data/lib/openc3/utilities/cli_generator.rb +42 -15
- data/lib/openc3/utilities/running_script.rb +1460 -0
- data/lib/openc3/version.rb +6 -6
- data/templates/conversion/conversion.py +1 -1
- data/templates/conversion/conversion.rb +1 -1
- data/templates/processor/processor.py +32 -0
- data/templates/processor/processor.rb +36 -0
- 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 +9 -1
@@ -37,36 +37,7 @@ READ_CONVERSION:
|
|
37
37
|
takes extra parameters and must always implement the `call` method. The conversion
|
38
38
|
factor is applied to the raw value in the telemetry packet before it is displayed
|
39
39
|
to the user. The user still has the ability to see the raw unconverted value
|
40
|
-
in a details dialog.
|
41
|
-
ruby_example: |
|
42
|
-
READ_CONVERSION the_great_conversion.rb 1000
|
43
|
-
|
44
|
-
Defined in the_great_conversion.rb:
|
45
|
-
|
46
|
-
require 'openc3/conversions/conversion'
|
47
|
-
module OpenC3
|
48
|
-
class TheGreatConversion < Conversion
|
49
|
-
def initialize(multiplier)
|
50
|
-
super()
|
51
|
-
@multiplier = multiplier.to_f
|
52
|
-
end
|
53
|
-
def call(value, packet, buffer)
|
54
|
-
return value * @multiplier
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
python_example: |
|
59
|
-
READ_CONVERSION the_great_conversion.py 1000
|
60
|
-
|
61
|
-
Defined in the_great_conversion.py:
|
62
|
-
|
63
|
-
from openc3.conversions.conversion import Conversion
|
64
|
-
class TheGreatConversion(Conversion):
|
65
|
-
def __init__(self, multiplier):
|
66
|
-
super().__init__()
|
67
|
-
self.multiplier = float(multiplier)
|
68
|
-
def call(self, value, packet, buffer):
|
69
|
-
return value * self.multiplier
|
40
|
+
in a details dialog. For more information see the [Conversion](/docs/configuration/conversions) documentation.
|
70
41
|
parameters:
|
71
42
|
- name: Class Filename
|
72
43
|
required: true
|
@@ -80,50 +51,16 @@ READ_CONVERSION:
|
|
80
51
|
description: Additional parameter values for the conversion which are passed
|
81
52
|
to the class constructor.
|
82
53
|
values: .*
|
54
|
+
ruby_example: |
|
55
|
+
READ_CONVERSION ip_read_conversion.rb
|
56
|
+
python_example: |
|
57
|
+
READ_CONVERSION openc3/conversions/ip_read_conversion.rb
|
83
58
|
POLY_READ_CONVERSION:
|
84
59
|
summary: Adds a polynomial conversion factor to the current telemetry item
|
85
|
-
description:
|
86
|
-
packet before it is displayed to the user. The user still has the ability
|
87
|
-
to see the raw unconverted value in a details dialog.
|
88
|
-
example: POLY_READ_CONVERSION 10 0.5 0.25
|
89
|
-
parameters:
|
90
|
-
- name: C0
|
91
|
-
required: true
|
92
|
-
description: Coefficient
|
93
|
-
values: .*
|
94
|
-
- name: Cx
|
95
|
-
required: false
|
96
|
-
description: Additional coefficient values for the conversion. Any order
|
97
|
-
polynomial conversion may be used so the value of 'x' will vary with the
|
98
|
-
order of the polynomial. Note that larger order polynomials take longer
|
99
|
-
to process than shorter order polynomials, but are sometimes more accurate.
|
100
|
-
values: .*
|
60
|
+
description: See [Polynomial Conversion](/docs/configuration/conversions#polynomial_conversion) for more information.
|
101
61
|
SEG_POLY_READ_CONVERSION:
|
102
62
|
summary: Adds a segmented polynomial conversion factor to the current telemetry item
|
103
|
-
description:
|
104
|
-
before it is displayed to the user. The user still has the ability to see the raw
|
105
|
-
unconverted value in a details dialog.
|
106
|
-
example: |
|
107
|
-
SEG_POLY_READ_CONVERSION 0 10 0.5 0.25 # Apply the conversion to all values < 50
|
108
|
-
SEG_POLY_READ_CONVERSION 50 11 0.5 0.275 # Apply the conversion to all values >= 50 and < 100
|
109
|
-
SEG_POLY_READ_CONVERSION 100 12 0.5 0.3 # Apply the conversion to all values >= 100
|
110
|
-
parameters:
|
111
|
-
- name: Lower Bound
|
112
|
-
required: true
|
113
|
-
description: Defines the lower bound of the range of values that this segmented
|
114
|
-
polynomial applies to. Is ignored for the segment with the smallest lower bound.
|
115
|
-
values: .*
|
116
|
-
- name: C0
|
117
|
-
required: true
|
118
|
-
description: Coefficient
|
119
|
-
values: .*
|
120
|
-
- name: Cx
|
121
|
-
required: false
|
122
|
-
description: Additional coefficient values for the conversion. Any order
|
123
|
-
polynomial conversion may be used so the value of 'x' will vary with the
|
124
|
-
order of the polynomial. Note that larger order polynomials take longer
|
125
|
-
to process than shorter order polynomials, but are sometimes more accurate.
|
126
|
-
values: .*
|
63
|
+
description: See [Segmented Polynomial Conversion](/docs/configuration/conversions#segmented_polynomial_conversion) for more information.
|
127
64
|
GENERIC_READ_CONVERSION_START:
|
128
65
|
summary: Start a generic read conversion
|
129
66
|
description: Adds a generic conversion function to the current telemetry item.
|
@@ -225,6 +162,7 @@ LIMITS:
|
|
225
162
|
values: .+
|
226
163
|
LIMITS_RESPONSE:
|
227
164
|
summary: Defines a response class that is called when the limits state of the current item changes
|
165
|
+
description: See the [Limits Response](/docs/configuration/limits-response) documentation for more information.
|
228
166
|
ruby_example: LIMITS_RESPONSE example_limits_response.rb 10
|
229
167
|
python_example: LIMITS_RESPONSE example_limits_response.py 10
|
230
168
|
parameters:
|
@@ -69,7 +69,7 @@ WRITE_CONVERSION:
|
|
69
69
|
It must implement the `initialize` (Ruby) or `__init__` (Python) method if it
|
70
70
|
takes extra parameters and must always implement the `call` method. The conversion
|
71
71
|
factor is applied to the value entered by the user before it is written into
|
72
|
-
the binary command packet and sent.
|
72
|
+
the binary command packet and sent. For more information see the [Conversion](/docs/configuration/conversions) documentation.
|
73
73
|
|
74
74
|
When applying a write_conversion sometimes the data type changes,
|
75
75
|
e.g. creating a UINT from an input STRING (for an example of this see
|
@@ -90,90 +90,30 @@ WRITE_CONVERSION:
|
|
90
90
|
given_values() method which can be used to retrieve a hash of the user provided
|
91
91
|
values to the command. That can be used to check parameter values passed in.
|
92
92
|
:::
|
93
|
-
ruby_example: |
|
94
|
-
WRITE_CONVERSION the_great_conversion.rb 1000
|
95
|
-
|
96
|
-
Defined in the_great_conversion.rb:
|
97
|
-
|
98
|
-
require 'openc3/conversions/conversion'
|
99
|
-
module OpenC3
|
100
|
-
class TheGreatConversion < Conversion
|
101
|
-
def initialize(multiplier)
|
102
|
-
super()
|
103
|
-
@multiplier = multiplier.to_f
|
104
|
-
end
|
105
|
-
def call(value, packet, buffer)
|
106
|
-
return value * multiplier
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
python_example: |
|
111
|
-
WRITE_CONVERSION the_great_conversion.py 1000
|
112
|
-
|
113
|
-
Defined in the_great_conversion.py:
|
114
|
-
|
115
|
-
from openc3.conversions.conversion import Conversion
|
116
|
-
class TheGreatConversion(Conversion):
|
117
|
-
def __init__(self, multiplier):
|
118
|
-
super().__init__()
|
119
|
-
self.multiplier = float(multiplier)
|
120
|
-
def call(self, value, packet, buffer):
|
121
|
-
return value * self.multiplier
|
122
93
|
parameters:
|
123
94
|
- name: Class Filename
|
124
95
|
required: true
|
125
96
|
description: The filename which contains the Ruby or Python class. The filename must
|
126
97
|
be named after the class such that the class is a CamelCase version of the
|
127
98
|
underscored filename. For example, 'the_great_conversion.rb' should contain
|
128
|
-
'class TheGreatConversion'.
|
99
|
+
'class TheGreatConversion'. Note the built-in Python conversions must specify
|
100
|
+
the full path to the file, e.g. 'openc3/conversions/bit_reverse_conversion.py'.
|
129
101
|
values: .*
|
130
102
|
- name: Parameter
|
131
103
|
required: false
|
132
104
|
description: Additional parameter values for the conversion which are passed
|
133
105
|
to the class constructor.
|
134
106
|
values: .*
|
107
|
+
ruby_example: |
|
108
|
+
WRITE_CONVERSION ip_write_conversion.rb
|
109
|
+
python_example: |
|
110
|
+
WRITE_CONVERSION openc3/conversions/ip_write_conversion.py
|
135
111
|
POLY_WRITE_CONVERSION:
|
136
112
|
summary: Adds a polynomial conversion factor to the current command parameter
|
137
|
-
description:
|
138
|
-
before it is written into the binary command packet and sent.
|
139
|
-
example: POLY_WRITE_CONVERSION 10 0.5 0.25
|
140
|
-
parameters:
|
141
|
-
- name: C0
|
142
|
-
required: true
|
143
|
-
description: Coefficient
|
144
|
-
values: .*
|
145
|
-
- name: Cx
|
146
|
-
required: false
|
147
|
-
description: Additional coefficient values for the conversion. Any order
|
148
|
-
polynomial conversion may be used so the value of 'x' will vary with the
|
149
|
-
order of the polynomial. Note that larger order polynomials take longer
|
150
|
-
to process than shorter order polynomials, but are sometimes more accurate.
|
151
|
-
values: .*
|
113
|
+
description: See [Polynomial Conversion](/docs/configuration/conversions#polynomial_conversion) for more information.
|
152
114
|
SEG_POLY_WRITE_CONVERSION:
|
153
115
|
summary: Adds a segmented polynomial conversion factor to the current command parameter
|
154
|
-
description:
|
155
|
-
before it is written into the binary command packet and sent.
|
156
|
-
example: |
|
157
|
-
SEG_POLY_WRITE_CONVERSION 0 10 0.5 0.25 # Apply the conversion to all values < 50
|
158
|
-
SEG_POLY_WRITE_CONVERSION 50 11 0.5 0.275 # Apply the conversion to all values >= 50 and < 100
|
159
|
-
SEG_POLY_WRITE_CONVERSION 100 12 0.5 0.3 # Apply the conversion to all values >= 100
|
160
|
-
parameters:
|
161
|
-
- name: Lower Bound
|
162
|
-
required: true
|
163
|
-
description: Defines the lower bound of the range of values that this segmented
|
164
|
-
polynomial applies to. Is ignored for the segment with the smallest lower bound.
|
165
|
-
values: .*
|
166
|
-
- name: C0
|
167
|
-
required: true
|
168
|
-
description: Coefficient
|
169
|
-
values: .*
|
170
|
-
- name: Cx
|
171
|
-
required: false
|
172
|
-
description: Additional coefficient values for the conversion. Any order
|
173
|
-
polynomial conversion may be used so the value of 'x' will vary with the
|
174
|
-
order of the polynomial. Note that larger order polynomials take longer
|
175
|
-
to process than shorter order polynomials, but are sometimes more accurate.
|
176
|
-
values: .*
|
116
|
+
description: See [Segmented Polynomial Conversion](/docs/configuration/conversions#segmented_polynomial_conversion) for more information.
|
177
117
|
GENERIC_WRITE_CONVERSION_START:
|
178
118
|
summary: Start a generic write conversion
|
179
119
|
description: |
|
data/data/config/plugins.yaml
CHANGED
@@ -88,4 +88,17 @@ WIDGET:
|
|
88
88
|
- name: Regex
|
89
89
|
required: false
|
90
90
|
description: Regex to match against filenames. If match, then no ERB processing
|
91
|
-
values: .+
|
91
|
+
values: .+
|
92
|
+
SCRIPT_ENGINE:
|
93
|
+
summary: Define a script engine to add language support to Script Runner
|
94
|
+
example: SCRIPT_ENGINE .print print_script_engine.py
|
95
|
+
description: Defines a script engine to add language support to Script Runner
|
96
|
+
parameters:
|
97
|
+
- name: Extension
|
98
|
+
description: Extension that will use this script engine
|
99
|
+
required: true
|
100
|
+
values: .+
|
101
|
+
- name: Script Engine Filename
|
102
|
+
description: Filename that implements the script engine. Should be in top level lib folder in plugin.
|
103
|
+
required: true
|
104
|
+
values: .+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
---
|
2
|
+
WATERMARK_PROCESSOR:
|
3
|
+
summary: Calculates high and low values for a given item
|
4
|
+
description: |
|
5
|
+
Stores high and low values for a given item as HIGH_WATER and LOW_WATER.
|
6
|
+
Values are retrieved using a [ProcessorConversion](/docs/configuration/conversions#processor_conversion).
|
7
|
+
parameters:
|
8
|
+
- name: Item Name
|
9
|
+
description: The item name to calculate high and low values for
|
10
|
+
required: true
|
11
|
+
values: .+
|
12
|
+
- name: Value Type
|
13
|
+
required: false
|
14
|
+
description: The type of the value to display. Default is CONVERTED.
|
15
|
+
values: <%= %w(RAW CONVERTED) %>
|
16
|
+
ruby_example: |
|
17
|
+
PROCESSOR TEMP1WATER watermark_processor.rb TEMP1
|
18
|
+
ITEM TEMP1HIGH 0 0 DERIVED "High-water mark for TEMP1"
|
19
|
+
READ_CONVERSION processor_conversion.rb TEMP1WATER HIGH_WATER
|
20
|
+
python_example: |
|
21
|
+
PROCESSOR TEMP1WATER openc3/conversions/watermark_processor.py TEMP1
|
22
|
+
ITEM TEMP1HIGH 0 0 DERIVED "High-water mark for TEMP1"
|
23
|
+
READ_CONVERSION openc3/conversions/processor_conversion.py TEMP1WATER HIGH_WATER
|
24
|
+
STATISTICS_PROCESSOR:
|
25
|
+
summary: Calculates statistics for a given item
|
26
|
+
description: |
|
27
|
+
This processor calculates statistics for a given item as MIN, MAX, MEAN, and STDDEV
|
28
|
+
over a specified number of samples. Values are retrieved using a [ProcessorConversion](/docs/configuration/conversions#processor_conversion).
|
29
|
+
parameters:
|
30
|
+
- name: Item Name
|
31
|
+
description: The item name to calculate statistics for
|
32
|
+
required: true
|
33
|
+
values: .+
|
34
|
+
- name: Samples to Average
|
35
|
+
required: true
|
36
|
+
description: The number of samples to average for statistics
|
37
|
+
values: .*
|
38
|
+
- name: Value Type
|
39
|
+
required: false
|
40
|
+
description: The type of the value to display. Default is CONVERTED.
|
41
|
+
values: <%= %w(RAW CONVERTED) %>
|
42
|
+
ruby_example: PROCESSOR TEMP1STAT statistics_processor.rb TEMP1 100
|
43
|
+
python_example: PROCESSOR TEMP1STAT openc3/processors/statistics_processor.rb TEMP1 100
|
44
|
+
ruby_example: |
|
45
|
+
PROCESSOR TEMP1STAT statistics_processor.rb TEMP1 100
|
46
|
+
ITEM TEMP1STDDEV 0 0 DERIVED "Stddev of most recent 100 samples for TEMP1"
|
47
|
+
READ_CONVERSION processor_conversion.rb TEMP1STAT STDDEV FLOAT 64
|
48
|
+
python_example: |
|
49
|
+
PROCESSOR TEMP1STAT openc3/conversions/statistics_processor.py TEMP1 100
|
50
|
+
ITEM TEMP1STDDEV 0 0 DERIVED "Stddev of most recent 100 samples for TEMP1"
|
51
|
+
READ_CONVERSION openc3/conversions/processor_conversion.py TEMP1STAT STDDEV FLOAT 64
|
@@ -135,6 +135,7 @@ META:
|
|
135
135
|
values: .*
|
136
136
|
PROCESSOR:
|
137
137
|
summary: Defines a processor class that executes code every time a packet is received
|
138
|
+
description: See the [Processor](/docs/configuration/processors) documentation for more information.
|
138
139
|
ruby_example: PROCESSOR TEMP1HIGH watermark_processor.rb TEMP1
|
139
140
|
python_example: PROCESSOR TEMP1HIGH watermark_processor.py TEMP1
|
140
141
|
parameters:
|
data/lib/openc3/api/api.rb
CHANGED
data/lib/openc3/api/tlm_api.rb
CHANGED
@@ -114,8 +114,8 @@ module OpenC3
|
|
114
114
|
#
|
115
115
|
# @param args [String|Array<String>] See the description for calling style
|
116
116
|
# @param type [Symbol] Telemetry type, :RAW, :CONVERTED (default), :FORMATTED, or :WITH_UNITS
|
117
|
-
def set_tlm(*args, type: :CONVERTED, manual: false, scope: $openc3_scope, token: $openc3_token)
|
118
|
-
target_name, packet_name, item_name, value = _set_tlm_process_args(args, __method__, scope: scope)
|
117
|
+
def set_tlm(*args, type: :CONVERTED, manual: false, cache_timeout: nil, scope: $openc3_scope, token: $openc3_token)
|
118
|
+
target_name, packet_name, item_name, value = _set_tlm_process_args(args, __method__, cache_timeout: cache_timeout, scope: scope)
|
119
119
|
authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, manual: manual, scope: scope, token: token)
|
120
120
|
CvtModel.set_item(target_name, packet_name, item_name, value, type: type.intern, scope: scope)
|
121
121
|
end
|
@@ -528,7 +528,7 @@ module OpenC3
|
|
528
528
|
return [target_name, packet_name, item_name]
|
529
529
|
end
|
530
530
|
|
531
|
-
def _set_tlm_process_args(args, method_name, scope: $openc3_scope, token: $openc3_token)
|
531
|
+
def _set_tlm_process_args(args, method_name, cache_timeout: nil, scope: $openc3_scope, token: $openc3_token)
|
532
532
|
case args.length
|
533
533
|
when 1
|
534
534
|
target_name, packet_name, item_name, value = extract_fields_from_set_tlm_text(args[0])
|
@@ -544,8 +544,13 @@ module OpenC3
|
|
544
544
|
target_name = target_name.upcase
|
545
545
|
packet_name = packet_name.upcase
|
546
546
|
item_name = item_name.upcase
|
547
|
-
|
548
|
-
|
547
|
+
|
548
|
+
if packet_name == 'LATEST'
|
549
|
+
packet_name = CvtModel.determine_latest_packet_for_item(target_name, item_name, cache_timeout: cache_timeout, scope: scope)
|
550
|
+
else
|
551
|
+
# Determine if this item exists, it will raise appropriate errors if not
|
552
|
+
TargetModel.packet_item(target_name, packet_name, item_name, scope: scope)
|
553
|
+
end
|
549
554
|
|
550
555
|
return [target_name, packet_name, item_name, value]
|
551
556
|
end
|
@@ -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
|
@@ -35,7 +35,7 @@ module OpenC3
|
|
35
35
|
super()
|
36
36
|
@seconds_item_name = seconds_item_name
|
37
37
|
@microseconds_item_name = microseconds_item_name
|
38
|
-
@converted_type = :
|
38
|
+
@converted_type = :TIME
|
39
39
|
@converted_bit_size = 0
|
40
40
|
@seconds_type = seconds_type.to_sym
|
41
41
|
@microseconds_type = microseconds_type.to_sym
|
@@ -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
|
@@ -32,9 +32,9 @@ module OpenC3
|
|
32
32
|
# represents the number of seconds since the UNIX time epoch
|
33
33
|
# @param microseconds_item_name [String] The telemetry item in the packet
|
34
34
|
# which represents microseconds
|
35
|
-
def initialize(seconds_item_name, microseconds_item_name = nil)
|
35
|
+
def initialize(seconds_item_name, microseconds_item_name = nil, seconds_type = 'RAW', microseconds_type = 'RAW')
|
36
36
|
# @params is set by the parent class in super()
|
37
|
-
super(seconds_item_name, microseconds_item_name)
|
37
|
+
super(seconds_item_name, microseconds_item_name, seconds_type, microseconds_type)
|
38
38
|
@converted_type = :STRING
|
39
39
|
@converted_bit_size = 0
|
40
40
|
end
|
@@ -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
|
@@ -32,9 +32,9 @@ module OpenC3
|
|
32
32
|
# represents the number of seconds since the UNIX time epoch
|
33
33
|
# @param microseconds_item_name [String] The telemetry item in the packet
|
34
34
|
# which represents microseconds
|
35
|
-
def initialize(seconds_item_name, microseconds_item_name = nil)
|
35
|
+
def initialize(seconds_item_name, microseconds_item_name = nil, seconds_type = 'RAW', microseconds_type = 'RAW')
|
36
36
|
# @params is set by the parent class in super()
|
37
|
-
super(seconds_item_name, microseconds_item_name)
|
37
|
+
super(seconds_item_name, microseconds_item_name, seconds_type, microseconds_type)
|
38
38
|
@converted_type = :FLOAT
|
39
39
|
@converted_bit_size = 64
|
40
40
|
end
|
data/lib/openc3/core_ext/time.rb
CHANGED
@@ -249,19 +249,12 @@ class Time
|
|
249
249
|
Time.total_seconds(self.hour, self.min, self.sec, self.usec)
|
250
250
|
end
|
251
251
|
|
252
|
-
# @return [String] Date formatted as YYYY/MM/DD HH:MM:SS.US
|
253
|
-
def formatted(include_year = true, fractional_digits = 3
|
252
|
+
# @return [String] Date formatted as YYYY/MM/DD HH:MM:SS.US
|
253
|
+
def formatted(include_year = true, fractional_digits = 3)
|
254
254
|
str = ""
|
255
255
|
str << "%Y/%m/%d " if include_year
|
256
256
|
str << "%H:%M:%S"
|
257
257
|
str << ".%#{fractional_digits}N" if fractional_digits > 0
|
258
|
-
if include_utc_offset
|
259
|
-
if self.utc?
|
260
|
-
str << " UTC"
|
261
|
-
else
|
262
|
-
str << " %z"
|
263
|
-
end
|
264
|
-
end
|
265
258
|
self.strftime(str)
|
266
259
|
end
|
267
260
|
|
@@ -128,15 +128,21 @@ module OpenC3
|
|
128
128
|
end
|
129
129
|
if msg_hash['raw']
|
130
130
|
if @interface.connected?
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
131
|
+
begin
|
132
|
+
@logger.info "#{@interface.name}: Write raw"
|
133
|
+
# A raw interface write results in an UNKNOWN packet
|
134
|
+
command = System.commands.packet('UNKNOWN', 'UNKNOWN')
|
135
|
+
command.received_count = TargetModel.increment_command_count('UNKNOWN', 'UNKNOWN', 1, scope: @scope)
|
136
|
+
command = command.clone
|
137
|
+
command.buffer = msg_hash['raw']
|
138
|
+
command.received_time = Time.now
|
139
|
+
CommandTopic.write_packet(command, scope: @scope)
|
140
|
+
@logger.info("write_raw sent #{msg_hash['raw'].length} bytes to #{@interface.name}", scope: @scope)
|
141
|
+
@interface.write_raw(msg_hash['raw'])
|
142
|
+
rescue => e
|
143
|
+
@logger.error "#{@interface.name}: write_raw: #{e.formatted}"
|
144
|
+
next e.message
|
145
|
+
end
|
140
146
|
next 'SUCCESS'
|
141
147
|
else
|
142
148
|
next "Interface not connected: #{@interface.name}"
|
@@ -824,7 +830,7 @@ module OpenC3
|
|
824
830
|
end
|
825
831
|
|
826
832
|
def sync_tlm_packet_counts(packet)
|
827
|
-
if @sync_packet_count_delay_seconds <= 0
|
833
|
+
if @sync_packet_count_delay_seconds <= 0 or $openc3_redis_cluster
|
828
834
|
# Perfect but slow method
|
829
835
|
packet.received_count = TargetModel.increment_telemetry_count(packet.target_name, packet.packet_name, 1, scope: @scope)
|
830
836
|
else
|
@@ -880,6 +886,6 @@ end
|
|
880
886
|
|
881
887
|
if __FILE__ == $0
|
882
888
|
OpenC3::InterfaceMicroservice.run
|
883
|
-
ThreadManager.instance.shutdown
|
884
|
-
ThreadManager.instance.join
|
889
|
+
OpenC3::ThreadManager.instance.shutdown
|
890
|
+
OpenC3::ThreadManager.instance.join
|
885
891
|
end
|
@@ -55,6 +55,8 @@ module OpenC3
|
|
55
55
|
@cycle_size = 50_000_000 unless @cycle_size # ~50 MB
|
56
56
|
|
57
57
|
@buffer_depth = DEFAULT_BUFFER_DEPTH unless @buffer_depth
|
58
|
+
@plws = {}
|
59
|
+
|
58
60
|
@error_count = 0
|
59
61
|
@metric.set(name: 'log_total', value: @count, type: 'counter')
|
60
62
|
@metric.set(name: 'log_error_total', value: @error_count, type: 'counter')
|
@@ -144,6 +146,6 @@ end
|
|
144
146
|
|
145
147
|
if __FILE__ == $0
|
146
148
|
OpenC3::LogMicroservice.run
|
147
|
-
ThreadManager.instance.shutdown
|
148
|
-
ThreadManager.instance.join
|
149
|
+
OpenC3::ThreadManager.instance.shutdown
|
150
|
+
OpenC3::ThreadManager.instance.join
|
149
151
|
end
|
@@ -43,6 +43,7 @@ module OpenC3
|
|
43
43
|
@cycle_time = 600 unless @cycle_time # 10 minutes
|
44
44
|
@cycle_size = 50_000_000 unless @cycle_size # ~50 MB
|
45
45
|
|
46
|
+
@tlws = {}
|
46
47
|
@error_count = 0
|
47
48
|
@metric.set(name: 'text_log_total', value: @count, type: 'counter')
|
48
49
|
@metric.set(name: 'text_error_total', value: @error_count, type: 'counter')
|
@@ -50,15 +51,27 @@ module OpenC3
|
|
50
51
|
|
51
52
|
def run
|
52
53
|
setup_tlws()
|
54
|
+
|
55
|
+
individual_topics = []
|
56
|
+
@topics.each do |topic|
|
57
|
+
individual_topics << [topic]
|
58
|
+
end
|
59
|
+
|
53
60
|
while true
|
54
61
|
break if @cancel_thread
|
55
62
|
|
56
|
-
|
63
|
+
# Read each topic separately to support multiple redis shards
|
64
|
+
# This is needed with Redis cluster because the topics will likely be on different shards and we don't use {} in the topic names
|
65
|
+
individual_topics.each do |individual_topic|
|
57
66
|
break if @cancel_thread
|
67
|
+
# 500ms timeout - To support completing within 1 second with two topics (DEFAULT and NOSCOPE)
|
68
|
+
Topic.read_topics(individual_topic, nil, 500) do |topic, msg_id, msg_hash, redis|
|
69
|
+
break if @cancel_thread
|
58
70
|
|
59
|
-
|
60
|
-
|
61
|
-
|
71
|
+
log_data(topic, msg_id, msg_hash, redis)
|
72
|
+
@count += 1
|
73
|
+
@metric.set(name: 'text_log_total', value: @count, type: 'counter')
|
74
|
+
end
|
62
75
|
end
|
63
76
|
end
|
64
77
|
end
|
@@ -104,6 +117,6 @@ end
|
|
104
117
|
|
105
118
|
if __FILE__ == $0
|
106
119
|
OpenC3::TextLogMicroservice.run
|
107
|
-
ThreadManager.instance.shutdown
|
108
|
-
ThreadManager.instance.join
|
120
|
+
OpenC3::ThreadManager.instance.shutdown
|
121
|
+
OpenC3::ThreadManager.instance.join
|
109
122
|
end
|
@@ -31,6 +31,7 @@ require 'openc3/models/gem_model'
|
|
31
31
|
require 'openc3/models/target_model'
|
32
32
|
require 'openc3/models/interface_model'
|
33
33
|
require 'openc3/models/router_model'
|
34
|
+
require 'openc3/models/script_engine_model'
|
34
35
|
require 'openc3/models/tool_model'
|
35
36
|
require 'openc3/models/widget_model'
|
36
37
|
require 'openc3/models/microservice_model'
|
@@ -249,7 +250,7 @@ module OpenC3
|
|
249
250
|
case keyword
|
250
251
|
when 'VARIABLE', 'NEEDS_DEPENDENCIES'
|
251
252
|
# Ignore during phase 2
|
252
|
-
when 'TARGET', 'INTERFACE', 'ROUTER', 'MICROSERVICE', 'TOOL', 'WIDGET'
|
253
|
+
when 'TARGET', 'INTERFACE', 'ROUTER', 'MICROSERVICE', 'TOOL', 'WIDGET', 'SCRIPT_ENGINE'
|
253
254
|
begin
|
254
255
|
if current_model
|
255
256
|
current_model.create unless validate_only
|
@@ -260,7 +261,7 @@ module OpenC3
|
|
260
261
|
# Otherwise we're stuck constantly iterating on the last model
|
261
262
|
ensure
|
262
263
|
current_model = nil
|
263
|
-
current_model = OpenC3.const_get((keyword.capitalize + 'Model').intern).handle_config(parser,
|
264
|
+
current_model = OpenC3.const_get((keyword.split('_').collect(&:capitalize).join + 'Model').intern).handle_config(parser,
|
264
265
|
keyword, params, plugin: plugin_model.name, needs_dependencies: needs_dependencies, scope: scope)
|
265
266
|
end
|
266
267
|
else
|
@@ -339,7 +340,7 @@ module OpenC3
|
|
339
340
|
sleep 15 if microservice_count > 0 # Cycle time 5s times 2 plus 5s wait for soft stop and then hard stop
|
340
341
|
# Remove all the other models now that the processes have stopped
|
341
342
|
# Save TargetModel for last as it has the most to cleanup
|
342
|
-
[InterfaceModel, RouterModel, ToolModel, WidgetModel, TargetModel].each do |model|
|
343
|
+
[InterfaceModel, RouterModel, ToolModel, WidgetModel, TargetModel, ScriptEngineModel].each do |model|
|
343
344
|
model.find_all_by_plugin(plugin: @name, scope: @scope).each do |_name, model_instance|
|
344
345
|
begin
|
345
346
|
model_instance.destroy
|
@@ -369,7 +370,7 @@ module OpenC3
|
|
369
370
|
ensure
|
370
371
|
# Double check everything is gone
|
371
372
|
found = []
|
372
|
-
[MicroserviceModel, InterfaceModel, RouterModel, ToolModel, WidgetModel, TargetModel].each do |model|
|
373
|
+
[MicroserviceModel, InterfaceModel, RouterModel, ToolModel, WidgetModel, TargetModel, ScriptEngineModel].each do |model|
|
373
374
|
model.find_all_by_plugin(plugin: @name, scope: @scope).each do |_name, model_instance|
|
374
375
|
found << model_instance
|
375
376
|
end
|