diff --git a/README.md b/README.md index 19b6efa..13780e3 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,68 @@ # soliscloud-api Python implementation for the SolisCloud API -Supports all endpoints specified in SolisCloud API v1.2 for reading Solis PV monitoring data from the SolisCloud service. +Supports all endpoints specified in SolisCloud API spec 2.0 for reading Solis PV monitoring data from the SolisCloud service. # Prerequisites Usage of the API requires an active account on https://www.soliscloud.com and also requires an API key and secret, to be obtained via SolisCloud. -# Supported endpoints - -* /V1/API/STATIONYEAR (PLANT YEARLY GRAPH) -* /V1/API/STATIONALL (PLANT CUMULATIVE GRAPH) -* /V1/API/INVERTERDAY (INVERTER DAILY GRAPH) -* /V1/API/INVERTERMONTH (INVERTER MONTHLY GRAPH) -* /V1/API/INVERTERYEAR (INVERTER YEARLY GRAPH) -* /V1/API/INVERTERALL (INVERTER CUMULATIVE GRAPH) -* /V1/API/ALARMLIST (ALARM INFO CHECK) -* /V1/API/STATIONDETAILLIST (BATCH ACQUIRE PLANT DETAILS) -* /V1/API/INVERTERDETAILLIST (BATCH ACQUIRE INVERTER DETAILS) -* /V1/API/STATIONDAYENERGYLIST (BATCH ACQUIRE PLANT DAILY GENERATION) -* /V1/API/STATIONMONTHENERGYLIST (BATCH ACQUIRE PLANT MONTHLY GENERATION) -* /V1/API/STATIONYEARENERGYLIST (BATCH ACQUIRE PLANT YEARLY GENERATION) -* /V1/API/EPMLIST (EPM LIST) -* /V1/API/EPMDETAIL (EPM DETAILS) -* /V1/API/EPM/DAY (EPM DAILY GRAPH) -* /V1/API/EPM/MONTH (EPM MONTHLY GRAPH) -* /V1/API/EPM/YEAR (EPM YEARLY GRAPH) -* /V1/API/EPM/ALL (EPM CUMULATIVE GRAPH) +* Submit a [service ticket](https://solis-service.solisinverters.com/support/solutions/articles/44002212561-api-access-soliscloud) and wait till it is resolved. +* Go to https://www.soliscloud.com/#/apiManage. +* Activate API management and agree with the usage conditions. +* After activation, click on view key tot get a pop-up window asking for the verification code. +* First click on "Verification code" after which you get an image with 2 puzzle pieces, which you need to overlap each other using the slider below. +* After that, you will receive an email with the verification code you need to enter (within 60 seconds). +* Once confirmed, you get the API ID, secret and API URL + + +# Supported API calls +NOTE: The spec uses the terms Plant, Station and Power Station interchangeably. In this document we will use plant. + +| Call | Description | +|----------------------------------|---------------------------------------------------------------| +| /v1/api/inverterList | Obtain list of all inverters under account or a specific plant. | +| /v1/api/inverterDetail | Obtain details for a single inverter. | +| /v1/api/inverterDetailList | Obtain list of details of all inverters under account. | +| /v1/api/inverterDay | Obtain real-time data of a single inverter on the specified day. | +| /v1/api/inverterMonth | Obtain daily data of a single inverter for the specified month. | +| /v1/api/inverterYear | Obtain monthly data of a single inverter for the specified year. | +| /v1/api/inverterAll | Obtain cumulative data of a single inverter for the current year. | +| /v1/api/inverter/shelfTime :new: | Warranty data of a single inverter. | +| /v1/api/alarmList | Obtain device alarm list of all or specific inverter under account. | +| /v1/api/collectorList | Obtain list of all collectors under account or for a specific plant. | +| /v1/api/collectorDetail | Obtain details for a single collector. | +| /v1/api/collector/day :new: | Obtain daily data for a single collector. | +| /v1/api/epmList | Obtain list of all EPM's under account or for a specific plant. | +| /v1/api/epmDetail | Obtain details for a single EPM. | +| /v1/api/epm/day | Obtain real-time data of a single EPM on the specified day. | +| /v1/api/epm/month | Obtain daily data of a single EPM for the specified month. | +| /v1/api/epm/year | Obtain monthly data of a single EPM for the specified year. | +| /v1/api/epm/all | Obtain cumulative data of a single EPM for the current year. | +| /v1/api/weatherList :new: | Obtain list of all meteorological instruments under account or for a specific plant. | +| /v1/api/weatherDetail :new: | Obtain details for a single meteorological instrument. | +| /v1/api/userStationList | Obtain list of all plants under account. | +| /v1/api/stationDetail | Obtain details for a single plant. | +| /v1/api/stationDetailList | Obtain details for a all plants under account. | +| /v1/api/stationDayEnergyList | Obtain real-time data of a single or all plants on the specified day. | +| /v1/api/stationMonthEnergyList | Obtain daily data of a single or all plants for the specified month. | +| /v1/api/stationYearEnergyList | Obtain monthly data of a single or all plants for the specified year. | +| /v1/api/stationDay | Obtain real-time data of a single plant on the specified day. | +| /v1/api/stationMonth | Obtain daily data of a single plant for the specified month. | +| /v1/api/stationYear | Obtain monthly data of a single plant for the specified year. | +| /v1/api/stationAll | Obtain cumulative data of a single plant for the current year. | + +# Currently unsupported API calls +| Call | Description | +|----------------------------------|---------------------------------------------------------------| +| /v1/api/addStation | Add a plant to the account. | +| /v1/api/stationUpdate | Update plant information. | +| /v1/api/addStationBindCollector | Binding a new collector to the plant. | +| /v1/api/delCollector | Unbind a collector from the plant. | +| /v1/api/addDevice | Binding a new inverter to the plant. | # Known issues 1. If the local time deviates more than 15 minutes from SolisCloud server time then the server will respond with HTTP 408. -2. When calls to the API return with error message "数据异常 请联系管理员" (English: abnormal data, please contact administrator), then SolisCloud helpdesk needs to fix your account, raise a ticket via soliscloud.com +2. When calls to the API return with error message "数据异常 请联系管理员" (English: abnormal data, please contact administrator.), then SolisCloud helpdesk needs to fix your account, raise a ticket via soliscloud.com 3. I could not test the use of the NMI parameter for AUS use cases, please create a ticket or pull request if you experience issues diff --git a/doc/SolisCloud API 1.2.pdf b/doc/SolisCloud API 1.2.pdf deleted file mode 100644 index 8a6f2c0..0000000 Binary files a/doc/SolisCloud API 1.2.pdf and /dev/null differ diff --git a/example.py b/example.py index 6ac8025..c620068 100644 --- a/example.py +++ b/example.py @@ -55,6 +55,21 @@ async def main(): # Use helper class as alternative inverter_ids = await Helpers.get_inverter_ids( soliscloud, api_key, api_secret) + + 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 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) + collector_list_json = json.dumps(collector_list, indent=2) + except ( SoliscloudAPI.SolisCloudError, SoliscloudAPI.HttpError, @@ -72,9 +87,15 @@ async def main(): print("InverterList call success:") print(f"{inverter_list_json}") + print("InverterDetails call success:") + print(f"{inverter_detail_json}") + print("Helper call success:") print(f"{inverter_ids}") + print("CollectorList call success:") + print(f"{collector_list_json}") + loop = asyncio.new_event_loop() loop.run_until_complete(main()) loop.close() diff --git a/soliscloud_api/__init__.py b/soliscloud_api/__init__.py index 7f119ea..4fb3349 100644 --- a/soliscloud_api/__init__.py +++ b/soliscloud_api/__init__.py @@ -32,6 +32,7 @@ STATION_DETAIL = RESOURCE_PREFIX + 'stationDetail' COLLECTOR_LIST = RESOURCE_PREFIX + 'collectorList' COLLECTOR_DETAIL = RESOURCE_PREFIX + 'collectorDetail' +COLLECTOR_DAY = RESOURCE_PREFIX + 'collector/day' INVERTER_LIST = RESOURCE_PREFIX + 'inverterList' INVERTER_DETAIL = RESOURCE_PREFIX + 'inverterDetail' STATION_DAY = RESOURCE_PREFIX + 'stationDay' @@ -42,7 +43,8 @@ INVERTER_MONTH = RESOURCE_PREFIX + 'inverterMonth' INVERTER_YEAR = RESOURCE_PREFIX + 'inverterYear' INVERTER_ALL = RESOURCE_PREFIX + 'inverterAll' -ALARM_LIST = RESOURCE_PREFIX + 'inverterAlarmList' +INVERTER_SHELF_TIME = RESOURCE_PREFIX + 'inverter/shelfTime' +ALARM_LIST = RESOURCE_PREFIX + 'alarmList' STATION_DETAIL_LIST = RESOURCE_PREFIX + 'stationDetailList' INVERTER_DETAIL_LIST = RESOURCE_PREFIX + 'inverterDetailList' STATION_DAY_ENERGY_LIST = RESOURCE_PREFIX + 'stationDayEnergyList' @@ -54,14 +56,21 @@ EPM_MONTH = RESOURCE_PREFIX + 'epm/month' EPM_YEAR = RESOURCE_PREFIX + 'epm/year' EPM_ALL = RESOURCE_PREFIX + 'epm/all' +WEATHER_LIST = RESOURCE_PREFIX + 'weatherList' +WEATHER_DETAIL = RESOURCE_PREFIX + 'weatherDetail' + ONLY_INV_ID_OR_SN_ERR = \ "Only pass one of inverter_id or inverter_sn as identifier" +INV_SN_ERR = "Pass inverter_sn as identifier" ONLY_COL_ID_OR_SN_ERR = \ "Only pass one of collector_id or collector_sn as identifier" +COL_SN_ERR = "Pass collector_sn as identifier" ONLY_STN_ID_OR_SN_ERR = \ "Only pass one of station_id or nmi_code as identifier" PAGE_SIZE_ERR = "page_size must be <= 100" +WEATHER_SN_ERR = "Pass instrument_sn as identifier, \ +containing weather instrument serial" class SoliscloudAPI(): @@ -211,6 +220,26 @@ async def collector_detail( raise SoliscloudAPI.SolisCloudError(ONLY_COL_ID_OR_SN_ERR) return await self._get_data(COLLECTOR_DETAIL, key_id, secret, params) + async def collector_day( + self, key_id: str, secret: bytes, /, *, + collector_sn: int = None, + time: str, + time_zone: int, + ) -> dict[str, str]: + """Datalogger day statistics""" + + SoliscloudAPI._verify_date(SoliscloudAPI.DateFormat.DAY, time) + params: dict[str, Any] = { + 'time': time, + 'timeZone': time_zone + } + + if (collector_sn is None): + raise SoliscloudAPI.SolisCloudError(COL_SN_ERR) + params['sn'] = collector_sn + + return await self._get_data(COLLECTOR_DAY, key_id, secret, params) + async def inverter_list( self, key_id: str, secret: bytes, /, *, page_no: int = 1, @@ -420,7 +449,28 @@ async def inverter_all( return await self._get_data(INVERTER_ALL, key_id, secret, params) - async def inverter_alarm_list( + async def inverter_shelf_time( + self, key_id: str, secret: bytes, /, *, + page_no: int = 1, + page_size: int = 20, + inverter_sn: str = None + ) -> dict[str, str]: + """Inverter warranty information""" + + if page_size > 100: + raise SoliscloudAPI.SolisCloudError(PAGE_SIZE_ERR) + if inverter_sn is None: + raise SoliscloudAPI.SolisCloudError(INV_SN_ERR) + + params: dict[str, Any] = { + 'pageNo': page_no, + 'pageSize': page_size, + 'sn': inverter_sn} + + return await self._get_records( + INVERTER_SHELF_TIME, key_id, secret, params) + + async def alarm_list( self, key_id: str, secret: bytes, /, *, page_no: int = 1, page_size: int = 20, @@ -617,6 +667,40 @@ async def epm_all( return await self._get_records(EPM_ALL, key_id, secret, params) + async def weather_list( + self, key_id: str, secret: bytes, /, *, + page_no: int = 1, + page_size: int = 20, + station_id: str = None, + nmi_code: str = None + ) -> dict[str, str]: + """Weather list""" + + if page_size > 100: + raise SoliscloudAPI.SolisCloudError(PAGE_SIZE_ERR) + + params: dict[str, Any] = {'pageNo': page_no, 'pageSize': page_size} + if station_id is not None: + # If not specified all inverters for all stations for key_id are + # returned + params['stationId'] = station_id + if nmi_code is not None: + params['nmiCode'] = nmi_code + return await self._get_records(WEATHER_LIST, key_id, secret, params) + + async def weather_detail( + self, key_id: str, secret: bytes, /, *, + instrument_sn: str = None + ) -> dict[str, str]: + """Inverter details""" + + params: dict[str, Any] = {} + if instrument_sn is None: + raise SoliscloudAPI.SolisCloudError(WEATHER_SN_ERR) + params['sn'] = instrument_sn + + return await self._get_data(WEATHER_DETAIL, key_id, secret, params) + async def _get_records( self, canonicalized_resource: str, key_id: str, secret: bytes, params: dict[str, Any] diff --git a/test/test_exceptions.py b/test/test_exceptions.py index 2ea460a..ef40d2c 100644 --- a/test/test_exceptions.py +++ b/test/test_exceptions.py @@ -18,17 +18,21 @@ def test_soliscloud_error(mocker): def test_api_error(mocker): err = SoliscloudAPI.ApiError() - assert f"{err}" == 'API returned an error: Undefined API error occurred, error code: Unknown, response: None' + assert f"{err}" == 'API returned an error: \ +Undefined API error occurred, error code: Unknown, response: None' err = SoliscloudAPI.ApiError("TEST") - assert f"{err}" == 'API returned an error: TEST, error code: Unknown, response: None' + assert f"{err}" == 'API returned an error: \ +TEST, error code: Unknown, response: None' err = SoliscloudAPI.ApiError("TEST", 3, 1) - assert f"{err}" == 'API returned an error: TEST, error code: 3, response: 1' + assert f"{err}" == 'API returned an error: \ +TEST, error code: 3, response: 1' def test_http_error(mocker): err = SoliscloudAPI.HttpError(408) now = datetime.now().strftime("%d-%m-%Y %H:%M GMT") - assert f"{err}" == f'Your system time is different from server time, your time is {now}' + assert f"{err}" == f'Your system time is different from server time, \ +your time is {now}' err = SoliscloudAPI.HttpError(502) assert f"{err}" == 'Http status code: 502' err = SoliscloudAPI.HttpError(502, "TEST") diff --git a/test/test_private_methods.py b/test/test_private_methods.py index 16066e5..449e123 100644 --- a/test/test_private_methods.py +++ b/test/test_private_methods.py @@ -14,7 +14,12 @@ 'Authorization': 'API 1234567891234567890:8+oYgqSEFjxPaHIOgUKSpIdYCGU=' } -INVALID_RESPONSE_KEYERROR = {'succes': True, 'codes': '0', 'msg': 'success', 'data': {'page': {'records': {'success': 1}}}} +INVALID_RESPONSE_KEYERROR = { + 'succes': True, + 'codes': '0', + 'msg': 'success', + 'data': {'page': {'records': {'success': 1}}} +} class MockedResponse(): @@ -49,27 +54,41 @@ def api_instance(): def test_prepare_header(mocker): # Mock datetime to get deterministic result - mocker.patch('soliscloud_api.SoliscloudAPI._now', return_value=datetime(2023, 1, 1, tzinfo=timezone.utc)) - header = SoliscloudAPI._prepare_header('1234567891234567890', b'DEADBEEFDEADBEEFDEADBEEFDEADBEEF', - {'pageNo': 1, 'pageSize': 100}, 'TEST') + mocker.patch( + 'soliscloud_api.SoliscloudAPI._now', + return_value=datetime(2023, 1, 1, tzinfo=timezone.utc)) + header = SoliscloudAPI._prepare_header( + '1234567891234567890', + b'DEADBEEFDEADBEEFDEADBEEFDEADBEEF', + {'pageNo': 1, 'pageSize': 100}, 'TEST') assert header == VALID_HEADER @pytest.mark.asyncio async def test_post_data_json(api_instance, mocker): - mocker.patch('soliscloud_api.SoliscloudAPI._do_post_aiohttp', return_value=VALID_HTTP_RESPONSE) - result = await api_instance._post_data_json("/TEST", VALID_HEADER, {'test': 'test'}) + mocker.patch( + 'soliscloud_api.SoliscloudAPI._do_post_aiohttp', + return_value=VALID_HTTP_RESPONSE) + result = await api_instance._post_data_json( + "/TEST", + VALID_HEADER, + {'test': 'test'}) assert result == VALID_RESPONSE['data'] @pytest.mark.asyncio async def test_post_data_json_throttled(api_instance, mocker): - mocker.patch('soliscloud_api.SoliscloudAPI._do_post_aiohttp', return_value=VALID_HTTP_RESPONSE) + mocker.patch( + 'soliscloud_api.SoliscloudAPI._do_post_aiohttp', + return_value=VALID_HTTP_RESPONSE) # test max 2 calls per second iterations = 10 start_time = time.time() for i in range(iterations): - result = await api_instance._post_data_json("/TEST", VALID_HEADER, {'test': 'test'}) + result = await api_instance._post_data_json( + "/TEST", + VALID_HEADER, + {'test': 'test'}) duration = time.time() - start_time print(f"Duration: {duration:2f} seconds") assert duration >= (iterations/2)-1 @@ -78,33 +97,69 @@ async def test_post_data_json_throttled(api_instance, mocker): @pytest.mark.asyncio async def test_post_data_json_fail(api_instance, mocker): - mocker.patch('soliscloud_api.SoliscloudAPI._do_post_aiohttp', return_value=HTTP_RESPONSE_KEYERROR) + mocker.patch( + 'soliscloud_api.SoliscloudAPI._do_post_aiohttp', + return_value=HTTP_RESPONSE_KEYERROR) with pytest.raises(SoliscloudAPI.ApiError): - await api_instance._post_data_json("/TEST", VALID_HEADER, {'test': 'test'}) - mocker.patch('soliscloud_api.SoliscloudAPI._do_post_aiohttp', return_value=VALID_HTTP_RESPONSE, - side_effect=asyncio.TimeoutError) + await api_instance._post_data_json( + "/TEST", + VALID_HEADER, + {'test': 'test'}) + mocker.patch( + 'soliscloud_api.SoliscloudAPI._do_post_aiohttp', + return_value=VALID_HTTP_RESPONSE, + side_effect=asyncio.TimeoutError) with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance._post_data_json("/TEST", VALID_HEADER, {'test': 'test'}) - mocker.patch('soliscloud_api.SoliscloudAPI._do_post_aiohttp', return_value=VALID_HTTP_RESPONSE, side_effect=ClientError) + await api_instance._post_data_json( + "/TEST", + VALID_HEADER, + {'test': 'test'}) + mocker.patch( + 'soliscloud_api.SoliscloudAPI._do_post_aiohttp', + return_value=VALID_HTTP_RESPONSE, + side_effect=ClientError) with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance._post_data_json("/TEST", VALID_HEADER, {'test': 'test'}) + await api_instance._post_data_json( + "/TEST", + VALID_HEADER, + {'test': 'test'}) @pytest.mark.asyncio async def test_get_data(api_instance, mocker): - mocker.patch.object(api_instance, '_post_data_json', return_value=VALID_RESPONSE) - mocker.patch('soliscloud_api.SoliscloudAPI._prepare_header', return_value=VALID_HEADER) - result = await api_instance._get_data("/TEST", KEY, SECRET, {'pageNo': 1, 'pageSize': 100}) - api_instance._post_data_json.assert_called_with('https://soliscloud_test.com:13333/TEST', VALID_HEADER, - {'pageNo': 1, 'pageSize': 100}) + mocker.patch.object( + api_instance, + '_post_data_json', + return_value=VALID_RESPONSE) + mocker.patch( + 'soliscloud_api.SoliscloudAPI._prepare_header', + return_value=VALID_HEADER) + result = await api_instance._get_data( + "/TEST", + KEY, SECRET, + {'pageNo': 1, 'pageSize': 100}) + api_instance._post_data_json.assert_called_with( + 'https://soliscloud_test.com:13333/TEST', + VALID_HEADER, + {'pageNo': 1, 'pageSize': 100}) assert result == VALID_RESPONSE @pytest.mark.asyncio async def test_get_records(api_instance, mocker): - mocker.patch.object(api_instance, '_post_data_json', return_value=VALID_RESPONSE['data']) - mocker.patch('soliscloud_api.SoliscloudAPI._prepare_header', return_value=VALID_HEADER) - result = await api_instance._get_records("/TEST", KEY, SECRET, {'pageNo': 1, 'pageSize': 100}) - api_instance._post_data_json.assert_called_with('https://soliscloud_test.com:13333/TEST', VALID_HEADER, - {'pageNo': 1, 'pageSize': 100}) + mocker.patch.object( + api_instance, + '_post_data_json', + return_value=VALID_RESPONSE['data']) + mocker.patch( + 'soliscloud_api.SoliscloudAPI._prepare_header', + return_value=VALID_HEADER) + result = await api_instance._get_records( + "/TEST", + KEY, SECRET, + {'pageNo': 1, 'pageSize': 100}) + api_instance._post_data_json.assert_called_with( + 'https://soliscloud_test.com:13333/TEST', + VALID_HEADER, + {'pageNo': 1, 'pageSize': 100}) assert result == VALID_RESPONSE['data']['page']['records'] diff --git a/test/test_public_methods.py b/test/test_public_methods.py index ac86bce..f07a4c7 100644 --- a/test/test_public_methods.py +++ b/test/test_public_methods.py @@ -1,624 +1,406 @@ import pytest +import soliscloud_api as api -from soliscloud_api import * +# from soliscloud_api import * from .const import KEY, SECRET, NMI, VALID_RESPONSE @pytest.fixture def api_instance(): - instance = SoliscloudAPI('https://soliscloud_test.com:13333', 1) + instance = api.SoliscloudAPI('https://soliscloud_test.com:13333', 1) return instance @pytest.fixture def patched_api(api_instance, mocker): - mocked_class = mocker.create_autospec(SoliscloudAPI) - mocker.patch.object(mocked_class, '_get_records', return_value=VALID_RESPONSE) + mocked_class = mocker.create_autospec(api.SoliscloudAPI) + mocker.patch.object(mocked_class, '_get_records', + return_value=VALID_RESPONSE) mocker.patch.object(mocked_class, '_get_data', return_value=VALID_RESPONSE) - mocker.patch.object(api_instance, '_get_records', mocked_class._get_records) + mocker.patch.object(api_instance, '_get_records', + mocked_class._get_records) mocker.patch.object(api_instance, '_get_data', mocked_class._get_data) return mocked_class -@pytest.mark.asyncio -async def test_user_station_list_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.user_station_list(KEY, SECRET) - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(USER_STATION_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) - assert result == VALID_RESPONSE - - # All arguments filled - result = await api_instance.user_station_list(KEY, SECRET, page_no=4, page_size=100, nmi_code=NMI) - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(USER_STATION_LIST, KEY, SECRET, {'pageNo': 4, 'pageSize': 100, - 'nmiCode': 'nmi_code'}) - - -@pytest.mark.asyncio -async def test_user_station_list_invalid_page_size(api_instance): - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.user_station_list(KEY, SECRET, page_size=101) - - -@pytest.mark.asyncio -async def test_station_detail_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.station_detail(KEY, SECRET, station_id=1000) - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_DETAIL, KEY, SECRET, {'id': 1000}) - - # All arguments filled - result = await api_instance.station_detail(KEY, SECRET, station_id=1000, nmi_code=NMI) - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_DETAIL, KEY, SECRET, {'id': 1000, 'nmiCode': 'nmi_code'}) - - @pytest.mark.asyncio async def test_collector_list_valid(api_instance, patched_api): # Required arguments only result = await api_instance.collector_list(KEY, SECRET) assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(COLLECTOR_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) + patched_api._get_records.assert_called_with( + api.COLLECTOR_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) # All arguments filled - result = await api_instance.collector_list(KEY, SECRET, page_no=4, page_size=100, station_id=1000, nmi_code=NMI) + result = await api_instance.collector_list( + KEY, + SECRET, + page_no=4, page_size=100, station_id=1000, nmi_code=NMI) assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(COLLECTOR_LIST, KEY, SECRET, {'pageNo': 4, 'pageSize': 100, - 'stationId': 1000, 'nmiCode': 'nmi_code'}) + patched_api._get_records.assert_called_with( + api.COLLECTOR_LIST, + KEY, SECRET, + { + 'pageNo': 4, + 'pageSize': 100, + 'stationId': 1000, + 'nmiCode': 'nmi_code' + }) @pytest.mark.asyncio async def test_collector_list_invalid_page_size(api_instance): - with pytest.raises(SoliscloudAPI.SolisCloudError): + with pytest.raises(api.SoliscloudAPI.SolisCloudError): await api_instance.collector_list(KEY, SECRET, page_size=101) @pytest.mark.asyncio async def test_collector_detail_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.collector_detail(KEY, SECRET, collector_sn=1000) + result = await api_instance.collector_detail( + KEY, SECRET, collector_sn=1000) assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(COLLECTOR_DETAIL, KEY, SECRET, {'sn': 1000}) + patched_api._get_data.assert_called_with( + api.COLLECTOR_DETAIL, KEY, SECRET, {'sn': 1000}) - result = await api_instance.collector_detail(KEY, SECRET, collector_id='1000') + result = await api_instance.collector_detail( + KEY, SECRET, collector_id='1000') assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(COLLECTOR_DETAIL, KEY, SECRET, {'id': '1000'}) + patched_api._get_data.assert_called_with( + api.COLLECTOR_DETAIL, KEY, SECRET, {'id': '1000'}) @pytest.mark.asyncio async def test_collector_detail_invalid_params(api_instance): # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.collector_detail(KEY, SECRET, collector_sn=1000, collector_id='1000') - - -@pytest.mark.asyncio -async def test_inverter_list_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.inverter_list(KEY, SECRET) - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(INVERTER_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) - - # All arguments filled - result = await api_instance.inverter_list(KEY, SECRET, page_no=4, page_size=100, station_id=1000, nmi_code=NMI) - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(INVERTER_LIST, KEY, SECRET, {'pageNo': 4, 'pageSize': 100, - 'stationId': 1000, 'nmiCode': 'nmi_code'}) - - -@pytest.mark.asyncio -async def test_inverter_list_invalid_page_size(api_instance): - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_list(KEY, SECRET, page_size=101) - - -@pytest.mark.asyncio -async def test_inverter_detail_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.inverter_detail(KEY, SECRET, inverter_sn=1000) - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_DETAIL, KEY, SECRET, {'sn': 1000}) - - result = await api_instance.inverter_detail(KEY, SECRET, inverter_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_DETAIL, KEY, SECRET, {'id': '1000'}) - - -@pytest.mark.asyncio -async def test_inverter_detail_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_detail(KEY, SECRET, inverter_sn=1000, inverter_id='1000') - - -@pytest.mark.asyncio -async def test_station_day_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.station_day(KEY, SECRET, currency='EUR', time='2023-01-01', time_zone=1, station_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_DAY, KEY, SECRET, {'money': 'EUR', 'time': '2023-01-01', - 'timeZone': 1, 'id': '1000'}) - - result = await api_instance.station_day(KEY, SECRET, currency='EUR', time='2023-01-01', time_zone=1, nmi_code=NMI) - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_DAY, KEY, SECRET, {'money': 'EUR', 'time': '2023-01-01', - 'timeZone': 1, 'nmiCode': NMI}) - - -@pytest.mark.asyncio -async def test_station_day_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day(KEY, SECRET, currency='EUR', time='2023-01-01', time_zone=1) - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day(KEY, SECRET, currency='EUR', time='2023-01-01', time_zone=1, - station_id='1000', nmi_code=NMI) - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day(KEY, SECRET, currency='EUR', time='2023', time_zone=1, station_id='1000') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day(KEY, SECRET, currency='EUR', time='2023+01-01', time_zone=1, station_id='1000') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day(KEY, SECRET, currency='EUR', time='2023-01+01', time_zone=1, station_id='1000') - - -@pytest.mark.asyncio -async def test_station_month_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.station_month(KEY, SECRET, currency='EUR', month='2023-01', station_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_MONTH, KEY, SECRET, {'money': 'EUR', 'month': '2023-01', 'id': '1000'}) - - result = await api_instance.station_month(KEY, SECRET, currency='EUR', month='2023-01', nmi_code=NMI) - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_MONTH, KEY, SECRET, {'money': 'EUR', 'month': '2023-01', 'nmiCode': NMI}) - - -@pytest.mark.asyncio -async def test_station_month_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_month(KEY, SECRET, currency='EUR', month='2023-01') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_month(KEY, SECRET, currency='EUR', month='2023-01', station_id='1000', nmi_code=NMI) - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_month(KEY, SECRET, currency='EUR', month='2023', station_id='1000') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_month(KEY, SECRET, currency='EUR', month='2023+01', station_id='1000') - - -@pytest.mark.asyncio -async def test_station_year_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.station_year(KEY, SECRET, currency='EUR', year='2023', station_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_YEAR, KEY, SECRET, {'money': 'EUR', 'year': '2023', 'id': '1000'}) - - result = await api_instance.station_year(KEY, SECRET, currency='EUR', year='2023', nmi_code=NMI) - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_YEAR, KEY, SECRET, {'money': 'EUR', 'year': '2023', 'nmiCode': NMI}) - - -@pytest.mark.asyncio -async def test_station_year_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_year(KEY, SECRET, currency='EUR', year='2023') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_year(KEY, SECRET, currency='EUR', year='2023', station_id='1000', nmi_code=NMI) - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_year(KEY, SECRET, currency='EUR', year='22023', station_id='1000') - - -@pytest.mark.asyncio -async def test_station_all_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.station_all(KEY, SECRET, currency='EUR', station_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_ALL, KEY, SECRET, {'money': 'EUR', 'id': '1000'}) - - result = await api_instance.station_all(KEY, SECRET, currency='EUR', nmi_code=NMI) - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(STATION_ALL, KEY, SECRET, {'money': 'EUR', 'nmiCode': NMI}) - - -@pytest.mark.asyncio -async def test_station_all_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_all(KEY, SECRET, currency='EUR') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_all(KEY, SECRET, currency='EUR', station_id='1000', nmi_code=NMI) + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.collector_detail( + KEY, SECRET, + collector_sn=1000, collector_id='1000') @pytest.mark.asyncio -async def test_inverter_day_valid(api_instance, patched_api): +async def test_collector_day_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.inverter_day(KEY, SECRET, currency='EUR', time='2023-01-01', time_zone=1, inverter_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_DAY, KEY, SECRET, {'money': 'EUR', 'time': '2023-01-01', - 'timeZone': 1, 'id': '1000'}) - - result = await api_instance.inverter_day(KEY, SECRET, currency='EUR', time='2023-01-01', time_zone=1, inverter_sn='sn') + result = await api_instance.collector_day( + KEY, SECRET, + collector_sn=1000, time='2023-01-01', time_zone=1) assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_DAY, KEY, SECRET, {'money': 'EUR', 'time': '2023-01-01', - 'timeZone': 1, 'sn': 'sn'}) + patched_api._get_data.assert_called_with( + api.COLLECTOR_DAY, + KEY, SECRET, + {'sn': 1000, 'time': '2023-01-01', 'timeZone': 1}) @pytest.mark.asyncio -async def test_inverter_day_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_day(KEY, SECRET, currency='EUR', time='2023-01-01', time_zone=1) - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_day(KEY, SECRET, currency='EUR', time='2023-01-01', time_zone=1, - inverter_id='1000', inverter_sn='sn') +async def test_collector_day_invalid_params(api_instance): + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.collector_day( + KEY, SECRET, + collector_sn=None, time='2023-01-01', time_zone=1) - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_day(KEY, SECRET, currency='EUR', time='2023', time_zone=1, inverter_id='1000') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.collector_day( + KEY, SECRET, + collector_sn='1000', time='2023', time_zone=1) - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_day(KEY, SECRET, currency='EUR', time='2023+01-01', time_zone=1, inverter_id='1000') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.collector_day( + KEY, SECRET, + collector_sn='1000', time='2023+01-01', time_zone=1) - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_day(KEY, SECRET, currency='EUR', time='2023-01+01', time_zone=1, inverter_id='1000') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.collector_day( + KEY, SECRET, + collector_sn='1000', time='2023-01+01', time_zone=1) @pytest.mark.asyncio -async def test_inverter_month_valid(api_instance, patched_api): +async def test_alarm_list_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.inverter_month(KEY, SECRET, currency='EUR', month='2023-01', inverter_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_MONTH, KEY, SECRET, {'money': 'EUR', 'month': '2023-01', 'id': '1000'}) - - result = await api_instance.inverter_month(KEY, SECRET, currency='EUR', month='2023-01', inverter_sn='sn') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_MONTH, KEY, SECRET, {'money': 'EUR', 'month': '2023-01', 'sn': 'sn'}) - - -@pytest.mark.asyncio -async def test_inverter_month_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_month(KEY, SECRET, currency='EUR', month='2023-01') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_month(KEY, SECRET, currency='EUR', month='2023-01', inverter_id='1000', inverter_sn='sn') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_month(KEY, SECRET, currency='EUR', month='2023', inverter_id='1000') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_month(KEY, SECRET, currency='EUR', month='2023+01', inverter_id='1000') - - -@pytest.mark.asyncio -async def test_inverter_year_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.inverter_year(KEY, SECRET, currency='EUR', year='2023', inverter_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_YEAR, KEY, SECRET, {'money': 'EUR', 'year': '2023', 'id': '1000'}) - - result = await api_instance.inverter_year(KEY, SECRET, currency='EUR', year='2023', inverter_sn='sn') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_YEAR, KEY, SECRET, {'money': 'EUR', 'year': '2023', 'sn': 'sn'}) - - -@pytest.mark.asyncio -async def test_inverter_year_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_year(KEY, SECRET, currency='EUR', year='2023') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_year(KEY, SECRET, currency='EUR', year='2023', inverter_id='1000', inverter_sn='sn') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_year(KEY, SECRET, currency='EUR', year='22023', inverter_id='1000') - - -@pytest.mark.asyncio -async def test_inverter_all_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.inverter_all(KEY, SECRET, currency='EUR', inverter_id='1000') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_ALL, KEY, SECRET, {'money': 'EUR', 'id': '1000'}) - - result = await api_instance.inverter_all(KEY, SECRET, currency='EUR', inverter_sn='sn') - assert result == VALID_RESPONSE - patched_api._get_data.assert_called_with(INVERTER_ALL, KEY, SECRET, {'money': 'EUR', 'sn': 'sn'}) - - -@pytest.mark.asyncio -async def test_inverter_all_invalid_params(api_instance): - # ID and SN together - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_all(KEY, SECRET, currency='EUR') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_all(KEY, SECRET, currency='EUR', inverter_id='1000', inverter_sn='sn') - - -@pytest.mark.asyncio -async def test_inverter_alarm_list_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.inverter_alarm_list(KEY, SECRET, station_id='1000', - begintime='2022-01-01', - endtime='2023-01-01') - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(ALARM_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20, 'stationId': '1000', - 'alarmBeginTime': '2022-01-01', - 'alarmEndTime': '2023-01-01'}) - - result = await api_instance.inverter_alarm_list(KEY, SECRET, device_sn='1000', begintime='2022-01-01', - endtime='2023-01-01') - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(ALARM_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20, - 'alarmDeviceSn': '1000', - 'alarmBeginTime': '2022-01-01', - 'alarmEndTime': '2023-01-01'}) - - result = await api_instance.inverter_alarm_list(KEY, SECRET, page_no=4, page_size=30, device_sn='1000', - begintime='2022-01-01', endtime='2023-01-01', nmi_code=NMI) - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(ALARM_LIST, KEY, SECRET, {'pageNo': 4, - 'pageSize': 30, - 'alarmDeviceSn': '1000', - 'alarmBeginTime': '2022-01-01', - 'alarmEndTime': '2023-01-01', - 'nmiCode': NMI}) - - -@pytest.mark.asyncio -async def test_inverter_alarm_list_invalid_params(api_instance): + result = await api_instance.alarm_list( + KEY, SECRET, + station_id='1000', begintime='2022-01-01', endtime='2023-01-01') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.ALARM_LIST, + KEY, SECRET, + { + 'pageNo': 1, + 'pageSize': 20, + 'stationId': '1000', + 'alarmBeginTime': '2022-01-01', + 'alarmEndTime': '2023-01-01'}) + + result = await api_instance.alarm_list( + KEY, SECRET, + device_sn='1000', begintime='2022-01-01', endtime='2023-01-01') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.ALARM_LIST, + KEY, SECRET, + { + 'pageNo': 1, + 'pageSize': 20, + 'alarmDeviceSn': '1000', + 'alarmBeginTime': '2022-01-01', + 'alarmEndTime': '2023-01-01'}) + + result = await api_instance.alarm_list( + KEY, SECRET, + page_no=4, + page_size=30, + device_sn='1000', + begintime='2022-01-01', + endtime='2023-01-01', + nmi_code=NMI) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.ALARM_LIST, + KEY, SECRET, + { + 'pageNo': 4, + 'pageSize': 30, + 'alarmDeviceSn': '1000', + 'alarmBeginTime': '2022-01-01', + 'alarmEndTime': '2023-01-01', + 'nmiCode': NMI}) + + +@pytest.mark.asyncio +async def test_alarm_list_invalid_params(api_instance): # Wrong page size - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, page_size=1000, station_id='1000', - begintime='2022-01-01', endtime='2023-01-01') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + page_size=1000, + station_id='1000', + begintime='2022-01-01', + endtime='2023-01-01') # No Id and no Sn - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, begintime='2022-01-01', endtime='2023-01-01') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + begintime='2022-01-01', endtime='2023-01-01') # Both Id and Sn - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, begintime='2022-01-01', endtime='2023-01-01', - station_id='1000', device_sn='sn') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + begintime='2022-01-01', + endtime='2023-01-01', + station_id='1000', + device_sn='sn') # Illegal begin time - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, begintime='2022', endtime='2023-01-01', station_id='1000') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, begintime='2022+01-01', endtime='2023-01-01', station_id='1000') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, begintime='2022-01+01', endtime='2023-01-01', station_id='1000') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + begintime='2022', + endtime='2023-01-01', + station_id='1000') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + begintime='2022+01-01', endtime='2023-01-01', station_id='1000') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + begintime='2022-01+01', + endtime='2023-01-01', + station_id='1000') # Illegal end time - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, begintime='2022-01-01', endtime='2023', station_id='1000') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + begintime='2022-01-01', endtime='2023', station_id='1000') - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, begintime='2022-01-01', endtime='2023+01-01', station_id='1000') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + begintime='2022-01-01', endtime='2023+01-01', station_id='1000') - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_alarm_list(KEY, SECRET, begintime='2022-01-01', endtime='2023-01+01', station_id='1000') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.alarm_list( + KEY, SECRET, + begintime='2022-01-01', endtime='2023-01+01', station_id='1000') @pytest.mark.asyncio -async def test_station_detail_list_valid(api_instance, patched_api): +async def test_epm_list_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.station_detail_list(KEY, SECRET) + result = await api_instance.epm_list(KEY, SECRET) assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(STATION_DETAIL_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) + patched_api._get_records.assert_called_with( + api.EPM_LIST, + KEY, SECRET, + {'pageNo': 1, 'pageSize': 20}) - result = await api_instance.station_detail_list(KEY, SECRET, page_no=4, page_size=30) + result = await api_instance.epm_list( + KEY, SECRET, + page_no=4, page_size=30, station_id='1000') assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(STATION_DETAIL_LIST, KEY, SECRET, {'pageNo': 4, 'pageSize': 30}) + patched_api._get_records.assert_called_with( + api.EPM_LIST, + KEY, SECRET, + {'pageNo': 4, 'pageSize': 30, 'stationId': '1000'}) @pytest.mark.asyncio -async def test_station_detail_list_invalid_params(api_instance): +async def test_epm_list_invalid_params(api_instance): # Wrong page_size - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_detail_list(KEY, SECRET, page_size=1000) + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.epm_list(KEY, SECRET, page_size=1000) @pytest.mark.asyncio -async def test_inverter_detail_list_valid(api_instance, patched_api): +async def test_epm_detail(api_instance, patched_api): # Required arguments only - result = await api_instance.inverter_detail_list(KEY, SECRET) - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(INVERTER_DETAIL_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) - - result = await api_instance.inverter_detail_list(KEY, SECRET, page_no=4, page_size=30) + result = await api_instance.epm_detail(KEY, SECRET, epm_sn='sn') assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(INVERTER_DETAIL_LIST, KEY, SECRET, {'pageNo': 4, 'pageSize': 30}) - - -@pytest.mark.asyncio -async def test_inverter_detail_list_invalid_params(api_instance): - # Wrong page_size - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.inverter_detail_list(KEY, SECRET, page_size=1000) + patched_api._get_records.assert_called_with( + api.EPM_DETAIL, + KEY, SECRET, + {'sn': 'sn'}) @pytest.mark.asyncio -async def test_station_day_energy_list_valid(api_instance, patched_api): +async def test_epm_day_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.station_day_energy_list(KEY, SECRET, time='2023-01-01') - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(STATION_DAY_ENERGY_LIST, KEY, SECRET, - {'pageNo': 1, 'pageSize': 20, 'time': '2023-01-01'}) - - result = await api_instance.station_day_energy_list(KEY, SECRET, page_no=4, page_size=30, time='2023-01-01') + result = await api_instance.epm_day( + KEY, SECRET, + searchinfo='info', epm_sn='sn', time='2023-01-01', time_zone=1) assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(STATION_DAY_ENERGY_LIST, KEY, SECRET, - {'pageNo': 4, 'pageSize': 30, 'time': '2023-01-01'}) + patched_api._get_records.assert_called_with( + api.EPM_DAY, + KEY, SECRET, + { + 'searchinfo': 'info', + 'sn': 'sn', + 'time': '2023-01-01', + 'timezone': 1 + }) @pytest.mark.asyncio -async def test_station_day_energy_list_invalid_params(api_instance): - # Wrong page_size - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day_energy_list(KEY, SECRET, page_size=1000, time='2023-01-01') +async def test_epm_day_invalid_params(api_instance): # Wrong time format - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day_energy_list(KEY, SECRET, time='2023') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.epm_day( + KEY, SECRET, + searchinfo='info', epm_sn='sn', time='2023', time_zone=1) - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day_energy_list(KEY, SECRET, time='2023+01-01') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.epm_day( + KEY, SECRET, + searchinfo='info', epm_sn='sn', time='2023+01-01', time_zone=1) - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_day_energy_list(KEY, SECRET, time='2023-01+01') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.epm_day( + KEY, SECRET, + searchinfo='info', epm_sn='sn', time='2023-01+01', time_zone=1) @pytest.mark.asyncio -async def test_station_month_energy_list_valid(api_instance, patched_api): +async def test_epm_month_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.station_month_energy_list(KEY, SECRET, month='2023-01') + result = await api_instance.epm_month( + KEY, SECRET, epm_sn='sn', month='2023-01') assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(STATION_MONTH_ENERGY_LIST, KEY, SECRET, - {'pageNo': 1, 'pageSize': 20, 'time': '2023-01'}) - - result = await api_instance.station_month_energy_list(KEY, SECRET, page_no=4, page_size=30, month='2023-01') - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(STATION_MONTH_ENERGY_LIST, KEY, SECRET, - {'pageNo': 4, 'pageSize': 30, 'time': '2023-01'}) + patched_api._get_records.assert_called_with( + api.EPM_MONTH, + KEY, SECRET, + {'sn': 'sn', 'month': '2023-01'}) @pytest.mark.asyncio -async def test_station_month_energy_list_invalid_params(api_instance): - # Wrong page_size - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_month_energy_list(KEY, SECRET, page_size=1000, month='2023-01') - # Wrong month format - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_month_energy_list(KEY, SECRET, month='2023') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_month_energy_list(KEY, SECRET, month='2023+01') - - -@pytest.mark.asyncio -async def test_station_year_energy_list_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.station_year_energy_list(KEY, SECRET, year='2023') - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(STATION_YEAR_ENERGY_LIST, KEY, SECRET, - {'pageNo': 1, 'pageSize': 20, 'time': '2023'}) - - result = await api_instance.station_year_energy_list(KEY, SECRET, page_no=4, page_size=30, year='2023') - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(STATION_YEAR_ENERGY_LIST, KEY, SECRET, - {'pageNo': 4, 'pageSize': 30, 'time': '2023'}) - +async def test_epm_month_invalid_params(api_instance): + # Wrong time format + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.epm_month( + KEY, SECRET, + epm_sn='sn', month='2023') -@pytest.mark.asyncio -async def test_station_year_energy_list_invalid_params(api_instance): - # Wrong page_size - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_year_energy_list(KEY, SECRET, page_size=1000, year='2023') - # Wrong year format - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.station_year_energy_list(KEY, SECRET, year='22023') + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.epm_month( + KEY, SECRET, + epm_sn='sn', month='2023+01') @pytest.mark.asyncio -async def test_epm_list_valid(api_instance, patched_api): +async def test_epm_year_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.epm_list(KEY, SECRET) + result = await api_instance.epm_year( + KEY, SECRET, + epm_sn='sn', year='2023') assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(EPM_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) - - result = await api_instance.epm_list(KEY, SECRET, page_no=4, page_size=30, station_id='1000') - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(EPM_LIST, KEY, SECRET, {'pageNo': 4, 'pageSize': 30, 'stationId': '1000'}) + patched_api._get_records.assert_called_with( + api.EPM_YEAR, + KEY, SECRET, + {'sn': 'sn', 'year': '2023'}) @pytest.mark.asyncio -async def test_epm_list_invalid_params(api_instance): - # Wrong page_size - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.epm_list(KEY, SECRET, page_size=1000) +async def test_epm_year_invalid_params(api_instance): + # Wrong time format + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.epm_year( + KEY, SECRET, + epm_sn='sn', year='22023') @pytest.mark.asyncio -async def test_epm_detail(api_instance, patched_api): +async def test_epm_all_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.epm_detail(KEY, SECRET, epm_sn='sn') + result = await api_instance.epm_all(KEY, SECRET, epm_sn='sn') assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(EPM_DETAIL, KEY, SECRET, {'sn': 'sn'}) + patched_api._get_records.assert_called_with( + api.EPM_ALL, KEY, SECRET, {'sn': 'sn'}) @pytest.mark.asyncio -async def test_epm_day_valid(api_instance, patched_api): +async def test_weather_list_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.epm_day(KEY, SECRET, searchinfo='info', epm_sn='sn', time='2023-01-01', time_zone=1) + result = await api_instance.weather_list(KEY, SECRET) assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(EPM_DAY, KEY, SECRET, - {'searchinfo': 'info', 'sn': 'sn', 'time': '2023-01-01', 'timezone': 1}) - - -@pytest.mark.asyncio -async def test_epm_day_invalid_params(api_instance): - # Wrong time format - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.epm_day(KEY, SECRET, searchinfo='info', epm_sn='sn', time='2023', time_zone=1) + patched_api._get_records.assert_called_with( + api.WEATHER_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.epm_day(KEY, SECRET, searchinfo='info', epm_sn='sn', time='2023+01-01', time_zone=1) - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.epm_day(KEY, SECRET, searchinfo='info', epm_sn='sn', time='2023-01+01', time_zone=1) - - -@pytest.mark.asyncio -async def test_epm_month_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.epm_month(KEY, SECRET, epm_sn='sn', month='2023-01') + # All arguments filled + result = await api_instance.weather_list( + KEY, SECRET, + page_no=4, page_size=100, station_id=1000, nmi_code=NMI) assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(EPM_MONTH, KEY, SECRET, {'sn': 'sn', 'month': '2023-01'}) + patched_api._get_records.assert_called_with( + api.WEATHER_LIST, + KEY, SECRET, + { + 'pageNo': 4, + 'pageSize': 100, + 'stationId': 1000, + 'nmiCode': 'nmi_code'}) @pytest.mark.asyncio -async def test_epm_month_invalid_params(api_instance): - # Wrong time format - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.epm_month(KEY, SECRET, epm_sn='sn', month='2023') - - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.epm_month(KEY, SECRET, epm_sn='sn', month='2023+01') +async def test_weather_list_invalid_page_size(api_instance): + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.weather_list(KEY, SECRET, page_size=101) @pytest.mark.asyncio -async def test_epm_year_valid(api_instance, patched_api): +async def test_weather_detail_valid(api_instance, patched_api): # Required arguments only - result = await api_instance.epm_year(KEY, SECRET, epm_sn='sn', year='2023') + result = await api_instance.weather_detail(KEY, SECRET, instrument_sn='sn') assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(EPM_YEAR, KEY, SECRET, {'sn': 'sn', 'year': '2023'}) + patched_api._get_data.assert_called_with( + api.WEATHER_DETAIL, KEY, SECRET, {'sn': 'sn'}) @pytest.mark.asyncio -async def test_epm_year_invalid_params(api_instance): - # Wrong time format - with pytest.raises(SoliscloudAPI.SolisCloudError): - await api_instance.epm_year(KEY, SECRET, epm_sn='sn', year='22023') - - -@pytest.mark.asyncio -async def test_epm_all_valid(api_instance, patched_api): - # Required arguments only - result = await api_instance.epm_all(KEY, SECRET, epm_sn='sn') - assert result == VALID_RESPONSE - patched_api._get_records.assert_called_with(EPM_ALL, KEY, SECRET, {'sn': 'sn'}) +async def test_weather_detail_invalid_params(api_instance): + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.weather_detail( + KEY, SECRET, + instrument_sn=None) diff --git a/test/test_public_methods_inverter.py b/test/test_public_methods_inverter.py new file mode 100644 index 0000000..b2325b6 --- /dev/null +++ b/test/test_public_methods_inverter.py @@ -0,0 +1,320 @@ +import pytest +import soliscloud_api as api + +# from soliscloud_api import * +from .const import KEY, SECRET, NMI, VALID_RESPONSE + + +@pytest.fixture +def api_instance(): + instance = api.SoliscloudAPI('https://soliscloud_test.com:13333', 1) + + return instance + + +@pytest.fixture +def patched_api(api_instance, mocker): + mocked_class = mocker.create_autospec(api.SoliscloudAPI) + mocker.patch.object(mocked_class, '_get_records', + return_value=VALID_RESPONSE) + mocker.patch.object(mocked_class, '_get_data', return_value=VALID_RESPONSE) + mocker.patch.object(api_instance, '_get_records', + mocked_class._get_records) + mocker.patch.object(api_instance, '_get_data', mocked_class._get_data) + + return mocked_class + + +@pytest.mark.asyncio +async def test_inverter_list_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.inverter_list(KEY, SECRET) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.INVERTER_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) + + # All arguments filled + result = await api_instance.inverter_list( + KEY, SECRET, + page_no=4, page_size=100, station_id=1000, nmi_code=NMI) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.INVERTER_LIST, + KEY, SECRET, + { + 'pageNo': 4, + 'pageSize': 100, + 'stationId': 1000, + 'nmiCode': + 'nmi_code'}) + + +@pytest.mark.asyncio +async def test_inverter_list_invalid_page_size(api_instance): + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_list(KEY, SECRET, page_size=101) + + +@pytest.mark.asyncio +async def test_inverter_detail_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.inverter_detail(KEY, SECRET, inverter_sn=1000) + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_DETAIL, KEY, SECRET, {'sn': 1000}) + + result = await api_instance.inverter_detail( + KEY, SECRET, + inverter_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_DETAIL, KEY, SECRET, {'id': '1000'}) + + +@pytest.mark.asyncio +async def test_inverter_detail_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_detail( + KEY, SECRET, + inverter_sn=1000, inverter_id='1000') + + +@pytest.mark.asyncio +async def test_inverter_day_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.inverter_day( + KEY, SECRET, + currency='EUR', time='2023-01-01', time_zone=1, inverter_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_DAY, + KEY, SECRET, + {'money': 'EUR', 'time': '2023-01-01', 'timeZone': 1, 'id': '1000'}) + + result = await api_instance.inverter_day( + KEY, SECRET, + currency='EUR', time='2023-01-01', time_zone=1, inverter_sn='sn') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_DAY, + KEY, SECRET, + {'money': 'EUR', 'time': '2023-01-01', 'timeZone': 1, 'sn': 'sn'}) + + +@pytest.mark.asyncio +async def test_inverter_day_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_day( + KEY, SECRET, + currency='EUR', time='2023-01-01', time_zone=1) + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_day( + KEY, SECRET, + currency='EUR', + time='2023-01-01', + time_zone=1, + inverter_id='1000', + inverter_sn='sn') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_day( + KEY, SECRET, + currency='EUR', time='2023', time_zone=1, inverter_id='1000') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_day( + KEY, SECRET, + currency='EUR', time='2023+01-01', time_zone=1, inverter_id='1000') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_day( + KEY, SECRET, + currency='EUR', time='2023-01+01', time_zone=1, inverter_id='1000') + + +@pytest.mark.asyncio +async def test_inverter_month_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.inverter_month( + KEY, SECRET, + currency='EUR', month='2023-01', inverter_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_MONTH, + KEY, SECRET, + {'money': 'EUR', 'month': '2023-01', 'id': '1000'}) + + result = await api_instance.inverter_month( + KEY, SECRET, + currency='EUR', month='2023-01', inverter_sn='sn') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_MONTH, + KEY, SECRET, + {'money': 'EUR', 'month': '2023-01', 'sn': 'sn'}) + + +@pytest.mark.asyncio +async def test_inverter_month_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_month( + KEY, SECRET, + currency='EUR', month='2023-01') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_month( + KEY, SECRET, + currency='EUR', + month='2023-01', + inverter_id='1000', + inverter_sn='sn') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_month( + KEY, SECRET, + currency='EUR', month='2023', inverter_id='1000') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_month( + KEY, SECRET, + currency='EUR', month='2023+01', inverter_id='1000') + + +@pytest.mark.asyncio +async def test_inverter_year_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.inverter_year( + KEY, SECRET, + currency='EUR', year='2023', inverter_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_YEAR, + KEY, SECRET, + {'money': 'EUR', 'year': '2023', 'id': '1000'}) + + result = await api_instance.inverter_year( + KEY, SECRET, + currency='EUR', year='2023', inverter_sn='sn') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_YEAR, + KEY, SECRET, + {'money': 'EUR', 'year': '2023', 'sn': 'sn'}) + + +@pytest.mark.asyncio +async def test_inverter_year_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_year( + KEY, SECRET, + currency='EUR', year='2023') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_year( + KEY, SECRET, + currency='EUR', year='2023', inverter_id='1000', inverter_sn='sn') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_year( + KEY, SECRET, + currency='EUR', year='22023', inverter_id='1000') + + +@pytest.mark.asyncio +async def test_inverter_all_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.inverter_all( + KEY, SECRET, + currency='EUR', inverter_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_ALL, + KEY, SECRET, + {'money': 'EUR', 'id': '1000'}) + + result = await api_instance.inverter_all( + KEY, SECRET, + currency='EUR', inverter_sn='sn') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.INVERTER_ALL, + KEY, SECRET, + {'money': 'EUR', 'sn': 'sn'}) + + +@pytest.mark.asyncio +async def test_inverter_all_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_all(KEY, SECRET, currency='EUR') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_all( + KEY, SECRET, + currency='EUR', inverter_id='1000', inverter_sn='sn') + + +@pytest.mark.asyncio +async def test_inverter_detail_list_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.inverter_detail_list(KEY, SECRET) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.INVERTER_DETAIL_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) + + result = await api_instance.inverter_detail_list( + KEY, SECRET, + page_no=4, page_size=30) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.INVERTER_DETAIL_LIST, + KEY, SECRET, + {'pageNo': 4, 'pageSize': 30}) + + +@pytest.mark.asyncio +async def test_inverter_detail_list_invalid_params(api_instance): + # Wrong page_size + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_detail_list(KEY, SECRET, page_size=1000) + + +@pytest.mark.asyncio +async def test_inverter_shelf_time(api_instance, patched_api): + # Required arguments only + result = await api_instance.inverter_shelf_time( + KEY, SECRET, + inverter_sn='sn') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.INVERTER_SHELF_TIME, + KEY, SECRET, + {'pageNo': 1, 'pageSize': 20, 'sn': 'sn'}) + + # Optional arguments + result = await api_instance.inverter_shelf_time( + KEY, SECRET, + page_no=50, page_size=50, inverter_sn='sn') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.INVERTER_SHELF_TIME, + KEY, SECRET, + {'pageNo': 50, 'pageSize': 50, 'sn': 'sn'}) + + +@pytest.mark.asyncio +async def test_inverter_shelf_time_invalid_params(api_instance): + # Wrong page_size + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_shelf_time( + KEY, SECRET, + page_size=1000, inverter_sn='sn') + + # Wrong page_size + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.inverter_shelf_time(KEY, SECRET, inverter_sn=None) diff --git a/test/test_public_methods_station.py b/test/test_public_methods_station.py new file mode 100644 index 0000000..0f443fc --- /dev/null +++ b/test/test_public_methods_station.py @@ -0,0 +1,392 @@ +import pytest +import soliscloud_api as api + +# from soliscloud_api import * +from .const import KEY, SECRET, NMI, VALID_RESPONSE + + +@pytest.fixture +def api_instance(): + instance = api.SoliscloudAPI('https://soliscloud_test.com:13333', 1) + + return instance + + +@pytest.fixture +def patched_api(api_instance, mocker): + mocked_class = mocker.create_autospec(api.SoliscloudAPI) + mocker.patch.object(mocked_class, '_get_records', + return_value=VALID_RESPONSE) + mocker.patch.object(mocked_class, '_get_data', return_value=VALID_RESPONSE) + mocker.patch.object(api_instance, '_get_records', + mocked_class._get_records) + mocker.patch.object(api_instance, '_get_data', mocked_class._get_data) + + return mocked_class + + +@pytest.mark.asyncio +async def test_user_station_list_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.user_station_list(KEY, SECRET) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.USER_STATION_LIST, KEY, SECRET, {'pageNo': 1, 'pageSize': 20}) + assert result == VALID_RESPONSE + + # All arguments filled + result = await api_instance.user_station_list( + KEY, SECRET, + page_no=4, page_size=100, nmi_code=NMI) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.USER_STATION_LIST, + KEY, SECRET, + {'pageNo': 4, 'pageSize': 100, 'nmiCode': 'nmi_code'}) + + +@pytest.mark.asyncio +async def test_user_station_list_invalid_page_size(api_instance): + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.user_station_list(KEY, SECRET, page_size=101) + + +@pytest.mark.asyncio +async def test_station_detail_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_detail(KEY, SECRET, station_id=1000) + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_DETAIL, KEY, SECRET, {'id': 1000}) + + # All arguments filled + result = await api_instance.station_detail( + KEY, SECRET, + station_id=1000, nmi_code=NMI) + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_DETAIL, + KEY, SECRET, + {'id': 1000, 'nmiCode': 'nmi_code'}) + + +@pytest.mark.asyncio +async def test_station_day_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_day( + KEY, SECRET, + currency='EUR', time='2023-01-01', time_zone=1, station_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_DAY, + KEY, SECRET, + {'money': 'EUR', 'time': '2023-01-01', 'timeZone': 1, 'id': '1000'}) + + result = await api_instance.station_day( + KEY, SECRET, + currency='EUR', time='2023-01-01', time_zone=1, nmi_code=NMI) + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_DAY, + KEY, SECRET, + {'money': 'EUR', 'time': '2023-01-01', 'timeZone': 1, 'nmiCode': NMI}) + + +@pytest.mark.asyncio +async def test_station_day_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day( + KEY, SECRET, + currency='EUR', time='2023-01-01', time_zone=1) + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day( + KEY, SECRET, + currency='EUR', + time='2023-01-01', + time_zone=1, + station_id='1000', + nmi_code=NMI) + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day( + KEY, SECRET, + currency='EUR', time='2023', time_zone=1, station_id='1000') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day( + KEY, SECRET, + currency='EUR', time='2023+01-01', time_zone=1, station_id='1000') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day( + KEY, SECRET, + currency='EUR', time='2023-01+01', time_zone=1, station_id='1000') + + +@pytest.mark.asyncio +async def test_station_month_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_month( + KEY, SECRET, + currency='EUR', month='2023-01', station_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_MONTH, + KEY, SECRET, + {'money': 'EUR', 'month': '2023-01', 'id': '1000'}) + + result = await api_instance.station_month( + KEY, SECRET, + currency='EUR', month='2023-01', nmi_code=NMI) + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_MONTH, + KEY, SECRET, + {'money': 'EUR', 'month': '2023-01', 'nmiCode': NMI}) + + +@pytest.mark.asyncio +async def test_station_month_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_month( + KEY, SECRET, + currency='EUR', month='2023-01') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_month( + KEY, SECRET, + currency='EUR', month='2023-01', station_id='1000', nmi_code=NMI) + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_month( + KEY, SECRET, + currency='EUR', month='2023', station_id='1000') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_month( + KEY, SECRET, + currency='EUR', month='2023+01', station_id='1000') + + +@pytest.mark.asyncio +async def test_station_year_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_year( + KEY, SECRET, + currency='EUR', year='2023', station_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_YEAR, + KEY, SECRET, + {'money': 'EUR', 'year': '2023', 'id': '1000'}) + + result = await api_instance.station_year( + KEY, SECRET, + currency='EUR', year='2023', nmi_code=NMI) + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_YEAR, + KEY, SECRET, + {'money': 'EUR', 'year': '2023', 'nmiCode': NMI}) + + +@pytest.mark.asyncio +async def test_station_year_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_year( + KEY, SECRET, + currency='EUR', year='2023') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_year( + KEY, SECRET, + currency='EUR', year='2023', station_id='1000', nmi_code=NMI) + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_year( + KEY, SECRET, + currency='EUR', year='22023', station_id='1000') + + +@pytest.mark.asyncio +async def test_station_all_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_all( + KEY, SECRET, + currency='EUR', station_id='1000') + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_ALL, KEY, SECRET, {'money': 'EUR', 'id': '1000'}) + + result = await api_instance.station_all( + KEY, SECRET, + currency='EUR', nmi_code=NMI) + assert result == VALID_RESPONSE + patched_api._get_data.assert_called_with( + api.STATION_ALL, KEY, SECRET, {'money': 'EUR', 'nmiCode': NMI}) + + +@pytest.mark.asyncio +async def test_station_all_invalid_params(api_instance): + # ID and SN together + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_all(KEY, SECRET, currency='EUR') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_all( + KEY, SECRET, + currency='EUR', station_id='1000', nmi_code=NMI) + + +@pytest.mark.asyncio +async def test_station_detail_list_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_detail_list(KEY, SECRET) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.STATION_DETAIL_LIST, + KEY, SECRET, + {'pageNo': 1, 'pageSize': 20}) + + result = await api_instance.station_detail_list( + KEY, SECRET, + page_no=4, page_size=30) + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.STATION_DETAIL_LIST, + KEY, SECRET, + {'pageNo': 4, 'pageSize': 30}) + + +@pytest.mark.asyncio +async def test_station_detail_list_invalid_params(api_instance): + # Wrong page_size + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_detail_list(KEY, SECRET, page_size=1000) + + +@pytest.mark.asyncio +async def test_station_day_energy_list_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_day_energy_list( + KEY, SECRET, + time='2023-01-01') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.STATION_DAY_ENERGY_LIST, + KEY, SECRET, + {'pageNo': 1, 'pageSize': 20, 'time': '2023-01-01'}) + + result = await api_instance.station_day_energy_list( + KEY, SECRET, + page_no=4, page_size=30, time='2023-01-01') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.STATION_DAY_ENERGY_LIST, + KEY, SECRET, + {'pageNo': 4, 'pageSize': 30, 'time': '2023-01-01'}) + + +@pytest.mark.asyncio +async def test_station_day_energy_list_invalid_params(api_instance): + # Wrong page_size + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day_energy_list( + KEY, SECRET, + page_size=1000, time='2023-01-01') + # Wrong time format + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day_energy_list( + KEY, SECRET, + time='2023') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day_energy_list( + KEY, SECRET, + time='2023+01-01') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_day_energy_list( + KEY, SECRET, + time='2023-01+01') + + +@pytest.mark.asyncio +async def test_station_month_energy_list_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_month_energy_list( + KEY, SECRET, + month='2023-01') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.STATION_MONTH_ENERGY_LIST, + KEY, SECRET, + {'pageNo': 1, 'pageSize': 20, 'time': '2023-01'}) + + result = await api_instance.station_month_energy_list( + KEY, SECRET, + page_no=4, page_size=30, month='2023-01') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.STATION_MONTH_ENERGY_LIST, + KEY, SECRET, + {'pageNo': 4, 'pageSize': 30, 'time': '2023-01'}) + + +@pytest.mark.asyncio +async def test_station_month_energy_list_invalid_params(api_instance): + # Wrong page_size + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_month_energy_list( + KEY, SECRET, + page_size=1000, month='2023-01') + # Wrong month format + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_month_energy_list( + KEY, SECRET, + month='2023') + + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_month_energy_list( + KEY, SECRET, + month='2023+01') + + +@pytest.mark.asyncio +async def test_station_year_energy_list_valid(api_instance, patched_api): + # Required arguments only + result = await api_instance.station_year_energy_list( + KEY, SECRET, + year='2023') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.STATION_YEAR_ENERGY_LIST, + KEY, SECRET, + {'pageNo': 1, 'pageSize': 20, 'time': '2023'}) + + result = await api_instance.station_year_energy_list( + KEY, SECRET, + page_no=4, page_size=30, year='2023') + assert result == VALID_RESPONSE + patched_api._get_records.assert_called_with( + api.STATION_YEAR_ENERGY_LIST, + KEY, SECRET, + {'pageNo': 4, 'pageSize': 30, 'time': '2023'}) + + +@pytest.mark.asyncio +async def test_station_year_energy_list_invalid_params(api_instance): + # Wrong page_size + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_year_energy_list( + KEY, SECRET, + page_size=1000, year='2023') + # Wrong year format + with pytest.raises(api.SoliscloudAPI.SolisCloudError): + await api_instance.station_year_energy_list( + KEY, SECRET, + year='22023')