rf-protocols 4.0.1__tar.gz → 4.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/PKG-INFO +1 -1
  2. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/pyproject.toml +1 -1
  3. rf_protocols-4.2.0/rf_protocols/codes/harbor_breeze/a25/__init__.py +34 -0
  4. rf_protocols-4.2.0/rf_protocols/commands/harbor_breeze_a25.py +71 -0
  5. rf_protocols-4.2.0/rf_protocols/commands/marantec.py +76 -0
  6. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols.egg-info/PKG-INFO +1 -1
  7. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols.egg-info/SOURCES.txt +3 -0
  8. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/LICENSE +0 -0
  9. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/README.md +0 -0
  10. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/__init__.py +0 -0
  11. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/codes/honeywell/string_lights/__init__.py +0 -0
  12. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/codes/honeywell/string_lights/turn_off.sub +0 -0
  13. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/codes/honeywell/string_lights/turn_on.sub +0 -0
  14. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/codes/novy/cooker_hood/__init__.py +0 -0
  15. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/codes/somfy/rts/__init__.py +0 -0
  16. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/commands/__init__.py +0 -0
  17. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/commands/ev1527.py +0 -0
  18. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/commands/kaku.py +0 -0
  19. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/commands/novy.py +0 -0
  20. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/commands/ook.py +0 -0
  21. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/commands/pilota_casa.py +0 -0
  22. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/commands/pt2262.py +0 -0
  23. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/commands/somfy_rts.py +0 -0
  24. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/loader.py +0 -0
  25. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols/parser.py +0 -0
  26. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols.egg-info/dependency_links.txt +0 -0
  27. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols.egg-info/requires.txt +0 -0
  28. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/rf_protocols.egg-info/top_level.txt +0 -0
  29. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/setup.cfg +0 -0
  30. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/tests/test_loader.py +0 -0
  31. {rf_protocols-4.0.1 → rf_protocols-4.2.0}/tests/test_parser.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rf-protocols
3
- Version: 4.0.1
3
+ Version: 4.2.0
4
4
  Summary: Library to decode and encode radio frequency signals.
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/home-assistant-libs/rf-protocols
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "rf-protocols"
7
- version = "4.0.1"
7
+ version = "4.2.0"
8
8
  license = "MIT"
9
9
  description = "Library to decode and encode radio frequency signals."
10
10
  readme = "README.md"
@@ -0,0 +1,34 @@
1
+ """Harbor Breeze A25 command identifiers."""
2
+
3
+ from enum import IntEnum
4
+
5
+ from ....commands.harbor_breeze_a25 import HarborBreezeA25Command
6
+
7
+
8
+ class HarborBreezeA25Button(IntEnum):
9
+ """Known Harbor Breeze A25 button codes.
10
+
11
+ Values are the decoded 6-bit command field found in the normalized frame.
12
+ """
13
+
14
+ BLOW = 0b111010
15
+ BREEZE = 0b000110
16
+ FAN_1 = 0b011110
17
+ FAN_2 = 0b101110
18
+ FAN_3 = 0b001110
19
+ FAN_4 = 0b110110
20
+ FAN_5 = 0b010110
21
+ FAN_6 = 0b100110
22
+ HOME = 0b000011
23
+ LIGHT = 0b011010
24
+ POWER = 0b111110
25
+ SUCK = 0b111000
26
+ TIMER = 0b001000
27
+ TIMER_2H = 0b011011
28
+ TIMER_4H = 0b101011
29
+ TIMER_8H = 0b001011
30
+
31
+ def to_command(self, *, address: int) -> HarborBreezeA25Command:
32
+ """Build a Harbor Breeze command for this button and address."""
33
+ return HarborBreezeA25Command(address=address, command=self.value)
34
+
@@ -0,0 +1,71 @@
1
+ """Harbor Breeze A25 RF command encoder."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import override
6
+
7
+ from . import ModulationType, RadioFrequencyCommand
8
+
9
+ _DEFAULT_FREQUENCY = 315_000_000
10
+ _DEFAULT_FRAME_COUNT = 6
11
+
12
+
13
+ class HarborBreezeA25Command(RadioFrequencyCommand):
14
+ """Encode Harbor Breeze A25 transmissions.
15
+
16
+ The frame layout consists of a three-symbol preamble, a 13-bit address,
17
+ two fixed bits, a 6-bit command field, two fixed trailer bits, and a final
18
+ inter-frame gap. The complete frame is emitted six times per transmission.
19
+ """
20
+
21
+ address: int
22
+ command: int
23
+
24
+ def __init__(
25
+ self,
26
+ *,
27
+ address: int,
28
+ command: int,
29
+ frequency: int = _DEFAULT_FREQUENCY,
30
+ ) -> None:
31
+ """Initialize the Harbor Breeze command.
32
+
33
+ Args:
34
+ address: 13-bit receiver address (0..8191).
35
+ command: 6-bit command value (0..63).
36
+ frequency: RF frequency in Hz.
37
+ """
38
+ if address < 0 or address >= (1 << 13):
39
+ raise ValueError("address must be in range 0..8191 (13-bit)")
40
+ if command < 0 or command >= (1 << 6):
41
+ raise ValueError("command must be in range 0..63 (6-bit)")
42
+
43
+ super().__init__(
44
+ frequency=frequency,
45
+ modulation=ModulationType.OOK,
46
+ repeat_count=0,
47
+ )
48
+ self.address = address
49
+ self.command = command
50
+
51
+ @override
52
+ def get_raw_timings(self) -> list[int]:
53
+ """Compute the repeated Harbor Breeze transmission timings."""
54
+ short_us = 493
55
+ long_us = 952
56
+ frame_gap_us = 10_936
57
+
58
+ payload_bits = f"{self.address:013b}00{self.command:06b}10"
59
+
60
+ frame: list[int] = [short_us, -long_us, short_us]
61
+ for bit in payload_bits:
62
+ if bit == "0":
63
+ frame.extend([-long_us, short_us])
64
+ else:
65
+ frame.extend([-short_us, long_us])
66
+ frame.append(-frame_gap_us)
67
+
68
+ timings: list[int] = []
69
+ for _ in range(_DEFAULT_FRAME_COUNT):
70
+ timings.extend(frame)
71
+ return timings
@@ -0,0 +1,76 @@
1
+ """Encoder for Marantec garage door / gate RF remotes.
2
+
3
+ 868.35 MHz OOK (433.92 MHz variant available), Manchester-coded. Encodes a
4
+ static, indefinitely valid (non-rolling) 49-bit code. Does not cover
5
+ rolling-code Marantec systems or the unrelated 24-bit "Marantec24" cloner
6
+ protocol.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import override
12
+
13
+ from . import ModulationType, RadioFrequencyCommand
14
+
15
+ _MARANTEC_FREQUENCY = 868_350_000
16
+ _MARANTEC_REPEAT_COUNT = 4
17
+
18
+ _TE_SHORT = 1000
19
+ _TE_LONG = 2000
20
+ _HEADER_LOW = _TE_LONG * 5
21
+
22
+ _BIT_COUNT = 49
23
+
24
+
25
+ class MarantecCommand(RadioFrequencyCommand):
26
+ """Encode a Marantec static-code garage door / gate frame."""
27
+
28
+ code: int
29
+
30
+ def __init__(
31
+ self,
32
+ *,
33
+ code: int,
34
+ frequency: int = _MARANTEC_FREQUENCY,
35
+ ) -> None:
36
+ """Initialize the Marantec command."""
37
+ if code < 0 or code >= (1 << _BIT_COUNT):
38
+ raise ValueError("code must be a 49-bit value (0..2**49-1)")
39
+ super().__init__(
40
+ frequency=frequency,
41
+ modulation=ModulationType.OOK,
42
+ repeat_count=_MARANTEC_REPEAT_COUNT,
43
+ )
44
+ self.code = code
45
+
46
+ @override
47
+ def get_raw_timings(self) -> list[int]:
48
+ """Compute the frame timings as signed mark/space microseconds.
49
+
50
+ Manchester (bit 0 = mark then space, bit 1 = space then mark), 49 bits,
51
+ trailing inter-frame gap. Frame starts on a mark so polarity (assigned
52
+ by index parity) stays correct; the first bit's leading space and the
53
+ gap are reconstructed across the repeated transmissions.
54
+ """
55
+ timings: list[int] = []
56
+
57
+ def add(us: int) -> None:
58
+ if timings and (us > 0) == (timings[-1] > 0):
59
+ timings[-1] += us
60
+ else:
61
+ timings.append(us)
62
+
63
+ for idx in range(_BIT_COUNT):
64
+ bit = (self.code >> (_BIT_COUNT - 1 - idx)) & 1
65
+ if idx == 0 and bit:
66
+ add(_TE_SHORT)
67
+ continue
68
+ if bit:
69
+ add(-_TE_SHORT)
70
+ add(_TE_SHORT)
71
+ else:
72
+ add(_TE_SHORT)
73
+ add(-_TE_SHORT)
74
+
75
+ add(-_HEADER_LOW)
76
+ return timings
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rf-protocols
3
- Version: 4.0.1
3
+ Version: 4.2.0
4
4
  Summary: Library to decode and encode radio frequency signals.
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/home-assistant-libs/rf-protocols
@@ -9,6 +9,7 @@ rf_protocols.egg-info/SOURCES.txt
9
9
  rf_protocols.egg-info/dependency_links.txt
10
10
  rf_protocols.egg-info/requires.txt
11
11
  rf_protocols.egg-info/top_level.txt
12
+ rf_protocols/codes/harbor_breeze/a25/__init__.py
12
13
  rf_protocols/codes/honeywell/string_lights/__init__.py
13
14
  rf_protocols/codes/honeywell/string_lights/turn_off.sub
14
15
  rf_protocols/codes/honeywell/string_lights/turn_on.sub
@@ -16,7 +17,9 @@ rf_protocols/codes/novy/cooker_hood/__init__.py
16
17
  rf_protocols/codes/somfy/rts/__init__.py
17
18
  rf_protocols/commands/__init__.py
18
19
  rf_protocols/commands/ev1527.py
20
+ rf_protocols/commands/harbor_breeze_a25.py
19
21
  rf_protocols/commands/kaku.py
22
+ rf_protocols/commands/marantec.py
20
23
  rf_protocols/commands/novy.py
21
24
  rf_protocols/commands/ook.py
22
25
  rf_protocols/commands/pilota_casa.py
File without changes
File without changes
File without changes