Skip to content

Commit

Permalink
Merge pull request #37 from tschamm/master
Browse files Browse the repository at this point in the history
Make nodes aware of their serial_number.
  • Loading branch information
Julius2342 committed Apr 26, 2020
2 parents 46d2e55 + f778af5 commit da4761d
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 74 deletions.
6 changes: 5 additions & 1 deletion pyvlx/frames/frame_get_node_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def __str__(self):


class FrameGetNodeInformationNotification(FrameBase):
"""Frame for notification of note information request."""
"""Frame for notification of node information request."""

PAYLOAD_LEN = 124

Expand Down Expand Up @@ -103,6 +103,10 @@ def serial_number(self):
"""Property for serial number in a human readable way."""
return ":".join("{:02x}".format(c) for c in self._serial_number)

@serial_number.setter
def serial_number(self, serial_number):
self._serial_number = serial_number

def get_payload(self):
"""Return Payload."""
payload = bytes()
Expand Down
16 changes: 10 additions & 6 deletions pyvlx/lightening_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
class LighteningDevice(Node):
"""Meta class for turning on device with one main parameter for intensity."""

def __init__(self, pyvlx, node_id, name):
def __init__(self, pyvlx, node_id, name, serial_number):
"""Initialize turning on device.
Parameters:
* pyvlx: PyVLX object
* node_id: internal id for addressing nodes.
Provided by KLF 200 device
* name: node name
* serial_number: serial number of the node.
"""
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name)
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name, serial_number=serial_number)
self.intensity = Intensity()

async def set_intensity(self, intensity, wait_for_completion=True):
Expand Down Expand Up @@ -68,23 +69,26 @@ async def turn_off(self, wait_for_completion=True):
class Light(LighteningDevice):
"""Light object."""

def __init__(self, pyvlx, node_id, name):
def __init__(self, pyvlx, node_id, name, serial_number):
"""Initialize Light class.
Parameters:
* pyvlx: PyVLX object
* node_id: internal id for addressing nodes.
Provided by KLF 200 device
* name: node name
* serial_number: serial number of the node.
"""
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name)
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name, serial_number=serial_number)

def __str__(self):
"""Return object as readable string."""
return '<{} name="{}" ' \
'node_id="{}"/>' \
'node_id="{}" ' \
'serial_number="{}"/>' \
.format(
type(self).__name__,
self.name,
self.node_id)
self.node_id,
self.serial_number)
9 changes: 6 additions & 3 deletions pyvlx/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
class Node:
"""Class for node abstraction."""

def __init__(self, pyvlx, node_id, name):
def __init__(self, pyvlx, node_id, name, serial_number):
"""Initialize Node object."""
self.pyvlx = pyvlx
self.node_id = node_id
self.name = name
self.serial_number = serial_number
self.device_updated_cbs = []

def register_device_updated_cb(self, device_updated_cb):
Expand Down Expand Up @@ -44,11 +45,13 @@ async def rename(self, name):
def __str__(self):
"""Return object as readable string."""
return '<{} name="{}" ' \
'node_id="{}"/>' \
'node_id="{}" ' \
'serial_number="{}"/>' \
.format(
type(self).__name__,
self.name,
self.node_id)
self.node_id,
self.serial_number)

def __eq__(self, other):
"""Equal operator."""
Expand Down
22 changes: 11 additions & 11 deletions pyvlx/node_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,32 @@ def convert_frame_to_node(pyvlx, frame):
"""Convert FrameGet[All]Node[s]InformationNotification into Node object."""
# pylint: disable=too-many-return-statements
if frame.node_type == NodeTypeWithSubtype.WINDOW_OPENER:
return Window(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, rain_sensor=False)
return Window(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number, rain_sensor=False)
if frame.node_type == NodeTypeWithSubtype.WINDOW_OPENER_WITH_RAIN_SENSOR:
return Window(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, rain_sensor=True)
return Window(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number, rain_sensor=True)
if frame.node_type == NodeTypeWithSubtype.ROLLER_SHUTTER or \
frame.node_type == NodeTypeWithSubtype.DUAL_ROLLER_SHUTTER:
return RollerShutter(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return RollerShutter(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)
if frame.node_type == NodeTypeWithSubtype.INTERIOR_VENETIAN_BLIND or \
frame.node_type == NodeTypeWithSubtype.VERTICAL_INTERIOR_BLINDS or \
frame.node_type == NodeTypeWithSubtype.EXTERIOR_VENETIAN_BLIND or \
frame.node_type == NodeTypeWithSubtype.LOUVER_BLIND:
return Blind(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return Blind(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)
if frame.node_type == NodeTypeWithSubtype.VERTICAL_EXTERIOR_AWNING or \
frame.node_type == NodeTypeWithSubtype.HORIZONTAL_AWNING:
return Awning(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return Awning(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)
if frame.node_type == NodeTypeWithSubtype.ON_OFF_SWITCH:
return OnOffSwitch(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return OnOffSwitch(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)
if frame.node_type == NodeTypeWithSubtype.GARAGE_DOOR_OPENER:
return GarageDoor(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return GarageDoor(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)
if frame.node_type == NodeTypeWithSubtype.GATE_OPENER:
return Gate(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return Gate(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)
if frame.node_type == NodeTypeWithSubtype.GATE_OPENER_ANGULAR_POSITION:
return Gate(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return Gate(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)
if frame.node_type == NodeTypeWithSubtype.BLADE_OPENER:
return Blade(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return Blade(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)
if frame.node_type == NodeTypeWithSubtype.LIGHT:
return Light(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name)
return Light(pyvlx=pyvlx, node_id=frame.node_id, name=frame.name, serial_number=frame.serial_number)

PYVLXLOG.warning("%s not implemented", frame.node_type)
return None
4 changes: 2 additions & 2 deletions pyvlx/on_off_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
class OnOffSwitch(Node):
"""Class for controlling on-off switches."""

def __init__(self, pyvlx, node_id, name):
def __init__(self, pyvlx, node_id, name, serial_number):
"""Initialize opening device."""
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name)
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name, serial_number=serial_number)
self.parameter = SwitchParameter()

async def set_state(self, parameter):
Expand Down
16 changes: 10 additions & 6 deletions pyvlx/opening_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
class OpeningDevice(Node):
"""Meta class for opening device with one main parameter for position."""

def __init__(self, pyvlx, node_id, name):
def __init__(self, pyvlx, node_id, name, serial_number):
"""Initialize opening device.
Parameters:
* pyvlx: PyVLX object
* node_id: internal id for addressing nodes.
Provided by KLF 200 device
* name: node name
* serial_number: serial number of the node.
"""
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name)
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name, serial_number=serial_number)
self.position = Position()

async def set_position(self, position, wait_for_completion=True):
Expand Down Expand Up @@ -80,29 +81,32 @@ async def stop(self, wait_for_completion=True):
class Window(OpeningDevice):
"""Window object."""

def __init__(self, pyvlx, node_id, name, rain_sensor=False):
def __init__(self, pyvlx, node_id, name, serial_number, rain_sensor=False):
"""Initialize Window class.
Parameters:
* pyvlx: PyVLX object
* node_id: internal id for addressing nodes.
Provided by KLF 200 device
* name: node name
* serial_number: serial number of the node.
* rain_sensor: set if device is equipped with a
rain sensor.
"""
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name)
super().__init__(pyvlx=pyvlx, node_id=node_id, name=name, serial_number=serial_number)
self.rain_sensor = rain_sensor

def __str__(self):
"""Return object as readable string."""
return '<{} name="{}" ' \
'node_id="{}" rain_sensor={}/>' \
'node_id="{}" rain_sensor={} ' \
'serial_number="{}"/>' \
.format(
type(self).__name__,
self.name,
self.node_id, self.rain_sensor)
self.node_id, self.rain_sensor,
self.serial_number)


class Blind(OpeningDevice):
Expand Down
12 changes: 6 additions & 6 deletions test/lightening_device_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ class TestLighteningDevice(unittest.TestCase):
def test_light_str(self):
"""Test string representation of Light object."""
pyvlx = PyVLX()
light = Light(pyvlx=pyvlx, node_id=23, name='Test Light')
self.assertEqual(str(light), '<Light name="Test Light" node_id="23"/>')
light = Light(pyvlx=pyvlx, node_id=23, name='Test Light', serial_number='aa:bb:aa:bb:aa:bb:aa:23')
self.assertEqual(str(light), '<Light name="Test Light" node_id="23" serial_number="aa:bb:aa:bb:aa:bb:aa:23"/>')

def test_eq(self):
"""Testing eq method with positive results."""
pyvlx = PyVLX()
node1 = Light(pyvlx=pyvlx, node_id=23, name='xxx')
node2 = Light(pyvlx=pyvlx, node_id=23, name='xxx')
node1 = Light(pyvlx=pyvlx, node_id=23, name='xxx', serial_number='aa:bb:aa:bb:aa:bb:aa:23')
node2 = Light(pyvlx=pyvlx, node_id=23, name='xxx', serial_number='aa:bb:aa:bb:aa:bb:aa:23')
self.assertEqual(node1, node2)

def test_nq(self):
"""Testing eq method with negative results."""
pyvlx = PyVLX()
node1 = Light(pyvlx=pyvlx, node_id=23, name='xxx')
node2 = Light(pyvlx=pyvlx, node_id=24, name='xxx')
node1 = Light(pyvlx=pyvlx, node_id=23, name='xxx', serial_number='aa:bb:aa:bb:aa:bb:aa:23')
node2 = Light(pyvlx=pyvlx, node_id=24, name='xxx', serial_number='aa:bb:aa:bb:aa:bb:aa:23')
self.assertNotEqual(node1, node2)
22 changes: 15 additions & 7 deletions test/node_helper_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,66 +18,73 @@ def test_window(self):
frame.node_id = 23
frame.name = "Fnord23"
frame.node_type = NodeTypeWithSubtype.WINDOW_OPENER
frame.serial_number = bytes.fromhex('aa bb aa bb aa bb aa 23')
pyvlx = PyVLX()
node = convert_frame_to_node(pyvlx, frame)
self.assertEqual(node, Window(pyvlx=pyvlx, name="Fnord23", node_id=23))
self.assertEqual(node, Window(pyvlx=pyvlx, name="Fnord23", node_id=23, serial_number='aa:bb:aa:bb:aa:bb:aa:23'))

def test_window_with_rain_sensor(self):
"""Test convert_frame_to_node with window with rain sensor."""
frame = FrameGetNodeInformationNotification()
frame.node_id = 23
frame.name = "Fnord23"
frame.node_type = NodeTypeWithSubtype.WINDOW_OPENER_WITH_RAIN_SENSOR
frame.serial_number = bytes.fromhex('aa bb aa bb aa bb aa 23')
pyvlx = PyVLX()
node = convert_frame_to_node(pyvlx, frame)
self.assertEqual(node, Window(pyvlx=pyvlx, name="Fnord23", node_id=23, rain_sensor=True))
self.assertEqual(node, Window(pyvlx=pyvlx, name="Fnord23", node_id=23, rain_sensor=True, serial_number='aa:bb:aa:bb:aa:bb:aa:23'))

def test_blind(self):
"""Test convert_frame_to_node with blind."""
frame = FrameGetNodeInformationNotification()
frame.node_id = 23
frame.name = "Fnord23"
frame.node_type = NodeTypeWithSubtype.INTERIOR_VENETIAN_BLIND
frame.serial_number = bytes.fromhex('aa bb aa bb aa bb aa 23')
pyvlx = PyVLX()
node = convert_frame_to_node(pyvlx, frame)
self.assertEqual(node, Blind(pyvlx=pyvlx, name="Fnord23", node_id=23))
self.assertEqual(node, Blind(pyvlx=pyvlx, name="Fnord23", node_id=23, serial_number='aa:bb:aa:bb:aa:bb:aa:23'))

def test_roller_shutter(self):
"""Test convert_frame_to_node roller shutter."""
frame = FrameGetNodeInformationNotification()
frame.node_id = 23
frame.name = "Fnord23"
frame.node_type = NodeTypeWithSubtype.ROLLER_SHUTTER
frame.serial_number = bytes.fromhex('aa bb aa bb aa bb aa 23')
pyvlx = PyVLX()
node = convert_frame_to_node(pyvlx, frame)
self.assertEqual(node, RollerShutter(pyvlx=pyvlx, name="Fnord23", node_id=23))
self.assertEqual(node, RollerShutter(pyvlx=pyvlx, name="Fnord23", node_id=23, serial_number='aa:bb:aa:bb:aa:bb:aa:23'))

def test_garage_door(self):
"""Test convert_frame_to_node garage door."""
frame = FrameGetNodeInformationNotification()
frame.node_id = 23
frame.name = "Fnord23"
frame.node_type = NodeTypeWithSubtype.GARAGE_DOOR_OPENER
frame.serial_number = bytes.fromhex('aa bb aa bb aa bb aa 23')
pyvlx = PyVLX()
node = convert_frame_to_node(pyvlx, frame)
self.assertEqual(node, GarageDoor(pyvlx=pyvlx, name="Fnord23", node_id=23))
self.assertEqual(node, GarageDoor(pyvlx=pyvlx, name="Fnord23", node_id=23, serial_number='aa:bb:aa:bb:aa:bb:aa:23'))

def test_blade(self):
"""Test convert_frame_to_node blade."""
frame = FrameGetNodeInformationNotification()
frame.node_id = 23
frame.name = "Fnord23"
frame.node_type = NodeTypeWithSubtype.BLADE_OPENER
frame.serial_number = bytes.fromhex('aa bb aa bb aa bb aa 23')
pyvlx = PyVLX()
node = convert_frame_to_node(pyvlx, frame)
self.assertEqual(node, Blade(pyvlx=pyvlx, name="Fnord23", node_id=23))
self.assertEqual(node, Blade(pyvlx=pyvlx, name="Fnord23", node_id=23, serial_number='aa:bb:aa:bb:aa:bb:aa:23'))

def test_no_type(self):
"""Test convert_frame_to_node with no type (convert_frame_to_node should return None)."""
frame = FrameGetNodeInformationNotification()
frame.node_id = 23
frame.name = "Fnord23"
frame.node_type = NodeTypeWithSubtype.NO_TYPE
frame.serial_number = bytes.fromhex('aa bb aa bb aa bb aa 23')
pyvlx = PyVLX()
self.assertEqual(convert_frame_to_node(pyvlx, frame), None)

Expand All @@ -87,6 +94,7 @@ def test_light(self):
frame.node_id = 23
frame.name = "Fnord23"
frame.node_type = NodeTypeWithSubtype.LIGHT
frame.serial_number = bytes.fromhex('aa bb aa bb aa bb aa 23')
pyvlx = PyVLX()
node = convert_frame_to_node(pyvlx, frame)
self.assertEqual(node, Light(pyvlx=pyvlx, name="Fnord23", node_id=23))
self.assertEqual(node, Light(pyvlx=pyvlx, name="Fnord23", node_id=23, serial_number='aa:bb:aa:bb:aa:bb:aa:23'))
Loading

0 comments on commit da4761d

Please sign in to comment.