lightwaverf 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/lightwaverf +4 -0
  2. data/lib/lightwaverf.rb +165 -17
  3. metadata +3 -2
data/bin/lightwaverf CHANGED
@@ -3,12 +3,16 @@ require 'lightwaverf'
3
3
  case ARGV[0]
4
4
  when 'help'
5
5
  puts LightWaveRF.new.help
6
+ when 'configure'
7
+ puts LightWaveRF.new.configure
6
8
  when 'sequence'
7
9
  puts LightWaveRF.new.sequence ARGV[1], ARGV[2]
8
10
  when 'energy'
9
11
  puts LightWaveRF.new.energy ARGV[1], ARGV[2], ARGV[3]
10
12
  when 'timer'
11
13
  puts LightWaveRF.new.timer ARGV[1], ARGV[2]
14
+ when 'update'
15
+ puts LightWaveRF.new.update_config ARGV[1], ARGV[2]
12
16
  else
13
17
  LightWaveRF.new.send ARGV[0], ARGV[1], ARGV[2], ARGV[3]
14
18
  end
data/lib/lightwaverf.rb CHANGED
@@ -11,7 +11,7 @@ class LightWaveRF
11
11
  # Display usage info
12
12
  def usage
13
13
  rooms = self.class.get_rooms self.get_config
14
- 'usage: lightwaverf ' + rooms.keys.first + ' ' + rooms.values.first['device'].keys.first.to_s + ' on # where "' + rooms.keys.first + '" is a room in ' + self.get_config_file
14
+ 'usage: lightwaverf ' + rooms.values.first['name'] + ' ' + rooms.values.first['device'].keys.first.to_s + ' on # where "' + rooms.keys.first + '" is a room in ' + self.get_config_file
15
15
  end
16
16
 
17
17
  # Display help
@@ -19,11 +19,53 @@ class LightWaveRF
19
19
  help = self.usage + "\n"
20
20
  help += "your rooms, devices, and sequences, as defined in " + self.get_config_file + ":\n\n"
21
21
  help += YAML.dump self.get_config['room']
22
- room = self.get_config['room'].keys.last
23
- device = self.get_config['room'][room].last
22
+ room = self.get_config['room'].last['name']
23
+ device = self.get_config['room'].last['device'].last
24
24
  help += "\n\nso to turn on " + room + " " + device + " type \"lightwaverf " + room + " " + device + " on\"\n"
25
25
  end
26
26
 
27
+ # Configure, build config file
28
+ def configure
29
+ config = { 'host' => self.get_config['host'], 'calendar' => self.get_config['calendar'] }
30
+ puts 'What is the ip address of your wifi link? (' + self.get_config['host'] + ')'
31
+ host = STDIN.gets.chomp
32
+ if ! host.to_s.empty?
33
+ config['host'] = host
34
+ end
35
+ puts 'What is the address of your google calendar? (' + self.get_config['calendar'] + ')'
36
+ calendar = STDIN.gets.chomp
37
+ if ! calendar.to_s.empty?
38
+ config['calendar'] = calendar
39
+ end
40
+ device = 'x'
41
+ while ! device.to_s.empty?
42
+ puts 'Give me the name of a room and its devices, space separated. For example "lounge light socket tv". Just hit enter to finish.'
43
+ if device = STDIN.gets.chomp
44
+ parts = device.split ' '
45
+ if !parts[0].to_s.empty? and !parts[1].to_s.empty?
46
+ new_room = parts.shift
47
+ puts 'got ' + device + ' todo: to split this up... new room is ' + new_room
48
+ if ! config['room']
49
+ config['room'] = [ ]
50
+ end
51
+ found = false
52
+ config['room'].each do | room |
53
+ if room['name'] == new_room
54
+ room['device'] = parts
55
+ found = true
56
+ end
57
+ p 'so now room is ' + room.to_s
58
+ end
59
+ if ! found
60
+ config['room'].push 'name' => new_room, 'device' => parts
61
+ end
62
+ end
63
+ end
64
+ end
65
+ puts 'end of configure, config is now ' + config.to_s
66
+ self.put_config config
67
+ end
68
+
27
69
  # Config file setter
28
70
  def set_config_file file
29
71
  @config_file = file
@@ -39,29 +81,130 @@ class LightWaveRF
39
81
  @log_file || File.expand_path('~') + '/lightwaverf.log'
40
82
  end
41
83
 
84
+ def put_config config = { 'host' => '192.168.1.64', 'room' => [ { 'name' => 'our', 'device' => [ 'light', 'lights' ] } ] }
85
+ puts 'put_config got ' + config.to_s
86
+ puts 'so writing ' + YAML.dump( config )
87
+ File.open( self.get_config_file, 'w' ) do | handle |
88
+ handle.write YAML.dump( config )
89
+ end
90
+ end
91
+
42
92
  # Get the config file, create it if it does not exist
43
93
  def get_config
44
94
  if ! @config
45
95
  if ! File.exists? self.get_config_file
46
- File.open( self.get_config_file, 'w' ) do | handle |
47
- handle.write YAML.dump( { 'host' => '192.168.0.14', 'room' => { 'our' => [ 'light', 'lights' ] }, 'sequence' => { 'lights' => [ [ 'our', 'light', 'on' ], [ 'our', 'lights', 'on' ] ] }} )
48
- end
96
+ puts self.get_config_file + ' does not exist - copy lightwaverf-configy.yml from https://github.com/pauly/lightwaverf to your home directory or type lightwaverf configure'
97
+ self.put_config
49
98
  end
50
99
  @config = YAML.load_file self.get_config_file
51
100
  end
52
101
  @config
53
102
  end
54
103
 
104
+ # Update the LightWaveRF Gem config file from the LightWaveRF Host server
105
+ #
106
+ # Example:
107
+ # >> LightWaveRF.new.update_config 'name@example.com', '1234'
108
+ #
109
+ # Arguments:
110
+ # email: (String)
111
+ # pin: (String)
112
+ # debug: (Boolean)
113
+ #
114
+ # Credits:
115
+ # wonko - http://lightwaverfcommunity.org.uk/forums/topic/querying-configuration-information-from-the-lightwaverf-website/
116
+ def update_config email = nil, pin = nil, debug = false
117
+
118
+ # Login to LightWaveRF Host server
119
+ require 'net/http'
120
+ require 'uri'
121
+ uri = URI.parse('https://lightwaverfhost.co.uk/manager/index.php')
122
+ http = Net::HTTP.new(uri.host, uri.port)
123
+ if uri.scheme == 'https'
124
+ require 'net/https'
125
+ http.use_ssl = true
126
+ end
127
+ data = 'pin=' + pin + '&email=' + email
128
+ headers = {'Content-Type'=> 'application/x-www-form-urlencoded'}
129
+ resp, data = http.post(uri.request_uri, data, headers)
130
+
131
+ if resp and resp.body
132
+ # Extract JavaScript variables from the page
133
+ # var gDeviceNames = [""]
134
+ # var gDeviceStatus = [""]
135
+ # var gRoomNames = [""]
136
+ # var gRoomStatus = [""]
137
+ # http://rubular.com/r/UH0H4b4afF
138
+ variables = Hash.new
139
+ resp.body.scan(/var (gDeviceNames|gDeviceStatus|gRoomNames|gRoomStatus)\s*=\s*([^;]*)/).each do |variable|
140
+ variables[variable[0]] = variable[1].scan(/"([^"]*)\"/)
141
+ end
142
+ debug and (p '[Info - LightWaveRF Gem] Javascript variables ' + variables.to_s)
143
+
144
+ rooms = Array.new
145
+ # Rooms - gRoomNames is a collection of 8 values, or room names
146
+ variables['gRoomNames'].each_with_index do |(roomName), roomIndex|
147
+ # Room Status - gRoomStatus is a collection of 8 values indicating the status of the corresponding room in gRoomNames
148
+ # A: Active
149
+ # I: Inactive
150
+ if variables['gRoomStatus'] and variables['gRoomStatus'][roomIndex] and variables['gRoomStatus'][roomIndex][0] == 'A'
151
+ # Devices - gDeviceNames is a collection of 80 values, structured in blocks of ten values for each room:
152
+ # Devices 1 - 6, Mood 1 - 3, All Off
153
+ roomDevices = Array.new
154
+ deviceNamesIndexStart = roomIndex*10
155
+ variables['gDeviceNames'][(deviceNamesIndexStart)..(deviceNamesIndexStart+5)].each_with_index do |(deviceName), deviceIndex|
156
+ # Device Status - gDeviceStatus is a collection of 80 values which indicate the status/type of the corresponding device in gDeviceNames
157
+ # O: On/Off Switch
158
+ # D: Dimmer
159
+ # R: Radiator(s)
160
+ # P: Open/Close
161
+ # I: Inactive (i.e. not configured)
162
+ # m: Mood (inactive)
163
+ # M: Mood (active)
164
+ # o: All Off
165
+ deviceStatusIndex = roomIndex*10+deviceIndex
166
+ if variables['gDeviceStatus'] and variables['gDeviceStatus'][deviceStatusIndex] and variables['gDeviceStatus'][deviceStatusIndex][0] != 'I'
167
+ roomDevices << deviceName
168
+ end
169
+ end
170
+ # Create a hash of the active room and active devices and add to rooms array
171
+ if roomName and roomDevices and roomDevices.any?
172
+ rooms << {'name'=>roomName,'device'=>roomDevices}
173
+ end
174
+ end
175
+ end
176
+
177
+ # Update 'room' element in LightWaveRF Gem config file
178
+ # config['room'] is an array of hashes containing the room name and device names
179
+ # in the format { 'name' => 'Room Name', 'device' => ['Device 1', Device 2'] }
180
+ if rooms and rooms.any?
181
+ config = self.get_config
182
+ config['room'] = rooms
183
+ File.open( self.get_config_file, 'w' ) do | handle |
184
+ handle.write YAML.dump( config )
185
+ end
186
+ debug and (p '[Info - LightWaveRF Gem] Updated config with ' + rooms.size.to_s + ' room(s): ' + rooms.to_s)
187
+ else
188
+ debug and (p '[Info - LightWaveRF Gem] Unable to update config: No active rooms or devices found')
189
+ end
190
+ else
191
+ debug and (p '[Info - LightWaveRF Gem] Unable to update config: No response from Host server')
192
+ end
193
+ self.get_config
194
+ end
195
+
55
196
  # Get a cleaned up version of the rooms and devices from the config file
56
- def self.get_rooms config = { 'room' => { }}
197
+ def self.get_rooms config = { 'room' => [ ]}, debug = false
57
198
  rooms = { }
58
199
  r = 1
59
- config['room'].each do | name, devices |
60
- rooms[name] = { 'id' => 'R' + r.to_s, 'name' => name, 'device' => { }}
200
+ config['room'].each do | room |
201
+ debug and ( puts room['name'] + ' = R' + r.to_s )
202
+ rooms[room['name']] = { 'id' => 'R' + r.to_s, 'name' => room['name'], 'device' => { }}
61
203
  d = 1
62
- devices.each do | device |
204
+ room['device'].each do | device |
63
205
  # @todo possibly need to complicate this to get a device name back in here
64
- rooms[name]['device'][device] = 'D' + d.to_s
206
+ debug and ( puts ' - ' + device + ' = D' + d.to_s )
207
+ rooms[room['name']]['device'][device] = 'D' + d.to_s
65
208
  d += 1
66
209
  end
67
210
  r += 1
@@ -78,8 +221,8 @@ class LightWaveRF
78
221
  # Arguments:
79
222
  # state: (String)
80
223
  def self.get_state state = 'on'
81
- if /^\d+$/.match state.to_s
82
- state = state.to_i
224
+ if /^\d+%?$/.match state.to_s
225
+ state = state.to_i
83
226
  end
84
227
  case state
85
228
  when 'off'
@@ -107,7 +250,7 @@ class LightWaveRF
107
250
  # state: (String)
108
251
  def command room, device, state
109
252
  # @todo get the device name in here...
110
- '666,!' + room['id'] + room['device'][device] + state + '|' + room['name'] + ' ' + room['id'] + '|via @pauly'
253
+ '666,!' + room['id'] + room['device'][device] + state + '|' + room['name'] + ' ' + device + ' ' + state + '|via @pauly'
111
254
  end
112
255
 
113
256
  # Turn one of your devices on or off
@@ -121,12 +264,13 @@ class LightWaveRF
121
264
  # state: (String)
122
265
  def send room = nil, device = nil, state = 'on', debug = false
123
266
  debug and ( puts 'config is ' + self.get_config.to_s )
124
- rooms = self.class.get_rooms self.get_config
267
+ rooms = self.class.get_rooms self.get_config, debug
125
268
  state = self.class.get_state state
126
269
  if rooms[room] and device and state and rooms[room]['device'][device]
127
270
  command = self.command rooms[room], device, state
128
271
  debug and ( p 'command is ' + command )
129
- self.raw command
272
+ data = self.raw command
273
+ debug and ( p 'response is ' + data )
130
274
  else
131
275
  STDERR.puts self.usage
132
276
  end
@@ -213,7 +357,11 @@ class LightWaveRF
213
357
  debug and ( p url )
214
358
  parsed_url = URI.parse url
215
359
  http = Net::HTTP.new parsed_url.host, parsed_url.port
216
- http.use_ssl = true
360
+ begin
361
+ http.use_ssl = true
362
+ rescue
363
+ debug && ( p 'cannot use ssl' )
364
+ end
217
365
  request = Net::HTTP::Get.new parsed_url.request_uri
218
366
  response = http.request request
219
367
  doc = REXML::Document.new response.body
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lightwaverf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Paul Clarke
9
+ - Ian Perrin
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2013-02-10 00:00:00.000000000 Z
13
+ date: 2013-02-26 00:00:00.000000000 Z
13
14
  dependencies: []
14
15
  description: Interact with lightwaverf wifi link from code or the command line. Control
15
16
  your lights, heating, sockets etc. Also set up timers using a google calendar and