Project leírás


Ez a hobby project egy adatkinyerési rendszer létrehozását célozza meg, amely az "Electricity" ingyenes API-t használja az aktuális szén-dioxid kibocsátási és energiafelhasználási adatok lekérésére. A rendszer minden órában frissíti az adatokat, és azokat az Amazon Web Services (AWS) felhőalapú szolgáltatásában tárolja. Az adatok feldolgozása és átalakítása Python nyelven történik, míg a vizualizációhoz a Power BI szolgáltatást használjuk.


Komponensek


Adatforrás: Electricity API
Az "Electricity" ingyenes API biztosítja az aktuális szén-dioxid kibocsátási és energiafelhasználási adatokat.
Az API óránként frissül, így biztosítva a legújabb információkat.

Adatkinyerés és Transzformáció: Python
A Python nyelvű ETL (Extract, Transform, Load) folyamat felelős az adatok lekéréséért és átalakításáért.
A lekért adatokat először nyers formában gyűjtjük össze, majd szükséges átalakításokat végzünk rajtuk (pl. adat tisztítás, normalizálás, formázás).

Adattárolás: AWS
Az átalakított adatokat az AWS infrastruktúrájában tároljuk.
Az AWS megbízható és skálázható megoldást kínál az adatok biztonságos tárolására és hozzáférésére.

Adatvizualizáció: Power BI
A Power BI használatával készítünk vizualizációkat az adatokból, amelyek lehetővé teszik a szén-dioxid kibocsátás és az energiafelhasználás trendjeinek nyomon követését.
A vizualizációk interaktívak és testreszabhatóak, így a felhasználók könnyedén áttekinthetik és elemezhetik az adatokat.

Működés


Adatlekérés
A Python script óránként lekéri az aktuális adatokat az Electricity API-ról.

Adatfeldolgozás és -átalakítás
Az adatokat először nyers formában gyűjtjük össze.
A script tisztítja és normalizálja az adatokat, hogy azok megfelelő formátumban kerüljenek tárolásra és későbbi felhasználásra.

Adatok tárolása
Az átalakított adatokat az AWS-ben tároljuk. Az AWS szolgáltatások (pl. S3, RDS) biztosítják az adatok megbízható és skálázható tárolását.

Vizualizáció
A Power BI rendszeresen lekérdezi az adatokat az AWS-ből, és frissíti a vizualizációkat.
A felhasználók interaktív módon böngészhetik a grafikonokat és jelentéseket, amelyeket az aktuális és történeti adatok alapján készítünk.

Technikai Megvalósítás


Programozási nyelv: Python
API: Electricity API
Felhőszolgáltató: AWS (Amazon Web Services)
Adatvizualizáció: Power BI
ETL eszköz: Egyedi Python script

Záró gondolatok


Ez a project egy remek példa arra, hogyan lehet modern technológiákat és szolgáltatásokat kombinálni egy környezetbarát és adatvezérelt megoldás létrehozásához. Az aktuális szén-dioxid kibocsátási és energiafelhasználási adatok rendszeres monitorozása segíthet a tudatosság növelésében és a fenntarthatóbb energiafelhasználási szokások kialakításában.

Lambda function



    import json
    import os
    import pandas as pd
    import requests
    import boto3
    from io import StringIO
    from datetime import datetime as dt
    from dateutil.relativedelta import relativedelta
    
    def extract_live_carbon_intensity(api_key: str, header: str, zone_data: json) -> pd.DataFrame:
        live_carbon_endpoint = 'https://api.electricitymap.org/v3/carbon-intensity/latest?'
        emission_df = pd.DataFrame()
        for key, value in zone_data.items():
            query = 'zone='+key
            url = live_carbon_endpoint + query
            response = requests.get(url, header).json()
            if len(response) != 1:
                emission_df = pd.concat([emission_df, pd.DataFrame(response, index=[0])])
        
        return emission_df
    
    def extract_breakdown_data(header, zone_data):
        breakdown_edpoint = 'https://api.electricitymap.org/v3/power-breakdown/latest?'
        consumption_breakdown_df = pd.DataFrame()
        production_breakdown_df = pd.DataFrame()
        breakdown_general_df = pd.DataFrame()
    
        for key, value in zone_data.items():
            query = 'zone=' + key
            url = breakdown_edpoint + query
            response = requests.get(url, header).json()
            
            if len(response) != 1:
                temp_df = pd.DataFrame(response['powerConsumptionBreakdown'], index=[0])
                temp_df['zone'] = response['zone']
                temp_df['date'] = response['datetime']
                consumption_breakdown_df = pd.concat([consumption_breakdown_df, temp_df], ignore_index=True)
                
                temp_df = pd.DataFrame(response['powerProductionBreakdown'], index=[0])
                temp_df['zone'] = response['zone']
                temp_df['date'] = response['datetime']
                production_breakdown_df = pd.concat([production_breakdown_df, temp_df], ignore_index=True)
        
                berakdown_general = {
                    'zone': response['zone'],
                    'datetime': response['datetime'],
                    'fossilFreePercentage': response['fossilFreePercentage'],
                    'renewablePercentage': response['renewablePercentage'],
                    'powerConsumptionTotal': response['powerConsumptionTotal'],
                    'powerProductionTotal': response['powerConsumptionTotal'],
                    'powerImportTotal': response['powerImportTotal'],
                    'powerExportTotal': response['powerExportTotal'],
                    'isEstimated': response['isEstimated'],
                    'estimationMethod': response['estimationMethod']
                }
                temp_df = pd.DataFrame(berakdown_general, index=[0])
                breakdown_general_df = pd.concat([breakdown_general_df, temp_df], ignore_index=True)
        
        return [consumption_breakdown_df, production_breakdown_df, breakdown_general_df]
    
    def save_to_processed(dataFrame, bucket, target_path, filename):
        s3 = boto3.client('s3')
        date = dt.now().strftime("%Y-%m-%d-%H")
        filename = filename + f'_{date}.csv'
        buffer = StringIO()
        dataFrame.to_csv(buffer, index=False)
        df_content = buffer.getvalue()
        
        s3.put_object(
            Bucket=bucket,
            Key=target_path + filename,
            Body=df_content
            )
        
    
    def load_zone_data(api_key, header):
        zone_endpoint = 'https://api.electricitymap.org/v3/zones'
        response = requests.get(zone_endpoint, header)
        return response.json()
    
    def lambda_handler(event, context):
        api_key = os.getenv('ELECTRICITYMAPS_API')
        header = {'auth-token': api_key}
        live_carbon_processed_folder = 'transformed_data/live_carbon/'
        consumption_breakdown_processed_folder = 'transformed_data/consumption_breakdown/'
        production_breakdown_processed_folder = 'transformed_data/production_breakdown/'
        general_processed_folder = 'transformed_data/general_breakdown_data/'
        bucket = 'chris-electric-power'
        
        zone_data = load_zone_data(api_key, header)
        extracted_carbon_data = extract_live_carbon_intensity(api_key, header, zone_data)
        save_to_processed(extracted_carbon_data, bucket, live_carbon_processed_folder, 'carbon_data')
        
        breakdown_data = extract_breakdown_data(header, zone_data)
        save_to_processed(breakdown_data[0], bucket, consumption_breakdown_processed_folder, 'consumption_breakdown_data')
        save_to_processed(breakdown_data[1], bucket, production_breakdown_processed_folder, 'production_breakdown_data')
        save_to_processed(breakdown_data[2], bucket, general_processed_folder, 'general_breakdown_data')