Skip to content

Commit 0245607

Browse files
author
James Wah
committed
fakes.Device: implement commissioning functions
This allows fakes to be discovered and assigned addresses.
1 parent f30fa48 commit 0245607

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

dali/tests/fakes.py

+71
Original file line numberDiff line numberDiff line change
@@ -488,11 +488,17 @@ def __init__(
488488
shortaddr: Optional[address.DeviceShort] = None,
489489
groups: Optional[Iterable[address.DeviceGroup]] = None,
490490
memory_banks: Optional[Iterable[Type[FakeMemoryBank]]] = (FakeDeviceBank0,),
491+
random_preload: list[int] = [],
491492
):
492493
# Store parameters
493494
self.shortaddr = shortaddr
494495
self.groups = set(groups) if groups else set()
495496
# Configure internal variables
497+
self.randomaddr = frame.Frame(24)
498+
self.searchaddr = frame.Frame(24)
499+
self.random_preload = random_preload
500+
self.initialising = False
501+
self.withdrawn = False
496502
self.dtr0: int = 0
497503
self.dtr1: int = 0
498504
self.dtr2: int = 0
@@ -504,6 +510,12 @@ def __init__(
504510
raise ValueError(f"Duplicate memory bank {bank_number}")
505511
self.memory_banks[bank_number] = fake_bank()
506512

513+
def _next_random_address(self):
514+
if self.random_preload:
515+
return self.random_preload.pop(0)
516+
else:
517+
return random.randrange(0, 0x1000000)
518+
507519
def valid_address(self, cmd: Command) -> bool:
508520
"""Should we respond to this command?"""
509521
if len(cmd.frame) != 24:
@@ -521,6 +533,13 @@ def valid_address(self, cmd: Command) -> bool:
521533
if isinstance(cmd.destination, address.DeviceGroup):
522534
return cmd.destination in self.groups
523535

536+
@property
537+
def shortaddr_int(self):
538+
if self.shortaddr is None:
539+
return 0xff
540+
else:
541+
return self.shortaddr.address
542+
524543
def send(self, cmd: Command) -> Optional[int]:
525544
# Reset enable_write_memory if command is not one of the memory
526545
# writing commands, even if the command is not addressed to us
@@ -627,6 +646,58 @@ def send(self, cmd: Command) -> Optional[int]:
627646
finally:
628647
if not bank.nobble_dtr0_update:
629648
self.dtr0 = min(self.dtr0 + 1, 255)
649+
elif isinstance(cmd, device.general.SetShortAddress):
650+
if self.dtr0 == 0xff:
651+
self.shortaddr = None
652+
elif (self.dtr0 & 1) == 1:
653+
self.shortaddr = address.DeviceShort((self.dtr0 & 0x7e) >> 1)
654+
elif isinstance(cmd, device.general.QueryMissingShortAddress):
655+
if self.shortaddr is None:
656+
return _yes
657+
elif isinstance(cmd, device.general.QueryRandomAddressH):
658+
return self.randomaddr[23:16]
659+
elif isinstance(cmd, device.general.QueryRandomAddressM):
660+
return self.randomaddr[15:8]
661+
elif isinstance(cmd, device.general.QueryRandomAddressL):
662+
return self.randomaddr[7:0]
663+
elif isinstance(cmd, device.general.Terminate):
664+
self.initialising = False
665+
self.withdrawn = False
666+
elif isinstance(cmd, device.general.Initialise):
667+
if cmd.param == 0xff \
668+
or (cmd.param == 0x7f and self.shortaddr is None) \
669+
or (cmd.param == self.shortaddr):
670+
self.initialising = True
671+
self.withdrawn = False
672+
# We don't implement the 15 minute timer
673+
elif isinstance(cmd, device.general.Randomise):
674+
self.randomaddr = frame.Frame(24, self._next_random_address())
675+
elif isinstance(cmd, device.general.Compare):
676+
if self.initialising \
677+
and not self.withdrawn \
678+
and self.randomaddr.as_integer <= self.searchaddr.as_integer:
679+
return _yes
680+
elif isinstance(cmd, device.general.Withdraw):
681+
if self.initialising \
682+
and self.randomaddr == self.searchaddr:
683+
self.withdrawn = True
684+
elif isinstance(cmd, device.general.SearchAddrH):
685+
self.searchaddr[23:16] = cmd.param
686+
elif isinstance(cmd, device.general.SearchAddrM):
687+
self.searchaddr[15:8] = cmd.param
688+
elif isinstance(cmd, device.general.SearchAddrL):
689+
self.searchaddr[7:0] = cmd.param
690+
elif isinstance(cmd, device.general.ProgramShortAddress):
691+
if self.initialising \
692+
and self.randomaddr == self.searchaddr:
693+
if cmd.param == 255:
694+
self.shortaddr = None
695+
else:
696+
self.shortaddr = address.DeviceShort(cmd.param)
697+
elif isinstance(cmd, device.general.VerifyShortAddress):
698+
if self.initialising \
699+
and self.shortaddr_int == cmd.param:
700+
return _yes
630701

631702
return None
632703

0 commit comments

Comments
 (0)