cosmos 4.1.0 → 4.1.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.
- checksums.yaml +4 -4
- data/Manifest.txt +5 -0
- data/appveyor.yml +2 -0
- data/autohotkey/tools/replay.ahk +45 -45
- data/autohotkey/tools/script_runner.ahk +3 -9
- data/cosmos.gemspec +1 -1
- data/data/config/interface_modifiers.yaml +23 -0
- data/data/config/screen.yaml +1 -1
- data/data/crc.txt +20 -18
- data/demo/config/targets/INST/cmd_tlm_server.txt +1 -1
- data/lib/cosmos/config/config_parser.rb +8 -3
- data/lib/cosmos/gui/dialogs/exception_dialog.rb +20 -5
- data/lib/cosmos/interfaces/protocols/burst_protocol.rb +13 -3
- data/lib/cosmos/interfaces/protocols/crc_protocol.rb +27 -3
- data/lib/cosmos/interfaces/protocols/fixed_protocol.rb +4 -2
- data/lib/cosmos/interfaces/protocols/length_protocol.rb +4 -2
- data/lib/cosmos/interfaces/protocols/override_protocol.rb +2 -2
- data/lib/cosmos/interfaces/protocols/preidentified_protocol.rb +3 -2
- data/lib/cosmos/interfaces/protocols/protocol.rb +16 -4
- data/lib/cosmos/interfaces/protocols/template_protocol.rb +7 -2
- data/lib/cosmos/interfaces/protocols/terminated_protocol.rb +4 -2
- data/lib/cosmos/packets/packet_config.rb +19 -859
- data/lib/cosmos/packets/packet_item.rb +56 -201
- data/lib/cosmos/packets/parsers/xtce_converter.rb +440 -0
- data/lib/cosmos/packets/parsers/xtce_parser.rb +682 -0
- data/lib/cosmos/tools/config_editor/config_editor.rb +143 -5
- data/lib/cosmos/tools/tlm_viewer/screen.rb +1 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +5 -3
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +40 -27
- data/lib/cosmos/version.rb +4 -4
- data/spec/config/config_parser_spec.rb +39 -2
- data/spec/install/config/targets/INST/screens/hs.txt +42 -0
- data/spec/install/config/targets/INST/target.txt +2 -0
- data/spec/interfaces/protocols/burst_protocol_spec.rb +18 -0
- data/spec/interfaces/protocols/length_protocol_spec.rb +49 -0
- data/spec/interfaces/udp_interface_spec.rb +0 -9
- data/spec/packets/packet_config_spec.rb +21 -144
- data/spec/packets/packet_item_spec.rb +68 -4
- data/spec/packets/parsers/packet_item_parser_spec.rb +12 -0
- data/spec/packets/parsers/xtce_parser_spec.rb +398 -0
- data/spec/tools/tlm_viewer/tlm_viewer_config_spec.rb +401 -0
- metadata +9 -10
@@ -0,0 +1,42 @@
|
|
1
|
+
SCREEN AUTO AUTO 0.5
|
2
|
+
GLOBAL_SETTING LABELVALUELIMITSBAR COLORBLIND TRUE
|
3
|
+
|
4
|
+
VERTICAL
|
5
|
+
|
6
|
+
TITLE "Instrument Health and Status"
|
7
|
+
SETTING BACKCOLOR 162 181 205
|
8
|
+
SETTING TEXTCOLOR black
|
9
|
+
|
10
|
+
VERTICALBOX
|
11
|
+
SECTIONHEADER "General Telemetry"
|
12
|
+
NAMED_WIDGET COLLECT_TYPE COMBOBOX NORMAL SPECIAL
|
13
|
+
BUTTON 'Start Collect' 'target_name = get_target_name("INST"); cmd("#{target_name} COLLECT with TYPE NORMAL, DURATION 5")'
|
14
|
+
FORMATVALUE INST HEALTH_STATUS COLLECTS "0x%08X"
|
15
|
+
LABELVALUE INST HEALTH_STATUS COLLECT_TYPE
|
16
|
+
LABELVALUE INST HEALTH_STATUS DURATION
|
17
|
+
LABELVALUE INST HEALTH_STATUS ASCIICMD WITH_UNITS 30
|
18
|
+
END
|
19
|
+
SETTING BACKCOLOR 163 185 163
|
20
|
+
|
21
|
+
VERTICALBOX
|
22
|
+
SECTIONHEADER "Temperatures"
|
23
|
+
LABELTRENDLIMITSBAR INST HEALTH_STATUS TEMP1 WITH_UNITS 5
|
24
|
+
LABELVALUELIMITSBAR INST HEALTH_STATUS TEMP2 CONVERTED 25
|
25
|
+
# LABELVALUELIMITSBAR INST HEALTH_STATUS TEMP2 RAW 20 # RAW is not allowed for LIMITSBAR widgets
|
26
|
+
LABELVALUELIMITSBAR INST HEALTH_STATUS TEMP2 FORMATTED
|
27
|
+
LABELVALUELIMITSBAR INST HEALTH_STATUS TEMP2 WITH_UNITS
|
28
|
+
LABELVALUELIMITSBAR INST HEALTH_STATUS TEMP3
|
29
|
+
LABELVALUELIMITSBAR INST HEALTH_STATUS TEMP4
|
30
|
+
SETTING GRAY_TOLERANCE 0.1
|
31
|
+
END
|
32
|
+
SETTING BACKCOLOR 203 173 158
|
33
|
+
|
34
|
+
VERTICALBOX
|
35
|
+
SECTIONHEADER "Ground Station"
|
36
|
+
LABELVALUE INST HEALTH_STATUS GROUND1STATUS
|
37
|
+
LABELVALUE INST HEALTH_STATUS GROUND2STATUS
|
38
|
+
END
|
39
|
+
|
40
|
+
SETTING BACKCOLOR 207 171 169
|
41
|
+
END
|
42
|
+
SETTING BACKCOLOR 162 181 205
|
@@ -197,6 +197,24 @@ module Cosmos
|
|
197
197
|
pkt = @interface.read
|
198
198
|
expect(pkt.length).to eql 3 # sync plus one byte
|
199
199
|
end
|
200
|
+
|
201
|
+
it "handle auto allow_empty_data correctly" do
|
202
|
+
@interface.add_protocol(BurstProtocol, [0, nil, false, nil], :READ_WRITE)
|
203
|
+
expect(@interface.read_protocols[0].read_data("")).to eql :STOP
|
204
|
+
expect(@interface.read_protocols[0].read_data("A")).to eql "A"
|
205
|
+
@interface.add_protocol(BurstProtocol, [0, nil, false, nil], :READ_WRITE)
|
206
|
+
expect(@interface.read_protocols[0].read_data("")).to eql ""
|
207
|
+
expect(@interface.read_protocols[1].read_data("")).to eql :STOP
|
208
|
+
expect(@interface.read_protocols[0].read_data("A")).to eql "A"
|
209
|
+
expect(@interface.read_protocols[1].read_data("A")).to eql "A"
|
210
|
+
@interface.add_protocol(BurstProtocol, [0, nil, false, nil], :READ_WRITE)
|
211
|
+
expect(@interface.read_protocols[0].read_data("")).to eql ""
|
212
|
+
expect(@interface.read_protocols[1].read_data("")).to eql ""
|
213
|
+
expect(@interface.read_protocols[2].read_data("")).to eql :STOP
|
214
|
+
expect(@interface.read_protocols[0].read_data("A")).to eql "A"
|
215
|
+
expect(@interface.read_protocols[1].read_data("A")).to eql "A"
|
216
|
+
expect(@interface.read_protocols[2].read_data("A")).to eql "A"
|
217
|
+
end
|
200
218
|
end
|
201
219
|
|
202
220
|
describe "write" do
|
@@ -46,6 +46,55 @@ module Cosmos
|
|
46
46
|
end
|
47
47
|
|
48
48
|
describe "read" do
|
49
|
+
it "caches data for reads correctly" do
|
50
|
+
@interface.instance_variable_set(:@stream, LengthStream.new)
|
51
|
+
@interface.add_protocol(LengthProtocol, [
|
52
|
+
0, # bit offset
|
53
|
+
8, # bit size
|
54
|
+
0, # length offset
|
55
|
+
1, # bytes per count
|
56
|
+
'BIG_ENDIAN'], :READ_WRITE)
|
57
|
+
$buffer = "\x02\x03\x02\x05"
|
58
|
+
packet = @interface.read
|
59
|
+
expect(packet.buffer.length).to eql 2
|
60
|
+
expect(packet.buffer).to eql "\x02\x03"
|
61
|
+
packet = @interface.read
|
62
|
+
expect(packet.buffer.length).to eql 2
|
63
|
+
expect(packet.buffer).to eql "\x02\x05"
|
64
|
+
expect(@interface.read_protocols[0].read_data("\x03\x01\x02\x03\x04\x05")).to eql "\x03\x01\x02"
|
65
|
+
expect(@interface.read_protocols[0].read_data("")).to eql "\x03\x04\x05"
|
66
|
+
expect(@interface.read_protocols[0].read_data("")).to eql :STOP
|
67
|
+
end
|
68
|
+
|
69
|
+
# This test case uses two length protocols to verify that data flows correctly between the two protocols and that earlier data
|
70
|
+
# is removed correctly using discard leading bytes. In general it is not typical to use two different length protocols, but it could
|
71
|
+
# be useful to pull out a packet inside of a packet.
|
72
|
+
it "caches data for reads correctly with multiple protocols" do
|
73
|
+
@interface.instance_variable_set(:@stream, LengthStream.new)
|
74
|
+
@interface.add_protocol(LengthProtocol, [
|
75
|
+
0, # bit offset
|
76
|
+
8, # bit size
|
77
|
+
0, # length offset
|
78
|
+
1, # bytes per count
|
79
|
+
'BIG_ENDIAN'], :READ_WRITE)
|
80
|
+
@interface.add_protocol(LengthProtocol, [
|
81
|
+
0, # bit offset
|
82
|
+
8, # bit size
|
83
|
+
0, # length offset
|
84
|
+
1, # bytes per count
|
85
|
+
'BIG_ENDIAN',
|
86
|
+
1], :READ_WRITE) # Discard leading bytes set to 1
|
87
|
+
# The second protocol above will receive the two byte packets from the first protocol and
|
88
|
+
# then drop the length field.
|
89
|
+
$buffer = "\x02\x03\x02\x05"
|
90
|
+
packet = @interface.read
|
91
|
+
expect(packet.buffer.length).to eql 1
|
92
|
+
expect(packet.buffer).to eql "\x03"
|
93
|
+
packet = @interface.read
|
94
|
+
expect(packet.buffer.length).to eql 1
|
95
|
+
expect(packet.buffer).to eql "\x05"
|
96
|
+
end
|
97
|
+
|
49
98
|
it "reads LITTLE_ENDIAN length fields from the stream" do
|
50
99
|
@interface.instance_variable_set(:@stream, LengthStream.new)
|
51
100
|
@interface.add_protocol(LengthProtocol, [
|
@@ -100,15 +100,6 @@ module Cosmos
|
|
100
100
|
end
|
101
101
|
|
102
102
|
describe "read" do
|
103
|
-
it "stops the read thread if no read port given" do
|
104
|
-
i = UdpInterface.new('localhost','8888','nil')
|
105
|
-
i.connect
|
106
|
-
thread = Thread.new { i.read }
|
107
|
-
sleep 0.1
|
108
|
-
expect(thread.stop?).to be true
|
109
|
-
Cosmos.kill_thread(nil, thread)
|
110
|
-
end
|
111
|
-
|
112
103
|
it "stops the read thread if there is an IOError" do
|
113
104
|
read = double("read")
|
114
105
|
allow(read).to receive(:read).and_raise(IOError)
|
@@ -13,36 +13,6 @@ require 'cosmos'
|
|
13
13
|
require 'cosmos/packets/packet_config'
|
14
14
|
require 'tempfile'
|
15
15
|
|
16
|
-
XTCE_START =<<END
|
17
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
18
|
-
<xtce:SpaceSystem xmlns:xtce="http://www.omg.org/space/xtce" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="INST" xsi:schemaLocation="http://www.omg.org/space/xtce http://www.omg.org/spec/XTCE/20061101/06-11-06.xsd">
|
19
|
-
<xtce:TelemetryMetaData>
|
20
|
-
<xtce:ParameterTypeSet>
|
21
|
-
<xtce:IntegerParameterType name="A_Type" shortDescription="A" signed="false">
|
22
|
-
<xtce:UnitSet/>
|
23
|
-
END
|
24
|
-
XTCE_END =<<END
|
25
|
-
</xtce:IntegerParameterType>
|
26
|
-
</xtce:ParameterTypeSet>
|
27
|
-
<xtce:ParameterSet>
|
28
|
-
<xtce:Parameter name="A" parameterTypeRef="A_Type"/>
|
29
|
-
</xtce:ParameterSet>
|
30
|
-
<xtce:ContainerSet>
|
31
|
-
<xtce:SequenceContainer name="B_Base" abstract="true">
|
32
|
-
<xtce:EntryList>
|
33
|
-
<xtce:ParameterRefEntry parameterRef="A"/>
|
34
|
-
</xtce:EntryList>
|
35
|
-
</xtce:SequenceContainer>
|
36
|
-
<xtce:SequenceContainer name="B" shortDescription="B">
|
37
|
-
<xtce:EntryList/>
|
38
|
-
<xtce:BaseContainer containerRef="B_Base">
|
39
|
-
</xtce:BaseContainer>
|
40
|
-
</xtce:SequenceContainer>
|
41
|
-
</xtce:ContainerSet>
|
42
|
-
</xtce:TelemetryMetaData>
|
43
|
-
</xtce:SpaceSystem>
|
44
|
-
END
|
45
|
-
|
46
16
|
module Cosmos
|
47
17
|
|
48
18
|
describe PacketConfig do
|
@@ -52,120 +22,6 @@ module Cosmos
|
|
52
22
|
@pc = PacketConfig.new
|
53
23
|
end
|
54
24
|
|
55
|
-
describe "xtce support" do
|
56
|
-
it "processes xtce telemetry" do
|
57
|
-
tf = Tempfile.new(['unittest', '.xtce'])
|
58
|
-
tf.puts XTCE_START
|
59
|
-
tf.puts '<xtce:IntegerDataEncoding sizeInBits="32" encoding="unsigned"/>'
|
60
|
-
tf.puts XTCE_END
|
61
|
-
tf.close
|
62
|
-
|
63
|
-
@pc.process_file(tf.path, 'TEST')
|
64
|
-
|
65
|
-
packet = @pc.telemetry['TEST']['B']
|
66
|
-
expect(packet).to_not be_nil
|
67
|
-
expect(packet.get_item('A').endianness).to eql :BIG_ENDIAN
|
68
|
-
|
69
|
-
tf.unlink
|
70
|
-
end
|
71
|
-
|
72
|
-
it "processes explicit big endian xtce telemetry" do
|
73
|
-
tf = Tempfile.new(['unittest', '.xtce'])
|
74
|
-
tf.puts XTCE_START
|
75
|
-
tf.puts '<xtce:IntegerDataEncoding sizeInBits="32" encoding="unsigned">' + "\n"
|
76
|
-
tf.puts ' <xtce:ByteOrderList>' + "\n"
|
77
|
-
tf.puts ' <xtce:Byte byteSignificance="3"/>' + "\n"
|
78
|
-
tf.puts ' <xtce:Byte byteSignificance="2"/>' + "\n"
|
79
|
-
tf.puts ' <xtce:Byte byteSignificance="1"/>' + "\n"
|
80
|
-
tf.puts ' <xtce:Byte byteSignificance="0"/>' + "\n"
|
81
|
-
tf.puts ' </xtce:ByteOrderList>' + "\n"
|
82
|
-
tf.puts '</xtce:IntegerDataEncoding>' + "\n"
|
83
|
-
tf.puts XTCE_END
|
84
|
-
tf.close
|
85
|
-
|
86
|
-
@pc.process_file(tf.path, 'TEST')
|
87
|
-
|
88
|
-
packet = @pc.telemetry['TEST']['B']
|
89
|
-
expect(packet).to_not be_nil
|
90
|
-
expect(packet.get_item('A').endianness).to eql :BIG_ENDIAN
|
91
|
-
expect(@pc.warnings).to be_empty
|
92
|
-
|
93
|
-
tf.unlink
|
94
|
-
end
|
95
|
-
|
96
|
-
it "processes explicit little endian xtce telemetry" do
|
97
|
-
tf = Tempfile.new(['unittest', '.xtce'])
|
98
|
-
tf.puts XTCE_START
|
99
|
-
tf.puts '<xtce:IntegerDataEncoding sizeInBits="32" encoding="unsigned">' + "\n"
|
100
|
-
tf.puts ' <xtce:ByteOrderList>' + "\n"
|
101
|
-
tf.puts ' <xtce:Byte byteSignificance="0"/>' + "\n"
|
102
|
-
tf.puts ' <xtce:Byte byteSignificance="1"/>' + "\n"
|
103
|
-
tf.puts ' <xtce:Byte byteSignificance="2"/>' + "\n"
|
104
|
-
tf.puts ' <xtce:Byte byteSignificance="3"/>' + "\n"
|
105
|
-
tf.puts ' </xtce:ByteOrderList>' + "\n"
|
106
|
-
tf.puts '</xtce:IntegerDataEncoding>' + "\n"
|
107
|
-
tf.puts XTCE_END
|
108
|
-
tf.close
|
109
|
-
|
110
|
-
@pc.process_file(tf.path, 'TEST')
|
111
|
-
|
112
|
-
packet = @pc.telemetry['TEST']['B']
|
113
|
-
expect(packet).to_not be_nil
|
114
|
-
expect(packet.get_item('A').endianness).to eql :LITTLE_ENDIAN
|
115
|
-
expect(@pc.warnings).to be_empty
|
116
|
-
|
117
|
-
tf.unlink
|
118
|
-
end
|
119
|
-
|
120
|
-
it "warn of bad byteorderlist no zero xtce telemetry" do
|
121
|
-
tf = Tempfile.new(['unittest', '.xtce'])
|
122
|
-
tf.puts XTCE_START
|
123
|
-
tf.puts '<xtce:IntegerDataEncoding sizeInBits="32" encoding="unsigned">' + "\n"
|
124
|
-
tf.puts ' <xtce:ByteOrderList>' + "\n"
|
125
|
-
tf.puts ' <xtce:Byte byteSignificance="1"/>' + "\n"
|
126
|
-
tf.puts ' <xtce:Byte byteSignificance="2"/>' + "\n"
|
127
|
-
tf.puts ' <xtce:Byte byteSignificance="3"/>' + "\n"
|
128
|
-
tf.puts ' <xtce:Byte byteSignificance="4"/>' + "\n"
|
129
|
-
tf.puts ' </xtce:ByteOrderList>' + "\n"
|
130
|
-
tf.puts '</xtce:IntegerDataEncoding>' + "\n"
|
131
|
-
tf.puts XTCE_END
|
132
|
-
tf.close
|
133
|
-
|
134
|
-
@pc.process_file(tf.path, 'TEST')
|
135
|
-
|
136
|
-
packet = @pc.telemetry['TEST']['B']
|
137
|
-
expect(packet).to_not be_nil
|
138
|
-
expect(packet.get_item('A').endianness).to eql :BIG_ENDIAN
|
139
|
-
expect(@pc.warnings).to_not be_empty
|
140
|
-
|
141
|
-
tf.unlink
|
142
|
-
end
|
143
|
-
|
144
|
-
it "warn of bad byteorderlist scrambled xtce telemetry" do
|
145
|
-
tf = Tempfile.new(['unittest', '.xtce'])
|
146
|
-
tf.puts XTCE_START
|
147
|
-
tf.puts '<xtce:IntegerDataEncoding sizeInBits="32" encoding="unsigned">' + "\n"
|
148
|
-
tf.puts ' <xtce:ByteOrderList>' + "\n"
|
149
|
-
tf.puts ' <xtce:Byte byteSignificance="0"/>' + "\n"
|
150
|
-
tf.puts ' <xtce:Byte byteSignificance="2"/>' + "\n"
|
151
|
-
tf.puts ' <xtce:Byte byteSignificance="1"/>' + "\n"
|
152
|
-
tf.puts ' <xtce:Byte byteSignificance="3"/>' + "\n"
|
153
|
-
tf.puts ' </xtce:ByteOrderList>' + "\n"
|
154
|
-
tf.puts '</xtce:IntegerDataEncoding>' + "\n"
|
155
|
-
tf.puts XTCE_END
|
156
|
-
tf.close
|
157
|
-
|
158
|
-
@pc.process_file(tf.path, 'TEST')
|
159
|
-
|
160
|
-
packet = @pc.telemetry['TEST']['B']
|
161
|
-
expect(packet).to_not be_nil
|
162
|
-
expect(packet.get_item('A').endianness).to eql :LITTLE_ENDIAN
|
163
|
-
expect(@pc.warnings).to_not be_empty
|
164
|
-
|
165
|
-
tf.unlink
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
25
|
it "complains about unknown keywords" do
|
170
26
|
tf = Tempfile.new('unittest')
|
171
27
|
tf.puts("BLAH")
|
@@ -174,6 +30,27 @@ module Cosmos
|
|
174
30
|
tf.unlink
|
175
31
|
end
|
176
32
|
|
33
|
+
it "outputs parsed definitions back to a file" do
|
34
|
+
tf = Tempfile.new('unittest')
|
35
|
+
tlm = "TELEMETRY TGT1 PKT1 LITTLE_ENDIAN \"Telemetry\"\n"\
|
36
|
+
" ITEM BYTE 0 8 UINT \"Item\"\n"
|
37
|
+
tf.write tlm
|
38
|
+
cmd = "COMMAND TGT1 PKT1 LITTLE_ENDIAN \"Command\"\n"\
|
39
|
+
" PARAMETER PARAM 0 16 UINT 0 0 0 \"Param\"\n"
|
40
|
+
tf.write cmd
|
41
|
+
limits = "LIMITS_GROUP TVAC\n"\
|
42
|
+
" LIMITS_GROUP_ITEM TGT1 PKT1 ITEM1\n"
|
43
|
+
tf.write limits
|
44
|
+
tf.close
|
45
|
+
@pc.process_file(tf.path, "TGT1")
|
46
|
+
@pc.to_config(System.paths["LOGS"])
|
47
|
+
@pc.to_xtce(System.paths["LOGS"])
|
48
|
+
expect(cmd.strip).to eql File.read(File.join(System.paths["LOGS"], 'TGT1', 'cmd_tlm', 'tgt1_cmd.txt')).strip
|
49
|
+
expect(tlm.strip).to eql File.read(File.join(System.paths["LOGS"], 'TGT1', 'cmd_tlm', 'tgt1_tlm.txt')).strip
|
50
|
+
expect(limits.strip).to eql File.read(File.join(System.paths["LOGS"], 'SYSTEM', 'cmd_tlm', 'limits_groups.txt')).strip
|
51
|
+
tf.unlink
|
52
|
+
end
|
53
|
+
|
177
54
|
context "with all telemetry keywords" do
|
178
55
|
before(:all) do
|
179
56
|
# top level keywords
|
@@ -24,6 +24,7 @@ module Cosmos
|
|
24
24
|
it "sets the format_string" do
|
25
25
|
@pi.format_string = "%5.1f"
|
26
26
|
expect(@pi.format_string).to eql "%5.1f"
|
27
|
+
expect(@pi.to_config(:TELEMETRY, :BIG_ENDIAN)).to match /FORMAT_STRING %5.1f/
|
27
28
|
end
|
28
29
|
|
29
30
|
it "sets the format_string to nil" do
|
@@ -47,6 +48,10 @@ module Cosmos
|
|
47
48
|
c = GenericConversion.new("value / 2")
|
48
49
|
@pi.read_conversion = c
|
49
50
|
expect(@pi.read_conversion.to_s == c.to_s).to be true
|
51
|
+
config = @pi.to_config(:TELEMETRY, :BIG_ENDIAN)
|
52
|
+
expect(config).to match /GENERIC_READ_CONVERSION_START/
|
53
|
+
expect(config).to match /value \/ 2/
|
54
|
+
expect(config).to match /GENERIC_READ_CONVERSION_END/
|
50
55
|
end
|
51
56
|
|
52
57
|
it "sets the read_conversion to nil" do
|
@@ -64,6 +69,10 @@ module Cosmos
|
|
64
69
|
c = GenericConversion.new("value / 2")
|
65
70
|
@pi.write_conversion = c
|
66
71
|
expect(@pi.write_conversion.to_s == c.to_s).to be true
|
72
|
+
config = @pi.to_config(:TELEMETRY, :BIG_ENDIAN)
|
73
|
+
expect(config).to match /GENERIC_WRITE_CONVERSION_START/
|
74
|
+
expect(config).to match /value \/ 2/
|
75
|
+
expect(config).to match /GENERIC_WRITE_CONVERSION_END/
|
67
76
|
end
|
68
77
|
|
69
78
|
it "sets the write_conversion to nil" do
|
@@ -78,14 +87,22 @@ module Cosmos
|
|
78
87
|
|
79
88
|
describe "id_value=" do
|
80
89
|
it "accepts id values according to data_type" do
|
90
|
+
@pi.range = (0..10)
|
81
91
|
@pi.id_value = 10
|
82
92
|
expect(@pi.id_value).to eql 10
|
83
93
|
@pi.data_type = :FLOAT
|
84
94
|
@pi.id_value = 10.0
|
85
95
|
expect(@pi.id_value).to eql 10.0
|
96
|
+
expect(@pi.to_config(:COMMAND, :BIG_ENDIAN)).to match(/ID_PARAMETER TEST 0 32 FLOAT 0 10 10.0/)
|
97
|
+
expect(@pi.to_config(:TELEMETRY, :BIG_ENDIAN)).to match(/ID_ITEM TEST 0 32 FLOAT 10.0/)
|
86
98
|
@pi.data_type = :STRING
|
87
99
|
@pi.id_value = "HI"
|
88
100
|
expect(@pi.id_value).to eql "HI"
|
101
|
+
expect(@pi.to_config(:COMMAND, :BIG_ENDIAN)).to match(/ID_PARAMETER TEST 0 32 STRING "HI"/)
|
102
|
+
expect(@pi.to_config(:TELEMETRY, :BIG_ENDIAN)).to match(/ID_ITEM TEST 0 32 STRING "HI"/)
|
103
|
+
@pi.id_value = "\xDE\xAD\xBE\xEF" # binary
|
104
|
+
expect(@pi.to_config(:COMMAND, :BIG_ENDIAN)).to match(/ID_PARAMETER TEST 0 32 STRING 0xDEADBEEF/)
|
105
|
+
expect(@pi.to_config(:TELEMETRY, :BIG_ENDIAN)).to match(/ID_ITEM TEST 0 32 STRING 0xDEADBEEF/)
|
89
106
|
end
|
90
107
|
|
91
108
|
it "sets the id_value to nil" do
|
@@ -105,6 +122,9 @@ module Cosmos
|
|
105
122
|
states = {"TRUE"=>1, "FALSE"=>0}
|
106
123
|
@pi.states = states
|
107
124
|
expect(@pi.states).to eql states
|
125
|
+
config = @pi.to_config(:TELEMETRY, :BIG_ENDIAN)
|
126
|
+
expect(config).to match(/STATE TRUE 1/)
|
127
|
+
expect(config).to match(/STATE FALSE 0/)
|
108
128
|
end
|
109
129
|
|
110
130
|
it "sets the states to nil" do
|
@@ -122,6 +142,7 @@ module Cosmos
|
|
122
142
|
description = "this is it"
|
123
143
|
@pi.description = description
|
124
144
|
expect(@pi.description).to eql description
|
145
|
+
expect(@pi.to_config(:TELEMETRY, :BIG_ENDIAN)).to match(/ITEM TEST 0 32 UINT "this is it"/)
|
125
146
|
end
|
126
147
|
|
127
148
|
it "sets the description to nil" do
|
@@ -156,6 +177,8 @@ module Cosmos
|
|
156
177
|
units = "V"
|
157
178
|
@pi.units = units
|
158
179
|
expect(@pi.units).to eql units
|
180
|
+
@pi.units_full = "Volts"
|
181
|
+
expect(@pi.to_config(:TELEMETRY, :BIG_ENDIAN)).to match(/UNITS Volts V/)
|
159
182
|
end
|
160
183
|
|
161
184
|
it "sets the units to nil" do
|
@@ -173,15 +196,25 @@ module Cosmos
|
|
173
196
|
pi = PacketItem.new("test", 0, 8, :INT, :BIG_ENDIAN, 16)
|
174
197
|
pi.default = [1, -1]
|
175
198
|
expect(pi.default).to eql [1, -1]
|
199
|
+
expect(pi.to_config(:COMMAND, :BIG_ENDIAN)).to match(/ARRAY_PARAMETER TEST 0 8 INT 16/)
|
200
|
+
expect(pi.to_config(:TELEMETRY, :BIG_ENDIAN)).to match(/ARRAY_ITEM TEST 0 8 INT 16/)
|
176
201
|
pi = PacketItem.new("test", 0, 32, :UINT, :BIG_ENDIAN, nil)
|
202
|
+
pi.range = (0..10)
|
177
203
|
pi.default = 0x01020304
|
178
204
|
expect(pi.default).to eql 0x01020304
|
205
|
+
expect(pi.to_config(:COMMAND, :BIG_ENDIAN)).to match(/PARAMETER TEST 0 32 UINT 0 10 16909060/)
|
179
206
|
pi = PacketItem.new("test", 0, 32, :FLOAT, :BIG_ENDIAN, nil)
|
207
|
+
pi.range = (-10..10)
|
180
208
|
pi.default = 5.5
|
181
209
|
expect(pi.default).to eql 5.5
|
210
|
+
expect(pi.to_config(:COMMAND, :BIG_ENDIAN)).to match(/PARAMETER TEST 0 32 FLOAT -10 10 5.5/)
|
182
211
|
pi = PacketItem.new("test", 0, 32, :STRING, :BIG_ENDIAN, nil)
|
183
212
|
pi.default = "HI"
|
184
213
|
expect(pi.default).to eql "HI"
|
214
|
+
expect(pi.to_config(:COMMAND, :BIG_ENDIAN)).to match(/PARAMETER TEST 0 32 STRING "HI"/)
|
215
|
+
pi = PacketItem.new("test", 0, 32, :STRING, :BIG_ENDIAN, nil)
|
216
|
+
pi.default = "\xDE\xAD\xBE\xEF"
|
217
|
+
expect(pi.to_config(:COMMAND, :BIG_ENDIAN)).to match(/PARAMETER TEST 0 32 STRING 0xDEADBEEF/)
|
185
218
|
end
|
186
219
|
|
187
220
|
it "sets the default to nil" do
|
@@ -269,6 +302,12 @@ module Cosmos
|
|
269
302
|
expect(@pi.hazardous).to eql hazardous
|
270
303
|
expect(@pi.hazardous["TRUE"]).to eql hazardous["TRUE"]
|
271
304
|
expect(@pi.hazardous["FALSE"]).to eql hazardous["FALSE"]
|
305
|
+
|
306
|
+
@pi.range = (0..1)
|
307
|
+
@pi.states = {"TRUE"=>1, "FALSE"=>0}
|
308
|
+
config = @pi.to_config(:COMMAND, :BIG_ENDIAN)
|
309
|
+
expect(config).to match(/STATE TRUE 1/)
|
310
|
+
expect(config).to match(/STATE FALSE 0 HAZARDOUS "NO FALSE ALLOWED"/)
|
272
311
|
end
|
273
312
|
|
274
313
|
it "sets hazardous to nil" do
|
@@ -286,6 +325,12 @@ module Cosmos
|
|
286
325
|
state_colors = {"TRUE"=>:GREEN, "FALSE"=>:RED}
|
287
326
|
@pi.state_colors = state_colors
|
288
327
|
expect(@pi.state_colors).to eql state_colors
|
328
|
+
|
329
|
+
@pi.range = (0..1)
|
330
|
+
@pi.states = {"TRUE"=>1, "FALSE"=>0}
|
331
|
+
config = @pi.to_config(:TELEMETRY, :BIG_ENDIAN)
|
332
|
+
expect(config).to match(/STATE TRUE 1 GREEN/)
|
333
|
+
expect(config).to match(/STATE FALSE 0 RED/)
|
289
334
|
end
|
290
335
|
|
291
336
|
it "sets the state_colors to nil" do
|
@@ -301,7 +346,16 @@ module Cosmos
|
|
301
346
|
describe "limits=" do
|
302
347
|
it "accepts limits as a PacketItemLimits" do
|
303
348
|
limits = PacketItemLimits.new
|
349
|
+
limits.values = {DEFAULT: [10, 20, 80, 90, 40, 50], TVAC: [100, 200, 800, 900]}
|
304
350
|
@pi.limits = limits
|
351
|
+
config = @pi.to_config(:TELEMETRY, :BIG_ENDIAN)
|
352
|
+
expect(config).to match(/LIMITS DEFAULT 1 DISABLED 10 20 80 90 40 50/)
|
353
|
+
expect(config).to match(/LIMITS TVAC 1 DISABLED 100 200 800 900/)
|
354
|
+
@pi.limits.enabled = true
|
355
|
+
@pi.limits.persistence_setting = 3
|
356
|
+
config = @pi.to_config(:TELEMETRY, :BIG_ENDIAN)
|
357
|
+
expect(config).to match(/LIMITS DEFAULT 3 ENABLED 10 20 80 90 40 50/)
|
358
|
+
expect(config).to match(/LIMITS TVAC 3 ENABLED 100 200 800 900/)
|
305
359
|
end
|
306
360
|
|
307
361
|
it "sets the limits to nil" do
|
@@ -314,10 +368,20 @@ module Cosmos
|
|
314
368
|
end
|
315
369
|
end
|
316
370
|
|
317
|
-
describe "meta" do
|
318
|
-
it "allows
|
319
|
-
@pi.meta
|
320
|
-
|
371
|
+
describe "meta=" do
|
372
|
+
it "only allows a hash" do
|
373
|
+
expect { @pi.meta = 1 }.to raise_error(ArgumentError, /must be a Hash/)
|
374
|
+
end
|
375
|
+
|
376
|
+
it "sets the meta hash" do
|
377
|
+
@pi.meta = { 'TYPE' => ['float32', 'uint8'], 'TEST' => ["test string"] }
|
378
|
+
expect(@pi.meta['TYPE']).to eql ['float32', 'uint8']
|
379
|
+
expect(@pi.meta['TEST']).to eql ["test string"]
|
380
|
+
config = @pi.to_config(:TELEMETRY, :BIG_ENDIAN)
|
381
|
+
expect(config).to match(/META TYPE float32 uint8/)
|
382
|
+
expect(config).to match(/META TEST "test string"/)
|
383
|
+
@pi.meta = nil # Clear the meta hash
|
384
|
+
expect(@pi.meta.empty?).to be true # Clearing it results in empty hash
|
321
385
|
end
|
322
386
|
end
|
323
387
|
|