Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Code examples are valid for both Python versions 2 and 3.

...

Data Delivery Web service (the API for

...

retrieving time series data)

Code Block
languagepythonpy
import requests

if __name__ == '__main__':
    import requests
    import xmltodict  # https://pypi.org/project/xmltodict/
    import pandas as pd

    api_key = 'demo'
    dateFrom = '2024-05-01'
    dateTo = '2024-05-01'
    latitude = 48.61259
    longitude = 20.827079
    tilt = 40
    azimuth = 180

    request_xml = f'''<ws:dataDeliveryRequest dateFrom="2014-04-28{dateFrom}" dateTo="2014-04-28{dateTo}"
    xmlns="http://geomodel.eu/schema/data/request"
    xmlns:ws="http://geomodel.eu/schema/ws/data"
    xmlns:geo="http://geomodel.eu/schema/common/geo"
    xmlns:pv="http://geomodel.eu/schema/common/pv"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <site id="demo_site" name="Demo site" lat="48.61259" lng="20.827079"" lat="{latitude}" lng="{longitude}">
    <pv:geometry xsi:type="pv:GeometryFixedOneAngle" tilt="{tilt}" azimuth="{azimuth}"/>
    <pv:system installedPower="1" installationType="ROOF_MOUNTED">
        <pv:module type="CSI"/>
        <pv:inverter/>
        <pv:losses/>
    </pv:system>
    </site>
    <processing key="GHI DNI DIF GTI TEMP WS WD RH" summarization="HOURLY" terrainShading="true">>
    <timeZone>GMT+02</timeZone>
    <timestampType>START</timestampType>
    </processing>
    </ws:dataDeliveryRequest>'''

   api_key = 'demo'
    url = f'https://solargis.info/ws/rest/datadelivery/request?key=%s' % {api_key}'
    headers = {'Content-Type': 'application/xml'}
    with requests.post(url, data=request_xml.encode('utf8'), headers=headers) as response:
        if not response.ok:
            print(f'Failed API request with code {response.status_code}:\n{response.text}')
        #else:
parse and consume successful response, or inspect error code and a message fromdatadict the server
Info

In real production environment you will automatically modify XML request in run-time (e.g. changing location, period etc.). You can do this by using of XML request templates when only particular data will by replaced (e.g. lat, lng, name, dateFrom). In such case the python native The ElementTree XML API can be helpful for XML manipulation. Creating new XML requests from scratch can be easier by using some "XML data binding" technology. First you generate python objects from Solargis XSD schema documents. Then you can use the python objects for marshaling (serializing python objects into XML text) and unmarshalling (deserializing XML text into python objects) either for the request or response. The PyXB package can be used (http://pyxb.sourceforge.net/).

...

= xmltodict.parse(response.text)  # transform XML document into Python dictionary
            columns = datadict['dataDeliveryResponse']['site']['columns'].split()  # get names of columns (GHI, DNI, etc.)
            rows = datadict['dataDeliveryResponse']['site']['row']  # get rows or records from XML
            rows = rows if isinstance(rows, list) else [rows]
            timestamps = [r['@dateTime'] for r in
                        rows]  # use '@dateTime' for sub/hourly data, '@date' for daily data, '@yearMonth' for monthly data
            data_values = [r['@values'].split() for r in rows]
            # create pandas dataframe from the response data:
            df = pd.DataFrame(data_values, index=pd.to_datetime(timestamps), columns=columns)
            df = df.apply(pd.to_numeric, errors='coerce')  # make numbers from original strings in XML
            print(df)
            print(df.describe())
            # plot the response:
            # import matplotlib.pyplot as plt
            # df.plot()
            # plt.savefig('solargi_api_response.png')

LTA Web service (the API for retrieving long-term average data)

Code Block
languagepythonpy
import requests

if __name__ == '__main__':
    import requests
    import xmltodict  # https://pypi.org/project/xmltodict/

    api_key = 'demo'
    latitude = 48.61259
    longitude = 20.827079
    tilt = 40
    azimuth = 180

    request_xml = f'''<calculateRequest 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:geo="http://geomodel.eu/schema/common/geo"
          xmlns:pv="http://geomodel.eu/schema/common/pv"
          xmlns="http://geomodel.eu/schema/ws/pvplanner">
        <site lat="48.612590{latitude}" lng="20.827079{longitude}">
            <!-- optional terrain data -->
            <geo:terrain elevation="246" azimuth="176" tilt="3.1" />
            <!-- optional custom horizon data can replaceoverride the natural terrain horizon -->
            <!--<geo:horizon>11.11:18.0 7.5:15.53 15.0:10.94 22.5:10.59 30.0:13.06 37.5:14.47 45.0:14.47 52.5:13.76 60.0:12.35 67.5:11.29 75.0:8.12 82.5:4.59 90.0:1.41 97.5:0.35 105.0:0.35 112.5:0.35 120.0:0.35 127.5:0.35 135.0:0.0 142.5:0.0 150.0:0.35 157.5:1.41 165.0:2.47 172.5:2.47 180.0:2.82 187.5:3.18 195.0:2.82 202.5:2.47 210.0:2.47 217.5:2.47 225.0:3.18 232.5:3.18 240.0:2.47 247.5:2.12 255.0:2.12 262.5:2.82 270.0:3.88 277.5:6.71 285.0:8.47 292.5:10.24 300.0:11.29 307.5:12.71 315.0:14.12 322.5:15.53 330.0:16.24 337.5:16.94 345.0:17.29 352.5:17.29</geo:horizon>-->
            <pv:geometry xsi:type="pv:GeometryFixedOneAngle" azimuth="175{azimuth}" tilt="45{tilt}"/>
            <pv:system installedPower="1" installationType="ROOF_MOUNTED" availability="99">
                <pv:module type="CSI">
                </pv:module>
                <pv:inverter>
                    <pv:efficiency xsi:type="pv:EfficiencyConstant" percent="97.5"/>
                </pv:inverter>
                <pv:losses dc="5.5" ac="1.5"/>
            </pv:system>
        </site>
    </calculateRequest>'''
  
 api_key = 'demo'
    url = f'https://solargis.info/ws/rest/pvplanner/calculate?key=%s' % {api_key}'
    headers = {'Content-Type': 'application/xml'}
    with requests.post(url, data=request_xml.encode('utf8'), headers=headers) as response:
        if not response.ok:
            print(f'Failed API request with code {response.status_code}:\n{response.text}')
        else:
      # parse and consume successful response, or inspect error code and a message from the server      datadict = xmltodict.parse(response.text)  # transform XML document into Python dictionary
            response_dict = datadict['ns3:calculateResponse']
            # explore solar and climate data in the response:
            climate_data = response_dict['ns3:irradiation']  
            climate_data_reference = climate_data['ns3:reference'] # general climate data
            solar_data_inplane = climate_data['ns3:inplane'] # POA irradiance components
            geometry_comparison = climate_data['ns3:comparison']  # comparison of the various geometry options with selected one
            optimum_angle = climate_data.get('ns3:optimum')  # optimum fixed angle for the selected location
            # get PV calculation data:
            pv_data = response_dict['ns3:calculation']
            pv_data_output = pv_data['ns3:output']  # PV system output total and specific
            pv_data_losses = pv_data['ns3:losses']  # PV system losses breakdown
            print('Climate data reference:', climate_data_reference)
            print('Solar data in-plane:', solar_data_inplane)
            print('Geometry comparison:', geometry_comparison)
            print('Optimum angle:', optimum_angle)
            print('PV data output:', pv_data_output)
            print('PV data losses:', pv_data_losses)