__init__.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import logging
  2. import time
  3. import cc1101
  4. _ADDRESS_LENGTH_BITS = 26
  5. _COMMAND_LENGTH_BITS = 2
  6. _BUTTON_INDEX_LENGTH_BITS = 4
  7. _MESSAGE_LENGTH_BITS = (
  8. _ADDRESS_LENGTH_BITS + _COMMAND_LENGTH_BITS + _BUTTON_INDEX_LENGTH_BITS
  9. )
  10. _LOGGER = logging.getLogger(__name__)
  11. def _cc1101_transmit(payload: bytes, repeats: int = 3) -> None:
  12. with cc1101.CC1101(lock_spi_device=True) as transceiver:
  13. transceiver.set_base_frequency_hertz(433.93e6)
  14. transceiver.set_symbol_rate_baud(3942)
  15. transceiver.set_sync_mode(cc1101.SyncMode.NO_PREAMBLE_AND_SYNC_WORD)
  16. transceiver.set_packet_length_mode(cc1101.PacketLengthMode.FIXED)
  17. transceiver.set_packet_length_bytes(len(payload))
  18. transceiver.disable_checksum()
  19. transceiver.set_output_power((0, 0xC6)) # OOK
  20. _LOGGER.info("%s", transceiver)
  21. for _ in range(repeats):
  22. transceiver.transmit(payload)
  23. time.sleep(0.08)
  24. def _encode_message(message: int) -> bytes:
  25. signal = [0b00000100, 0]
  26. assert 0 <= message < 2 ** _MESSAGE_LENGTH_BITS, message
  27. for bit_index in reversed(range(_MESSAGE_LENGTH_BITS)):
  28. if message & (0b1 << bit_index):
  29. signal.append(0b10000010)
  30. else:
  31. signal.append(0b10100000)
  32. signal.append(0b10000000)
  33. return bytes(signal)
  34. class RemoteControl:
  35. def __init__(self, address: int) -> None:
  36. assert 0 <= address < 2 ** _ADDRESS_LENGTH_BITS, address
  37. self._address = address
  38. def _send_command(self, command: int, button_index: int) -> None:
  39. assert 0 <= command < 2 ** _COMMAND_LENGTH_BITS
  40. assert 0 <= button_index < 2 ** _BUTTON_INDEX_LENGTH_BITS
  41. _cc1101_transmit(
  42. _encode_message(
  43. (self._address << _COMMAND_LENGTH_BITS | command)
  44. << _BUTTON_INDEX_LENGTH_BITS
  45. | button_index
  46. )
  47. )
  48. def turn_on(self, button_index: int) -> None:
  49. self._send_command(command=0b01, button_index=button_index)
  50. def turn_off(self, button_index: int) -> None:
  51. self._send_command(command=0b00, button_index=button_index)