sonnenbatterie 0.7.dev3__tar.gz → 0.7.dev5__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 (37) hide show
  1. {sonnenbatterie-0.7.dev3/sonnenbatterie.egg-info → sonnenbatterie-0.7.dev5}/PKG-INFO +1 -1
  2. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/setup.cfg +1 -1
  3. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie/sonnenbatterie.py +55 -30
  4. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5/sonnenbatterie.egg-info}/PKG-INFO +1 -1
  5. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/LICENSE +0 -0
  6. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/README.md +0 -0
  7. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/pyproject.toml +0 -0
  8. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/setup.py +0 -0
  9. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie/__init__.py +0 -0
  10. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie/const.py +0 -0
  11. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie.egg-info/SOURCES.txt +0 -0
  12. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie.egg-info/dependency_links.txt +0 -0
  13. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie.egg-info/requires.txt +0 -0
  14. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie.egg-info/top_level.txt +0 -0
  15. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie2/__init__.py +0 -0
  16. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie2/const.py +0 -0
  17. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/sonnenbatterie2/sonnenbatterie2.py +0 -0
  18. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_api_v1.py +0 -0
  19. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_api_v2.py +0 -0
  20. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_battery_reserve.py +0 -0
  21. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_battery_reserve_async.py +0 -0
  22. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_operating_mode.py +0 -0
  23. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_operating_mode_api_v2.py +0 -0
  24. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_operating_mode_async.py +0 -0
  25. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_operating_mode_async_api_v2.py +0 -0
  26. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_retrieval_loop.py +0 -0
  27. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_set_flow.py +0 -0
  28. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_set_flow_async.py +0 -0
  29. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_set_flow_v2.py +0 -0
  30. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_set_flow_v2_async.py +0 -0
  31. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_timeofuse.py +0 -0
  32. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_timeofuse_async.py +0 -0
  33. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_timeofuse_lib.py +0 -0
  34. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_timeofuse_v2.py +0 -0
  35. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/test/test_timeofuse_v2_async.py +0 -0
  36. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/timeofuse/__init__.py +0 -0
  37. {sonnenbatterie-0.7.dev3 → sonnenbatterie-0.7.dev5}/timeofuse/timeofuse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sonnenbatterie
3
- Version: 0.7.dev3
3
+ Version: 0.7.dev5
4
4
  Summary: "Access Sonnenbatterie REST API"
5
5
  Home-page: https://github.com/weltmeyer/python_sonnenbatterie
6
6
  Author: Jan Weltmeyer
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = sonnenbatterie
3
- version = 0.7.dev3
3
+ version = 0.7.dev5
4
4
  author = Jan Weltmeyer
5
5
  description = "Access Sonnenbatterie REST API"
6
6
  long_description = file: README.md
@@ -295,46 +295,71 @@ class AsyncSonnenBatterie:
295
295
  if saltResponseCode!=200: #use old variant where no salt is availlable
296
296
  #Old path (no salt): PBKDF2 over sha512(password) + challenge → hex
297
297
  response=hashlib.pbkdf2_hmac('sha512',pw_sha512.encode('utf-8'),challenge.encode('utf-8'),7500,64).hex()
298
- else:#New path (with salt): PBKDF2 over password + salt → HMAC-SHA256(challenge) → hex.
299
- salt_payload = await salt.json()
300
- salt_str = salt_payload["salt"]
301
- try:
302
- if len(salt_str) % 2 == 0 and all(c in string.hexdigits for c in salt_str):
303
- salt_bytes = bytes.fromhex(salt_str)
304
- else:
305
- raise ValueError
306
- except Exception:
307
- try:
308
- salt_bytes = base64.b64decode(salt_str, validate=True)
309
- except Exception:
310
- salt_bytes = salt_str.encode("utf-8")
311
-
312
-
313
- dk = hashlib.pbkdf2_hmac(
314
- "sha512",
315
- self.password.encode("utf-8"), # raw password (not pre-hashed)
316
- salt_bytes,
317
- 7500,
318
- dklen=64
298
+ session = await self._session.post(
299
+ url = self.baseurl+'session',
300
+ data = {"user":self.username,"challenge":challenge,"response":response},
301
+ timeout=self._timeout,
319
302
  )
320
- response = hmac.new(dk, challenge.encode("utf-8"), hashlib.sha256).hexdigest()
303
+ session.raise_for_status()
304
+ token = await session.json()
305
+ self.token = token['authentication_token']
306
+ else:#New path (with salt): PBKDF2 over password + salt → HMAC-SHA256(challenge) → hex.
307
+ await self.create_session_token_new()
321
308
 
322
309
 
323
310
 
324
- session = await self._session.post(
325
- url = self.baseurl+'session',
326
- data = {"user":self.username,"challenge":challenge,"response":response},
327
- timeout=self._timeout,
328
- )
329
- session.raise_for_status()
330
- token = await session.json()
331
- self.token = token['authentication_token']
332
311
 
333
312
  # Inisitalite async API v2
334
313
  if self.sb2 is None:
335
314
  self.sb2 = AsyncSonnenBatterieV2(ip_address=self.ipaddress, api_token=self.token)
336
315
 
337
316
 
317
+ async def create_session_token_new(self):
318
+ # Step 1: challenge
319
+ async with self._session.get(f"{self.baseurl}challenge") as r:
320
+ r.raise_for_status()
321
+ try:
322
+ challenge = await r.json()
323
+ if isinstance(challenge, dict):
324
+ challenge = challenge.get("challenge") or next(iter(challenge.values()))
325
+ except Exception:
326
+ challenge = (await r.text()).strip()
327
+
328
+ # Step 2: salt
329
+ async with self._session.get(f"{self.baseurl}salt/{self.username}") as r:
330
+ r.raise_for_status()
331
+ salt = (await r.json())["salt"]
332
+
333
+ # Step 3: derive key
334
+ pw_sha512_hex = hashlib.sha512(self.password.encode("utf-8")).hexdigest()
335
+ pw_bytes = pw_sha512_hex.encode("utf-8")
336
+ dk = hashlib.pbkdf2_hmac("sha512", pw_bytes, salt.encode("utf-8"), 7500, dklen=64)
337
+ derived_hex = dk.hex()
338
+
339
+ # Step 4: loop: POST /session, maybe retry with new_challenge
340
+ for _ in range(2):
341
+ key = derived_hex.encode("utf-8")
342
+ response = hmac.new(key, challenge.encode("utf-8"), hashlib.sha256).hexdigest()
343
+ payload = {"user": self.username, "challenge": challenge, "response": response}
344
+
345
+ async with self._session.post(f"{self.baseurl}session", json=payload) as r:
346
+ r.raise_for_status()
347
+ data = await r.json()
348
+
349
+ if "new_challenge" in data and data["new_challenge"]:
350
+ challenge = data["new_challenge"]
351
+ continue
352
+
353
+ if "authentication_token" in data and data["authentication_token"]:
354
+ self.token = data["authentication_token"]
355
+
356
+ raise RuntimeError(f"Unexpected /session response: {json.dumps(data)}")
357
+
358
+ raise RuntimeError("Failed to obtain authentication_token")
359
+
360
+
361
+
362
+
338
363
  """ Base functions """
339
364
 
340
365
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sonnenbatterie
3
- Version: 0.7.dev3
3
+ Version: 0.7.dev5
4
4
  Summary: "Access Sonnenbatterie REST API"
5
5
  Home-page: https://github.com/weltmeyer/python_sonnenbatterie
6
6
  Author: Jan Weltmeyer