Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
# --exit-zero removed to enforce zero lint errors
flake8 . --extend-ignore=E128,E124,F403,F405 --count --max-complexity=10 --max-line-length=127 --statistics
flake8 . --extend-ignore=C901,E128,E124,F403,F405 --count --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytest --capture=tee-sys -v
99 changes: 63 additions & 36 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
"""Example application."""
"""
Example application.
Demonstrates usage of the SoliscloudAPI class to interact with the Soliscloud
API. It also shows how to use the Helpers class for common tasks.
Fill in your own API key and secret in config.json before running.
"""

import asyncio
import logging
import json

from aiohttp import ClientSession

from soliscloud_api import SoliscloudAPI
from soliscloud_api.helpers import Helpers
from soliscloud_api import SoliscloudAPI, SoliscloudError, \
SoliscloudHttpError, SoliscloudTimeoutError, SoliscloudApiError, \
Helpers


logging.basicConfig(level=logging.DEBUG)
Expand All @@ -29,52 +36,54 @@ async def main():
soliscloud = SoliscloudAPI(
'https://soliscloud.com:13333', websession)

# Retrieves list of Stations, a.k.a. plants,
# containing the inverters.
# Retrieve list of Stations, a.k.a. plants
station_list = await soliscloud.user_station_list(
api_key, api_secret, page_no=1, page_size=100)
# Australian accounts require nmi, uncomment if required.
# (NOT TESTED!)
# station_list = await soliscloud.user_station_list(
# api_key, api_secret, page_no=1,
# page_size=100, nmi_code=api_nmi)
api_key, api_secret, page_no=1, page_size=100,
# Australian accounts require nmi, uncomment if required.
# (NOT TESTED!)
# nmi_code=api_nmi
)
station_list_json = json.dumps(station_list, indent=2)
# Use helper class as alternative
# Use helper class as alternative to directly retrieve station id's
station_ids = await Helpers.get_station_ids(
soliscloud, api_key, api_secret)

# Get inverters for all stations
# Get inverter data for all stations
inverter_list = await soliscloud.inverter_list(
api_key, api_secret, page_no=1, page_size=100)
# Australian accounts require nmi, uncomment if required.
# (NOT TESTED!)
# inverter_list = await soliscloud.inverter_list(
# api_key, api_secret, page_no=1,
# page_size=100, nmi_code=api_nmi)
api_key, api_secret, page_no=1, page_size=100,
# Australian accounts require nmi, uncomment if required.
# (NOT TESTED!)
# nmi_code=api_nmi
)
inverter_list_json = json.dumps(inverter_list, indent=2)
# Use helper class as alternative
inverter_ids = await Helpers.get_inverter_ids(
soliscloud, api_key, api_secret)
# Use helper class to retrieve all inverter id's
inverter_ids = Helpers.get_inverter_ids_from_response(
inverter_list)

inverter_detail = await soliscloud.inverter_detail(
api_key, api_secret, inverter_id=inverter_ids[0])
inverter_detail_json = json.dumps(inverter_detail, indent=2)
# Get detailed data for all inverters
idl = await soliscloud.inverter_detail_list(api_key, api_secret)
idl_json = json.dumps(idl, indent=2)

# Use serial number of first inverter to get details
# (should be same as first in inverter_list)
inverter_x = await soliscloud.inverter_detail(
api_key, api_secret, inverter_sn=inverter_list[0]['sn'])
inverter_detail_json = json.dumps(inverter_x, indent=2)

# Get data collectors for all stations
collector_list = await soliscloud.collector_list(
api_key, api_secret, page_no=1, page_size=100)
# Australian accounts require nmi, uncomment if required.
# (NOT TESTED!)
# collector_list = await soliscloud.collector_list(
# api_key, api_secret, page_no=1,
# page_size=100, nmi_code=api_nmi)
api_key, api_secret, page_no=1, page_size=100,
# Australian accounts require nmi, uncomment if required.
# (NOT TESTED!)
# nmi_code=api_nmi
)
collector_list_json = json.dumps(collector_list, indent=2)

except (
SoliscloudAPI.SolisCloudError,
SoliscloudAPI.HttpError,
SoliscloudAPI.TimeoutError,
SoliscloudAPI.ApiError,
SoliscloudError,
SoliscloudHttpError,
SoliscloudTimeoutError,
SoliscloudApiError,
) as error:
print(f"Error: {error}")
else:
Expand All @@ -88,14 +97,32 @@ async def main():
print(f"{inverter_list_json}")

print("InverterDetails call success:")
print(f"{inverter_detail_json}")
print(inverter_detail_json)
for key in ['iA', 'uA', 'pA', 'iB', 'uB', 'pB', 'iC', 'uC', 'pC']:
print(f"{key}: {inverter_x[key]}")

print("Helper call success:")
print(f"{inverter_ids}")

print("CollectorList call success:")
print(f"{collector_list_json}")

print("InverterDetailList call success:")
print(idl_json)
for key in [
'iAc1',
'uAc1',
'pA',
'iB',
'uB',
'pB',
'iC',
'uC',
'pC',
'apparentPower'
]:
print(f"{key}: {idl[0][key]}")

loop = asyncio.new_event_loop()
loop.run_until_complete(main())
loop.close()
85 changes: 85 additions & 0 deletions example_entities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""
Example application.
Demonstrates the use of entity classes as a higher level interface to the
Soliscloud API. Fill in your own API key and secret in config.json before
running.
By using the entity classes you can more easily access the data
attributes of the plant, inverters and collectors.

There are 2 ways to create the entity classes:
1. Use the class method 'initialize_from_data' to create entity instances
from data retrieved from the API. It will create one or more entity
instances from the data passed in. This method will not retrieve any data
from the API, so you need to do that yourself first. It will not
recursively create all entities, i.e. plants, inverters and collectors.
You need to call it separately for each entity class.
2. Use the class method 'initialize_from_session' to create entity instances
by passing in the aiohttp session and API credentials. This method will
retrieve the data from the API and create the entity instances. It
will recursively create all entities, i.e. plants, inverters
and collectors when called on the Plant class and inverters and collectors
when called on the Inverter class.
"""
from __future__ import annotations

import asyncio
import logging
import json

from aiohttp import ClientSession

from soliscloud_api import SoliscloudError, SoliscloudHttpError, \
SoliscloudTimeoutError, SoliscloudApiError
from soliscloud_api import Plant, Inverter, Collector # noqa: F401
from soliscloud_api import SoliscloudAPI as api


logging.basicConfig(level=logging.DEBUG)


async def main():
"""Run main function."""
# Put your own key and secret in the config.json file
with open('config.json', 'r') as file:
data = json.load(file)

api_key = data['key']
api_secret = bytearray(data['secret'], 'utf-8')
# Australian accounts require nmi, uncomment if required.
# (NOT TESTED!)
# api_nmi = data['nmi']

async with ClientSession() as websession:
try:
the_api = api('https://soliscloud.com:13333', websession)
data = await the_api.inverter_list(
api_key, api_secret, page_no=1, page_size=100)
# use plant_id of your own plant here to get inverters for that plant
# use inverter_id to only get one specific inverter
inverters = Inverter.initialize_from_data(
data, plant_id='your plant id goes here')
plants = await Plant.initialize_from_session(
websession, api_key, api_secret)
except (
SoliscloudError,
SoliscloudHttpError,
SoliscloudTimeoutError,
SoliscloudApiError,
) as error:
print(f"Error: {error}")
else:
p = plants[0]
print(f"Plant id: {p.plant_id}")
print(f"Plant name: {p.data['station_name']}")
print(f"Number of inverters: {len(p.inverters)}")
for inv in inverters:
print(f"Inverter id: {inv.inverter_id}")
# The attributes if the inverter are in inv.data
# If an attribute has a unit then the value is of
# dimensioned type
print(f"Total energy: {inv.data['etotal']}")
print(f"Total energy value: {inv.data['etotal'].value}")
print(f"Total energy unit: {inv.data['etotal'].unit}")
loop = asyncio.new_event_loop()
loop.run_until_complete(main())
loop.close()
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "soliscloud-api"
version = "1.2.0"
version = "1.3.0"
authors = [
{ name="Peter van Hulten", email="peter.vanhulten@gmx.net" },
]
Expand Down
Loading