rzwaveway 0.0.2 → 0.0.3
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/lib/rzwaveway/command_classes.rb +41 -7
- data/lib/rzwaveway/events.rb +10 -0
- data/lib/rzwaveway/zwave_device.rb +14 -20
- data/lib/rzwaveway/zway.rb +39 -43
- data/rzwaveway.gemspec +5 -4
- metadata +20 -3
@@ -1,26 +1,47 @@
|
|
1
1
|
module RZWaveWay
|
2
2
|
module CommandClasses
|
3
|
+
BASIC = 32
|
3
4
|
SENSOR_BINARY = 48
|
4
5
|
MULTI_LEVEL_SENSOR = 49
|
5
6
|
CONFIGURATION = 112
|
6
7
|
BATTERY = 128
|
7
8
|
WAKEUP = 132
|
8
9
|
ALARM_SENSOR = 156
|
10
|
+
|
11
|
+
DATA = {
|
12
|
+
SENSOR_BINARY => {
|
13
|
+
'level' => 'data.1.level.value',
|
14
|
+
'lastLevelChangeTime' => 'data.1.level.updateTime'
|
15
|
+
},
|
16
|
+
WAKEUP => {
|
17
|
+
'wakeUpInterval' => 'data.interval.value',
|
18
|
+
'lastSleepTime' => 'data.lastSleep.value',
|
19
|
+
'lastWakeUpTime' => 'data.lastWakeup.value'
|
20
|
+
},
|
21
|
+
BATTERY => {
|
22
|
+
'batteryLevel' => 'data.last.value'
|
23
|
+
}
|
24
|
+
}
|
9
25
|
end
|
10
26
|
|
11
27
|
class CommandClass
|
12
28
|
include CommandClasses
|
13
29
|
attr_reader :id
|
14
|
-
|
30
|
+
attr_reader :properties
|
15
31
|
|
16
32
|
def initialize(id, data)
|
17
33
|
@id = id
|
18
|
-
@
|
34
|
+
@properties = {}
|
35
|
+
if DATA.has_key? id
|
36
|
+
DATA[id].each do |key, name|
|
37
|
+
@properties[key] = get_data(name, data)
|
38
|
+
end
|
39
|
+
end
|
19
40
|
end
|
20
41
|
|
21
|
-
def get_data name
|
42
|
+
def get_data name, data
|
22
43
|
parts = name.split '.'
|
23
|
-
result =
|
44
|
+
result = data
|
24
45
|
parts.each do | part |
|
25
46
|
raise "Could not find part '#{part}' in '#{name}'" unless result.has_key? part
|
26
47
|
result = result[part]
|
@@ -30,19 +51,32 @@ module RZWaveWay
|
|
30
51
|
|
31
52
|
def process updates, device_id
|
32
53
|
event = nil
|
33
|
-
names = updates.
|
54
|
+
names = updates.keys
|
34
55
|
case id
|
35
56
|
when WAKEUP
|
36
57
|
if names.include?("data.lastWakeup") &&
|
37
58
|
names.include?("data.lastSleep")
|
38
|
-
|
59
|
+
@properties['lastSleepTime'] = updates["data.lastSleep"]["value"]
|
60
|
+
event = AliveEvent.new(device_id, @properties['lastSleepTime'])
|
39
61
|
end
|
40
62
|
when SENSOR_BINARY
|
41
63
|
if names.include?("data.1")
|
42
|
-
|
64
|
+
@properties['lastLevelChangeTime'] = updates['data.1']["level"]["updateTime"]
|
65
|
+
@properties['level'] = updates['data.1']["level"]["value"]
|
66
|
+
event = LevelEvent.new(device_id, @properties['lastLevelChangeTime'], @properties['level'])
|
43
67
|
end
|
44
68
|
end
|
45
69
|
event
|
46
70
|
end
|
71
|
+
|
72
|
+
def process_alive_check device_id
|
73
|
+
wakeup_interval = @properties['wakeUpInterval']
|
74
|
+
last_sleep_time = @properties['lastSleepTime']
|
75
|
+
current_time = Time.now.to_i
|
76
|
+
estimated_wakeup_time = (last_sleep_time + wakeup_interval * 1.1).to_i
|
77
|
+
if(current_time > estimated_wakeup_time)
|
78
|
+
return NotAliveEvent.new(device_id, current_time - estimated_wakeup_time)
|
79
|
+
end
|
80
|
+
end
|
47
81
|
end
|
48
82
|
end
|
data/lib/rzwaveway/events.rb
CHANGED
@@ -9,6 +9,16 @@ module RZWaveWay
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
class NotAliveEvent
|
13
|
+
attr_reader :device_id
|
14
|
+
attr_reader :time_delay
|
15
|
+
|
16
|
+
def initialize device_id, time_delay
|
17
|
+
@device_id = device_id
|
18
|
+
@time_delay = time_delay
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
12
22
|
class LevelEvent
|
13
23
|
attr_reader :device_id
|
14
24
|
attr_reader :time
|
@@ -22,23 +22,8 @@ module RZWaveWay
|
|
22
22
|
|
23
23
|
def build_json
|
24
24
|
properties = {'deviceId' => @id}
|
25
|
-
|
26
|
-
properties.merge!(
|
27
|
-
'level' => @command_classes[SENSOR_BINARY].get_data('data.1.level.value'),
|
28
|
-
'lastLevelChangeTime' => @command_classes[SENSOR_BINARY].get_data('data.1.level.updateTime')
|
29
|
-
})
|
30
|
-
end
|
31
|
-
if(support_commandclass? WAKEUP)
|
32
|
-
properties.merge!( {
|
33
|
-
'wakeUpInterval' => @command_classes[WAKEUP].get_data('data.interval.value'),
|
34
|
-
'lastSleepTime' => @command_classes[WAKEUP].get_data('data.lastSleep.value'),
|
35
|
-
'lastWakeUpTime' => @command_classes[WAKEUP].get_data('data.lastWakeup.value')
|
36
|
-
})
|
37
|
-
end
|
38
|
-
if(support_commandclass? BATTERY)
|
39
|
-
properties.merge!( {
|
40
|
-
'batteryLevel' => @command_classes[BATTERY].get_data('data.last.value')
|
41
|
-
})
|
25
|
+
@command_classes.each do |cc_id, cc|
|
26
|
+
properties.merge!(cc.properties)
|
42
27
|
end
|
43
28
|
properties.to_json
|
44
29
|
end
|
@@ -52,7 +37,8 @@ module RZWaveWay
|
|
52
37
|
updates_per_commandclass = group_per_commandclass updates
|
53
38
|
updates_per_commandclass.each do |cc, values|
|
54
39
|
if @command_classes.has_key? cc
|
55
|
-
|
40
|
+
event = @command_classes[cc].process(values, @id)
|
41
|
+
events << event if event
|
56
42
|
else
|
57
43
|
$log.warn "Could not find command class: '#{cc}'"
|
58
44
|
end
|
@@ -60,14 +46,22 @@ module RZWaveWay
|
|
60
46
|
events
|
61
47
|
end
|
62
48
|
|
49
|
+
def process_alive_check
|
50
|
+
if(support_commandclass? WAKEUP)
|
51
|
+
return @command_classes[WAKEUP].process_alive_check(@id)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
63
57
|
def group_per_commandclass updates
|
64
|
-
updates_per_commandclass = Hash.new
|
58
|
+
updates_per_commandclass = Hash.new({})
|
65
59
|
updates.each do | key, value |
|
66
60
|
match_data = key.match(/\Ainstances.0.commandClasses.(\d+)./)
|
67
61
|
if match_data
|
68
62
|
command_class = match_data[1].to_i
|
69
63
|
cc_updates = updates_per_commandclass[command_class]
|
70
|
-
cc_updates
|
64
|
+
cc_updates[match_data.post_match] = value
|
71
65
|
updates_per_commandclass[command_class] = cc_updates
|
72
66
|
else
|
73
67
|
$log.warn "? #{key}" unless key.match(/\Adata./)
|
data/lib/rzwaveway/zway.rb
CHANGED
@@ -1,54 +1,49 @@
|
|
1
|
-
require '
|
1
|
+
require 'httpclient'
|
2
2
|
require 'log4r'
|
3
|
-
require 'net/http'
|
4
3
|
require 'json'
|
5
4
|
|
6
5
|
module RZWaveWay
|
7
|
-
|
6
|
+
module ZWay
|
7
|
+
extend self
|
8
8
|
include Log4r
|
9
9
|
|
10
|
-
|
10
|
+
BASE_PATH='/ZWaveAPI/Data/'
|
11
|
+
|
12
|
+
def self.init hostname
|
11
13
|
$log = Logger.new 'RZWaveWay'
|
12
14
|
outputter = Outputter.stdout
|
13
15
|
outputter.formatter = PatternFormatter.new(:pattern => "[%l] %d - %m")
|
14
16
|
$log.outputters = Outputter.stdout
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize hostname
|
18
17
|
@devices = {}
|
19
18
|
@update_time = "0"
|
20
|
-
@uri = URI::HTTP.build({:host => hostname, :port => 8083})
|
21
19
|
@event_handlers = {}
|
20
|
+
@http_client = HTTPClient.new
|
21
|
+
@base_uri="http://#{hostname}:8083"
|
22
22
|
end
|
23
23
|
|
24
24
|
def get_devices
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@update_time = results["updateTime"]
|
30
|
-
results["devices"].each do |device |
|
31
|
-
device_id = device[0].to_i
|
32
|
-
@devices[device_id] = ZWaveDevice.new(device_id, device[1]) if device_id > 1
|
33
|
-
end
|
34
|
-
@devices
|
35
|
-
else
|
36
|
-
pp response.code
|
37
|
-
return {}
|
25
|
+
results = http_post_request
|
26
|
+
results["devices"].each do |device_id,device_data_tree|
|
27
|
+
device_id = device_id.to_i
|
28
|
+
@devices[device_id] = ZWaveDevice.new(device_id, device_data_tree) if device_id > 1
|
38
29
|
end
|
30
|
+
@devices
|
39
31
|
end
|
40
32
|
|
41
33
|
def process_events
|
42
34
|
events = []
|
43
|
-
updates =
|
35
|
+
updates = http_post_request
|
44
36
|
updates_per_device = group_per_device updates
|
45
37
|
updates_per_device.each do | id, updates |
|
46
38
|
if @devices[id]
|
47
|
-
|
39
|
+
device_events = @devices[id].process updates
|
40
|
+
events += device_events unless device_events.empty?
|
48
41
|
else
|
49
42
|
$log.warn "Could not find device with id '#{id}'"
|
50
43
|
end
|
51
44
|
end
|
45
|
+
alive_events = check_not_alive_devices
|
46
|
+
events += alive_events unless alive_events.empty?
|
52
47
|
events.each do |event|
|
53
48
|
handler = @event_handlers[event.class]
|
54
49
|
if handler
|
@@ -60,27 +55,14 @@ module RZWaveWay
|
|
60
55
|
events
|
61
56
|
end
|
62
57
|
|
63
|
-
def get_updates
|
64
|
-
@uri.path = "/ZWaveAPI/Data/#{@update_time}"
|
65
|
-
response = http_post_request
|
66
|
-
if response.is_a?(Net::HTTPSuccess)
|
67
|
-
results = JSON.parse response.body
|
68
|
-
@update_time = results.delete("updateTime")
|
69
|
-
return results
|
70
|
-
else
|
71
|
-
pp response.code
|
72
|
-
return {}
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
58
|
def group_per_device updates
|
77
|
-
updates_per_device = Hash.new
|
59
|
+
updates_per_device = Hash.new({})
|
78
60
|
updates.each do | key, value |
|
79
61
|
match_data = key.match(/\Adevices\.(\d+)\./)
|
80
62
|
if match_data
|
81
63
|
device_id = match_data[1].to_i
|
82
64
|
device_updates = updates_per_device[device_id]
|
83
|
-
device_updates
|
65
|
+
device_updates[match_data.post_match] = value
|
84
66
|
updates_per_device[device_id] = device_updates
|
85
67
|
else
|
86
68
|
$log.warn "? #{key}"
|
@@ -89,12 +71,26 @@ module RZWaveWay
|
|
89
71
|
updates_per_device
|
90
72
|
end
|
91
73
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
74
|
+
def check_not_alive_devices
|
75
|
+
events = []
|
76
|
+
@devices.values.each do |device|
|
77
|
+
event = device.process_alive_check
|
78
|
+
events << event if event
|
79
|
+
end
|
80
|
+
events
|
81
|
+
end
|
95
82
|
|
96
|
-
|
97
|
-
|
83
|
+
def http_post_request
|
84
|
+
results = {}
|
85
|
+
url = @base_uri + BASE_PATH + "#{@update_time}"
|
86
|
+
response = @http_client.post(url)
|
87
|
+
if response.ok?
|
88
|
+
results = JSON.parse response.body
|
89
|
+
@update_time = results.delete("updateTime")
|
90
|
+
else
|
91
|
+
$log.error(response.reason)
|
92
|
+
end
|
93
|
+
results
|
98
94
|
end
|
99
95
|
|
100
96
|
def on_event (event, &listener)
|
data/rzwaveway.gemspec
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rzwaveway"
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.3"
|
4
4
|
s.authors = ["Vincent Touchard"]
|
5
5
|
s.date = %q{2014-02-08}
|
6
6
|
s.summary = 'ZWave API for ZWay'
|
7
7
|
s.description = 'A Ruby API to use the Razberry ZWave ZWay interface'
|
8
|
-
s.email = 'vincentoo@yahoo.com'
|
9
|
-
s.homepage = 'https://github.com/rzwaveway'
|
8
|
+
s.email = 'vincentoo.ignore@yahoo.com'
|
9
|
+
s.homepage = 'https://github.com/touchardv/rzwaveway'
|
10
10
|
s.files = `git ls-files`.split("\n")
|
11
11
|
s.has_rdoc = false
|
12
12
|
|
13
13
|
dependencies = [
|
14
|
-
[:runtime,
|
14
|
+
[:runtime, "log4r", "~> 1.1.10"],
|
15
|
+
[:runtime, "httpclient", "~> 2.3.4.1"]
|
15
16
|
]
|
16
17
|
|
17
18
|
dependencies.each do |type, name, version|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rzwaveway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -27,8 +27,24 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 1.1.10
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: httpclient
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.3.4.1
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.3.4.1
|
30
46
|
description: A Ruby API to use the Razberry ZWave ZWay interface
|
31
|
-
email: vincentoo@yahoo.com
|
47
|
+
email: vincentoo.ignore@yahoo.com
|
32
48
|
executables: []
|
33
49
|
extensions: []
|
34
50
|
extra_rdoc_files: []
|
@@ -42,7 +58,7 @@ files:
|
|
42
58
|
- lib/rzwaveway/zwave_device.rb
|
43
59
|
- lib/rzwaveway/zway.rb
|
44
60
|
- rzwaveway.gemspec
|
45
|
-
homepage: https://github.com/rzwaveway
|
61
|
+
homepage: https://github.com/touchardv/rzwaveway
|
46
62
|
licenses: []
|
47
63
|
post_install_message:
|
48
64
|
rdoc_options: []
|
@@ -67,3 +83,4 @@ signing_key:
|
|
67
83
|
specification_version: 3
|
68
84
|
summary: ZWave API for ZWay
|
69
85
|
test_files: []
|
86
|
+
has_rdoc: false
|