libastag 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|