nxt 0.3.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +45 -0
- data/lib/communication/bluetooth_communication.rb +85 -0
- data/lib/communication/serial_port_profile.rb +71 -0
- data/lib/nxt.rb +111 -20
- data/lib/ruby-nxt.sublime-project +8 -0
- data/lib/ruby-nxt.sublime-workspace +288 -0
- data/lib/telegrams/commands/direct/get_battery_level.rb +8 -0
- data/lib/telegrams/commands/direct/get_current_program_name.rb +8 -0
- data/lib/{nxt/commands/sound.rb → telegrams/commands/direct/get_input_values.rb} +0 -0
- data/lib/{nxt/commands/tone.rb → telegrams/commands/direct/keep_alive.rb} +0 -0
- data/lib/telegrams/commands/direct/ls_get_status.rb +0 -0
- data/lib/telegrams/commands/direct/ls_read.rb +0 -0
- data/lib/telegrams/commands/direct/ls_write.rb +0 -0
- data/lib/telegrams/commands/direct/message_read.rb +0 -0
- data/lib/telegrams/commands/direct/message_write.rb +0 -0
- data/lib/telegrams/commands/direct/output_state.rb +229 -0
- data/lib/telegrams/commands/direct/play_sound_file.rb +38 -0
- data/lib/telegrams/commands/direct/play_tone.rb +34 -0
- data/lib/telegrams/commands/direct/replies/get_battery_level_reply.rb +28 -0
- data/lib/telegrams/commands/direct/replies/get_current_program_name_reply.rb +30 -0
- data/lib/telegrams/commands/direct/replies/play_sound_file_reply.rb +13 -0
- data/lib/telegrams/commands/direct/replies/play_tone_reply.rb +14 -0
- data/lib/telegrams/commands/direct/replies/reset_motor_position_reply.rb +13 -0
- data/lib/telegrams/commands/direct/replies/set_input_mode_reply.rb +11 -0
- data/lib/telegrams/commands/direct/replies/set_output_state_reply.rb +11 -0
- data/lib/telegrams/commands/direct/replies/start_program_reply.rb +13 -0
- data/lib/telegrams/commands/direct/replies/stop_program_reply.rb +13 -0
- data/lib/telegrams/commands/direct/replies/stop_sound_playback_reply.rb +13 -0
- data/lib/telegrams/commands/direct/reset_input_scaled_value.rb +0 -0
- data/lib/telegrams/commands/direct/reset_motor_position.rb +8 -0
- data/lib/telegrams/commands/direct/set_input_mode.rb +101 -0
- data/lib/telegrams/commands/direct/set_output_state.rb +29 -0
- data/lib/telegrams/commands/direct/start_program.rb +30 -0
- data/lib/telegrams/commands/direct/stop_program.rb +9 -0
- data/lib/telegrams/commands/direct/stop_sound_playback.rb +8 -0
- data/lib/telegrams/commands/direct_command.rb +8 -0
- data/lib/telegrams/commands/direct_command_reply.rb +10 -0
- data/lib/telegrams/commands/message_translator.rb +46 -0
- data/lib/telegrams/commands/system/get_device_info.rb +8 -0
- data/lib/telegrams/commands/system/replies/get_device_info_reply.rb +41 -0
- data/lib/telegrams/commands/system_command.rb +8 -0
- data/lib/telegrams/messages/error.rb +0 -0
- data/lib/telegrams/messages/message.rb +0 -0
- data/lib/telegrams/messages/success.rb +0 -0
- data/lib/telegrams/no_message_reply.rb +10 -0
- data/lib/telegrams/reply.rb +82 -0
- data/lib/telegrams/respondable_telegram.rb +29 -0
- data/lib/telegrams/telegram.rb +14 -0
- data/spec/communication/bluetooth_communication_spec.rb +170 -0
- data/spec/communication/serial_port_profile_spec.rb +139 -0
- data/spec/helper.rb +1 -0
- data/spec/nxt_spec.rb +438 -0
- data/spec/telegrams/commands/direct/get_battery_level_spec.rb +26 -0
- data/spec/telegrams/commands/direct/get_current_program_name_spec.rb +26 -0
- data/spec/telegrams/commands/direct/output_state_spec.rb +198 -0
- data/spec/telegrams/commands/direct/play_sound_file_spec.rb +75 -0
- data/spec/telegrams/commands/direct/play_tone_spec.rb +63 -0
- data/spec/telegrams/commands/direct/replies/get_battery_level_reply_spec.rb +40 -0
- data/spec/telegrams/commands/direct/replies/get_current_program_name_reply_spec.rb +33 -0
- data/spec/telegrams/commands/direct/replies/play_sound_file_reply_spec.rb +13 -0
- data/spec/telegrams/commands/direct/replies/play_tone_reply_spec.rb +14 -0
- data/spec/telegrams/commands/direct/replies/reset_motor_position_reply_spec.rb +13 -0
- data/spec/telegrams/commands/direct/replies/set_input_mode_reply_spec.rb +12 -0
- data/spec/telegrams/commands/direct/replies/set_output_state_reply_spec.rb +12 -0
- data/spec/telegrams/commands/direct/replies/start_program_reply_spec.rb +12 -0
- data/spec/telegrams/commands/direct/replies/stop_program_reply_spec.rb +13 -0
- data/spec/telegrams/commands/direct/replies/stop_sound_playback_reply_spec.rb +13 -0
- data/spec/telegrams/commands/direct/reset_motor_position_spec.rb +31 -0
- data/spec/telegrams/commands/direct/set_input_mode_spec.rb +122 -0
- data/spec/telegrams/commands/direct/set_output_state_spec.rb +72 -0
- data/spec/telegrams/commands/direct/start_program_spec.rb +58 -0
- data/spec/telegrams/commands/direct/stop_program_spec.rb +34 -0
- data/spec/telegrams/commands/direct/stop_sound_playback_spec.rb +34 -0
- data/spec/telegrams/commands/direct_command_reply_spec.rb +7 -0
- data/spec/telegrams/commands/direct_command_spec.rb +34 -0
- data/spec/telegrams/commands/system/get_device_info_spec.rb +16 -0
- data/spec/telegrams/commands/system/replies/get_device_info_reply_spec.rb +63 -0
- data/spec/telegrams/commands/system_command_spec.rb +26 -0
- data/spec/telegrams/no_message_reply_spec.rb +12 -0
- data/spec/telegrams/reply_spec.rb +63 -0
- data/spec/telegrams/respondable_telegram_spec.rb +66 -0
- data/spec/telegrams/telegram_spec.rb +38 -0
- metadata +97 -116
- data/README.markdown +0 -52
- data/Rakefile +0 -35
- data/lib/nxt/commands/base.rb +0 -51
- data/lib/nxt/commands/input.rb +0 -60
- data/lib/nxt/commands/output.rb +0 -105
- data/lib/nxt/commands/program.rb +0 -70
- data/lib/nxt/connectors/base.rb +0 -35
- data/lib/nxt/connectors/input/color.rb +0 -30
- data/lib/nxt/connectors/input/touch.rb +0 -11
- data/lib/nxt/connectors/input/ultrasonic.rb +0 -11
- data/lib/nxt/connectors/output/motor.rb +0 -114
- data/lib/nxt/errors.rb +0 -25
- data/lib/nxt/exceptions.rb +0 -26
- data/lib/nxt/interfaces/base.rb +0 -36
- data/lib/nxt/interfaces/serial_port.rb +0 -88
- data/lib/nxt/interfaces/usb.rb +0 -8
- data/lib/nxt/nxt_brick.rb +0 -167
- data/lib/nxt/patches/module.rb +0 -22
- data/lib/nxt/patches/string.rb +0 -29
- data/lib/nxt/utils/accessors.rb +0 -24
- data/spec/matchers.rb +0 -7
- data/spec/nxt/connectors/output/motor_spec.rb +0 -55
- data/spec/nxt/interfaces/serial_port_spec.rb +0 -73
- data/spec/nxt/nxt_brick_spec.rb +0 -199
- data/spec/spec_helper.rb +0 -4
@@ -0,0 +1,26 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
require './lib/telegrams/commands/direct/get_battery_level'
|
3
|
+
|
4
|
+
describe GetBatteryLevel do
|
5
|
+
describe "when constructing the object" do
|
6
|
+
it "must not accept any parameters" do
|
7
|
+
-> { GetBatteryLevel.new false }.must_raise ArgumentError
|
8
|
+
end
|
9
|
+
|
10
|
+
it "must default to requiring a response since it is asking for one" do
|
11
|
+
GetBatteryLevel.new.require_response?.must_equal true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must have a command of 0x0B for getbatterylevel" do
|
15
|
+
GetBatteryLevel.new.command.must_equal 0x0B
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "as_bytes" do
|
20
|
+
it "must have the command as the second byte" do
|
21
|
+
command = GetBatteryLevel.new
|
22
|
+
command.as_bytes[1].must_equal command.command
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
|
3
|
+
require './lib/telegrams/commands/direct/get_current_program_name'
|
4
|
+
|
5
|
+
describe GetCurrentProgramName do
|
6
|
+
describe "when constructing the object" do
|
7
|
+
it "must not accept any parameters" do
|
8
|
+
-> { GetCurrentProgramName.new false }.must_raise ArgumentError
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must default to requiring a response since it is asking for one" do
|
12
|
+
GetCurrentProgramName.new.require_response?.must_equal true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "must have a command of 0x11 for getcurrentprogramname" do
|
16
|
+
GetCurrentProgramName.new.command.must_equal 0x11
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "as_bytes" do
|
21
|
+
it "must have the command as the second byte" do
|
22
|
+
command = GetCurrentProgramName.new
|
23
|
+
command.as_bytes[1].must_equal command.command
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
require './lib/telegrams/commands/direct/output_state'
|
3
|
+
|
4
|
+
describe OutputState do
|
5
|
+
# attr_reader :port, :power, :mode, :regulation_mode, :turn_ratio, :run_state, :tacho_limit
|
6
|
+
|
7
|
+
# this next group can only be read from a GetOutputState call:
|
8
|
+
# tacho_count # internal count; number of counts since last reset of the motor counter
|
9
|
+
# block_tacho_count # current position relative to last programmed movement
|
10
|
+
# rotation_count # current position relative to last reset of the rotation sensor for this motor
|
11
|
+
describe "when constructing the object" do
|
12
|
+
it "must accept hash contructor arguments with defaults of 0" do
|
13
|
+
state = OutputState.new({ :port => :a })
|
14
|
+
state.port.must_equal :a
|
15
|
+
state.mode_flags.must_equal 0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "when using the builder structure" do
|
20
|
+
before do
|
21
|
+
@state = OutputState.new
|
22
|
+
end
|
23
|
+
|
24
|
+
it "must accept a 'for_port(port_symbol) message that sets the value and returns the object itself" do
|
25
|
+
@state.for_port(:a).must_equal @state
|
26
|
+
@state.port.must_equal :a
|
27
|
+
end
|
28
|
+
|
29
|
+
it "must accept a 'with_power(power)' message that sets the value and returns the object itself" do
|
30
|
+
@state.with_power(100).must_equal @state
|
31
|
+
@state.power.must_equal 100
|
32
|
+
end
|
33
|
+
|
34
|
+
it "must accept a 'with_mode_flags(mode_flags)' that sets the value and returns the object itself" do
|
35
|
+
@state.with_mode_flags(OutputModeFlags.MOTORON | OutputModeFlags.REGULATED).must_equal @state
|
36
|
+
@state.mode_flags.must_equal OutputModeFlags.MOTORON | OutputModeFlags.REGULATED
|
37
|
+
end
|
38
|
+
|
39
|
+
it "must accept a 'with_regulation_mode(regulation_mode)' that sets the value and returns the object itself" do
|
40
|
+
@state.with_regulation_mode(:motor_speed).must_equal @state
|
41
|
+
@state.regulation_mode.must_equal :motor_speed
|
42
|
+
end
|
43
|
+
|
44
|
+
it "must accept a 'with_turn_ratio(turn_ratio)' message that sets the value and returns the object itself" do
|
45
|
+
@state.with_turn_ratio(100).must_equal @state
|
46
|
+
@state.turn_ratio.must_equal 100
|
47
|
+
end
|
48
|
+
|
49
|
+
it "must accept a 'with_run_state(run_state)' that sets the value and returns the object itself" do
|
50
|
+
@state.with_run_state(:ramp_up).must_equal @state
|
51
|
+
@state.run_state.must_equal :ramp_up
|
52
|
+
end
|
53
|
+
|
54
|
+
it "must accept a 'with_tacho_limit(tacho_limit)' that sets the value and returns the object itself" do
|
55
|
+
@state.with_tacho_limit(325).must_equal @state
|
56
|
+
@state.tacho_limit.must_equal 325
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "when using the setter methods" do
|
61
|
+
before do
|
62
|
+
@state = OutputState.new
|
63
|
+
end
|
64
|
+
|
65
|
+
it "must validate that the port is :a, :b, :c, or :all" do
|
66
|
+
@state.port = :a
|
67
|
+
@state.port = :b
|
68
|
+
@state.port = :c
|
69
|
+
@state.port = :all
|
70
|
+
-> { @state.port = :d }.must_raise ArgumentError
|
71
|
+
end
|
72
|
+
|
73
|
+
it "must set the port when it is set" do
|
74
|
+
@state.port = :b
|
75
|
+
@state.port.must_equal :b
|
76
|
+
end
|
77
|
+
|
78
|
+
it "must validate that the power is between -100 and 100" do
|
79
|
+
[-100, 0, 100].each do |power|
|
80
|
+
@state.power = power
|
81
|
+
@state.power.must_equal power
|
82
|
+
end
|
83
|
+
-> { @state.power = -101 }.must_raise ArgumentError
|
84
|
+
-> { @state.power = 101 }.must_raise ArgumentError
|
85
|
+
end
|
86
|
+
|
87
|
+
it "must vaidate that the mode_flags is a valid combination of 0 to all flags (0-7 as an integer)" do
|
88
|
+
(0..7).each do |mode|
|
89
|
+
@state.mode_flags = mode
|
90
|
+
@state.mode_flags.must_equal mode
|
91
|
+
end
|
92
|
+
|
93
|
+
-> { @state.mode_flags = 8 }.must_raise ArgumentError
|
94
|
+
end
|
95
|
+
|
96
|
+
it "must validate that the regulation_mode is one of the valid enumerations" do
|
97
|
+
[:idle, :motor_speed, :motor_sync].each do |regulation_mode|
|
98
|
+
@state.regulation_mode = regulation_mode
|
99
|
+
@state.regulation_mode.must_equal regulation_mode
|
100
|
+
end
|
101
|
+
|
102
|
+
-> { @state.regulation_mode = :garbage }.must_raise ArgumentError
|
103
|
+
-> { @state.regulation_mode = 1 }.must_raise ArgumentError
|
104
|
+
end
|
105
|
+
|
106
|
+
it "must validate that the turn_ratio is between -100 and 100" do
|
107
|
+
[-100, 0, 100].each do |turn_ratio|
|
108
|
+
@state.turn_ratio = turn_ratio
|
109
|
+
@state.turn_ratio.must_equal turn_ratio
|
110
|
+
end
|
111
|
+
-> { @state.turn_ratio = -101 }.must_raise ArgumentError
|
112
|
+
-> { @state.turn_ratio = 101 }.must_raise ArgumentError
|
113
|
+
end
|
114
|
+
|
115
|
+
it "must validate that the run_state is one of the valid enumerations" do
|
116
|
+
[:idle, :running, :ramp_up, :ramp_down].each do |run_state|
|
117
|
+
@state.run_state = run_state
|
118
|
+
@state.run_state.must_equal run_state
|
119
|
+
end
|
120
|
+
|
121
|
+
-> { @state.run_state = :garbage }.must_raise ArgumentError
|
122
|
+
-> { @state.run_state = 1 }.must_raise ArgumentError
|
123
|
+
end
|
124
|
+
|
125
|
+
it "must have a constant representing 'run forever' or 'unlimited'" do
|
126
|
+
OutputState.RUN_FOREVER.must_equal 0
|
127
|
+
end
|
128
|
+
|
129
|
+
it "must set the tacho_limit" do
|
130
|
+
@state.tacho_limit = 39123 # it's an unsigned long value, 4 bytes
|
131
|
+
@state.tacho_limit.must_equal 39123
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe OutputModeFlags do
|
137
|
+
it "must have MOTORON set to 0x01" do
|
138
|
+
OutputModeFlags.MOTORON.must_equal 0x01
|
139
|
+
end
|
140
|
+
|
141
|
+
it "must have BRAKE set to 0x02" do
|
142
|
+
OutputModeFlags.BRAKE.must_equal 0x02
|
143
|
+
end
|
144
|
+
|
145
|
+
it "must have REGULATED set to 0x04" do
|
146
|
+
OutputModeFlags.REGULATED.must_equal 0x04
|
147
|
+
end
|
148
|
+
|
149
|
+
it "must allow MOTORON and BRAKE to be combined into 0x03" do
|
150
|
+
(OutputModeFlags.MOTORON | OutputModeFlags.BRAKE).must_equal 0x03
|
151
|
+
end
|
152
|
+
|
153
|
+
it "must allow MOTORON and REGULATED to be combined into 0x05" do
|
154
|
+
(OutputModeFlags.MOTORON | OutputModeFlags.REGULATED).must_equal 0x05
|
155
|
+
end
|
156
|
+
|
157
|
+
it "must allow BRAKE and REGULATED to be combined into 0x06" do
|
158
|
+
(OutputModeFlags.BRAKE | OutputModeFlags.REGULATED).must_equal 0x06
|
159
|
+
end
|
160
|
+
|
161
|
+
it "must allow all three to be combined into 0x07" do
|
162
|
+
(OutputModeFlags.MOTORON | OutputModeFlags.BRAKE | OutputModeFlags.REGULATED).must_equal 0x07
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
describe RegulationMode do
|
168
|
+
it "must have IDLE defined as 0x00" do
|
169
|
+
RegulationMode.IDLE.must_equal 0x00
|
170
|
+
end
|
171
|
+
|
172
|
+
it "must have MOTOR_SPEED defined as 0x01" do
|
173
|
+
RegulationMode.MOTOR_SPEED.must_equal 0x01
|
174
|
+
end
|
175
|
+
|
176
|
+
it "must have MOTOR_SYNC defined as 0x02" do
|
177
|
+
RegulationMode.MOTOR_SYNC.must_equal 0x02
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
describe RunState do
|
183
|
+
it "must have IDLE defined as 0x00" do
|
184
|
+
RunState.IDLE.must_equal 0x00
|
185
|
+
end
|
186
|
+
|
187
|
+
it "must have RAMPUP defined as 0x10" do
|
188
|
+
RunState.RAMPUP.must_equal 0x10
|
189
|
+
end
|
190
|
+
|
191
|
+
it "must have RUNNING defined as 0x20" do
|
192
|
+
RunState.RUNNING.must_equal 0x20
|
193
|
+
end
|
194
|
+
|
195
|
+
it "must have RAMPDOWN defined as 0x40" do
|
196
|
+
RunState.RAMPDOWN.must_equal 0x40
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
|
3
|
+
require './lib/telegrams/commands/direct/play_sound_file'
|
4
|
+
|
5
|
+
|
6
|
+
describe PlaySoundFile do
|
7
|
+
describe "when creating the play sound file command" do
|
8
|
+
it "must default to requiring a response" do
|
9
|
+
PlaySoundFile.new('name').require_response?.must_equal true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "must set the require_response member to the value passed in" do
|
13
|
+
PlaySoundFile.new('name', true, false).require_response?.must_equal false
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must raise an ArgumentError when the filename is nil" do
|
17
|
+
-> { PlaySoundFile.new(nil) }.must_raise ArgumentError
|
18
|
+
end
|
19
|
+
|
20
|
+
it "must set the command value to 0x02 (startprogram)" do
|
21
|
+
PlaySoundFile.new('name').command.must_equal 0x02
|
22
|
+
end
|
23
|
+
|
24
|
+
it "must set the filename to the value passed in" do
|
25
|
+
PlaySoundFile.new('name.mp3').name.must_equal 'name.mp3'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "must default the loop_sound value to false" do
|
29
|
+
PlaySoundFile.new('name.mp3').loop_sound?.must_equal false
|
30
|
+
end
|
31
|
+
|
32
|
+
it "must set the loop_sound boolean to the value passed in" do
|
33
|
+
PlaySoundFile.new('name.mp3', true).loop_sound?.must_equal true
|
34
|
+
end
|
35
|
+
|
36
|
+
it "must set the loop_sound? value to false unless explicitely set to true" do
|
37
|
+
PlaySoundFile.new('name.mp3', "bizbuzz").loop_sound?.must_equal false
|
38
|
+
end
|
39
|
+
|
40
|
+
it "must try adding '.rso' to the end of the filename if there is no file extension" do
|
41
|
+
name = 'sound'
|
42
|
+
PlaySoundFile.new(name).name.must_equal "#{name}.rso"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "must leave the filename alone if there is a 3 letter extension of any kind" do
|
46
|
+
name = 'sound.foo'
|
47
|
+
PlaySoundFile.new(name).name.must_equal name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "when rendering the command using as_bytes" do
|
52
|
+
it "must have the command value as the second byte" do
|
53
|
+
command = PlaySoundFile.new('name')
|
54
|
+
command.as_bytes[1].must_equal command.command
|
55
|
+
end
|
56
|
+
|
57
|
+
it "must have the loop_sound value as the third byte" do
|
58
|
+
PlaySoundFile.new('name.mp3', false).as_bytes[2].must_equal 0x00
|
59
|
+
PlaySoundFile.new('name.mp3', true).as_bytes[2].must_equal 0xff
|
60
|
+
end
|
61
|
+
|
62
|
+
it "must have the program name in ASCIIZ (null terminated ascii) for bytes 4-23" do
|
63
|
+
name = 'sound.mp3'
|
64
|
+
name_as_asciiz = [115, 111, 117, 110, 100, 46, 109, 112, 51, 0,
|
65
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
66
|
+
|
67
|
+
command = PlaySoundFile.new(name)
|
68
|
+
bytes = command.as_bytes
|
69
|
+
name_bytes = bytes.slice(3, 20)
|
70
|
+
|
71
|
+
name_bytes.must_equal name_as_asciiz
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
require './lib/telegrams/commands/direct/play_tone'
|
3
|
+
|
4
|
+
describe PlayTone do
|
5
|
+
describe "when constructing the command" do
|
6
|
+
before do
|
7
|
+
@command = PlayTone.new(200, 100)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "must be a direct command" do
|
11
|
+
@command.type.must_equal DirectCommand.new.type
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must have a command of 0x03" do
|
15
|
+
@command.command.must_equal 0x03
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must require a response by default" do
|
19
|
+
@command.require_response?.must_equal true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "must throw an ArgumentException if the frequency is not passed in" do
|
23
|
+
-> { PlayTone.new }.must_raise ArgumentError
|
24
|
+
end
|
25
|
+
|
26
|
+
it "must throw an ArgumentException if the duration is not passed in" do
|
27
|
+
-> { PlayTone.new(500) }.must_raise ArgumentError
|
28
|
+
end
|
29
|
+
|
30
|
+
it "must set the frequency to what is passed in" do
|
31
|
+
PlayTone.new(500, 100).frequency.must_equal 500
|
32
|
+
end
|
33
|
+
|
34
|
+
it "must set the duration to what is passed in" do
|
35
|
+
PlayTone.new(500, 100).duration.must_equal 100
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must validate that the frequency (in Hz) is between 200 and 14000 Hz (the valid range)" do
|
39
|
+
-> { PlayTone.new(199, 100) }.must_raise ArgumentError
|
40
|
+
-> { PlayTone.new(14001, 100) }.must_raise ArgumentError
|
41
|
+
end
|
42
|
+
|
43
|
+
it "must validate that the duration (in ms) is positive or zero" do
|
44
|
+
-> { PlayTone.new(500, -1) }.must_raise ArgumentError
|
45
|
+
PlayTone.new(500, 0)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "when rendering the command as bytes" do
|
50
|
+
it "must set byte 1 to 0x03 as the playtone command" do
|
51
|
+
PlayTone.new(500, 1).as_bytes[1].must_equal 0x03
|
52
|
+
end
|
53
|
+
|
54
|
+
it "must set bytes 2-3 to a UWORD of the frequency to play in reverse order" do
|
55
|
+
PlayTone.new(500, 1).as_bytes[2..3].must_equal [0xf4, 0x01]
|
56
|
+
end
|
57
|
+
|
58
|
+
it "must set bytes 4-5 to a UWORD of the duration to play the tone" do
|
59
|
+
PlayTone.new(500, 2000).as_bytes[4..5].must_equal [0xd0, 0x07]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
require './lib/telegrams/commands/direct/replies/get_battery_level_reply'
|
3
|
+
|
4
|
+
describe GetBatteryLevelReply do
|
5
|
+
describe "when creating the reply" do
|
6
|
+
before do
|
7
|
+
@millivolts = 4100
|
8
|
+
|
9
|
+
# null pad out to max length and convert to ASCIIZ bytes
|
10
|
+
@millivolts_bytes = [@millivolts.to_s(16).rjust(4, "0")].pack("H*").bytes.to_a.reverse
|
11
|
+
@reply_bytes = [2, 0x0B, 0].concat(@millivolts_bytes)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must parse the millivolts into the message member" do
|
15
|
+
reply = GetBatteryLevelReply.new(@reply_bytes)
|
16
|
+
|
17
|
+
reply.message.must_equal @millivolts
|
18
|
+
end
|
19
|
+
|
20
|
+
it "must allow access to the message through the millivolts member" do
|
21
|
+
reply = GetBatteryLevelReply.new(@reply_bytes)
|
22
|
+
|
23
|
+
reply.millivolts.must_equal @millivolts
|
24
|
+
end
|
25
|
+
|
26
|
+
it "must convert the millivolts to volts through the volts member" do
|
27
|
+
reply = GetBatteryLevelReply.new(@reply_bytes)
|
28
|
+
|
29
|
+
reply.volts.must_equal @millivolts/1000.0
|
30
|
+
end
|
31
|
+
|
32
|
+
it "must raise an ArgumentError if the reply is not for GetBatteryLevel" do
|
33
|
+
reply_bytes = [2, 0x01, 0].concat(@millivolts_bytes)
|
34
|
+
|
35
|
+
-> { reply = GetBatteryLevelReply.new(reply_bytes) }.must_raise ArgumentError
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
require './lib/telegrams/commands/direct/replies/get_current_program_name_reply'
|
3
|
+
|
4
|
+
describe GetCurrentProgramNameReply do
|
5
|
+
describe "when creating the reply" do
|
6
|
+
before do
|
7
|
+
@filename = "foobar.rxe"
|
8
|
+
|
9
|
+
# null pad out to max length and convert to ASCIIZ bytes
|
10
|
+
@filename_bytes = @filename.ljust(20, "\0").unpack('C*')
|
11
|
+
@reply_bytes = [2, 0x11, 0].concat(@filename_bytes)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must parse the filename into the message member" do
|
15
|
+
reply = GetCurrentProgramNameReply.new(@reply_bytes)
|
16
|
+
|
17
|
+
reply.message.must_equal @filename
|
18
|
+
end
|
19
|
+
|
20
|
+
it "must allow access to the message through the program_name member" do
|
21
|
+
reply = GetCurrentProgramNameReply.new(@reply_bytes)
|
22
|
+
|
23
|
+
reply.program_name.must_equal @filename
|
24
|
+
end
|
25
|
+
|
26
|
+
it "must raise an ArgumentError if the reply is not for GetCurrentProgramName" do
|
27
|
+
reply_bytes = [2, 0x01, 0].concat(@filename_bytes)
|
28
|
+
|
29
|
+
-> { reply = GetCurrentProgramNameReply.new(reply_bytes) }.must_raise ArgumentError
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|