leneda-client 0.4.0__tar.gz → 0.6.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.
- {leneda_client-0.4.0/src/leneda_client.egg-info → leneda_client-0.6.0}/PKG-INFO +6 -2
- {leneda_client-0.4.0 → leneda_client-0.6.0}/README.md +3 -0
- leneda_client-0.6.0/examples/advanced_usage.py +299 -0
- leneda_client-0.6.0/examples/basic_usage.py +160 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/pyproject.toml +3 -3
- leneda_client-0.6.0/requirements.txt +3 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/setup.py +2 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda/client.py +136 -58
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda/exceptions.py +6 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda/models.py +9 -0
- leneda_client-0.6.0/src/leneda/py.typed +0 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda/version.py +1 -1
- {leneda_client-0.4.0 → leneda_client-0.6.0/src/leneda_client.egg-info}/PKG-INFO +6 -2
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda_client.egg-info/SOURCES.txt +1 -0
- leneda_client-0.6.0/src/leneda_client.egg-info/requires.txt +3 -0
- leneda_client-0.6.0/tests/test_client.py +475 -0
- leneda_client-0.4.0/examples/advanced_usage.py +0 -540
- leneda_client-0.4.0/examples/basic_usage.py +0 -163
- leneda_client-0.4.0/requirements.txt +0 -2
- leneda_client-0.4.0/src/leneda_client.egg-info/requires.txt +0 -2
- leneda_client-0.4.0/tests/test_client.py +0 -383
- {leneda_client-0.4.0 → leneda_client-0.6.0}/LICENSE +0 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/MANIFEST.in +0 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/setup.cfg +0 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda/__init__.py +0 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda/obis_codes.py +0 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda_client.egg-info/dependency_links.txt +0 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/src/leneda_client.egg-info/top_level.txt +0 -0
- {leneda_client-0.4.0 → leneda_client-0.6.0}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: leneda-client
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.6.0
|
4
4
|
Summary: Python client for the Leneda energy data platform
|
5
5
|
Home-page: https://github.com/fedus/leneda-client
|
6
6
|
Author: fedus
|
@@ -22,8 +22,9 @@ Classifier: Topic :: Utilities
|
|
22
22
|
Requires-Python: >=3.8
|
23
23
|
Description-Content-Type: text/markdown
|
24
24
|
License-File: LICENSE
|
25
|
-
Requires-Dist:
|
25
|
+
Requires-Dist: aiohttp>=3.9.0
|
26
26
|
Requires-Dist: python-dateutil>=2.8.2
|
27
|
+
Requires-Dist: pytest-asyncio>=0.23.0
|
27
28
|
Dynamic: author
|
28
29
|
Dynamic: author-email
|
29
30
|
Dynamic: classifier
|
@@ -46,6 +47,9 @@ Dynamic: summary
|
|
46
47
|
|
47
48
|
A Python client for interacting with the Leneda energy data platform API.
|
48
49
|
|
50
|
+
PLEASE NOTE: As long as the library is in a version below 1.0.0, breaking changes
|
51
|
+
may also be introduced between minor version bumps.
|
52
|
+
|
49
53
|
## Overview
|
50
54
|
|
51
55
|
This client provides a simple interface to the Leneda API, which allows users to:
|
@@ -7,6 +7,9 @@
|
|
7
7
|
|
8
8
|
A Python client for interacting with the Leneda energy data platform API.
|
9
9
|
|
10
|
+
PLEASE NOTE: As long as the library is in a version below 1.0.0, breaking changes
|
11
|
+
may also be introduced between minor version bumps.
|
12
|
+
|
10
13
|
## Overview
|
11
14
|
|
12
15
|
This client provides a simple interface to the Leneda API, which allows users to:
|
@@ -0,0 +1,299 @@
|
|
1
|
+
"""
|
2
|
+
Advanced usage examples for the Leneda API client.
|
3
|
+
|
4
|
+
This script demonstrates more complex use cases of the Leneda API client,
|
5
|
+
including data analysis, visualization, and error handling.
|
6
|
+
It accepts API credentials via command-line arguments or environment variables.
|
7
|
+
|
8
|
+
Environment variables:
|
9
|
+
LENEDA_API_KEY: Your Leneda API key
|
10
|
+
LENEDA_ENERGY_ID: Your Energy ID
|
11
|
+
|
12
|
+
Usage:
|
13
|
+
python advanced_usage.py --api-key YOUR_API_KEY --energy-id YOUR_ENERGY_ID --metering-point LU-METERING_POINT1
|
14
|
+
python advanced_usage.py --api-key YOUR_API_KEY --energy-id YOUR_ENERGY_ID --metering-point LU-METERING_POINT1 --example 2
|
15
|
+
"""
|
16
|
+
|
17
|
+
import argparse
|
18
|
+
import asyncio
|
19
|
+
import logging
|
20
|
+
import os
|
21
|
+
import sys
|
22
|
+
from datetime import datetime, timedelta
|
23
|
+
from typing import Optional
|
24
|
+
|
25
|
+
import matplotlib.pyplot as plt
|
26
|
+
import pandas as pd
|
27
|
+
|
28
|
+
from leneda import LenedaClient
|
29
|
+
from leneda.models import MeteringData
|
30
|
+
from leneda.obis_codes import ObisCode
|
31
|
+
|
32
|
+
# Set up logging
|
33
|
+
logging.basicConfig(
|
34
|
+
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
35
|
+
)
|
36
|
+
logger = logging.getLogger("leneda_advanced_example")
|
37
|
+
|
38
|
+
|
39
|
+
def parse_arguments() -> argparse.Namespace:
|
40
|
+
"""Parse command-line arguments."""
|
41
|
+
parser = argparse.ArgumentParser(description="Leneda API Client Advanced Usage Example")
|
42
|
+
|
43
|
+
# API credentials
|
44
|
+
parser.add_argument(
|
45
|
+
"--api-key",
|
46
|
+
help="Your Leneda API key (or set LENEDA_API_KEY environment variable)",
|
47
|
+
)
|
48
|
+
parser.add_argument(
|
49
|
+
"--energy-id",
|
50
|
+
help="Your Energy ID (or set LENEDA_ENERGY_ID environment variable)",
|
51
|
+
)
|
52
|
+
|
53
|
+
# Other parameters
|
54
|
+
parser.add_argument(
|
55
|
+
"--metering-point",
|
56
|
+
help="Metering point code (default: LU-METERING_POINT1)",
|
57
|
+
)
|
58
|
+
parser.add_argument(
|
59
|
+
"--example",
|
60
|
+
type=int,
|
61
|
+
default=0,
|
62
|
+
help="Example number to run (0 for all, 1-3 for specific examples)",
|
63
|
+
)
|
64
|
+
parser.add_argument(
|
65
|
+
"--days",
|
66
|
+
type=int,
|
67
|
+
default=7,
|
68
|
+
help="Number of days to retrieve data for (default: 7)",
|
69
|
+
)
|
70
|
+
parser.add_argument(
|
71
|
+
"--year",
|
72
|
+
type=int,
|
73
|
+
default=None,
|
74
|
+
help="Year to analyze (default: current year)",
|
75
|
+
)
|
76
|
+
parser.add_argument(
|
77
|
+
"--threshold",
|
78
|
+
type=float,
|
79
|
+
default=0.0,
|
80
|
+
help="Threshold for anomaly detection (default: 0.0)",
|
81
|
+
)
|
82
|
+
parser.add_argument(
|
83
|
+
"--save-plots",
|
84
|
+
action="store_true",
|
85
|
+
help="Save plots to files instead of displaying them",
|
86
|
+
)
|
87
|
+
parser.add_argument(
|
88
|
+
"--output-dir",
|
89
|
+
default="plots",
|
90
|
+
help="Directory to save plots (default: plots)",
|
91
|
+
)
|
92
|
+
parser.add_argument("--debug", action="store_true", help="Enable debug logging")
|
93
|
+
|
94
|
+
return parser.parse_args()
|
95
|
+
|
96
|
+
|
97
|
+
def get_credentials(args: argparse.Namespace) -> tuple[str, str]:
|
98
|
+
"""Get API credentials from arguments or environment variables."""
|
99
|
+
api_key = args.api_key or os.environ.get("LENEDA_API_KEY")
|
100
|
+
energy_id = args.energy_id or os.environ.get("LENEDA_ENERGY_ID")
|
101
|
+
|
102
|
+
if not api_key:
|
103
|
+
logger.error(
|
104
|
+
"API key not provided. Use --api-key or set LENEDA_API_KEY environment variable."
|
105
|
+
)
|
106
|
+
sys.exit(1)
|
107
|
+
|
108
|
+
if not energy_id:
|
109
|
+
logger.error(
|
110
|
+
"Energy ID not provided. Use --energy-id or set LENEDA_ENERGY_ID environment variable."
|
111
|
+
)
|
112
|
+
sys.exit(1)
|
113
|
+
|
114
|
+
return api_key, energy_id
|
115
|
+
|
116
|
+
|
117
|
+
def convert_to_dataframe(data: MeteringData) -> pd.DataFrame:
|
118
|
+
"""Convert MeteringData to a pandas DataFrame."""
|
119
|
+
df = pd.DataFrame(
|
120
|
+
[
|
121
|
+
{
|
122
|
+
"timestamp": item.started_at,
|
123
|
+
"value": item.value,
|
124
|
+
"type": item.type,
|
125
|
+
"calculated": item.calculated,
|
126
|
+
}
|
127
|
+
for item in data.items
|
128
|
+
]
|
129
|
+
)
|
130
|
+
df.set_index("timestamp", inplace=True)
|
131
|
+
return df
|
132
|
+
|
133
|
+
|
134
|
+
def plot_consumption_data(
|
135
|
+
df: pd.DataFrame, title: str, unit: str, save_path: Optional[str] = None
|
136
|
+
) -> None:
|
137
|
+
"""Plot consumption data."""
|
138
|
+
plt.figure(figsize=(12, 6))
|
139
|
+
plt.plot(df.index, df["value"], label="Consumption")
|
140
|
+
plt.title(title)
|
141
|
+
plt.xlabel("Time")
|
142
|
+
plt.ylabel(f"Consumption ({unit})")
|
143
|
+
plt.grid(True)
|
144
|
+
plt.legend()
|
145
|
+
|
146
|
+
if save_path:
|
147
|
+
os.makedirs(os.path.dirname(save_path), exist_ok=True)
|
148
|
+
plt.savefig(save_path)
|
149
|
+
plt.close()
|
150
|
+
else:
|
151
|
+
plt.show()
|
152
|
+
|
153
|
+
|
154
|
+
def detect_anomalies(df: pd.DataFrame, threshold: float) -> pd.DataFrame:
|
155
|
+
"""Detect anomalies in the data using a simple threshold-based approach."""
|
156
|
+
mean = df["value"].mean()
|
157
|
+
std = df["value"].std()
|
158
|
+
df["anomaly"] = abs(df["value"] - mean) > (threshold * std)
|
159
|
+
return df
|
160
|
+
|
161
|
+
|
162
|
+
async def main() -> None:
|
163
|
+
# Parse command-line arguments
|
164
|
+
args = parse_arguments()
|
165
|
+
|
166
|
+
# Set up debug logging if requested
|
167
|
+
if args.debug:
|
168
|
+
logging.getLogger("leneda").setLevel(logging.DEBUG)
|
169
|
+
logger.setLevel(logging.DEBUG)
|
170
|
+
logger.debug("Debug logging enabled")
|
171
|
+
|
172
|
+
# Get API credentials
|
173
|
+
api_key, energy_id = get_credentials(args)
|
174
|
+
|
175
|
+
# Get other parameters
|
176
|
+
metering_point = args.metering_point
|
177
|
+
example_num = args.example
|
178
|
+
days = args.days
|
179
|
+
threshold = args.threshold
|
180
|
+
save_plots = args.save_plots
|
181
|
+
output_dir = args.output_dir
|
182
|
+
|
183
|
+
# Initialize the client
|
184
|
+
client = LenedaClient(api_key, energy_id, debug=args.debug)
|
185
|
+
|
186
|
+
# Run all examples or a specific one based on the command-line argument
|
187
|
+
if example_num == 0 or example_num == 1:
|
188
|
+
# Example 1: Get and visualize hourly electricity consumption for the last week
|
189
|
+
end_date = datetime.now()
|
190
|
+
start_date = end_date - timedelta(days=days)
|
191
|
+
|
192
|
+
print(
|
193
|
+
f"\nExample 1: Visualizing hourly electricity consumption (kWh) for the last {days} days"
|
194
|
+
)
|
195
|
+
consumption_data = await client.get_metering_data(
|
196
|
+
metering_point_code=metering_point,
|
197
|
+
obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
|
198
|
+
start_date_time=start_date,
|
199
|
+
end_date_time=end_date,
|
200
|
+
)
|
201
|
+
|
202
|
+
# Convert to DataFrame and compute kWh for each 15-min period
|
203
|
+
df = convert_to_dataframe(consumption_data)
|
204
|
+
df["kWh"] = df["value"] * 0.25 # 15 min = 0.25 h
|
205
|
+
# Resample to hourly energy (sum of 4 periods per hour)
|
206
|
+
hourly_kwh = df["kWh"].resample("H").sum()
|
207
|
+
plt.figure(figsize=(12, 6))
|
208
|
+
plt.plot(hourly_kwh.index, hourly_kwh.values, label="Hourly Energy Consumption")
|
209
|
+
plt.title(
|
210
|
+
f"Hourly Electricity Consumption (kWh) ({start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')})"
|
211
|
+
)
|
212
|
+
plt.xlabel("Time")
|
213
|
+
plt.ylabel("Consumption (kWh)")
|
214
|
+
plt.grid(True)
|
215
|
+
plt.legend()
|
216
|
+
if save_plots:
|
217
|
+
os.makedirs(output_dir, exist_ok=True)
|
218
|
+
plt.savefig(os.path.join(output_dir, "hourly_consumption_kwh.png"))
|
219
|
+
plt.close()
|
220
|
+
else:
|
221
|
+
plt.show()
|
222
|
+
|
223
|
+
if example_num == 0 or example_num == 2:
|
224
|
+
# Example 2: Analyze daily consumption patterns (average power in kW)
|
225
|
+
end_date = datetime.now()
|
226
|
+
start_date = end_date - timedelta(days=30) # Last 30 days
|
227
|
+
|
228
|
+
print("\nExample 2: Analyzing daily average power patterns (kW)")
|
229
|
+
consumption_data = await client.get_metering_data(
|
230
|
+
metering_point_code=metering_point,
|
231
|
+
obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
|
232
|
+
start_date_time=start_date,
|
233
|
+
end_date_time=end_date,
|
234
|
+
)
|
235
|
+
|
236
|
+
# Convert to DataFrame and analyze
|
237
|
+
df = convert_to_dataframe(consumption_data)
|
238
|
+
df["hour"] = df.index.hour
|
239
|
+
df["day_of_week"] = df.index.day_name()
|
240
|
+
|
241
|
+
# Calculate average power by hour (kW)
|
242
|
+
hourly_avg = df.groupby("hour")["value"].mean()
|
243
|
+
plt.figure(figsize=(12, 6))
|
244
|
+
hourly_avg.plot(kind="bar")
|
245
|
+
plt.title("Average Hourly Power (kW)")
|
246
|
+
plt.xlabel("Hour of Day")
|
247
|
+
plt.ylabel("Average Power (kW)")
|
248
|
+
plt.grid(True)
|
249
|
+
if save_plots:
|
250
|
+
os.makedirs(output_dir, exist_ok=True)
|
251
|
+
plt.savefig(os.path.join(output_dir, "hourly_patterns_kw.png"))
|
252
|
+
plt.close()
|
253
|
+
else:
|
254
|
+
plt.show()
|
255
|
+
|
256
|
+
if example_num == 0 or example_num == 3:
|
257
|
+
# Example 3: Detect anomalies in consumption data
|
258
|
+
end_date = datetime.now()
|
259
|
+
start_date = end_date - timedelta(days=90) # Last 90 days
|
260
|
+
|
261
|
+
print("\nExample 3: Detecting anomalies in consumption data")
|
262
|
+
consumption_data = await client.get_metering_data(
|
263
|
+
metering_point_code=metering_point,
|
264
|
+
obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
|
265
|
+
start_date_time=start_date,
|
266
|
+
end_date_time=end_date,
|
267
|
+
)
|
268
|
+
|
269
|
+
# Convert to DataFrame and detect anomalies
|
270
|
+
df = convert_to_dataframe(consumption_data)
|
271
|
+
df = detect_anomalies(df, threshold)
|
272
|
+
|
273
|
+
# Plot the data with anomalies highlighted
|
274
|
+
plt.figure(figsize=(12, 6))
|
275
|
+
plt.plot(df.index, df["value"], label="Consumption")
|
276
|
+
anomalies = df[df["anomaly"]]
|
277
|
+
plt.scatter(
|
278
|
+
anomalies.index,
|
279
|
+
anomalies["value"],
|
280
|
+
color="red",
|
281
|
+
label="Anomalies",
|
282
|
+
zorder=5,
|
283
|
+
)
|
284
|
+
plt.title(f"Electricity Consumption with Anomalies (Threshold: {threshold}σ)")
|
285
|
+
plt.xlabel("Time")
|
286
|
+
plt.ylabel(f"Consumption ({consumption_data.unit})")
|
287
|
+
plt.grid(True)
|
288
|
+
plt.legend()
|
289
|
+
|
290
|
+
if save_plots:
|
291
|
+
os.makedirs(output_dir, exist_ok=True)
|
292
|
+
plt.savefig(os.path.join(output_dir, "anomalies.png"))
|
293
|
+
plt.close()
|
294
|
+
else:
|
295
|
+
plt.show()
|
296
|
+
|
297
|
+
|
298
|
+
if __name__ == "__main__":
|
299
|
+
asyncio.run(main())
|
@@ -0,0 +1,160 @@
|
|
1
|
+
"""
|
2
|
+
Basic usage examples for the Leneda API client.
|
3
|
+
|
4
|
+
This script demonstrates basic usage of the Leneda API client.
|
5
|
+
It accepts API credentials via command-line arguments or environment variables.
|
6
|
+
|
7
|
+
Environment variables:
|
8
|
+
LENEDA_API_KEY: Your Leneda API key
|
9
|
+
LENEDA_ENERGY_ID: Your Energy ID
|
10
|
+
|
11
|
+
Usage:
|
12
|
+
python basic_usage.py --api-key YOUR_API_KEY --energy-id YOUR_ENERGY_ID --metering-point LU-METERING_POINT1
|
13
|
+
"""
|
14
|
+
|
15
|
+
import argparse
|
16
|
+
import asyncio
|
17
|
+
import logging
|
18
|
+
import os
|
19
|
+
import sys
|
20
|
+
from datetime import datetime, timedelta
|
21
|
+
|
22
|
+
from leneda import LenedaClient
|
23
|
+
from leneda.obis_codes import ObisCode
|
24
|
+
|
25
|
+
# Set up logging
|
26
|
+
logging.basicConfig(
|
27
|
+
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
28
|
+
)
|
29
|
+
logger = logging.getLogger("leneda_example")
|
30
|
+
|
31
|
+
|
32
|
+
def parse_arguments() -> argparse.Namespace:
|
33
|
+
"""Parse command-line arguments."""
|
34
|
+
parser = argparse.ArgumentParser(description="Leneda API Client Basic Usage Example")
|
35
|
+
|
36
|
+
# API credentials
|
37
|
+
parser.add_argument(
|
38
|
+
"--api-key",
|
39
|
+
help="Your Leneda API key (or set LENEDA_API_KEY environment variable)",
|
40
|
+
)
|
41
|
+
parser.add_argument(
|
42
|
+
"--energy-id",
|
43
|
+
help="Your Energy ID (or set LENEDA_ENERGY_ID environment variable)",
|
44
|
+
)
|
45
|
+
|
46
|
+
# Other parameters
|
47
|
+
parser.add_argument(
|
48
|
+
"--metering-point",
|
49
|
+
help="Metering point code (default: LU-METERING_POINT1)",
|
50
|
+
)
|
51
|
+
parser.add_argument(
|
52
|
+
"--days",
|
53
|
+
type=int,
|
54
|
+
default=7,
|
55
|
+
help="Number of days to retrieve data for (default: 7)",
|
56
|
+
)
|
57
|
+
parser.add_argument("--debug", action="store_true", help="Enable debug logging")
|
58
|
+
|
59
|
+
return parser.parse_args()
|
60
|
+
|
61
|
+
|
62
|
+
def get_credentials(args: argparse.Namespace) -> tuple[str, str]:
|
63
|
+
"""Get API credentials from arguments or environment variables."""
|
64
|
+
api_key = args.api_key or os.environ.get("LENEDA_API_KEY")
|
65
|
+
energy_id = args.energy_id or os.environ.get("LENEDA_ENERGY_ID")
|
66
|
+
|
67
|
+
if not api_key:
|
68
|
+
logger.error(
|
69
|
+
"API key not provided. Use --api-key or set LENEDA_API_KEY environment variable."
|
70
|
+
)
|
71
|
+
sys.exit(1)
|
72
|
+
|
73
|
+
if not energy_id:
|
74
|
+
logger.error(
|
75
|
+
"Energy ID not provided. Use --energy-id or set LENEDA_ENERGY_ID environment variable."
|
76
|
+
)
|
77
|
+
sys.exit(1)
|
78
|
+
|
79
|
+
return api_key, energy_id
|
80
|
+
|
81
|
+
|
82
|
+
async def main() -> None:
|
83
|
+
# Parse command-line arguments
|
84
|
+
args = parse_arguments()
|
85
|
+
|
86
|
+
# Set up debug logging if requested
|
87
|
+
if args.debug:
|
88
|
+
logging.getLogger("leneda").setLevel(logging.DEBUG)
|
89
|
+
logger.setLevel(logging.DEBUG)
|
90
|
+
logger.debug("Debug logging enabled")
|
91
|
+
|
92
|
+
# Get API credentials
|
93
|
+
api_key, energy_id = get_credentials(args)
|
94
|
+
|
95
|
+
# Get other parameters
|
96
|
+
metering_point = args.metering_point
|
97
|
+
days = args.days
|
98
|
+
|
99
|
+
# Initialize the client
|
100
|
+
client = LenedaClient(api_key, energy_id, debug=args.debug)
|
101
|
+
|
102
|
+
# Example 1: Get hourly electricity consumption data for the specified number of days
|
103
|
+
end_date = datetime.now()
|
104
|
+
start_date = end_date - timedelta(days=days)
|
105
|
+
|
106
|
+
print(f"\nExample 1: Getting hourly electricity consumption data for the last {days} days")
|
107
|
+
consumption_data = await client.get_metering_data(
|
108
|
+
metering_point_code=metering_point,
|
109
|
+
obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
|
110
|
+
start_date_time=start_date.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
111
|
+
end_date_time=end_date.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
112
|
+
)
|
113
|
+
|
114
|
+
# Process and display the data
|
115
|
+
print(f"Retrieved {len(consumption_data.items)} consumption measurements")
|
116
|
+
print(f"Unit: {consumption_data.unit}")
|
117
|
+
print(f"Interval length: {consumption_data.interval_length}")
|
118
|
+
print(f"Metering point: {consumption_data.metering_point_code}")
|
119
|
+
print(f"OBIS code: {consumption_data.obis_code}")
|
120
|
+
|
121
|
+
# Display the first 3 items
|
122
|
+
if consumption_data.items:
|
123
|
+
print("\nFirst 3 measurements:")
|
124
|
+
for item in consumption_data.items[:3]:
|
125
|
+
print(
|
126
|
+
f"Time: {item.started_at.isoformat()}, Value: {item.value} {consumption_data.unit}, "
|
127
|
+
f"Type: {item.type}, Version: {item.version}, Calculated: {item.calculated}"
|
128
|
+
)
|
129
|
+
|
130
|
+
# Example 2: Get monthly aggregated electricity consumption for the current year
|
131
|
+
today = datetime.now()
|
132
|
+
start_of_year = datetime(today.year, 1, 1)
|
133
|
+
|
134
|
+
print("\nExample 2: Getting monthly aggregated electricity consumption for the current year")
|
135
|
+
aggregated_data = await client.get_aggregated_metering_data(
|
136
|
+
metering_point_code=metering_point,
|
137
|
+
obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
|
138
|
+
start_date=start_of_year.strftime("%Y-%m-%d"),
|
139
|
+
end_date=today.strftime("%Y-%m-%d"),
|
140
|
+
aggregation_level="Month",
|
141
|
+
transformation_mode="Accumulation",
|
142
|
+
)
|
143
|
+
|
144
|
+
# Process and display the data
|
145
|
+
print(f"Retrieved {len(aggregated_data.aggregated_time_series)} monthly measurements")
|
146
|
+
print(f"Unit: {aggregated_data.unit}")
|
147
|
+
|
148
|
+
# Display all measurements
|
149
|
+
if aggregated_data.aggregated_time_series:
|
150
|
+
print("\nMonthly measurements:")
|
151
|
+
for metering_value in aggregated_data.aggregated_time_series:
|
152
|
+
print(
|
153
|
+
f"Period: {metering_value.started_at.strftime('%Y-%m')}, "
|
154
|
+
f"Value: {metering_value.value} {aggregated_data.unit}, "
|
155
|
+
f"Calculated: {metering_value.calculated}"
|
156
|
+
)
|
157
|
+
|
158
|
+
|
159
|
+
if __name__ == "__main__":
|
160
|
+
asyncio.run(main())
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[tool.black]
|
6
6
|
line-length = 100
|
7
|
-
target-version = ['
|
7
|
+
target-version = ['py39', 'py310', 'py311']
|
8
8
|
include = '\.pyi?$'
|
9
9
|
|
10
10
|
[tool.isort]
|
@@ -14,12 +14,12 @@ multi_line_output = 3
|
|
14
14
|
src_paths = ["src", "tests"]
|
15
15
|
|
16
16
|
[tool.mypy]
|
17
|
-
python_version = "3.
|
17
|
+
python_version = "3.9"
|
18
18
|
warn_return_any = true
|
19
19
|
warn_unused_configs = true
|
20
20
|
disallow_untyped_defs = true
|
21
21
|
disallow_incomplete_defs = true
|
22
|
-
|
22
|
+
explicit_package_bases = true
|
23
23
|
|
24
24
|
[tool.pytest.ini_options]
|
25
25
|
testpaths = ["tests"]
|
@@ -35,6 +35,8 @@ setup(
|
|
35
35
|
url="https://github.com/fedus/leneda-client",
|
36
36
|
package_dir={"": "src"},
|
37
37
|
packages=find_packages(where="src"),
|
38
|
+
include_package_data=True,
|
39
|
+
package_data={"leneda": ["py.typed"]},
|
38
40
|
install_requires=requirements,
|
39
41
|
classifiers=[
|
40
42
|
"Development Status :: 4 - Beta",
|