lightwaverf 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|