topherfangio-lcdproc-ruby 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.document +5 -0
  2. data/.gitignore +6 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +9 -0
  5. data/Rakefile +70 -0
  6. data/TODO +18 -0
  7. data/VERSION +1 -0
  8. data/devices/crystalfontz/packet.rb +108 -0
  9. data/devices/devices.rb +41 -0
  10. data/examples/basic.rb +39 -0
  11. data/examples/clock.rb +78 -0
  12. data/examples/lights.rb +67 -0
  13. data/lcdproc.rb +43 -0
  14. data/lib/console.rb +39 -0
  15. data/lib/core_extensions/array.rb +37 -0
  16. data/lib/core_extensions/string.rb +37 -0
  17. data/lib/includes/lcdproc.rb +27 -0
  18. data/lib/lcdproc-ruby.rb +0 -0
  19. data/lib/lcdproc/client.rb +458 -0
  20. data/lib/lcdproc/command.rb +54 -0
  21. data/lib/lcdproc/errors.rb +41 -0
  22. data/lib/lcdproc/key_event.rb +59 -0
  23. data/lib/lcdproc/menu.rb +188 -0
  24. data/lib/lcdproc/menu_event.rb +49 -0
  25. data/lib/lcdproc/menu_item.rb +108 -0
  26. data/lib/lcdproc/menu_items/action.rb +72 -0
  27. data/lib/lcdproc/menu_items/alpha.rb +85 -0
  28. data/lib/lcdproc/menu_items/checkbox.rb +76 -0
  29. data/lib/lcdproc/menu_items/ip.rb +75 -0
  30. data/lib/lcdproc/menu_items/numeric.rb +75 -0
  31. data/lib/lcdproc/menu_items/ring.rb +75 -0
  32. data/lib/lcdproc/menu_items/slider.rb +83 -0
  33. data/lib/lcdproc/menu_items/submenu.rb +77 -0
  34. data/lib/lcdproc/response.rb +65 -0
  35. data/lib/lcdproc/screen.rb +283 -0
  36. data/lib/lcdproc/widget.rb +142 -0
  37. data/lib/lcdproc/widgets/graph.rb +185 -0
  38. data/lib/lcdproc/widgets/hbar.rb +101 -0
  39. data/lib/lcdproc/widgets/icon.rb +94 -0
  40. data/lib/lcdproc/widgets/num.rb +92 -0
  41. data/lib/lcdproc/widgets/scroller.rb +110 -0
  42. data/lib/lcdproc/widgets/string.rb +94 -0
  43. data/lib/lcdproc/widgets/title.rb +90 -0
  44. data/lib/lcdproc/widgets/vbar.rb +111 -0
  45. data/script/console.rb +28 -0
  46. data/script/telnet.rb +90 -0
  47. data/tasks/test/basic.rake +82 -0
  48. data/tasks/test/keys.rake +66 -0
  49. data/tasks/test/menus.rake +74 -0
  50. metadata +104 -0
@@ -0,0 +1,83 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ module LCDProc
28
+
29
+ module MenuItems
30
+
31
+ class Slider
32
+ include LCDProc::MenuItem
33
+ LCDProc::MenuItem.add_support( :slider, self )
34
+
35
+ @@slider_item_count = 0
36
+
37
+ # Creates a new Slider MenuItem object.
38
+ #
39
+ # The <tt>user_options</tt> will accept a hash of the following MenuItem options.
40
+ #
41
+ # * <tt>:id</tt> - The unique string that identifies this slider. Defaults to "SliderMenuItem_" + a sequence number.
42
+ #
43
+ # The <tt>lcdproc_options</tt> will accept a hash of the options to be passed to LCDd when creating or updating the slider.
44
+ #
45
+ # * <tt>:text</tt> - The text to be displayed on the LCD for this slider. Defaults to the id.
46
+ # * <tt>:mintext</tt> - The text to be displayed at the far left (minimum) end of the slider. Defaults to "".
47
+ # * <tt>:maxtext</tt> - The text to be displayed at the far left (maximum) end of the slider. Defaults to "".
48
+ # * <tt>:minvalue</tt> - The minimum value that the slider should allow. Defaults to 0.
49
+ # * <tt>:maxvalue</tt> - The maximum value that the slider should allow. Defaults to 100.
50
+ # * <tt>:value</tt> - The initial starting value of the slider. Defaults to 0.
51
+ # * <tt>:stepsize</tt> - The number by which the value is increased with every press of the increment or decrement key. Defaults to 1. A value of 0 means that it can only be controled from within the client program.
52
+ def initialize( user_options = {}, lcdproc_options = {} )
53
+ @lcdproc_options = {}
54
+
55
+ if user_options[:id].nil?
56
+ @id = "SliderMenuItem_#{@@slider_item_count}"
57
+ else
58
+ @id = user_options[:id]
59
+ end
60
+
61
+ @lcdproc_type = "slider"
62
+ @lcdproc_event_type = "(plus|minus)"
63
+
64
+ @lcdproc_options[:text] = "#{@id}"
65
+
66
+ @lcdproc_options[:mintext] = ""
67
+ @lcdproc_options[:maxtext] = ""
68
+ @lcdproc_options[:minvalue] = 0
69
+ @lcdproc_options[:maxvalue] = 100
70
+ @lcdproc_options[:value] = 0
71
+ @lcdproc_options[:stepsize] = 1
72
+
73
+ @lcdproc_options.update( lcdproc_options )
74
+
75
+ [ :text, :mintext, :maxtext ].each { |s| @lcdproc_options[s].quotify! }
76
+
77
+ @@slider_item_count += 1
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,77 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ module LCDProc
28
+
29
+ module MenuItems
30
+
31
+ class SubMenu < LCDProc::Menu
32
+ include LCDProc::MenuItem
33
+ LCDProc::MenuItem.add_support( :submenu, self )
34
+
35
+ # Go ahead and add support so that users can pass :menu instead of :submenu to MenuItem.new
36
+ LCDProc::MenuItem.add_support( :menu, self )
37
+
38
+ @@submenu_item_count = 0
39
+
40
+ # Creates a new SubMenu MenuItem object.
41
+ #
42
+ # The <tt>user_options</tt> will accept a hash of the following MenuItem options.
43
+ #
44
+ # * <tt>:id</tt> - The unique string that identifies this sub menu. Defaults to "SubMenuMenuItem_" + a sequence number.
45
+ #
46
+ # The <tt>lcdproc_options</tt> will accept a hash of the options to be passed to LCDd when creating or updating the sub menu.
47
+ #
48
+ # * <tt>:text</tt> - The text to be displayed on the LCD for this sub menu. Defaults to the id.
49
+ def initialize( user_options = {}, lcdproc_options = {} )
50
+
51
+ # Initialize the menu system with a nil client
52
+ super( nil )
53
+
54
+ @lcdproc_options = {}
55
+
56
+ if user_options[:id].nil?
57
+ @id = "SubMenuMenuItem_#{@@submenu_item_count}"
58
+ else
59
+ @id = user_options[:id]
60
+ end
61
+
62
+ @lcdproc_type = "menu"
63
+ @lcdproc_event_type = "(enter|leave)"
64
+
65
+ @lcdproc_options[:text] = "#{@id}"
66
+
67
+ @lcdproc_options.update( lcdproc_options )
68
+
69
+ [ :text ].each { |s| @lcdproc_options[s].quotify! }
70
+
71
+ @@submenu_item_count += 1
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,65 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ module LCDProc
28
+
29
+ class Response
30
+ attr_reader :message
31
+
32
+ def initialize( message )
33
+ @message = message
34
+ end
35
+
36
+ def successful?
37
+ passed = true
38
+
39
+ if @message.kind_of? String
40
+ messages = [@message]
41
+ else
42
+ messages = @message
43
+ end
44
+
45
+ messages.each do |m|
46
+ if m =~ /^huh/
47
+ passed = false
48
+ break
49
+ end
50
+ end
51
+
52
+ return passed
53
+ end
54
+
55
+ def message
56
+ if @message.kind_of? Array
57
+ return @message.join
58
+ else
59
+ return @message
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,283 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ module LCDProc
28
+
29
+ class Screen
30
+ @@screen_count = 0
31
+
32
+ attr_reader :key_events, :client, :id, :lcdproc_attributes, :priority, :widgets
33
+
34
+ PRIORITIES = [ :hidden, :background, :info, :foreground, :alert, :input ]
35
+
36
+ # Creates a new screen to which you may attach widgets.
37
+ #
38
+ # Example Usage:
39
+ #
40
+ # Screen.new( 'TestScreen' )
41
+ def initialize( id = "Screen_" + @@screen_count.to_s )
42
+ @id = id
43
+ @client = nil
44
+ @widgets = []
45
+ @key_events = []
46
+ @priority = :info
47
+
48
+ @lcdproc_attributes = {}
49
+ @lcdproc_attributes[:heartbeat] = :open
50
+
51
+ @@screen_count += 1
52
+ end
53
+
54
+
55
+ # Add a widget to this screen
56
+ def add_widget( widget )
57
+ if @widgets.select{ |w| w == widget }.empty?
58
+
59
+ if widget.attach_to( self )
60
+ @widgets << widget
61
+
62
+ if @client
63
+ if widget.show
64
+ return true
65
+ else
66
+ return false
67
+ end
68
+ else
69
+ return true
70
+ end
71
+ else
72
+ return false
73
+ end
74
+
75
+ else
76
+ if @client
77
+ @client.add_message( "Widget '#{widget.id}' is already added" )
78
+ end
79
+
80
+ return false
81
+ end
82
+ end
83
+
84
+
85
+ # Sets the priority of this screen to "alert" status
86
+ def alert!
87
+ self.priority = :alert
88
+ end
89
+
90
+
91
+ # Attaches the screen to the requested client
92
+ def attach_to( client )
93
+ response = client.send_command( Command.new( "screen_add #{id.to_s}" ) )
94
+
95
+ if response.successful?
96
+ client.add_message( "Screen '#{self.id}' attached to client '#{client.name}'" )
97
+ @client = client
98
+
99
+ return true
100
+ else
101
+ client.add_message( "Error: Failed to attach screen '#{self.id}' to client '#{client.name}' (#{response.message} : #{response.successful?})" )
102
+ return false
103
+ end
104
+ end
105
+
106
+
107
+ # Detaches the screen from any client
108
+ def detach
109
+ if @client
110
+ response = @client.send_command( Command.new( "screen_del #{self.id}" ) )
111
+
112
+ if response.successful?
113
+ @client.add_message( "Screen '#{self.id}' detached from client '#{@client.name}'" )
114
+ @client = nil
115
+
116
+ return true
117
+ end
118
+ else
119
+ add_message "Error: Failed to detach screen '#{self.id}' from '#{@client.name}' (#{response.message})"
120
+ return false
121
+ end
122
+ end
123
+
124
+
125
+ # Turns on or off the screen's heartbeat
126
+ #
127
+ # * <tt>state</tt> - A symbol representing the state in which you wish the heartbeat to be. Valid values are <tt>:on</tt>, <tt>:off</tt> or <tt>:open</tt>.
128
+ def heartbeat= state
129
+ @lcdproc_attributes[:heartbeat] = state
130
+
131
+ update_lcdproc_attribute( :heartbeat )
132
+ end
133
+
134
+ # Turns on or off the screen's backlight
135
+ #
136
+ # * <tt>state</tt> - A symbol representing the state in which you wish the backlight to be.Valid values are
137
+ # * :on - Always on.
138
+ # * :off - Always off.
139
+ # * :toggle - Toggle the current state.
140
+ # * :open - Use the client's setting.
141
+ # * :blink - Moderately striking backlight variation.
142
+ # * :flash - Very striking backlight variation.
143
+ def backlight= state
144
+ @lcdproc_attributes[:backlight] = state
145
+
146
+ update_lcdproc_attribute( :backlight )
147
+ end
148
+
149
+
150
+ # Sets the priority status of this screen
151
+ #
152
+ # * <tt>other</tt> - The priority that you wish this screen to have. Accepted values are any integer (see LCDProc developer documentation for integer-priority mappings) or one of the following:
153
+ # * :hidden
154
+ # * :background
155
+ # * :info
156
+ # * :foreground
157
+ # * :alert
158
+ # * :input
159
+ def priority=( other )
160
+ if other.kind_of? Fixnum or ( other.kind_of? Symbol and Screen::PRIORITIES.inlcude? other )
161
+
162
+ @priority = other
163
+
164
+ if @client
165
+ response = @client.send_command( Command.new( "screen_set #{@id} -priority #{@priority}" ) )
166
+
167
+ if response.successful?
168
+ return @priority
169
+ else
170
+ return nil
171
+ end
172
+ end
173
+
174
+ return @priority
175
+
176
+ end
177
+
178
+ return nil
179
+ end
180
+
181
+
182
+ # Processed a particular key event
183
+ def process_key( key )
184
+ @key_events.select{ |ke| ke.key === key }.each do |ke|
185
+ ke.block.call unless ke.block.nil?
186
+ end
187
+ end
188
+
189
+
190
+ # Register a key event to be handled when the key is pressed on this screen. Note that you can register
191
+ # the same key multiple times. All actions that are registered will be performed!
192
+ #
193
+ # Example:
194
+ #
195
+ # c = Client.new
196
+ # s = Screen.new
197
+ # s.register_key_event( KeyEvent.new( 'Left' ) { puts "Left button was pressed!" } )
198
+ def register_key_event( key_event )
199
+
200
+ if key_event and @client and @client.valid_keys.include? key_event.key
201
+ response = @client.send_command( Command.new( "client_add_key -shared #{key_event.key}" ) )
202
+
203
+ if response.successful?
204
+ @key_events << key_event
205
+ return key_event
206
+ end
207
+ end
208
+
209
+ return nil
210
+ end
211
+
212
+
213
+ # Removes a widget from the screen
214
+ def remove_widget( widget )
215
+ if @widgets.include? widget
216
+
217
+ if widget.hide and widget.detach
218
+ @widgets.delete( widget )
219
+ return true
220
+ else
221
+ return false
222
+ end
223
+
224
+ else
225
+ if @client
226
+ @client.add_message( "Widget '#{widget.id}' is not attached to Screen '#{@id}'" )
227
+ end
228
+
229
+ return false
230
+ end
231
+ end
232
+
233
+
234
+ # Unregisters a key event so that it will no longer be processed
235
+ def unregister_key_event( key_event )
236
+ if @key_events.include? key_event
237
+ @key_events.delete key_event
238
+ return key_event
239
+ else
240
+ return nil
241
+ end
242
+ end
243
+
244
+ # Updates the current contents of the screen by iterating through it's widgets and calling each of their
245
+ # update methods as well as making sure that they are displayed on the screen by calling their show method.
246
+ def update
247
+ if @client
248
+ passed = true
249
+
250
+ @widgets.each{ |widget| widget.show; passed = widget.update; if not passed then break end }
251
+
252
+ if passed
253
+ return true
254
+ else
255
+ return false
256
+ end
257
+ else
258
+ return false
259
+ end
260
+ end
261
+
262
+
263
+ # Updates a particular LCDProc attribute
264
+ def update_lcdproc_attribute( attribute )
265
+ if @client
266
+ display = attribute.to_s.capitalize
267
+ value = @lcdproc_attributes[attribute].to_s
268
+
269
+ response = @client.send_command( Command.new( "screen_set #{@id} -#{attribute.to_s} #{value}" ) )
270
+
271
+ if response.successful?
272
+ @client.add_message( "#{display} set to '#{value}' for Screen '#{@id}'" )
273
+ return true
274
+ else
275
+ @client.add_message( "Error: #{display} could not be set to '#{value}' for Screen '#{@id}' (#{response.message})" )
276
+ return false
277
+ end
278
+ end
279
+ end
280
+
281
+ end
282
+
283
+ end