commit
c0dc90ca79
7 changed files with 644 additions and 0 deletions
@ -0,0 +1,4 @@ |
|||||
|
__pycache__/ |
||||
|
*.pyc |
||||
|
.env |
||||
|
.vscode/ |
||||
@ -0,0 +1,287 @@ |
|||||
|
API Status: 200 |
||||
|
API Body: { |
||||
|
"req_serial_num":"202604069c4343c38cc94dfb3a71c7fc", |
||||
|
"result_code":"1", |
||||
|
"result_msg":"success", |
||||
|
"result_data":{ |
||||
|
"pageList":[ |
||||
|
{ |
||||
|
"total_energy":{ |
||||
|
"unit":"MWh", |
||||
|
"value":"43.13" |
||||
|
}, |
||||
|
"alarm_count":0, |
||||
|
"latitude":50.56129590941345, |
||||
|
"description":null, |
||||
|
"total_income_update_time":null, |
||||
|
"valid_flag":1, |
||||
|
"curr_power":{ |
||||
|
"unit":"W", |
||||
|
"value":"0" |
||||
|
}, |
||||
|
"ps_fault_status":3, |
||||
|
"co2_reduce_update_time":null, |
||||
|
"install_date":"2024-02-07 08:13:34", |
||||
|
"build_status":2, |
||||
|
"today_energy_update_time":"2026-04-06T05:01:52+08:00", |
||||
|
"year_income_update_time":null, |
||||
|
"total_energy_update_time":"2026-04-06T05:01:52+08:00", |
||||
|
"ps_type":5, |
||||
|
"longitude":9.72615326343812, |
||||
|
"total_capcity_update_time":"2024-03-19T15:51:21+08:00", |
||||
|
"equivalent_hour_update_time":"2026-04-06T05:01:52+08:00", |
||||
|
"ps_name":"PV_Siegel", |
||||
|
"co2_reduce_total":{ |
||||
|
"unit":"kg", |
||||
|
"value":"42936" |
||||
|
}, |
||||
|
"curr_power_update_time":"2026-04-06T05:01:52+08:00", |
||||
|
"today_income":{ |
||||
|
"unit":"", |
||||
|
"value":"--" |
||||
|
}, |
||||
|
"grid_connection_status":0, |
||||
|
"equivalent_hour":{ |
||||
|
"unit":"Hour", |
||||
|
"value":"2.95" |
||||
|
}, |
||||
|
"co2_reduce_total_update_time":null, |
||||
|
"ps_location":"Geisaer Weg 13, 36100 Petersberg, Deutschland", |
||||
|
"total_income":{ |
||||
|
"unit":"EUR", |
||||
|
"value":"6901" |
||||
|
}, |
||||
|
"total_capcity":{ |
||||
|
"unit":"kWp", |
||||
|
"value":"21.93" |
||||
|
}, |
||||
|
"share_type":"0", |
||||
|
"year_income":{ |
||||
|
"unit":"EUR", |
||||
|
"value":"642.409" |
||||
|
}, |
||||
|
"ps_current_time_zone":"GMT+2", |
||||
|
"today_income_update_time":null, |
||||
|
"ps_id":5425899, |
||||
|
"grid_connection_time":null, |
||||
|
"connect_type":2, |
||||
|
"today_energy":{ |
||||
|
"unit":"kWh", |
||||
|
"value":"64.8" |
||||
|
}, |
||||
|
"ps_status":1, |
||||
|
"co2_reduce":{ |
||||
|
"unit":"kg", |
||||
|
"value":"0" |
||||
|
}, |
||||
|
"fault_count":0 |
||||
|
} |
||||
|
], |
||||
|
"rowCount":1 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
API Status: 200 |
||||
|
API Body: { |
||||
|
"req_serial_num":"2026040649654a0cb04020d10860cc31", |
||||
|
"result_code":"1", |
||||
|
"result_msg":"success", |
||||
|
"result_data":{ |
||||
|
"pageList":[ |
||||
|
{ |
||||
|
"type_name":"Batterie", |
||||
|
"ps_key":"5425899_43_2_1", |
||||
|
"firmware_version_info":{ |
||||
|
"bat_version":"SBRBCU-S_22011.01.21" |
||||
|
}, |
||||
|
"device_type":43, |
||||
|
"factory_name":"SUNGROW", |
||||
|
"uuid":3799231, |
||||
|
"grid_connection_date":"2024-02-07 16:42:54", |
||||
|
"device_name":"Battery (WR Master)", |
||||
|
"dev_fault_status":4, |
||||
|
"device_model_id":355481, |
||||
|
"communication_dev_sn":"B2341313692", |
||||
|
"device_model_code":"SBR160", |
||||
|
"chnnl_id":1, |
||||
|
"rel_time":"2024-02-07 16:42:54", |
||||
|
"device_sn":"S2309190060", |
||||
|
"dev_status":"1", |
||||
|
"rel_state":1, |
||||
|
"device_code":2, |
||||
|
"ps_id":5425899 |
||||
|
}, |
||||
|
{ |
||||
|
"type_name":"Wechselrichter", |
||||
|
"ps_key":"5425899_1_1_2", |
||||
|
"firmware_version_info":{ |
||||
|
"sdsp_version":"SUBCTL-S_04011.01.01", |
||||
|
"mdsp_version":"BERYL-S_03011.01.74", |
||||
|
"lcd_version":"BERYL-S_01011.01.39", |
||||
|
"afci_version":"AFD_06001.02.03" |
||||
|
}, |
||||
|
"device_type":1, |
||||
|
"factory_name":"SUNGROW", |
||||
|
"uuid":3798939, |
||||
|
"grid_connection_date":"2024-02-07 15:17:44", |
||||
|
"device_name":"WR Slave", |
||||
|
"dev_fault_status":4, |
||||
|
"device_model_id":742, |
||||
|
"communication_dev_sn":"B2321768031", |
||||
|
"device_model_code":"SG10RT", |
||||
|
"chnnl_id":2, |
||||
|
"rel_time":"2024-02-07 15:17:44", |
||||
|
"device_sn":"A2322221161", |
||||
|
"dev_status":"1", |
||||
|
"rel_state":1, |
||||
|
"device_code":1, |
||||
|
"ps_id":5425899 |
||||
|
}, |
||||
|
{ |
||||
|
"type_name":"Kommunikationsmodul", |
||||
|
"ps_key":"5425899_22_247_2", |
||||
|
"firmware_version_info":{ |
||||
|
"m_version":"WINET-SV200.001.00.P038" |
||||
|
}, |
||||
|
"device_type":22, |
||||
|
"factory_name":"SUNGROW", |
||||
|
"uuid":3798938, |
||||
|
"grid_connection_date":"2024-02-07 15:17:44", |
||||
|
"device_name":"Communication Module2", |
||||
|
"dev_fault_status":4, |
||||
|
"device_model_id":1361, |
||||
|
"communication_dev_sn":"B2321768031", |
||||
|
"device_model_code":"WiNet-S", |
||||
|
"chnnl_id":2, |
||||
|
"rel_time":"2024-02-07 15:17:44", |
||||
|
"device_sn":"B2321768031", |
||||
|
"dev_status":"1", |
||||
|
"rel_state":1, |
||||
|
"device_code":247, |
||||
|
"ps_id":5425899 |
||||
|
}, |
||||
|
{ |
||||
|
"type_name":"Hybrid (speicherfähig)", |
||||
|
"ps_key":"5425899_14_1_1", |
||||
|
"firmware_version_info":{ |
||||
|
"sdsp_version":"SUBCTL-S_04011.01.01", |
||||
|
"mdsp_version":"SAPPHIRE-H_03011.51.04", |
||||
|
"lcd_version":"SAPPHIRE-H_01011.51.05", |
||||
|
"bat_version":"SBRBCU-S_22011.01.21" |
||||
|
}, |
||||
|
"device_type":14, |
||||
|
"factory_name":"SUNGROW", |
||||
|
"uuid":3798934, |
||||
|
"grid_connection_date":"2024-02-07 15:14:36", |
||||
|
"device_name":"WR Master", |
||||
|
"dev_fault_status":4, |
||||
|
"device_model_id":366316, |
||||
|
"communication_dev_sn":"B2341313692", |
||||
|
"device_model_code":"SH10RT-V112", |
||||
|
"chnnl_id":1, |
||||
|
"rel_time":"2024-02-07 15:14:36", |
||||
|
"device_sn":"A2341306461", |
||||
|
"dev_status":"1", |
||||
|
"rel_state":1, |
||||
|
"device_code":1, |
||||
|
"ps_id":5425899 |
||||
|
}, |
||||
|
{ |
||||
|
"type_name":"Kommunikationsmodul", |
||||
|
"ps_key":"5425899_22_247_1", |
||||
|
"firmware_version_info":{ |
||||
|
"m_version":"WINET-SV200.001.00.P038" |
||||
|
}, |
||||
|
"device_type":22, |
||||
|
"factory_name":"SUNGROW", |
||||
|
"uuid":3798933, |
||||
|
"grid_connection_date":"2024-02-07 15:14:35", |
||||
|
"device_name":"Communication Module1", |
||||
|
"dev_fault_status":4, |
||||
|
"device_model_id":1361, |
||||
|
"communication_dev_sn":"B2341313692", |
||||
|
"device_model_code":"WiNet-S", |
||||
|
"chnnl_id":1, |
||||
|
"rel_time":"2024-02-07 15:14:35", |
||||
|
"device_sn":"B2341313692", |
||||
|
"dev_status":"1", |
||||
|
"rel_state":1, |
||||
|
"device_code":247, |
||||
|
"ps_id":5425899 |
||||
|
} |
||||
|
], |
||||
|
"rowCount":5 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
API Status: 200 |
||||
|
API Body: { |
||||
|
"req_serial_num":"20260406cbc64e2ca6dab1c63d4073e3", |
||||
|
"result_code":"1", |
||||
|
"result_msg":"success", |
||||
|
"result_data":{ |
||||
|
"pageList":[ |
||||
|
{ |
||||
|
"type_name":"Anlage", |
||||
|
"ps_key":"5425899_11_0_0", |
||||
|
"firmware_version_info":{}, |
||||
|
"device_type":11, |
||||
|
"factory_name":null, |
||||
|
"uuid":3798932, |
||||
|
"grid_connection_date":"2024-02-07 15:13:34", |
||||
|
"device_name":"PV_Siegel", |
||||
|
"dev_fault_status":4, |
||||
|
"device_model_id":null, |
||||
|
"communication_dev_sn":null, |
||||
|
"device_model_code":null, |
||||
|
"chnnl_id":0, |
||||
|
"rel_time":null, |
||||
|
"device_sn":null, |
||||
|
"dev_status":"1", |
||||
|
"rel_state":1, |
||||
|
"device_code":0, |
||||
|
"ps_id":5425899 |
||||
|
} |
||||
|
], |
||||
|
"rowCount":1 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
API Status: 200 |
||||
|
API Body: { |
||||
|
"req_serial_num":"202604064c60475f975eca70db983580", |
||||
|
"result_code":"1", |
||||
|
"result_msg":"success", |
||||
|
"result_data":{ |
||||
|
"fail_ps_key_list":[], |
||||
|
"device_point_list":[ |
||||
|
{ |
||||
|
"device_point":{ |
||||
|
"ps_key":"5425899_11_0_0", |
||||
|
"device_sn":null, |
||||
|
"dev_status":1, |
||||
|
"p83009":"33400.0", |
||||
|
"p83119":"18900.0", |
||||
|
"p83118":"39400.0", |
||||
|
"p83097":"5900.0", |
||||
|
"p83072":"25400.0", |
||||
|
"uuid":3798932, |
||||
|
"p83022":"64800.0", |
||||
|
"p83033":"0.0", |
||||
|
"p83252":"0.557", |
||||
|
"device_name":"PV_Siegel", |
||||
|
"dev_fault_status":4, |
||||
|
"ps_id":5425899, |
||||
|
"communication_dev_sn":null, |
||||
|
"device_time":"20260405234500" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
{ |
||||
|
"version": "0.2.0", |
||||
|
"configurations": [ |
||||
|
{ |
||||
|
"name": "Python: main.py", |
||||
|
"type": "python", |
||||
|
"request": "launch", |
||||
|
"program": "${workspaceFolder}/main.py", |
||||
|
"console": "integratedTerminal", |
||||
|
"envFile": "${workspaceFolder}/.env" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,92 @@ |
|||||
|
from sungrow_api import get_device_list, login, call_api, get_power_station_list, get_device_list, get_device_realtime_data, ensure_success, pretty_print |
||||
|
from sungrow_state import save_state |
||||
|
|
||||
|
def main(): |
||||
|
print("Logging in...") |
||||
|
token = login() |
||||
|
print("Token:", token[:12], "...") |
||||
|
|
||||
|
# 1) Get plant list |
||||
|
plant_list = get_power_station_list(token, debug=True) |
||||
|
print("Plant List Response:") |
||||
|
pretty_print(plant_list) |
||||
|
|
||||
|
# Validate before accessing |
||||
|
ensure_success(plant_list) |
||||
|
|
||||
|
# 2) Extract ps_id |
||||
|
ps_id = plant_list["result_data"]["pageList"][0]["ps_id"] |
||||
|
print("Using ps_id:", ps_id) |
||||
|
|
||||
|
|
||||
|
# 3) Query device list |
||||
|
device_list = get_device_list( |
||||
|
token=token, |
||||
|
ps_id=ps_id, |
||||
|
cur_page=1, |
||||
|
size=20, |
||||
|
is_virtual_unit="0", # 0 physical devices, 1 virtual |
||||
|
#device_type_list=[1, 3, 11], # inverter, grid point, plant |
||||
|
#rel_state="1", # only claimed devices |
||||
|
is_get_firmware_version="1", # 1: include firmware info |
||||
|
debug=True |
||||
|
) |
||||
|
|
||||
|
# 4) Query device list on plant level |
||||
|
device_list = get_device_list( |
||||
|
token=token, |
||||
|
ps_id=ps_id, |
||||
|
cur_page=1, |
||||
|
size=20, |
||||
|
is_virtual_unit="1", # 0 physical devices, 1 virtual |
||||
|
#device_type_list=[1, 3, 11], # inverter, grid point, plant |
||||
|
#rel_state="1", # only claimed devices |
||||
|
is_get_firmware_version="0", # 1: include firmware info |
||||
|
debug=True |
||||
|
) |
||||
|
|
||||
|
# Extract relevant data from the first device in the list (assuming it's the plant-level virtual device) |
||||
|
device_info = device_list["result_data"]["pageList"][0] |
||||
|
|
||||
|
ps_key = device_info["ps_key"] |
||||
|
device_name = device_info["device_name"] |
||||
|
|
||||
|
# Save them persistently |
||||
|
save_state(ps_key=ps_key, device_name=device_name) |
||||
|
|
||||
|
|
||||
|
# 4) Query realtime data on plant level |
||||
|
realtime = get_device_realtime_data( |
||||
|
token=token, |
||||
|
point_id_list = [ |
||||
|
"83022", # Daily Yield of Plant "64800.0" ok |
||||
|
"83033", # Plant Power "0.0" |
||||
|
#"83006", # Meter Daily Yield |
||||
|
#"83011", # Meter E-daily Consumption |
||||
|
#"83052", # Load Power |
||||
|
"83072", # Feed-in Energy Today "25400.0" ok |
||||
|
"83252", # Battery Level (SOC) "0.557" ok |
||||
|
#"83129", # Battery SOC |
||||
|
"83009", # Inverter Daily Yield "33400.0" ok, nur Inverter "WR Slave" |
||||
|
"83097", # Daily Direct Energy Consumption "5900.0" ?? |
||||
|
"83118", # Daily Load Consumption "39400.0" ok |
||||
|
"83119" # Daily Feed-in Energy (PV) "18900.0" ?? |
||||
|
], |
||||
|
device_type=11, |
||||
|
ps_key_list=["5425899_11_0_0"], |
||||
|
debug=True |
||||
|
) |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
print("Device List Response:") |
||||
|
pretty_print(device_list) |
||||
|
|
||||
|
|
||||
|
#print("Response:") |
||||
|
#print(data) |
||||
|
|
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
main() |
||||
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"ps_id": 5425899, |
||||
|
"device_name": "PV_Siegel", |
||||
|
"ps_key": "5425899_11_0_0" |
||||
|
} |
||||
@ -0,0 +1,202 @@ |
|||||
|
import os |
||||
|
import time |
||||
|
import uuid |
||||
|
import requests |
||||
|
import json |
||||
|
from dotenv import load_dotenv |
||||
|
from sungrow_state import load_ps_id |
||||
|
|
||||
|
|
||||
|
|
||||
|
BASE_URL = os.getenv("SUNGROW_BASE_URL") |
||||
|
USERNAME = os.getenv("SUNGROW_USERNAME") |
||||
|
PASSWORD = os.getenv("SUNGROW_PASSWORD") |
||||
|
APPKEY = os.getenv("SUNGROW_APPKEY") |
||||
|
KEY = os.getenv("SUNGROW_KEY") |
||||
|
|
||||
|
|
||||
|
def login(): |
||||
|
url = f"{BASE_URL}/openapi/login" |
||||
|
|
||||
|
headers = { |
||||
|
"Content-Type": "application/json;charset=UTF-8", |
||||
|
"sys_code": "901", |
||||
|
"x-access-key": KEY |
||||
|
} |
||||
|
|
||||
|
body = { |
||||
|
"user_account": USERNAME, |
||||
|
"user_password": PASSWORD, |
||||
|
"appkey": APPKEY, |
||||
|
"lang": "_de_DE" |
||||
|
} |
||||
|
|
||||
|
response = requests.post(url, json=body, headers=headers, timeout=10) |
||||
|
|
||||
|
print("Login Status:", response.status_code) |
||||
|
print("Login Body:", response.text) |
||||
|
|
||||
|
response.raise_for_status() |
||||
|
|
||||
|
data = response.json() |
||||
|
|
||||
|
if data.get("result_code") != "1": |
||||
|
raise Exception(f"Login failed: {data}") |
||||
|
|
||||
|
return data["result_data"]["token"] |
||||
|
|
||||
|
|
||||
|
def call_api(endpoint: str, token: str, params: dict = None, debug: bool = False): |
||||
|
if params is None: |
||||
|
params = {} |
||||
|
|
||||
|
# Auto-inject ps_id if requested |
||||
|
if "ps_id" in params and params["ps_id"] is None: |
||||
|
stored_ps_id = load_ps_id() |
||||
|
if stored_ps_id is None: |
||||
|
raise ValueError("ps_id was requested but no stored ps_id found.") |
||||
|
params["ps_id"] = stored_ps_id |
||||
|
|
||||
|
url = f"{BASE_URL}{endpoint}" |
||||
|
|
||||
|
headers = { |
||||
|
"Content-Type": "application/json;charset=UTF-8", |
||||
|
"sys_code": "901", |
||||
|
"x-access-key": KEY |
||||
|
} |
||||
|
|
||||
|
base_body = { |
||||
|
"appkey": APPKEY, |
||||
|
"token": token, |
||||
|
"lang": "_de_DE", |
||||
|
"timestamp": str(int(time.time() * 1000)), |
||||
|
"nonce": uuid.uuid4().hex |
||||
|
} |
||||
|
|
||||
|
body = {**base_body, **params} |
||||
|
|
||||
|
# Debug: print full request |
||||
|
if debug: |
||||
|
import json |
||||
|
print("\n=== API REQUEST ===") |
||||
|
print("URL:", url) |
||||
|
print("Headers:", json.dumps(headers, indent=4, ensure_ascii=False)) |
||||
|
print("Body:", json.dumps(body, indent=4, ensure_ascii=False)) |
||||
|
print("===================\n") |
||||
|
|
||||
|
response = requests.post(url, json=body, headers=headers, timeout=10) |
||||
|
|
||||
|
# Debug: print full response |
||||
|
if debug: |
||||
|
print("=== API RESPONSE ===") |
||||
|
print("Status:", response.status_code) |
||||
|
print("Body:", response.text) |
||||
|
print("====================\n") |
||||
|
|
||||
|
response.raise_for_status() |
||||
|
return response.json() |
||||
|
|
||||
|
|
||||
|
def get_power_station_list(token: str, cur_page: int = 1, size: int = 10, debug: bool = False): |
||||
|
""" |
||||
|
Wrapper for /openapi/getPowerStationList |
||||
|
""" |
||||
|
params = { |
||||
|
"curPage": cur_page, |
||||
|
"size": size |
||||
|
} |
||||
|
|
||||
|
return call_api("/openapi/getPowerStationList", token, params, debug=debug) |
||||
|
|
||||
|
def get_device_list( |
||||
|
token: str, |
||||
|
ps_id: int, |
||||
|
cur_page: int = 1, |
||||
|
size: int = 50, |
||||
|
is_virtual_unit: str | None = None, |
||||
|
device_type_list: list | None = None, |
||||
|
rel_state: str | None = None, |
||||
|
is_get_firmware_version: str | None = None, |
||||
|
debug: bool = False |
||||
|
): |
||||
|
""" |
||||
|
Wrapper for /openapi/getDeviceList |
||||
|
|
||||
|
Parameters: |
||||
|
ps_id (int): Plant ID (required) |
||||
|
cur_page (int): Page number (required) |
||||
|
size (int): Page size (required) |
||||
|
is_virtual_unit (str): "1" = virtual, "0" = physical |
||||
|
device_type_list (list): e.g. [1, 3, 11] |
||||
|
rel_state (str): "0" = unclaimed, "1" = claimed |
||||
|
is_get_firmware_version (str): "0" = no, "1" = yes |
||||
|
""" |
||||
|
|
||||
|
params = { |
||||
|
"ps_id": ps_id, |
||||
|
"curPage": cur_page, |
||||
|
"size": size |
||||
|
} |
||||
|
|
||||
|
# Only include optional parameters if they are provided |
||||
|
if is_virtual_unit is not None: |
||||
|
params["is_virtual_unit"] = is_virtual_unit |
||||
|
|
||||
|
if device_type_list is not None: |
||||
|
params["device_type_list"] = device_type_list |
||||
|
|
||||
|
if rel_state is not None: |
||||
|
params["rel_state"] = rel_state |
||||
|
|
||||
|
if is_get_firmware_version is not None: |
||||
|
params["is_get_firmware_version"] = is_get_firmware_version |
||||
|
|
||||
|
return call_api("/openapi/getDeviceList", token, params, debug=debug) |
||||
|
|
||||
|
def get_device_realtime_data( |
||||
|
token: str, |
||||
|
point_id_list: list, |
||||
|
device_type: int, |
||||
|
ps_key_list: list | None = None, |
||||
|
sn_list: list | None = None, |
||||
|
debug: bool = False |
||||
|
): |
||||
|
""" |
||||
|
Wrapper for /openapi/getDeviceRealTimeData |
||||
|
|
||||
|
Required: |
||||
|
point_id_list (list[str]) |
||||
|
device_type (int) |
||||
|
|
||||
|
Optional (choose one): |
||||
|
ps_key_list (list[str]) |
||||
|
sn_list (list[str]) |
||||
|
""" |
||||
|
|
||||
|
if ps_key_list is None and sn_list is None: |
||||
|
raise ValueError("You must provide either ps_key_list or sn_list.") |
||||
|
|
||||
|
params = { |
||||
|
"point_id_list": point_id_list, |
||||
|
"device_type": device_type |
||||
|
} |
||||
|
|
||||
|
if ps_key_list is not None: |
||||
|
params["ps_key_list"] = ps_key_list |
||||
|
|
||||
|
if sn_list is not None: |
||||
|
params["sn_list"] = sn_list |
||||
|
|
||||
|
return call_api("/openapi/getDeviceRealTimeData", token, params, debug=debug) |
||||
|
|
||||
|
|
||||
|
def ensure_success(response: dict): |
||||
|
if response.get("result_code") != "1": |
||||
|
raise Exception( |
||||
|
f"API error {response.get('result_code')}: {response.get('result_msg')}" |
||||
|
) |
||||
|
|
||||
|
|
||||
|
def pretty_print(data): |
||||
|
import json |
||||
|
print(json.dumps(data, indent=4, ensure_ascii=False)) |
||||
@ -0,0 +1,41 @@ |
|||||
|
import json |
||||
|
import os |
||||
|
|
||||
|
STATE_FILE = "plant_state.json" |
||||
|
|
||||
|
|
||||
|
def save_state(ps_id=None, ps_key=None, device_name=None): |
||||
|
state = load_state() or {} |
||||
|
|
||||
|
if device_name is not None: |
||||
|
state["device_name"] = device_name |
||||
|
if ps_id is not None: |
||||
|
state["ps_id"] = ps_id |
||||
|
if ps_key is not None: |
||||
|
state["ps_key"] = ps_key |
||||
|
|
||||
|
|
||||
|
with open(STATE_FILE, "w") as f: |
||||
|
json.dump(state, f, indent=4) |
||||
|
|
||||
|
|
||||
|
def load_state(): |
||||
|
if not os.path.exists(STATE_FILE): |
||||
|
return None |
||||
|
with open(STATE_FILE) as f: |
||||
|
return json.load(f) |
||||
|
|
||||
|
|
||||
|
def load_ps_id(): |
||||
|
state = load_state() |
||||
|
return state.get("ps_id") if state else None |
||||
|
|
||||
|
|
||||
|
def load_ps_key(): |
||||
|
state = load_state() |
||||
|
return state.get("ps_key") if state else None |
||||
|
|
||||
|
|
||||
|
def load_device_name(): |
||||
|
state = load_state() |
||||
|
return state.get("device_name") if state else None |
||||
Loading…
Reference in new issue