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.
@@ -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