ramses-rf 0.22.2__py3-none-any.whl → 0.51.1__py3-none-any.whl

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 (72) hide show
  1. ramses_cli/__init__.py +18 -0
  2. ramses_cli/client.py +597 -0
  3. ramses_cli/debug.py +20 -0
  4. ramses_cli/discovery.py +405 -0
  5. ramses_cli/utils/cat_slow.py +17 -0
  6. ramses_cli/utils/convert.py +60 -0
  7. ramses_rf/__init__.py +31 -10
  8. ramses_rf/binding_fsm.py +787 -0
  9. ramses_rf/const.py +124 -105
  10. ramses_rf/database.py +297 -0
  11. ramses_rf/device/__init__.py +69 -39
  12. ramses_rf/device/base.py +187 -376
  13. ramses_rf/device/heat.py +540 -552
  14. ramses_rf/device/hvac.py +286 -171
  15. ramses_rf/dispatcher.py +153 -177
  16. ramses_rf/entity_base.py +478 -361
  17. ramses_rf/exceptions.py +82 -0
  18. ramses_rf/gateway.py +378 -514
  19. ramses_rf/helpers.py +57 -19
  20. ramses_rf/py.typed +0 -0
  21. ramses_rf/schemas.py +148 -194
  22. ramses_rf/system/__init__.py +16 -23
  23. ramses_rf/system/faultlog.py +363 -0
  24. ramses_rf/system/heat.py +295 -302
  25. ramses_rf/system/schedule.py +312 -198
  26. ramses_rf/system/zones.py +318 -238
  27. ramses_rf/version.py +2 -8
  28. ramses_rf-0.51.1.dist-info/METADATA +72 -0
  29. ramses_rf-0.51.1.dist-info/RECORD +55 -0
  30. {ramses_rf-0.22.2.dist-info → ramses_rf-0.51.1.dist-info}/WHEEL +1 -2
  31. ramses_rf-0.51.1.dist-info/entry_points.txt +2 -0
  32. {ramses_rf-0.22.2.dist-info → ramses_rf-0.51.1.dist-info/licenses}/LICENSE +1 -1
  33. ramses_tx/__init__.py +160 -0
  34. {ramses_rf/protocol → ramses_tx}/address.py +65 -59
  35. ramses_tx/command.py +1454 -0
  36. ramses_tx/const.py +903 -0
  37. ramses_tx/exceptions.py +92 -0
  38. {ramses_rf/protocol → ramses_tx}/fingerprints.py +56 -15
  39. {ramses_rf/protocol → ramses_tx}/frame.py +132 -131
  40. ramses_tx/gateway.py +338 -0
  41. ramses_tx/helpers.py +883 -0
  42. {ramses_rf/protocol → ramses_tx}/logger.py +67 -53
  43. {ramses_rf/protocol → ramses_tx}/message.py +155 -191
  44. ramses_tx/opentherm.py +1260 -0
  45. ramses_tx/packet.py +210 -0
  46. ramses_tx/parsers.py +2957 -0
  47. ramses_tx/protocol.py +801 -0
  48. ramses_tx/protocol_fsm.py +672 -0
  49. ramses_tx/py.typed +0 -0
  50. {ramses_rf/protocol → ramses_tx}/ramses.py +262 -185
  51. {ramses_rf/protocol → ramses_tx}/schemas.py +150 -133
  52. ramses_tx/transport.py +1471 -0
  53. ramses_tx/typed_dicts.py +492 -0
  54. ramses_tx/typing.py +181 -0
  55. ramses_tx/version.py +4 -0
  56. ramses_rf/discovery.py +0 -398
  57. ramses_rf/protocol/__init__.py +0 -59
  58. ramses_rf/protocol/backports.py +0 -42
  59. ramses_rf/protocol/command.py +0 -1561
  60. ramses_rf/protocol/const.py +0 -697
  61. ramses_rf/protocol/exceptions.py +0 -111
  62. ramses_rf/protocol/helpers.py +0 -390
  63. ramses_rf/protocol/opentherm.py +0 -1170
  64. ramses_rf/protocol/packet.py +0 -235
  65. ramses_rf/protocol/parsers.py +0 -2673
  66. ramses_rf/protocol/protocol.py +0 -613
  67. ramses_rf/protocol/transport.py +0 -1011
  68. ramses_rf/protocol/version.py +0 -10
  69. ramses_rf/system/hvac.py +0 -82
  70. ramses_rf-0.22.2.dist-info/METADATA +0 -64
  71. ramses_rf-0.22.2.dist-info/RECORD +0 -42
  72. ramses_rf-0.22.2.dist-info/top_level.txt +0 -1
@@ -1,29 +1,17 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- #
4
- """RAMSES RF - a RAMSES-II protocol decoder & analyser.
2
+ """RAMSES RF - Heating devices (e.g. CTL, OTB, BDR, TRV)."""
5
3
 
6
- Heating devices.
7
- """
8
4
  from __future__ import annotations
9
5
 
10
6
  import logging
7
+ from typing import TYPE_CHECKING, Any
11
8
 
12
- from ..const import DEV_TYPE_MAP, __dev_mode__
13
- from ..protocol import Address, Message
14
- from ..schemas import SZ_CLASS, SZ_FAKED
9
+ from ramses_rf.const import DEV_TYPE_MAP
10
+ from ramses_tx.const import DevType
11
+ from ramses_tx.schemas import SZ_CLASS, SZ_FAKED
15
12
 
16
- # skipcq: PY-W2000
17
- from ..const import ( # noqa: F401, isort: skip, pylint: disable=unused-import
18
- I_,
19
- RP,
20
- RQ,
21
- W_,
22
- )
23
-
24
- # skipcq: PY-W2000
25
13
  from .base import ( # noqa: F401, isort: skip, pylint: disable=unused-import
26
- BASE_CLASS_BY_SLUG,
14
+ BASE_CLASS_BY_SLUG as _BASE_CLASS_BY_SLUG,
27
15
  Device,
28
16
  Fakeable,
29
17
  DeviceHeat,
@@ -31,9 +19,9 @@ from .base import ( # noqa: F401, isort: skip, pylint: disable=unused-import
31
19
  DeviceHvac,
32
20
  )
33
21
 
34
- # skipcq: PY-W2000
22
+
35
23
  from .heat import ( # noqa: F401, isort: skip, pylint: disable=unused-import
36
- HEAT_CLASS_BY_SLUG,
24
+ HEAT_CLASS_BY_SLUG as _HEAT_CLASS_BY_SLUG,
37
25
  BdrSwitch,
38
26
  Controller,
39
27
  DhwSensor,
@@ -47,9 +35,9 @@ from .heat import ( # noqa: F401, isort: skip, pylint: disable=unused-import
47
35
  class_dev_heat,
48
36
  )
49
37
 
50
- # skipcq: PY-W2000
38
+
51
39
  from .hvac import ( # noqa: F401, isort: skip, pylint: disable=unused-import
52
- HVAC_CLASS_BY_SLUG,
40
+ HVAC_CLASS_BY_SLUG as _HVAC_CLASS_BY_SLUG,
53
41
  HvacCarbonDioxideSensor,
54
42
  HvacHumiditySensor,
55
43
  HvacRemote,
@@ -58,42 +46,82 @@ from .hvac import ( # noqa: F401, isort: skip, pylint: disable=unused-import
58
46
  class_dev_hvac,
59
47
  )
60
48
 
61
- DEV_MODE = __dev_mode__ # and False
49
+ if TYPE_CHECKING:
50
+ from ramses_rf import Gateway
51
+ from ramses_tx import Address, Message
52
+
53
+
54
+ __all__ = [
55
+ # .base
56
+ "Device",
57
+ "Fakeable",
58
+ "DeviceHeat",
59
+ "HgiGateway",
60
+ "DeviceHvac",
61
+ # .heat
62
+ "BdrSwitch",
63
+ "Controller",
64
+ "DhwSensor",
65
+ "OtbGateway",
66
+ "OutSensor",
67
+ "Temperature",
68
+ "Thermostat",
69
+ "TrvActuator",
70
+ "UfhCircuit",
71
+ "UfhController",
72
+ "class_dev_heat",
73
+ # .hvac
74
+ "HvacCarbonDioxideSensor",
75
+ "HvacHumiditySensor",
76
+ "HvacRemote",
77
+ "HvacVentilator",
78
+ "RfsGateway",
79
+ "class_dev_hvac",
80
+ #
81
+ "best_dev_role",
82
+ "device_factory",
83
+ ]
62
84
 
63
85
  _LOGGER = logging.getLogger(__name__)
64
- if DEV_MODE:
65
- _LOGGER.setLevel(logging.DEBUG)
66
86
 
67
87
 
68
- _CLASS_BY_SLUG = BASE_CLASS_BY_SLUG | HEAT_CLASS_BY_SLUG | HVAC_CLASS_BY_SLUG
88
+ _CLASS_BY_SLUG = _BASE_CLASS_BY_SLUG | _HEAT_CLASS_BY_SLUG | _HVAC_CLASS_BY_SLUG
89
+
90
+ HEAT_DEV_CLASS_BY_SLUG = {
91
+ k: v for k, v in _HEAT_CLASS_BY_SLUG.items() if k is not DevType.HEA
92
+ }
93
+ HVAC_DEV_CLASS_BY_SLUG = {
94
+ k: v for k, v in _HVAC_CLASS_BY_SLUG.items() if k is not DevType.HVC
95
+ }
69
96
 
70
97
 
71
98
  def best_dev_role(
72
99
  dev_addr: Address,
73
100
  *,
74
- msg: Message = None,
101
+ msg: Message | None = None,
75
102
  eavesdrop: bool = False,
76
- **schema,
103
+ **schema: Any,
77
104
  ) -> type[Device]:
78
105
  """Return the best device role (object class) for a given device id/msg/schema.
79
106
 
80
107
  Heat (CH/DHW) devices can reliably be determined by their address type (e.g. '04:').
81
108
  Any device without a known Heat type is considered a HVAC device.
82
109
 
83
- HVAC devices must be explicity typed, or fingerprinted/eavesdropped.
110
+ HVAC devices must be explicitly typed, or fingerprinted/eavesdropped.
84
111
  The generic HVAC class can be promoted later on, when more information is available.
85
112
  """
86
113
 
87
- cls: None | type[Device] = None
88
- slug: None | str = None
114
+ cls: type[Device]
115
+ slug: str
89
116
 
90
117
  try: # convert (say) 'dhw_sensor' to DHW
91
- slug = DEV_TYPE_MAP.slug(schema.get(SZ_CLASS))
118
+ slug = DEV_TYPE_MAP.slug(schema.get(SZ_CLASS)) # type: ignore[arg-type]
92
119
  except KeyError:
93
120
  slug = schema.get(SZ_CLASS)
94
121
 
95
- # a specified device class always takes precidence (even if it is wrong)...
96
- if cls := _CLASS_BY_SLUG.get(slug):
122
+ # a specified device class always takes precedence (even if it is wrong)...
123
+ if slug in _CLASS_BY_SLUG:
124
+ cls = _CLASS_BY_SLUG[slug]
97
125
  _LOGGER.debug(
98
126
  f"Using an explicitly-defined class for: {dev_addr!r} ({cls._SLUG})"
99
127
  )
@@ -101,12 +129,12 @@ def best_dev_role(
101
129
 
102
130
  if dev_addr.type == DEV_TYPE_MAP.HGI:
103
131
  _LOGGER.debug(f"Using the default class for: {dev_addr!r} ({HgiGateway._SLUG})")
104
- return HgiGateway # type: ignore[return-value]
132
+ return HgiGateway
105
133
 
106
134
  try: # or, is it a well-known CH/DHW class, derived from the device type...
107
135
  if cls := class_dev_heat(dev_addr, msg=msg, eavesdrop=eavesdrop):
108
136
  _LOGGER.debug(
109
- f"Using the default Heat class for: {dev_addr!r} ({cls._SLUG})" # type: ignore[attr-defined]
137
+ f"Using the default Heat class for: {dev_addr!r} ({cls._SLUG})"
110
138
  )
111
139
  return cls
112
140
  except TypeError:
@@ -115,7 +143,7 @@ def best_dev_role(
115
143
  try: # or, a HVAC class, eavesdropped from the message code/payload...
116
144
  if cls := class_dev_hvac(dev_addr, msg=msg, eavesdrop=eavesdrop):
117
145
  _LOGGER.debug(
118
- f"Using eavesdropped HVAC class for: {dev_addr!r} ({cls._SLUG})" # type: ignore[attr-defined]
146
+ f"Using eavesdropped HVAC class for: {dev_addr!r} ({cls._SLUG})"
119
147
  )
120
148
  return cls # includes DeviceHvac
121
149
  except TypeError:
@@ -125,10 +153,12 @@ def best_dev_role(
125
153
  _LOGGER.debug(
126
154
  f"Using a promotable HVAC class for: {dev_addr!r} ({DeviceHvac._SLUG})"
127
155
  )
128
- return DeviceHvac # type: ignore[return-value]
156
+ return DeviceHvac
129
157
 
130
158
 
131
- def device_factory(gwy, dev_addr: Address, *, msg: Message = None, **traits) -> Device:
159
+ def device_factory(
160
+ gwy: Gateway, dev_addr: Address, *, msg: Message | None = None, **traits: Any
161
+ ) -> Device:
132
162
  """Return the initial device class for a given device id/msg/traits.
133
163
 
134
164
  Devices of certain classes are promotable to a compatible sub class.