solarlog-cli 0.6.0__tar.gz → 0.6.1__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 (43) hide show
  1. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.coverage +0 -0
  2. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/PKG-INFO +1 -1
  3. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/pyproject.toml +1 -1
  4. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/src/solarlog_cli/solarlog_client.py +44 -41
  5. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/test_solarlog_cli.py +0 -2
  6. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.devcontainer/devcontainer.json +0 -0
  7. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.github/workflows/pylint.yml +0 -0
  8. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.github/workflows/python-publish.yml +0 -0
  9. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.github/workflows/ruff.yml +0 -0
  10. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.github/workflows/tests.yml +0 -0
  11. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.github/workflows/typing.yml +0 -0
  12. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.gitignore +0 -0
  13. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.vscode/settings.json +0 -0
  14. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/.vscode/tasks.json +0 -0
  15. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/LICENSE +0 -0
  16. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/README.md +0 -0
  17. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/pytest.ini +0 -0
  18. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/requirements.txt +0 -0
  19. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/src/solarlog_cli/__init__.py +0 -0
  20. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/src/solarlog_cli/py.typed +0 -0
  21. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/src/solarlog_cli/solarlog_connector.py +0 -0
  22. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/src/solarlog_cli/solarlog_exceptions.py +0 -0
  23. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/src/solarlog_cli/solarlog_models.py +0 -0
  24. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/__init__.py +0 -0
  25. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/__snapshots__/test_solarlog_cli.ambr +0 -0
  26. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/conftest.py +0 -0
  27. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/basic_data.json +0 -0
  28. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/basic_data_during_update.json +0 -0
  29. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/basic_data_no_power.json +0 -0
  30. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/battery_data.json +0 -0
  31. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/battery_data_without_battery.json +0 -0
  32. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/device_data_1.json +0 -0
  33. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/device_data_2.json +0 -0
  34. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/device_data_3.json +0 -0
  35. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/device_data_4.json +0 -0
  36. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/device_list.json +0 -0
  37. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/device_list_access_denied.json +0 -0
  38. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/energy_per_inverter.json +0 -0
  39. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/extended_data.json +0 -0
  40. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/power_per_inverter.json +0 -0
  41. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/fixtures/user_salts.json +0 -0
  42. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/ruff.toml +0 -0
  43. {solarlog_cli-0.6.0 → solarlog_cli-0.6.1}/tests/syrupy.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: solarlog_cli
3
- Version: 0.6.0
3
+ Version: 0.6.1
4
4
  Summary: Python library to access the Solar-Log
5
5
  Project-URL: Repository, https://github.com/dontinelli/solarlog_cli.git
6
6
  Project-URL: Issues, https://github.com/dontinelli/solarlog_cli/issues
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "solarlog_cli"
3
- version = "0.6.0"
3
+ version = "0.6.1"
4
4
  authors = [
5
5
  { name="dontinelli", email="73341522+dontinelli@users.noreply.github.com" },
6
6
  ]
@@ -22,6 +22,7 @@ from .solarlog_models import SolarlogData
22
22
  SOLARLOG_REQUEST_PAYLOAD = '{ "801": { "170": null } }'
23
23
  _LOGGER = logging.getLogger(__name__)
24
24
 
25
+
25
26
  class Client:
26
27
  """Client class to access Solar-Log."""
27
28
 
@@ -30,7 +31,6 @@ class Client:
30
31
  def __init__(self, host: str, session: ClientSession | None, password: str = "") -> None:
31
32
  self.host: str = host
32
33
  self.password: str = password
33
- self.token: str = ""
34
34
 
35
35
  self.request_timeout = 30
36
36
 
@@ -39,9 +39,9 @@ class Client:
39
39
  else:
40
40
  self.session = session
41
41
 
42
+ self._hashed_pwd: bool = False
42
43
  self._close_session: bool = True
43
44
 
44
-
45
45
  async def test_connection(self) -> bool:
46
46
  """Test the connection to Solar-Log."""
47
47
  if self.session is None:
@@ -68,12 +68,12 @@ class Client:
68
68
 
69
69
  payload: str = f"u=user&p={self.password}"
70
70
 
71
- response = await self.execute_http_request(payload,"login")
71
+ response = await self.execute_http_request(payload, "login")
72
72
 
73
73
  text = await response.text()
74
- _LOGGER.debug("Response: %s",text)
74
+ _LOGGER.debug("Response: %s", text)
75
75
  if text.count("FAILED - User was wrong"):
76
- #Response means, that no password is required
76
+ # Response means, that no password is required
77
77
  self.password = ""
78
78
  return False
79
79
 
@@ -87,19 +87,21 @@ class Client:
87
87
  response = await self.execute_http_request(payload)
88
88
 
89
89
  text = await response.text()
90
- _LOGGER.debug("Response to request for user salts: %s",text)
90
+ _LOGGER.debug("Response to request for user salts: %s", text)
91
91
  r_dict: dict[str, Any] = json.loads(text)
92
92
 
93
- salt: str = r_dict.get('550',{}).get('104')
94
- _LOGGER.debug("Salt to hash pwd: %s",salt)
93
+ salt: str = r_dict.get('550', {}).get('104')
94
+ _LOGGER.debug("Salt to hash pwd: %s", salt)
95
95
 
96
96
  try:
97
97
  if salt != 'QUERY IMPOSSIBLE 000' and salt is not None:
98
- hashed_password = bcrypt.hashpw(self.password.encode(), salt.encode())
98
+ hashed_password = bcrypt.hashpw(
99
+ self.password.encode(), salt.encode())
99
100
  payload = f"u=user&p={hashed_password.decode('utf-8')}"
100
- response = await self.execute_http_request(payload,"login")
101
+ response = await self.execute_http_request(payload, "login")
101
102
  text = await response.text()
102
- _LOGGER.debug("Response of login with hashed pwd: %s",text)
103
+ _LOGGER.debug(
104
+ "Response of login with hashed pwd: %s", text)
103
105
  if text.count("FAILED - Password was wrong"):
104
106
  _LOGGER.debug("Wrong password (hashed)")
105
107
  raise SolarLogAuthenticationError
@@ -107,11 +109,13 @@ class Client:
107
109
  except Exception as exception:
108
110
  raise SolarLogAuthenticationError from exception
109
111
 
110
- self.token = response.cookies["SolarLog"].value
112
+ self._hashed_pwd = True
113
+
114
+ self.session.cookie_jar.update_cookies({"SolarLog": response.cookies["SolarLog"].value})
111
115
 
112
- _LOGGER.debug("response: %s",text)
113
- _LOGGER.debug("cookies: %s",response.cookies)
114
- _LOGGER.debug("Login successful, token: %s",self.token)
116
+ _LOGGER.debug("response: %s", text)
117
+ _LOGGER.debug("cookies: %s", response.cookies)
118
+ _LOGGER.debug("Login successful, token: %s", response.cookies["SolarLog"].value)
115
119
 
116
120
  return True
117
121
 
@@ -124,11 +128,8 @@ class Client:
124
128
  url = f"{self.host}/{path}"
125
129
 
126
130
  header = {"Content-Type": "text/html", "X-SL-CSRF-PROTECTION": "1"}
127
- if self.token != "":
128
- header |= {"Cookie": f"SolarLog={self.token}"}
129
- body = f"token={self.token}; " + body
130
131
 
131
- _LOGGER.debug("HTTP-request header: %s",header)
132
+ _LOGGER.debug("HTTP-request header: %s", header)
132
133
  _LOGGER.debug("HTTP-request body: %s", body)
133
134
 
134
135
  try:
@@ -153,14 +154,14 @@ class Client:
153
154
  {"Content-Type": content_type, "response": text},
154
155
  )
155
156
 
156
- _LOGGER.debug("HTTP-request successful: %s",response)
157
+ _LOGGER.debug("HTTP-request successful: %s", response)
157
158
  return response
158
159
 
159
160
  async def parse_http_response(self, response: ClientResponse) -> dict[str, Any]:
160
161
  """Helper function to parse the HTTP response."""
161
162
 
162
- text = await response.text()
163
- _LOGGER.debug("Parsing http response: %s",text)
163
+ text = await response.text(errors="replace")
164
+ _LOGGER.debug("Parsing http response: %s", text)
164
165
 
165
166
  if text.count('{"QUERY IMPOSSIBLE 000"}'):
166
167
  raise SolarLogUpdateError(f"Server response: {text}")
@@ -188,29 +189,30 @@ class Client:
188
189
  raw_data = raw_data["801"]["170"]
189
190
 
190
191
  data = SolarlogData(
191
- last_updated = datetime.strptime(raw_data["100"], "%d.%m.%y %H:%M:%S"),
192
- power_ac = raw_data["101"],
193
- power_dc = raw_data["102"],
194
- voltage_ac = raw_data["103"],
195
- voltage_dc = raw_data["104"],
196
- yield_day = raw_data["105"],
197
- yield_yesterday = raw_data["106"],
198
- yield_month = raw_data["107"],
199
- yield_year = raw_data["108"],
200
- yield_total = raw_data["109"],
201
- consumption_ac = raw_data["110"],
202
- consumption_day = raw_data["111"],
203
- consumption_yesterday = raw_data["112"],
204
- consumption_month = raw_data["113"],
205
- consumption_year = raw_data["114"],
206
- consumption_total = raw_data["115"],
207
- total_power = raw_data["116"],
192
+ last_updated=datetime.strptime(
193
+ raw_data["100"], "%d.%m.%y %H:%M:%S"),
194
+ power_ac=raw_data["101"],
195
+ power_dc=raw_data["102"],
196
+ voltage_ac=raw_data["103"],
197
+ voltage_dc=raw_data["104"],
198
+ yield_day=raw_data["105"],
199
+ yield_yesterday=raw_data["106"],
200
+ yield_month=raw_data["107"],
201
+ yield_year=raw_data["108"],
202
+ yield_total=raw_data["109"],
203
+ consumption_ac=raw_data["110"],
204
+ consumption_day=raw_data["111"],
205
+ consumption_yesterday=raw_data["112"],
206
+ consumption_month=raw_data["113"],
207
+ consumption_year=raw_data["114"],
208
+ consumption_total=raw_data["115"],
209
+ total_power=raw_data["116"],
208
210
  )
209
211
 
210
212
  return data
211
213
 
212
214
  async def get_battery_data(self) -> list[float]:
213
- """Get power data from Solar-Log"""
215
+ """Get battery data from Solar-Log"""
214
216
 
215
217
  raw_data: dict = await self.parse_http_response(
216
218
  await self.execute_http_request('{ "858": null }')
@@ -227,7 +229,8 @@ class Client:
227
229
  await self.execute_http_request('{ "782": null }')
228
230
  )
229
231
 
230
- data = {int(key): val for key, val in raw_data["782"].items() if val != "0"}
232
+ data = {int(key): val for key,
233
+ val in raw_data["782"].items() if val != "0"}
231
234
 
232
235
  return data
233
236
 
@@ -144,7 +144,6 @@ async def test_login_and_data_retreival(responses: aioresponses) -> None:
144
144
  "http://solarlog.com", password="pwd")
145
145
 
146
146
  assert await solarlog_connector.login()
147
- assert solarlog_connector.client.token == "token"
148
147
 
149
148
  responses.post(
150
149
  "http://solarlog.com/getjp",
@@ -176,7 +175,6 @@ async def test_login_hashed_pwd(responses: aioresponses) -> None:
176
175
  "http://solarlog.com", password="pwd")
177
176
 
178
177
  assert await solarlog_connector.login()
179
- assert solarlog_connector.client.token == "token"
180
178
 
181
179
  await solarlog_connector.client.close()
182
180
  assert solarlog_connector.client.session.closed
File without changes
File without changes
File without changes
File without changes