smartbox 2.1.2__tar.gz → 2.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.
- smartbox-2.2.0/.github/ISSUE_TEMPLATE/new-reseller.md +18 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/.github/workflows/publish-to-pypi.yml +1 -1
- {smartbox-2.1.2 → smartbox-2.2.0}/.github/workflows/python-package.yml +3 -3
- {smartbox-2.1.2 → smartbox-2.2.0}/PKG-INFO +7 -7
- {smartbox-2.1.2 → smartbox-2.2.0}/README.md +6 -6
- {smartbox-2.1.2 → smartbox-2.2.0}/pyproject.toml +1 -1
- {smartbox-2.1.2 → smartbox-2.2.0}/src/smartbox/__init__.py +5 -5
- {smartbox-2.1.2 → smartbox-2.2.0}/src/smartbox/cmd.py +29 -5
- {smartbox-2.1.2 → smartbox-2.2.0}/src/smartbox/error.py +2 -2
- {smartbox-2.1.2 → smartbox-2.2.0}/src/smartbox/models.py +37 -4
- smartbox-2.1.2/src/smartbox/resailer.py → smartbox-2.2.0/src/smartbox/reseller.py +46 -34
- {smartbox-2.1.2 → smartbox-2.2.0}/src/smartbox/session.py +58 -26
- {smartbox-2.1.2 → smartbox-2.2.0}/src/smartbox/socket.py +8 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/src/smartbox/update_manager.py +19 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/conftest.py +8 -8
- smartbox-2.2.0/tests/fixtures/devs/device1/connected.json +3 -0
- smartbox-2.2.0/tests/fixtures/devs/device1/mgr/nodes.json +31 -0
- smartbox-2.2.0/tests/fixtures/devs/device1/pmo/3/samples.json +16 -0
- smartbox-2.2.0/tests/fixtures/devs/device1/pmo/3/setup.json +5 -0
- smartbox-2.2.0/tests/fixtures/devs/device1/pmo/3/status.json +4 -0
- smartbox-2.2.0/tests/fixtures/devs/device2/connected.json +3 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/test_cmd.py +34 -8
- smartbox-2.2.0/tests/test_reseller.py +58 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/test_session.py +98 -21
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/test_update_manager.py +18 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/uv.lock +2 -1
- smartbox-2.1.2/.github/ISSUE_TEMPLATE/new-resailer.md +0 -18
- smartbox-2.1.2/requirements.txt +0 -2
- smartbox-2.1.2/tests/fixtures/devs/device1/mgr/nodes.json +0 -18
- smartbox-2.1.2/tests/test_resailer.py +0 -46
- {smartbox-2.1.2 → smartbox-2.2.0}/.github/FUNDING.yml +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/.github/dependabot.yml +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/.gitignore +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/.pre-commit-config.yaml +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/.vscode/settings.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/CHANGELOG.md +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/CODEOWNERS +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/LICENSE +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/api-notes.md +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/codecov.yml +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/src/smartbox/py.typed +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/__init__.py +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/common.py +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device1/acm/1/samples.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device1/acm/1/setup.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device1/acm/1/status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device1/htr/0/samples.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device1/htr/0/setup.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device1/htr/0/status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device1/htr_system/power_limit.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device1/mgr/away_status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/0/samples.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/0/setup.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/0/status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/1/samples.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/1/setup.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/1/status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/2/samples.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/2/setup.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/2/status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/3/samples.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/3/setup.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/3/status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/4/samples.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/4/setup.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/4/status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/5/samples.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/5/setup.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_mod/5/status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/htr_system/power_limit.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/mgr/away_status.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs/device2/mgr/nodes.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/devs.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/grouped_devs.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/groups/test_home/guest_users.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/fixtures/test_path.json +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tests/test_models.py +0 -0
- {smartbox-2.1.2 → smartbox-2.2.0}/tox.ini +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: New reseller
|
|
3
|
+
about: Add a new available reseller.
|
|
4
|
+
title: "[RESELLER] New available reseller"
|
|
5
|
+
labels: reseller
|
|
6
|
+
assignees: Delmael
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
> [!NOTE]
|
|
11
|
+
> If you do not see your current reseller in the available list, you can ask to add it. We cannot ensure your device go through this platform
|
|
12
|
+
|
|
13
|
+
* [ ] I have check with the `smartbox resellers` command that my reseller is not already present
|
|
14
|
+
* **Website url (mandatory)** :
|
|
15
|
+
* Name of the resellers:
|
|
16
|
+
* API url :
|
|
17
|
+
* Basic auth headers :
|
|
18
|
+
* Serial id:
|
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
with:
|
|
23
23
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
24
24
|
- name: Set up Python ${{ env.PYTHON_VERSION }}
|
|
25
|
-
uses: actions/setup-python@v5.
|
|
25
|
+
uses: actions/setup-python@v5.5.0
|
|
26
26
|
with:
|
|
27
27
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
28
28
|
- name: Build a binary wheel and a source tarball
|
|
@@ -25,7 +25,7 @@ jobs:
|
|
|
25
25
|
with:
|
|
26
26
|
python-version: ${{ matrix.python-version }}
|
|
27
27
|
- name: Set up Python ${{ matrix.python-version }}
|
|
28
|
-
uses: actions/setup-python@v5.
|
|
28
|
+
uses: actions/setup-python@v5.5.0
|
|
29
29
|
with:
|
|
30
30
|
python-version: ${{ matrix.python-version }}
|
|
31
31
|
- name: Install the project
|
|
@@ -47,7 +47,7 @@ jobs:
|
|
|
47
47
|
with:
|
|
48
48
|
python-version: ${{ matrix.python-version }}
|
|
49
49
|
- name: Set up Python ${{ matrix.python-version }}
|
|
50
|
-
uses: actions/setup-python@v5.
|
|
50
|
+
uses: actions/setup-python@v5.5.0
|
|
51
51
|
with:
|
|
52
52
|
python-version: ${{ matrix.python-version }}
|
|
53
53
|
- name: Install the project
|
|
@@ -70,7 +70,7 @@ jobs:
|
|
|
70
70
|
python-version: ${{ matrix.python-version }}
|
|
71
71
|
|
|
72
72
|
- name: Set up Python ${{ matrix.python-version }}
|
|
73
|
-
uses: actions/setup-python@v5.
|
|
73
|
+
uses: actions/setup-python@v5.5.0
|
|
74
74
|
with:
|
|
75
75
|
python-version: ${{ matrix.python-version }}
|
|
76
76
|
- name: Install the project
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: smartbox
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Python API to control heating 'smart boxes'
|
|
5
5
|
Project-URL: Homepage, https://github.com/ajtudela/smartbox
|
|
6
6
|
Project-URL: Issues, https://github.com/ajtudela/smartbox/issues
|
|
@@ -53,7 +53,7 @@ A few common options are required for all commands:
|
|
|
53
53
|
Verbose logging can be enabled with the `-v`/`--verbose` flag.
|
|
54
54
|
|
|
55
55
|
### Optional options
|
|
56
|
-
These options are useful if your
|
|
56
|
+
These options are useful if your reseller is not configured.
|
|
57
57
|
|
|
58
58
|
* `-b`/`--base-auth-creds`: An HTTP Basic Auth credential used to do initial
|
|
59
59
|
authentication with the server. Use the base64 encoded string directly. See
|
|
@@ -61,7 +61,7 @@ These options are useful if your resailer is not configured.
|
|
|
61
61
|
* `-a`/`--api-name`: The API name for your heater vendor. This is visible in
|
|
62
62
|
the 'API Host' entry in the 'Version' menu item in the mobile app/web app. If
|
|
63
63
|
the host name is of the form `api-foo.xxxx` or `api.xxxx` use the values
|
|
64
|
-
`api-foo` or `api` respectively. The
|
|
64
|
+
`api-foo` or `api` respectively. The reseller has to be declared in the package.
|
|
65
65
|
* `-r`/`--x-referer`: The referer of your request.
|
|
66
66
|
* `-i`/`--x-serial-id`: The serial-id of your request.
|
|
67
67
|
|
|
@@ -132,11 +132,11 @@ The `health-check` command can be used to know if the API is alived
|
|
|
132
132
|
|
|
133
133
|
smartbox <auth options...> health-check
|
|
134
134
|
|
|
135
|
-
### List available
|
|
136
|
-
The `
|
|
137
|
-
If your
|
|
135
|
+
### List available resellers
|
|
136
|
+
The `resellers` command can be used to know which resellers has an automatic configuration.
|
|
137
|
+
If your reseller is not present you can raise an issue in github, or use the optional options.
|
|
138
138
|
|
|
139
|
-
smartbox <auth options...>
|
|
139
|
+
smartbox <auth options...> resellers
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
See [api-notes.md](./api-notes.md) for notes on REST and socket.io endpoints.
|
|
@@ -31,7 +31,7 @@ A few common options are required for all commands:
|
|
|
31
31
|
Verbose logging can be enabled with the `-v`/`--verbose` flag.
|
|
32
32
|
|
|
33
33
|
### Optional options
|
|
34
|
-
These options are useful if your
|
|
34
|
+
These options are useful if your reseller is not configured.
|
|
35
35
|
|
|
36
36
|
* `-b`/`--base-auth-creds`: An HTTP Basic Auth credential used to do initial
|
|
37
37
|
authentication with the server. Use the base64 encoded string directly. See
|
|
@@ -39,7 +39,7 @@ These options are useful if your resailer is not configured.
|
|
|
39
39
|
* `-a`/`--api-name`: The API name for your heater vendor. This is visible in
|
|
40
40
|
the 'API Host' entry in the 'Version' menu item in the mobile app/web app. If
|
|
41
41
|
the host name is of the form `api-foo.xxxx` or `api.xxxx` use the values
|
|
42
|
-
`api-foo` or `api` respectively. The
|
|
42
|
+
`api-foo` or `api` respectively. The reseller has to be declared in the package.
|
|
43
43
|
* `-r`/`--x-referer`: The referer of your request.
|
|
44
44
|
* `-i`/`--x-serial-id`: The serial-id of your request.
|
|
45
45
|
|
|
@@ -110,11 +110,11 @@ The `health-check` command can be used to know if the API is alived
|
|
|
110
110
|
|
|
111
111
|
smartbox <auth options...> health-check
|
|
112
112
|
|
|
113
|
-
### List available
|
|
114
|
-
The `
|
|
115
|
-
If your
|
|
113
|
+
### List available resellers
|
|
114
|
+
The `resellers` command can be used to know which resellers has an automatic configuration.
|
|
115
|
+
If your reseller is not present you can raise an issue in github, or use the optional options.
|
|
116
116
|
|
|
117
|
-
smartbox <auth options...>
|
|
117
|
+
smartbox <auth options...> resellers
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
See [api-notes.md](./api-notes.md) for notes on REST and socket.io endpoints.
|
|
@@ -5,7 +5,7 @@ import importlib.metadata
|
|
|
5
5
|
from .error import (
|
|
6
6
|
APIUnavailableError,
|
|
7
7
|
InvalidAuthError,
|
|
8
|
-
|
|
8
|
+
ResellerNotExistError,
|
|
9
9
|
SmartboxError,
|
|
10
10
|
)
|
|
11
11
|
from .models import (
|
|
@@ -21,7 +21,7 @@ from .models import (
|
|
|
21
21
|
NodeStatus,
|
|
22
22
|
SmartboxNodeType,
|
|
23
23
|
)
|
|
24
|
-
from .
|
|
24
|
+
from .reseller import AvailableResellers, SmartboxReseller
|
|
25
25
|
from .session import AsyncSmartboxSession, Session
|
|
26
26
|
from .socket import SocketSession
|
|
27
27
|
from .update_manager import UpdateManager
|
|
@@ -33,7 +33,7 @@ __all__ = [
|
|
|
33
33
|
"APIUnavailableError",
|
|
34
34
|
"AcmNodeStatus",
|
|
35
35
|
"AsyncSmartboxSession",
|
|
36
|
-
"
|
|
36
|
+
"AvailableResellers",
|
|
37
37
|
"DefaultNodeStatus",
|
|
38
38
|
"GuestUser",
|
|
39
39
|
"Guests",
|
|
@@ -44,11 +44,11 @@ __all__ = [
|
|
|
44
44
|
"NodeFactoryOptions",
|
|
45
45
|
"NodeSetup",
|
|
46
46
|
"NodeStatus",
|
|
47
|
-
"
|
|
47
|
+
"ResellerNotExistError",
|
|
48
48
|
"Session",
|
|
49
49
|
"SmartboxError",
|
|
50
50
|
"SmartboxNodeType",
|
|
51
|
-
"
|
|
51
|
+
"SmartboxReseller",
|
|
52
52
|
"SocketSession",
|
|
53
53
|
"UpdateManager",
|
|
54
54
|
]
|
|
@@ -7,7 +7,7 @@ from typing import Any
|
|
|
7
7
|
from aiohttp import ClientSession
|
|
8
8
|
import asyncclick as click
|
|
9
9
|
|
|
10
|
-
from smartbox.
|
|
10
|
+
from smartbox.reseller import AvailableResellers
|
|
11
11
|
from smartbox.session import AsyncSmartboxSession
|
|
12
12
|
from smartbox.socket import SocketSession
|
|
13
13
|
|
|
@@ -277,6 +277,21 @@ async def device_away_status(ctx) -> None:
|
|
|
277
277
|
_pretty_print(device_away_status)
|
|
278
278
|
|
|
279
279
|
|
|
280
|
+
@smartbox.command(help="Show device connected status")
|
|
281
|
+
@click.pass_context
|
|
282
|
+
async def device_connected_status(ctx) -> None:
|
|
283
|
+
"""Show device connected status."""
|
|
284
|
+
session = ctx.obj["session"]
|
|
285
|
+
devices = await session.get_devices()
|
|
286
|
+
|
|
287
|
+
for device in devices:
|
|
288
|
+
print(f"{device['name']} (dev_id: {device['dev_id']})")
|
|
289
|
+
device_away_status = await session.get_device_connected(
|
|
290
|
+
device["dev_id"],
|
|
291
|
+
)
|
|
292
|
+
_pretty_print(device_away_status)
|
|
293
|
+
|
|
294
|
+
|
|
280
295
|
@smartbox.command(
|
|
281
296
|
help="Set device away_status (pass settings as extra args, e.g. away=true)",
|
|
282
297
|
)
|
|
@@ -379,10 +394,19 @@ async def health_check(ctx) -> None:
|
|
|
379
394
|
_pretty_print(health)
|
|
380
395
|
|
|
381
396
|
|
|
382
|
-
@smartbox.command(help="Get the
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
397
|
+
@smartbox.command(help="Get version of the API.")
|
|
398
|
+
@click.pass_context
|
|
399
|
+
async def api_version(ctx) -> None:
|
|
400
|
+
"""Get the version of the API."""
|
|
401
|
+
session = ctx.obj["session"]
|
|
402
|
+
version = await session.api_version()
|
|
403
|
+
_pretty_print(version)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
@smartbox.command(help="Get the availables resellers.")
|
|
407
|
+
def resellers() -> None:
|
|
408
|
+
"""Get the availables resellers."""
|
|
409
|
+
for item in AvailableResellers.resellers.items():
|
|
386
410
|
print(item)
|
|
387
411
|
|
|
388
412
|
|
|
@@ -47,7 +47,15 @@ class NodeExtraOptions(BaseModel):
|
|
|
47
47
|
boost_time: int
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
class
|
|
50
|
+
class PmoSetup(BaseModel):
|
|
51
|
+
"""Pmo node setup."""
|
|
52
|
+
|
|
53
|
+
circuit_type: int
|
|
54
|
+
power_limit: int
|
|
55
|
+
reverse: bool
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class DefaultNodeSetup(BaseModel):
|
|
51
59
|
"""NodeSetup model."""
|
|
52
60
|
|
|
53
61
|
sync_status: str
|
|
@@ -66,6 +74,16 @@ class NodeSetup(BaseModel):
|
|
|
66
74
|
extra_options: NodeExtraOptions
|
|
67
75
|
|
|
68
76
|
|
|
77
|
+
class NodeSetup(RootModel[DefaultNodeSetup | PmoSetup]):
|
|
78
|
+
"""NodeSetup model."""
|
|
79
|
+
|
|
80
|
+
root: DefaultNodeSetup | PmoSetup
|
|
81
|
+
|
|
82
|
+
def __getattr__(self, name: str) -> DefaultNodeSetup | PmoSetup:
|
|
83
|
+
"""Get the root model directly."""
|
|
84
|
+
return getattr(self.root, name)
|
|
85
|
+
|
|
86
|
+
|
|
69
87
|
class DefaultNodeStatus(BaseModel):
|
|
70
88
|
"""Default Node Status."""
|
|
71
89
|
|
|
@@ -196,17 +214,26 @@ class Homes(RootModel[list[Home]]):
|
|
|
196
214
|
|
|
197
215
|
|
|
198
216
|
class Sample(BaseModel):
|
|
199
|
-
"""Sample model."""
|
|
217
|
+
"""Pmo Sample model."""
|
|
200
218
|
|
|
201
219
|
t: int
|
|
220
|
+
counter: float
|
|
202
221
|
temp: str
|
|
203
|
-
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class PmoSample(BaseModel):
|
|
225
|
+
"""Default Sample."""
|
|
226
|
+
|
|
227
|
+
t: int
|
|
228
|
+
counter: float
|
|
229
|
+
max: int
|
|
230
|
+
min: int
|
|
204
231
|
|
|
205
232
|
|
|
206
233
|
class Samples(BaseModel):
|
|
207
234
|
"""Samples model."""
|
|
208
235
|
|
|
209
|
-
samples: list[Sample]
|
|
236
|
+
samples: list[PmoSample | Sample]
|
|
210
237
|
|
|
211
238
|
|
|
212
239
|
class Token(BaseModel):
|
|
@@ -229,3 +256,9 @@ class Guests(BaseModel):
|
|
|
229
256
|
"""Guests model."""
|
|
230
257
|
|
|
231
258
|
guest_users: list[GuestUser]
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class DeviceConnected(BaseModel):
|
|
262
|
+
"""Connected status of devices."""
|
|
263
|
+
|
|
264
|
+
connected: bool
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Reseller of Smartbox."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
from typing import ClassVar
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel, ValidationError
|
|
7
7
|
|
|
8
|
-
from smartbox.error import
|
|
8
|
+
from smartbox.error import ResellerNotExistError
|
|
9
9
|
|
|
10
10
|
SMARTBOX_GENERIC_BASIC_AUTH = "NTRiY2NiZmI0MWE5YTUxMTNmMDQ4OGQwOnZkaXZkaQ=="
|
|
11
11
|
_LOGGER = logging.getLogger(__name__)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class
|
|
15
|
-
"""Model of Smartbox
|
|
14
|
+
class SmartboxReseller(BaseModel):
|
|
15
|
+
"""Model of Smartbox Reseller config."""
|
|
16
16
|
|
|
17
17
|
name: str = "Smartbox"
|
|
18
18
|
web_url: str = ""
|
|
@@ -21,43 +21,55 @@ class SmartboxResailer(BaseModel):
|
|
|
21
21
|
serial_id: int = 0
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class
|
|
25
|
-
"""
|
|
24
|
+
class AvailableResellers:
|
|
25
|
+
"""Resellers that have been verified."""
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
"api":
|
|
27
|
+
resellers: ClassVar[dict[str, SmartboxReseller]] = {
|
|
28
|
+
"api": SmartboxReseller(
|
|
29
29
|
name="Helki",
|
|
30
30
|
web_url="https://app.helki.com/",
|
|
31
31
|
api_url="api",
|
|
32
32
|
serial_id=1,
|
|
33
33
|
),
|
|
34
|
-
"api-
|
|
34
|
+
"api-ehc": SmartboxReseller(
|
|
35
|
+
name="Electric Heating Company",
|
|
36
|
+
web_url="https://control.electric-heatingcompany.co.uk/",
|
|
37
|
+
api_url="api-ehc",
|
|
38
|
+
serial_id=3,
|
|
39
|
+
),
|
|
40
|
+
"api-climastar": SmartboxReseller(
|
|
35
41
|
name="Climastar",
|
|
36
42
|
web_url="https://avantwifi.climastar.es/",
|
|
37
43
|
api_url="api-climastar",
|
|
38
44
|
serial_id=5,
|
|
39
45
|
),
|
|
40
|
-
"api-elnur":
|
|
46
|
+
"api-elnur": SmartboxReseller(
|
|
41
47
|
name="Elnur",
|
|
42
48
|
web_url="https://remotecontrol.elnur.es/",
|
|
43
49
|
api_url="api-elnur",
|
|
44
50
|
serial_id=7,
|
|
45
51
|
),
|
|
46
|
-
"api-hjm":
|
|
52
|
+
"api-hjm": SmartboxReseller(
|
|
47
53
|
name="HJM",
|
|
48
54
|
web_url="https://api.calorhjm.com/",
|
|
49
55
|
api_url="api-hjm",
|
|
50
56
|
serial_id=10,
|
|
51
57
|
),
|
|
52
|
-
"api-
|
|
58
|
+
"api-evconfort": SmartboxReseller(
|
|
59
|
+
name="Electrorad",
|
|
60
|
+
web_url="https://app.controls-electrorad.co.uk/",
|
|
61
|
+
api_url="api-evconfort",
|
|
62
|
+
serial_id=12,
|
|
63
|
+
),
|
|
64
|
+
"api-haverland": SmartboxReseller(
|
|
53
65
|
name="Haverland",
|
|
54
66
|
web_url="https://i2control.haverland.com/",
|
|
55
67
|
api_url="api-haverland",
|
|
56
68
|
basic_auth="NTU2ZDc0MWI3OGUzYmU5YjU2NjA3NTQ4OnZkaXZkaQ==",
|
|
57
69
|
serial_id=14,
|
|
58
70
|
),
|
|
59
|
-
"api-lhz":
|
|
60
|
-
name="Technotherm",
|
|
71
|
+
"api-lhz": SmartboxReseller(
|
|
72
|
+
name="Technotherm / Lucht-LHZ",
|
|
61
73
|
web_url="https://ttiapp.technotherm.com/",
|
|
62
74
|
api_url="api-lhz",
|
|
63
75
|
serial_id=16,
|
|
@@ -72,7 +84,7 @@ class AvailableResailers:
|
|
|
72
84
|
serial_id: int | None = None,
|
|
73
85
|
name: str = "Smartbox",
|
|
74
86
|
) -> None:
|
|
75
|
-
"""Check if
|
|
87
|
+
"""Check if reseller is already available or try to create one."""
|
|
76
88
|
self._api_url = api_url
|
|
77
89
|
self._basic_auth = basic_auth
|
|
78
90
|
self._web_url = web_url
|
|
@@ -80,27 +92,27 @@ class AvailableResailers:
|
|
|
80
92
|
self._name = name
|
|
81
93
|
|
|
82
94
|
@property
|
|
83
|
-
def
|
|
84
|
-
"""Get the
|
|
85
|
-
|
|
86
|
-
if
|
|
95
|
+
def reseller(self) -> SmartboxReseller:
|
|
96
|
+
"""Get the reseller."""
|
|
97
|
+
reseller = self.resellers.get(self._api_url, None)
|
|
98
|
+
if reseller is None:
|
|
87
99
|
if (
|
|
88
100
|
self._basic_auth is None
|
|
89
101
|
or self._web_url is None
|
|
90
102
|
or self._serial_id is None
|
|
91
103
|
):
|
|
92
|
-
msg = "This
|
|
93
|
-
raise
|
|
104
|
+
msg = "This reseller is not yet available or some arguments are missing."
|
|
105
|
+
raise ResellerNotExistError(msg)
|
|
94
106
|
try:
|
|
95
107
|
_LOGGER.debug(
|
|
96
|
-
"Creating a new
|
|
108
|
+
"Creating a new reseller api_url (%s), name=%s, web_url %s, basic_auth=%s, serial_id=%s",
|
|
97
109
|
self._api_url,
|
|
98
110
|
self._name,
|
|
99
111
|
self._web_url,
|
|
100
112
|
self._basic_auth,
|
|
101
113
|
self._serial_id,
|
|
102
114
|
)
|
|
103
|
-
|
|
115
|
+
reseller = SmartboxReseller(
|
|
104
116
|
api_url=self._api_url,
|
|
105
117
|
basic_auth=self._basic_auth,
|
|
106
118
|
web_url=self._web_url,
|
|
@@ -108,26 +120,26 @@ class AvailableResailers:
|
|
|
108
120
|
name=self._name,
|
|
109
121
|
)
|
|
110
122
|
except ValidationError as e:
|
|
111
|
-
raise
|
|
123
|
+
raise ResellerNotExistError from e
|
|
112
124
|
_LOGGER.debug(
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
125
|
+
"Reseller api_url (%s), name=%s, web_url %s",
|
|
126
|
+
reseller.api_url,
|
|
127
|
+
reseller.name,
|
|
128
|
+
reseller.web_url,
|
|
117
129
|
)
|
|
118
|
-
return
|
|
130
|
+
return reseller
|
|
119
131
|
|
|
120
132
|
@property
|
|
121
133
|
def api_url(self) -> str:
|
|
122
134
|
"""Get the api sub domain url."""
|
|
123
|
-
return self.
|
|
135
|
+
return self.reseller.api_url
|
|
124
136
|
|
|
125
137
|
@property
|
|
126
138
|
def name(self) -> str:
|
|
127
|
-
"""Get the name of
|
|
128
|
-
return self.
|
|
139
|
+
"""Get the name of reseller."""
|
|
140
|
+
return self.reseller.name
|
|
129
141
|
|
|
130
142
|
@property
|
|
131
143
|
def web_url(self) -> str:
|
|
132
|
-
"""Get the public websit of the
|
|
133
|
-
return self.
|
|
144
|
+
"""Get the public websit of the reseller."""
|
|
145
|
+
return self.reseller.web_url
|