rzwaveway 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- @data
30
+ attr_reader :properties
15
31
 
16
32
  def initialize(id, data)
17
33
  @id = id
18
- @data = data
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 = @data
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.collect { |x| x[0]}
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
- event = AliveEvent.new(device_id, updates[1][1]["value"])
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
- event = LevelEvent.new(device_id,updates[0][1]["level"]["updateTime"], updates[0][1]["level"]["value"])
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
@@ -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
- if(support_commandclass? SENSOR_BINARY)
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
- events << (@command_classes[cc].process(values, @id))
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 << [match_data.post_match, value]
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./)
@@ -1,54 +1,49 @@
1
- require 'uri'
1
+ require 'httpclient'
2
2
  require 'log4r'
3
- require 'net/http'
4
3
  require 'json'
5
4
 
6
5
  module RZWaveWay
7
- class ZWay
6
+ module ZWay
7
+ extend self
8
8
  include Log4r
9
9
 
10
- def self.init
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
- @uri.path = "/ZWaveAPI/Data/#{@update_time}"
26
- response = http_post_request
27
- if response.code == "200"
28
- results = JSON.parse response.body
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 = get_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
- events.concat (@devices[id].process updates)
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 << [match_data.post_match, value]
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 http_post_request
93
- http = Net::HTTP.new(@uri.host, @uri.port)
94
- http.use_ssl = false
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
- request = Net::HTTP::Post.new(@uri.path)
97
- http.request(request)
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.2"
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, "log4r", "~> 1.1.10"]
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.2
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