homeconnect-watcher 0.0.12.dev1__tar.gz → 0.0.12.dev3__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 (60) hide show
  1. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/PKG-INFO +6 -6
  2. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/README.md +5 -5
  3. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/_version.py +2 -2
  4. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/client/appliance.py +7 -8
  5. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/client/client.py +8 -6
  6. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/event.py +3 -3
  7. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/exporter/postgres.py +6 -0
  8. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher.egg-info/PKG-INFO +6 -6
  9. homeconnect_watcher-0.0.12.dev3/tests/conftest.py +115 -0
  10. homeconnect_watcher-0.0.12.dev3/tests/db/views/test_view_appliances.py +36 -0
  11. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/db/views/test_view_events.py +14 -14
  12. homeconnect_watcher-0.0.12.dev3/tests/db/views/test_view_session.py +144 -0
  13. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/exporter/test_postgres.py +1 -1
  14. homeconnect_watcher-0.0.12.dev1/tests/conftest.py +0 -115
  15. homeconnect_watcher-0.0.12.dev1/tests/db/views/test_view_appliances.py +0 -36
  16. homeconnect_watcher-0.0.12.dev1/tests/db/views/test_view_session.py +0 -144
  17. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/.github/workflows/ci.yaml +0 -0
  18. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/.github/workflows/publish.yaml +0 -0
  19. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/.gitignore +0 -0
  20. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/.pre-commit-config.yaml +0 -0
  21. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/LICENSE +0 -0
  22. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/pyproject.toml +0 -0
  23. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/setup.cfg +0 -0
  24. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/__init__.py +0 -0
  25. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/api.py +0 -0
  26. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/cli.py +0 -0
  27. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/client/__init__.py +0 -0
  28. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/db/__init__.py +0 -0
  29. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/db/client.py +0 -0
  30. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/db/utils.py +0 -0
  31. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/db/view.py +0 -0
  32. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/exceptions.py +0 -0
  33. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/exporter/__init__.py +0 -0
  34. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/exporter/base.py +0 -0
  35. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/exporter/file.py +0 -0
  36. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/read.py +0 -0
  37. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/sql/0_appliances.sql +0 -0
  38. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/sql/1_events.sql +0 -0
  39. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/sql/2_raw_events_active.sql +0 -0
  40. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/sql/3_raw_events_with_session_id.sql +0 -0
  41. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/sql/4_sessions.sql +0 -0
  42. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/trigger.py +0 -0
  43. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/utils/__init__.py +0 -0
  44. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/utils/logging.py +0 -0
  45. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/utils/metrics.py +0 -0
  46. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/utils/retry.py +0 -0
  47. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher/utils/timeout.py +0 -0
  48. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher.egg-info/SOURCES.txt +0 -0
  49. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher.egg-info/dependency_links.txt +0 -0
  50. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher.egg-info/entry_points.txt +0 -0
  51. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher.egg-info/requires.txt +0 -0
  52. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/src/homeconnect_watcher.egg-info/top_level.txt +0 -0
  53. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/client/test_client.py +0 -0
  54. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/db/test_db_client.py +0 -0
  55. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/db/test_views.py +0 -0
  56. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/db/views/conftest.py +0 -0
  57. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/exporter/test_file.py +0 -0
  58. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/test_event.py +0 -0
  59. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/utils/test_retry.py +0 -0
  60. {homeconnect_watcher-0.0.12.dev1 → homeconnect_watcher-0.0.12.dev3}/tests/utils/test_timeout.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: homeconnect-watcher
3
- Version: 0.0.12.dev1
3
+ Version: 0.0.12.dev3
4
4
  Summary: Python service that listens to HomeConnect event and logs them.
5
5
  Author-email: Rogier van der Geer <rogier@vander-geer.nl>
6
6
  License: MIT
@@ -102,7 +102,7 @@ Status changes (e.g. "DoorState")
102
102
 
103
103
  ```
104
104
  event:STATUS
105
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.LocalControlActive","level":"hint","timestamp":1676897835,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.LocalControlActive","value":true},{"handling":"none","key":"BSH.Common.Status.RemoteControlActive","level":"hint","timestamp":1676897835,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.RemoteControlActive","value":false}]}
105
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.LocalControlActive","level":"hint","timestamp":1676897835.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.LocalControlActive","value":true},{"handling":"none","key":"BSH.Common.Status.RemoteControlActive","level":"hint","timestamp":1676897835.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.RemoteControlActive","value":false}]}
106
106
  id:SIEMENS-WM14T6H9NL-AB1234567890
107
107
  ```
108
108
 
@@ -112,7 +112,7 @@ Event (e.g. "Preheat finished")
112
112
 
113
113
  ```
114
114
  event:EVENT
115
- data:{"items":[{"timestamp":1642001123,"handling":"none","key":"BSH.Common.Event.ProgramFinished","value":"BSH.Common.EnumType.EventPresentState.Present","level":"hint"}],"haId":"SIEMENS-WM14T6H9NL-AB1234567890"}
115
+ data:{"items":[{"timestamp":1642001123.000,"handling":"none","key":"BSH.Common.Event.ProgramFinished","value":"BSH.Common.EnumType.EventPresentState.Present","level":"hint"}],"haId":"SIEMENS-WM14T6H9NL-AB1234567890"}
116
116
  id:SIEMENS-WM14T6H9NL-AB1234567890
117
117
  ```
118
118
 
@@ -122,7 +122,7 @@ Value changes
122
122
 
123
123
  ```
124
124
  event:NOTIFY
125
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897836,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected","value":"LaundryCare.Washer.Program.DelicatesSilk"}]}
125
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897836.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected","value":"LaundryCare.Washer.Program.DelicatesSilk"}]}
126
126
  id:SIEMENS-WM14T6H9NL-AB1234567890
127
127
  ```
128
128
 
@@ -132,7 +132,7 @@ Connection to home appliance re-established
132
132
 
133
133
  ```
134
134
  event:CONNECTED
135
- data:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Connected","level":"hint","timestamp":1676897865,"value":true}
135
+ data:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Connected","level":"hint","timestamp":1676897865.000,"value":true}
136
136
  id:SIEMENS-WT8HXM90NL-AB1234567890
137
137
  ```
138
138
 
@@ -142,7 +142,7 @@ Connection to home appliance lost or not possible
142
142
 
143
143
  ```
144
144
  event:DISCONNECTED
145
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Disconnected","level":"hint","timestamp":1676897981,"value":true}
145
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Disconnected","level":"hint","timestamp":1676897981.000,"value":true}
146
146
  id:SIEMENS-WM14T6H9NL-AB1234567890
147
147
  ```
148
148
 
@@ -74,7 +74,7 @@ Status changes (e.g. "DoorState")
74
74
 
75
75
  ```
76
76
  event:STATUS
77
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.LocalControlActive","level":"hint","timestamp":1676897835,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.LocalControlActive","value":true},{"handling":"none","key":"BSH.Common.Status.RemoteControlActive","level":"hint","timestamp":1676897835,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.RemoteControlActive","value":false}]}
77
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.LocalControlActive","level":"hint","timestamp":1676897835.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.LocalControlActive","value":true},{"handling":"none","key":"BSH.Common.Status.RemoteControlActive","level":"hint","timestamp":1676897835.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.RemoteControlActive","value":false}]}
78
78
  id:SIEMENS-WM14T6H9NL-AB1234567890
79
79
  ```
80
80
 
@@ -84,7 +84,7 @@ Event (e.g. "Preheat finished")
84
84
 
85
85
  ```
86
86
  event:EVENT
87
- data:{"items":[{"timestamp":1642001123,"handling":"none","key":"BSH.Common.Event.ProgramFinished","value":"BSH.Common.EnumType.EventPresentState.Present","level":"hint"}],"haId":"SIEMENS-WM14T6H9NL-AB1234567890"}
87
+ data:{"items":[{"timestamp":1642001123.000,"handling":"none","key":"BSH.Common.Event.ProgramFinished","value":"BSH.Common.EnumType.EventPresentState.Present","level":"hint"}],"haId":"SIEMENS-WM14T6H9NL-AB1234567890"}
88
88
  id:SIEMENS-WM14T6H9NL-AB1234567890
89
89
  ```
90
90
 
@@ -94,7 +94,7 @@ Value changes
94
94
 
95
95
  ```
96
96
  event:NOTIFY
97
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897836,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected","value":"LaundryCare.Washer.Program.DelicatesSilk"}]}
97
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897836.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected","value":"LaundryCare.Washer.Program.DelicatesSilk"}]}
98
98
  id:SIEMENS-WM14T6H9NL-AB1234567890
99
99
  ```
100
100
 
@@ -104,7 +104,7 @@ Connection to home appliance re-established
104
104
 
105
105
  ```
106
106
  event:CONNECTED
107
- data:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Connected","level":"hint","timestamp":1676897865,"value":true}
107
+ data:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Connected","level":"hint","timestamp":1676897865.000,"value":true}
108
108
  id:SIEMENS-WT8HXM90NL-AB1234567890
109
109
  ```
110
110
 
@@ -114,7 +114,7 @@ Connection to home appliance lost or not possible
114
114
 
115
115
  ```
116
116
  event:DISCONNECTED
117
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Disconnected","level":"hint","timestamp":1676897981,"value":true}
117
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Disconnected","level":"hint","timestamp":1676897981.000,"value":true}
118
118
  id:SIEMENS-WM14T6H9NL-AB1234567890
119
119
  ```
120
120
 
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.0.12.dev1'
16
- __version_tuple__ = version_tuple = (0, 0, 12, 'dev1')
15
+ __version__ = version = '0.0.12.dev3'
16
+ __version_tuple__ = version_tuple = (0, 0, 12, 'dev3')
@@ -14,14 +14,13 @@ class HomeConnectAppliance:
14
14
  self.appliance_id = appliance_id
15
15
  self.appliance_type = appliance_type
16
16
  self._available_programs: list[str] | None = None
17
- self._last_update: float = time()
17
+ self._last_update: dict[str, float] = dict()
18
18
 
19
19
  def __repr__(self) -> str:
20
20
  return f"HomeConnect{self.appliance_type}(ha_id={repr(self.appliance_id)})"
21
21
 
22
- @property
23
- def time_since_update(self) -> float:
24
- return time() - self._last_update
22
+ def time_since_update(self, request_type: str) -> float:
23
+ return time() - self._last_update.get(request_type, 0)
25
24
 
26
25
  async def get_available_programs(self) -> list[str] | None:
27
26
  if self._available_programs is None:
@@ -43,24 +42,24 @@ class HomeConnectAppliance:
43
42
  return self._available_programs if len(self._available_programs) else None
44
43
 
45
44
  async def get_status(self) -> HomeConnectEvent:
46
- self._last_update: float = time()
45
+ self._last_update["status"] = time()
47
46
  response = await self.client._get(f"/{self.appliance_id}/status")
48
47
  return HomeConnectEvent.from_request(request="STATUS", appliance_id=self.appliance_id, response=response)
49
48
 
50
49
  async def get_settings(self) -> HomeConnectEvent:
51
- self._last_update: float = time()
50
+ self._last_update["settings"] = time()
52
51
  response = await self.client._get(f"/{self.appliance_id}/settings")
53
52
  return HomeConnectEvent.from_request(request="SETTINGS", appliance_id=self.appliance_id, response=response)
54
53
 
55
54
  async def get_active_program(self) -> HomeConnectEvent:
56
- self._last_update: float = time()
55
+ self._last_update["active_program"] = time()
57
56
  response = await self.client._get(f"/{self.appliance_id}/programs/active")
58
57
  return HomeConnectEvent.from_request(
59
58
  request="ACTIVE-PROGRAM", appliance_id=self.appliance_id, response=response
60
59
  )
61
60
 
62
61
  async def get_selected_program(self) -> HomeConnectEvent:
63
- self._last_update: float = time()
62
+ self._last_update["selected_program"] = time()
64
63
  response = await self.client._get(f"/{self.appliance_id}/programs/selected")
65
64
  return HomeConnectEvent.from_request(
66
65
  request="SELECTED-PROGRAM", appliance_id=self.appliance_id, response=response
@@ -192,17 +192,19 @@ class HomeConnectClient:
192
192
  if trigger is None:
193
193
  return
194
194
  appliance = await self.get_appliance(trigger.appliance_id)
195
- if trigger.interval and appliance.time_since_update < 300:
196
- return # If the trigger is an interval trigger, only do requests if last requests were 5 minutes ago.
197
195
  if trigger.status:
198
- yield await appliance.get_status()
196
+ if not trigger.interval or appliance.time_since_update("status") >= 300:
197
+ yield await appliance.get_status()
199
198
  if trigger.settings:
200
- yield await appliance.get_settings()
199
+ if not trigger.interval or appliance.time_since_update("settings") >= 300:
200
+ yield await appliance.get_settings()
201
201
  if await appliance.get_available_programs(): # Only if the appliance supports programs.
202
202
  if trigger.active_program:
203
- yield await appliance.get_active_program()
203
+ if not trigger.interval or appliance.time_since_update("active_program") >= 300:
204
+ yield await appliance.get_active_program()
204
205
  if trigger.selected_program:
205
- yield await appliance.get_selected_program()
206
+ if not trigger.interval or appliance.time_since_update("selected_program") >= 300:
207
+ yield await appliance.get_selected_program()
206
208
 
207
209
  def _load_token(self) -> OAuth2Token | None:
208
210
  """Load the OAuth token from file."""
@@ -9,7 +9,7 @@ from homeconnect_watcher.trigger import Trigger
9
9
  @dataclass
10
10
  class HomeConnectEvent:
11
11
  event: str
12
- timestamp: int
12
+ timestamp: float
13
13
  appliance_id: str | None = None
14
14
  data: dict[str, ...] | None = None
15
15
  error: dict[str, ...] | None = None
@@ -28,7 +28,7 @@ class HomeConnectEvent:
28
28
  error = None
29
29
  return HomeConnectEvent(
30
30
  event=f"{request}-REQUEST",
31
- timestamp=int(time()),
31
+ timestamp=time(),
32
32
  appliance_id=appliance_id,
33
33
  data=data,
34
34
  error=error,
@@ -36,7 +36,7 @@ class HomeConnectEvent:
36
36
 
37
37
  @classmethod
38
38
  def from_stream(cls, stream: bytes) -> "HomeConnectEvent":
39
- data = {"timestamp": int(time())}
39
+ data = {"timestamp": time()}
40
40
  for line in stream.decode("utf-8").split("\n"):
41
41
  if line.startswith("data:") and len(line) > 5:
42
42
  data["data"] = loads(line[5:])
@@ -24,3 +24,9 @@ class PGExporter(BaseExporter, WatcherDBClient):
24
24
  if datetime.now() > self._next_refresh:
25
25
  self.refresh_views()
26
26
  self._next_refresh: datetime = datetime.now() + self.refresh_interval
27
+
28
+ def bulk_export(self, events: list[HomeConnectEvent]) -> None:
29
+ self.write_events(events)
30
+ if datetime.now() > self._next_refresh:
31
+ self.refresh_views()
32
+ self._next_refresh: datetime = datetime.now() + self.refresh_interval
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: homeconnect-watcher
3
- Version: 0.0.12.dev1
3
+ Version: 0.0.12.dev3
4
4
  Summary: Python service that listens to HomeConnect event and logs them.
5
5
  Author-email: Rogier van der Geer <rogier@vander-geer.nl>
6
6
  License: MIT
@@ -102,7 +102,7 @@ Status changes (e.g. "DoorState")
102
102
 
103
103
  ```
104
104
  event:STATUS
105
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.LocalControlActive","level":"hint","timestamp":1676897835,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.LocalControlActive","value":true},{"handling":"none","key":"BSH.Common.Status.RemoteControlActive","level":"hint","timestamp":1676897835,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.RemoteControlActive","value":false}]}
105
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.LocalControlActive","level":"hint","timestamp":1676897835.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.LocalControlActive","value":true},{"handling":"none","key":"BSH.Common.Status.RemoteControlActive","level":"hint","timestamp":1676897835.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.RemoteControlActive","value":false}]}
106
106
  id:SIEMENS-WM14T6H9NL-AB1234567890
107
107
  ```
108
108
 
@@ -112,7 +112,7 @@ Event (e.g. "Preheat finished")
112
112
 
113
113
  ```
114
114
  event:EVENT
115
- data:{"items":[{"timestamp":1642001123,"handling":"none","key":"BSH.Common.Event.ProgramFinished","value":"BSH.Common.EnumType.EventPresentState.Present","level":"hint"}],"haId":"SIEMENS-WM14T6H9NL-AB1234567890"}
115
+ data:{"items":[{"timestamp":1642001123.000,"handling":"none","key":"BSH.Common.Event.ProgramFinished","value":"BSH.Common.EnumType.EventPresentState.Present","level":"hint"}],"haId":"SIEMENS-WM14T6H9NL-AB1234567890"}
116
116
  id:SIEMENS-WM14T6H9NL-AB1234567890
117
117
  ```
118
118
 
@@ -122,7 +122,7 @@ Value changes
122
122
 
123
123
  ```
124
124
  event:NOTIFY
125
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897836,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected","value":"LaundryCare.Washer.Program.DelicatesSilk"}]}
125
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897836.000,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected","value":"LaundryCare.Washer.Program.DelicatesSilk"}]}
126
126
  id:SIEMENS-WM14T6H9NL-AB1234567890
127
127
  ```
128
128
 
@@ -132,7 +132,7 @@ Connection to home appliance re-established
132
132
 
133
133
  ```
134
134
  event:CONNECTED
135
- data:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Connected","level":"hint","timestamp":1676897865,"value":true}
135
+ data:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Connected","level":"hint","timestamp":1676897865.000,"value":true}
136
136
  id:SIEMENS-WT8HXM90NL-AB1234567890
137
137
  ```
138
138
 
@@ -142,7 +142,7 @@ Connection to home appliance lost or not possible
142
142
 
143
143
  ```
144
144
  event:DISCONNECTED
145
- data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Disconnected","level":"hint","timestamp":1676897981,"value":true}
145
+ data:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Disconnected","level":"hint","timestamp":1676897981.000,"value":true}
146
146
  id:SIEMENS-WM14T6H9NL-AB1234567890
147
147
  ```
148
148
 
@@ -0,0 +1,115 @@
1
+ from asyncio import get_event_loop
2
+
3
+ from dotenv import load_dotenv
4
+ from pytest import fixture
5
+ from pytest_asyncio import fixture as async_fixture
6
+
7
+ from homeconnect_watcher.client import HomeConnectClient, HomeConnectAppliance
8
+ from homeconnect_watcher.client.client import HomeConnectSimulationClient
9
+ from homeconnect_watcher.db import WatcherDBClient
10
+ from homeconnect_watcher.event import HomeConnectEvent
11
+
12
+
13
+ @fixture(scope="session", autouse=True)
14
+ def dotenv():
15
+ load_dotenv()
16
+
17
+
18
+ @fixture(scope="session")
19
+ def event_loop():
20
+ loop = get_event_loop()
21
+ yield loop
22
+ loop.close()
23
+
24
+
25
+ @async_fixture(scope="session")
26
+ async def client(tmp_path_factory) -> HomeConnectClient:
27
+ result = HomeConnectSimulationClient(token_cache=tmp_path_factory.mktemp("cache") / "token")
28
+ await result.authenticate(username="user", password="password")
29
+ return result
30
+
31
+
32
+ @async_fixture(scope="session")
33
+ async def appliance(client: HomeConnectClient) -> HomeConnectAppliance:
34
+ appliances = await client.appliances
35
+ for app in appliances:
36
+ if app.appliance_type == "Washer":
37
+ return app
38
+ raise RuntimeError("No washers available.")
39
+
40
+
41
+ STREAM_EVENTS = [
42
+ b'event:EVENT\ndata:{"items":[{"timestamp":1642001123,"handling":"none","key":"BSH.Common.Event.ProgramFinished","value":"BSH.Common.EnumType.EventPresentState.Present","level":"hint"}],"haId":"SIEMENS-WM14T6H9NL-AB1234567890"}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
43
+ b"event:KEEP-ALIVE\ndata:\n\n",
44
+ b"event:KEEP-ALIVE\ndata:\n\n",
45
+ b"event:KEEP-ALIVE\ndata:\n\n",
46
+ b"event: KEEP-ALIVE\ndata:\n\n", # Simulator events have spaces.
47
+ b'event: STATUS\ndata: {"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.LocalControlActive","level":"hint","timestamp":1676897835,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.LocalControlActive","value":true},{"handling":"none","key":"BSH.Common.Status.RemoteControlActive","level":"hint","timestamp":1676897835,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.RemoteControlActive","value":false}]}\nid: SIEMENS-WM14T6H9NL-AB1234567890\n\n',
48
+ b'event:NOTIFY\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897836,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected","value":"LaundryCare.Washer.Program.DelicatesSilk"}]}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
49
+ b'event:NOTIFY\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"LaundryCare.Washer.Option.SpinSpeed","level":"hint","timestamp":1676897836,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected/options/LaundryCare.Washer.Option.SpinSpeed","value":"LaundryCare.Washer.EnumType.SpinSpeed.RPM600"},{"handling":"none","key":"LaundryCare.Washer.Option.Temperature","level":"hint","timestamp":1676897836,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected/options/LaundryCare.Washer.Option.Temperature","value":"LaundryCare.Washer.EnumType.Temperature.GC30"}]}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
50
+ b'event:NOTIFY\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Option.FinishInRelative","level":"hint","timestamp":1676897837,"unit":"seconds","uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected/options/BSH.Common.Option.FinishInRelative","value":2580}]}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
51
+ b'event:NOTIFY\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897837,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected","value":"LaundryCare.Washer.Program.Wool"}]}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
52
+ b'event:NOTIFY\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"LaundryCare.Washer.Option.SpinSpeed","level":"hint","timestamp":1676897837,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected/options/LaundryCare.Washer.Option.SpinSpeed","value":"LaundryCare.Washer.EnumType.SpinSpeed.RPM800"}]}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
53
+ b'event:NOTIFY\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Option.FinishInRelative","level":"hint","timestamp":1676897838,"unit":"seconds","uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected/options/BSH.Common.Option.FinishInRelative","value":2400}]}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
54
+ b'event:STATUS\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.DoorState","level":"hint","timestamp":1676897842,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.DoorState","value":"BSH.Common.EnumType.DoorState.Closed"}]}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
55
+ b'event:STATUS\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.DoorState","level":"hint","timestamp":1676897845,"uri":"/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.DoorState","value":"BSH.Common.EnumType.DoorState.Open"}]}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
56
+ b'event:CONNECTED\ndata:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Connected","level":"hint","timestamp":1676897865,"value":true}\nid:SIEMENS-WT8HXM90NL-AB1234567890\n\n',
57
+ b"event:KEEP-ALIVE\ndata:\n\n",
58
+ b'event:STATUS\ndata:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Status.RemoteControlStartAllowed","level":"hint","timestamp":1676897868,"uri":"/api/homeappliances/SIEMENS-WT8HXM90NL-AB1234567890/status/BSH.Common.Status.RemoteControlStartAllowed","value":false}]}\nid:SIEMENS-WT8HXM90NL-AB1234567890\n\n',
59
+ b'event:NOTIFY\ndata:{"haId":"SIEMENS-WT8HXM90NL-AB1234567890","items":[{"handling":"none","key":"BSH.Common.Root.ActiveProgram","level":"hint","timestamp":1676897868,"uri":"/api/homeappliances/SIEMENS-WT8HXM90NL-AB1234567890/programs/active","value":null},{"handling":"none","key":"BSH.Common.Root.SelectedProgram","level":"hint","timestamp":1676897868,"uri":"/api/homeappliances/SIEMENS-WT8HXM90NL-AB1234567890/programs/selected","value":"LaundryCare.Dryer.Program.Cotton"}]}\nid:SIEMENS-WT8HXM90NL-AB1234567890\n\n',
60
+ b"event:KEEP-ALIVE\ndata:\n\n",
61
+ b"event:KEEP-ALIVE\ndata:\n\n",
62
+ b'event:DISCONNECTED\ndata:{"haId":"SIEMENS-WM14T6H9NL-AB1234567890","handling":"none","key":"BSH.Common.Appliance.Disconnected","level":"hint","timestamp":1676897981,"value":true}\nid:SIEMENS-WM14T6H9NL-AB1234567890\n\n',
63
+ b"event:KEEP-ALIVE\ndata:\n\n",
64
+ ]
65
+
66
+
67
+ JSON_EVENTS = [
68
+ '{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "CONNECTED", "timestamp": 1642062149.0}',
69
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "CONNECTED", "timestamp": 1678086769.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "handling": "none", "key": "BSH.Common.Appliance.Connected", "level": "hint", "timestamp": 1678086769.0, "value": true}}',
70
+ '{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "DISCONNECTED", "timestamp": 1642272958.0}',
71
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "DISCONNECTED", "timestamp": 1678523735.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "handling": "none", "key": "BSH.Common.Appliance.Disconnected", "level": "hint", "timestamp": 1678523735.0, "value": true}}',
72
+ '{"appliance_id": "SIEMENS-WT8HXM90NL-AB1234567890", "event": "EVENT", "timestamp": 1642099217.0, "data": {"items": [{"timestamp": 1642099216.0, "handling": "none", "key": "BSH.Common.Event.ProgramFinished", "value": "BSH.Common.EnumType.EventPresentState.Present", "level": "hint"}], "haId": "SIEMENS-WT8HXM90NL-AB1234567890"}}',
73
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "EVENT", "timestamp": 1676105965.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "ConsumerProducts.CoffeeMaker.Event.DripTrayFull", "level": "alert", "timestamp": 1676105965.0, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}',
74
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "NOTIFY", "timestamp": 1674156563.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "BSH.Common.Option.ProgramProgress", "level": "hint", "timestamp": 1674156563.0, "unit": "%", "uri": "/api/homeappliances/SIEMENS-TI9553X1RW-AB1234567890/programs/active/options/BSH.Common.Option.ProgramProgress", "value": 31}]}}',
75
+ '{"appliance_id": "SIEMENS-WT8HXM90NL-AB1234567890", "event": "NOTIFY", "timestamp": 1642002626.0, "data": {"items": [{"timestamp": 1642002626.0, "handling": "none", "uri": "/api/homeappliances/SIEMENS-WT8HXM90NL-AB1234567890/programs/active/options/BSH.Common.Option.RemainingProgramTime", "key": "BSH.Common.Option.RemainingProgramTime", "unit": "seconds", "value": 17460, "level": "hint"}], "haId": "SIEMENS-WT8HXM90NL-AB1234567890"}}',
76
+ '{"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "NOTIFY", "timestamp": 1642090703.0, "data": {"items": [{"timestamp": 1642090703.0, "handling": "none", "uri": "/api/homeappliances/SIEMENS-EX877LVV5E-AB1234567890/programs/active/options/BSH.Common.Option.ElapsedProgramTime", "key": "BSH.Common.Option.ElapsedProgramTime", "unit": "seconds", "value": 72, "level": "hint"}], "haId": "SIEMENS-EX877LVV5E-AB1234567890"}}',
77
+ '{"appliance_id": "SIEMENS-WT8HXM90NL-AB1234567890", "event": "STATUS", "timestamp": 1642087522.0, "data": {"items": [{"timestamp": 1642087522.0, "handling": "none", "uri": "/api/homeappliances/SIEMENS-WT8HXM90NL-AB1234567890/status/BSH.Common.Status.LocalControlActive", "key": "BSH.Common.Status.LocalControlActive", "value": true, "level": "hint"}, {"timestamp": 1642087522.0, "handling": "none", "uri": "/api/homeappliances/SIEMENS-WT8HXM90NL-AB1234567890/status/BSH.Common.Status.RemoteControlActive", "key": "BSH.Common.Status.RemoteControlActive", "value": false, "level": "hint"}], "haId": "SIEMENS-WT8HXM90NL-AB1234567890"}}',
78
+ '{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "STATUS", "timestamp": 1642001123.0, "data": {"items": [{"timestamp": 1642001123.0, "handling": "none", "uri": "/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.OperationState", "key": "BSH.Common.Status.OperationState", "value": "BSH.Common.EnumType.OperationState.Finished", "level": "hint"}, {"timestamp": 1642001123.0, "handling": "none", "uri": "/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/status/BSH.Common.Status.DoorState", "key": "BSH.Common.Status.DoorState", "value": "BSH.Common.EnumType.DoorState.Closed", "level": "hint"}], "haId": "SIEMENS-WM14T6H9NL-AB1234567890"}}',
79
+ '{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "ACTIVE-PROGRAM-REQUEST", "timestamp": 1677680171.0, "data": {"key": "LaundryCare.Washer.Program.DelicatesSilk", "options": [{"key": "LaundryCare.Common.Option.LoadRecommendation", "value": 2000, "unit": "gram"}, {"key": "LaundryCare.Common.Option.VarioPerfect", "value": "LaundryCare.Common.EnumType.VarioPerfect.Off"}, {"key": "LaundryCare.Washer.Option.IDos1DosingLevel", "value": "LaundryCare.Washer.EnumType.IDosingLevel.Light"}, {"key": "LaundryCare.Washer.Option.IDos2DosingLevel", "value": "LaundryCare.Washer.EnumType.IDosingLevel.Light"}, {"key": "LaundryCare.Washer.Option.LessIroning", "value": false}, {"key": "LaundryCare.Washer.Option.Prewash", "value": false}, {"key": "LaundryCare.Washer.Option.SpinSpeed", "value": "LaundryCare.Washer.EnumType.SpinSpeed.RPM600"}, {"key": "LaundryCare.Washer.Option.Temperature", "value": "LaundryCare.Washer.EnumType.Temperature.GC30"}, {"key": "LaundryCare.Washer.Option.WaterAndRinsePlus", "value": "LaundryCare.Washer.EnumType.WaterAndRinsePlus.Off"}, {"key": "BSH.Common.Option.ProgramProgress", "value": 0, "unit": "%"}, {"key": "BSH.Common.Option.RemainingProgramTime", "value": 0, "unit": "seconds"}, {"key": "BSH.Common.Option.RemainingProgramTimeIsEstimated", "value": true}, {"key": "LaundryCare.Washer.Option.ProcessPhase", "value": "LaundryCare.Washer.EnumType.ProcessPhase.FinalSpinning"}, {"key": "BSH.Common.Option.EnergyForecast", "value": 60, "unit": "%"}, {"key": "BSH.Common.Option.WaterForecast", "value": 80, "unit": "%"}], "timestamp": 1677680171.0}}',
80
+ '{"appliance_id": "SIEMENS-WT8HXM90NL-AB1234567890", "event": "ACTIVE-PROGRAM-REQUEST", "timestamp": 1678036051.0, "error": {"description": "There is no program active", "key": "SDK.Error.NoProgramActive", "timestamp": 1678036051.0}}',
81
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "ACTIVE-PROGRAM-REQUEST", "timestamp": 1677741033.0, "data": {"key": "ConsumerProducts.CoffeeMaker.Program.CleaningModes.ApplianceOnRinsing", "options": [{"key": "BSH.Common.Option.ProgramProgress", "value": 52, "unit": "%"}], "timestamp": 1677741033.0}}',
82
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "ACTIVE-PROGRAM-REQUEST", "timestamp": 1677742394.0, "data": {"key": "ConsumerProducts.CoffeeMaker.Program.Beverage.Coffee", "options": [{"key": "ConsumerProducts.CoffeeMaker.Option.CoffeeTemperature", "value": "ConsumerProducts.CoffeeMaker.EnumType.CoffeeTemperature.88C"}, {"key": "ConsumerProducts.CoffeeMaker.Option.BeanAmount", "value": "ConsumerProducts.CoffeeMaker.EnumType.BeanAmount.Strong"}, {"key": "ConsumerProducts.CoffeeMaker.Option.FillQuantity", "value": 120, "unit": "ml"}, {"key": "ConsumerProducts.CoffeeMaker.Option.MultipleBeverages", "value": false}, {"key": "ConsumerProducts.CoffeeMaker.Option.FlowRate", "value": "ConsumerProducts.CoffeeMaker.EnumType.FlowRate.Normal"}, {"key": "BSH.Common.Option.ProgramProgress", "value": 0, "unit": "%"}], "timestamp": 1677742394.0}}',
83
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "SELECTED-PROGRAM-REQUEST", "timestamp": 1677848265.0, "error": {"description": "There is no program selected", "key": "SDK.Error.NoProgramSelected", "timestamp": 1677848265.0}}',
84
+ '{"appliance_id": "SIEMENS-WT8HXM90NL-AB1234567890", "event": "SELECTED-PROGRAM-REQUEST", "timestamp": 1677673218.0, "data": {"key": "LaundryCare.Dryer.Program.ColdRefresh.1Piece", "options": [{"key": "BSH.Common.Option.FinishInRelative", "value": 0, "unit": "seconds"}, {"key": "LaundryCare.Dryer.Option.DryingTarget", "value": "LaundryCare.Dryer.EnumType.DryingTarget.CupboardDry"}, {"key": "LaundryCare.Dryer.Option.WrinkleGuard", "value": "LaundryCare.Dryer.EnumType.WrinkleGuard.Min60"}], "timestamp": 1677673218.0}}',
85
+ '{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "SELECTED-PROGRAM-REQUEST", "timestamp": 1678031334.0, "data": {"key": "LaundryCare.Washer.Program.Auto40", "options": [{"key": "LaundryCare.Common.Option.LoadRecommendation", "value": 6000, "unit": "gram"}, {"key": "LaundryCare.Washer.Option.IDos1DosingLevel", "value": "LaundryCare.Washer.EnumType.IDosingLevel.Normal"}, {"key": "LaundryCare.Washer.Option.IDos2DosingLevel", "value": "LaundryCare.Washer.EnumType.IDosingLevel.Normal"}, {"key": "LaundryCare.Washer.Option.SpinSpeed", "value": "LaundryCare.Washer.EnumType.SpinSpeed.Auto"}, {"key": "LaundryCare.Washer.Option.Temperature", "value": "LaundryCare.Washer.EnumType.Temperature.Auto"}], "timestamp": 1678031334.0}}',
86
+ '{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "SETTINGS-REQUEST", "timestamp": 1641970292.0, "error": {"key": "SDK.Error.HomeAppliance.Connection.Initialization.Failed", "description": "HomeAppliance is offline"}}',
87
+ '{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "SETTINGS-REQUEST", "timestamp": 1642000630.0, "data": {"settings": [{"key": "BSH.Common.Setting.PowerState", "value": "BSH.Common.EnumType.PowerState.On"}]}}',
88
+ '{"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "SETTINGS-REQUEST", "timestamp": 1642089087.0, "data": {"settings": [{"key": "BSH.Common.Setting.PowerState", "value": "BSH.Common.EnumType.PowerState.Off"}, {"key": "BSH.Common.Setting.AlarmClock", "value": 0, "unit": "seconds"}, {"key": "BSH.Common.Setting.ChildLock", "value": false}, {"key": "BSH.Common.Setting.TemperatureUnit", "value": "BSH.Common.EnumType.TemperatureUnit.Celsius"}]}}',
89
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "SETTINGS-REQUEST", "timestamp": 1674293120.0, "data": {"settings": [{"key": "BSH.Common.Setting.ChildLock", "value": false}, {"key": "BSH.Common.Setting.PowerState", "value": "BSH.Common.EnumType.PowerState.On"}, {"key": "ConsumerProducts.CoffeeMaker.Setting.CupWarmer", "value": false}]}}',
90
+ '{"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "STATUS-REQUEST", "timestamp": 1642000633.0, "data": {"status": [{"key": "BSH.Common.Status.LocalControlActive", "value": false}, {"key": "BSH.Common.Status.OperationState", "value": "BSH.Common.EnumType.OperationState.Inactive"}, {"key": "BSH.Common.Status.RemoteControlActive", "value": true}]}}',
91
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "STATUS-REQUEST", "timestamp": 1674291950.0, "data": {"status": [{"key": "BSH.Common.Status.OperationState", "value": "BSH.Common.EnumType.OperationState.Ready"}, {"key": "BSH.Common.Status.RemoteControlStartAllowed", "value": false}, {"key": "BSH.Common.Status.LocalControlActive", "value": false}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterRistrettoEspresso", "value": 0}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterCoffee", "value": 1}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterCoffeeAndMilk", "value": 0}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterFrothyMilk", "value": 0}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterHotMilk", "value": 0}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterHotWater", "value": 0, "unit": "ml"}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterPowderCoffee", "value": 1}, {"key": "BSH.Common.Status.DoorState", "value": "BSH.Common.EnumType.DoorState.Closed"}]}}',
92
+ '{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "STATUS-REQUEST", "timestamp": 1677667430.0, "data": {"status": [{"key": "BSH.Common.Status.OperationState", "value": "BSH.Common.EnumType.OperationState.Inactive"}, {"key": "BSH.Common.Status.RemoteControlStartAllowed", "value": true}, {"key": "BSH.Common.Status.LocalControlActive", "value": false}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterRistrettoEspresso", "value": 16}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterCoffee", "value": 38}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterCoffeeAndMilk", "value": 43}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterFrothyMilk", "value": 0}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterHotMilk", "value": 0}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterHotWater", "value": 0, "unit": "ml"}, {"key": "ConsumerProducts.CoffeeMaker.Status.BeverageCounterPowderCoffee", "value": 1}, {"key": "BSH.Common.Status.DoorState", "value": "BSH.Common.EnumType.DoorState.Closed"}], "timestamp": 1677667430.0}}',
93
+ '{"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "SETTINGS-REQUEST", "timestamp": 1702944761.0, "data": {"settings": [{"key": "BSH.Common.Setting.PowerState", "value": "BSH.Common.EnumType.PowerState.Off"}, {"key": "BSH.Common.Setting.AlarmClock", "value": 0, "unit": "seconds"}, {"key": "BSH.Common.Setting.ChildLock", "value": false}, {"key": "BSH.Common.Setting.TemperatureUnit", "value": "BSH.Common.EnumType.TemperatureUnit.Celsius"}]}}',
94
+ '{"appliance_id": null, "event": "KEEP-ALIVE", "timestamp": 1674291950.0}',
95
+ '{"appliance_id": "SIEMENS-WT8HXM90NL-AB1234567890", "event": "SETTINGS-REQUEST", "timestamp": 1682306041.0, "error": {"description": "The rate limit \\"10 successive error calls in 10 minutes\\" was reached. Requests are blocked during the remaining period of 564 seconds.", "key": "429"}}',
96
+ ]
97
+
98
+
99
+ @fixture(scope="function", params=STREAM_EVENTS)
100
+ def stream_event(request) -> bytes:
101
+ return request.param
102
+
103
+
104
+ @fixture(scope="function", params=JSON_EVENTS)
105
+ def event(request) -> HomeConnectEvent:
106
+ return HomeConnectEvent.from_string(request.param)
107
+
108
+
109
+ @fixture(scope="function")
110
+ def db_client(postgresql) -> WatcherDBClient:
111
+ client = WatcherDBClient(
112
+ connection_string=f"postgresql://{postgresql.info.user}:@{postgresql.info.host}:{postgresql.info.port}/{postgresql.info.dbname}"
113
+ )
114
+ with client:
115
+ yield client
@@ -0,0 +1,36 @@
1
+ from pytest import mark
2
+
3
+ from homeconnect_watcher.db import WatcherDBClient
4
+
5
+
6
+ @mark.events(
7
+ """{"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "NOTIFY", "timestamp": 1703264021.0, "data": {"haId": "SIEMENS-EX877LVV5E-AB1234567890", "items": [{"handling": "none", "key": "BSH.Common.Root.SelectedProgram", "level": "hint", "timestamp": 1703264019.0, "uri": "/api/homeappliances/SIEMENS-EX877LVV5E-AB1234567890/programs/selected", "value": "Cooking.Hob.Program.PowerLevelMode"}]}}"""
8
+ )
9
+ def test_hob(db_with_events: WatcherDBClient):
10
+ db_with_events.cursor.execute("SELECT * FROM v_appliances")
11
+ result = db_with_events.cursor.fetchall()
12
+ assert len(result) == 1
13
+ assert result[0] == ("SIEMENS-EX877LVV5E-AB1234567890", "Hob")
14
+
15
+
16
+ @mark.events(
17
+ """{"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "NOTIFY", "timestamp": 1704095918.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "BSH.Common.Root.SelectedProgram", "level": "hint", "timestamp": 1704095918.0, "uri": "/api/homeappliances/SIEMENS-TI9553X1RW-AB1234567890/programs/selected", "value": null}]}}"""
18
+ )
19
+ def test_missing_program(db_with_events: WatcherDBClient):
20
+ """Verify that notifications where no program is selected do not show up."""
21
+ db_with_events.cursor.execute("SELECT * FROM v_appliances")
22
+ result = db_with_events.cursor.fetchall()
23
+ assert len(result) == 0
24
+
25
+
26
+ @mark.events(
27
+ """
28
+ {"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "NOTIFY", "timestamp": 1704095918.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "BSH.Common.Root.SelectedProgram", "level": "hint", "timestamp": 1704095918.0, "uri": "/api/homeappliances/SIEMENS-TI9553X1RW-AB1234567890/programs/selected", "value": null}]}}
29
+ {"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "NOTIFY", "timestamp": 1708587519.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "BSH.Common.Root.SelectedProgram", "level": "hint", "timestamp": 1708587519.0, "uri": "/api/homeappliances/SIEMENS-TI9553X1RW-AB1234567890/programs/selected", "value": "ConsumerProducts.CoffeeMaker.Program.Beverage.Coffee"}, {"handling": "none", "key": "ConsumerProducts.CoffeeMaker.Option.BeanAmount", "level": "hint", "timestamp": 1708587519.0, "uri": "/api/homeappliances/SIEMENS-TI9553X1RW-AB1234567890/programs/selected/options/ConsumerProducts.CoffeeMaker.Option.BeanAmount", "value": "ConsumerProducts.CoffeeMaker.EnumType.BeanAmount.Strong"}, {"handling": "none", "key": "ConsumerProducts.CoffeeMaker.Option.FillQuantity", "level": "hint", "timestamp": 1708587519.0, "unit": "ml", "uri": "/api/homeappliances/SIEMENS-TI9553X1RW-AB1234567890/programs/selected/options/ConsumerProducts.CoffeeMaker.Option.FillQuantity", "value": 140}]}}
30
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "NOTIFY", "timestamp": 1707925134.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "none", "key": "LaundryCare.Common.Option.VarioPerfect", "level": "hint", "timestamp": 1707925131.0, "uri": "/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected/options/LaundryCare.Common.Option.VarioPerfect", "value": "LaundryCare.Common.EnumType.VarioPerfect.Off"}, {"handling": "none", "key": "LaundryCare.Washer.Option.SpinSpeed", "level": "hint", "timestamp": 1707925131.0, "uri": "/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected/options/LaundryCare.Washer.Option.SpinSpeed", "value": "LaundryCare.Washer.EnumType.SpinSpeed.RPM1200"}, {"handling": "none", "key": "LaundryCare.Washer.Option.Temperature", "level": "hint", "timestamp": 1707925131.0, "uri": "/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected/options/LaundryCare.Washer.Option.Temperature", "value": "LaundryCare.Washer.EnumType.Temperature.GC40"}, {"handling": "none", "key": "BSH.Common.Root.SelectedProgram", "level": "hint", "timestamp": 1707925131.0, "uri": "/api/homeappliances/SIEMENS-WM14T6H9NL-AB1234567890/programs/selected", "value": "LaundryCare.Washer.Program.DelicatesSilk"}]}}
31
+ """
32
+ )
33
+ def test_multiple(db_with_events: WatcherDBClient):
34
+ db_with_events.cursor.execute("SELECT * FROM v_appliances")
35
+ result = db_with_events.cursor.fetchall()
36
+ assert len(result) == 2
@@ -6,7 +6,7 @@ from homeconnect_watcher.db import WatcherDBClient
6
6
 
7
7
 
8
8
  @mark.events(
9
- """{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1703406303, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1703406303, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}"""
9
+ """{"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1703406303.1, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1703406303.0, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}"""
10
10
  )
11
11
  def test_single_event(db_with_events: WatcherDBClient):
12
12
  db_with_events.cursor.execute("SELECT * FROM v_events")
@@ -15,7 +15,7 @@ def test_single_event(db_with_events: WatcherDBClient):
15
15
  assert result[0] == (
16
16
  "SIEMENS-WM14T6H9NL-AB1234567890",
17
17
  "ProgramFinished",
18
- datetime(2023, 12, 24, 9, 25, 3, tzinfo=ZoneInfo("Europe/Amsterdam")).astimezone(
18
+ datetime(2023, 12, 24, 9, 25, 3, 100000, tzinfo=ZoneInfo("Europe/Amsterdam")).astimezone(
19
19
  db_with_events.connection.info.timezone
20
20
  ),
21
21
  None,
@@ -24,9 +24,9 @@ def test_single_event(db_with_events: WatcherDBClient):
24
24
 
25
25
  @mark.events(
26
26
  """
27
- {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1703406303, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1703406303, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
28
- {"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "EVENT", "timestamp": 1703412414, "data": {"haId": "SIEMENS-EX877LVV5E-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1703412414, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
29
- {"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "EVENT", "timestamp": 1703412423, "data": {"haId": "SIEMENS-EX877LVV5E-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1703412423, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}
27
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1703406303.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1703406303.0, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
28
+ {"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "EVENT", "timestamp": 1703412414.0, "data": {"haId": "SIEMENS-EX877LVV5E-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1703412414.0, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
29
+ {"appliance_id": "SIEMENS-EX877LVV5E-AB1234567890", "event": "EVENT", "timestamp": 1703412423.0, "data": {"haId": "SIEMENS-EX877LVV5E-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1703412423.0, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}
30
30
  """
31
31
  )
32
32
  def test_multiple_appliances(db_with_events: WatcherDBClient):
@@ -55,13 +55,13 @@ def test_multiple_appliances(db_with_events: WatcherDBClient):
55
55
 
56
56
  @mark.events(
57
57
  """
58
- {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707376385, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707376385, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
59
- {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707376691, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707376691, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}
60
- {"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "EVENT", "timestamp": 1707377425, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "ConsumerProducts.CoffeeMaker.Event.DripTrayFull", "level": "alert", "timestamp": 1707377425, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
61
- {"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "EVENT", "timestamp": 1707377768, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "ConsumerProducts.CoffeeMaker.Event.DripTrayFull", "level": "alert", "timestamp": 1707377768, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}
62
- {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707379832, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707379832, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
63
- {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707379944, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707379944, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}
64
- {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707382275, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707382275, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
58
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707376385.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707376385.0, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
59
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707376691.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707376691.0, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}
60
+ {"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "EVENT", "timestamp": 1707377425.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "ConsumerProducts.CoffeeMaker.Event.DripTrayFull", "level": "alert", "timestamp": 1707377425.0, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
61
+ {"appliance_id": "SIEMENS-TI9553X1RW-AB1234567890", "event": "EVENT", "timestamp": 1707377768.0, "data": {"haId": "SIEMENS-TI9553X1RW-AB1234567890", "items": [{"handling": "none", "key": "ConsumerProducts.CoffeeMaker.Event.DripTrayFull", "level": "alert", "timestamp": 1707377768.0, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}
62
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707379832.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707379832.0, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
63
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707379944.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707379944.0, "value": "BSH.Common.EnumType.EventPresentState.Off"}]}}
64
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707382275.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707382275.0, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
65
65
  """
66
66
  )
67
67
  def test_successive(db_with_events: WatcherDBClient):
@@ -110,8 +110,8 @@ def test_successive(db_with_events: WatcherDBClient):
110
110
 
111
111
  @mark.events(
112
112
  """
113
- {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707466277, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707466277, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
114
- {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "DISCONNECTED", "timestamp": 1707490575, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "handling": "none", "key": "BSH.Common.Appliance.Disconnected", "level": "hint", "timestamp": 1707490575, "value": true}}
113
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "EVENT", "timestamp": 1707466277.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "items": [{"handling": "acknowledge", "key": "BSH.Common.Event.ProgramFinished", "level": "hint", "timestamp": 1707466277.0, "value": "BSH.Common.EnumType.EventPresentState.Present"}]}}
114
+ {"appliance_id": "SIEMENS-WM14T6H9NL-AB1234567890", "event": "DISCONNECTED", "timestamp": 1707490575.0, "data": {"haId": "SIEMENS-WM14T6H9NL-AB1234567890", "handling": "none", "key": "BSH.Common.Appliance.Disconnected", "level": "hint", "timestamp": 1707490575.0, "value": true}}
115
115
  """
116
116
  )
117
117
  def test_end_by_disconnect(db_with_events: WatcherDBClient):