rzwaveway 0.0.11 → 0.0.13

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 01e99f245086e41fbeca9e16d6c0c6867324906d
4
- data.tar.gz: adc57ec22b54fb1f084b2adc44bbcde9835fb3c8
3
+ metadata.gz: 6f5e0b677ce1728466c714be10191c2fea92bc97
4
+ data.tar.gz: b07f33865fb9ac752453ef12efcccfa3f206d120
5
5
  SHA512:
6
- metadata.gz: 54c2f9b32d733c49a8e5022e452cc8d16c828f9b7eab5da5436db7dab2c15b73f7391378895f163b17bc6558a46dd13c3330e033a255d9b8fc23d0a973264687
7
- data.tar.gz: 7c1b8a78ebd3e5942b86e576b9e2323089b865c73dff680c7edd031c0c096e50afed5aa469db3853523b8911e640a53567e2ad8affbee8b55f10652f934e6486
6
+ metadata.gz: e0043ffd5ae35ceaaea940771f828e1662256d9a145ae9440dcd7d53a03f4ce604ec5a7ebdfc7ec09855062bdbb24729865638f95f7c56d665a56341aec8dba5
7
+ data.tar.gz: b9d79401b008fe87b9ba484602fe4c7c7f3027d7dcc7ae210c328cb7fa6ebca8e29f632b27ec0dce053cc909283116652920c231230436e8ae8d0b23f34427c5
data/README.md CHANGED
@@ -10,7 +10,7 @@ A Ruby library for communicating with the ZWave protocol stack from ZWay, runnin
10
10
  require 'rzwaveway'
11
11
 
12
12
  z_way = RZWaveWay::ZWay.instance
13
- z_way.setup('192.168.1.123')
13
+ z_way.setup(hostname: '192.168.1.123', port: 8083)
14
14
  z_way.start
15
15
  ```
16
16
 
@@ -27,7 +27,7 @@ z_way.on_event(RZWaveWay::AliveEvent) {|event| puts "A device woke up" }
27
27
  z_way.on_event(RZWaveWay::LevelEvent) {|event| puts "A device got triggered" }
28
28
  while true do
29
29
  sleep 5
30
- z_way.process_events
30
+ z_way.process
31
31
  end
32
32
  ```
33
33
 
@@ -40,6 +40,6 @@ or
40
40
 
41
41
  ```
42
42
  switch = z_way.devices[4]
43
- switch.SwitchBinary.set(1)
44
- switch.SwitchBinary.set(0)
43
+ switch.SwitchBinary.level = 1
44
+ switch.SwitchBinary.level = 0
45
45
  ```
@@ -1,6 +1,8 @@
1
+ require_relative 'rzwaveway/logger'
2
+ require_relative 'rzwaveway/property'
3
+ require_relative 'rzwaveway/properties_cache'
1
4
  require_relative 'rzwaveway/command_classes'
2
5
  require_relative 'rzwaveway/events'
3
- require_relative 'rzwaveway/logger'
4
6
  require_relative 'rzwaveway/zwave_device'
5
7
  require_relative 'rzwaveway/zway'
6
8
  require_relative 'rzwaveway/extensions'
@@ -1,29 +1,40 @@
1
1
  module RZWaveWay
2
- module CommandClass
2
+ class CommandClass
3
+ include Logger
4
+ include PropertiesCache
5
+
3
6
  BASIC = 32
4
7
  SWITCH_BINARY = 37
5
8
  SWITCH_MULTI_LEVEL = 38
6
9
  SENSOR_BINARY = 48
7
10
  SENSOR_MULTI_LEVEL = 49
11
+ METER = 50
8
12
  CONFIGURATION = 112
9
13
  ALARM = 113
14
+ NOTIFICATION = ALARM
10
15
  MANUFACTURER_SPECIFIC = 114
11
16
  BATTERY = 128
12
17
  WAKEUP = 132
13
18
  ASSOCIATION = 133
14
19
  VERSION = 134
20
+ SECURITY = 152
15
21
  ALARM_SENSOR = 156
16
22
 
17
- private
23
+ attr_reader :device
24
+
25
+ def initialize(device)
26
+ @device = device
27
+ end
28
+
29
+ def build_from(data)
30
+ end
18
31
 
19
- def find(name, data)
20
- parts = name.split '.'
21
- result = data
22
- parts.each do | part |
23
- raise "Could not find part '#{part}' in '#{name}'" unless result.has_key? part
24
- result = result[part]
25
- end
26
- result
32
+ def name
33
+ self.class.name.split('::').last
34
+ end
35
+
36
+ def to_s
37
+ name
27
38
  end
28
39
  end
29
40
  end
@@ -1,6 +1,8 @@
1
1
  require 'singleton'
2
2
 
3
3
  require_relative 'command_class'
4
+ require_relative 'command_classes/alarm'
5
+ require_relative 'command_classes/alarm_sensor'
4
6
  require_relative 'command_classes/battery'
5
7
  require_relative 'command_classes/switch_binary'
6
8
  require_relative 'command_classes/switch_multi_level'
@@ -9,36 +11,48 @@ require_relative 'command_classes/wake_up'
9
11
 
10
12
  module RZWaveWay
11
13
  module CommandClasses
12
- class Dummy
14
+ class Unsupported
13
15
  include Singleton
14
16
 
15
- def initialize
17
+ def build_from(data)
16
18
  end
17
19
 
18
20
  def process(updates)
19
21
  end
22
+
23
+ def save_properties
24
+ end
25
+
26
+ def to_hash
27
+ {}
28
+ end
29
+
30
+ def to_s
31
+ 'Unsupported'
32
+ end
20
33
  end
21
34
 
22
35
  class Factory
23
36
  include Singleton
24
- include CommandClass
25
37
 
26
- def instantiate(id, data, device)
38
+ def instantiate(id, device)
27
39
  if CLASSES.has_key? id
28
- return CLASSES[id].new(data, device)
40
+ CLASSES[id].new(device)
29
41
  else
30
- return CommandClasses::Dummy.instance
42
+ CommandClasses::Unsupported.instance
31
43
  end
32
44
  end
33
45
 
34
46
  private
35
47
 
36
48
  CLASSES = {
37
- SWITCH_BINARY => CommandClasses::SwitchBinary,
38
- SWITCH_MULTI_LEVEL => CommandClasses::SwitchMultiLevel,
39
- SENSOR_BINARY => CommandClasses::SensorBinary,
40
- WAKEUP => CommandClasses::WakeUp,
41
- BATTERY => CommandClasses::Battery
49
+ CommandClass::SWITCH_BINARY => CommandClasses::SwitchBinary,
50
+ CommandClass::SWITCH_MULTI_LEVEL => CommandClasses::SwitchMultiLevel,
51
+ CommandClass::SENSOR_BINARY => CommandClasses::SensorBinary,
52
+ CommandClass::WAKEUP => CommandClasses::WakeUp,
53
+ CommandClass::ALARM => CommandClasses::Alarm,
54
+ CommandClass::ALARM_SENSOR => CommandClasses::AlarmSensor,
55
+ CommandClass::BATTERY => CommandClasses::Battery
42
56
  }
43
57
  end
44
58
  end
@@ -0,0 +1,43 @@
1
+ module RZWaveWay
2
+ module CommandClasses
3
+ class Alarm < CommandClass
4
+
5
+ def process(updates)
6
+ updates.each do |key, value|
7
+ if key == 'data.V1event'
8
+ alarm_type = value['alarmType']['value']
9
+ yield AlarmEvent.new(device_id: device.id,
10
+ time: value['updateTime'],
11
+ alarm_type: ALARM_TYPES[alarm_type],
12
+ level: value['level']['value'])
13
+ else
14
+ match_data = key.match(/^data.(\d+)/)
15
+ if match_data
16
+ alarm_type = match_data[1].to_i
17
+ yield AlarmEvent.new(device_id: device.id,
18
+ time: value['updateTime'],
19
+ alarm_type: ALARM_TYPES[alarm_type],
20
+ level: value['event']['value'])
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ ALARM_TYPES = {
29
+ 0x01 => :smoke,
30
+ 0x02 => :co,
31
+ 0x03 => :co2,
32
+ 0x04 => :heat,
33
+ 0x05 => :water,
34
+ 0x06 => :access_control,
35
+ 0x07 => :burglar,
36
+ 0x08 => :power_management,
37
+ 0x09 => :system,
38
+ 0x0a => :emergency,
39
+ 0x0b => :clock
40
+ }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ module RZWaveWay
2
+ module CommandClasses
3
+ class AlarmSensor < CommandClass
4
+ GENERAL_PURPOSE = 0x00
5
+ SMOKE = 0x01
6
+ CO = 0x02
7
+ CO2 = 0x03
8
+ HEAT = 0x04
9
+ WATER_LEAK = 0x05
10
+
11
+ def process(updates)
12
+ log.info updates
13
+ nil
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,28 +1,24 @@
1
1
  module RZWaveWay
2
2
  module CommandClasses
3
- class Battery
4
- include CommandClass
3
+ class Battery < CommandClass
5
4
 
6
- def initialize(data, device)
7
- @device = device
8
- @device.add_property(name: :battery_level,
9
- value: find('data.last.value', data),
10
- update_time: find('data.last.updateTime', data))
5
+ def build_from(data)
6
+ define_property(:battery_level, 'data.last', true, data)
11
7
  end
12
8
 
13
9
  def process(updates)
14
10
  if updates.keys.include?('data.last')
15
11
  data = updates['data.last']
16
12
  value = data['value']
17
- updateTime = data['updateTime']
18
- if @device.update_property(:battery_level, value, updateTime)
19
- return BatteryValueEvent.new(@device.id, updateTime, value)
13
+ update_time = data['updateTime']
14
+ if @properties[:battery_level].update(value, update_time)
15
+ yield BatteryValueEvent.new(device_id: device.id, time: update_time, value: value)
20
16
  end
21
17
  end
22
18
  end
23
19
 
24
- def get
25
- RZWaveWay::ZWay.instance.execute(@device.id, BATTERY, :Get)
20
+ def refresh
21
+ RZWaveWay::ZWay.instance.execute(device.id, BATTERY, :Get)
26
22
  end
27
23
  end
28
24
  end
@@ -1,32 +1,24 @@
1
1
  module RZWaveWay
2
2
  module CommandClasses
3
- class SensorBinary
4
- include CommandClass
3
+ class SensorBinary < CommandClass
5
4
 
6
- def initialize(data, device)
7
- @device = device
8
- @device.add_property(name: :level,
9
- value: find('data.1.level.value', data),
10
- update_time: find('data.1.level.updateTime', data))
5
+ def build_from(data)
6
+ define_property(:level, 'data.1.level', true, data)
11
7
  end
12
8
 
13
9
  def process(updates)
14
10
  if updates.keys.include?('data.1')
15
11
  data = updates['data.1']['level']
16
12
  value = data['value']
17
- updateTime = data['updateTime']
18
- if @device.update_property(:level, value, updateTime)
19
- return LevelEvent.new(@device.id, updateTime, value)
13
+ update_time = data['updateTime']
14
+ if @properties[:level].update(value, update_time)
15
+ yield LevelEvent.new(device_id: device.id, time: update_time, level: value)
20
16
  end
21
17
  end
22
18
  end
23
19
 
24
- def level
25
- @device.get_property(:level)[0]
26
- end
27
-
28
- def get
29
- RZWaveWay::ZWay.instance.execute(@device.id, SENSOR_BINARY, :Get)
20
+ def refresh
21
+ RZWaveWay::ZWay.instance.execute(device.id, SENSOR_BINARY, :Get)
30
22
  end
31
23
  end
32
24
  end
@@ -1,37 +1,28 @@
1
1
  module RZWaveWay
2
2
  module CommandClasses
3
- class SwitchBinary
4
- include CommandClass
3
+ class SwitchBinary < CommandClass
5
4
 
6
- def initialize(data, device)
7
- @device = device
8
- @device.add_property(name: :level,
9
- value: find('data.level.value', data),
10
- update_time: find('data.level.updateTime', data),
11
- read_only: false)
5
+ def build_from(data)
6
+ define_property(:level, 'data.level', false, data)
12
7
  end
13
8
 
14
9
  def process(updates)
15
10
  if updates.keys.include?('data.level')
16
11
  data = updates['data.level']
17
12
  value = data['value']
18
- updateTime = data['updateTime']
19
- if @device.update_property(:level, value, updateTime)
20
- return LevelEvent.new(@device.id, updateTime, value)
13
+ update_time = data['updateTime']
14
+ if @properties[:level].update(value, update_time)
15
+ yield LevelEvent.new(device_id: device.id, time: update_time, level: value)
21
16
  end
22
17
  end
23
18
  end
24
19
 
25
- def level
26
- @device.get_property(:level)[0]
20
+ def level=(value)
21
+ RZWaveWay::ZWay.instance.execute(device.id, SWITCH_BINARY, :Set, value)
27
22
  end
28
23
 
29
- def get
30
- RZWaveWay::ZWay.instance.execute(@device.id, SWITCH_BINARY, :Get)
31
- end
32
-
33
- def set(value)
34
- RZWaveWay::ZWay.instance.execute(@device.id, SWITCH_BINARY, :Set, value)
24
+ def refresh
25
+ RZWaveWay::ZWay.instance.execute(device.id, SWITCH_BINARY, :Get)
35
26
  end
36
27
  end
37
28
  end
@@ -1,37 +1,28 @@
1
1
  module RZWaveWay
2
2
  module CommandClasses
3
- class SwitchMultiLevel
4
- include CommandClass
3
+ class SwitchMultiLevel < CommandClass
5
4
 
6
- def initialize(data, device)
7
- @device = device
8
- @device.add_property(name: :level,
9
- value: find('data.level.value', data),
10
- update_time: find('data.level.updateTime', data),
11
- read_only: false)
5
+ def build_from(data)
6
+ define_property(:level, 'data.level', false, data)
12
7
  end
13
8
 
14
9
  def process(updates)
15
10
  if updates.keys.include?('data.level')
16
11
  data = updates['data.level']
17
12
  value = data['value']
18
- updateTime = data['updateTime']
19
- if @device.update_property(:level, value, updateTime)
20
- return MultiLevelEvent.new(@device.id, updateTime, value)
13
+ update_time = data['updateTime']
14
+ if @properties[:level].update(value, update_time)
15
+ yield MultiLevelEvent.new(device_id: device.id, time: update_time, level: value)
21
16
  end
22
17
  end
23
18
  end
24
19
 
25
- def level
26
- @device.get_property(:level)[0]
20
+ def level=(value)
21
+ RZWaveWay::ZWay.instance.execute(device.id, SWITCH_MULTI_LEVEL, :Set, value)
27
22
  end
28
23
 
29
- def get
30
- RZWaveWay::ZWay.instance.execute(@device.id, SWITCH_MULTI_LEVEL, :Get)
31
- end
32
-
33
- def set(value)
34
- RZWaveWay::ZWay.instance.execute(@device.id, SWITCH_MULTI_LEVEL, :Set, value)
24
+ def refresh
25
+ RZWaveWay::ZWay.instance.execute(device.id, SWITCH_MULTI_LEVEL, :Get)
35
26
  end
36
27
  end
37
28
  end
@@ -1,44 +1,41 @@
1
1
  module RZWaveWay
2
2
  module CommandClasses
3
- class WakeUp
4
- include CommandClass
3
+ class WakeUp < CommandClass
5
4
 
6
- def initialize(data, device)
7
- @device = device
8
- wakeup_interval = find('data.interval.value', data)
9
- last_wakeup_time = find('data.lastWakeup.value', data)
10
- last_sleep_time = find('data.lastSleep.value', data)
5
+ def build_from(data)
6
+ define_property(:contact_frequency, 'data.interval', true, data)
7
+ define_property(:last_sleep_time, 'data.lastSleep', true, data)
8
+ define_property(:last_wakeup_time, 'data.lastWakeup', true, data)
11
9
 
12
- @device.add_property(name: :wakeup_interval,
13
- value: wakeup_interval,
14
- update_time: find('data.interval.updateTime', data),
15
- internal: true)
16
- @device.add_property(name: :wakeup_last_sleep_time,
17
- value: last_sleep_time,
18
- update_time: find('data.lastSleep.updateTime', data),
19
- internal: true)
20
- @device.add_property(name: :wakeup_last_wakeup_time,
21
- value: last_wakeup_time,
22
- update_time: find('data.lastWakeup.updateTime', data),
23
- internal: true)
10
+ device.notify_contacted(find('data.lastWakeup.value', data))
11
+ end
12
+
13
+ def missed_contact_count(time = Time.now)
14
+ (elapsed_seconds_since_last_contact(time) / contact_frequency).to_i
15
+ end
24
16
 
25
- @device.contact_frequency = wakeup_interval
26
- @device.notify_contacted(last_wakeup_time)
17
+ def on_time?(time = Time.now)
18
+ elapsed_seconds_since_last_contact(time) < (contact_frequency * 1.2)
27
19
  end
28
20
 
29
21
  def process(updates)
30
22
  if updates.keys.include?('data.lastWakeup')
31
23
  data = updates['data.lastWakeup']
32
24
  value = data['value']
33
- updateTime = data['updateTime']
34
- if @device.update_property(:wakeup_last_wakeup_time, value, updateTime)
35
- @device.notify_contacted(value)
36
- return AliveEvent.new(@device.id, value)
25
+ update_time = data['updateTime']
26
+ if @properties[:last_wakeup_time].update(value, update_time)
27
+ device.notify_contacted(value)
37
28
  end
38
29
  end
39
-
30
+ nil
40
31
  # TODO handle change of wake up interval value?
41
32
  end
33
+
34
+ private
35
+
36
+ def elapsed_seconds_since_last_contact(time)
37
+ time.to_i - device.last_contact_time
38
+ end
42
39
  end
43
40
  end
44
41
  end