Пример #1
0
def add_asset_to_asset_list(asset_list, asset):
    port_list = []
    ports = asset.port
    for p in ports:
        conn_to_ids = [cp.id for cp in p.connectedTo]
        profile = p.profile
        profile_info_list = []
        p_carr_id = None
        if p.carrier:
            p_carr_id = p.carrier.id
        if profile:
            profile_info_list = []  # generate_profile_info(profile)
        port_list.append({
            'name': p.name,
            'id': p.id,
            'type': type(p).__name__,
            'conn_to': conn_to_ids,
            'profile': profile_info_list,
            'carrier': p_carr_id
        })

    state = asset_state_to_ui(asset)
    geom = asset.geometry
    if geom:
        if isinstance(geom, esdl.Point):
            lat = geom.lat
            lon = geom.lon

            capability_type = ESDLAsset.get_asset_capability_type(asset)
            attrs = get_tooltip_asset_attrs(asset, 'marker')
            add_spatial_attributes(asset, attrs)
            asset_list.append([
                'point', 'asset', asset.name, asset.id,
                type(asset).__name__, [lat, lon], attrs, state, port_list,
                capability_type
            ])
        if isinstance(geom, esdl.Line):
            coords = []
            for point in geom.point:
                coords.append([point.lat, point.lon])
            attrs = get_tooltip_asset_attrs(asset, 'line')
            add_spatial_attributes(asset, attrs)
            asset_list.append([
                'line', 'asset', asset.name, asset.id,
                type(asset).__name__, coords, attrs, state, port_list
            ])
        if isinstance(geom, esdl.Polygon):
            coords = ESDLGeometry.parse_esdl_subpolygon(geom.exterior,
                                                        False)  # [lon, lat]
            coords = ESDLGeometry.exchange_coordinates(
                coords)  # --> [lat, lon]
            capability_type = ESDLAsset.get_asset_capability_type(asset)
            attrs = get_tooltip_asset_attrs(asset, 'polygon')
            add_spatial_attributes(asset, attrs)
            asset_list.append([
                'polygon', 'asset', asset.name, asset.id,
                type(asset).__name__, coords, attrs, state, port_list,
                capability_type
            ])
Пример #2
0
    def add_asset_and_emit(self, esh: EnergySystemHandler, es_id: str, asset: EnergyAsset, area_bld_id: str):
        with self.flask_app.app_context():
            asset_to_be_added_list = list()
            port_list = self.calculate_port_list(asset)
            message = self.create_asset_discription_message(asset, port_list)
            asset_to_be_added_list.append(message)

            if not ESDLAsset.add_object_to_area(esh.get_energy_system(es_id), asset, area_bld_id):
                ESDLAsset.add_object_to_building(esh.get_energy_system(es_id), asset, area_bld_id)

            emit('add_esdl_objects', {'es_id': es_id, 'asset_pot_list': asset_to_be_added_list, 'zoom': False}, namespace='/esdl')
Пример #3
0
def energy_asset_to_ui(esh, es_id, asset): # , port_asset_mapping):
    port_list = []
    conn_list = []

    ports = asset.port
    for p in ports:
        # p_asset = port_asset_mapping[p.id]
        p_asset = get_asset_and_coord_from_port_id(esh, es_id, p.id)
        p_asset_coord = p_asset['coord']        # get proper coordinate if asset is line
        conn_to = [cp.id for cp in p.connectedTo]
        profile = p.profile
        profile_info_list = []
        if profile:
            profile_info_list = generate_profile_info(profile)
        port_list.append \
            ({'name': p.name, 'id': p.id, 'type': type(p).__name__, 'conn_to': conn_to, 'profile': profile_info_list})
        if conn_to:
            # conn_to_list = conn_to.split(' ')   # connectedTo attribute is list of port ID's separated by a space
            for id in conn_to:
                # pc_asset = port_asset_mapping[id]
                pc_asset = get_asset_and_coord_from_port_id(esh, es_id, id)
                pc_asset_coord = pc_asset['coord']

                conn_list.append \
                    ({'from-port-id': p.id, 'from-asset-id': p_asset['asset'].id, 'from-asset-coord': p_asset_coord,
                                  'to-port-id': id, 'to-asset-id': pc_asset['asset'].id, 'to-asset-coord': pc_asset_coord})

    geom = asset.geometry
    if geom:
        if isinstance(geom, esdl.Point):
            lat = geom.lat
            lon = geom.lon

            capability_type = ESDLAsset.get_asset_capability_type(asset)
            return ['point', 'asset', asset.name, asset.id, type(asset).__name__, [lat, lon], port_list, capability_type], conn_list
        elif isinstance(geom, esdl.Line):
            coords = []
            for point in geom.point:
                coords.append([point.lat, point.lon])
            return ['line', 'asset', asset.name, asset.id, type(asset).__name__, coords, port_list], conn_list
        elif isinstance(geom, esdl.Polygon):
            if isinstance(asset, esdl.WindParc) or isinstance(asset, esdl.PVParc) or isinstance(asset, esdl.WindPark) \
                    or isinstance(asset, esdl.PVPark):
                coords = ESDLGeometry.parse_esdl_subpolygon(geom.exterior, False)   # [lon, lat]
                coords = ESDLGeometry.exchange_coordinates(coords)                  # --> [lat, lon]
                capability_type = ESDLAsset.get_asset_capability_type(asset)
                # print(coords)
                return ['polygon', 'asset', asset.name, asset.id, type(asset).__name__, coords, port_list, capability_type], conn_list
        else:
            return [], []
Пример #4
0
    def get_edr_vesta_measures(self, measures_id):
        url = self.vesta_plugin_settings[
            "edr_url"] + "/store/esdl/" + measures_id + "?format=xml"

        try:
            r = requests.get(url)
            if r.status_code == 200:
                result = []
                self.selected_measures = ESDLAsset.load_asset_from_string(
                    r.text)
                for m in self.selected_measures.measure:
                    result.append({"id": m.id, "name": m.name})
                return result
            else:
                print(
                    'EDR returned unexpected result. Check Vesta plugin settings'
                )
                send_alert(
                    'EDR returned unexpected result. Check Vesta plugin settings'
                )
                return None

        except Exception as e:
            print('Error accessing EDR API: ' + str(e))
            send_alert('Error accessing EDR API: ' + str(e))
            return None
Пример #5
0
        def get_bag_contours(info):
            with self.flask_app.app_context():
                print("getting bag information")
                esh = get_handler()
                active_es_id = get_session('active_es_id')

                area_id = info["id"]
                area_polygon = { 'type': 'polygon', 'coordinates': info["polygon"] }
                geometry = ESDLGeometry.create_ESDL_geometry(area_polygon)
                boundary_wgs = ESDLGeometry.create_boundary_from_geometry(geometry)
                # boundary_geojson = ESDLGeometry.create_geojson(area_id, '', [], boundary_wgs)
                wkt_string = wkt.dumps(boundary_wgs)
                # wkt_string = 'POLYGON ((4.359093904495239 52.012174264626445, 4.357388019561768 52.01154692445308, 4.357978105545044 52.01078750089633, 4.360188245773315 52.01160635705717, 4.362355470657349 52.012478026181434, 4.360767602920532 52.012847820073766, 4.359093904495239 52.012174264626445))'
                # wkt_quoted = urllib.parse.quote(wkt_string)

                es_edit = esh.get_energy_system(es_id=active_es_id)
                instance = es_edit.instance
                top_area = instance[0].area
                target_area = ESDLEnergySystem.find_area(top_area, area_id)
                if target_area:
                    try:
                        # url = 'http://' + settings.bag_config["host"] + ':' + settings.bag_config["port"] + \
                        #        settings.bag_config["path_contour"] + '?wkt=' + wkt_quoted + '&format=xml'
                        # print(url)
                        # r = requests.get(url)
                        url = 'http://' + settings.bag_config["host"] + ':' + settings.bag_config["port"] + \
                               settings.bag_config["path_contour"] + '?format=xml'
                        print(url)
                        r = requests.post(url, json={"wkt": wkt_string})
                        if r.status_code == 201:
                            esdl_string = r.text
                            bag_es = ESDLAsset.load_asset_from_string(esdl_string)
                            if bag_es:
                                bag_inst = bag_es.instance[0]
                                if bag_inst:
                                    bag_area = bag_inst.area
                                    if bag_area:
                                        bld_list = []
                                        for bld in bag_area.asset:
                                            if isinstance(bld, esdl.Building):
                                                target_area.asset.append(bld.deepcopy())
                                                geometry = bld.geometry
                                                boundary_wgs = ESDLGeometry.create_boundary_from_geometry(geometry)
                                                bld_list.append(ESDLGeometry.create_geojson(bld.id, bld.name, [], boundary_wgs))

                                        if bld_list:
                                            emit('geojson', {"layer": "bld_layer", "geojson": bld_list})

                    except Exception as e:
                        print('ERROR in accessing BAG service: '+str(e))
                        return None

                    # @EWOUD: Deze 'mogelijkheid' kunnen we ook gebruiken om geometries te renderen in de frontend
                    # self.emit_geometries_to_client(esh, active_es_id, bld_list)
                else:
                    print("ERROR in finding area in ESDL for BAG service")
                    # self.flask_app.send_alert("ERROR in finding area in ESDL for BAG service")
                    return None
Пример #6
0
 def create_asset_discription_message(asset: EnergyAsset, port_list):
     if isinstance(asset, AbstractConductor):
         # assume a Line geometry here
         coords = [(p.lat, p.lon) for p in asset.geometry.point]
         return ['line', 'asset', asset.name, asset.id, type(asset).__name__, coords, port_list]
     else:
         capability_type = ESDLAsset.get_asset_capability_type(asset)
         return ['point', 'asset', asset.name, asset.id, type(asset).__name__, asset.geometry.lat,
              asset.geometry.lon, port_list, capability_type]
    def convert_potential(esh, active_es_id, pot, add_to_building, percentage, asset_list):
        pot_container = pot.eContainer()

        # Determine orientation from potential information
        orientation_name = ""
        if pot.orientation in PICO_ROOF_ORIENTATIONS:
            orientation_name = " (" + PICO_ROOF_ORIENTATIONS[pot.orientation] + ")"

        # Create a PVInstallation instance and attach a profile with the percentage of the potential that
        # will be 'installed'
        pv_installation = esdl.PVInstallation(id=str(uuid.uuid4()), name="PV Installation" + orientation_name)
        pv_outport = esdl.OutPort(id=str(uuid.uuid4()), name="Out")
        pv_profile = esdl.SingleValue(id=str(uuid.uuid4()), name="PV production", value=pot.value * percentage / 100)
        # Assume kWh for now, Geodan should communicate this in the ESDL in the end
        pv_profile.profileQuantityAndUnit = esdl.QuantityAndUnitType(
            physicalQuantity=esdl.PhysicalQuantityEnum.ENERGY,
            unit=esdl.UnitEnum.WATTHOUR,
            multiplier=esdl.MultiplierEnum.KILO)
        pv_outport.profile.append(pv_profile)
        pv_installation.port.append(pv_outport)

        # Generate a location on the map for the PV Installation
        if isinstance(pot_container, esdl.AbstractBuilding):
            # Place the Asset in the top left corner of the BuildingEditor
            pv_geometry = esdl.Point(lon=10.0, lat=490.0, CRS="Simple")
            pv_installation.geometry = pv_geometry
            add_to_building[0] = True
        else:
            pot_geometry = pot.geometry
            if isinstance(pot_geometry, esdl.Point):
                # Place the Asset with a small offset from the SolarPotential marker
                pv_geometry = esdl.Point(lon=pot_geometry.lon + 0.001, lat=pot_geometry.lat - 0.001)
                pv_installation.geometry = pv_geometry
            else:
                logger.warning('Using potentials with geometry other than esdl.Point not supported yet')

        # Add the PVInstallation to the same container as the SolarPotential (Area or Building)
        pot_container.asset.append(pv_installation)
        esh.add_object_to_dict(active_es_id, pv_installation, recursive=True)
        if isinstance(pot_container, esdl.AbstractBuilding):
            calc_building_assets_location(pot_container, True)

        # Adapt the potential (substract the installed value)
        pot.value = pot.value * (100-percentage) / 100

        port_list = [{'name': pv_outport.name, 'id': pv_outport.id, 'type': type(pv_outport).__name__, 'conn_to': []}]
        capability_type = ESDLAsset.get_asset_capability_type(pv_installation)
        tooltip_asset_attrs = get_tooltip_asset_attrs(pv_installation, 'marker')
        asset_list.append(['point', 'asset', pv_installation.name, pv_installation.id,
                           type(pv_installation).__name__, [pv_geometry.lat, pv_geometry.lon],
                           tooltip_asset_attrs, 'e', port_list, capability_type])
        return pv_installation
Пример #8
0
 def create_asset_description_message(asset: EnergyAsset, port_list):
     state = asset_state_to_ui(asset)
     if isinstance(asset, AbstractConductor):
         # assume a Line geometry here
         coords = [(p.lat, p.lon) for p in asset.geometry.point]
         tooltip_asset_attrs = get_tooltip_asset_attrs(asset, 'line')
         add_spatial_attributes(asset, tooltip_asset_attrs)
         return [
             'line', 'asset', asset.name, asset.id,
             type(asset).__name__, coords, tooltip_asset_attrs, state,
             port_list
         ]
     else:
         capability_type = ESDLAsset.get_asset_capability_type(asset)
         tooltip_asset_attrs = get_tooltip_asset_attrs(asset, 'marker')
         add_spatial_attributes(asset, tooltip_asset_attrs)
         return [
             'point', 'asset', asset.name, asset.id,
             type(asset).__name__, [asset.geometry.lat, asset.geometry.lon],
             tooltip_asset_attrs, state, port_list, capability_type
         ]
        def use_part_of_potential(pot_id, percentage):
            """
            Use part of a SolarPotential to install a PVInstallation

            :param pot_id: id of the SolarPotential
            :param percentage: percentage (0-100) of the SolarPotential that should be installed as a PVInstallation
            :return: None
            """
            with self.flask_app.app_context():
                esh = get_handler()
                active_es_id = get_session('active_es_id')

                pot = esh.get_by_id(active_es_id, pot_id)
                pot_container = pot.eContainer()

                # Create a PVInstallation instance and attach a profile with the percentage of the potential that
                # will be 'installed'
                pv_installation = esdl.PVInstallation(id=str(uuid.uuid4()),
                                                      name="PV Installation")
                pv_outport = esdl.OutPort(id=str(uuid.uuid4()), name="Out")
                pv_profile = esdl.SingleValue(id=str(uuid.uuid4()),
                                              name="PV production",
                                              value=pot.value * percentage /
                                              100)
                # Assume kWh for now, Geodan should communicate this in the ESDL in the end
                pv_profile.profileQuantityAndUnit = esdl.QuantityAndUnitType(
                    physicalQuantity=esdl.PhysicalQuantityEnum.ENERGY,
                    unit=esdl.UnitEnum.WATTHOUR,
                    multiplier=esdl.MultiplierEnum.KILO)
                pv_outport.profile.append(pv_profile)
                pv_installation.port.append(pv_outport)

                add_to_building = False
                # Generate a location on the map for the PV Installation
                if isinstance(pot_container, esdl.AbstractBuilding):
                    # Place the Asset in the top left corner of the BuildingEditor
                    pv_geometry = esdl.Point(lon=10, lat=490, CRS="Simple")
                    pv_installation.geometry = pv_geometry
                    add_to_building = True
                else:
                    pot_geometry = pot.geometry
                    if isinstance(pot_geometry, esdl.Point):
                        # Place the Asset with a small offset from the SolarPotential marker
                        pv_geometry = esdl.Point(lon=pot_geometry.lon + 0.001,
                                                 lat=pot_geometry.lat - 0.001)
                        pv_installation.geometry = pv_geometry
                    else:
                        logger.warning(
                            'Using potentials with geometry other than esdl.Point not supported yet'
                        )

                # Add the PVInstallation to the same container as the SolarPotential (Area or Building)
                pot_container.asset.append(pv_installation)
                esh.add_object_to_dict(active_es_id,
                                       pv_installation,
                                       recursive=True)

                # Adapt the potential (substract the installed value)
                pot.value = pot.value * (100 - percentage) / 100

                # Emit the information to the front-end
                asset_list = []
                port_list = [{
                    'name': pv_outport.name,
                    'id': pv_outport.id,
                    'type': type(pv_outport).__name__,
                    'conn_to': []
                }]
                capability_type = ESDLAsset.get_asset_capability_type(
                    pv_installation)
                asset_list.append([
                    'point', 'asset', pv_installation.name, pv_installation.id,
                    type(pv_installation).__name__,
                    [pv_geometry.lat, pv_geometry.lon], port_list,
                    capability_type
                ])
                emit(
                    'add_esdl_objects', {
                        'es_id': active_es_id,
                        'add_to_building': add_to_building,
                        'asset_pot_list': asset_list,
                        'zoom': False
                    })
Пример #10
0
def process_area(esh, es_id, asset_list, building_list, area_bld_list, conn_list, area, level):
    area_bld_list.append(['Area', area.id, area.name, level])

    # process subareas
    for ar in area.area:
        process_area(esh, es_id, asset_list, building_list, area_bld_list, conn_list, ar, level+1)

    # process assets in area
    for asset in area.asset:
        if isinstance(asset, esdl.AbstractBuilding):
            process_building(esh, es_id, asset_list, building_list, area_bld_list, conn_list, asset, False, level+1)
        if isinstance(asset, esdl.EnergyAsset):
            port_list = []
            ports = asset.port
            for p in ports:
                p_asset = get_asset_and_coord_from_port_id(esh, es_id, p.id)
                p_asset_coord = p_asset['coord']        # get proper coordinate if asset is line
                conn_to_ids = [cp.id for cp in p.connectedTo]
                profile = p.profile
                profile_info_list = []
                p_carr_id = None
                if p.carrier:
                    p_carr_id = p.carrier.id
                if profile:
                    profile_info_list = generate_profile_info(profile)
                port_list.append({'name': p.name, 'id': p.id, 'type': type(p).__name__, 'conn_to': conn_to_ids, 'profile': profile_info_list, 'carrier': p_carr_id})
                if conn_to_ids:
                    for pc in p.connectedTo:
                        pc_asset = get_asset_and_coord_from_port_id(esh, es_id, pc.id)
                        if pc_asset['asset'].containingBuilding:
                            bld_pc_asset = pc_asset['asset'].containingBuilding
                            if bld_pc_asset.geometry:
                                if isinstance(bld_pc_asset.geometry, esdl.Point):
                                    pc_asset_coord = (bld_pc_asset.geometry.lat, bld_pc_asset.geometry.lon)
                                elif isinstance(bld_pc_asset.geometry, esdl.Polygon):
                                    pc_asset_coord = ESDLGeometry.calculate_polygon_center(bld_pc_asset.geometry)
                        else:
                            pc_asset_coord = pc_asset['coord']

                        pc_carr_id = None
                        if pc.carrier:
                            pc_carr_id = pc.carrier.id
                        conn_list.append({'from-port-id': p.id, 'from-port-carrier': p_carr_id, 'from-asset-id': p_asset['asset'].id, 'from-asset-coord': p_asset_coord,
                                          'to-port-id': pc.id, 'to-port-carrier': pc_carr_id, 'to-asset-id': pc_asset['asset'].id, 'to-asset-coord': pc_asset_coord})

            geom = asset.geometry
            if geom:
                if isinstance(geom, esdl.Point):
                    lat = geom.lat
                    lon = geom.lon

                    capability_type = ESDLAsset.get_asset_capability_type(asset)
                    asset_list.append(['point', 'asset', asset.name, asset.id, type(asset).__name__, [lat, lon], port_list, capability_type])
                if isinstance(geom, esdl.Line):
                    coords = []
                    for point in geom.point:
                        coords.append([point.lat, point.lon])
                    asset_list.append(['line', 'asset', asset.name, asset.id, type(asset).__name__, coords, port_list])
                if isinstance(geom, esdl.Polygon):
                    # if isinstance(asset, esdl.WindParc) or isinstance(asset, esdl.PVParc) or isinstance(asset, esdl.WindPark) or isinstance(asset, esdl.PVPark):
                    coords = ESDLGeometry.parse_esdl_subpolygon(geom.exterior, False)   # [lon, lat]
                    coords = ESDLGeometry.exchange_coordinates(coords)                  # --> [lat, lon]
                    capability_type = ESDLAsset.get_asset_capability_type(asset)
                    # print(coords)
                    asset_list.append(['polygon', 'asset', asset.name, asset.id, type(asset).__name__, coords, port_list, capability_type])

    for potential in area.potential:
        geom = potential.geometry
        if geom:
            if isinstance(geom, esdl.Point):
                lat = geom.lat
                lon = geom.lon

                asset_list.append(
                    ['point', 'potential', potential.name, potential.id, type(potential).__name__, [lat, lon]])
            if isinstance(geom, esdl.Polygon):
                coords = []

                for point in geom.exterior.point:
                    coords.append([point.lat, point.lon])
                asset_list.append(['polygon', 'potential', potential.name, potential.id, type(potential).__name__, coords])
Пример #11
0
def process_building(esh, es_id, asset_list, building_list, area_bld_list, conn_list, building, bld_editor, level):
    # Add building to list that is shown in a dropdown at the top
    area_bld_list.append(['Building', building.id, building.name, level])

    # Determine if building has assets
    building_has_assets = False
    if building.asset:
        for basset in building.asset:
            if isinstance(basset, esdl.EnergyAsset):
                building_has_assets = True
                break

    # Generate information for drawing building (as a point or a polygon)
    if isinstance(building, esdl.Building) or isinstance(building, esdl.AggregatedBuilding):
        geometry = building.geometry
        bld_KPIs = create_building_KPIs(building)
        if geometry:
            if isinstance(geometry, esdl.Point):
                building_list.append(
                    ['point', building.name, building.id, type(building).__name__, [geometry.lat, geometry.lon], building_has_assets, bld_KPIs])
                bld_coord = (geometry.lat, geometry.lon)
            elif isinstance(geometry, esdl.Polygon):
                coords = ESDLGeometry.parse_esdl_subpolygon(building.geometry.exterior, False)  # [lon, lat]
                coords = ESDLGeometry.exchange_coordinates(coords)  # --> [lat, lon]
                # building_list.append(['polygon', building.name, building.id, type(building).__name__, coords, building_has_assets])
                boundary = ESDLGeometry.create_boundary_from_geometry(geometry)
                building_list.append(['polygon', building.name, building.id, type(building).__name__, boundary['coordinates'], building_has_assets, bld_KPIs])
                # bld_coord = coords
                bld_coord = ESDLGeometry.calculate_polygon_center(geometry)
    elif building.containingBuilding:       # BuildingUnit
        bld_geom = building.containingBuilding.geometry
        if bld_geom:
            if isinstance(bld_geom, esdl.Point):
                bld_coord = (bld_geom.lat, bld_geom.lon)
            elif isinstance(bld_geom, esdl.Polygon):
                bld_coord = ESDLGeometry.calculate_polygon_center(bld_geom)

    # Iterate over all assets in building to gather all required information
    for basset in building.asset:
        if isinstance(basset, esdl.AbstractBuilding):
            process_building(esh, es_id, asset_list, building_list, area_bld_list, conn_list, basset, bld_editor, level + 1)
        else:
            # Create a list of ports for this asset
            port_list = []
            ports = basset.port
            for p in ports:
                conn_to = p.connectedTo
                conn_to_id_list = [ct.id for ct in conn_to]
                # TODO: add profile_info and carrier
                port_list.append({'name': p.name, 'id': p.id, 'type': type(p).__name__, 'conn_to': conn_to_id_list})

            geom = basset.geometry
            coord = ()
            if geom:    # Individual asset in Building has its own geometry information
                if isinstance(geom, esdl.Point):
                    lat = geom.lat
                    lon = geom.lon
                    coord = (lat, lon)

                    capability_type = ESDLAsset.get_asset_capability_type(basset)
                    if bld_editor:
                        asset_list.append(['point', 'asset', basset.name, basset.id, type(basset).__name__, [lat, lon], port_list, capability_type])
                else:
                    send_alert("Assets within buildings with geometry other than esdl.Point are not supported")

            # Inherit geometry from containing building
            # if level > 0:
            #     coord = bld_coord

            ports = basset.port
            for p in ports:
                p_carr_id = None
                if p.carrier:
                    p_carr_id = p.carrier.id
                conn_to = p.connectedTo
                if conn_to:
                    for pc in conn_to:
                        in_different_buildings = False
                        pc_asset = get_asset_and_coord_from_port_id(esh, es_id, pc.id)

                        # If the asset the current asset connects to, is in a building...
                        if pc_asset['asset'].containingBuilding:
                            bld_pc_asset = pc_asset['asset'].containingBuilding
                            bld_basset = basset.containingBuilding
                            # If the asset is in a different building ...
                            if not bld_pc_asset == bld_basset:
                                in_different_buildings = True
                                if bld_pc_asset.geometry:
                                    if bld_editor:
                                        # ... connect to the left border
                                        pc_asset_coord = (coord[0], 0)
                                    else:
                                        # ... use the building coordinate instead of the asset coordinate
                                        if isinstance(bld_pc_asset.geometry, esdl.Point):
                                            pc_asset_coord = (bld_pc_asset.geometry.lat, bld_pc_asset.geometry.lon)
                                        elif isinstance(bld_pc_asset.geometry, esdl.Polygon):
                                            pc_asset_coord = ESDLGeometry.calculate_polygon_center(bld_pc_asset.geometry)

                                    # If connecting to a building outside of the current, replace current asset
                                    # coordinates with building coordinates too
                                    if not bld_editor:
                                        coord = bld_coord
                            else:
                                # asset is in the same building, use asset's own coordinates
                                pc_asset_coord = pc_asset['coord']
                        else:
                            # other asset is not in a building
                            if bld_editor:
                                # ... connect to the left border
                                pc_asset_coord = (coord[0], 0)
                            else:
                                # ... just use asset's location
                                pc_asset_coord = pc_asset['coord']

                        pc_carr_id = None
                        if pc.carrier:
                            pc_carr_id = pc.carrier.id
                        # Add connections if we're editing a building or if the connection is between two different buildings
                        # ( The case of an asset in an area that is connected with an asset in a building is handled
                        #   in process_area (now all connections are added twice, from both sides) )
                        if bld_editor or in_different_buildings:
                            conn_list.append({'from-port-id': p.id, 'from-port-carrier': p_carr_id, 'from-asset-id': basset.id, 'from-asset-coord': coord,
                                'to-port-id': pc.id, 'to-port-carrier': pc_carr_id, 'to-asset-id': pc_asset['asset'].id, 'to-asset-coord': pc_asset_coord})

    if bld_editor:
        for potential in building.potential:
            geom = potential.geometry
            if geom:
                if isinstance(geom, esdl.Point):
                    lat = geom.lat
                    lon = geom.lon

                    asset_list.append(
                        ['point', 'potential', potential.name, potential.id, type(potential).__name__, [lat, lon]])
Пример #12
0
    def call_esdl_service(self, service_params):
        """Actually call an ESDL service."""

        esh = get_handler()
        active_es_id = get_session("active_es_id")

        # {'service_id': '18d106cf-2af1-407d-8697-0dae23a0ac3e', 'area_scope': 'provincies', 'area_id': '12',
        #  'query_parameters': {'bebouwingsafstand': '32432', 'restrictie': 'vliegveld', 'preferentie': 'infrastructuur', 'geometrie': 'true'}}

        # Find the currently active service.
        service = None
        for config_service in self.config:
            if config_service["id"] == service_params["service_id"]:
                service = config_service
                break
            # If it's a workflow, lookin its steps.
            if config_service["type"] == "workflow":
                for step in config_service["workflow"]:
                    if (step["type"] == "service" and step["service"]["id"]
                            == service_params["service_id"]):
                        service = step["service"]
                        break

        if service is None:
            return False, None

        url = service["url"]
        headers = service["headers"]
        if service.get("with_jwt_token", False):
            jwt_token = get_session("jwt-token")
            headers["Authorization"] = f"Bearer {jwt_token}"

        body = {}

        if "send_email_in_post_body_parameter" in service:
            body[service["send_email_in_post_body_parameter"]] = get_session(
                "user-email")

        if service["type"] == "geo_query":
            area_scope_tag = service["geographical_scope"]["url_area_scope"]
            area_id_tag = service["geographical_scope"]["url_area_id"]

            area_scope = service_params["area_scope"]
            url = url.replace(area_scope_tag, area_scope)
            ares_id = service_params["area_id"]
            url = url.replace(area_id_tag, ares_id)
            if "url_area_subscope" in service["geographical_scope"]:
                area_subscope_tag = service["geographical_scope"][
                    "url_area_subscope"]
                area_subscope = service_params["area_subscope"]
                url = url.replace(area_subscope_tag, area_subscope)
        elif service["type"] == "send_esdl":
            esdlstr = esh.to_string(active_es_id)

            if service["body"] == "url_encoded":
                body["energysystem"] = urllib.parse.quote(esdlstr)
                # print(body)
            elif service["body"] == "base64_encoded":
                esdlstr_bytes = esdlstr.encode('ascii')
                esdlstr_base64_bytes = base64.b64encode(esdlstr_bytes)
                body["energysystem"] = esdlstr_base64_bytes.decode('ascii')
            else:
                body = esdlstr
        elif service["type"] == "simulation":
            esdlstr = esh.to_string(active_es_id)

            if service["body"] == "url_encoded":
                body["energysystem"] = urllib.parse.quote(esdlstr)
            elif service["body"] == "base64_encoded":
                esdlstr_bytes = esdlstr.encode('ascii')
                esdlstr_base64_bytes = base64.b64encode(esdlstr_bytes)
                body["energysystem"] = esdlstr_base64_bytes.decode('ascii')
            else:
                body = esdlstr

        query_params = service_params["query_parameters"]
        config_service_params = service["query_parameters"]
        if query_params:
            first_qp = True
            for key in query_params:
                if query_params[
                        key]:  # to filter empty lists for multi-selection parameters
                    for cfg_service_param in config_service_params:
                        if cfg_service_param["parameter_name"] == key:
                            if "location" in cfg_service_param:
                                if cfg_service_param["location"] == "url":
                                    url = url.replace(
                                        "<" +
                                        cfg_service_param["parameter_name"] +
                                        ">",
                                        query_params[key],
                                    )
                                elif cfg_service_param[
                                        "location"] == "body" and isinstance(
                                            body, dict):
                                    body[cfg_service_param[
                                        "parameter_name"]] = query_params[key]
                            else:
                                if first_qp:
                                    url = url + "?"
                                else:
                                    url = url + "&"
                                url = (url + key + "=" +
                                       self.array2list(query_params[key]))
                                first_qp = False

        try:
            if service["http_method"] == "get":
                r = requests.get(url, headers=headers)
            elif service["http_method"] == "post":
                if service["type"] == "json":
                    kwargs = {"json": body}
                else:
                    kwargs = {"data": body}
                r = requests.post(url, headers=headers, **kwargs)
            else:
                # Should not happen, there should always be a method.
                return False, None

            if (service["http_method"] == "get" and r.status_code == 200) or \
                    (service["http_method"] == "post" and r.status_code == 201):
                # print(r.text)

                if service["result"][0]["action"] == "esdl":
                    esh.add_from_string(service["name"], r.text)
                    return True, None
                elif service["result"][0]["action"] == "print":
                    return True, json.loads(r.text)
                elif service["result"][0]["action"] == "add_assets":
                    es_edit = esh.get_energy_system(es_id=active_es_id)
                    instance = es_edit.instance
                    area = instance[0].area
                    asset_str_list = json.loads(r.text)

                    try:
                        for asset_str in asset_str_list["add_assets"]:
                            asset = ESDLAsset.load_asset_from_string(asset_str)
                            esh.add_object_to_dict(active_es_id, asset)
                            ESDLAsset.add_asset_to_area(
                                es_edit, asset, area.id)
                            asset_ui, conn_list = energy_asset_to_ui(
                                esh, active_es_id, asset)
                            emit(
                                "add_esdl_objects",
                                {
                                    "es_id": active_es_id,
                                    "asset_pot_list": [asset_ui],
                                    "zoom": True,
                                },
                            )
                            emit(
                                "add_connections",
                                {
                                    "es_id": active_es_id,
                                    "conn_list": conn_list
                                },
                            )
                    except Exception as e:
                        logger.warning("Exception occurred: " + str(e))
                        return False, None

                    return True, {"send_message_to_UI_but_do_nothing": {}}
                elif service["result"][0]["action"] == "show_message":
                    return True, {"message": service["result"][0]["message"]}
            else:
                logger.warning("Error running ESDL service - response " +
                               str(r.status_code) + " with reason: " +
                               str(r.reason))
                logger.warning(r)
                logger.warning(r.content)
                return False, None
        except Exception as e:
            logger.warning("Error accessing external ESDL service: " + str(e))
            return False, None

        return False, None
    def call_esdl_service(self, service_params):
        """Actually call an ESDL service."""

        esh = get_handler()
        active_es_id = get_session("active_es_id")

        # {'service_id': '18d106cf-2af1-407d-8697-0dae23a0ac3e', 'area_scope': 'provincies', 'area_id': '12',
        #  'query_parameters': {'bebouwingsafstand': '32432', 'restrictie': 'vliegveld', 'preferentie': 'infrastructuur', 'geometrie': 'true'}}

        # Find the currently active service.
        service = None
        # services_list = get_session('services_list')
        user_email = get_session('user-email')
        role = get_session('user-role')
        services_list = self.get_user_services_list(user_email, role)
        for config_service in services_list:
            if config_service["id"] == service_params["service_id"]:
                service = config_service
                break
            # If it's a workflow, look in its steps.
            if config_service["type"] in ("workflow", "vueworkflow"):
                for step in config_service["workflow"]:
                    if (step["type"] in ("service", "custom")):
                        if "service" in step and step["service"][
                                "id"] == service_params["service_id"]:
                            service = step["service"]
                            break

        if service is None:
            return False, None

        url = service["url"]
        headers = service["headers"]
        if service.get("with_jwt_token", False):
            jwt_token = get_session("jwt-token")
            headers["Authorization"] = f"Bearer {jwt_token}"

        body = {}

        if "send_email_in_post_body_parameter" in service:
            body[service["send_email_in_post_body_parameter"]] = get_session(
                "user-email")

        if service["type"] == "geo_query":
            area_scope_tag = service["geographical_scope"]["url_area_scope"]
            area_id_tag = service["geographical_scope"]["url_area_id"]

            area_scope = service_params["area_scope"]
            url = url.replace(area_scope_tag, area_scope)
            ares_id = service_params["area_id"]
            url = url.replace(area_id_tag, ares_id)
            if "url_area_subscope" in service["geographical_scope"]:
                area_subscope_tag = service["geographical_scope"][
                    "url_area_subscope"]
                area_subscope = service_params["area_subscope"]
                url = url.replace(area_subscope_tag, area_subscope)
        elif service["type"].startswith("send_esdl"):
            esdlstr = esh.to_string(active_es_id)

            if service["body"] == "url_encoded":
                body["energysystem"] = urllib.parse.quote(esdlstr)
                # print(body)
            elif service["body"] == "base64_encoded":
                esdlstr_bytes = esdlstr.encode('utf-8')
                esdlstr_base64_bytes = base64.b64encode(esdlstr_bytes)
                body["energysystem"] = esdlstr_base64_bytes.decode('utf-8')
            else:
                body = esdlstr
        elif service["type"] == "simulation":
            esdlstr = esh.to_string(active_es_id)

            if service["body"] == "url_encoded":
                body["energysystem"] = urllib.parse.quote(esdlstr)
            elif service["body"] == "base64_encoded":
                esdlstr_bytes = esdlstr.encode('utf-8')
                esdlstr_base64_bytes = base64.b64encode(esdlstr_bytes)
                body["energysystem"] = esdlstr_base64_bytes.decode('utf-8')
            else:
                body = esdlstr

        if "body_config" in service:
            if service["body_config"]["type"] == "text":
                esdlstr = esh.to_string(active_es_id)
                if service["body_config"]["encoding"] == "none":
                    body = esdlstr
                if service["body_config"]["encoding"] == "url_encoded":
                    body = urllib.parse.quote(esdlstr)
                if service["body_config"]["encoding"] == "base64_encoded":
                    esdlstr_bytes = esdlstr.encode('utf-8')
                    esdlstr_base64_bytes = base64.b64encode(esdlstr_bytes)
                    body = esdlstr_base64_bytes.decode('utf-8')
            if service["body_config"]["type"] == "json":
                body = {}
                for param in service["body_config"]['parameters']:
                    if param["type"] == "esdl":
                        esdlstr = esh.to_string(active_es_id)
                        if param["encoding"] == "none":
                            body[param["parameter"]] = esdlstr
                        if param["encoding"] == "url_encoded":
                            body[param["parameter"]] = urllib.parse.quote(
                                esdlstr)
                        if param["encoding"] == "base64_encoded":
                            esdlstr_bytes = esdlstr.encode('utf-8')
                            esdlstr_base64_bytes = base64.b64encode(
                                esdlstr_bytes)
                            body[param[
                                "parameter"]] = esdlstr_base64_bytes.decode(
                                    'utf-8')
                    if param["type"] == "value":
                        body[param["parameter"]] = param["value"]
                    if param["type"] == "json_string":
                        body_params = service_params["body_config"]
                        for bp in body_params:
                            if param["parameter"] == bp:
                                body[param["parameter"]] = body_params[bp]

        query_params = service_params["query_parameters"]
        config_service_params = service.get("query_parameters", {})
        if query_params:
            first_qp = True
            for key in query_params:
                if query_params[
                        key]:  # to filter empty lists for multi-selection parameters
                    for cfg_service_param in config_service_params:
                        if cfg_service_param["parameter_name"] == key:
                            if "location" in cfg_service_param:
                                if cfg_service_param["location"] == "url":
                                    url = url.replace(
                                        "<" +
                                        cfg_service_param["parameter_name"] +
                                        ">",
                                        str(query_params[key]),
                                    )
                                elif cfg_service_param[
                                        "location"] == "body" and isinstance(
                                            body, dict):
                                    body[cfg_service_param[
                                        "parameter_name"]] = query_params[key]
                            else:
                                if first_qp:
                                    url = url + "?"
                                else:
                                    url = url + "&"
                                url = (url + key + "=" +
                                       self.array2list(query_params[key]))
                                first_qp = False

        try:
            if service["http_method"] == "get":
                r = requests.get(url, headers=headers)
            elif service["http_method"] == "post":
                if service["type"].endswith("json") or (
                        "body_config" in service
                        and service["body_config"]["type"] == "json"):
                    kwargs = {"json": body}
                else:
                    kwargs = {"data": body}
                r = requests.post(url, headers=headers, **kwargs)
            else:
                # Should not happen, there should always be a method.
                return False, None

            if r.status_code == 200 or r.status_code == 201:
                # print(r.text)

                if service["result"][0]["action"] == "esdl":
                    if "encoding" in service["result"][0]:
                        if service["result"][0]["encoding"] == "url_encoded":
                            esdl_response = urllib.parse.quote(r.text)
                        elif service["result"][0][
                                "encoding"] == "base64_encoded":
                            esdlstr_bytes = r.text.encode('utf-8')
                            esdlstr_base64_bytes = base64.b64decode(
                                esdlstr_bytes)
                            esdl_response = esdlstr_base64_bytes.decode(
                                'utf-8')
                        else:
                            esdl_response = r.text
                    else:
                        esdl_response = r.text

                    es, parse_info = esh.add_from_string(
                        service["name"], esdl_response)
                    # TODO deal with parse_info?
                    return True, None
                elif service["result"][0]["action"] == "print":
                    return True, json.loads(r.text)
                elif service["result"][0]["action"] == "add_assets":
                    es_edit = esh.get_energy_system(es_id=active_es_id)
                    instance = es_edit.instance
                    area = instance[0].area
                    asset_str_list = json.loads(r.text)

                    # Fix for services that return an ESDL string that represents one asset
                    if isinstance(asset_str_list, str):
                        asset_str_list = {"add_assets": [asset_str_list]}

                    try:
                        for asset_str in asset_str_list["add_assets"]:
                            asset = ESDLAsset.load_asset_from_string(asset_str)
                            esh.add_object_to_dict(active_es_id, asset)
                            ESDLAsset.add_object_to_area(
                                es_edit, asset, area.id)
                            asset_ui, conn_list = energy_asset_to_ui(
                                esh, active_es_id, asset)
                            emit(
                                "add_esdl_objects",
                                {
                                    "es_id": active_es_id,
                                    "asset_pot_list": [asset_ui],
                                    "zoom": True,
                                },
                            )
                            emit(
                                "add_connections",
                                {
                                    "es_id": active_es_id,
                                    "conn_list": conn_list
                                },
                            )
                    except Exception as e:
                        logger.warning("Exception occurred: " + str(e))
                        return False, None

                    return True, {"send_message_to_UI_but_do_nothing": {}}
                elif service["result"][0]["action"] == "add_notes":
                    es_edit = esh.get_energy_system(es_id=active_es_id)
                    esi = es_edit.energySystemInformation
                    if not esi:
                        esi = es_edit.energySystemInformation = esdl.EnergySystemInformation(
                            id=str(uuid.uuid4()))
                        esh.add_object_to_dict(active_es_id, esi)
                    notes = esi.notes
                    if not notes:
                        notes = esi.notes = esdl.Notes(id=str(uuid.uuid4()))
                        esh.add_object_to_dict(active_es_id, notes)

                    notes_from_service = ESDLAsset.load_asset_from_string(
                        esdl_string=r.text)
                    if isinstance(notes_from_service, esdl.Notes):
                        notes_list = []
                        for note in list(notes_from_service.note):
                            notes.note.append(note)
                            esh.add_object_to_dict(active_es_id, note)
                            map_location = note.mapLocation
                            if map_location:
                                coords = {
                                    'lng': map_location.lon,
                                    'lat': map_location.lat
                                }
                                notes_list.append({
                                    'id': note.id,
                                    'location': coords,
                                    'title': note.title,
                                    'text': note.text,
                                    'author': note.author
                                })  # , 'date': n.date})
                        emit('add_notes', {
                            'es_id': active_es_id,
                            'notes_list': notes_list
                        })
                    else:
                        logger.error("Service with id " +
                                     service_params["service_id"] +
                                     " did not return a esdl.Notes object")
                        return False, None

                    return True, {"send_message_to_UI_but_do_nothing": {}}
                elif service["result"][0]["action"] == "asset_feedback":
                    service_results = json.loads(r.text)

                    asset_results_dict = dict()
                    for sr in service_results:
                        asset_results_dict[sr['assetID']] = sr['messages']
                    return True, {"asset_feedback": asset_results_dict}
                elif service["result"][0]["action"] == "show_message":
                    return True, {"message": service["result"][0]["message"]}
            else:
                logger.warning("Error running ESDL service - response " +
                               str(r.status_code) + " with reason: " +
                               str(r.reason))
                logger.warning(r)
                logger.warning(r.content)
                return False, str(r.content)
        except Exception as e:
            logger.exception("Error accessing external ESDL service: " +
                             str(e))
            return False, None

        return False, None