mirror of
https://github.com/mjg59/python-broadlink.git
synced 2024-11-21 22:51:41 +01:00
Encapsulate crc16() to avoid global (#566)
This commit is contained in:
parent
86b5d0727c
commit
4e1e690762
@ -3,7 +3,7 @@ from typing import List
|
|||||||
|
|
||||||
from . import exceptions as e
|
from . import exceptions as e
|
||||||
from .device import device
|
from .device import device
|
||||||
from .helpers import crc16
|
from .helpers import CRC16
|
||||||
|
|
||||||
|
|
||||||
class hysen(device):
|
class hysen(device):
|
||||||
@ -19,7 +19,7 @@ class hysen(device):
|
|||||||
|
|
||||||
def send_request(self, input_payload: bytes) -> bytes:
|
def send_request(self, input_payload: bytes) -> bytes:
|
||||||
"""Send a request to the device."""
|
"""Send a request to the device."""
|
||||||
crc = crc16(input_payload)
|
crc = CRC16.calculate(input_payload)
|
||||||
|
|
||||||
# first byte is length, +2 for CRC16
|
# first byte is length, +2 for CRC16
|
||||||
request_payload = bytearray([len(input_payload) + 2, 0x00])
|
request_payload = bytearray([len(input_payload) + 2, 0x00])
|
||||||
@ -40,7 +40,7 @@ class hysen(device):
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
"hysen_response_error", "first byte of response is not length"
|
"hysen_response_error", "first byte of response is not length"
|
||||||
)
|
)
|
||||||
crc = crc16(response_payload[2:response_payload_len])
|
crc = CRC16.calculate(response_payload[2:response_payload_len])
|
||||||
if (response_payload[response_payload_len] == crc & 0xFF) and (
|
if (response_payload[response_payload_len] == crc & 0xFF) and (
|
||||||
response_payload[response_payload_len + 1] == (crc >> 8) & 0xFF
|
response_payload[response_payload_len + 1] == (crc >> 8) & 0xFF
|
||||||
):
|
):
|
||||||
|
@ -1,32 +1,38 @@
|
|||||||
"""Helper functions."""
|
"""Helper functions and classes."""
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
_crc16_cache = {}
|
|
||||||
|
|
||||||
|
class CRC16: # pylint: disable=R0903
|
||||||
|
"""Helps with CRC-16 calculation.
|
||||||
|
|
||||||
def crc16(
|
CRC tables are cached for performance.
|
||||||
sequence: t.Sequence[int],
|
"""
|
||||||
polynomial: int = 0xA001, # Default: Modbus CRC-16.
|
|
||||||
init_value: int = 0xFFFF,
|
|
||||||
) -> int:
|
|
||||||
"""Calculate the CRC-16 of a sequence of integers."""
|
|
||||||
global _crc16_cache
|
|
||||||
|
|
||||||
try:
|
_cache = {}
|
||||||
crc_table = _crc16_cache[polynomial]
|
|
||||||
except KeyError:
|
|
||||||
crc_table = []
|
|
||||||
for dividend in range(0, 256):
|
|
||||||
remainder = dividend
|
|
||||||
for _ in range(0, 8):
|
|
||||||
if remainder & 1:
|
|
||||||
remainder = remainder >> 1 ^ polynomial
|
|
||||||
else:
|
|
||||||
remainder = remainder >> 1
|
|
||||||
crc_table.append(remainder)
|
|
||||||
_crc16_cache[polynomial] = crc_table
|
|
||||||
|
|
||||||
crc = init_value
|
@classmethod
|
||||||
for item in sequence:
|
def calculate(
|
||||||
crc = crc >> 8 ^ crc_table[(crc ^ item) & 0xFF]
|
cls,
|
||||||
return crc
|
sequence: t.Sequence[int],
|
||||||
|
polynomial: int = 0xA001, # Modbus CRC-16.
|
||||||
|
init_value: int = 0xFFFF,
|
||||||
|
) -> int:
|
||||||
|
"""Calculate the CRC-16 of a sequence of integers."""
|
||||||
|
try:
|
||||||
|
crc_table = cls._cache[polynomial]
|
||||||
|
except KeyError:
|
||||||
|
crc_table = []
|
||||||
|
for dividend in range(0, 256):
|
||||||
|
remainder = dividend
|
||||||
|
for _ in range(0, 8):
|
||||||
|
if remainder & 1:
|
||||||
|
remainder = remainder >> 1 ^ polynomial
|
||||||
|
else:
|
||||||
|
remainder = remainder >> 1
|
||||||
|
crc_table.append(remainder)
|
||||||
|
cls._cache[polynomial] = crc_table
|
||||||
|
|
||||||
|
crc = init_value
|
||||||
|
for item in sequence:
|
||||||
|
crc = crc >> 8 ^ crc_table[(crc ^ item) & 0xFF]
|
||||||
|
return crc
|
||||||
|
Loading…
Reference in New Issue
Block a user