libastag 0.0.1 → 0.0.2
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.
- data/BUGS +10 -0
- data/CHANGES +8 -1
- data/MIT-LICENSE +2 -1
- data/README +7 -3
- data/Rakefile +3 -2
- data/TODO +4 -7
- data/doc/classes/Helpers.html +16 -20
- data/doc/classes/Helpers/REXML.html +4 -4
- data/doc/classes/Helpers/REXML/Attributes.html +10 -10
- data/doc/classes/Libastag.html +5 -5
- data/doc/classes/Libastag/Rabbit.html +56 -56
- data/doc/classes/Libastag/RabitEar.html +4 -4
- data/doc/classes/Libastag/RabitLed.html +4 -4
- data/doc/classes/Request.html +33 -37
- data/doc/classes/Request/Action.html +34 -34
- data/doc/classes/Request/AudioStream.html +313 -0
- data/doc/classes/Request/Base.html +13 -10
- data/doc/classes/Request/Base/Event.html +58 -23
- data/doc/classes/Request/Base/EventCollection.html +35 -32
- data/doc/classes/Request/Choregraphy.html +500 -0
- data/doc/classes/Request/Choregraphy/BadChorDesc.html +135 -0
- data/doc/classes/Request/Choregraphy/Ears.html +130 -0
- data/doc/classes/Request/Choregraphy/Ears/Directions.html +141 -0
- data/doc/classes/Request/Choregraphy/Ears/Positions.html +146 -0
- data/doc/classes/Request/Choregraphy/Leds.html +130 -0
- data/doc/classes/Request/Choregraphy/Leds/Colors.html +171 -0
- data/doc/classes/Request/Choregraphy/Leds/Positions.html +161 -0
- data/doc/classes/Request/GET_EARS_POSITION.html +17 -14
- data/doc/classes/Request/IdMessage.html +234 -0
- data/doc/classes/Request/Query.html +80 -55
- data/doc/classes/Request/SetEarsPosition.html +58 -36
- data/doc/classes/Request/TtsMessage.html +74 -50
- data/doc/classes/Response.html +55 -124
- data/doc/classes/Response/AbuseSending.html +34 -34
- data/doc/classes/Response/Base.html +34 -34
- data/doc/classes/Response/Base/BadServerRsp.html +34 -34
- data/doc/classes/Response/Base/GoodServerRsp.html +34 -34
- data/doc/classes/Response/Base/ServerRsp.html +53 -53
- data/doc/classes/Response/Blacklist.html +34 -34
- data/doc/classes/Response/ChorNotSend.html +34 -34
- data/doc/classes/Response/ChorSend.html +34 -34
- data/doc/classes/Response/CommandSend.html +34 -34
- data/doc/classes/Response/EarPositionNotSend.html +34 -34
- data/doc/classes/Response/EarPositionSend.html +34 -34
- data/doc/classes/Response/EmptyServerRsp.html +34 -34
- data/doc/classes/Response/LangListUser.html +34 -34
- data/doc/classes/Response/LinkPreview.html +34 -34
- data/doc/classes/Response/ListFriend.html +34 -34
- data/doc/classes/Response/ListReceivedMsg.html +34 -34
- data/doc/classes/Response/MessageNotSend.html +34 -34
- data/doc/classes/Response/MessageSend.html +34 -34
- data/doc/classes/Response/NabCastNotSend.html +34 -34
- data/doc/classes/Response/NabCastSend.html +34 -34
- data/doc/classes/Response/NoCorrectParameters.html +34 -34
- data/doc/classes/Response/NoGoodTokenOrSerial.html +34 -34
- data/doc/classes/Response/NotV2Rabbit.html +34 -34
- data/doc/classes/Response/PositionEar.html +34 -34
- data/doc/classes/Response/ProtocolExcepion.html +35 -35
- data/doc/classes/Response/RabbitName.html +34 -34
- data/doc/classes/Response/RabbitSleep.html +34 -34
- data/doc/classes/Response/RabbitVersion.html +34 -34
- data/doc/classes/Response/Signature.html +34 -34
- data/doc/classes/Response/Timezone.html +34 -34
- data/doc/classes/Response/TtsNotSend.html +34 -34
- data/doc/classes/Response/TtsSend.html +34 -34
- data/doc/classes/Response/VoiceListTts.html +34 -34
- data/doc/classes/Response/WebRadioNotSend.html +34 -34
- data/doc/classes/Response/WebRadioSend.html +34 -34
- data/doc/created.rid +1 -1
- data/doc/dot/f_0.png +0 -0
- data/doc/dot/f_5.dot +13 -445
- data/doc/dot/f_5.png +0 -0
- data/doc/dot/f_6.dot +445 -11
- data/doc/dot/f_6.png +0 -0
- data/doc/dot/f_7.dot +30 -5
- data/doc/dot/f_7.png +0 -0
- data/doc/dot/f_8.dot +39 -0
- data/doc/dot/f_8.png +0 -0
- data/doc/files/{lib/violet/violetapi_rb.html → BUGS.html} +17 -9
- data/doc/files/CHANGES.html +15 -2
- data/doc/files/MIT-LICENSE.html +2 -2
- data/doc/files/README.html +13 -3
- data/doc/files/TODO.html +5 -8
- data/doc/files/lib/libastag_rb.html +12 -10
- data/doc/files/lib/violet/helpers_rb.html +5 -5
- data/doc/files/lib/violet/request_rb.html +16 -12
- data/doc/files/lib/violet/response_rb.html +36 -35
- data/doc/fr_class_index.html +10 -1
- data/doc/fr_file_index.html +1 -1
- data/doc/fr_method_index.html +25 -12
- data/examples/morse.rb +72 -0
- data/lib/libastag.rb +6 -2
- data/lib/violet/helpers.rb +4 -2
- data/lib/violet/request.rb +501 -47
- data/lib/violet/response.rb +5 -2
- data/test/fake_violet_srv.rb +1 -1
- data/test/test_helpers.rb +3 -5
- data/test/{test_send.rb → test_query_and_actions.rb} +27 -10
- data/test/test_request_base.rb +76 -0
- data/test/test_request_chor.rb +162 -0
- data/test/test_request_stuff.rb +171 -0
- data/test/test_response.rb +3 -4
- metadata +45 -20
- data/doc/classes/VioletAPI.html +0 -118
- data/doc/dot/f_4.dot +0 -57
- data/doc/dot/f_4.png +0 -0
- data/lib/violet/violetapi.rb +0 -14
- data/test/test_request.rb +0 -20
data/doc/fr_class_index.html
CHANGED
|
@@ -29,10 +29,20 @@
|
|
|
29
29
|
<a href="classes/Libastag/RabitLed.html">Libastag::RabitLed</a><br />
|
|
30
30
|
<a href="classes/Request.html">Request</a><br />
|
|
31
31
|
<a href="classes/Request/Action.html">Request::Action</a><br />
|
|
32
|
+
<a href="classes/Request/AudioStream.html">Request::AudioStream</a><br />
|
|
32
33
|
<a href="classes/Request/Base.html">Request::Base</a><br />
|
|
33
34
|
<a href="classes/Request/Base/Event.html">Request::Base::Event</a><br />
|
|
34
35
|
<a href="classes/Request/Base/EventCollection.html">Request::Base::EventCollection</a><br />
|
|
36
|
+
<a href="classes/Request/Choregraphy.html">Request::Choregraphy</a><br />
|
|
37
|
+
<a href="classes/Request/Choregraphy/BadChorDesc.html">Request::Choregraphy::BadChorDesc</a><br />
|
|
38
|
+
<a href="classes/Request/Choregraphy/Ears.html">Request::Choregraphy::Ears</a><br />
|
|
39
|
+
<a href="classes/Request/Choregraphy/Ears/Directions.html">Request::Choregraphy::Ears::Directions</a><br />
|
|
40
|
+
<a href="classes/Request/Choregraphy/Ears/Positions.html">Request::Choregraphy::Ears::Positions</a><br />
|
|
41
|
+
<a href="classes/Request/Choregraphy/Leds.html">Request::Choregraphy::Leds</a><br />
|
|
42
|
+
<a href="classes/Request/Choregraphy/Leds/Colors.html">Request::Choregraphy::Leds::Colors</a><br />
|
|
43
|
+
<a href="classes/Request/Choregraphy/Leds/Positions.html">Request::Choregraphy::Leds::Positions</a><br />
|
|
35
44
|
<a href="classes/Request/GET_EARS_POSITION.html">Request::GET_EARS_POSITION</a><br />
|
|
45
|
+
<a href="classes/Request/IdMessage.html">Request::IdMessage</a><br />
|
|
36
46
|
<a href="classes/Request/Query.html">Request::Query</a><br />
|
|
37
47
|
<a href="classes/Request/SetEarsPosition.html">Request::SetEarsPosition</a><br />
|
|
38
48
|
<a href="classes/Request/TtsMessage.html">Request::TtsMessage</a><br />
|
|
@@ -72,7 +82,6 @@
|
|
|
72
82
|
<a href="classes/Response/VoiceListTts.html">Response::VoiceListTts</a><br />
|
|
73
83
|
<a href="classes/Response/WebRadioNotSend.html">Response::WebRadioNotSend</a><br />
|
|
74
84
|
<a href="classes/Response/WebRadioSend.html">Response::WebRadioSend</a><br />
|
|
75
|
-
<a href="classes/VioletAPI.html">VioletAPI</a><br />
|
|
76
85
|
</div>
|
|
77
86
|
</div>
|
|
78
87
|
</body>
|
data/doc/fr_file_index.html
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
<div id="index">
|
|
21
21
|
<h1 class="section-bar">Files</h1>
|
|
22
22
|
<div id="index-entries">
|
|
23
|
+
<a href="files/BUGS.html">BUGS</a><br />
|
|
23
24
|
<a href="files/CHANGES.html">CHANGES</a><br />
|
|
24
25
|
<a href="files/MIT-LICENSE.html">MIT-LICENSE</a><br />
|
|
25
26
|
<a href="files/README.html">README</a><br />
|
|
@@ -28,7 +29,6 @@
|
|
|
28
29
|
<a href="files/lib/violet/helpers_rb.html">lib/violet/helpers.rb</a><br />
|
|
29
30
|
<a href="files/lib/violet/request_rb.html">lib/violet/request.rb</a><br />
|
|
30
31
|
<a href="files/lib/violet/response_rb.html">lib/violet/response.rb</a><br />
|
|
31
|
-
<a href="files/lib/violet/violetapi_rb.html">lib/violet/violetapi.rb</a><br />
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
34
|
</body>
|
data/doc/fr_method_index.html
CHANGED
|
@@ -20,34 +20,47 @@
|
|
|
20
20
|
<div id="index">
|
|
21
21
|
<h1 class="section-bar">Methods</h1>
|
|
22
22
|
<div id="index-entries">
|
|
23
|
+
<a href="classes/Request/AudioStream.html#M000027">+ (Request::AudioStream)</a><br />
|
|
23
24
|
<a href="classes/Request/Base/Event.html#M000020">+ (Request::Base::Event)</a><br />
|
|
25
|
+
<a href="classes/Request/AudioStream.html#M000028">== (Request::AudioStream)</a><br />
|
|
26
|
+
<a href="classes/Request/Choregraphy.html#M000032">== (Request::Choregraphy)</a><br />
|
|
24
27
|
<a href="classes/Libastag/Rabbit.html#M000010">asleep? (Libastag::Rabbit)</a><br />
|
|
25
28
|
<a href="classes/Libastag/Rabbit.html#M000012">awake? (Libastag::Rabbit)</a><br />
|
|
26
29
|
<a href="classes/Response/Base/ServerRsp.html#M000006">bad? (Response::Base::ServerRsp)</a><br />
|
|
30
|
+
<a href="classes/Request/Choregraphy.html#M000031">bubble (Request::Choregraphy)</a><br />
|
|
27
31
|
<a href="classes/Helpers.html#M000001">constantize (Helpers)</a><br />
|
|
28
32
|
<a href="classes/Request/Base/EventCollection.html#M000017">each (Request::Base::EventCollection)</a><br />
|
|
29
33
|
<a href="classes/Response/Base/ServerRsp.html#M000007">get_all (Response::Base::ServerRsp)</a><br />
|
|
30
34
|
<a href="classes/Response/Base/ServerRsp.html#M000005">good? (Response::Base::ServerRsp)</a><br />
|
|
35
|
+
<a href="classes/Request/Choregraphy.html#M000034">move (Request::Choregraphy)</a><br />
|
|
31
36
|
<a href="classes/Libastag/Rabbit.html#M000009">name (Libastag::Rabbit)</a><br />
|
|
37
|
+
<a href="classes/Request/AudioStream.html#M000025">new (Request::AudioStream)</a><br />
|
|
38
|
+
<a href="classes/Request/Base/EventCollection.html#M000016">new (Request::Base::EventCollection)</a><br />
|
|
39
|
+
<a href="classes/Request/TtsMessage.html#M000038">new (Request::TtsMessage)</a><br />
|
|
40
|
+
<a href="classes/Request/Query.html#M000035">new (Request::Query)</a><br />
|
|
41
|
+
<a href="classes/Request/Base/Event.html#M000019">new (Request::Base::Event)</a><br />
|
|
32
42
|
<a href="classes/Response/Base/ServerRsp.html#M000004">new (Response::Base::ServerRsp)</a><br />
|
|
33
|
-
<a href="classes/Request/Query.html#M000024">new (Request::Query)</a><br />
|
|
34
43
|
<a href="classes/Libastag/Rabbit.html#M000008">new (Libastag::Rabbit)</a><br />
|
|
35
|
-
<a href="classes/Request/
|
|
36
|
-
<a href="classes/Request/
|
|
37
|
-
<a href="classes/Request/
|
|
38
|
-
<a href="classes/Request/
|
|
39
|
-
<a href="classes/Request/Base/EventCollection.html#M000016">new (Request::Base::EventCollection)</a><br />
|
|
44
|
+
<a href="classes/Request/SetEarsPosition.html#M000042">new (Request::SetEarsPosition)</a><br />
|
|
45
|
+
<a href="classes/Request/Action.html#M000023">new (Request::Action)</a><br />
|
|
46
|
+
<a href="classes/Request/IdMessage.html#M000040">new (Request::IdMessage)</a><br />
|
|
47
|
+
<a href="classes/Request/Choregraphy.html#M000029">new (Request::Choregraphy)</a><br />
|
|
40
48
|
<a href="classes/Response.html#M000003">parse (Response)</a><br />
|
|
41
|
-
<a href="classes/Request/Query.html#
|
|
49
|
+
<a href="classes/Request/Query.html#M000037">send! (Request::Query)</a><br />
|
|
50
|
+
<a href="classes/Request/Choregraphy.html#M000033">set (Request::Choregraphy)</a><br />
|
|
42
51
|
<a href="classes/Libastag/Rabbit.html#M000011">sleep! (Libastag::Rabbit)</a><br />
|
|
52
|
+
<a href="classes/Request/Base/Event.html#M000022">streamed? (Request::Base::Event)</a><br />
|
|
43
53
|
<a href="classes/Helpers/REXML/Attributes.html#M000002">to_hash (Helpers::REXML::Attributes)</a><br />
|
|
54
|
+
<a href="classes/Request/Query.html#M000036">to_url (Request::Query)</a><br />
|
|
55
|
+
<a href="classes/Request/Action.html#M000024">to_url (Request::Action)</a><br />
|
|
56
|
+
<a href="classes/Request/Base/Event.html#M000021">to_url (Request::Base::Event)</a><br />
|
|
44
57
|
<a href="classes/Request/Base/EventCollection.html#M000018">to_url (Request::Base::EventCollection)</a><br />
|
|
45
|
-
<a href="classes/Request/
|
|
58
|
+
<a href="classes/Request/AudioStream.html#M000026">to_url (Request::AudioStream)</a><br />
|
|
59
|
+
<a href="classes/Request/IdMessage.html#M000041">to_url (Request::IdMessage)</a><br />
|
|
60
|
+
<a href="classes/Request/SetEarsPosition.html#M000043">to_url (Request::SetEarsPosition)</a><br />
|
|
61
|
+
<a href="classes/Request/TtsMessage.html#M000039">to_url (Request::TtsMessage)</a><br />
|
|
62
|
+
<a href="classes/Request/Choregraphy.html#M000030">to_url (Request::Choregraphy)</a><br />
|
|
46
63
|
<a href="classes/Request/GET_EARS_POSITION.html#M000015">to_url (Request::GET_EARS_POSITION)</a><br />
|
|
47
|
-
<a href="classes/Request/Query.html#M000025">to_url (Request::Query)</a><br />
|
|
48
|
-
<a href="classes/Request/Base/Event.html#M000021">to_url (Request::Base::Event)</a><br />
|
|
49
|
-
<a href="classes/Request/TtsMessage.html#M000028">to_url (Request::TtsMessage)</a><br />
|
|
50
|
-
<a href="classes/Request/SetEarsPosition.html#M000030">to_url (Request::SetEarsPosition)</a><br />
|
|
51
64
|
<a href="classes/Libastag/Rabbit.html#M000014">version (Libastag::Rabbit)</a><br />
|
|
52
65
|
<a href="classes/Libastag/Rabbit.html#M000013">wakeup! (Libastag::Rabbit)</a><br />
|
|
53
66
|
</div>
|
data/examples/morse.rb
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require File.join( File.dirname(__FILE__), '..', 'lib', 'violet', 'request.rb' )
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class String
|
|
7
|
+
|
|
8
|
+
MORSE_TABLE = {'a'=> %|.-|,'b'=> %|-...|,'c'=> %|-.-.|,'d'=> %|-..|,'e'=> %|.|,'f'=> %|..-.|,'g'=> %|--.|,'h'=> %|....|,'i'=> %|..|,'j'=> %|.---|,'k'=> %|-.-|,'l'=> %|.-..|,'m'=> %|--|,'n'=> %|-.|,'o'=> %|---|,'p'=> %|.--.|,'q'=> %|--.-|,'r'=> %|.-.|,'s'=> %|...|,'t'=> %|-|,'u'=> %|..-|,'v'=> %|...-|,'w'=> %|.--|,'x'=> %|-..-|,'y'=> %|-.--|,'z'=> %|--..|,'0'=> %|-----|,'1'=> %|.----|,'2'=> %|..---|,'3'=> %|...--|,'4'=> %|....-|,'5'=> %|.....|,'6'=> %|-....|,'7'=> %|--...|,'8'=> %|---..|,'9'=> %|----.| }
|
|
9
|
+
|
|
10
|
+
# "translate" a String into Morse code
|
|
11
|
+
def to_morse
|
|
12
|
+
self.downcase.scan(/./).collect do |c|
|
|
13
|
+
MORSE_TABLE[c]
|
|
14
|
+
end.join
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# time in sec of a dot .
|
|
20
|
+
DOT_TIME = 0.1
|
|
21
|
+
# time in sec of a dash - (usually 3*DOT_TIME)
|
|
22
|
+
DASH_TIME = 3 * DOT_TIME
|
|
23
|
+
# time in sec of space between morses . or -
|
|
24
|
+
SPACE_TIME = DOT_TIME
|
|
25
|
+
|
|
26
|
+
# asking user
|
|
27
|
+
def ask question
|
|
28
|
+
print question
|
|
29
|
+
gets.chomp
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def debug
|
|
34
|
+
yield if $DEBUG
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# get user's name and convert it in morse code
|
|
38
|
+
morse = ask("what's your name ? ").to_morse
|
|
39
|
+
# get naba's infos
|
|
40
|
+
|
|
41
|
+
infos = ask('token: '), ask('serial: ')
|
|
42
|
+
|
|
43
|
+
c = Request::Choregraphy.new do
|
|
44
|
+
# initialize the timer
|
|
45
|
+
timer = 0
|
|
46
|
+
|
|
47
|
+
# each dot or dash
|
|
48
|
+
morse.scan(/./).each do |m|
|
|
49
|
+
# choose the good duration time
|
|
50
|
+
time_to_display = if m == '.' then DOT_TIME else DASH_TIME end
|
|
51
|
+
# choose colors at random :)
|
|
52
|
+
random_colors = [rand(255), rand(255), rand(255)]
|
|
53
|
+
|
|
54
|
+
at time timer
|
|
55
|
+
set top led to random_colors
|
|
56
|
+
|
|
57
|
+
at time (timer + time_to_display)
|
|
58
|
+
set top led off
|
|
59
|
+
|
|
60
|
+
timer = timer + time_to_display + SPACE_TIME
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
q = Request::Query.new :token => infos.first,
|
|
65
|
+
:serial => infos.last,
|
|
66
|
+
:event => c
|
|
67
|
+
|
|
68
|
+
debug { puts q.inspect }
|
|
69
|
+
rsp = q.send!
|
|
70
|
+
debug { puts rsp }
|
|
71
|
+
|
|
72
|
+
puts (rsp.good? ? 'OK ! sended !' : 'Woaw. arg.')
|
data/lib/libastag.rb
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
|
|
2
|
+
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) or $:.include?(File.expand_path(File.dirname(__FILE__)))
|
|
3
|
+
|
|
4
|
+
|
|
2
5
|
|
|
3
6
|
# Handy class/methods to control a Nabastag.
|
|
4
7
|
module Libastag
|
|
5
|
-
VERSION = '0.0.
|
|
8
|
+
VERSION = '0.0.2'
|
|
6
9
|
|
|
7
|
-
require
|
|
10
|
+
require 'violet/response.rb'
|
|
11
|
+
require 'violet/request.rb'
|
|
8
12
|
|
|
9
13
|
# this class store all attribute of a Nabaztag.
|
|
10
14
|
# it receive events and retrieve information
|
data/lib/violet/helpers.rb
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
some handy class/methods and modifications.
|
|
4
4
|
=end
|
|
5
5
|
|
|
6
|
+
require 'rexml/document'
|
|
7
|
+
|
|
6
8
|
module Helpers
|
|
7
|
-
require 'rexml/document'
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
# REXML::Attributes#to_hash seems to be broken.
|
|
@@ -23,7 +24,8 @@ module Helpers
|
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
# ==Credits
|
|
26
|
-
#
|
|
27
|
+
# Copyright (c) 2005 David Heinemeier Hansson
|
|
28
|
+
# taken from active_support/inflector.rb (MIT licence)
|
|
27
29
|
# see http://rubyforge.org/projects/activesupport
|
|
28
30
|
#
|
|
29
31
|
#
|
data/lib/violet/request.rb
CHANGED
|
@@ -6,8 +6,13 @@ but other Event derivated class are used to create objects.
|
|
|
6
6
|
|
|
7
7
|
=end
|
|
8
8
|
|
|
9
|
+
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) or $:.include?(File.expand_path(File.dirname(__FILE__)))
|
|
10
|
+
|
|
11
|
+
require 'response.rb'
|
|
12
|
+
require 'helpers.rb'
|
|
13
|
+
|
|
14
|
+
|
|
9
15
|
module Request
|
|
10
|
-
require File.join( File.dirname(__FILE__), 'response.rb' )
|
|
11
16
|
|
|
12
17
|
# the VioletAPI url where we send request.
|
|
13
18
|
API_URL = 'http://api.nabaztag.com/vl/FR/api.jsp'
|
|
@@ -27,8 +32,10 @@ module Request
|
|
|
27
32
|
raise NotImplementedError
|
|
28
33
|
end
|
|
29
34
|
|
|
30
|
-
# it's possible to send multiples events on a single request.
|
|
35
|
+
# it's possible to send multiples events on a single request. this method return a new EventCollection object,
|
|
36
|
+
# that cotains +self+ and +other+.
|
|
31
37
|
def + other
|
|
38
|
+
raise ArgumentError.new("#{other.inspect} is a Streamed Event") if other.streamed?
|
|
32
39
|
EventCollection.new self, other
|
|
33
40
|
end
|
|
34
41
|
|
|
@@ -36,6 +43,11 @@ module Request
|
|
|
36
43
|
def to_url
|
|
37
44
|
raise NotImplementedError
|
|
38
45
|
end
|
|
46
|
+
|
|
47
|
+
# return +true+ if self is a Stream Event (that use APISTREAM_URL instead of API_URL), +false+ otherwise.
|
|
48
|
+
def streamed?
|
|
49
|
+
self.class.to_s =~ /Stream$/
|
|
50
|
+
end
|
|
39
51
|
end
|
|
40
52
|
|
|
41
53
|
|
|
@@ -66,7 +78,7 @@ module Request
|
|
|
66
78
|
|
|
67
79
|
# override Event#to_url.
|
|
68
80
|
def to_url
|
|
69
|
-
@childrens.collect { |e| e.to_url }.
|
|
81
|
+
@childrens.collect { |e| e.to_url }.flatten
|
|
70
82
|
end
|
|
71
83
|
end
|
|
72
84
|
|
|
@@ -74,16 +86,20 @@ module Request
|
|
|
74
86
|
|
|
75
87
|
|
|
76
88
|
|
|
77
|
-
# this class is used to "translate" our Events into URLs.
|
|
78
|
-
#
|
|
79
|
-
#
|
|
89
|
+
# this class is used to "translate" our Events into URLs. a query contains an event to send and the serial/token
|
|
90
|
+
# of the target Rabbit. That way, you can send the same event to many nabaztag easily.
|
|
91
|
+
#
|
|
80
92
|
# see http://api.nabaztag.com/docs/home.html
|
|
93
|
+
#
|
|
94
|
+
# ==Examples
|
|
95
|
+
# q = Query.new :token => "my_token", :serial => "my_serial", :event => GET_RABBIT_NAME # => #<Request::Query:0x2aaaaaee10b8 @event=#<Request::Action:0x2b74bb47f828 @id=10>, @token="my_token", @serial="my_serial">
|
|
81
96
|
class Query
|
|
82
97
|
require 'open-uri'
|
|
83
98
|
|
|
84
99
|
# create a new Query object with the give parameters. +serial+ and +token+ parameters should be checked at
|
|
85
100
|
# a higher level. +event+ parameter is usually an Event object, but you can give any Object that respond to
|
|
86
|
-
# to_url
|
|
101
|
+
# to_url, it should return a string that contains some GET parameters like "foo=bar&oni=2", or an array of
|
|
102
|
+
# GET options like [ "foo=bar", "oni=2" ].
|
|
87
103
|
def initialize h
|
|
88
104
|
raise ArgumentError.new('event parameter has no "to_url" method or is empty') unless h[:event] and h[:event].respond_to?(:to_url)
|
|
89
105
|
raise ArgumentError.new('need a :serial') unless h[:serial]
|
|
@@ -92,14 +108,27 @@ module Request
|
|
|
92
108
|
@event, @serial, @token = h[:event], h[:serial], h[:token]
|
|
93
109
|
end
|
|
94
110
|
|
|
95
|
-
# return the complet url
|
|
111
|
+
# return the complet url
|
|
96
112
|
def to_url
|
|
97
|
-
|
|
113
|
+
opts = @event.to_url
|
|
114
|
+
if opts.respond_to?(:join) then opts = opts.join('&') end
|
|
115
|
+
|
|
116
|
+
base_url = if @event.streamed? then APISTREAM_URL else API_URL end
|
|
117
|
+
|
|
118
|
+
"#{base_url}?" << [ "sn=#{@serial}", "token=#{@token}", opts ].join('&')
|
|
98
119
|
end
|
|
99
120
|
|
|
100
|
-
#
|
|
121
|
+
# send the query to the server. it return a ServerRsp object from the corresponding class if no args is given.
|
|
122
|
+
#
|
|
123
|
+
# ==Arguments
|
|
124
|
+
# [:xml] the raw xml server's response
|
|
125
|
+
#
|
|
126
|
+
# ==Examples
|
|
127
|
+
# q = Query.new :token => "my_token", :serial => "my_serial", :event => GET_RABBIT_NAME # => #<Request::Query:0x2aaaaaee10b8 @event=#<Request::Action:0x2b74bb47f828 @id=10>, @token="my_token", @serial="my_serial">
|
|
128
|
+
# q.send! # => #<Response::RabbitName:0x2b74b8c38798 @xml=<UNDEFINED> ... </>>
|
|
129
|
+
# q.send!(:xml) # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><rsp><rabbitName>Makoto</rabbitName></rsp>\n"
|
|
130
|
+
#
|
|
101
131
|
def send! response_type=nil
|
|
102
|
-
# TODO: rescue ?
|
|
103
132
|
rsp = open(self.to_url) { |rsp| rsp.read }
|
|
104
133
|
if response_type == :xml then rsp else Response.parse(rsp) end
|
|
105
134
|
end
|
|
@@ -107,10 +136,19 @@ module Request
|
|
|
107
136
|
|
|
108
137
|
|
|
109
138
|
|
|
139
|
+
# SetEarsPosition events change your rabbit's ears positions.
|
|
140
|
+
# you can set left ear position, or right ear position, or both.
|
|
141
|
+
#
|
|
142
|
+
# =Examples
|
|
143
|
+
# SetEarsPosition.new :posleft => 12 # => #<Request::SetEarsPosition:0x2ad0b2c79680 @h={:posleft=>12}>
|
|
144
|
+
# SetEarsPosition.new :posright => 1 # => #<Request::SetEarsPosition:0x2ad0b2c70260 @h={:posright=>1}>
|
|
145
|
+
# SetEarsPosition.new :posright => 5, :posleft => 5 # => #<Request::SetEarsPosition:0x2ad0b2c5e330 @h={:posleft=>5, :posright=>5}>
|
|
110
146
|
class SetEarsPosition < Base::Event
|
|
111
147
|
MIN_POS = 0
|
|
112
148
|
MAX_POS = 16
|
|
113
149
|
|
|
150
|
+
# take an hash in parameter, with <tt>:posright</tt> and/or <tt>:posleft</tt> keys. values should be between
|
|
151
|
+
# SetEarsPosition::MIN_POS and SetEarsPosition::MAX_POS.
|
|
114
152
|
def initialize h
|
|
115
153
|
@h = h.dup
|
|
116
154
|
raise ArgumentError.new('at least :posright or :posleft must be set') unless @h[:posleft] or @h[:posright]
|
|
@@ -118,59 +156,475 @@ module Request
|
|
|
118
156
|
raise ArgumentError.new(":posleft must be between #{MIN_POS} and #{MAX_POS}") if @h[:posleft ] and not @h[:posleft ].to_i.between?(MIN_POS,MAX_POS)
|
|
119
157
|
end
|
|
120
158
|
|
|
121
|
-
|
|
122
159
|
def to_url
|
|
123
160
|
url = Array.new
|
|
124
|
-
url << "posleft=#{h[:posleft].to_i}" if h[:posleft]
|
|
125
|
-
url << "posright=#{h[:posright].to_i}" if h[:posright]
|
|
126
|
-
url.
|
|
161
|
+
url << "posleft=#{@h[:posleft].to_i}" if @h[:posleft]
|
|
162
|
+
url << "posright=#{@h[:posright].to_i}" if @h[:posright]
|
|
163
|
+
url.sort
|
|
127
164
|
end
|
|
128
165
|
end
|
|
129
166
|
|
|
130
167
|
|
|
168
|
+
# TtsMessage events are used to Text-To-Speach messages.
|
|
169
|
+
#
|
|
170
|
+
# =Examples
|
|
171
|
+
# TtsMessage.new :tts => "oups!" # => #<Request::TtsMessage:0x2ab1ba3cd8e0 @h={:tts=>"oups!"}>
|
|
172
|
+
# TtsMessage.new :tts => "allez hop !", :speed => 200, :voice => "caroline22k" # => #<Request::TtsMessage:0x2ab1ba3b8e40 @h={:tts=>"allez%20hop%20!", :speed=>200, :voice=>"caroline22k"}>
|
|
173
|
+
# TtsMessage.new :tts => "GNU is Not Unix", :speed => 200, :pitch => 400 # => #<Request::TtsMessage:0x2ab1ba3a9580 @h={:tts=>"GNU%20is%20Not%20Unix", :speed=>200, :pitch=>400}>
|
|
131
174
|
class TtsMessage < Base::Event
|
|
132
|
-
require 'cgi'
|
|
133
175
|
MIN_SPEED = 1
|
|
134
|
-
MAX_SPEED =
|
|
176
|
+
MAX_SPEED = 32_000
|
|
135
177
|
|
|
136
178
|
MIN_PITCH = 1
|
|
137
|
-
MAX_PITCH =
|
|
138
|
-
|
|
179
|
+
MAX_PITCH = 32_000
|
|
139
180
|
|
|
181
|
+
# take an hash in parameter, with at least <tt>:tts</tt> key. the <tt>:tts</tt> key must be a string encoded
|
|
182
|
+
# in UTF-8. Optionals parameters are <tt>:speed</tt> and <tt>:pitch</tt>, they must be between MIN_SPEED and
|
|
183
|
+
# MAX_SPEED (MIN_PITCH and MAX_PITCH respectively). Default values for speed/pitch is 100.
|
|
140
184
|
def initialize h
|
|
141
|
-
raise ArgumentError.new('no
|
|
185
|
+
raise ArgumentError.new('no :tts given') unless h[:tts]
|
|
142
186
|
@h = h.dup
|
|
143
187
|
|
|
144
|
-
[:speed,:pitch].each do |
|
|
145
|
-
min = Helpers.constantize("#{self.class}::MIN_#{
|
|
146
|
-
max = Helpers.constantize("#{self.class}::MAX_#{
|
|
188
|
+
[:speed,:pitch].each do |k|
|
|
189
|
+
min = Helpers.constantize("#{self.class}::MIN_#{k.to_s.upcase}")
|
|
190
|
+
max = Helpers.constantize("#{self.class}::MAX_#{k.to_s.upcase}")
|
|
147
191
|
|
|
148
|
-
unless @h[
|
|
149
|
-
raise ArgumentError.new("#{
|
|
192
|
+
unless @h[k].to_i.between?(min,max)
|
|
193
|
+
raise ArgumentError.new("#{k} values must be between #{min} and #{max}")
|
|
150
194
|
else
|
|
151
|
-
@h[
|
|
152
|
-
end if @h[
|
|
195
|
+
@h[k] = @h[k].to_i
|
|
196
|
+
end if @h[k]
|
|
153
197
|
end
|
|
154
198
|
|
|
155
|
-
|
|
199
|
+
# to have a well formatted url
|
|
200
|
+
@h[:tts] = URI.escape @h[:tts]
|
|
201
|
+
@h[:nabcasttitle] = URI.escape @h[:nabcasttitle] if @h[:nabcasttitle]
|
|
156
202
|
end
|
|
157
203
|
|
|
158
204
|
def to_url
|
|
159
|
-
for
|
|
160
|
-
(url ||= Array.new) << "#{
|
|
205
|
+
for key,val in @h
|
|
206
|
+
(url ||= Array.new) << "#{key}=#{val}" if val
|
|
161
207
|
end
|
|
208
|
+
url.sort
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# IdMessage events are used with a message id from Library or a personal MP3 file.
|
|
214
|
+
# Library can be seen here : http://my.nabaztag.com/vl/action/myMessagesBiblio.do
|
|
215
|
+
#
|
|
216
|
+
# =Example (Batman)
|
|
217
|
+
# IdMessage.new :idmessage => 10282 # => #<Request::IdMessage:0x2b28ec730128 @h={:idmessage=>10282}>
|
|
218
|
+
class IdMessage < Base::Event
|
|
219
|
+
MIN_IDMESSAGE = 1
|
|
162
220
|
|
|
163
|
-
|
|
221
|
+
# take an Hash in parameter, with at least <tt>:idmessage</tt> key. the <tt>:idmessage</tt> must respond_to
|
|
222
|
+
# to_i and have a to_i representation greater or equal than IdMessage::MIN_IDMESSAGE.
|
|
223
|
+
def initialize h
|
|
224
|
+
@h = h.dup
|
|
225
|
+
|
|
226
|
+
raise ArgumentError.new('no :idmessage given') unless @h[:idmessage]
|
|
227
|
+
raise ArgumentError.new(":idmessage must be greater than #{MIN_IDMESSAGE}") unless @h[:idmessage].to_i >= MIN_IDMESSAGE
|
|
228
|
+
|
|
229
|
+
@h[:idmessage] = @h[:idmessage].to_i
|
|
230
|
+
|
|
231
|
+
@h[:nabcasttitle] = URI.escape @h[:nabcasttitle] if @h[:nabcasttitle]
|
|
232
|
+
@h[:nabcast] = @h[:nabcast].to_i if @h[:nabcast]
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def to_url
|
|
236
|
+
url = Array.new
|
|
237
|
+
@h.each_pair do |key,val|
|
|
238
|
+
url << "#{key}=#{val}" if val
|
|
239
|
+
end
|
|
240
|
+
url
|
|
164
241
|
end
|
|
165
242
|
end
|
|
166
243
|
|
|
167
244
|
|
|
245
|
+
# AudioStream events are used with MP3 hyperlinks to make your rabbit play podcasts or webradio.
|
|
246
|
+
# Your rabbit has to be a tag/tag to use AudioStream events (it should be checked at higher level, this class won't do that for you :))
|
|
247
|
+
#
|
|
248
|
+
# see http://api.nabaztag.com/docs/home.html#sendurl
|
|
249
|
+
#
|
|
250
|
+
# =Examples
|
|
251
|
+
# you can give a String argument, or an Array of String if you want to play several urls, or a Hash with a
|
|
252
|
+
# <tt>:url_list</tt> key.
|
|
253
|
+
# AudioStream.new "http://my_streamed_url.com" # => #<Request::AudioStream:0x2b44fafd52e0 @args=["http://my_streamed_url.com"]>
|
|
254
|
+
# AudioStream.new :url_list => "http://my_streamed_url.com" # => #<Request::AudioStream:0x2b52a24acf70 @args=["http://my_streamed_url.com"]>
|
|
255
|
+
#
|
|
256
|
+
# AudioStream.new "http://my_streamed_url.com", "http://plop.test" # => #<Request::AudioStream:0x2b44fafc9058 @args=["http://my_streamed_url.com", "http://plop.test"]>
|
|
257
|
+
# AudioStream.new ["http://my_streamed_url.com", "http://plop.test"] # => #<Request::AudioStream:0x2b44fafbdc30 @args=["http://my_streamed_url.com", "http://plop.test"]>
|
|
258
|
+
# AudioStream.new :url_list => ["http://my_streamed_url.com", "http://plop.test"] # => #<Request::AudioStream:0x2b52a24a28e0 @args=["http://my_streamed_url.com", "http://plop.test"]>
|
|
259
|
+
class AudioStream < Base::Event
|
|
260
|
+
|
|
261
|
+
# take an Array of String or many Strings arguments, each String is a URL to play. Another way to create
|
|
262
|
+
# AudioStream is to give a Hash in argument, with the <tt>:url_list</tt> keys that contains an Array of Strings
|
|
263
|
+
# or a String. see examples.
|
|
264
|
+
def initialize *args
|
|
265
|
+
raise ArgumentError.new('no args given') if args.empty? or args.first.empty?
|
|
266
|
+
if args.first.is_a?(Hash)
|
|
267
|
+
args = [ args.first[:url_list] ]
|
|
268
|
+
raise ArgumentError.new('empty :url_list key in Hash argument') if args.first.nil? or args.first.empty?
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
@url_list = args.flatten
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def to_url
|
|
275
|
+
"urlList=#{@url_list.join('|')}"
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# AudioStream object can be added with other AudioStream objects. When you add first to second, the new
|
|
279
|
+
# AudioStream will play all the urls in first, then all the urls in second.
|
|
280
|
+
#
|
|
281
|
+
# ==Examples
|
|
282
|
+
# one = AudioStream.new "http://www.one.com" # => #<Request::AudioStream:0x2b2d075e0b28 @url_list=["http://www.one.com"]>
|
|
283
|
+
# two = AudioStream.new "http://www.two.com" # => #<Request::AudioStream:0x2b2d075db510 @url_list=["http://www.two.com"]>
|
|
284
|
+
# onetwo = one + two # => #<Request::AudioStream:0x2b2d075d7a78 @url_list=["http://www.one.com", "http://www.two.com"]>
|
|
285
|
+
# twoone = two + one # => #<Request::AudioStream:0x2b2d075cff80 @url_list=["http://www.two.com", "http://www.one.com"]>
|
|
286
|
+
def + other
|
|
287
|
+
raise ArgumentError.new("#{other.inspect} is not a Streamed Event") unless other.streamed?
|
|
288
|
+
AudioStream.new(self.url_list, other.url_list)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# compare two AudioStream. AudioStream are equals if and only if they have the same url list.
|
|
292
|
+
def == other
|
|
293
|
+
raise ArgumentError.new("#{other.inspect} is not a Streamed Event") unless other.streamed?
|
|
294
|
+
self.url_list == other.url_list
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
protected
|
|
298
|
+
attr_reader :url_list
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
# =Choregraphy
|
|
303
|
+
# Choregraphy in the Violet API looks like binary CSV code. It isn't really "user-friendly".
|
|
304
|
+
# We use a DSL (Domain Specific Language) to describe Choregraphy more easily, and then translate it in with
|
|
305
|
+
# this class. This allows us to create a more powerful language, making easy (for examples) to set all leds in
|
|
306
|
+
# one sentence, instead of five 90% redundant lines :
|
|
307
|
+
#
|
|
308
|
+
# 'set all to green' will we translated into 'chor=10,0,led,0,0,255,0,0,led,1,0,255,0,0,led,2,0,255,0,0,led,3,0,255,0,0,led,4,0,255,0'
|
|
309
|
+
#
|
|
310
|
+
# Moreover, if you think that a Choregraphy is a Set of Events (that are either an ear command either a led
|
|
311
|
+
# command), then we can use logic operations such as ==, \+, -, | and & on Choregraphy (code taken from test file
|
|
312
|
+
# test_request_chor.rb):
|
|
313
|
+
#
|
|
314
|
+
# one = Choregraphy.new { move left ear forward of degrees 42 }
|
|
315
|
+
# two = Choregraphy.new { move right ear forward of degrees 42 }
|
|
316
|
+
# onetwo = Choregraphy.new { move both ears forward of degrees 42 }
|
|
317
|
+
#
|
|
318
|
+
# assert_equal one | two, one + two
|
|
319
|
+
# assert_equal one & two, Choregraphy.new
|
|
320
|
+
# assert_equal one - two, one
|
|
321
|
+
# assert_equal two - one, two
|
|
322
|
+
# assert_equal onetwo, one + two
|
|
323
|
+
# assert_equal onetwo & two, two
|
|
324
|
+
# assert_equal onetwo & one, one
|
|
325
|
+
# assert_equal onetwo - two, one
|
|
326
|
+
# assert_equal onetwo - one, two
|
|
327
|
+
# assert_equal onetwo | two, onetwo
|
|
328
|
+
# assert_equal onetwo | one, onetwo
|
|
329
|
+
#
|
|
330
|
+
# =Choregraphy Creation
|
|
331
|
+
# see new
|
|
332
|
+
#
|
|
333
|
+
# =Choregraphy DSL description
|
|
334
|
+
# Here is the syntax description: [] are alternation with | or range with - and <> are optionals.
|
|
335
|
+
#
|
|
336
|
+
# at time 1.2 <do>
|
|
337
|
+
# move [right|left|both] <ear|ears> [backward|forward] <of> degrees [0-180]
|
|
338
|
+
# set [bottom|left|middle|right|top|all] <led|leds> to [off|red|green|blue|yellow|magenta|cyan|white|rgb([0-255],[0-255],[0-255])]
|
|
339
|
+
# <end>
|
|
340
|
+
#
|
|
341
|
+
# =Examples
|
|
342
|
+
# for examples, please see the test file (namely test_request_chor.rb), because there are a lot of possible
|
|
343
|
+
# chor description and I don't want to duplicate too much code :)
|
|
344
|
+
class Choregraphy < Base::Event
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
# Take some Choregraphy DSL code and translate it into a Choregraphy description of Violet API.
|
|
348
|
+
#
|
|
349
|
+
# ==Arguments
|
|
350
|
+
# (optionals) an Hash in argument with keys:
|
|
351
|
+
# [name] the chortitle
|
|
352
|
+
# [code] an array of String/Proc or a String/Proc that describe the Choregraphy in our DSL.
|
|
353
|
+
# (optionals) a block of code that describe the Choregraphy.
|
|
354
|
+
#
|
|
355
|
+
# ==Raise
|
|
356
|
+
# raise a Choregraphy::BadChorDesc if not happy.
|
|
357
|
+
#
|
|
358
|
+
# ==Examples (all results are equals)
|
|
359
|
+
# Request::Choregraphy.new { set all off; move right ear forward of degrees 180 } # => #<Request::Choregraphy:0x2b07a05f8ca0 @chor=["0,led,0,0,0,0", "0,led,1,0,0,0", "0,led,2,0,0,0", "0,led,3,0,0,0", "0,led,4,0,0,0", "0,motor,0,180,0,0"], @code=[#<Proc:0x00002b07a05f8d40@(irb):3>], @time=0>
|
|
360
|
+
# Request::Choregraphy.new :code => 'set all off; move right ear forward of degrees 180' # => #<Request::Choregraphy:0x2b07a05e84b8 @chor=["0,led,0,0,0,0", "0,led,1,0,0,0", "0,led,2,0,0,0", "0,led,3,0,0,0", "0,led,4,0,0,0", "0,motor,0,180,0,0"], @code=["set all off; move right ear forward of degrees 180"], @time=0>
|
|
361
|
+
# Request::Choregraphy.new :code => [ 'set all off', 'move right ear forward of degrees 180' ] # => #<Request::Choregraphy:0x2b07a05dae30 @chor=["0,led,0,0,0,0", "0,led,1,0,0,0", "0,led,2,0,0,0", "0,led,3,0,0,0", "0,led,4,0,0,0", "0,motor,0,180,0,0"], @code=["set all off", "move right ear forward of degrees 180"], @time=0>
|
|
362
|
+
#
|
|
363
|
+
def initialize(h=Hash.new, &block)
|
|
364
|
+
@name = h[:name] if h[:name]
|
|
365
|
+
@code = if block_given? then block else h[:code] end
|
|
366
|
+
__choreval__
|
|
367
|
+
@chor.sort! unless @chor.nil?
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def to_url
|
|
371
|
+
raise BadChorDesc.new('no choregraphy given') unless @chor
|
|
372
|
+
|
|
373
|
+
url = Array.new
|
|
374
|
+
url << "chor=10," + @chor.join(',') unless @chor.nil?
|
|
375
|
+
url << "chortitle=#{@name}" unless @name.nil?
|
|
376
|
+
url
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# define dummy methods for DSL
|
|
380
|
+
def self.bubble(*methods)
|
|
381
|
+
methods.each do |m|
|
|
382
|
+
define_method(m) { |args| args }
|
|
383
|
+
private(m.to_sym)
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# raised when the Choregraphy DSL is not ok
|
|
388
|
+
class BadChorDesc < StandardError; end
|
|
389
|
+
|
|
390
|
+
# + has the same behaviour that |
|
|
391
|
+
%w[+ - & |].each do |op|
|
|
392
|
+
define_method(op) do |other|
|
|
393
|
+
new_chor = if self.chor.nil? then other.chor.method(op).call(self.chor).uniq.sort else self.chor.method(op).call(other.chor).uniq.sort end
|
|
394
|
+
ret = Choregraphy.new
|
|
395
|
+
ret.instance_eval { @chor = new_chor } # hacky !
|
|
396
|
+
ret
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def == other
|
|
401
|
+
self.chor == other.chor
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def set command
|
|
405
|
+
raise BadChorDesc.new('wrong Choregraphy description') unless command.is_a?(LedCommandStruct)
|
|
406
|
+
raise BadChorDesc.new('need an element') unless command.elements
|
|
407
|
+
command.elements.each do |e|
|
|
408
|
+
raise BadChorDesc.new('wrong element') unless e == :all or e.between?(Leds::Positions::BOTTOM,Leds::Positions::TOP)
|
|
409
|
+
end
|
|
410
|
+
raise BadChorDesc.new('need a time') unless command.time
|
|
411
|
+
raise BadChorDesc.new('time must be >= than zero') unless command.time.to_i >= 0
|
|
412
|
+
raise BadChorDesc.new('need a color') unless command.color
|
|
413
|
+
raise BadChorDesc.new('wrong size for rgb color array') unless command.color.size == 3
|
|
414
|
+
command.color.collect! do |c|
|
|
415
|
+
raise BadChorDesc.new('color code must be betwen 0 and 255') unless c.to_i.between?(0,255)
|
|
416
|
+
c.to_i
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
template = '%s,led,%s,%s'
|
|
420
|
+
command.color = command.color.join(',')
|
|
421
|
+
|
|
422
|
+
# remove trailling element if all is set
|
|
423
|
+
command.elements.uniq!
|
|
424
|
+
command.elements = [:all] if command.elements.include?(:all)
|
|
425
|
+
|
|
426
|
+
command.elements.each do |e|
|
|
427
|
+
if e == :all
|
|
428
|
+
(Leds::Positions.constants - ['ALL']).each do |cste_name|
|
|
429
|
+
cste = Helpers.constantize "#{self.class}::Leds::Positions::#{cste_name}"
|
|
430
|
+
@chor << template % [ command.time.to_i, cste, command.color ]
|
|
431
|
+
end
|
|
432
|
+
else
|
|
433
|
+
@chor << template % [ command.time.to_i, e, command.color ]
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
def move command
|
|
439
|
+
raise BadChorDesc.new('wrong Choregraphy description') unless command.is_a?(EarCommandStruct)
|
|
440
|
+
raise BadChorDesc.new('need a time') unless command.time
|
|
441
|
+
raise BadChorDesc.new('time must be >= zero') unless command.time.to_i >= 0
|
|
442
|
+
raise BadChorDesc.new('need an angle') unless command.angle
|
|
443
|
+
raise BadChorDesc.new('angle must be between 0 and 180') unless (0..180).include?(command.angle)
|
|
444
|
+
raise BadChorDesc.new('need a direction') unless command.direction
|
|
445
|
+
raise BadChorDesc.new('wrong direction') unless command.direction.between?(Ears::Directions::FORWARD,Ears::Directions::BACKWARD)
|
|
446
|
+
raise BadChorDesc.new('need an element') unless command.element
|
|
447
|
+
raise BadChorDesc.new('wrong element') unless command.element == :both or command.element.between?(Ears::Positions::RIGHT,Ears::Positions::LEFT)
|
|
448
|
+
|
|
449
|
+
template = '%s,motor,%s,%s,0,%s'
|
|
450
|
+
|
|
451
|
+
if command.element == :both
|
|
452
|
+
# we don't know, maybe your rabbit has more than two ears :)
|
|
453
|
+
(Ears::Positions.constants - ['BOTH']).each do |cste_name|
|
|
454
|
+
cste = Helpers.constantize "#{self.class}::Ears::Positions::#{cste_name}"
|
|
455
|
+
@chor << template % [ command.time.to_i, cste, command.angle, command.direction ]
|
|
456
|
+
end
|
|
457
|
+
else
|
|
458
|
+
@chor << template % [ command.time.to_i, command.element, command.angle, command.direction ]
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
#
|
|
464
|
+
# used internally
|
|
465
|
+
#
|
|
466
|
+
|
|
467
|
+
# Command Structs for ears
|
|
468
|
+
EarCommandStruct = Struct.new :element, :direction, :angle, :time
|
|
469
|
+
# Command Structs for leds
|
|
470
|
+
LedCommandStruct = Struct.new :elements, :color, :time
|
|
471
|
+
|
|
472
|
+
# used by operators == + - & |
|
|
473
|
+
protected
|
|
474
|
+
attr_reader :chor
|
|
475
|
+
|
|
476
|
+
private
|
|
477
|
+
|
|
478
|
+
# String of block evaluator
|
|
479
|
+
def __choreval__
|
|
480
|
+
@chor, @time = Array.new, 0
|
|
481
|
+
|
|
482
|
+
@code = [@code] unless @code.respond_to?(:each)
|
|
483
|
+
@code.each do |code|
|
|
484
|
+
if code.is_a?(Proc)
|
|
485
|
+
instance_eval(&code)
|
|
486
|
+
else
|
|
487
|
+
instance_eval(code.to_s, __FILE__, __LINE__)
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# set the time and call block if any
|
|
493
|
+
def at time_formated
|
|
494
|
+
@time = time_formated
|
|
495
|
+
yield if block_given?
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
# format the time
|
|
499
|
+
def time t
|
|
500
|
+
(10 * t.to_f).round
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
# right/left hook, because they must be defined for ears and for leds.
|
|
504
|
+
[:right, :left].each do |m|
|
|
505
|
+
define_method(m) do |arg|
|
|
506
|
+
target = if arg.is_a?(EarCommandStruct) then :ear else :led end
|
|
507
|
+
method("__#{m}_for_#{target}__").call(arg)
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
module Leds
|
|
513
|
+
module Colors
|
|
514
|
+
RED = [255, 0, 0]
|
|
515
|
+
GREEN = [0, 255, 0]
|
|
516
|
+
BLUE = [0, 0, 255]
|
|
517
|
+
CYAN = [0, 255, 255]
|
|
518
|
+
MAGENTA = [255, 0, 255]
|
|
519
|
+
YELLOW = [255, 255, 0]
|
|
520
|
+
WHITE = [255, 255, 255]
|
|
521
|
+
OFF = [ 0, 0, 0]
|
|
522
|
+
end
|
|
523
|
+
module Positions
|
|
524
|
+
BOTTOM = 0
|
|
525
|
+
LEFT = 1
|
|
526
|
+
MIDDLE = 2
|
|
527
|
+
RIGHT = 3
|
|
528
|
+
TOP = 4
|
|
529
|
+
ALL = :all
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
# leds dummy methods setup
|
|
534
|
+
bubble :led, :leds
|
|
535
|
+
|
|
536
|
+
# make possible to write
|
|
537
|
+
# my_color = [1,2,3]
|
|
538
|
+
# set all to my_color
|
|
539
|
+
# and also
|
|
540
|
+
# set all to 1,2,3
|
|
541
|
+
def to *args
|
|
542
|
+
case i = args.first
|
|
543
|
+
when Array then rgb(*i)
|
|
544
|
+
when LedCommandStruct then i
|
|
545
|
+
else rgb(*args)
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
# check values and convert to array
|
|
550
|
+
def rgb(*color)
|
|
551
|
+
command = LedCommandStruct.new
|
|
552
|
+
command.time, command.color = @time, color[0..2]
|
|
553
|
+
command
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# generate colors methods
|
|
557
|
+
Leds::Colors.constants.each do |cste_name|
|
|
558
|
+
cste = Helpers.constantize "#{self}::Leds::Colors::#{cste_name}"
|
|
559
|
+
define_method(cste_name.downcase) { |args| rgb(*cste) }
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
# generate leds positions methods
|
|
563
|
+
Leds::Positions.constants.each do |cste_name|
|
|
564
|
+
cste = Helpers.constantize "#{self}::Leds::Positions::#{cste_name}"
|
|
565
|
+
# right and left are specials cases
|
|
566
|
+
cste_name = "__#{cste_name}_for_led__" if cste_name =~ /^(LEFT|RIGHT)$/
|
|
567
|
+
|
|
568
|
+
define_method(cste_name.downcase) do |command|
|
|
569
|
+
(command.elements ||= Array.new) << cste
|
|
570
|
+
command
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
module Ears
|
|
576
|
+
module Positions
|
|
577
|
+
RIGHT = 0
|
|
578
|
+
LEFT = 1
|
|
579
|
+
BOTH = :both
|
|
580
|
+
end
|
|
581
|
+
module Directions
|
|
582
|
+
FORWARD = 0
|
|
583
|
+
BACKWARD = 1
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
# ears dummy methods setup
|
|
588
|
+
bubble :of, :ear, :ears
|
|
589
|
+
|
|
590
|
+
def degrees angle
|
|
591
|
+
angle = angle.to_i
|
|
592
|
+
command = EarCommandStruct.new
|
|
593
|
+
command.angle, command.time = angle, @time
|
|
594
|
+
command
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
Ears::Directions.constants.each do |cste_name|
|
|
598
|
+
cste = Helpers.constantize "#{self}::Ears::Directions::#{cste_name}"
|
|
599
|
+
|
|
600
|
+
define_method(cste_name.downcase) do |command|
|
|
601
|
+
command.direction = cste
|
|
602
|
+
command
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
Ears::Positions.constants.each do |cste_name|
|
|
607
|
+
cste = Helpers.constantize "#{self}::Ears::Positions::#{cste_name}"
|
|
608
|
+
# right and left are specials cases
|
|
609
|
+
cste_name = "__#{cste_name}_for_ear__" if cste_name =~ /^(LEFT|RIGHT)$/
|
|
610
|
+
|
|
611
|
+
define_method(cste_name.downcase) do |command|
|
|
612
|
+
command.element = cste
|
|
613
|
+
command
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
end # class Choregraphy
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
168
621
|
#
|
|
169
622
|
# Actions list.
|
|
170
623
|
#
|
|
171
624
|
# see http://api.nabaztag.com/docs/home.html#getinfo
|
|
172
625
|
#
|
|
173
626
|
|
|
627
|
+
|
|
174
628
|
# actions are used to retrieve informations about the Nabaztag or the Nabaztag's owners.
|
|
175
629
|
# see constants of Request module, all Action are Request constant that begin with GET or
|
|
176
630
|
# SET. Request::GET_EARS_POSITION is not an Action in the violet API, but we implement it as it was.
|
|
@@ -182,7 +636,6 @@ module Request
|
|
|
182
636
|
@id = id
|
|
183
637
|
end
|
|
184
638
|
|
|
185
|
-
# Action have only action= option.
|
|
186
639
|
def to_url
|
|
187
640
|
"action=#{@id}"
|
|
188
641
|
end
|
|
@@ -190,84 +643,84 @@ module Request
|
|
|
190
643
|
|
|
191
644
|
|
|
192
645
|
# Preview the TTS or music (with music id) without sending it
|
|
193
|
-
# Examples
|
|
646
|
+
# Examples
|
|
194
647
|
# Query.new(:event => GET_LINKPREVIEW, :serial => my_serial, :token => my_token).send! # => #<Response::LinkPreview:0x2aaaab100f88 @xml=<UNDEFINED> ... </>>
|
|
195
648
|
# see Response::LinkPreview
|
|
196
649
|
GET_LINKPREVIEW = Action.new 1
|
|
197
650
|
|
|
198
651
|
|
|
199
652
|
# Get a list of your friends
|
|
200
|
-
# Examples
|
|
653
|
+
# Examples
|
|
201
654
|
# Query.new(:event => GET_FRIENDS_LIST, :serial => my_serial, :token => my_token).send! # => #<Response::ListFriend:0x2af08fd53568 @xml=<UNDEFINED> ... </>>
|
|
202
655
|
# see Response::ListFriend
|
|
203
656
|
GET_FRIENDS_LIST = Action.new 2
|
|
204
657
|
|
|
205
658
|
|
|
206
659
|
# Get a count and the list of the messages in your inbox
|
|
207
|
-
# Examples
|
|
660
|
+
# Examples
|
|
208
661
|
# Query.new(:event => GET_INBOX_LIST, :serial => my_serial, :token => my_token).send! # => #<Response::ListReceivedMsg:0x2aaaab0e0be8 @xml=<UNDEFINED> ... </>>
|
|
209
662
|
# see Response::ListReceivedMsg
|
|
210
663
|
GET_INBOX_LIST = Action.new 3
|
|
211
664
|
|
|
212
665
|
|
|
213
666
|
# Get the timezone in which your Nabaztag is set
|
|
214
|
-
# Examples
|
|
667
|
+
# Examples
|
|
215
668
|
# Query.new(:event => GET_TIMEZONE, :serial => my_serial, :token => my_token).send! # => #<Response::Timezone:0x2af091e58f60 @xml=<UNDEFINED> ... </>>
|
|
216
669
|
# see Response::Timezone
|
|
217
670
|
GET_TIMEZONE = Action.new 4
|
|
218
671
|
|
|
219
672
|
|
|
220
673
|
# Get the signature defined for the Nabaztag
|
|
221
|
-
# Examples
|
|
674
|
+
# Examples
|
|
222
675
|
# Query.new(:event => GET_SIGNATURE, :serial => my_serial, :token => my_token).send! # => #<Response::Signature:0x2aaaab0c8c28 @xml=<UNDEFINED> ... </>>
|
|
223
676
|
# see Response::Signature
|
|
224
677
|
GET_SIGNATURE = Action.new 5
|
|
225
678
|
|
|
226
679
|
|
|
227
680
|
# Get a count and the list of people in your blacklist
|
|
228
|
-
# Examples
|
|
681
|
+
# Examples
|
|
229
682
|
# Query.new(:event => GET_BLACKLISTED, :serial => my_serial, :token => my_token).send! # => #<Response::Blacklist:0x2aaaab0b0ad8 @xml=<UNDEFINED> ... </>>
|
|
230
683
|
# see Response::Blacklist
|
|
231
684
|
GET_BLACKLISTED = Action.new 6
|
|
232
685
|
|
|
233
686
|
|
|
234
687
|
# Get to know if the Nabaztag is sleeping (YES) or not (NO)
|
|
235
|
-
# Examples
|
|
688
|
+
# Examples
|
|
236
689
|
# Query.new(:event => GET_RABBIT_STATUS, :serial => my_serial, :token => my_token).send! # => #<Response::RabbitSleep:0x2aaaab092a88 @xml=<UNDEFINED> ... </>>
|
|
237
690
|
# see Response::RabbitSleep
|
|
238
691
|
GET_RABBIT_STATUS = Action.new 7
|
|
239
692
|
|
|
240
693
|
|
|
241
694
|
# Get to know if the Nabaztag is a Nabaztag (V1) or a Nabaztag/tag (V2)
|
|
242
|
-
# Examples
|
|
695
|
+
# Examples
|
|
243
696
|
# Query.new(:event => GET_RABBIT_VERSION, :serial => my_serial, :token => my_token).send! # => #<Response::RabbitVersion:0x2aaaab07c418 @xml=<UNDEFINED> ... </>>
|
|
244
697
|
# see Response::RabbitVersion
|
|
245
698
|
GET_RABBIT_VERSION = Action.new 8
|
|
246
699
|
|
|
247
700
|
|
|
248
701
|
# Get a list of all supported languages/voices for TTS (text to speach) engine
|
|
249
|
-
# Examples
|
|
702
|
+
# Examples
|
|
250
703
|
# Query.new(:event => GET_LANG_VOICE, :serial => my_serial, :token => my_token).send! # => #<Response::VoiceListTts:0x2aaaab064368 @xml=<UNDEFINED> ... </>>
|
|
251
704
|
# see Response::VoiceListTts
|
|
252
705
|
GET_LANG_VOICE = Action.new 9
|
|
253
706
|
|
|
254
707
|
|
|
255
708
|
# Get the name of the Nabaztag
|
|
256
|
-
# Examples
|
|
709
|
+
# Examples
|
|
257
710
|
# Query.new(:event => GET_RABBIT_NAME, :serial => my_serial, :token => my_token).send! # => #<Response::RabbitName:0x2aaaab0459b8 @xml=<UNDEFINED> ... </>>
|
|
258
711
|
# see Response::RabbitName
|
|
259
712
|
GET_RABBIT_NAME = Action.new 10
|
|
260
713
|
|
|
261
714
|
|
|
262
715
|
# Get the languages selected for the Nabaztag
|
|
263
|
-
# Examples
|
|
716
|
+
# Examples
|
|
264
717
|
# Query.new(:event => GET_SELECTED_LANG, :serial => my_serial, :token => my_token).send! # => #<Response::LangListUser:0x2aaaab02bfb8 @xml=<UNDEFINED> ... </>>
|
|
265
718
|
# see Response::LangListUser
|
|
266
719
|
GET_SELECTED_LANG = Action.new 11
|
|
267
720
|
|
|
268
721
|
|
|
269
722
|
# Get a preview of a message. This works only with the urlPlay parameter and URLs like broad/001/076/801/262.mp3
|
|
270
|
-
# Examples
|
|
723
|
+
# Examples
|
|
271
724
|
# Query.new(:event => GET_MESSAGE_PREVIEW, :serial => my_serial, :token => my_token).send! # => #<Response::LinkPreview:0x2aaaab011258 @xml=<UNDEFINED> ... </>>
|
|
272
725
|
# see Response::LinkPreview
|
|
273
726
|
GET_MESSAGE_PREVIEW = Action.new 12
|
|
@@ -275,7 +728,7 @@ module Request
|
|
|
275
728
|
|
|
276
729
|
# Get the position of the ears to your Nabaztag. this request is not an action in the Violet API but we do as
|
|
277
730
|
# if it was because it's make more sens (to me).
|
|
278
|
-
# Examples
|
|
731
|
+
# Examples
|
|
279
732
|
# Query.new(:event => GET_EARS_POSITION, :serial => my_serial, :token => my_token).send! # => #<Response::PositionEar:0x2aaaaaff6908 @xml=<UNDEFINED> ... </>>
|
|
280
733
|
# see Response::PositionEar
|
|
281
734
|
GET_EARS_POSITION = Action.new nil
|
|
@@ -286,16 +739,17 @@ module Request
|
|
|
286
739
|
|
|
287
740
|
|
|
288
741
|
# Send your Rabbit to sleep
|
|
289
|
-
# Examples
|
|
742
|
+
# Examples
|
|
290
743
|
# Query.new(:event => SET_RABBIT_ASLEEP, :serial => my_serial, :token => my_token).send! # => #<Response::CommandSend:0x2aaaaafbf980 @xml=<UNDEFINED> ... </>>
|
|
291
744
|
# see Response::CommandSend
|
|
292
745
|
SET_RABBIT_ASLEEP = Action.new 13
|
|
293
746
|
|
|
294
747
|
|
|
295
748
|
# Wake up your Rabbit
|
|
296
|
-
# Examples
|
|
749
|
+
# Examples
|
|
297
750
|
# Query.new(:event => SET_RABBIT_AWAKE, :serial => my_serial, :token => my_token).send! # => #<Response::CommandSend:0x2aaaaafa60c0 @xml=<UNDEFINED> ... </>>
|
|
298
751
|
# see Response::CommandSend
|
|
299
752
|
SET_RABBIT_AWAKE = Action.new 14
|
|
300
753
|
|
|
301
754
|
end # module Request
|
|
755
|
+
|