gridx-connector 1.0.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.
@@ -0,0 +1,22 @@
1
+
2
+ The MIT License (MIT)
3
+
4
+ Copyright (c) 2019 Marvin Pinto and contributors
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: gridx-connector
3
+ Version: 1.0.1
4
+ Summary: Connector for GridX to fetch live data from your Photovoltaic System
5
+ Description-Content-Type: text/markdown
6
+ License-File: LICENSE
7
+ Requires-Dist: requests
8
+ Requires-Dist: authlib
9
+ Dynamic: description
10
+ Dynamic: description-content-type
11
+ Dynamic: license-file
12
+ Dynamic: requires-dist
13
+ Dynamic: summary
14
+
15
+ # Gridx Connector
16
+
17
+ ### **<h3 style="text-align: center;">This is not an Offical Gridx Library</h3>**
18
+
19
+ Harness the power of your photovoltaic system with the GridboxConnector library. This versatile tool taps into the same REST API as the official dashboard and app, providing you with direct access to your data from the cloud.<br>
20
+
21
+ Whether you're a developer looking to integrate solar data into your own project, or a power user seeking command-line access, GridboxConnector has you covered. With its dual functionality, you can either embed it into your Python project as a library or use it as a standalone command-line interface (CLI) tool.<br>
22
+
23
+ **Take control of your solar data with GridboxConnector, and unlock the full potential of your photovoltaic system.**<br><br>
24
+ ![Screenshot vom mygridbox](images/screenshot.png)
25
+
26
+ ## Supported Realms
27
+ * Viessmann (will shutdown end of 2025)
28
+ * eon Home
29
+
30
+ ## Installation
31
+
32
+ ```script shell
33
+ pip install gridx-connector
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ You can use the CLI to retrieve live data from the Viessmann Gridbox API or use the GridboxConnector class in your own code. <br>
39
+ Use your Login data from the App or from https://company.gridx.de/login
40
+
41
+ ### CLI
42
+
43
+ ```script shell
44
+ pip install gridx-connector
45
+ viessmann --username <username> --password <password>
46
+ ```
47
+
48
+ ### in your code
49
+
50
+ ```python
51
+ from gridx_connector import GridboxConnector
52
+ from importlib.resources import files
53
+ import json
54
+ from supported_oem import SupportedOEM
55
+
56
+ config_file = files('gridx_connector').joinpath(f'{oem}.config.json')
57
+ with open(config_file, 'r') as file:
58
+ data = json.load(file)
59
+ data["login"]["username"] = username
60
+ data["login"]["password"] = password
61
+ connector = GridboxConnector(data)
62
+ # Retrieve live data
63
+ live_data = connector.retrieve_live_data()
64
+ return live_data
65
+ ```
66
+
67
+ ### Example Output
68
+
69
+ ```script json
70
+ {
71
+ "consumption": 496,
72
+ "directConsumption": 413,
73
+ "directConsumptionEV": 0,
74
+ "directConsumptionHeatPump": 0,
75
+ "directConsumptionHeater": 0,
76
+ "directConsumptionHousehold": 413,
77
+ "directConsumptionRate": 1,
78
+ "grid": 83,
79
+ "gridMeterReadingNegative": 4318200000,
80
+ "gridMeterReadingPositive": 14499360000,
81
+ "measuredAt": "2023-08-04T11:29:43Z",
82
+ "photovoltaic": 413,
83
+ "production": 413,
84
+ "selfConsumption": 413,
85
+ "selfConsumptionRate": 1,
86
+ "selfSufficiencyRate": 0.8326612903225806,
87
+ "selfSupply": 413,
88
+ "totalConsumption": 496
89
+ }
90
+ ```
91
+
92
+ ## Dependencies
93
+
94
+ - requests
95
+
96
+ ## Contributing
97
+
98
+ If you'd like to contribute to gridx-connector, please follow these steps:
99
+
100
+ Fork the repository.
101
+ Create a new branch for your feature or bug fix.
102
+ Make your changes and write tests if possible.
103
+ Run tests and ensure they pass.
104
+ Submit a pull request.
105
+
106
+ ## License
107
+
108
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,94 @@
1
+ # Gridx Connector
2
+
3
+ ### **<h3 style="text-align: center;">This is not an Offical Gridx Library</h3>**
4
+
5
+ Harness the power of your photovoltaic system with the GridboxConnector library. This versatile tool taps into the same REST API as the official dashboard and app, providing you with direct access to your data from the cloud.<br>
6
+
7
+ Whether you're a developer looking to integrate solar data into your own project, or a power user seeking command-line access, GridboxConnector has you covered. With its dual functionality, you can either embed it into your Python project as a library or use it as a standalone command-line interface (CLI) tool.<br>
8
+
9
+ **Take control of your solar data with GridboxConnector, and unlock the full potential of your photovoltaic system.**<br><br>
10
+ ![Screenshot vom mygridbox](images/screenshot.png)
11
+
12
+ ## Supported Realms
13
+ * Viessmann (will shutdown end of 2025)
14
+ * eon Home
15
+
16
+ ## Installation
17
+
18
+ ```script shell
19
+ pip install gridx-connector
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ You can use the CLI to retrieve live data from the Viessmann Gridbox API or use the GridboxConnector class in your own code. <br>
25
+ Use your Login data from the App or from https://company.gridx.de/login
26
+
27
+ ### CLI
28
+
29
+ ```script shell
30
+ pip install gridx-connector
31
+ viessmann --username <username> --password <password>
32
+ ```
33
+
34
+ ### in your code
35
+
36
+ ```python
37
+ from gridx_connector import GridboxConnector
38
+ from importlib.resources import files
39
+ import json
40
+ from supported_oem import SupportedOEM
41
+
42
+ config_file = files('gridx_connector').joinpath(f'{oem}.config.json')
43
+ with open(config_file, 'r') as file:
44
+ data = json.load(file)
45
+ data["login"]["username"] = username
46
+ data["login"]["password"] = password
47
+ connector = GridboxConnector(data)
48
+ # Retrieve live data
49
+ live_data = connector.retrieve_live_data()
50
+ return live_data
51
+ ```
52
+
53
+ ### Example Output
54
+
55
+ ```script json
56
+ {
57
+ "consumption": 496,
58
+ "directConsumption": 413,
59
+ "directConsumptionEV": 0,
60
+ "directConsumptionHeatPump": 0,
61
+ "directConsumptionHeater": 0,
62
+ "directConsumptionHousehold": 413,
63
+ "directConsumptionRate": 1,
64
+ "grid": 83,
65
+ "gridMeterReadingNegative": 4318200000,
66
+ "gridMeterReadingPositive": 14499360000,
67
+ "measuredAt": "2023-08-04T11:29:43Z",
68
+ "photovoltaic": 413,
69
+ "production": 413,
70
+ "selfConsumption": 413,
71
+ "selfConsumptionRate": 1,
72
+ "selfSufficiencyRate": 0.8326612903225806,
73
+ "selfSupply": 413,
74
+ "totalConsumption": 496
75
+ }
76
+ ```
77
+
78
+ ## Dependencies
79
+
80
+ - requests
81
+
82
+ ## Contributing
83
+
84
+ If you'd like to contribute to gridx-connector, please follow these steps:
85
+
86
+ Fork the repository.
87
+ Create a new branch for your feature or bug fix.
88
+ Make your changes and write tests if possible.
89
+ Run tests and ensure they pass.
90
+ Submit a pull request.
91
+
92
+ ## License
93
+
94
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,133 @@
1
+ import requests
2
+ import time
3
+ import logging
4
+ import os
5
+ from authlib.integrations.requests_client import OAuth2Session
6
+ class GridboxConnector:
7
+ id_token: str = ""
8
+ gateways: list[str] = []
9
+ token: dict = {}
10
+ client: OAuth2Session = None
11
+ config: dict = {}
12
+ username: str = ""
13
+ password: str = ""
14
+
15
+ def __init__(self, config, logger=None):
16
+ if not logger:
17
+ self.init_logging()
18
+ self.config = config
19
+ self.login_url = config["urls"]["login"]
20
+ self.login_body = config["login"]
21
+ self.gateway_url = config["urls"]["gateways"]
22
+ self.live_url = config["urls"]["live"]
23
+ self.historical_url = config["urls"]["historical"]
24
+ self.username = os.getenv('USERNAME', self.login_body["username"])
25
+ self.password = os.getenv('PASSWORD', self.login_body["password"])
26
+ self.init_auth()
27
+
28
+ def init_logging(self):
29
+ self.logger = logging.getLogger(__name__)
30
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(funcName)s - %(message)s')
31
+ console_handler = logging.StreamHandler()
32
+ console_handler.setFormatter(formatter)
33
+ self.logger.addHandler(console_handler)
34
+
35
+ def set_loglevel(self, loglevel):
36
+ self.logger.setLevel(logging.getLevelName(loglevel))
37
+
38
+ def get_new_token(self):
39
+ self.token = self.client.fetch_token(
40
+ self.login_url,
41
+ username=self.login_body["username"],
42
+ password=self.login_body["password"],
43
+ grant_type=self.login_body['grant_type'],
44
+ audience=self.login_body['audience'],
45
+ realm=self.login_body['realm'],
46
+ scope=self.login_body['scope']
47
+ )
48
+ self.logger.debug(f"Token expires at {self.token['expires_at']}")
49
+
50
+ # Funktion zum Überprüfen und Erneuern des Tokens
51
+ def ensure_valid_token(self):
52
+ # Prüfe, ob das Token abgelaufen ist
53
+ expires_at = self.token.get('expires_at')
54
+ if expires_at is None or expires_at < time.time():
55
+ self.logger.info("Token ist abgelaufen oder nicht vorhanden, erneuern...")
56
+ self.get_new_token()
57
+
58
+ def get_header(self):
59
+ self.ensure_valid_token()
60
+ return {"Authorization": f'Bearer {self.token["id_token"]}'}
61
+
62
+ def init_auth(self):
63
+ client_id = self.login_body["client_id"]
64
+ client_secret = self.login_body["client_secret"]
65
+ self.client = OAuth2Session(client_id, client_secret, scope=self.login_body["scope"])
66
+ self.get_new_token()
67
+ self.get_gateway_id()
68
+
69
+ def get_gateway_id(self):
70
+ self.gateways.clear()
71
+ try:
72
+ response = requests.get(self.gateway_url, headers=self.get_header())
73
+ response_json = response.json()
74
+ for gateway in response_json:
75
+ self.gateways.append(gateway["system"]["id"])
76
+ except Exception as e:
77
+ self.logger.error(e)
78
+ time.sleep(60)
79
+ self.get_gateway_id()
80
+
81
+ def get_gateways(self):
82
+ return self.gateways
83
+
84
+ def retrieve_live_data_by_id(self, id):
85
+ try:
86
+ response = requests.get(self.live_url.format(id), headers=self.get_header())
87
+ if response.status_code == 200:
88
+ return response
89
+ else:
90
+ self.logger.warning(f"Status Code {response.status_code} with response {response.json()}")
91
+ return response
92
+ except Exception as e:
93
+ self.logger.error(e)
94
+
95
+ def retrieve_live_data(self):
96
+ responses = []
97
+ for id in self.gateways:
98
+ try:
99
+ response = self.retrieve_live_data_by_id(id)
100
+ if response.status_code == 200:
101
+ response_json = response.json()
102
+ responses.append(response_json)
103
+ except Exception as e:
104
+ self.logger.error(e)
105
+ return responses
106
+
107
+ def retrieve_historical_data_by_id(self, id, start, end, resolution='15m'):
108
+ interval = f"{start}/{end}"
109
+ import urllib.parse
110
+ encoded_string = urllib.parse.quote(interval)
111
+ self.historical_url_created = self.historical_url.format(id, encoded_string, resolution)
112
+ try:
113
+ response = requests.get(self.historical_url_created, headers=self.get_header())
114
+ if response.status_code == 200:
115
+ return response
116
+ else:
117
+ self.logger.warning("Requested url {}".format(self.historical_url_created))
118
+ self.logger.warning(f"Status Code {response.status_code} with response {response.json()}")
119
+ return response
120
+ except Exception as e:
121
+ self.logger.error(e)
122
+
123
+ def retrieve_historical_data(self, start, end, resolution='15m'):
124
+ responses = []
125
+ for id in self.gateways:
126
+ try:
127
+ response = self.retrieve_historical_data_by_id(id, start, end, resolution)
128
+ if response.status_code == 200:
129
+ response_json = response.json()
130
+ responses.append(response_json)
131
+ except Exception as e:
132
+ self.logger.error(e)
133
+ return responses
@@ -0,0 +1 @@
1
+ from .GridboxConnector import GridboxConnector
@@ -0,0 +1,29 @@
1
+ import argparse
2
+ from gridx_connector import GridboxConnector
3
+ from importlib.resources import files
4
+ import json
5
+ from supported_oem import SupportedOEM
6
+
7
+ def retrieve_live_data(username: str, password: str, oem: str = SupportedOEM.VIESSMANN):
8
+ config_file = files('gridx_connector').joinpath(f'{oem}.config.json')
9
+ with open(config_file, 'r') as file:
10
+ data = json.load(file)
11
+ data["login"]["username"] = username
12
+ data["login"]["password"] = password
13
+ connector = GridboxConnector(data)
14
+ # Retrieve live data
15
+ live_data = connector.retrieve_live_data()
16
+ return live_data
17
+
18
+ def main():
19
+ parser = argparse.ArgumentParser(description='Retrieve live data from GridX Gridbox.')
20
+ parser.add_argument('-u', '--username', required=True, help='The username to use.')
21
+ parser.add_argument('-p', '--password', required=True, help='The password to use.')
22
+ parser.add_argument('-o', '--oem', default=SupportedOEM.VIESSMANN, help='The OEM configuration to use.', choices=[SupportedOEM.VIESSMANN, SupportedOEM.EON_HOME])
23
+ args = parser.parse_args()
24
+
25
+ live_data = retrieve_live_data(args.username, args.password, args.oem)
26
+ print(live_data)
27
+
28
+ if __name__ == '__main__':
29
+ main()
@@ -0,0 +1,18 @@
1
+ {
2
+ "urls": {
3
+ "login": "https://gridx.eu.auth0.com/oauth/token",
4
+ "gateways": "https://api.gridx.de/gateways",
5
+ "live": "https://api.gridx.de/systems/{}/live",
6
+ "historical": "https://api.gridx.de/systems/{}/historical?interval={}&resolution={}"
7
+ },
8
+ "login": {
9
+ "grant_type": "http://auth0.com/oauth/grant-type/password-realm",
10
+ "username": "username",
11
+ "password": "password!",
12
+ "audience": "my.gridx",
13
+ "client_id": "mG0Phmo7DmnvAqO7p6B0WOYBODppY3cc",
14
+ "scope": "email openid offline_access",
15
+ "realm": "eon-home-authentication-db",
16
+ "client_secret": ""
17
+ }
18
+ }
@@ -0,0 +1,3 @@
1
+ class SupportedOEM:
2
+ VIESSMANN = "viessmann" # Will depracted in future
3
+ EON_HOME = "eon-home"
@@ -0,0 +1,18 @@
1
+ {
2
+ "urls": {
3
+ "login": "https://gridx.eu.auth0.com/oauth/token",
4
+ "gateways": "https://api.gridx.de/gateways",
5
+ "live": "https://api.gridx.de/systems/{}/live",
6
+ "historical": "https://api.gridx.de/systems/{}/historical?interval={}&resolution={}"
7
+ },
8
+ "login": {
9
+ "grant_type": "http://auth0.com/oauth/grant-type/password-realm",
10
+ "username": "username",
11
+ "password": "password!",
12
+ "audience": "my.gridx",
13
+ "client_id": "oZpr934Ikn8OZOHTJEcrgXkjio0I0Q7b",
14
+ "scope": "email openid",
15
+ "realm": "viessmann-authentication-db",
16
+ "client_secret": ""
17
+ }
18
+ }
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: gridx-connector
3
+ Version: 1.0.1
4
+ Summary: Connector for GridX to fetch live data from your Photovoltaic System
5
+ Description-Content-Type: text/markdown
6
+ License-File: LICENSE
7
+ Requires-Dist: requests
8
+ Requires-Dist: authlib
9
+ Dynamic: description
10
+ Dynamic: description-content-type
11
+ Dynamic: license-file
12
+ Dynamic: requires-dist
13
+ Dynamic: summary
14
+
15
+ # Gridx Connector
16
+
17
+ ### **<h3 style="text-align: center;">This is not an Offical Gridx Library</h3>**
18
+
19
+ Harness the power of your photovoltaic system with the GridboxConnector library. This versatile tool taps into the same REST API as the official dashboard and app, providing you with direct access to your data from the cloud.<br>
20
+
21
+ Whether you're a developer looking to integrate solar data into your own project, or a power user seeking command-line access, GridboxConnector has you covered. With its dual functionality, you can either embed it into your Python project as a library or use it as a standalone command-line interface (CLI) tool.<br>
22
+
23
+ **Take control of your solar data with GridboxConnector, and unlock the full potential of your photovoltaic system.**<br><br>
24
+ ![Screenshot vom mygridbox](images/screenshot.png)
25
+
26
+ ## Supported Realms
27
+ * Viessmann (will shutdown end of 2025)
28
+ * eon Home
29
+
30
+ ## Installation
31
+
32
+ ```script shell
33
+ pip install gridx-connector
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ You can use the CLI to retrieve live data from the Viessmann Gridbox API or use the GridboxConnector class in your own code. <br>
39
+ Use your Login data from the App or from https://company.gridx.de/login
40
+
41
+ ### CLI
42
+
43
+ ```script shell
44
+ pip install gridx-connector
45
+ viessmann --username <username> --password <password>
46
+ ```
47
+
48
+ ### in your code
49
+
50
+ ```python
51
+ from gridx_connector import GridboxConnector
52
+ from importlib.resources import files
53
+ import json
54
+ from supported_oem import SupportedOEM
55
+
56
+ config_file = files('gridx_connector').joinpath(f'{oem}.config.json')
57
+ with open(config_file, 'r') as file:
58
+ data = json.load(file)
59
+ data["login"]["username"] = username
60
+ data["login"]["password"] = password
61
+ connector = GridboxConnector(data)
62
+ # Retrieve live data
63
+ live_data = connector.retrieve_live_data()
64
+ return live_data
65
+ ```
66
+
67
+ ### Example Output
68
+
69
+ ```script json
70
+ {
71
+ "consumption": 496,
72
+ "directConsumption": 413,
73
+ "directConsumptionEV": 0,
74
+ "directConsumptionHeatPump": 0,
75
+ "directConsumptionHeater": 0,
76
+ "directConsumptionHousehold": 413,
77
+ "directConsumptionRate": 1,
78
+ "grid": 83,
79
+ "gridMeterReadingNegative": 4318200000,
80
+ "gridMeterReadingPositive": 14499360000,
81
+ "measuredAt": "2023-08-04T11:29:43Z",
82
+ "photovoltaic": 413,
83
+ "production": 413,
84
+ "selfConsumption": 413,
85
+ "selfConsumptionRate": 1,
86
+ "selfSufficiencyRate": 0.8326612903225806,
87
+ "selfSupply": 413,
88
+ "totalConsumption": 496
89
+ }
90
+ ```
91
+
92
+ ## Dependencies
93
+
94
+ - requests
95
+
96
+ ## Contributing
97
+
98
+ If you'd like to contribute to gridx-connector, please follow these steps:
99
+
100
+ Fork the repository.
101
+ Create a new branch for your feature or bug fix.
102
+ Make your changes and write tests if possible.
103
+ Run tests and ensure they pass.
104
+ Submit a pull request.
105
+
106
+ ## License
107
+
108
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,15 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ gridx_connector/GridboxConnector.py
5
+ gridx_connector/__init__.py
6
+ gridx_connector/cli.py
7
+ gridx_connector/eon-home.config.json
8
+ gridx_connector/supported_oem.py
9
+ gridx_connector/viessmann.config.json
10
+ gridx_connector.egg-info/PKG-INFO
11
+ gridx_connector.egg-info/SOURCES.txt
12
+ gridx_connector.egg-info/dependency_links.txt
13
+ gridx_connector.egg-info/entry_points.txt
14
+ gridx_connector.egg-info/requires.txt
15
+ gridx_connector.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ gridx = gridx_connector.cli:main
@@ -0,0 +1,2 @@
1
+ requests
2
+ authlib
@@ -0,0 +1 @@
1
+ gridx_connector
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name='gridx-connector',
5
+ version='1.0.1',
6
+ long_description=open('README.md').read(),
7
+ long_description_content_type='text/markdown',
8
+ description="Connector for GridX to fetch live data from your Photovoltaic System",
9
+ packages=find_packages(),
10
+ install_requires=[
11
+ 'requests',
12
+ 'authlib'
13
+ ],
14
+ package_data={
15
+ 'gridx_connector': ['eon-home.config.json','viessmann.config.json'],
16
+ },
17
+ entry_points={
18
+ 'console_scripts': [
19
+ 'gridx=gridx_connector.cli:main',
20
+ ],
21
+ },
22
+ )