doorcontrol: Keep better track of which cards are 26 bit
Some checks failed
Ruff / ruff (push) Successful in 34s
Test / test (push) Failing after 3m31s

This commit is contained in:
Adam Goldsmith 2024-12-03 18:56:59 -05:00
parent 64d8d1fcfb
commit b4329a5b77
2 changed files with 14 additions and 9 deletions

View File

@ -24,6 +24,7 @@ class InvalidParity(InvalidHexCode):
@dataclasses.dataclass(frozen=True) @dataclasses.dataclass(frozen=True)
class Credential: class Credential:
bits: bitstring.Bits bits: bitstring.Bits
is_26bit: bool = dataclasses.field(default=False, compare=False)
@staticmethod @staticmethod
def even_parity(bits: bitstring.Bits) -> bool: def even_parity(bits: bitstring.Bits) -> bool:
@ -55,16 +56,12 @@ class Credential:
if bits[31] != (cls.odd_parity(bits)): if bits[31] != (cls.odd_parity(bits)):
raise InvalidParity(bits, "odd") raise InvalidParity(bits, "odd")
return cls(bits) return cls(bits, is_26bit=True)
@classmethod @classmethod
def from_any_hex(cls, hex_code: str) -> "Credential": def from_raw_hex(cls, hex_code: str) -> "Credential":
return cls(bitstring.Bits(hex=hex_code)) return cls(bitstring.Bits(hex=hex_code))
@property
def is_26bit(self) -> bool:
return self.bits[:6].all(0)
@property @property
def facility_code(self) -> int: def facility_code(self) -> int:
if not self.is_26bit: if not self.is_26bit:

View File

@ -45,7 +45,7 @@ class DoorMember:
) )
) )
if member.nfc_card_number: if member.nfc_card_number:
credentials.add(Credential.from_any_hex(member.nfc_card_number)) credentials.add(Credential.from_raw_hex(member.nfc_card_number))
reasons_and_schedules: dict[str, str] = {} reasons_and_schedules: dict[str, str] = {}
if ( if (
@ -107,7 +107,11 @@ class DoorMember:
}, },
cardholderID=data.attrib["cardholderID"], cardholderID=data.attrib["cardholderID"],
credentials={ credentials={
Credential.from_any_hex(c.attrib["rawCardNumber"]) (
Credential.from_26bit_hex(c.attrib["rawCardNumber"])
if "formatID" in c.attrib
else Credential.from_raw_hex(c.attrib["rawCardNumber"])
)
for c in data.findall("{*}Credential") for c in data.findall("{*}Credential")
}, },
schedules={r.attrib["scheduleName"] for r in data.findall("{*}Role")}, schedules={r.attrib["scheduleName"] for r in data.findall("{*}Role")},
@ -237,7 +241,11 @@ def update_door(door: Door, dry_run: bool = False):
logger.debug(f"Fetching credentials from {door}") logger.debug(f"Fetching credentials from {door}")
existing_door_credentials = { existing_door_credentials = {
Credential.from_any_hex(c.attrib["rawCardNumber"]) (
Credential.from_26bit_hex(c.attrib["rawCardNumber"])
if "formatID" in c.attrib
else Credential.from_raw_hex(c.attrib["rawCardNumber"])
)
for c in door.controller.get_credentials() for c in door.controller.get_credentials()
} }