leneda-client 0.1.0__tar.gz → 0.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.
- {leneda_client-0.1.0 → leneda_client-0.2.0}/PKG-INFO +1 -1
- {leneda_client-0.1.0 → leneda_client-0.2.0}/examples/advanced_usage.py +10 -13
- {leneda_client-0.1.0 → leneda_client-0.2.0}/examples/basic_usage.py +5 -6
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda/__init__.py +2 -4
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda/client.py +49 -39
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda/models.py +16 -12
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda/obis_codes.py +60 -63
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda/version.py +1 -1
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda_client.egg-info/PKG-INFO +1 -1
- {leneda_client-0.1.0 → leneda_client-0.2.0}/tests/test_client.py +25 -11
- {leneda_client-0.1.0 → leneda_client-0.2.0}/MANIFEST.in +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/README.md +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/pyproject.toml +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/requirements.txt +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/setup.cfg +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/setup.py +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda_client.egg-info/SOURCES.txt +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda_client.egg-info/dependency_links.txt +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda_client.egg-info/requires.txt +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/src/leneda_client.egg-info/top_level.txt +0 -0
- {leneda_client-0.1.0 → leneda_client-0.2.0}/tests/__init__.py +0 -0
| @@ -10,8 +10,8 @@ LENEDA_API_KEY: Your Leneda API key | |
| 10 10 | 
             
            LENEDA_ENERGY_ID: Your Energy ID
         | 
| 11 11 |  | 
| 12 12 | 
             
            Usage:
         | 
| 13 | 
            -
            python advanced_usage.py --api-key YOUR_API_KEY --energy-id YOUR_ENERGY_ID
         | 
| 14 | 
            -
            python advanced_usage.py --metering-point LU-METERING_POINT1 --example 2
         | 
| 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 15 | 
             
            """
         | 
| 16 16 |  | 
| 17 17 | 
             
            import argparse
         | 
| @@ -24,12 +24,9 @@ from typing import Optional | |
| 24 24 | 
             
            import matplotlib.pyplot as plt
         | 
| 25 25 | 
             
            import pandas as pd
         | 
| 26 26 |  | 
| 27 | 
            -
            from leneda import  | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
                LenedaClient,
         | 
| 31 | 
            -
                MeteringData,
         | 
| 32 | 
            -
            )
         | 
| 27 | 
            +
            from leneda import LenedaClient
         | 
| 28 | 
            +
            from leneda.models import AggregatedMeteringData, MeteringData
         | 
| 29 | 
            +
            from leneda.obis_codes import ObisCode
         | 
| 33 30 |  | 
| 34 31 | 
             
            # Set up logging
         | 
| 35 32 | 
             
            logging.basicConfig(
         | 
| @@ -193,7 +190,7 @@ def compare_consumption_periods( | |
| 193 190 | 
             
                # Get data for period 1
         | 
| 194 191 | 
             
                period1_data = client.get_metering_data(
         | 
| 195 192 | 
             
                    metering_point_code=metering_point,
         | 
| 196 | 
            -
                    obis_code= | 
| 193 | 
            +
                    obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 197 194 | 
             
                    start_date_time=period1_start,
         | 
| 198 195 | 
             
                    end_date_time=period1_end,
         | 
| 199 196 | 
             
                )
         | 
| @@ -201,7 +198,7 @@ def compare_consumption_periods( | |
| 201 198 | 
             
                # Get data for period 2
         | 
| 202 199 | 
             
                period2_data = client.get_metering_data(
         | 
| 203 200 | 
             
                    metering_point_code=metering_point,
         | 
| 204 | 
            -
                    obis_code= | 
| 201 | 
            +
                    obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 205 202 | 
             
                    start_date_time=period2_start,
         | 
| 206 203 | 
             
                    end_date_time=period2_end,
         | 
| 207 204 | 
             
                )
         | 
| @@ -290,7 +287,7 @@ def analyze_monthly_trends( | |
| 290 287 |  | 
| 291 288 | 
             
                monthly_data = client.get_aggregated_metering_data(
         | 
| 292 289 | 
             
                    metering_point_code=metering_point,
         | 
| 293 | 
            -
                    obis_code= | 
| 290 | 
            +
                    obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 294 291 | 
             
                    start_date=start_date,
         | 
| 295 292 | 
             
                    end_date=end_date,
         | 
| 296 293 | 
             
                    aggregation_level="Month",
         | 
| @@ -355,7 +352,7 @@ def detect_consumption_anomalies( | |
| 355 352 | 
             
                # Get hourly consumption data
         | 
| 356 353 | 
             
                consumption_data = client.get_metering_data(
         | 
| 357 354 | 
             
                    metering_point_code=metering_point,
         | 
| 358 | 
            -
                    obis_code= | 
| 355 | 
            +
                    obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 359 356 | 
             
                    start_date_time=start_date,
         | 
| 360 357 | 
             
                    end_date_time=end_date,
         | 
| 361 358 | 
             
                )
         | 
| @@ -473,7 +470,7 @@ def main(): | |
| 473 470 | 
             
                        )
         | 
| 474 471 | 
             
                        consumption_data = client.get_metering_data(
         | 
| 475 472 | 
             
                            metering_point_code=metering_point,
         | 
| 476 | 
            -
                            obis_code= | 
| 473 | 
            +
                            obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 477 474 | 
             
                            start_date_time=start_date,
         | 
| 478 475 | 
             
                            end_date_time=end_date,
         | 
| 479 476 | 
             
                        )
         | 
| @@ -9,8 +9,7 @@ Environment variables: | |
| 9 9 | 
             
                LENEDA_ENERGY_ID: Your Energy ID
         | 
| 10 10 |  | 
| 11 11 | 
             
            Usage:
         | 
| 12 | 
            -
                python basic_usage.py --api-key YOUR_API_KEY --energy-id YOUR_ENERGY_ID
         | 
| 13 | 
            -
                python basic_usage.py --metering-point LU-METERING_POINT1
         | 
| 12 | 
            +
                python basic_usage.py --api-key YOUR_API_KEY --energy-id YOUR_ENERGY_ID --metering-point LU-METERING_POINT1
         | 
| 14 13 | 
             
            """
         | 
| 15 14 |  | 
| 16 15 | 
             
            import argparse
         | 
| @@ -19,7 +18,8 @@ import os | |
| 19 18 | 
             
            import sys
         | 
| 20 19 | 
             
            from datetime import datetime, timedelta
         | 
| 21 20 |  | 
| 22 | 
            -
            from leneda import  | 
| 21 | 
            +
            from leneda import LenedaClient
         | 
| 22 | 
            +
            from leneda.obis_codes import ObisCode
         | 
| 23 23 |  | 
| 24 24 | 
             
            # Set up logging
         | 
| 25 25 | 
             
            logging.basicConfig(
         | 
| @@ -45,7 +45,6 @@ def parse_arguments(): | |
| 45 45 | 
             
                # Other parameters
         | 
| 46 46 | 
             
                parser.add_argument(
         | 
| 47 47 | 
             
                    "--metering-point",
         | 
| 48 | 
            -
                    default="LU-METERING_POINT1",
         | 
| 49 48 | 
             
                    help="Metering point code (default: LU-METERING_POINT1)",
         | 
| 50 49 | 
             
                )
         | 
| 51 50 | 
             
                parser.add_argument(
         | 
| @@ -107,7 +106,7 @@ def main(): | |
| 107 106 | 
             
                    print(f"\nExample 1: Getting hourly electricity consumption data for the last {days} days")
         | 
| 108 107 | 
             
                    consumption_data = client.get_metering_data(
         | 
| 109 108 | 
             
                        metering_point_code=metering_point,
         | 
| 110 | 
            -
                        obis_code= | 
| 109 | 
            +
                        obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 111 110 | 
             
                        start_date_time=start_date.strftime("%Y-%m-%dT%H:%M:%SZ"),
         | 
| 112 111 | 
             
                        end_date_time=end_date.strftime("%Y-%m-%dT%H:%M:%SZ"),
         | 
| 113 112 | 
             
                    )
         | 
| @@ -136,7 +135,7 @@ def main(): | |
| 136 135 | 
             
                    print(f"\nExample 2: Getting monthly aggregated electricity consumption for {today.year}")
         | 
| 137 136 | 
             
                    monthly_consumption = client.get_aggregated_metering_data(
         | 
| 138 137 | 
             
                        metering_point_code=metering_point,
         | 
| 139 | 
            -
                        obis_code= | 
| 138 | 
            +
                        obis_code=ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 140 139 | 
             
                        start_date=first_day.strftime("%Y-%m-%d"),
         | 
| 141 140 | 
             
                        end_date=last_day.strftime("%Y-%m-%d"),
         | 
| 142 141 | 
             
                        aggregation_level="Month",
         | 
| @@ -17,7 +17,7 @@ from .models import ( | |
| 17 17 | 
             
            )
         | 
| 18 18 |  | 
| 19 19 | 
             
            # Import the OBIS code constants
         | 
| 20 | 
            -
            from .obis_codes import  | 
| 20 | 
            +
            from .obis_codes import ObisCode
         | 
| 21 21 |  | 
| 22 22 | 
             
            # Import the version
         | 
| 23 23 | 
             
            from .version import __version__
         | 
| @@ -25,9 +25,7 @@ from .version import __version__ | |
| 25 25 | 
             
            # Define what's available when using "from leneda import *"
         | 
| 26 26 | 
             
            __all__ = [
         | 
| 27 27 | 
             
                "LenedaClient",
         | 
| 28 | 
            -
                " | 
| 29 | 
            -
                "ElectricityProduction",
         | 
| 30 | 
            -
                "GasConsumption",
         | 
| 28 | 
            +
                "ObisCode",
         | 
| 31 29 | 
             
                "MeteringValue",
         | 
| 32 30 | 
             
                "MeteringData",
         | 
| 33 31 | 
             
                "AggregatedMeteringValue",
         | 
| @@ -8,11 +8,15 @@ energy consumption and production data for electricity and gas. | |
| 8 8 | 
             
            import json
         | 
| 9 9 | 
             
            import logging
         | 
| 10 10 | 
             
            from datetime import datetime
         | 
| 11 | 
            -
            from typing import Any, Dict, Union
         | 
| 11 | 
            +
            from typing import Any, Dict, List, Optional, Union
         | 
| 12 12 |  | 
| 13 13 | 
             
            import requests
         | 
| 14 14 |  | 
| 15 | 
            -
            from .models import  | 
| 15 | 
            +
            from .models import (
         | 
| 16 | 
            +
                AggregatedMeteringData,
         | 
| 17 | 
            +
                MeteringData,
         | 
| 18 | 
            +
            )
         | 
| 19 | 
            +
            from .obis_codes import ObisCode
         | 
| 16 20 |  | 
| 17 21 | 
             
            # Set up logging
         | 
| 18 22 | 
             
            logger = logging.getLogger("leneda.client")
         | 
| @@ -50,22 +54,22 @@ class LenedaClient: | |
| 50 54 |  | 
| 51 55 | 
             
                def _make_request(
         | 
| 52 56 | 
             
                    self,
         | 
| 57 | 
            +
                    method: str,
         | 
| 53 58 | 
             
                    endpoint: str,
         | 
| 54 | 
            -
                     | 
| 55 | 
            -
                     | 
| 56 | 
            -
             | 
| 57 | 
            -
                ) -> Dict[str, Any]:
         | 
| 59 | 
            +
                    params: Optional[dict] = None,
         | 
| 60 | 
            +
                    json_data: Optional[dict] = None,
         | 
| 61 | 
            +
                ) -> dict:
         | 
| 58 62 | 
             
                    """
         | 
| 59 63 | 
             
                    Make a request to the Leneda API.
         | 
| 60 64 |  | 
| 61 65 | 
             
                    Args:
         | 
| 62 | 
            -
                         | 
| 63 | 
            -
                         | 
| 64 | 
            -
                        params:  | 
| 65 | 
            -
                         | 
| 66 | 
            +
                        method: The HTTP method to use
         | 
| 67 | 
            +
                        endpoint: The API endpoint to call
         | 
| 68 | 
            +
                        params: Optional query parameters
         | 
| 69 | 
            +
                        json_data: Optional JSON data to send in the request body
         | 
| 66 70 |  | 
| 67 71 | 
             
                    Returns:
         | 
| 68 | 
            -
                         | 
| 72 | 
            +
                        The JSON response from the API
         | 
| 69 73 | 
             
                    """
         | 
| 70 74 | 
             
                    url = f"{self.BASE_URL}/{endpoint}"
         | 
| 71 75 |  | 
| @@ -73,13 +77,13 @@ class LenedaClient: | |
| 73 77 | 
             
                    logger.debug(f"Making {method} request to {url}")
         | 
| 74 78 | 
             
                    if params:
         | 
| 75 79 | 
             
                        logger.debug(f"Query parameters: {params}")
         | 
| 76 | 
            -
                    if  | 
| 77 | 
            -
                        logger.debug(f"Request data: { | 
| 80 | 
            +
                    if json_data:
         | 
| 81 | 
            +
                        logger.debug(f"Request data: {json.dumps(json_data, indent=2)}")
         | 
| 78 82 |  | 
| 79 83 | 
             
                    try:
         | 
| 80 84 | 
             
                        # Make the request
         | 
| 81 85 | 
             
                        response = requests.request(
         | 
| 82 | 
            -
                            method=method, url=url, headers=self.headers, params=params, json= | 
| 86 | 
            +
                            method=method, url=url, headers=self.headers, params=params, json=json_data
         | 
| 83 87 | 
             
                        )
         | 
| 84 88 |  | 
| 85 89 | 
             
                        # Check for HTTP errors
         | 
| @@ -117,7 +121,7 @@ class LenedaClient: | |
| 117 121 | 
             
                def get_metering_data(
         | 
| 118 122 | 
             
                    self,
         | 
| 119 123 | 
             
                    metering_point_code: str,
         | 
| 120 | 
            -
                    obis_code:  | 
| 124 | 
            +
                    obis_code: ObisCode,
         | 
| 121 125 | 
             
                    start_date_time: Union[str, datetime],
         | 
| 122 126 | 
             
                    end_date_time: Union[str, datetime],
         | 
| 123 127 | 
             
                ) -> MeteringData:
         | 
| @@ -126,7 +130,7 @@ class LenedaClient: | |
| 126 130 |  | 
| 127 131 | 
             
                    Args:
         | 
| 128 132 | 
             
                        metering_point_code: The metering point code
         | 
| 129 | 
            -
                        obis_code: The OBIS code
         | 
| 133 | 
            +
                        obis_code: The OBIS code (from ElectricityConsumption, ElectricityProduction, or GasConsumption)
         | 
| 130 134 | 
             
                        start_date_time: Start date and time (ISO format string or datetime object)
         | 
| 131 135 | 
             
                        end_date_time: End date and time (ISO format string or datetime object)
         | 
| 132 136 |  | 
| @@ -142,23 +146,21 @@ class LenedaClient: | |
| 142 146 | 
             
                    # Set up the endpoint and parameters
         | 
| 143 147 | 
             
                    endpoint = f"metering-points/{metering_point_code}/time-series"
         | 
| 144 148 | 
             
                    params = {
         | 
| 145 | 
            -
                        "obisCode": obis_code,
         | 
| 149 | 
            +
                        "obisCode": obis_code.value,  # Use enum value for API request
         | 
| 146 150 | 
             
                        "startDateTime": start_date_time,
         | 
| 147 151 | 
             
                        "endDateTime": end_date_time,
         | 
| 148 152 | 
             
                    }
         | 
| 149 153 |  | 
| 150 154 | 
             
                    # Make the request
         | 
| 151 | 
            -
                    response_data = self._make_request(endpoint, params=params)
         | 
| 155 | 
            +
                    response_data = self._make_request(method="GET", endpoint=endpoint, params=params)
         | 
| 152 156 |  | 
| 153 157 | 
             
                    # Parse the response into a MeteringData object
         | 
| 154 | 
            -
                    return MeteringData.from_dict(
         | 
| 155 | 
            -
                        response_data, metering_point_code=metering_point_code, obis_code=obis_code
         | 
| 156 | 
            -
                    )
         | 
| 158 | 
            +
                    return MeteringData.from_dict(response_data)
         | 
| 157 159 |  | 
| 158 160 | 
             
                def get_aggregated_metering_data(
         | 
| 159 161 | 
             
                    self,
         | 
| 160 162 | 
             
                    metering_point_code: str,
         | 
| 161 | 
            -
                    obis_code:  | 
| 163 | 
            +
                    obis_code: ObisCode,
         | 
| 162 164 | 
             
                    start_date: Union[str, datetime],
         | 
| 163 165 | 
             
                    end_date: Union[str, datetime],
         | 
| 164 166 | 
             
                    aggregation_level: str = "Day",
         | 
| @@ -169,11 +171,11 @@ class LenedaClient: | |
| 169 171 |  | 
| 170 172 | 
             
                    Args:
         | 
| 171 173 | 
             
                        metering_point_code: The metering point code
         | 
| 172 | 
            -
                        obis_code: The OBIS code
         | 
| 174 | 
            +
                        obis_code: The OBIS code (from ElectricityConsumption, ElectricityProduction, or GasConsumption)
         | 
| 173 175 | 
             
                        start_date: Start date (ISO format string or datetime object)
         | 
| 174 176 | 
             
                        end_date: End date (ISO format string or datetime object)
         | 
| 175 | 
            -
                        aggregation_level: Aggregation level (Day, Week, Month,  | 
| 176 | 
            -
                        transformation_mode: Transformation mode (Accumulation | 
| 177 | 
            +
                        aggregation_level: Aggregation level (Hour, Day, Week, Month, Infinite)
         | 
| 178 | 
            +
                        transformation_mode: Transformation mode (Accumulation)
         | 
| 177 179 |  | 
| 178 180 | 
             
                    Returns:
         | 
| 179 181 | 
             
                        AggregatedMeteringData object containing the aggregated time series data
         | 
| @@ -187,7 +189,7 @@ class LenedaClient: | |
| 187 189 | 
             
                    # Set up the endpoint and parameters
         | 
| 188 190 | 
             
                    endpoint = f"metering-points/{metering_point_code}/time-series/aggregated"
         | 
| 189 191 | 
             
                    params = {
         | 
| 190 | 
            -
                        "obisCode": obis_code,
         | 
| 192 | 
            +
                        "obisCode": obis_code.value,  # Use enum value for API request
         | 
| 191 193 | 
             
                        "startDate": start_date,
         | 
| 192 194 | 
             
                        "endDate": end_date,
         | 
| 193 195 | 
             
                        "aggregationLevel": aggregation_level,
         | 
| @@ -195,32 +197,40 @@ class LenedaClient: | |
| 195 197 | 
             
                    }
         | 
| 196 198 |  | 
| 197 199 | 
             
                    # Make the request
         | 
| 198 | 
            -
                    response_data = self._make_request(endpoint, params=params)
         | 
| 200 | 
            +
                    response_data = self._make_request(method="GET", endpoint=endpoint, params=params)
         | 
| 199 201 |  | 
| 200 202 | 
             
                    # Parse the response into an AggregatedMeteringData object
         | 
| 201 | 
            -
                    return AggregatedMeteringData.from_dict(
         | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 205 | 
            -
             | 
| 206 | 
            -
             | 
| 207 | 
            -
                     | 
| 208 | 
            -
             | 
| 209 | 
            -
                 | 
| 203 | 
            +
                    return AggregatedMeteringData.from_dict(response_data)
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                def request_metering_data_access(
         | 
| 206 | 
            +
                    self,
         | 
| 207 | 
            +
                    from_energy_id: str,
         | 
| 208 | 
            +
                    from_name: str,
         | 
| 209 | 
            +
                    metering_point_codes: List[str],
         | 
| 210 | 
            +
                    obis_codes: List[ObisCode],
         | 
| 211 | 
            +
                ) -> Dict[str, Any]:
         | 
| 210 212 | 
             
                    """
         | 
| 211 213 | 
             
                    Request access to metering data for a specific metering point.
         | 
| 212 214 |  | 
| 213 215 | 
             
                    Args:
         | 
| 214 | 
            -
                         | 
| 216 | 
            +
                        from_energy_id: The energy ID of the requester
         | 
| 217 | 
            +
                        from_name: The name of the requester
         | 
| 218 | 
            +
                        metering_point_codes: The metering point codes to access
         | 
| 219 | 
            +
                        obis_point_codes: The OBIS point codes to access (from ElectricityConsumption, ElectricityProduction, or GasConsumption)
         | 
| 215 220 |  | 
| 216 221 | 
             
                    Returns:
         | 
| 217 222 | 
             
                        Response data from the API
         | 
| 218 223 | 
             
                    """
         | 
| 219 224 | 
             
                    # Set up the endpoint and data
         | 
| 220 225 | 
             
                    endpoint = "metering-data-access-request"
         | 
| 221 | 
            -
                    data = { | 
| 226 | 
            +
                    data = {
         | 
| 227 | 
            +
                        "from": from_energy_id,
         | 
| 228 | 
            +
                        "fromName": from_name,
         | 
| 229 | 
            +
                        "meteringPointCodes": metering_point_codes,
         | 
| 230 | 
            +
                        "obisCodes": [code.value for code in obis_codes],  # Use enum values for API request
         | 
| 231 | 
            +
                    }
         | 
| 222 232 |  | 
| 223 233 | 
             
                    # Make the request
         | 
| 224 | 
            -
                    response_data = self._make_request( | 
| 234 | 
            +
                    response_data = self._make_request(method="POST", endpoint=endpoint, json_data=data)
         | 
| 225 235 |  | 
| 226 236 | 
             
                    return response_data
         | 
| @@ -12,6 +12,8 @@ from typing import Any, Dict, List | |
| 12 12 |  | 
| 13 13 | 
             
            from dateutil import parser
         | 
| 14 14 |  | 
| 15 | 
            +
            from .obis_codes import ObisCode
         | 
| 16 | 
            +
             | 
| 15 17 | 
             
            # Set up logging
         | 
| 16 18 | 
             
            logger = logging.getLogger("leneda.models")
         | 
| 17 19 |  | 
| @@ -64,23 +66,21 @@ class MeteringData: | |
| 64 66 | 
             
                """Metering data for a specific metering point and OBIS code."""
         | 
| 65 67 |  | 
| 66 68 | 
             
                metering_point_code: str
         | 
| 67 | 
            -
                obis_code:  | 
| 69 | 
            +
                obis_code: ObisCode
         | 
| 68 70 | 
             
                interval_length: str
         | 
| 69 71 | 
             
                unit: str
         | 
| 70 72 | 
             
                items: List[MeteringValue] = field(default_factory=list)
         | 
| 71 73 |  | 
| 72 74 | 
             
                @classmethod
         | 
| 73 | 
            -
                def from_dict(
         | 
| 74 | 
            -
                    cls, data: Dict[str, Any], metering_point_code: str = "", obis_code: str = ""
         | 
| 75 | 
            -
                ) -> "MeteringData":
         | 
| 75 | 
            +
                def from_dict(cls, data: Dict[str, Any]) -> "MeteringData":
         | 
| 76 76 | 
             
                    """Create a MeteringData from a dictionary."""
         | 
| 77 77 | 
             
                    try:
         | 
| 78 78 | 
             
                        # Log the raw data for debugging
         | 
| 79 79 | 
             
                        logger.debug(f"Creating MeteringData from: {data}")
         | 
| 80 80 |  | 
| 81 | 
            -
                        # Use values from the response | 
| 82 | 
            -
                        metering_point_code_value = data | 
| 83 | 
            -
                        obis_code_value = data | 
| 81 | 
            +
                        # Use values from the response
         | 
| 82 | 
            +
                        metering_point_code_value = data["meteringPointCode"]
         | 
| 83 | 
            +
                        obis_code_value = ObisCode(data["obisCode"])
         | 
| 84 84 |  | 
| 85 85 | 
             
                        # Extract items safely
         | 
| 86 86 | 
             
                        items_data = data.get("items", [])
         | 
| @@ -101,6 +101,10 @@ class MeteringData: | |
| 101 101 | 
             
                            unit=data.get("unit", ""),
         | 
| 102 102 | 
             
                            items=items,
         | 
| 103 103 | 
             
                        )
         | 
| 104 | 
            +
                    except KeyError as e:
         | 
| 105 | 
            +
                        logger.error(f"Missing key in API response: {e}")
         | 
| 106 | 
            +
                        logger.debug(f"API response data: {data}")
         | 
| 107 | 
            +
                        raise
         | 
| 104 108 | 
             
                    except Exception as e:
         | 
| 105 109 | 
             
                        logger.error(f"Error creating MeteringData: {e}")
         | 
| 106 110 | 
             
                        logger.debug(f"API response data: {data}")
         | 
| @@ -184,10 +188,6 @@ class AggregatedMeteringData: | |
| 184 188 | 
             
                def from_dict(
         | 
| 185 189 | 
             
                    cls,
         | 
| 186 190 | 
             
                    data: Dict[str, Any],
         | 
| 187 | 
            -
                    metering_point_code: str = "",
         | 
| 188 | 
            -
                    obis_code: str = "",
         | 
| 189 | 
            -
                    aggregation_level: str = "",
         | 
| 190 | 
            -
                    transformation_mode: str = "",
         | 
| 191 191 | 
             
                ) -> "AggregatedMeteringData":
         | 
| 192 192 | 
             
                    """Create an AggregatedMeteringData from a dictionary."""
         | 
| 193 193 | 
             
                    try:
         | 
| @@ -206,7 +206,11 @@ class AggregatedMeteringData: | |
| 206 206 | 
             
                                logger.warning(f"Skipping invalid aggregated item: {e}")
         | 
| 207 207 | 
             
                                logger.debug(f"Invalid item data: {item_data}")
         | 
| 208 208 |  | 
| 209 | 
            -
                        return cls(unit=data | 
| 209 | 
            +
                        return cls(unit=data["unit"], aggregated_time_series=time_series)
         | 
| 210 | 
            +
                    except KeyError as e:
         | 
| 211 | 
            +
                        logger.error(f"Missing key in API response: {e}")
         | 
| 212 | 
            +
                        logger.debug(f"API response data: {data}")
         | 
| 213 | 
            +
                        raise
         | 
| 210 214 | 
             
                    except Exception as e:
         | 
| 211 215 | 
             
                        logger.error(f"Error creating AggregatedMeteringData: {e}")
         | 
| 212 216 | 
             
                        logger.debug(f"API response data: {data}")
         | 
| @@ -20,139 +20,136 @@ class ObisCodeInfo: | |
| 20 20 | 
             
                description: str
         | 
| 21 21 |  | 
| 22 22 |  | 
| 23 | 
            -
            class  | 
| 24 | 
            -
                """OBIS codes for  | 
| 23 | 
            +
            class ObisCode(str, Enum):
         | 
| 24 | 
            +
                """OBIS codes for all energy types."""
         | 
| 25 25 |  | 
| 26 | 
            -
                 | 
| 27 | 
            -
                 | 
| 26 | 
            +
                # Electricity Consumption
         | 
| 27 | 
            +
                ELEC_CONSUMPTION_ACTIVE = "1-1:1.29.0"  # Measured active consumption (kW)
         | 
| 28 | 
            +
                ELEC_CONSUMPTION_REACTIVE = "1-1:3.29.0"  # Measured reactive consumption (kVAR)
         | 
| 28 29 |  | 
| 29 30 | 
             
                # Consumption covered by production sharing groups
         | 
| 30 | 
            -
                 | 
| 31 | 
            -
                 | 
| 32 | 
            -
                 | 
| 33 | 
            -
                 | 
| 34 | 
            -
                 | 
| 35 | 
            -
             | 
| 31 | 
            +
                ELEC_CONSUMPTION_COVERED_LAYER1 = "1-65:1.29.1"  # Layer 1 sharing Group (AIR)
         | 
| 32 | 
            +
                ELEC_CONSUMPTION_COVERED_LAYER2 = "1-65:1.29.3"  # Layer 2 sharing Group (ACR/ACF/AC1)
         | 
| 33 | 
            +
                ELEC_CONSUMPTION_COVERED_LAYER3 = "1-65:1.29.2"  # Layer 3 sharing Group (CEL)
         | 
| 34 | 
            +
                ELEC_CONSUMPTION_COVERED_LAYER4 = "1-65:1.29.4"  # Layer 4 sharing Group (APS/CER/CEN)
         | 
| 35 | 
            +
                ELEC_CONSUMPTION_REMAINING = (
         | 
| 36 | 
            +
                    "1-65:1.29.9"  # Remaining consumption after sharing invoiced by supplier
         | 
| 37 | 
            +
                )
         | 
| 36 38 |  | 
| 37 | 
            -
             | 
| 38 | 
            -
                "" | 
| 39 | 
            -
             | 
| 40 | 
            -
                ACTIVE = "1-1:2.29.0"  # Measured active production (kW)
         | 
| 41 | 
            -
                REACTIVE = "1-1:4.29.0"  # Measured reactive production (kVAR)
         | 
| 39 | 
            +
                # Electricity Production
         | 
| 40 | 
            +
                ELEC_PRODUCTION_ACTIVE = "1-1:2.29.0"  # Measured active production (kW)
         | 
| 41 | 
            +
                ELEC_PRODUCTION_REACTIVE = "1-1:4.29.0"  # Measured reactive production (kVAR)
         | 
| 42 42 |  | 
| 43 43 | 
             
                # Production shared within sharing groups
         | 
| 44 | 
            -
                 | 
| 45 | 
            -
                 | 
| 46 | 
            -
                 | 
| 47 | 
            -
                 | 
| 48 | 
            -
                 | 
| 44 | 
            +
                ELEC_PRODUCTION_SHARED_LAYER1 = "1-65:2.29.1"  # Layer 1 sharing Group (AIR)
         | 
| 45 | 
            +
                ELEC_PRODUCTION_SHARED_LAYER2 = "1-65:2.29.3"  # Layer 2 sharing Group (ACR/ACF/AC1)
         | 
| 46 | 
            +
                ELEC_PRODUCTION_SHARED_LAYER3 = "1-65:2.29.2"  # Layer 3 sharing Group (CEL)
         | 
| 47 | 
            +
                ELEC_PRODUCTION_SHARED_LAYER4 = "1-65:2.29.4"  # Layer 4 sharing Group (APS/CER/CEN)
         | 
| 48 | 
            +
                ELEC_PRODUCTION_REMAINING = "1-65:2.29.9"  # Remaining production after sharing sold to market
         | 
| 49 49 |  | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
                "" | 
| 53 | 
            -
             | 
| 54 | 
            -
                VOLUME = "7-1:99.23.15"  # Measured consumed volume (m³)
         | 
| 55 | 
            -
                STANDARD_VOLUME = "7-1:99.23.17"  # Measured consumed standard volume (Nm³)
         | 
| 56 | 
            -
                ENERGY = "7-20:99.33.17"  # Measured consumed energy (kWh)
         | 
| 50 | 
            +
                # Gas Consumption
         | 
| 51 | 
            +
                GAS_CONSUMPTION_VOLUME = "7-1:99.23.15"  # Measured consumed volume (m³)
         | 
| 52 | 
            +
                GAS_CONSUMPTION_STANDARD_VOLUME = "7-1:99.23.17"  # Measured consumed standard volume (Nm³)
         | 
| 53 | 
            +
                GAS_CONSUMPTION_ENERGY = "7-20:99.33.17"  # Measured consumed energy (kWh)
         | 
| 57 54 |  | 
| 58 55 |  | 
| 59 56 | 
             
            # Complete mapping of all OBIS codes to their details
         | 
| 60 57 | 
             
            OBIS_CODES: Dict[str, ObisCodeInfo] = {
         | 
| 61 58 | 
             
                # Electricity Consumption
         | 
| 62 | 
            -
                 | 
| 63 | 
            -
                     | 
| 59 | 
            +
                ObisCode.ELEC_CONSUMPTION_ACTIVE: ObisCodeInfo(
         | 
| 60 | 
            +
                    ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 64 61 | 
             
                    "kW",
         | 
| 65 62 | 
             
                    "Consumption",
         | 
| 66 63 | 
             
                    "Measured active consumption",
         | 
| 67 64 | 
             
                ),
         | 
| 68 | 
            -
                 | 
| 69 | 
            -
                     | 
| 65 | 
            +
                ObisCode.ELEC_CONSUMPTION_REACTIVE: ObisCodeInfo(
         | 
| 66 | 
            +
                    ObisCode.ELEC_CONSUMPTION_REACTIVE,
         | 
| 70 67 | 
             
                    "kVAR",
         | 
| 71 68 | 
             
                    "Consumption",
         | 
| 72 69 | 
             
                    "Measured reactive consumption",
         | 
| 73 70 | 
             
                ),
         | 
| 74 | 
            -
                 | 
| 75 | 
            -
                     | 
| 71 | 
            +
                ObisCode.ELEC_CONSUMPTION_COVERED_LAYER1: ObisCodeInfo(
         | 
| 72 | 
            +
                    ObisCode.ELEC_CONSUMPTION_COVERED_LAYER1,
         | 
| 76 73 | 
             
                    "kW",
         | 
| 77 74 | 
             
                    "Consumption",
         | 
| 78 75 | 
             
                    "Consumption covered by production of layer 1 sharing Group (AIR)",
         | 
| 79 76 | 
             
                ),
         | 
| 80 | 
            -
                 | 
| 81 | 
            -
                     | 
| 77 | 
            +
                ObisCode.ELEC_CONSUMPTION_COVERED_LAYER2: ObisCodeInfo(
         | 
| 78 | 
            +
                    ObisCode.ELEC_CONSUMPTION_COVERED_LAYER2,
         | 
| 82 79 | 
             
                    "kW",
         | 
| 83 80 | 
             
                    "Consumption",
         | 
| 84 81 | 
             
                    "Consumption covered by production of layer 2 sharing Group (ACR/ACF/AC1)",
         | 
| 85 82 | 
             
                ),
         | 
| 86 | 
            -
                 | 
| 87 | 
            -
                     | 
| 83 | 
            +
                ObisCode.ELEC_CONSUMPTION_COVERED_LAYER3: ObisCodeInfo(
         | 
| 84 | 
            +
                    ObisCode.ELEC_CONSUMPTION_COVERED_LAYER3,
         | 
| 88 85 | 
             
                    "kW",
         | 
| 89 86 | 
             
                    "Consumption",
         | 
| 90 87 | 
             
                    "Consumption covered by production of layer 3 sharing Group (CEL)",
         | 
| 91 88 | 
             
                ),
         | 
| 92 | 
            -
                 | 
| 93 | 
            -
                     | 
| 89 | 
            +
                ObisCode.ELEC_CONSUMPTION_COVERED_LAYER4: ObisCodeInfo(
         | 
| 90 | 
            +
                    ObisCode.ELEC_CONSUMPTION_COVERED_LAYER4,
         | 
| 94 91 | 
             
                    "kW",
         | 
| 95 92 | 
             
                    "Consumption",
         | 
| 96 93 | 
             
                    "Consumption covered by production of layer 4 sharing Group (APS/CER/CEN)",
         | 
| 97 94 | 
             
                ),
         | 
| 98 | 
            -
                 | 
| 99 | 
            -
                     | 
| 95 | 
            +
                ObisCode.ELEC_CONSUMPTION_REMAINING: ObisCodeInfo(
         | 
| 96 | 
            +
                    ObisCode.ELEC_CONSUMPTION_REMAINING,
         | 
| 100 97 | 
             
                    "kW",
         | 
| 101 98 | 
             
                    "Consumption",
         | 
| 102 99 | 
             
                    "Remaining consumption after sharing invoiced by supplier",
         | 
| 103 100 | 
             
                ),
         | 
| 104 101 | 
             
                # Electricity Production
         | 
| 105 | 
            -
                 | 
| 106 | 
            -
                     | 
| 102 | 
            +
                ObisCode.ELEC_PRODUCTION_ACTIVE: ObisCodeInfo(
         | 
| 103 | 
            +
                    ObisCode.ELEC_PRODUCTION_ACTIVE, "kW", "Production", "Measured active production"
         | 
| 107 104 | 
             
                ),
         | 
| 108 | 
            -
                 | 
| 109 | 
            -
                     | 
| 105 | 
            +
                ObisCode.ELEC_PRODUCTION_REACTIVE: ObisCodeInfo(
         | 
| 106 | 
            +
                    ObisCode.ELEC_PRODUCTION_REACTIVE,
         | 
| 110 107 | 
             
                    "kVAR",
         | 
| 111 108 | 
             
                    "Consumption",
         | 
| 112 109 | 
             
                    "Measured reactive production",
         | 
| 113 110 | 
             
                ),
         | 
| 114 | 
            -
                 | 
| 115 | 
            -
                     | 
| 111 | 
            +
                ObisCode.ELEC_PRODUCTION_SHARED_LAYER1: ObisCodeInfo(
         | 
| 112 | 
            +
                    ObisCode.ELEC_PRODUCTION_SHARED_LAYER1,
         | 
| 116 113 | 
             
                    "kW",
         | 
| 117 114 | 
             
                    "Production",
         | 
| 118 115 | 
             
                    "Production shared within layer 1 sharing Group (AIR)",
         | 
| 119 116 | 
             
                ),
         | 
| 120 | 
            -
                 | 
| 121 | 
            -
                     | 
| 117 | 
            +
                ObisCode.ELEC_PRODUCTION_SHARED_LAYER2: ObisCodeInfo(
         | 
| 118 | 
            +
                    ObisCode.ELEC_PRODUCTION_SHARED_LAYER2,
         | 
| 122 119 | 
             
                    "kW",
         | 
| 123 120 | 
             
                    "Production",
         | 
| 124 121 | 
             
                    "Production shared within layer 2 sharing Group (ACR/ACF/AC1)",
         | 
| 125 122 | 
             
                ),
         | 
| 126 | 
            -
                 | 
| 127 | 
            -
                     | 
| 123 | 
            +
                ObisCode.ELEC_PRODUCTION_SHARED_LAYER3: ObisCodeInfo(
         | 
| 124 | 
            +
                    ObisCode.ELEC_PRODUCTION_SHARED_LAYER3,
         | 
| 128 125 | 
             
                    "kW",
         | 
| 129 126 | 
             
                    "Production",
         | 
| 130 127 | 
             
                    "Production shared within layer 3 sharing Group (CEL)",
         | 
| 131 128 | 
             
                ),
         | 
| 132 | 
            -
                 | 
| 133 | 
            -
                     | 
| 129 | 
            +
                ObisCode.ELEC_PRODUCTION_SHARED_LAYER4: ObisCodeInfo(
         | 
| 130 | 
            +
                    ObisCode.ELEC_PRODUCTION_SHARED_LAYER4,
         | 
| 134 131 | 
             
                    "kW",
         | 
| 135 132 | 
             
                    "Production",
         | 
| 136 133 | 
             
                    "Production shared within layer 4 sharing Group (APS/CER/CEN)",
         | 
| 137 134 | 
             
                ),
         | 
| 138 | 
            -
                 | 
| 139 | 
            -
                     | 
| 135 | 
            +
                ObisCode.ELEC_PRODUCTION_REMAINING: ObisCodeInfo(
         | 
| 136 | 
            +
                    ObisCode.ELEC_PRODUCTION_REMAINING,
         | 
| 140 137 | 
             
                    "kW",
         | 
| 141 138 | 
             
                    "Production",
         | 
| 142 139 | 
             
                    "Remaining production after sharing sold to market",
         | 
| 143 140 | 
             
                ),
         | 
| 144 141 | 
             
                # Gas Consumption
         | 
| 145 | 
            -
                 | 
| 146 | 
            -
                     | 
| 142 | 
            +
                ObisCode.GAS_CONSUMPTION_VOLUME: ObisCodeInfo(
         | 
| 143 | 
            +
                    ObisCode.GAS_CONSUMPTION_VOLUME, "m³", "Consumption", "Measured consumed volume"
         | 
| 147 144 | 
             
                ),
         | 
| 148 | 
            -
                 | 
| 149 | 
            -
                     | 
| 145 | 
            +
                ObisCode.GAS_CONSUMPTION_STANDARD_VOLUME: ObisCodeInfo(
         | 
| 146 | 
            +
                    ObisCode.GAS_CONSUMPTION_STANDARD_VOLUME,
         | 
| 150 147 | 
             
                    "Nm³",
         | 
| 151 148 | 
             
                    "Consumption",
         | 
| 152 149 | 
             
                    "Measured consumed standard volume",
         | 
| 153 150 | 
             
                ),
         | 
| 154 | 
            -
                 | 
| 155 | 
            -
                     | 
| 151 | 
            +
                ObisCode.GAS_CONSUMPTION_ENERGY: ObisCodeInfo(
         | 
| 152 | 
            +
                    ObisCode.GAS_CONSUMPTION_ENERGY, "kWh", "Consumption", "Measured consumed energy"
         | 
| 156 153 | 
             
                ),
         | 
| 157 154 | 
             
            }
         | 
| 158 155 |  | 
| @@ -171,7 +168,7 @@ def get_obis_info(obis_code: str) -> ObisCodeInfo: | |
| 171 168 | 
             
                    KeyError: If the OBIS code is not found
         | 
| 172 169 |  | 
| 173 170 | 
             
                Example:
         | 
| 174 | 
            -
                    >>> info = get_obis_info( | 
| 171 | 
            +
                    >>> info = get_obis_info(ObisCode.ELEC_CONSUMPTION_ACTIVE)
         | 
| 175 172 | 
             
                    >>> print(info.unit)
         | 
| 176 173 | 
             
                    'kW'
         | 
| 177 174 | 
             
                """
         | 
| @@ -192,7 +189,7 @@ def get_unit(obis_code: str) -> str: | |
| 192 189 | 
             
                    KeyError: If the OBIS code is not found
         | 
| 193 190 |  | 
| 194 191 | 
             
                Example:
         | 
| 195 | 
            -
                    >>> unit = get_unit( | 
| 192 | 
            +
                    >>> unit = get_unit(ObisCode.ELEC_CONSUMPTION_ACTIVE)
         | 
| 196 193 | 
             
                    >>> print(unit)
         | 
| 197 194 | 
             
                    'kW'
         | 
| 198 195 | 
             
                """
         | 
| @@ -20,6 +20,7 @@ from src.leneda.models import ( | |
| 20 20 | 
             
                MeteringData,
         | 
| 21 21 | 
             
                MeteringValue,
         | 
| 22 22 | 
             
            )
         | 
| 23 | 
            +
            from src.leneda.obis_codes import ObisCode
         | 
| 23 24 |  | 
| 24 25 |  | 
| 25 26 | 
             
            class TestLenedaClient(unittest.TestCase):
         | 
| @@ -34,7 +35,7 @@ class TestLenedaClient(unittest.TestCase): | |
| 34 35 | 
             
                    # Sample response data
         | 
| 35 36 | 
             
                    self.sample_metering_data = {
         | 
| 36 37 | 
             
                        "meteringPointCode": "LU-METERING_POINT1",
         | 
| 37 | 
            -
                        "obisCode":  | 
| 38 | 
            +
                        "obisCode": ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 38 39 | 
             
                        "intervalLength": "PT15M",
         | 
| 39 40 | 
             
                        "unit": "kWh",
         | 
| 40 41 | 
             
                        "items": [
         | 
| @@ -86,7 +87,7 @@ class TestLenedaClient(unittest.TestCase): | |
| 86 87 | 
             
                    # Call the method
         | 
| 87 88 | 
             
                    result = self.client.get_metering_data(
         | 
| 88 89 | 
             
                        "LU-METERING_POINT1",
         | 
| 89 | 
            -
                         | 
| 90 | 
            +
                        ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 90 91 | 
             
                        "2023-01-01T00:00:00Z",
         | 
| 91 92 | 
             
                        "2023-01-02T00:00:00Z",
         | 
| 92 93 | 
             
                    )
         | 
| @@ -94,7 +95,7 @@ class TestLenedaClient(unittest.TestCase): | |
| 94 95 | 
             
                    # Check the result
         | 
| 95 96 | 
             
                    self.assertIsInstance(result, MeteringData)
         | 
| 96 97 | 
             
                    self.assertEqual(result.metering_point_code, "LU-METERING_POINT1")
         | 
| 97 | 
            -
                    self.assertEqual(result.obis_code,  | 
| 98 | 
            +
                    self.assertEqual(result.obis_code, ObisCode.ELEC_CONSUMPTION_ACTIVE)
         | 
| 98 99 | 
             
                    self.assertEqual(result.unit, "kWh")
         | 
| 99 100 | 
             
                    self.assertEqual(len(result.items), 2)
         | 
| 100 101 |  | 
| @@ -116,7 +117,7 @@ class TestLenedaClient(unittest.TestCase): | |
| 116 117 | 
             
                            "Content-Type": "application/json",
         | 
| 117 118 | 
             
                        },
         | 
| 118 119 | 
             
                        params={
         | 
| 119 | 
            -
                            "obisCode":  | 
| 120 | 
            +
                            "obisCode": ObisCode.ELEC_CONSUMPTION_ACTIVE.value,
         | 
| 120 121 | 
             
                            "startDateTime": "2023-01-01T00:00:00Z",
         | 
| 121 122 | 
             
                            "endDateTime": "2023-01-02T00:00:00Z",
         | 
| 122 123 | 
             
                        },
         | 
| @@ -136,7 +137,7 @@ class TestLenedaClient(unittest.TestCase): | |
| 136 137 | 
             
                    # Call the method
         | 
| 137 138 | 
             
                    result = self.client.get_aggregated_metering_data(
         | 
| 138 139 | 
             
                        "LU-METERING_POINT1",
         | 
| 139 | 
            -
                         | 
| 140 | 
            +
                        ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 140 141 | 
             
                        "2023-01-01",
         | 
| 141 142 | 
             
                        "2023-01-31",
         | 
| 142 143 | 
             
                        "Day",
         | 
| @@ -171,7 +172,7 @@ class TestLenedaClient(unittest.TestCase): | |
| 171 172 | 
             
                            "Content-Type": "application/json",
         | 
| 172 173 | 
             
                        },
         | 
| 173 174 | 
             
                        params={
         | 
| 174 | 
            -
                            "obisCode":  | 
| 175 | 
            +
                            "obisCode": ObisCode.ELEC_CONSUMPTION_ACTIVE.value,
         | 
| 175 176 | 
             
                            "startDate": "2023-01-01",
         | 
| 176 177 | 
             
                            "endDate": "2023-01-31",
         | 
| 177 178 | 
             
                            "aggregationLevel": "Day",
         | 
| @@ -186,12 +187,20 @@ class TestLenedaClient(unittest.TestCase): | |
| 186 187 | 
             
                    # Set up the mock response
         | 
| 187 188 | 
             
                    mock_response = MagicMock()
         | 
| 188 189 | 
             
                    mock_response.status_code = 200
         | 
| 189 | 
            -
                    mock_response.json.return_value =  | 
| 190 | 
            -
                    mock_response.content = "{}"
         | 
| 190 | 
            +
                    mock_response.json.return_value = {"requestId": "test-request-id", "status": "PENDING"}
         | 
| 191 191 | 
             
                    mock_request.return_value = mock_response
         | 
| 192 192 |  | 
| 193 193 | 
             
                    # Call the method
         | 
| 194 | 
            -
                    self.client.request_metering_data_access( | 
| 194 | 
            +
                    result = self.client.request_metering_data_access(
         | 
| 195 | 
            +
                        from_energy_id="test_energy_id",
         | 
| 196 | 
            +
                        from_name="Test User",
         | 
| 197 | 
            +
                        metering_point_codes=["LU-METERING_POINT1"],
         | 
| 198 | 
            +
                        obis_codes=[ObisCode.ELEC_CONSUMPTION_ACTIVE],
         | 
| 199 | 
            +
                    )
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                    # Check the result
         | 
| 202 | 
            +
                    self.assertEqual(result["requestId"], "test-request-id")
         | 
| 203 | 
            +
                    self.assertEqual(result["status"], "PENDING")
         | 
| 195 204 |  | 
| 196 205 | 
             
                    # Check that the request was made correctly
         | 
| 197 206 | 
             
                    mock_request.assert_called_once_with(
         | 
| @@ -203,7 +212,12 @@ class TestLenedaClient(unittest.TestCase): | |
| 203 212 | 
             
                            "Content-Type": "application/json",
         | 
| 204 213 | 
             
                        },
         | 
| 205 214 | 
             
                        params=None,
         | 
| 206 | 
            -
                        json={ | 
| 215 | 
            +
                        json={
         | 
| 216 | 
            +
                            "from": "test_energy_id",
         | 
| 217 | 
            +
                            "fromName": "Test User",
         | 
| 218 | 
            +
                            "meteringPointCodes": ["LU-METERING_POINT1"],
         | 
| 219 | 
            +
                            "obisCodes": [ObisCode.ELEC_CONSUMPTION_ACTIVE.value],
         | 
| 220 | 
            +
                        },
         | 
| 207 221 | 
             
                    )
         | 
| 208 222 |  | 
| 209 223 | 
             
                @patch("requests.request")
         | 
| @@ -216,7 +230,7 @@ class TestLenedaClient(unittest.TestCase): | |
| 216 230 | 
             
                    with self.assertRaises(requests.exceptions.HTTPError):
         | 
| 217 231 | 
             
                        self.client.get_metering_data(
         | 
| 218 232 | 
             
                            "LU-METERING_POINT1",
         | 
| 219 | 
            -
                             | 
| 233 | 
            +
                            ObisCode.ELEC_CONSUMPTION_ACTIVE,
         | 
| 220 234 | 
             
                            "2023-01-01T00:00:00Z",
         | 
| 221 235 | 
             
                            "2023-01-02T00:00:00Z",
         | 
| 222 236 | 
             
                        )
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |