【一条工務店i-smile】太陽光発電量の予測と実績(2023年3~9月)

別記事の通り、一条工務店i-smileで家を建てました。i-smileは太陽光発電+蓄電池がセットになっており、アプリから発電量・消費量の実績値を確認することができます。

www.ichijo.co.jp

アプリを見ていると9月の発電量が極端に下がっていることから、ちゃんと発電できているか気になりました。そこで、発電量予測をして実績値と比較をしてみます。

なお、発電量予測と実績値比較にはPythonを用いました。スクリプトGithubに置いてあります。

github.com

発電量予測・実績値比較の方法

今回、太陽光発電量の予測値計算と実績値の比較を以下のステップで行いました。

予測値計算の流れは以下の記事を参考にしました。 sma-ene.jp

  1. 地域・方位角・傾斜角から日射量を取得する。
  2. 取得した日射量と損失・システム容量から、時間・日・月別発電量予測値を算出する
  3. 予測値と実績値を比較する
  4. (もし3で予測と実績が外れていれば、)今年の日射量計測値で予測値を補正し、補正した予測値と実績値を比較する

1-3では平均的な年の日射量データで予測をしますが、今年の日射量が平均と大きく異なる場合に予測値があてにならなくなるので、ステップ4で補正をしています。結果から言うと2023年はこの処理が必要でした。

1. 日射量データの取得

1-1. 日射量データのダウンロード

まずは予測のベースとなる日射量データを取得します。日射量はNEDOの日射量データベース閲覧システムから取得できます。

appww2.infoc.nedo.go.jp

このシステムには3つに分かれていますが、今回はMETPV-20を使います。METPV-20は代表年の時別日射量のDBで、エリアが粗い(アメダス観測地点別程度)でしか指定できないものの、方位角・傾斜角を1°単位で指定することができます。

METPV-20に入るとエリア・地点の指定があるので、予測地点を指定し表示ボタンを押します。

すると時別日射量グラフが出てくるので、左上の「表示データ選択」を斜面日射量とし、「日射量データ表示種類」を任意の指定として、太陽光パネルの方位角・傾斜角を指定します。

自宅の方位角・傾斜角は、配置図・立面図から読み取ります。私の家は方位角0°、傾斜角8°でした。

ここで「1年分のデータをダウンロード」ボタンを押すと1年分の時別日射量のCSVファイルがダウンロードできます。

1-2. 日射量データの前処理

ダウンロードしたCSVファイルはそのままだと解釈しづらい形式のため、解釈しやすい形式に直します。 なお、CSVファイルの仕様は以下PDFのp26に記載があります。

日射量データベース閲覧システム WEB版 VER3.0 操作マニュアル

Pythonで以下のスクリプトを実行します。やっていることは大きく以下の4つです。

  • CSVファイルの読み込み、余計な列の削除
  • 列方向にある時間別データの、行方向への変換
    • CSVは1行に1日の24時間分の日射量を記載する形式ですが、正直扱いづらいです。1行に1時間のデータを取るように変換します
  • 時間表記にある24時を翌日0時に変換
    • NEDOのデータは、直前1時間の日射量の積算値であるため、翌日0時ではなく当日24時、という形式で時刻が含まれています。しかし、このままだと扱いづらいので、24時の行は翌日0時にして、Pythonのdatetimeに変換します
  • 単位の変換
    • 時別日射量データは0.01[MJ/m2]ですが、後々の計算をしやすくするため[kWh/m2]に変換します
import pandas as pd
import datetime

# CSVファイルを読み込む
csv_file_hourly = 'rm44132year_d000s10.csv'
hourly_data = pd.read_csv(csv_file_hourly, skiprows=1, header=None)

# 列名を設定する
column_names = [
    '0', '気象要素番号', '月', '日', '代表年', '1時', '2時', '3時', '4時', '5時', '6時', '7時', '8時',
    '9時', '10時', '11時', '12時', '13時', '14時', '15時', '16時', '17時', '18時', '19時',
    '20時', '21時', '22時', '23時', '24時', '最大', '最小', '積算', '平均', '行番号'
]
column_names = [column_name.replace('時', '') for column_name in column_names]
hourly_data.columns = column_names

# 不要な列を削除
hourly_data = hourly_data.drop(columns=['0', '気象要素番号', '代表年', '最大', '最小', '積算', '平均', '行番号'])

# 1時間ごとのデータを各行に配置
hourly_data = pd.melt(hourly_data, id_vars=['月', '日'], var_name='時間', value_name='値')

# 日時をdatetime型に変換してソート
year = datetime.datetime.now().year # 現在年を取得
hourly_data['日付'] = hourly_data.apply(lambda row: f"{year}-{row['月']}-{row['日']}", axis=1) # 年月日を結合した列を作成
hourly_data['date'] = pd.to_datetime(hourly_data['日付']) # 年月日をdatetime型に変換
hourly_data['datetime'] = hourly_data['date']+pd.to_timedelta(hourly_data['時間'].astype(int), unit='h') # 時間を加算
# 日時をindexに設定してソート
hourly_data = hourly_data.set_index('datetime')
hourly_data = hourly_data.drop(columns=['月', '日', '時間', '日付', 'date']) # 不要な列を削除
hourly_data = hourly_data.sort_index() # ソート

# CSVは[0.01MJ/m2]のため、MJ/m2→kWh/m2に単位を換算する
hourly_data = hourly_data/100 # 0.01MJ/m2 -> MJ/m2
hourly_data_kWh = hourly_data/3.6 # MJ/m2 -> kWh/m2
hourly_data_kWh.columns = ['Global Solar Radiation[kWh/m2]']

これで、以下のような8760行(24時間×365日)のデータに変換できました。

datetime Global Solar Radiation[kWh/m2]
2023-01-01 01:00:00 0.0
2023-01-01 02:00:00 0.0
... ...
2023-12-31 23:00:00 0.0
2024-01-01 00:00:00 0.0

2. 時間別・月別発電量予測値の計算

日射量を用いた発電量予測値の計算は、上に記載したサイトを参考に、以下の式で算出します。

  • 発電量[kWh] = 日射量[kWh/m2]×太陽光発電システム容量[kW]×損失[%]
    • この式、単位をみるとおかしく思えるのですが、以下のロジックで正しいようです。
      • 太陽光パネルによる発電量は、単位面積当たり日射量[kW/m2]×パネル面積[m2]×太陽光変換効率[%]で計算できる
      • 太陽光変換効率は1m2に1kWの日射量があった場合に何kWの発電出力があるか、という定義のため、パネル容量÷パネル面積[kW/m2・kW]で置き換えられる
      • そのため発電量は、単位面積当たり日射量[kW/m2]×パネル面積[m2]×パネル容量÷パネル面積[kW/m2・kW]=単位面積当たり日射量×パネル容量でよい
      • kWがkWhになっても考え方は同じ
    • 損失は、パワコン効率や温度上昇に伴うパネル変換効率低下、線路損失などを含むもので、以下のような目安があるらしいのでこれを使います。 https://sma-ene.jp/wp-content/uploads/2019/04/correction-300x201.png

引用:日射量から発電量を算出!太陽光発電のセルフシミュレーション方法

我が家の太陽光発電システム容量は8.5kWなので、それと上記の損失の積をとれば発電量が計算できます。以下のスクリプトを作成しました。

# 定数定義
coef = {'Month': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
        'Coefficient': [0.9, 0.9, 0.9, 0.85, 0.85, 0.8, 0.8, 0.8, 0.8, 0.85, 0.85, 0.9]}
coef_df = pd.DataFrame(coef) # 損失
pv_cap = 8.5 # システム容量

# 発電量計算
hourly_data_kWh['Month'] = hourly_data_kWh.index.month # 月の列を追加
merged_df = hourly_data_kWh.merge(coef_df, on='Month', how='left') # 月に該当する損失の列を追加
hourly_gen = merged_df['Global Solar Radiation[kWh/m2]'] * pv_cap * merged_df['Coefficient'] # 時間別発電量を計算
hourly_gen.name = 'Power Generation[kWh]'
hourly_gen.index = hourly_data_kWh.index # 時間別発電量
monthly_sum_gen = hourly_gen.resample('M').sum() # 月別発電量

3. 予測値と実績値の比較

3-1. 月別発電量の比較

発電量が計算できたので、次に実績値と比較してみます。実績値は電力量を記録するアプリICHIJO POWER MONITORからデータを取得しました。 我が家の3-9月の発電量実績値は以下でした。

month    発電
2023-02-28     209.059
2023-03-31     874.925
2023-04-30    1094.150
2023-05-31    1187.143
2023-06-30     998.247
2023-07-31    1357.425
2023-08-31    1237.183
2023-09-30     865.109

これと先ほど計算した発電量予測値と並べてグラフにすると以下のような形でした。

import matplotlib.pyplot as plt

plt.plot(range(3,10), monthly_sum_gen[2:9], "o-", range(3,10), monthly_sum_act['発電'], "o-")
plt.grid()
plt.xlabel('Month')
plt.ylabel(hourly_gen.name)
plt.legend(["Estimated data", "Actual data"])

  • 全体としては、毎月の傾向は予測できていそうです。
  • 7-8月は予測が低く実績がかなり高めに出ています。これは、実際の日射量が代表年より高かったのではないかと思います。この補正を後ほどしたいと思います。
  • 一方、3月は逆に実績が低めで、こちらも補正が必要そうです。ただ、3月に引き渡しだったため試験等の影響で実績が低めに出ている可能性はあります。

3-2. 時間別発電量の比較

せっかく時間別データを使っているので、時間別発電量も比較してみます。とはいえ対象日がかなり多いので、近い発電量の動きになっている日を月に1日ピックアップしました。

こちらも傾向は再現できていそうなことがわかります。日射・雲は日によって変わるので毎日正確に予測というのは無理でしょうが、5月や7-8月の晴れている日なんかは代表年とほぼ同様でうまく予測できる日もありそうです。

4. 日射量計測値による発電量予測値の補正

3-1の結果から、今年の7-8月の日射量は代表年より高かったと考えました。そこで、代表年と今年の日射量計測値の比で発電量予測値を補正すれば、もう少し正確な予測になると思い、補正をしてみます。

日射量は気象庁のHPから取得します。こちらのページによれば、全国約60か所の地方気象台で日射量計測をしているようなのですが、私の住む神奈川県の横浜地方気象台ではデータがなかったため、東京のデータを用います。 www.data.jma.go.jp

地点を東京、項目として時別値の全天日射量を選択し、期間を代表年(METPV-20からダウンロードしたCSVに記載の、2011年~2017年)および2023年として「CSVファイルをダウンロード」ボタンでデータ取得できます。

注意点として、

  • 表示オプションに余計な値を「表示(格納)しない」を選択しておかないと、CSVが読みにくい形式になります。
  • 右上の「選択済みデータ量」のゲージが100%近くだと時間帯によっては全然ダウンロードできないので、少なめのデータ量で小分けしてダウンロードしないと能率が悪くなるかもしれません。私は月毎に分けでダウンロードしました。

ダウンロードしたデータを以下のようにPandas DataFrameとして取り込み、代表年と今年の差を見てみます。
ちなみに、CSVはShift-JISではなくcp932をencodingに指定しないと、Shift-JISに含まれていない文字が読み取れずエラーになります。

# 代表年の各月データを集約
dir = "./代表年データ"
files = os.listdir(dir)
rad_rep_year = pd.DataFrame()
for file in files:
    if "csv" in file:
        print(file)
        df = pd.read_csv(dir+"/"+file, skiprows=3, index_col=0, encoding="cp932")
        rad_rep_year = pd.concat([rad_rep_year, df])
rad_rep_year.index = pd.to_datetime(rad_rep_year.index)
rad_rep_year.index = [x.replace(year=2020) for x in rad_rep_year.index] # 年が異なってソートしにくいので統一
rad_rep_year = rad_rep_year.sort_index()
monthly_rep_year = rad_rep_year['日射量(MJ/㎡)'].resample('M').sum()

# 2023年のデータを読み込み
file = "tokyo_temp_rad_230221-230930.csv"
rad_this_year = pd.read_csv(file, skiprows=3, index_col=0, encoding="cp932")
rad_this_year.index = pd.to_datetime(rad_this_year.index)
monthly_this_year = rad_this_year['日射量(MJ/㎡)'].resample('M').sum()

# 2023と代表年の(東京の)日射量の差をプロット
plt.plot(range(3,10), monthly_this_year[1:8],"o-", range(3,10), monthly_rep_year[2:9], "o-")
plt.grid()
plt.xlabel('Month')
plt.ylabel("Solar radiation[MJ/m2]")
plt.legend(["2023", "Representative year"])
plt.title("Total solar radiation in Tokyo")

日射量をプロットしたのがこちらです。予想通り、代表年に比べ2023年は7-8月がとびぬけて日射量が高く、3月がやや低いことがわかりました。

ちなみに、気象庁の報道発表資料を見ても、今年の3月は神奈川あたりは日照時間が少なく、夏は日照時間が長かったようです。

このデータは全天日射量であり、太陽光パネルが受ける傾斜面日射量とは異なると思いますが、このデータを使って補正をしてみたいと思います。

# 日射量補正値を計算し、月別発電量を補正
rad_adj = monthly_this_year[1:8].values / monthly_rep_year[2:9].values # 補正値
monthly_sum_gen_adj = monthly_sum_gen[2:9] * rad_adj # 補正した予測発電量
plt.plot(range(3,10), monthly_sum_gen[2:9], "o-", range(3,10), monthly_sum_gen_adj, "o-g", range(3,10), monthly_sum_act['発電'][1:8], "o-")
plt.grid()
plt.xlabel('Month')
plt.ylabel(hourly_gen.name)
plt.legend(["Estimated data(unadjusted)", "Estimated data(adjusted)", "Actual data"])

月毎の代表年に対する2023年の日射量の比を補正値とし、それを発電量予測値にかけて補正しました。

結果、上のグラフの緑の線のようになり、青の補正前の線より実績値に近い値となりました。3-9月の期間の平均絶対パーセント誤差(MAPE)を計算しても7.3%→4.27%と3ポイントほど改善したことから、日射量の代表年との差により誤差が大きく出ていたものと考えます。

ちなみに、今回は、太陽光発電量の変動や予測誤差の要因を分析する目的で、日射量の実績値を使って事後的に太陽光発電量予測の補正を行い誤差改善しました。もしこのような補正を事前予測として行う場合、気象庁の季節予報などの情報をもとに、多照年・寡照年のデータを使って補正する、といった方法で誤差改善する、という方法がとれるんではないかと思います。

まとめ

  • NEDOの提供する代表年の日射量データを用いて太陽光発電量の予測値を計算しました。また、気象庁の日射量計測データを用いて予測値を補正しました。
  • 一条工務店のアプリから取得した2023/3~9月の太陽光発電量実績値と比較したところ、予測値は毎月の発電量の傾向を予測できていそうなこと、今年の3月・7-8月の日射量の変動によって発電量も増減していたことがわかりました。
  • 9月に太陽光発電量が極端に下がったと思ったのですが、7-8月が例年にないほど高い日射量で発電量が多く、9月は平年並みだったことから大きく下がったように感じられただけであり、太陽光発電システムの異常等ではなさそうなことが確認できました。
    • 発電量が2/3になったのでびっくりしましたが、日射量/季節によってそれだけの差が発生しただけでした…