基于Python与SolarEdge API的光伏数据本地化采集与自动化监控方案
2026/6/3 14:21:06 网站建设 项目流程

1. 项目概述:为何要将光伏数据掌握在自己手中?

如果你家里或公司安装了SolarEdge的光伏系统,每天看着监控App里跳动的发电数字,有没有想过一个问题:这些数据到底是谁的?答案可能让你有点意外——从技术上讲,这些实时和历史数据都存储在SolarEdge的云端服务器上。这意味着,一旦网络中断、厂商服务调整,或者你只是想用这些数据做一些App不支持的分析和自动化,就会立刻感到束手无策。这正是我决定动手的原因:把属于我自己的发电数据,拿回到我自己的地盘上来。

这个项目的核心,就是利用SolarEdge官方开放的API接口,通过Python脚本,将光伏系统的实时功率、日/月/年发电量、设备状态等关键数据,定时拉取并存储到本地。这不仅仅是“获取数据”那么简单,它代表了一种数据主权的回归。拥有了本地数据,你可以做的事情就多了:比如,用Raspberry Pi搭建一个本地能源监控仪表盘,不受网络波动影响;将发电数据与家庭用电数据结合,分析自给自足率;甚至触发一些自动化操作,比如当发电功率超过某个阈值时,自动开启热水器或给电动汽车充电。Python以其丰富的库生态和简洁的语法,成为了实现这一目标的绝佳工具,而整个过程,其实比你想象的要简单。

2. 核心思路与方案设计:从云端到本地的技术路径

2.1 理解SolarEdge API的数据模型与权限

在动手写代码之前,我们必须先搞清楚我们要“拿”的是什么,以及SolarEdge允许我们怎么“拿”。SolarEdge的API是基于RESTful原则设计的,这意味着我们通过标准的HTTP请求(主要是GET)来访问特定的URL(端点),就能获取结构化的数据(通常是JSON格式)。

这里有几个关键概念需要厘清:

  • 站点(Site): 这是最顶层的概念,对应你安装的一套完整的SolarEdge光伏系统。每个站点有一个唯一的site_id
  • 设备(Equipment): 指站点下的具体硬件,如逆变器(Inverter)、功率优化器(Power Optimizer)、电表(Meter)等。一个站点下可能有多个设备。
  • 数据维度: API提供了不同时间维度的数据,例如:
    • 概览(Overview): 站点当前的总发电功率、日/月/年累计发电量等摘要信息。
    • 详情(Details): 站点详情,如装机容量、位置等。
    • 能源(Energy): 指定时间段(如某一天、某一月)内的详细发电量数据。
    • 功率(Power): 指定时间段的详细功率数据(通常为15分钟间隔)。

我们的方案设计遵循一个清晰的链条:认证 -> 请求 -> 解析 -> 存储 -> 应用。首先,我们需要从SolarEdge监控平台获取访问凭证(API Key和Site ID)。然后,使用Python的requests库构造带有这些凭证的HTTP请求,发送到正确的API端点。服务器验证通过后,会返回JSON数据。我们解析这些数据,提取出有用的信息,并将其存储到本地文件(如CSV、SQLite数据库)或内存中,供后续的程序调用和分析。

2.2 工具选型:为什么是Python + Requests + Raspberry Pi?

这个组合几乎是为此类物联网数据采集任务量身定制的。

  1. Python: 语法简洁,拥有海量的第三方库。对于HTTP请求、JSON解析、数据分析和定时任务,都有成熟且易用的解决方案,极大降低了开发门槛。
  2. Requests库: 它是Python中处理HTTP请求的“事实标准”。相比Python内置的urllibrequests的API设计更加人性化,几行代码就能完成复杂的请求构造和响应处理,让开发者更专注于业务逻辑。
  3. Raspberry Pi(树莓派): 作为本项目的“大脑”和运行平台,它有几个不可替代的优势:
    • 低功耗与持续运行: 树莓派功耗极低,可以7x24小时不间断运行数据采集脚本,完美契合监控任务。
    • 成本与可扩展性: 硬件成本低,且GPIO接口可以方便地连接传感器、屏幕等外设,未来扩展性强(例如加装本地显示屏)。
    • Linux环境: 基于Linux系统,可以方便地使用cron等工具设置定时任务,自动化运行脚本。

整个技术栈的选择,核心考量就是高效、稳定、低成本且易于维护。一个简单的Python脚本,配合树莓派的定时任务,就能构建一个可靠的数据管道。

3. 实操准备:获取你的API密钥与站点ID

这是整个项目中最关键,也最容易出错的一步。请严格按照以下步骤操作,并注意其中的细节。

3.1 登录与导航至API管理页面

  1. 打开浏览器,访问 SolarEdge监控平台 并使用你的账户登录。
  2. 登录成功后,你会看到默认的监控仪表盘。注意:很多用户找不到“Admin”按钮,这是因为SolarEdge的界面可能因账户类型(安装商/终端用户)或站点权限不同而有所差异。
  3. 在页面左上角,找到你的站点名称,点击其右侧的齿轮(Settings)图标。这个图标就是进入管理界面的入口。如果找不到,请尝试在页面顶部或侧边栏寻找“Admin”、“Settings”或“管理”字样的链接。
  4. 进入设置页面后,在左侧菜单栏中寻找“Site Access”(站点访问)或类似选项。

3.2 生成并保存API密钥

  1. 在“Site Access”页面,你需要找到一个名为“API Access”的板块或选项。
  2. 确保“API Access”的开关或复选框处于开启(Enabled)状态。如果没有开启,请先开启它。
  3. 下方应该会有一个“Generate New Key”(生成新密钥)或“Create API Key”的按钮。点击它。
  4. 系统可能会弹出一个对话框,提示你确认操作。生成成功后,页面上会显示两串至关重要的信息:
    • API Key(API密钥): 一长串由数字和字母组成的字符串,例如ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789请立即妥善保存,因为它通常只显示一次,关闭页面后可能无法再次查看完整密钥。
    • Site ID(站点ID): 一串数字,这是你站点的唯一标识符。

重要提示: 将你的API Key和Site ID保存在一个安全的地方,比如本地的密码管理器或加密文档中。绝对不要将它们直接硬编码在打算公开分享的脚本里。我们后续会介绍如何安全地管理这些凭证。

3.3 理解API权限与限制

在API手册或生成密钥的页面,你可能会看到关于密钥类型的说明。通常,从用户界面生成的是“User”级密钥,它拥有读取该站点所有数据的权限,这正是我们需要的。而“Site”级密钥可能权限范围不同。如果你的密钥遇到403错误,请确认你生成的是User Key,并且拥有对应站点的读取权限。

此外,SolarEdge的免费API通常有调用频率限制(Rate Limiting),例如每分钟或每小时最多允许多少次请求。在编写脚本时,尤其是计划高频采集时,务必查阅官方文档了解限制细则,避免因频繁请求导致IP或密钥被临时封锁。

4. 核心代码解析与编写:构建你的数据采集器

现在,我们进入核心环节,一步步编写Python脚本。我们将从一个最简单的示例开始,逐步增加错误处理、数据解析和存储功能。

4.1 基础环境搭建与依赖安装

首先,确保你的Python环境(无论是电脑还是树莓派)已经就绪。建议使用Python 3.6或更高版本。

打开终端(命令行),安装必需的库:

pip install requests pandas
  • requests: 用于发送HTTP请求。
  • pandas: 非必须,但它是数据处理和分析的神器,能轻松将JSON数据转换为表格(DataFrame)并进行存储,强烈推荐安装。

4.2 编写第一个API请求脚本

创建一个新文件,例如solaredge_data.py。我们将从获取站点“概览(Overview)”数据开始,这是最简单也是信息最全面的一个接口。

import requests import json from datetime import datetime # !!!重要:请用你刚才获取的实际值替换下面的引号内容 !!! API_KEY = “YOUR_API_KEY_HERE” # 例如:”L4ZYG4RD3N1234567890ABCDEF” SITE_ID = “YOUR_SITE_ID_HERE” # 例如:”1234567” # 1. 构造API请求URL # 这里是获取站点概览信息的端点 base_url = “https://monitoringapi.solaredge.com” endpoint = f”/site/{SITE_ID}/overview” url = base_url + endpoint # 2. 设置请求参数 params = { ‘api_key’: API_KEY } # 3. 发送GET请求 try: response = requests.get(url, params=params, timeout=10) # 设置10秒超时 # 检查HTTP状态码,200表示成功 response.raise_for_status() except requests.exceptions.RequestException as e: print(f”请求失败: {e}”) # 这里可以加入更详细的错误处理,比如网络重试、日志记录等 exit(1) # 4. 解析JSON响应 data = response.json() # 5. 提取并打印我们关心的数据 overview = data.get(‘overview’, {}) current_power = overview.get(‘currentPower’, {}).get(‘power’, 0) # 当前功率,单位瓦特(W) energy_today = overview.get(‘lastDayData’, {}).get(‘energy’, 0) # 今日发电量,单位瓦时(Wh) last_update_time = overview.get(‘lastUpdateTime’, ‘N/A’) # 最后数据更新时间 print(“=== SolarEdge 站点概览 ==”) print(f”站点ID: {SITE_ID}”) print(f”当前发电功率: {current_power / 1000:.2f} kW”) # 转换为千瓦 print(f”今日累计发电: {energy_today / 1000:.2f} kWh”) # 转换为千瓦时 print(f”数据更新时间: {last_update_time}”) print(“=” * 30) # 6. (可选)将原始JSON数据保存到文件,用于调试或备份 timestamp = datetime.now().strftime(“%Y%m%d_%H%M%S”) filename = f”solaredge_overview_{timestamp}.json” with open(filename, ‘w’) as f: json.dump(data, f, indent=2) print(f”原始数据已保存至: {filename}”)

代码要点解析

  • URL构造: SolarEdge API的端点路径通常包含/site/{siteId}/{resource}的格式。我们使用Python的f-string将SITE_ID动态插入到URL中。
  • 参数传递: API密钥api_key是通过查询参数(Query Parameters)传递的,这是SolarEdge API的常见做法。
  • 错误处理: 使用try-except块和response.raise_for_status()是良好的实践,它能捕获网络错误和HTTP错误(如403、404、500)。
  • 数据提取: 返回的JSON是嵌套结构。我们使用.get()方法安全地访问字典键值,避免因键不存在而抛出KeyError.get(‘key’, default)在键不存在时返回默认值(如0或空字典{})。
  • 单位转换: API返回的功率单位通常是瓦特(W),能量单位是瓦时(Wh)。除以1000转换为更常用的千瓦(kW)和千瓦时(kWh)。

运行这个脚本,如果一切配置正确,你应该能在终端看到你光伏系统的实时发电数据。

4.3 进阶:获取历史能源数据并存储为CSV

概览数据很好,但要做分析,我们需要历史数据。下面我们编写一个函数,获取指定日期的详细发电数据,并存储到CSV文件中。

import requests import pandas as pd from datetime import datetime, timedelta API_KEY = “YOUR_API_KEY_HERE” SITE_ID = “YOUR_SITE_ID_HERE” base_url = “https://monitoringapi.solaredge.com” def fetch_energy_data(date_str, time_unit=”DAY”): “”” 获取指定日期的能源数据 :param date_str: 日期字符串,格式 ‘YYYY-MM-DD’ :param time_unit: 时间单位,可以是 ‘QUARTER_OF_AN_HOUR’, ‘HOUR’, ‘DAY’, ‘WEEK’, ‘MONTH’, ‘YEAR’ :return: pandas DataFrame 或 None “”” endpoint = f”/site/{SITE_ID}/energy” url = base_url + endpoint params = { ‘api_key’: API_KEY, ‘startDate’: date_str, ‘endDate’: date_str, # 获取单日数据 ‘timeUnit’: time_unit } try: response = requests.get(url, params=params, timeout=15) response.raise_for_status() data = response.json() except requests.exceptions.RequestException as e: print(f”获取{date_str}数据失败: {e}”) return None # 解析能源数据 energy_details = data.get(‘energy’, {}).get(‘values’, []) if not energy_details: print(f”{date_str} 无数据返回。”) return None # 将数据转换为pandas DataFrame df = pd.DataFrame(energy_details) # 重命名列,使其更易读 df.rename(columns={‘date’: ‘timestamp’, ‘value’: ‘energy_wh’}, inplace=True) # 转换时间戳字符串为datetime对象 df[‘timestamp’] = pd.to_datetime(df[‘timestamp’]) # 添加一个日期列,方便按天汇总 df[‘date’] = df[‘timestamp’].dt.date return df def main(): # 获取昨天的数据(避免当天数据不完整) yesterday = (datetime.now() – timedelta(days=1)).strftime(‘%Y-%m-%d’) print(f”正在获取 {yesterday} 的发电数据…”) df_energy = fetch_energy_data(yesterday, time_unit=”QUARTER_OF_AN_HOUR”) # 获取15分钟间隔数据 if df_energy is not None and not df_energy.empty: # 打印一些统计信息 total_energy_wh = df_energy[‘energy_wh’].sum() print(f”{yesterday} 总发电量: {total_energy_wh / 1000:.2f} kWh”) # 保存到CSV文件 csv_filename = f”solaredge_energy_{yesterday}.csv” df_energy.to_csv(csv_filename, index=False) print(f”详细数据已保存至: {csv_filename}”) # 简单分析:找出发电功率最高的时段 # 假设15分钟发电量,可近似估算该时段平均功率 (能量/时间) df_energy[‘avg_power_w’] = df_energy[‘energy_wh’] / 0.25 # 0.25小时=15分钟 max_power_row = df_energy.loc[df_energy[‘avg_power_w’].idxmax()] print(f”峰值平均功率时段: {max_power_row[‘timestamp’]}, 功率: {max_power_row[‘avg_power_w’]:.0f} W”) if __name__ == “__main__”: main()

代码进阶解析

  • 函数封装: 将数据获取逻辑封装成fetch_energy_data函数,提高了代码的可重用性和可读性。参数time_unit允许你获取不同时间颗粒度的数据。
  • 使用Pandas: Pandas的DataFrame是处理表格数据的利器。我们轻松地将JSON列表转换为DataFrame,进行列重命名、时间转换和计算。
  • 数据持久化: 使用to_csv方法将DataFrame保存为CSV文件。CSV是通用格式,可以用Excel、Numbers或任何文本编辑器打开,也可以轻松导入到数据库或其他分析工具中。
  • 简单分析: 脚本演示了如何对获取的数据进行即时分析,如计算总发电量和找到峰值功率时段。

4.4 安全与配置管理:如何保护你的API密钥

将API密钥直接写在代码里是极不安全的,尤其是当你想将代码分享或上传到GitHub时。推荐以下两种方法:

方法一:使用环境变量(推荐)在运行脚本的系统中设置环境变量。

# Linux/macOS 终端 export SOLAREDGE_API_KEY=”YOUR_ACTUAL_API_KEY” export SOLAREDGE_SITE_ID=”YOUR_ACTUAL_SITE_ID” # Windows 命令提示符 set SOLAREDGE_API_KEY=YOUR_ACTUAL_API_KEY set SOLAREDGE_SITE_ID=YOUR_ACTUAL_SITE_ID

然后在Python脚本中读取:

import os API_KEY = os.environ.get(“SOLAREDGE_API_KEY”) SITE_ID = os.environ.get(“SOLAREDGE_SITE_ID”) if not API_KEY or not SITE_ID: raise ValueError(“请设置 SOLAREDGE_API_KEY 和 SOLAREDGE_SITE_ID 环境变量。”)

方法二:使用配置文件创建一个config.inisecrets.json文件(务必将其加入.gitignore,避免提交到版本库)。

// secrets.json { “solaredge_api_key”: “YOUR_ACTUAL_API_KEY”, “solaredge_site_id”: “YOUR_ACTUAL_SITE_ID” }

在脚本中读取:

import json with open(‘secrets.json’, ‘r’) as f: config = json.load(f) API_KEY = config[‘solaredge_api_key’] SITE_ID = config[‘solaredge_site_id’]

5. 部署与自动化:让数据采集在树莓派上7x24运行

脚本在本地运行成功只是第一步。我们的目标是建立一个无人值守的自动化数据采集系统。

5.1 在树莓派上设置Python环境

  1. 连接与更新: 通过SSH连接到你的树莓派,首先更新系统包列表。
    sudo apt update sudo apt upgrade -y
  2. 安装Python3和pip: 通常树莓派OS已预装,若没有则安装。
    sudo apt install python3 python3-pip -y
  3. 安装项目依赖: 在树莓派上同样安装requestspandas
    pip3 install requests pandas
  4. 传输脚本: 使用scp命令或将代码上传到GitHub后克隆的方式,将你的Python脚本(以及安全的配置文件)放到树莓派上,例如放在/home/pi/solaredge_monitor/目录下。
  5. 设置环境变量: 编辑树莓派用户的shell配置文件(如~/.bashrc),在末尾添加环境变量设置,然后重启终端或运行source ~/.bashrc使其生效。
    echo ‘export SOLAREDGE_API_KEY=”YOUR_KEY”‘ >> ~/.bashrc echo ‘export SOLAREDGE_SITE_ID=”YOUR_SITE_ID”‘ >> ~/.bashrc source ~/.bashrc

5.2 使用Cron实现定时任务

Cron是Linux系统的定时任务工具。我们可以让脚本每隔15分钟或1小时自动运行一次。

  1. 编辑当前用户的cron表:

    crontab -e
  2. 如果是第一次使用,可能会让你选择编辑器,选择nano(比较简单)。

  3. 在文件末尾添加一行。例如,让脚本每15分钟运行一次,并将输出日志追加到指定文件:

    */15 * * * * /usr/bin/python3 /home/pi/solaredge_monitor/solaredge_data.py >> /home/pi/solaredge_monitor/cron.log 2>&1
    • */15 * * * *: 时间表达式,表示每15分钟。
    • /usr/bin/python3: Python3解释器的完整路径(可用which python3命令查看)。
    • /home/pi/.../solaredge_data.py: 你的Python脚本的完整路径。
    • >> /home/pi/.../cron.log 2>&1: 将脚本的标准输出和标准错误都重定向(追加)到日志文件,方便调试。
  4. 保存并退出(在nano中按Ctrl+X,然后按Y确认,再按Enter)。

  5. Cron会立即生效。你可以通过查看日志文件来检查任务是否正常运行。

    tail -f /home/pi/solaredge_monitor/cron.log

5.3 数据存储优化:从CSV到SQLite数据库

当数据量日积月累,多个CSV文件会变得难以管理。使用轻量级数据库SQLite是更好的选择。

import sqlite3 from datetime import datetime def save_to_db(df, db_path=”solaredge_data.db”): “””将DataFrame数据存储到SQLite数据库””” if df is None or df.empty: return conn = sqlite3.connect(db_path) # 创建一个表来存储能源数据 df.to_sql(‘energy_detail’, conn, if_exists=’append’, index=False) conn.close() print(f”数据已存入数据库 {db_path}”) # 在主函数中,获取df_energy后,调用此函数 # save_to_db(df_energy)

使用SQLite后,你可以方便地用SQL查询历史数据,例如:“查询上个月发电总量”、“找出所有发电量低于平均值的日子”等,为更复杂的分析打下基础。

6. 常见问题排查与实战心得

在实际操作中,你几乎一定会遇到一些问题。下面是我踩过坑后总结的排查清单。

6.1 问题排查速查表

问题现象可能原因排查步骤与解决方案
HTTP 403 Forbidden1. API密钥无效或已撤销。
2. 密钥类型不对(如用了Site Key而非User Key)。
3. 该密钥无权访问指定的site_id
1. 登录SolarEdge后台,确认API Access已开启,重新生成并复制完整密钥。
2. 确认生成的是“User” API Key。
3. 确认SITE_ID与密钥所属站点一致。
HTTP 400 Bad Request1. 请求参数错误或缺失。
2. 日期格式不正确。
3. 请求了不存在的site_id
1. 检查URL和参数拼写,确保api_keysite_id参数正确传递。
2. 日期格式必须为YYYY-MM-DD
3. 核对SITE_ID
HTTP 429 Too Many Requests触发了API调用频率限制。1. 降低脚本执行频率(如从每分钟改为每15分钟)。
2. 查阅SolarEdge API文档,了解具体的限流策略并遵守。
返回数据为空[]null1. 请求的时间段内确实没有数据(如逆变器未启动、夜间)。
2. 时间单位timeUnit与时间段不匹配(如用DAY单位请求15分钟数据)。
1. 尝试请求一个已知有发电的日期。
2. 检查startDateendDate,确保timeUnit参数合理(如QUARTER_OF_AN_HOUR对应短时段)。
脚本在树莓派上权限错误1. 脚本文件没有执行权限。
2. 日志文件路径不可写。
1.chmod +x /home/pi/solaredge_monitor/solaredge_data.py
2. 确保日志文件目录存在且用户有写权限。
Cron任务不执行1. 命令路径错误。
2. 环境变量问题(Cron的环境与用户Shell环境不同)。
3. Python依赖未安装。
1. 在Cron命令中使用绝对路径。
2. 在Cron任务中直接设置环境变量,或在脚本开头通过读取配置文件解决。
3. 在Cron命令中指定完整的Python路径,并确保依赖是全局安装或使用虚拟环境。

6.2 实操心得与进阶建议

  1. 从“概览”接口开始overview接口信息全面且调用简单,非常适合验证API连通性和初步数据展示。在开发调试阶段,多用这个接口。
  2. 注意时区问题: SolarEdge API返回的时间戳通常是UTC时间。如果你在本地存储和分析,可能需要根据你的时区进行转换。在Pandas中,可以使用df[‘timestamp’].dt.tz_convert(‘Your/Timezone’)来处理。
  3. 实现优雅的失败重试: 网络请求可能偶尔失败。在生产脚本中,建议为requests.get()添加重试逻辑。可以使用tenacitybackoff库,或者自己写一个简单的重试循环,在遇到短暂的网络错误时重试几次。
  4. 数据去重: 如果你的脚本可能因为某种原因(如手动执行、Cron意外触发)在短时间内多次运行,向数据库插入数据时需要考虑去重。可以在数据库表中为timestamp字段创建唯一索引,或者使用INSERT OR IGNORE语句。
  5. 超越数据采集: 获取数据只是第一步。真正的价值在于应用。你可以:
    • 可视化: 使用matplotlib,plotlygrafana(如果部署在服务器上)创建本地图表。
    • 告警: 设置阈值,当发电量异常低(可能设备故障)或今日发电量已达目标时,通过邮件、Telegram Bot或手机推送通知自己。
    • 集成智能家居: 将实时发电功率通过MQTT发送到Home Assistant,作为自动化条件(如“当发电功率>3000W时,打开空调”)。

将数据拿回本地,你获得的不仅仅是数字,更是对自家能源系统的深度理解和控制能力。这个过程本身,就是一次极有价值的物联网和编程实践。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询