lightwaverf 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/lightwaverf +4 -0
- data/lib/lightwaverf.rb +165 -17
- 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.
|
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'].
|
23
|
-
device = self.get_config['room'][
|
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
|
-
|
47
|
-
|
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 |
|
60
|
-
|
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
|
-
|
204
|
+
room['device'].each do | device |
|
63
205
|
# @todo possibly need to complicate this to get a device name back in here
|
64
|
-
|
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
|
82
|
-
|
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'] + ' ' +
|
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
|
-
|
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.
|
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-
|
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
|