Skip to content

Commit

Permalink
Implement reading and writing bits in the plc status dword
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanscherzinger committed Jul 30, 2024
1 parent e79f736 commit d2bb958
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
21 changes: 21 additions & 0 deletions schunk_egu_egk_gripper_dummy/src/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def __init__(self):
self.data = None
self.plc_input = "0x0040"
self.plc_output = "0x0048"
self.reserved_status_bits = [10, 15] + list(range(18, 31))

enum_config = os.path.join(
Path(__file__).resolve().parents[1], "config/enum.json"
Expand Down Expand Up @@ -101,3 +102,23 @@ def get_plc_input(self):

def get_plc_output(self):
return [self.plc_output_buffer.hex().upper()]

def set_status_bit(self, bit: int, value: bool) -> bool:
if bit < 0 or bit > 31:
return False
if bit in self.reserved_status_bits:
return False
byte_index, bit_index = divmod(bit, 8)
if value:
self.plc_input_buffer[byte_index] |= 1 << bit_index
else:
self.plc_input_buffer[byte_index] &= ~(1 << bit_index)
return True

def get_status_bit(self, bit: int) -> int | bool:
if bit < 0 or bit > 31:
return False
if bit in self.reserved_status_bits:
return False
byte_index, bit_index = divmod(bit, 8)
return 1 if self.plc_input_buffer[byte_index] & (1 << bit_index) != 0 else 0
36 changes: 36 additions & 0 deletions schunk_egu_egk_gripper_dummy/tests/test_plc_communication.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,42 @@ def test_dummy_returns_plc_data():
assert dummy.data[dummy.plc_output] == dummy.get_plc_output()


def test_dummy_rejects_writing_reserved_status_bits():
dummy = Dummy()
invalid_bits = [-1, 999]
for bit in invalid_bits + dummy.reserved_status_bits:
assert not dummy.set_status_bit(bit, True)


def test_dummy_rejects_reading_reserved_status_bits():
dummy = Dummy()
for bit in dummy.reserved_status_bits:
assert isinstance(dummy.get_status_bit(bit), bool) # call fails
assert not dummy.get_status_bit(bit)


def test_dummy_supports_reading_and_writing_bits_in_plc_status():
dummy = Dummy()
valid_bits = list(range(0, 10)) + [11, 12, 13, 14, 16, 17, 31]
for bit in valid_bits:
dummy.set_status_bit(bit=bit, value=True)
result = dummy.get_status_bit(bit=bit)
assert isinstance(result, int) # successful calls get the bit's value
assert result == 1


def test_dummy_only_touches_specified_bits():
dummy = Dummy()
before = dummy.get_plc_input()
valid_bits = list(range(0, 10)) + [11, 12, 13, 14, 16, 17, 31]
for bit in valid_bits:
initial_value = dummy.get_status_bit(bit=bit)
dummy.set_status_bit(bit=bit, value=True)
dummy.set_status_bit(bit=bit, value=initial_value)

assert dummy.get_plc_input() == before


# See p. 24 in
# Booting and establishing operational readiness [1]

Expand Down

0 comments on commit d2bb958

Please sign in to comment.