Використовуємо Google Colab для аналізу перспективності міні-СЕС на балконі квартири в міській забудові

Привіт, спільното. Мене все ще звати Олег Можаровський. І я все ще працюю Automation Quality Assurance Engineer.

В минулій публікації ми розглядали підхід до вимірювання різних характеристик споживання електроенергії в домогосподарстві з залученням розумних лічильників, IoT, хмарних інструментів AWS та GCP. Може навіть хтось повторив мій досвід і зміг оптимізувати свою тарифікацію споживання електроенергії.

День зимового сонцестояння вже давно минув, дні стають довшими (на момент початку написання цього матеріалу), а отже час активніше починати думати, як можна отримати вигоду від сонця і цією вигодою зменшити власний рахунок за електроенергію. Як і личить інженерам, спочатку рахуємо, потім робимо.

Отримання даних про потенційну генерацію від сонця

Дякувати технологічному прогресу, ми маємо багато способів з певною точністю оцінити потенціал використання сонячної генерації. Один з них — використати дані з:

PhotoVoltaic Geographical Information System. PVGIS — це інструмент, розроблений Європейським Центром Зв’язку та Інформації з Відновлюваних Джерел Енергії (JRC).

Дозволяє оцінювати потенціал сонячної енергії в різних частинах світу. PVGIS використовує географічні дані та метеорологічну інформацію для розрахунку очікуваної виробленої енергії від фотоелектричних систем. Цей інструмент корисний для планувальників, інженерів та дослідників, які займаються розробкою й впровадженням сонячних енергетичних проєктів. Прям про нас.

Переходимо за посиланням, клікаємо на «HOURLY DATA». І йдемо читати документацію. З документації розуміємо, що нам для коректного обчислення бажано мати файл горизонтів. Оскільки в більшості випадків наш прорахунок буде стосуватись міської забудови певної щільності, а не абстрактної сонячної панелі в степовому вакуумі на рівнині.

Формат файлу горизонту наступний: кожен рядок відображає кут лінії горизонту відносно позиції спостерігача. Відлік починається з півночі, проходить за годинниковою стрілкою. Всі внесені заміри рівномірно розподіляються по 360 градусах. Щоб не вигадувати велосипед, можна використати підхід як в довіднику і зробити 36 замірів. Продублювавши замір для 0 та 360 градусів. Беремо компас, транспортир, виходимо на балкон (чи інше місце, де ви плануєте встановити генеруючі модулі).

Умовно накреслюєте червону лінію (а влітку дерева будуть з листям і робитимуть добру тінь) і дуже обережно робите вигляд, що ви Ілон Маск.

Якщо рука вказує не на небо, а на стіну або стелю будинку, це «90». В моєму дослідженні кілька об’єктів в міській забудові. Не сказати, що багатообіцяюче, але вже як є.






Файли горизонту для них вийшли наступного вигляду:

bc_01

kb_e

kb_n

kn_e

0

10

10

10

0

0

0

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

0

0

00

30

30

30

0

40

45

45

45

45

60

60

75

75

75

75

75

75

75

50

40

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

30

30

40

30

30

45

40

60

75

75

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

60

50

30

30

35

40

40

45

45

45

30

30

80

80

75

75

65

55

30

30

30

30

40

45

50

50

30

30

30

30

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

90

80

Об’єкт «bc_01» — квартира в міській забудові з орієнтацією вікон на північ. Через високий поверх розміщення і відсутність багатоповерхівок поряд має майже чистий горизонт.

Має два потенційних місця на балконі для монтажу модулів, розміщених під різними азимутами (025 градусів та 335 градусів, отака чудернацька радянська спадщина), але площа кожної з позицій обмежена.

Об’єкти «kb_e» та «kb_n» — одна квартира з двома балконами (орієнтація схід та північ) на середньому по висоті поверсі та з перепонами на горизонті (сусідніми будинками та деревами).

«kb_e» — звичайна квартира з видом на схід та внутрішній двір.

Можливо, програмісти PVGIS були з Австралії, чи може ще через якісь інші причини «0» при вказуванні азимуту це південь,"-90″ — схід, «90» — захід, «180» або «-180» — північ.

Будьте уважні при введенні даних щодо зазначення азимутального кута орієнтації майбутньої можливої сонячної мініелектростанції.

Кут нахилу — «90». Навряд чи є сенс сильно заморочуватись зі спеціальною системою нахилу змонтованих модулей. Але якщо у вас є час та натхнення — відобразіть свою завзятість в полі «Slope [°]».

Для «kb_e», «kb_n», «kn_e» я зазначав потужність 0.8 кВт (800 Вт) по модулях, для «bc_01» по 0.4 кВт (400 Вт) на кожен кут орієнтації.

По кнопці «CSV» отримаємо в рази два компактніший файл в порівнянні з «JSON». Надалі будемо працювати з CSV.

Якщо бути досить допитливим, то можна через інструменти розробника підгледіти GET-запит для отримання файлу (актуально для API версії 5.3):

https://re.jrc.ec.europa.eu/api/v5_3/seriescalc?lat=XX.XXX&lon=XX.XXX&raddatabase=PVGIS-SARAH3&browser=1&outputformat=csv&userhorizon=40%2C45%2C45%2C45%2C45%2C60%2C60%2C75%2C75%2C75%2C75%2C75%2C75%2C75%2C50%2C40%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C90%2C30%2C30&usehorizon=&angle=90&aspect=-110&startyear=2005&endyear=2023&mountingplace=free&optimalinclination=0&optimalangles=0&js=1&select_database_hourly=PVGIS-SARAH3&hstartyear=2005&hendyear=2023&trackingtype=0&hourlyangle=90&hourlyaspect=-110&pvcalculation=1&pvtechchoice=crystSi&peakpower=0.8&loss=20&components=1

В параметрі «userhorizon» передається наш горизонт, як, напевно, було помітно. Так, я «округлив» втрати до 20%.

Далі читання документації вголос щодо формату отриманого файлу. Пропустимо заголовки, з ними зрозуміло. Таблиця містить наступні поля:

  • time [UTC] — час по UTC.
  • P [W] — потенційна генерація електроенергії від сонячних модулів;
  • Gb(i) [W/m2] — пряме опромінення;
  • Gd(i) [W/m2] — розсіяне опромінення;
  • Gr(i) [W/m2] — відбите опромінення;
  • H_sun [°] - кут Сонця над горизонтом;
  • T2m [°C] — температура повітря (припустімо, але не використовуватиметься в наших розрахунках);
  • WS10m [m/s] — швидкість вітру (не знаю, до чого вона, потенційно обдування вітром сонячних модулів впливає на їх ефективність через охолодження, але в наших розрахунках точно не буде використовуватись);
  • Int — незадокументоване значення.

Зручно, що можна отримати вже готову генерацію, зважаючи на задану потужність сонячних модулей. Значення прямого, розсіяного та відбитого опромінення будуть цікаві для поглибленого вивчення питання, якщо у когось будуть час та натхнення.

Раніше я використовував компоненти GCP для обробки даних. Цього разу теж скористуємось цими сервісами. Нам знадобиться GCP Bucket та GCP Big Query.

Я отримав п’ять наборів даних. 8,5 Мб кожний, 166536 рядків даних. В будь-який зручний спосіб видаляємо в кінці файлів строки, що не стосуються даних. Пакуємо все в gzip-архів (саме gzip, тому що Big Query не працює з zip-архівами). Створюємо в GCP Bucket директорію ‘JRC_insolation_data_2025_2023’ і в будь-який зручний спосіб розмішуємо архіви в директорію.

Далі додаємо архівні файли як зовнішні таблиці до Big Query:

bq load \
--source_format=CSV \
--skip_leading_rows=11 \
PROJECT_ID:DATA_SET_NAME.kb_e_070_800W \
gs://BUCKET_NAME/JRC_insolation_data_2025_2023/kb_e_XX.XXX_XX.XXX_SA3_08kWp_crystSi_20_90deg_-110deg_2005_2023.csv.gz \
time:STRING,P:FLOAT,Gb_i:FLOAT,Gd_i:FLOAT,Gr_i:FLOAT,H_sun:FLOAT,T2m:FLOAT,WS10m:FLOAT,Int:FLOAT

Очікується, що для подальшого аналізу будемо використовувати Google Colab та pySpark. Тому слід зробити певну підготовчу роботу.

Перш за все, для кожної таблиці слід створити view:

CREATE VIEW `PROJECT_ID.DATA_SET_NAME.view_kb_e_070_800W` AS
SELECT * FROM `PROJECT_ID.DATA_SET_NAME.kb_e_070_800W`;

Щоб Google Colab зміг отримати доступ до даних в GCP, слід створити сервісний акаунт і дати йому наступні ролі: BigQuery Data Viewer, BigQuery User, Storage Object Viewer, BigQuery Job User і BigQuery Data Editor (виключно логічно, останнє не потрібно, оскільки у нас тільки читання, але інакше скрипт не виконується через помилку прав доступу).

Крім того, сервісний акаунт слід додати в як Storage Object Viewer в Permissions GCP Bucket’а, в якому зберігаються дані для зовнішніх таблиць.

# Create service account
gcloud iam service-accounts create colab_gcp_account \
    --description="Service account for BigQuery and GCS access from Colab" \
    --display-name="GCP-Colab"

Надання ролей:

# BigQuery Data Viewer
gcloud projects add-iam-policy-binding [PROJECT-ID] \
    --member serviceAccount:colab_gcp_account @[PROJECT-ID].iam.gserviceaccount.com \
    --role roles/bigquery.dataViewer
# BigQuery User
gcloud projects add-iam-policy-binding [PROJECT-ID] \
    --member serviceAccount:colab_gcp_account @[PROJECT-ID].iam.gserviceaccount.com \
    --role roles/bigquery.user
# BigQuery Job User
gcloud projects add-iam-policy-binding [PROJECT-ID] \
    --member serviceAccount:colab_gcp_account @[PROJECT-ID].iam.gserviceaccount.com \
    --role roles/bigquery.jobUser
# BigQuery Data Editor
gcloud projects add-iam-policy-binding [PROJECT-ID] \
    --member serviceAccount:colab_gcp_account @[PROJECT-ID].iam.gserviceaccount.com \
    --role roles/bigquery.dataEditor
# Storage Object Viewer
gsutil iam ch serviceAccount:colab_gcp_account @[PROJECT-ID].iam.gserviceaccount.com:objectViewer gs://[BUCKET-NAME]

Звичайно ж, нам знадобиться файл ключа від новоствореного акаунту:

gcloud iam service-accounts keys create colab_gcp_account.json \
    --iam-account colab_gcp_account@[PROJECT-ID].iam.gserviceaccount.com

Зберігаємо його локально. Надалі я завантажив його на свій Google Drive, щоб Google Colab зміг мати до нього доступ при під’єднанні до GCP.

Підготовка завершена, переходимо до Google Colab і обробки даних.

GCP пропонує для аналогічних задач Vertex AI Workbench instances. На мою думку, їх використання буде надлишковим для означеної задачі. Можливо, на їх налаштування довелось би витратити більше часу, ніж на підготовку Google Colab.

Створюємо Google Colab Notebook і додаємо код для встановлення всіх необхідних компонентів:

!apt-get install -y openjdk-8-jdk-headless -qq > /dev/null
!wget  https://dlcdn.apache.org/spark/spark-3.5.5/spark-3.5.5-bin-hadoop3.tgz
!tar xf spark-3.5.4-bin-hadoop3.tgz
!pip install findspark
!pip install pyspark
!wget https://repo1.maven.org/maven2/com/google/cloud/spark/spark-bigquery-with-dependencies_2.12/0.21.0/spark-bigquery-with-dependencies_2.12-0.21.0.jar
import os
os.environ["JAVA_HOME"] = "/usr/lib/jvm/java-8-openjdk-amd64"
os.environ["SPARK_HOME"] = "/content/spark-3.5.4-bin-hadoop3"
from google.colab import drive
drive.mount('/content/drive')
path_to_credentials = '/content/drive/My Drive/Colab Notebooks/colab_gcp_keys/shelly-gcp-data-analytics-colab-bq.json'
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = path_to_credentials
os.environ['NO_GCE_CHECK'] = 'true'

Посилання на spark-3.5.4-bin-hadoop3.tgz може бути застарілим, якщо необхідний файл не скачується, оновіть посилання та згадки в коді, знайшовши актуальну версію через spark.apache.org/downloads.html.

Цікава особливість, у вас може бути в Google Drive «Мій диск», «הדיסק שלי» чи навіть «Мой диск». Але до нього завжди можна буде звернутись «My Drive», як зазначено в прикладі.

Створюємо екземпляр і під’єднуємось до GCP Big Query:

import findspark
findspark.init()
from pyspark.sql import SparkSession
from pyspark.sql.functions import col
from pyspark.sql.types import DoubleType

spark = SparkSession.builder \
    .appName("BigQuery with Spark") \
    .config("spark.jars", "spark-bigquery-with-dependencies_2.12-0.21.0.jar") \
    .config("viewsEnabled", "true") \
    .config("parentProject", "_YOUR_GCP_PROJECT_NAME") \
    .config("credentialsFile", path_to_credentials) \
    .getOrCreate()

Завантажуємо таблицю і впевнюємось, що попередньо дані завантажені без помилок:

table = "PROJECT.DATASET.VIEW_NAME"
jrc_radiation_df = spark.read.format('bigquery').option("table", table).load()
jrc_radiation_df.drop('Int')
jrc_radiation_df.show()
jrc_radiation_df.printSchema()

Як альтернативу ми можемо використовувати Google Colab та зберегти наш файл з даними від JRC в Google Drive, або в сам інстанс, на якому буде виконуватись Google Colab. Продемонструю альтернативну ініціалізацію зі зчитуванням зі збереженого файлу в Google Drive. Але треба попередньо видалити зайві рядки на початку та наприкінці файлу.

from pyspark.sql import SparkSession

csv_spark = SparkSession.builder \
    .appName("Read CSV from Google Drive") \
    .getOrCreate()
# In case drive not mounted yet
from google.colab import drive
drive.mount('/content/drive', force_remount=True)
# path to uploaded jrc data
file_path = "/content/drive/My Drive/Colab Notebooks/raw_xxx_data/filtered_raw_kv_xxx_800.csv"
# read csv to data frame
csv_jrc_radiation_df = csv_spark.read.csv(file_path, header=True, inferSchema=True)
csv_jrc_radiation_df.drop('Int')
# ensure file readed
csv_jrc_radiation_df.show()
csv_jrc_radiation_df.printSchema()

Маючи історичні дані щодо можливої генераці, спробуємо зробити прості прогнози щодо генерації в цьому році.

from pyspark.sql.functions import col, mean, max, min, stddev, unix_timestamp 
from pyspark.sql.functions import date_format, from_unixtime
from datetime import datetime

def agregate_dayly_hourly_data(spark_df):
    # Timestamp conversion
    spark_df = spark_df.withColumn(
        "time_normalized",
        from_unixtime(unix_timestamp(col("time"), "yyyyMMdd:HHmm"), "yyyy-MM-dd HH:mm:ss")
    )
    current_year = datetime.now().year
    spark_df = spark_df.withColumn("month_day_hour", date_format("time_normalized", "MM-dd-HH"))
    spark_df = spark_df.withColumn(
        "year_month_day_hour",
        date_format("time_normalized", f"{current_year}-MM-dd HH:00")
    )
    # Grouping data by ‘year_month_day_hour’ and calculating statistics
    daily_hourly_spark_df = spark_df.groupBy("year_month_day_hour").agg(
        mean("P").alias("mean_generation"),
        max("P").alias("max_generation"),
        min("P").alias("min_generation"),
        stddev("P").alias("stddev_generation")
    )
    return daily_hourly_spark_df

Для візуалізації очікуваної генерації на певний день можемо скористатись методом, зазначеним нижче. На жаль, matplotlib напряму зі spark-датафреймами не працює, і для візуалізації довелось переводити датафрейм в pandas. Якби знав раніше, і враховуючи об’єм даних, то почав би одразу не з pyspark, а з pandas:

import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
from pyspark.sql.functions import concat, lit, to_timestamp, col
from matplotlib.ticker import MaxNLocator, AutoMinorLocator, MultipleLocator

def visualize_energy_generation(spark_df, start_date, end_date):
    # Отримання року з start_date
    start_year = datetime.strptime(start_date, '%Y-%m-%d').year

    # Filtering date via PySpark DataFrame before passing to pandas
    filtered_spark_df = spark_df.filter((col('year_month_day_hour') >= start_date) & (col('year_month_day_hour') <= end_date))

    # Converting the filtered Spark DataFrame to a Pandas DataFrame
    pandas_df = filtered_spark_df.toPandas()

    # Sorting data by 'year_month_day_hour'
    pandas_df = pandas_df.sort_values('year_month_day_hour')

    # Formatting 'month_day_hour' for visualization
    pandas_df['year_month_day_hour'] = pd.to_datetime(pandas_df['year_month_day_hour'])
    pandas_df['year_month_day_hour'] = pandas_df['year_month_day_hour'].dt.strftime('%d %b %H:%M')

    # Data visualization
    plt.figure(figsize=(12, 6))
    plt.errorbar(pandas_df['year_month_day_hour'], pandas_df['mean_generation'],
                 yerr=pandas_df['stddev_generation'], fmt='-o', ecolor='red', capsize=5,
                 label='Mean Generation ± Std Dev')
    plt.fill_between(pandas_df['year_month_day_hour'], pandas_df['min_generation'], pandas_df['max_generation'],
                     color='gray', alpha=0.2, label='Min-Max Range')
    plt.title('Energy Generation Data Visualization')
    plt.xlabel('Date')
    plt.ylabel('Generation (Wh)')
    plt.xticks(rotation=90)
    plt.gca().xaxis.set_major_locator(MaxNLocator(nbins=10))
    plt.gca().xaxis.set_minor_locator(MultipleLocator(1))
    plt.legend()
    # plt.grid(True, which='both', axis='x', linestyle='--', linewidth=0.5)
    plt.grid(True, which='major', axis='x', linestyle='-', linewidth=0.5)
    plt.grid(True, which='minor', axis='x', linestyle='--', linewidth=0.5, color='gray')
    plt.grid(True)
    plt.tight_layout()
    plt.show()

І на перший погляд наче все на вигляд багатообіцяюче.

kb_e:






kb_n:






kn_e:






bc_01 (графіки виключно для однієї орієнтації, яка 400 Вт, а не 800 Вт, як в інших прикладах):






Але нам цікаво глянути ширший діапазон в перспективі всього року.

Для розрахунку прогнозованої генерації електроенергії за різні періоди, використовуючи історичні дані, можна застосувати кілька методик:

  • Просте усереднення: може дати базове уявлення про очікувану генерацію.
  • Вагове усереднення: ваги визначаються на основі історичної важливості кожної години або дня.
  • Регресійний аналіз: використання статистичних даних або машинного навчання моделей для прогнозування генерації на основі історичних даних.
  • Метод Монте-Карло: використовується для моделювання різних сценаріїв на основі випадкових вибірок з історичних даних. Це може допомогти оцінити ризики та невизначеність у прогнозах генерації.
  • Використання розрахованого стандартного відхилення на додачу до використання усереднених даних: стандартне відхилення є мірою розсіювання даних відносно їх середнього значення.

Так вже склалось, що у нас всі години важливі для енергоживлення. Регресійний аналіз? Я не розумію його застосування в даному випадку. Моделювання сценаріїв я маю план все ж спробувати надалі, виключно щоб зрозуміти, про що мова. Побудуємо прогноз звичайними середніми значеннями та стандартними відхиленнями.

Зі стандартним відхиленням теж виявилось не все просто. Ті, хто вчив математику краще за мене, напевно не здивуються терміну «правило трьох сигм». Правило напрочуд просте:

  • Приблизно 68% значень знаходяться в межах одного стандартного відхилення від середнього.
  • Приблизно 95% значень знаходяться в межах двох стандартних відхилень від середнього.
  • Приблизно 99.7% значень знаходяться в межах трьох стандартних відхилень від середнього.

Пишучи текст вже після того, як переглянув дані, я вирішив залишитись в межах одного стандартного відхилення. Оскільки використання подвійного чи потрійного значення за поточних даних спотворить оцінку.

Додаємо обраховані значення в датафрейм, використовуючи метод для подальшого багаторазового використання:

from pyspark.sql.functions import when, month

def add_generation_estimates_to_df(spark_df):
    modified_df = spark_df.withColumn(
        'optimistic_generation',
        when(
            (col('mean_generation') + col('stddev_generation')) < 0, 0
        ).otherwise(col('mean_generation') + col('stddev_generation'))
    ).withColumn(
        'pessimistic_generation',
        when(
            (col('mean_generation') - col('stddev_generation')) < 0, 0
        ).otherwise(col('mean_generation') - col('stddev_generation'))
    )
    return modified_df

Ну і зробимо агрегований по місяцях набір даних:

def aggregate_monthly_generation(spark_df):
    # adding col with month name and number
    spark_df = spark_df.withColumn("month_name", date_format("year_month_day_hour", "MMMM")) \
                       .withColumn("month_number", month("year_month_day_hour"))

    spark_df = spark_df.filter(col("year_month_day_hour").isNotNull())
    # grouping by month and calculating
    monthly_aggregated_df = spark_df.groupBy("month_name", "month_number").agg(
        spark_sum("mean_generation").alias("total_mean_generation"),
        spark_sum("optimistic_generation").alias("total_optimistic_generation"),
        spark_sum("pessimistic_generation").alias("total_pessimistic_generation")
    )
    # sorting by month
    monthly_aggregated_df = monthly_aggregated_df.filter(col("month_name").isNotNull())
    sorted_monthly_aggregated_df = monthly_aggregated_df.orderBy("month_number")
    # removing number col
    final_df = sorted_monthly_aggregated_df.drop("month_number")
    return sorted_monthly_aggregated_df

Ну і спробуємо візуалізувати:

def visualize_monthly_generation_data(spark_df):
    # converting Spark DataFrame to Pandas DataFrame for visualization
    pd_df = spark_df.toPandas()
    # sorting by month
    pd_df.sort_values('month_number', inplace=True)
    pd_df.set_index('month_name', inplace=True)
    # making plot
    plt.figure(figsize=(10, 6))
    plt.plot(pd_df['total_mean_generation'], label='Total Mean Generation', color='blue', marker='o')
    plt.fill_between(pd_df.index, pd_df['total_optimistic_generation'], pd_df['total_pessimistic_generation'], color='lightgray', alpha=0.5, label='Optimistic to Pessimistic Range')
    # Adding names
    plt.title('Monthly Generation Data Visualization')
    plt.xlabel('Month')
    plt.ylabel('Generation')
    plt.legend()
    plt.xticks(rotation=45)
    # showing plot
    plt.grid(True)
    plt.show()

Розмірність шкали «Generation» в графіку очікуваної місячної генерації — Ват*год. Щоб отримати звичні для всіх кВат*год, треба прибрати три нулі.






Повторюсь, розмірність шкали «Generation» — Ват*год. Щоб отримати звичні для всіх кВат*год, треба прибрати три нулі.

Якщо Вам здається, що щось малувато, то це сумна реальність для обраних локацій. Можливо, для ваших локацій буде більше.

Нагадаю, для розрахунку використовувалась номінальна потужність встановлених модулів в 800 Вт.

На початку умовного дослідження я ще планував порівняти потенціал генерації впродовж доби зі споживанням. На випадок, якщо генерація буде надлишковою, може навіть відкоригувати (зменшити) потужність потенційно встановлених модулів.

Наразі з отриманими даними це не має сенсу. Але.

Давайте хоч дізнаємось можливий потенціал для більш вдалих локацій (менше затіненості, орієнтація на південь). Запит на дані для 800 Вт модулів на Майдані Незалежності в Києві з оптимальною орієнтацією по горизонту (38 градусів) та азимутом (-2 градуси):

https://re.jrc.ec.europa.eu/api/v5_3/seriescalc?lat=50.450&lon=30.524&raddatabase=PVGIS-SARAH3&browser=1&outputformat=csv&userhorizon=&usehorizon=1&angle=38&aspect=-2&startyear=2005&endyear=2023&mountingplace=free&optimalinclination=0&optimalangles=1&js=1&select_database_hourly=PVGIS-SARAH3&hstartyear=2005&hendyear=2023&trackingtype=0&hourlyoptimalangles=1&pvcalculation=1&pvtechchoice=crystSi&peakpower=1&loss=14&components=1

Робимо ті самі маніпуляції з даними.






Розмірність шкали «Generation» в графіку очікуваної місячної генерації — Ват*год. Щоб отримати звичні для всіх кВат*год треба, прибрати три нулі.

А якщо повернутись знов до цифр:

============================================================
kb_e (800 W)
Mean yearly generation: 125.00 kWh - 11.36% from ideal scenario (1100.20 kWh).
Optimistic yearly generation: 180.57 kWh - 10.46% from ideal scenario (1725.65 kWh).
Pessimistic yearly generation: 69.54 kWh - 14.13% from ideal scenario (492.06 kWh).
============================================================
kb_n (800 W)
Mean yearly generation: 121.30 kWh - 11.03% from ideal scenario (1100.20 kWh).
Optimistic yearly generation: 176.60 kWh - 10.23% from ideal scenario (1725.65 kWh).
Pessimistic yearly generation: 66.09 kWh - 13.43% from ideal scenario (492.06 kWh).
============================================================
Overal KB (1600 W)
Mean yearly generation: 246.30 kWh - 11.19% from ideal scenario (2200.41 kWh).
Optimistic yearly generation: 301.61 kWh - 8.74% from ideal scenario (3451.30 kWh).
Pessimistic yearly generation: 191.09 kWh - 19.42% from ideal scenario (984.13 kWh).
============================================================
kn_e (800 W)
Mean yearly generation: 193.44 kWh - 17.58% from ideal scenario (1100.20 kWh).
Optimistic yearly generation: 275.55 kWh - 15.97% from ideal scenario (1725.65 kWh).
Pessimistic yearly generation: 111.43 kWh - 22.65% from ideal scenario (492.06 kWh).
============================================================
bc_01_025 (400 W)
Mean yearly generation: 63.87 kWh - 11.61% from ideal scenario (550.10 kWh).
Optimistic yearly generation: 94.46 kWh - 10.95% from ideal scenario (862.83 kWh).
Pessimistic yearly generation: 34.09 kWh - 13.86% from ideal scenario (246.03 kWh).
===========================================================
bc_01_335 (400 W)
Mean yearly generation: 62.06 kWh - 11.28% from ideal scenario (550.10 kWh).
Optimistic yearly generation: 90.09 kWh - 10.44% from ideal scenario (862.83 kWh).
Pessimistic yearly generation: 34.09 kWh - 13.85% from ideal scenario (246.03 kWh).
===========================================================
Overal BC_01 (800W)
Mean yearly generation: 125.94 kWh - 11.45% from ideal scenario (1100.20 kWh).
Optimistic yearly generation: 184.55 kWh - 10.69% from ideal scenario (1725.65 kWh).
Pessimistic yearly generation: 68.17 kWh - 13.85% from ideal scenario (492.06 kWh).
===========================================================

Як-то кажуть, за можливості оминайте помешкання з вікнами не на південь або з сильним затіненням.

Висновки

Мала сонячна генерація для окремого домогосподарства в міській забудові можлива. В ідеальних умовах кожен встановлений кілоВат потужності за рік згенерує приблизно 1000 кілоВат*годин електроенергії для домогосподарства, яку не треба буде брати з міської мережі.

До чинників, які порушують ідеал, відноситься орієнтація фасаду в сторону, відмінну від півдня, затінення від рослинності або сусідніх будинків. Якщо у вас міська квартира, про автономію немає жодного сенсу думати — у Вас просто не вистачить фасаду для розміщення необхідних потужностей. А якщо Ваш фасад виходить на вулицю, можливо, це потребуватиме додаткових узгоджень, щоб уникнути порушення естетики будівлі.

Важливими компонентами в майбутній квартирній СЕС є мікроінвертор. А щоб запобігти зворотньому перетіканню струму через квартирний лічильник електроенергії, коли ви споживаєте менше, ніж генерують панелі, ще треба пристрій обмеження генерації.

Добре зарекомендувало себе поєднання розумного лічильника Shelly EM та мікроінвертора Ecoflow Powerstream. Вже встановлений і підключений лічильник без необхідності додаткових специфічних навичок доєднується до облікового запису Ecoflow в застосунку і виступає пристроєм генерації/обмеження по запиту, не треба докупати на оселю розумні розетки Ecoflow. Лічильник біля 80 євро, мікроінвертор 120 євро. І ще до 800 Вт модулів (звіряйтесь з технічними характеристиками мікроінвертора). За поточних цін на електроенергію для населення це матиме економічний ефект... не дуже швидко, так би мовити.

Крім Ecoflow схожі пристрої є у Deye, Bluetti та інших виробників з Китаю без відомих імен (так вже історично склалось, що Китай зараз флагман інновацій в сонячній енергетиці, о буремні часи). У Deye є ще розумний лічильник для обмеження генерації, але за розмірами він трохи більший за Shelly EM. Виробник обіцяє легке підключення лічильника до мікроінвертора. За ціною комплекти приблизно однакові в перерахунку на Ватт-потужності. Хіба що у Deye є моделі мікроінверторів на 2,2 кВт потужності.

Зазначена методика надає можливість прорахувати енергоперспективність власного фасаду в міській забудові. Для власного фасаду вам потрібно буде прорахувати файл горизонту (з руками не сильно захоплюйтесь, косплеїти Ілона Маска зараз ще той моветон) та, взаємодіючи з PVGIS-порталом, отримати ваші локальні дані.

«Еталонні Київські» дані для порівняння можна взяти з посилання вище в публікації. Дані завантажуєте у свій Google Drive, ноутбук створюйте все в тому ж Google Colab, він безкоштовний. Успішних обрахунків.

А якщо отримані дані будуть викликати сумнів щодо доцільності (а не явно вказуватимуть на перспективність або безперспективність) інвестицій в міні-СЕС, завжди слід пам’ятати, що електроенергія дешевшати не буде, а «сонце рахунків не виставляє».

Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.

👍ПодобаєтьсяСподобалось6
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

шикарна стаття!

В минулій публікації...

Варто зробити це посиленням, щоб не шукати довго.

Я більш практик ніж теоретик, тож на початку повномасштабної коли вже стало очевидно що орки будуть тероризувати саме енергетику прикупив собі 4 мобільні панелі. Балкон в мене виходить на схід і в сонячні дні в теплу пору сонця аж забагато. Тому і вирішив їх розмістити зсередини. Вони легкі, прикріпив їх зсередини просто скотчем до скла — такий собі імпровізований антиуламковий ролєт вийшов.

В Ваших розрахунках не береться до уваги досить важливий параметр — температура навколишнього середовища.

Ось приклади свіжі

Потужність 4.2 Вати коли сонце на сході
www.screenpresso.com/=r3GEv9SBveEg

Потужність 16.7 коли сонце вже на заході
www.screenpresso.com/=utK35RG3YTXn
Напрямок сонця вже з іншого боку
www.screenpresso.com/=u21wiidwevED

Здавалося що якись парадокс що нема прямого освітлення, а потужність вищща.

А вся загадка легко розгадується. Всі вимірювання відбуваються у ідеальних умовах, про що і зазначено на соняшних панелях, тобто при температурі 25 градусів.
www.screenpresso.com/=xFEOMf64Y0o9

За умповами прямих сонячних променів, навіть не під тим кутом, панелі нагріваються значно вище, знижуючи ефективінсть. Я навіть робив досліди охолоджуючи оприскувачем задній бік, потужність виробітки одразу підстрибувала.

Так що беріть до уваги що спрямовувати панелі на південь треба взимку, при значному зростанні світлої пори максимуми панелі будуть видавати саме спрямовані на схід і захід.

Пане, в цьому теоретичному куточку Вас справді не вистачало. Маю на увазі, реальні кейси.
Температура береться опосередковано: PVGIS розрахунки генерації робить з огляду на температуру. Але використовують середню температуру по палаті (закреслено) регіону.

Багато чого залежить від самих панелей + самого контролера. Краще брати MPPT — він вміє «гратися» зі струмом і напругою щоб витягувати максимум потужності навіть при поганому освітленні/хмарності. В мене найдешевший MPPT, без наворотів і за панелі я не переплачував (не готовий віддавати по +100 баксів за лише 1 додатковий ват). Я за прибутком не гнався, питання видачі надлишків в мережу не розглядав — квартира винвймана, просто якось себе треба було підстрахувати на найгірший довгостроковий випадок блекауту. Замовив тоді цей варіант без попереднього розрахунку.
Тоді ж почав дивитись ютубчик на цю тему наших співвітчизників, багато чого цікавого дізнався. Зараз знайду www.youtube.com/...​@ievgeny_ieremenko/videos — інфи багато, але не дуже його раджу, скажімо так, через «специфічність подачі автором» він доречі Киянин. Цього раджу — www.youtube.com/@izmailinvertorlife, але він на півдні, там майже весь рік світить. І ще один чудовий пан є з Києва, але не згадав поки і не знайшов швидко. В нього і канал і ТГ є все про СЕС — багато корисної інфи і про батареї, про контролери, панелі — професійно займається і освідчує людей на цю тему.
Стосовно втрат на перегріві панелей є в мене ідейка заживити мікроконтроллер керування водною помпою для змочування тильної сторони панелі при досягненні певної температури, але руки поки так і не дійшли до експериментів(.
Із плюсів — пів року можна працювати на ноуті від сонця, + зарядка телефонів від юсб прикурювача і 12 або 5 вольтові світлодіодні лампи в 2х кімнатах. В низький сезон — з жовтня по квітень вже так не вийде.

У власному будинку простіше все, робиш 30квт дозволених і все

Мені 12 вистачає. Але будинок не дуже великий.

Так зелений тариф, надлишкова хай сусідам йде за гроші

Так зелений тариф, надлишкова хай сусідам йде за гроші

По слухам и жалобам зелёный тариф — всё ©

Платять потрохи, або нетметерінг можна оформити

Є окремі експериментатори, котрі «ринок добу на перед» навіть практикують в приватних будинках.

Так, в власному приватному будинку значно більша свобода вибору в тому числі щодо енергоживлення будинку. На жаль світ несправедливий і певна кількість громадян мешкає в квартирах багатоповерхівок. Про що власне і є ця публікація.

Навіть за містом, автономності лише 3-4 місяця на рік. Що в цілому нівелюється рахунком за опалення зимою, але охолоджувати хату енергією від сонця то безцінно))
В цілому всі ці дані можна було б скормити і чатгпт.

Приватні будинки це зовсім інші вже цифри. Якщо мова про автономію, то мова вже про АКБ, що суттєво по бюджету.
Мова про часткову компенсацію споживання з мережі впродовж року. Як зараз бізнеси роблять — будують сонячну генерацію 40-60% від потреб в електроенергії.

Що в цілому нівелюється рахунком за опалення зимою,

Як наявність сонячних панелей впливає на опалення взимку? У мене у батьків сусіди з усіх 3х боків поставили собі панелі, і взагалі на вулиці у них кожен другий будинок їх має. Думаєш дураки?

Думаєш дураки?

Ві удивитесь, но не исключено
не все умеют в єкономику, рои и вот єто всё

Який регіон, скільки сонячних днів на рік?
Немає сенсу порівнювати південь з Києвом чи тим паче Львовом

при всем уважении, но єто віглядит как студенческая лаба по курсу «бигдата в докере»
разворачивать спарк с хадупом там, где достаточно єксель файла — єто немного черезчур

но как лаба — віше всяких похвал, твердіе 100 даже если сдано с опозданием

Я не хотів ексель або шітс, я хотів бігдата. Але дати виявилось менше очікуваного. Я згадував в тексті, що коли отримав дані (і розрахунки), то зрозумів, що можна було інакше. Хоча б на pandas. Перероблювати вже працююче і тим паче на безкоштовному Google Colab? Вирішив вже логічно закінчити.

Я пішов в розрахунках з іншого боку : споживання ~5кВт день.Грубо:В взимку панель видає максимум 10% , весна осінь нехай 30-40%, літом до 100% пару годин в день — з за особливості місцевості. На фасаді не вистачить місця для панелей на декілька кіловат . На даху не варіант -можуть вкрасти. Як висновок техніко-економічне обгрунтування не проходить. Без реєстрації та AWS

5 кВт пропустити, то вже норм інвертор (і бюджет) треба.
Так звані мікроінвертори значно дешевші.
Але знов таки: 5кВт чи 5 кВт*год?

Споживаю десь 150-400кВт/Год в місяць. Треба сонячну міні ферму та окрему кімнату для акб. Оверпрайс короче. Можливо маленьку флексібл або розкладну панель для заспокоєння ,але то так в планах

Розкладна то зовсім якесь плацебо.
Флексібл цікавий варіант: 3-8 кг за модуль 100-400 Вт. Вони легки і не навішуєш на балкон +30 кг самої панелі ще й конструкцій, які її тримають.

коли бачиш

кВт/Год

замість кВт*год
цифри вже довіри не викликають

Крутий аналіз!

Для розрахунку прогнозованої генерації електроенергії за різні періоди, використовуючи історичні дані, можна застосувати кілька методик:

Ще можна використати «Типовий метереологічний рік», він доволі часто застосовується, наприклад при підборі обладнання, і не складний в побудові. nsrdb.nrel.gov/data-sets/tmy

Я про абривіатуру «TMY» чув, але далі не заглиблювався. Налякав одразу довгий мануал «Як отримати дані». У PVGIS здалось значно простішим процес.

Підписатись на коментарі