Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions octoprint_octorelay/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,23 @@ class Driver():

def __init__(self, pin: int, inverted: bool, pin_factory=None):
self.pin = pin # GPIO pin
self.inverted = inverted # marks the relay as normally closed
self.handle = LED(pin, pin_factory=pin_factory, initial_value=inverted)
self.handle = LED(pin, pin_factory=pin_factory, active_high=not inverted)
# release immediately, avoid lock, allow physical buttons to operate same relays:
self.handle.pin_factory.release_pins(self.handle, self.pin)

def __repr__(self) -> str:
return f"{type(self).__name__}(pin={self.pin},inverted={self.inverted},closed={self.is_closed()})"

@property
def inverted(self):
"""Returns true if the relay is normally closed."""
return not self.handle.active_high

@inverted.setter
def inverted(self, value):
"""Changing this will invert is_closed value without inverting the pin"""
self.handle.active_high = not value

def close(self):
"""Activates the current flow through the relay."""
self.toggle(True)
Expand All @@ -28,7 +37,7 @@ def open(self):

def is_closed(self) -> bool:
"""Returns the logical state of the relay."""
return xor(self.inverted, self.handle.is_lit)
return self.handle.is_lit

def toggle(self, desired_state: Optional[bool] = None) -> bool:
"""
Expand All @@ -38,7 +47,7 @@ def toggle(self, desired_state: Optional[bool] = None) -> bool:
"""
if desired_state is None:
desired_state = not self.is_closed()
(self.handle.on if xor(self.inverted, desired_state) else self.handle.off)()
(self.handle.on if desired_state else self.handle.off)()
return desired_state

@classmethod
Expand Down
14 changes: 7 additions & 7 deletions tests/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_serialization(self):
def test_close(self):
cases = [
{ "relay": Driver(18, False, MockFactory()), "expected_pin_state": True },
{ "relay": Driver(18, True, MockFactory()), "expected_pin_state": False }
{ "relay": Driver(18, True, MockFactory()), "expected_pin_state": True }
]
for case in cases:
case["relay"].close()
Expand All @@ -36,7 +36,7 @@ def test_close(self):
def test_open(self):
cases = [
{ "relay": Driver(18, False, MockFactory()), "expected_pin_state": False },
{ "relay": Driver(18, True, MockFactory()), "expected_pin_state": True }
{ "relay": Driver(18, True, MockFactory()), "expected_pin_state": False }
]
for case in cases:
case["relay"].open()
Expand All @@ -46,8 +46,8 @@ def test_is_closed(self):
cases = [
{ "mocked_state": 1, "inverted": False, "expected_relay_state": True },
{ "mocked_state": 0, "inverted": False, "expected_relay_state": False },
{ "mocked_state": 1, "inverted": True, "expected_relay_state": False },
{ "mocked_state": 0, "inverted": True, "expected_relay_state": True },
{ "mocked_state": 1, "inverted": True, "expected_relay_state": True },
{ "mocked_state": 0, "inverted": True, "expected_relay_state": False },
]
for case in cases:
relay = Driver(18, case["inverted"], MockFactory())
Expand All @@ -58,8 +58,8 @@ def test_toggle__no_argument(self):
cases = [
{ "mocked_state": 1, "inverted": False, "expected_pin_state": False, "expected_relay_state": False },
{ "mocked_state": 0, "inverted": False, "expected_pin_state": True, "expected_relay_state": True },
{ "mocked_state": 1, "inverted": True, "expected_pin_state": False, "expected_relay_state": True },
{ "mocked_state": 0, "inverted": True, "expected_pin_state": True, "expected_relay_state": False },
{ "mocked_state": 1, "inverted": True, "expected_pin_state": False, "expected_relay_state": False },
{ "mocked_state": 0, "inverted": True, "expected_pin_state": True, "expected_relay_state": True },
]
for case in cases:
relay = Driver(18, case["inverted"], MockFactory())
Expand All @@ -75,7 +75,7 @@ def test_ensure(self):
self.assertFalse(relay1.inverted)

# Test retrieving the existing relay with the same pin and inversion
relay2 = Driver.ensure(17, True, MockFactory())
relay2 = Driver.ensure(17, False, MockFactory())
Comment thread
cesaregiannetti marked this conversation as resolved.
self.assertIs(relay1, relay2)
self.assertEqual(len(Driver.cache), 1) # Should still be 1

Expand Down
Loading