def load_asset_from_string(esdl_string): uri = StringURI('from_string.esdl', esdl_string) # self._new_resource_set() rset = ResourceSet() resource = rset.create_resource(uri) resource.load() esdl_instance = resource.contents[0] return esdl_instance
def test_resourceset_createresource_ecore(): rset = ResourceSet() resource = rset.create_resource(URI('simple.ecore')) rpath = path.abspath('simple.ecore') assert rpath in rset.resources assert rset.resources[rpath] is resource assert rset in resource.decoders assert isinstance(resource, rset.resource_factory['ecore']('').__class__)
def main(debug=False): # Go to working directory if str(os.path.dirname(__file__)) != '': os.chdir(str(os.path.dirname(__file__))) # Count arguments if len(sys.argv) < 2 or len(sys.argv) > 3: print( 'Please give at least an GRS file name (input model) and optionaly an XMI file name (output model)' ) sys.exit(0) # Obtain GRS model filename # ~ grs_filename = os.path.relpath(sys.argv[1], str(os.getcwd())) grs_filename = os.path.relpath(sys.argv[1], str(os.getcwd())) # Obtain XMI model filename if len(sys.argv) == 3: xmi_filename = sys.argv[2] else: xmi_filename = '../models/generos.xmi' # Load Grammar dsl_metamodel = metamodel_from_file('generos.tx', debug=False) # Convert importURI string (if needed) def conv(i): return i.replace(".", "/") + ".grs" # Scope Providers dsl_metamodel.register_scope_providers( {"*.*": scoping_providers.FQNImportURI(importAs=True)}) # Recursive function that loads the commands of the imported models to the main model def resolve_imports(current_model): # Load imported models imports = get_children_of_type("Import", current_model) for i in imports: for m in i._tx_loaded_models: # Recursively attach commands of more deep imports m = resolve_imports(m) # Attach commands of the submodels (imports) to the main model current_model.commands.extend(m.commands) return current_model # Load Model model = dsl_metamodel.model_from_file(grs_filename) resolve_imports(model) # Fire up the generation system = RosSystem() system.interpret(model) #create rset global_registry[Ecore.nsURI] = Ecore rset = ResourceSet() rset.metamodel_registry[metageneros.nsURI] = metageneros model_res = rset.create_resource(URI(xmi_filename)) # Save model_res.append(system.rosystem) model_res.save()
def load_external_string(self, esdl_string, name='from_string'): """Loads an energy system from a string but does NOT add it to the resourceSet (e.g. as a separate resource) It returns an Energy System, but it is not part of a resource in the ResourceSet """ uri = StringURI(name + '.esdl', esdl_string) external_rset = ResourceSet() external_resource = external_rset.create_resource(uri) external_resource.load() external_energy_system = external_resource.contents[0] self.validate(es=external_energy_system) return external_energy_system
def serialize(self, geppetto_model): #we now create a resource to save the geppetto model and serialize it to a JSON string rset = ResourceSet() uri = StringURI('netpyne_model.json') rset.resource_factory['*'] = lambda uri: GeppettoResource(uri, indent=2) resource = rset.create_resource(uri) resource.append(geppetto_model) #TODO: We need to apply a visitor and set all the serialised objects to synched resource.save(options={JsonOptions.SERIALIZE_DEFAULT_VALUES: True}) return uri.getvalue()
def saveModel(model): # create a resourceSet that hold the contents of the gdm.ecore model and the instances we use/create rset = ResourceSet() # register the metamodel (available in the generated files) rset.metamodel_registry[gdm.nsURI] = gdm rset.resource_factory['gdm'] = lambda uri: XMIResource(uri) resource = rset.create_resource(URI('Static_model_test.xmi')) resource.append(model) resource.save() return
def load_external_string(self, esdl_string, name='from_string'): """Loads an energy system from a string but does NOT add it to the resourceSet (e.g. as a separate resource) It returns an Energy System and parse info as a tuple, but the ES is not part of a resource in the ResourceSet """ uri = StringURI(name + '.esdl', esdl_string) external_rset = ResourceSet() external_resource = external_rset.create_resource(uri) external_resource.load() parse_info = [] if isinstance(external_resource, XMLResource): parse_info = external_resource.get_parse_information() external_energy_system = external_resource.contents[0] self.validate(es=external_energy_system) return external_energy_system, parse_info
class EnergySystemHandler: def __init__(self): self.rset = None self.resource = None self.energy_system = None self._new_resource_set() esdl.ProfileElement.from_.name = 'from' setattr(esdl.ProfileElement, 'from', esdl.ProfileElement.from_) alias('start', esdl.ProfileElement.from_) esdl.FromToIntPerc.from_.name = 'from' setattr(esdl.FromToIntPerc, 'from', esdl.FromToIntPerc.from_) alias('start', esdl.FromToIntPerc.from_) esdl.FromToDoublePerc.from_.name = 'from' setattr(esdl.FromToDoublePerc, 'from', esdl.FromToDoublePerc.from_) alias('start', esdl.FromToDoublePerc.from_) def _new_resource_set(self): self.rset = ResourceSet() self._set_resource_factories() def _set_resource_factories(self): # Assign files with the .esdl extension to the XMLResource instead of default XMI self.rset.resource_factory['esdl'] = XMLResource self.rset.resource_factory['*'] = XMLResource def load_from_string(self, esdl_string, name='from_string'): """Loads an energy system from a string and adds it to a *new* resourceSet :returns the loaded EnergySystem """ uri = StringURI(name + '.esdl', esdl_string) self._new_resource_set() self.resource = self.rset.create_resource(uri) try: self.resource.load() self.energy_system = self.resource.contents[0] return self.energy_system except Exception as e: log.error("Exception when loading resource: {}: {}".format( name, e)) raise def get_energy_system(self): return self.energy_system
def test_resource_update_URI(): resource = Resource(uri=URI('test_uri')) assert resource.uri.plain == 'test_uri' resource.uri = URI('http://new_URI') assert resource.uri.plain == 'http://new_URI' resource.uri = 'http://newnewURI' assert resource.uri.plain == 'http://newnewURI' rset = ResourceSet() resource = rset.create_resource('http://test_URI') assert resource.uri.plain == 'http://test_URI' resource.uri = 'http://newURI' assert 'http://newURI' in rset.resources assert 'http://test_URI' not in rset.resources assert resource.uri.plain == 'http://newURI'
def test_allinstances_dynamic(): A = EClass('A') a = A() b = A() assert a in A.allInstances() assert b in A.allInstances() from pyecore.resources import ResourceSet rset = ResourceSet() r1 = rset.create_resource('http://test1') r2 = rset.create_resource('http://test2') r1.append(a) r2.append(b) assert a in A.allInstances(resources=(r1, )) assert a not in A.allInstances(resources=(r2, )) assert b in A.allInstances(resources=(r2, )) assert b not in A.allInstances(resources=(r1, ))
def test_allinstances_static(): @EMetaclass class A(object): pass a = A() b = A() assert a in A.allInstances() assert b in A.allInstances() from pyecore.resources import ResourceSet rset = ResourceSet() r1 = rset.create_resource('http://test1') r2 = rset.create_resource('http://test2') r1.append(a) r2.append(b) assert a in A.allInstances(resources=(r1, )) assert a not in A.allInstances(resources=(r2, )) assert b in A.allInstances(resources=(r2, )) assert b not in A.allInstances(resources=(r1, ))
class EnergySystemHandler: def __init__(self, energy_system=None): if energy_system is not None: self.energy_system = energy_system self.resource = None self.rset = ResourceSet() self.esid_uri_dict = {} self._set_resource_factories() # fix python builtin 'from' that is also used in ProfileElement as attribute # use 'start' instead of 'from' when using a ProfileElement # and make sure that it is serialized back as 'from' instead of 'from_' esdl.ProfileElement.from_.name = 'from' setattr(esdl.ProfileElement, 'from', esdl.ProfileElement.from_) alias('start', esdl.ProfileElement.from_) # also for FromToIntItem esdl.FromToIntItem.from_.name = 'from' setattr(esdl.FromToIntItem, 'from', esdl.FromToIntItem.from_) alias('start', esdl.FromToIntItem.from_) # also for FromToDoubleItem esdl.FromToDoubleItem.from_.name = 'from' setattr(esdl.FromToDoubleItem, 'from', esdl.FromToDoubleItem.from_) alias('start', esdl.FromToDoubleItem.from_) # add support for cloning of EObjects and coppy.copy() setattr(EObject, '__copy__', support_functions.clone) setattr(EObject, 'clone', support_functions.clone) # add support for deepcopying EObjects and copy.deepcopy() setattr(EObject, '__deepcopy__', support_functions.deepcopy) setattr(EObject, 'deepcopy', support_functions.deepcopy) # have a nice __repr__ for some ESDL classes when printing ESDL objects (includes all Assets and EnergyAssets) esdl.EnergySystem.__repr__ = \ lambda x: '{}: ({})'.format(x.name, EnergySystemHandler.attr_to_dict(x)) def _new_resource_set(self): """Resets the resourceset (e.g. when loading a new file)""" self.rset = ResourceSet() self.resource = None self._set_resource_factories() def _set_resource_factories(self): # Assign files with the .esdl extension to the XMLResource instead of default XMI self.rset.resource_factory['esdl'] = XMLResource self.rset.resource_factory['*'] = XMLResource def load_file(self, uri_or_filename) -> (esdl.EnergySystem, []): """Loads a EnergySystem file or URI into a new resourceSet :returns EnergySystem and the parse warnings as a tuple (es, parse_info)""" if isinstance(uri_or_filename, str): if uri_or_filename[:4] == 'http': uri = HttpURI(uri_or_filename) else: uri = URI(uri_or_filename) else: uri = uri_or_filename return self.load_uri(uri) def import_file(self, uri_or_filename): """ :returns: EnergySystem and the parse warnings as a tuple (es, parse_info) """ if isinstance(uri_or_filename, str): if uri_or_filename[:4] == 'http': uri = HttpURI(uri_or_filename) else: uri = URI(uri_or_filename) else: uri = uri_or_filename return self.add_uri(uri) def load_uri(self, uri) -> (esdl.EnergySystem, []): """Loads a new resource in a new resourceSet :returns: EnergySystem and the parse warnings as a tuple (es, parse_info) """ self._new_resource_set() self.resource = self.rset.get_resource(uri) parse_info = [] if isinstance(self.resource, XMLResource): parse_info = self.resource.get_parse_information() # At this point, the model instance is loaded! self.energy_system = self.resource.contents[0] if isinstance(uri, str): self.esid_uri_dict[self.energy_system.id] = uri else: self.esid_uri_dict[self.energy_system.id] = uri.normalize() self.add_object_to_dict(self.energy_system.id, self.energy_system, False) return self.energy_system, parse_info def add_uri(self, uri): """ Adds the specified URI to the resource set, i.e. load extra resources that the resource can refer to. :returns: EnergySystem and the parse warnings as a tuple (es, parse_info) """ tmp_resource = self.rset.get_resource(uri) parse_info = [] if isinstance(tmp_resource, XMLResource): parse_info = tmp_resource.get_parse_information() # At this point, the model instance is loaded! # self.energy_system = self.resource.contents[0] self.validate(es=tmp_resource.contents[0]) if isinstance(uri, str): self.esid_uri_dict[tmp_resource.contents[0].id] = uri else: self.esid_uri_dict[tmp_resource.contents[0].id] = uri.normalize() # Edwin: recursive moet hier toch False zijn?? immers elke resource heeft zijn eigen uuid_dict # Ewoud: precies, dus in False veranderd self.add_object_to_dict(tmp_resource.contents[0].id, tmp_resource.contents[0], False) return tmp_resource.contents[0], parse_info def load_from_string(self, esdl_string, name='from_string'): """ Loads an energy system from a string and adds it to a *new* resourceSet :returns: EnergySystem and the parse warnings as a tuple (es, parse_info) """ if name is '': name = str(uuid4()) uri = StringURI(name + '.esdl', esdl_string) self._new_resource_set() self.resource = self.rset.create_resource(uri) try: self.resource.load() self.energy_system = self.resource.contents[0] parse_info = [] if isinstance(self.resource, XMLResource): parse_info = self.resource.get_parse_information() self.validate() self.esid_uri_dict[self.energy_system.id] = uri.normalize() # set to False, otherwise all the ids are added again after loading, is not smart and is slow # is only here to make sure the id of the energy system is also in the uuid_dict self.add_object_to_dict(self.energy_system.id, self.energy_system, False) return self.energy_system, parse_info except Exception as e: logger.error("Exception when loading resource: {}: {}".format( name, e)) raise def load_external_string(self, esdl_string, name='from_string'): """Loads an energy system from a string but does NOT add it to the resourceSet (e.g. as a separate resource) It returns an Energy System and parse info as a tuple, but the ES is not part of a resource in the ResourceSet """ uri = StringURI(name + '.esdl', esdl_string) external_rset = ResourceSet() external_resource = external_rset.create_resource(uri) external_resource.load() parse_info = [] if isinstance(external_resource, XMLResource): parse_info = external_resource.get_parse_information() external_energy_system = external_resource.contents[0] self.validate(es=external_energy_system) return external_energy_system, parse_info def add_from_string(self, name, esdl_string): """Loads an energy system from a string and adds it to the *existing* resourceSet :returns: EnergySystem and the parse warnings as a tuple (es, parse_info) """ uri = StringURI(name + '.esdl', esdl_string) # self.add_uri(uri) try: tmp_resource = self.rset.get_resource(uri) parse_info = [] if isinstance(tmp_resource, XMLResource): parse_info = tmp_resource.get_parse_information() tmp_es = tmp_resource.contents[0] self.validate(es=tmp_es) self.esid_uri_dict[tmp_es.id] = uri.normalize() self.add_object_to_dict(tmp_es.id, tmp_es, True) return tmp_resource.contents[0], parse_info except Exception as e: logger.error("Exception when loading resource: {}: {}".format( name, e)) raise def to_string(self, es_id=None): # to use strings as resources, we simulate a string as being a URI uri = StringURI('to_string_' + str(uuid4()) + '.esdl') if es_id is None: self.resource.save(uri) else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] resource = self.rset.resources[my_uri] resource.save(uri) else: # TODO: what to do? original behaviour self.resource.save(uri) # return the string return uri.getvalue() def to_bytesio(self): """Returns a BytesIO stream for the energy system""" uri = StringURI('bytes_io_to_string.esdl') self.resource.save(uri) return uri.get_stream() def save(self, es_id=None, filename=None): """Add the resource to the resourceSet when saving""" if filename is None: if es_id is None: self.resource.save() else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] resource = self.rset.resources[my_uri] resource.save() else: # TODO: what to do? original behaviour self.resource.save() else: uri = URI(filename) fileresource = self.rset.create_resource(uri) if es_id is None: # add the current energy system fileresource.append(self.energy_system) else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] es = self.rset.resources[my_uri].contents[0] fileresource.append(es) else: # TODO: what to do? original behaviour # add the current energy system fileresource.append(self.energy_system) # save the resource fileresource.save() self.rset.remove_resource(fileresource) def save_as(self, filename): """Saves the resource under a different filename""" self.resource.save(output=filename) def save_resourceSet(self): """Saves the complete resourceSet, including additional loaded resources encountered during loading of the initial resource""" for uri, resource in self.rset.resources.items(): logger.info('Saving {}'.format(uri)) resource.save( ) # raises an Error for HTTP URI, but not for CDOHttpURI def get_resource(self, es_id=None): if es_id is None: return self.resource else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] res = self.rset.resources[my_uri] return res else: return None def get_energy_system(self, es_id=None): if es_id is None: return self.energy_system else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] es = self.rset.resources[my_uri].contents[0] return es else: return None def remove_energy_system(self, es_id=None): if es_id is None: return else: my_uri = self.esid_uri_dict[es_id] del self.rset.resources[my_uri] del self.esid_uri_dict[es_id] def get_energy_systems(self): es_list = [] # for esid in self.esid_uri_dict: # uri = self.esid_uri_dict[esid] # es_list.append(self.rset.resources[uri]) for key in self.rset.resources.keys(): es_list.append(self.rset.resources[key].contents[0]) return es_list def validate(self, es=None): if es is None and self.energy_system is not None: es = self.energy_system if es is not None: if es.id is None: es.id = str(uuid4()) logger.warning( "Energysystem has no id, generating one: {}".format(es)) else: logger.warning("Can't validate EnergySystem {}".format(es)) # Using this function you can query for objects by ID # After loading an ESDL-file, all objects that have an ID defines are stored in resource.uuid_dict automatically # Note: If you add things later to the resource, it won't be added automatically to this dictionary though. # Use get_by_id_slow() for that or add them manually using add_object_to_dict() def get_by_id(self, es_id, object_id): if object_id in self.get_resource(es_id).uuid_dict: return self.get_resource(es_id).uuid_dict[object_id] else: logger.error( 'Can\'t find asset for id={} in uuid_dict of the ESDL model'. format(object_id)) #print(self.get_resource(es_id).uuid_dict) raise KeyError( 'Can\'t find asset for id={} in uuid_dict of the ESDL model'. format(object_id)) return None def add_object_to_dict(self, es_id: str, esdl_object: EObject, recursive=False): if recursive: for obj in esdl_object.eAllContents(): self.add_object_to_dict(es_id, obj) if hasattr(esdl_object, 'id'): if esdl_object.id is not None: self.get_resource(es_id).uuid_dict[ esdl_object.id] = esdl_object else: logger.warning('Id has not been set for object {}({})'.format( esdl_object.eClass.name, esdl_object)) def remove_object_from_dict(self, es_id, esdl_object: EObject, recursive=False): if recursive: for obj in esdl_object.eAllContents(): self.remove_object_from_dict(es_id, obj) if hasattr(esdl_object, 'id'): if esdl_object.id is not None and self.get_resource(es_id): del self.get_resource(es_id).uuid_dict[esdl_object.id] def remove_object_from_dict_by_id(self, es_id, object_id): del self.get_resource(es_id).uuid_dict[object_id] # returns a generator of all assets of a specific type. Not only the ones defined in the main Instance's Area # e.g. QuantityAndUnits can be defined in the KPI of an Area or in the EnergySystemInformation object # this function returns all of them at once # @staticmethod def get_all_instances_of_type(self, esdl_type, es_id): all_instances = list() for esdl_element in self.get_energy_system(es_id=es_id).eAllContents(): if isinstance(esdl_element, esdl_type): all_instances.append(esdl_element) return all_instances #return esdl_type.allInstances() # Creates a dict of all the attributes of an ESDL object, useful for printing/debugging @staticmethod def attr_to_dict(esdl_object): d = dict() d['esdlType'] = esdl_object.eClass.name for attr in dir(esdl_object): attr_value = esdl_object.eGet(attr) if attr_value is not None: d[attr] = attr_value return d # Creates a uuid: useful for generating unique IDs @staticmethod def generate_uuid(): return str(uuid4()) def create_empty_energy_system(self, name, es_description, inst_title, area_title, esdlVersion=None): es_id = str(uuid4()) self.energy_system = esdl.EnergySystem(id=es_id, name=name, description=es_description, esdlVersion=esdlVersion) uri = StringURI('empty_energysystem.esdl') self.resource = self.rset.create_resource(uri) # add the current energy system self.resource.append(self.energy_system) self.esid_uri_dict[self.energy_system.id] = uri.normalize() instance = esdl.Instance(id=str(uuid4()), name=inst_title) self.energy_system.instance.append(instance) # TODO: check if this (adding scope) solves error???? area = esdl.Area(id=str(uuid4()), name=area_title, scope=esdl.AreaScopeEnum.from_string('UNDEFINED')) instance.area = area # add generated id's to uuid dict self.add_object_to_dict(es_id, self.energy_system) self.add_object_to_dict(es_id, instance) self.add_object_to_dict(es_id, area) return self.energy_system # Support for Pickling when serializing the energy system in a session # The pyEcore classes by default do not allow for simple serialization for Session management in Flask. # Internally Flask Sessions use Pickle to serialize a data structure by means of its __dict__. This does not work. # Furthermore, ESDL can contain cyclic relations. Therefore we serialize to XMI and back if necessary. def __getstate__(self): state = dict() #print('Serialize rset {}'.format(self.rset.resources)) print('Serializing EnergySystem...', end="") state['energySystem'] = self.to_string() print('done') return state def __setstate__(self, state): self.__init__() #print('Deserialize rset {}'.format(self.rset.resources)) print('Deserializing EnergySystem...', end="") self.load_from_string(state['energySystem']) print('done') def update_version(self, es_id) -> str: """ Increments the version of this Energy System and returns it """ es = self.get_energy_system(es_id) version = '' if es.version is None else str(es.version) try: import re splitted = re.split(r"\D", version) print(splitted) major = splitted[0] major = int(major) + 1 except ValueError: major = 1 es.version = str(major) return es.version
def MakeESDL(RegioNaam, flipcsv, actions): rset = ResourceSet() rset.metamodel_registry[esdl.nsURI] = esdl rset.resource_factory['esdl'] = lambda uri: XMLResource( uri ) # we register the factory for '.esdl' extension and XML serialization es_name = RegioNaam # Create a new EnergySystem es = EnergySystem(id=str(uuid.uuid4()), name=es_name) instance = Instance(id=str(uuid.uuid4()), name='y2030') # AbstractInstanceDate = InstanceDate.date(2020) RawDate = '2030' instance.date = InstanceDate(date=EDate.from_string(RawDate + "-01-01")) instance.aggrType = AggrTypeEnum.PER_COMMODITY es.instance.append(instance) es.instance[0].area = Area(id=RegioNaam, name=RegioNaam) esi = EnergySystemInformation(id=str(uuid.uuid4())) qau = QuantityAndUnits(id=str(uuid.uuid4())) es.energySystemInformation = esi esi.quantityAndUnits = qau s1a = Measures(id=str(uuid.uuid4())) if not os.path.exists(flipcsv): print("========= WARNING: {} does not exist! Skipping...".format( flipcsv)) else: with open(flipcsv, newline='') as csvfile: csvfile = (line.lower() for line in csvfile) reader = csv.reader(csvfile, delimiter=';') column_names = next(reader) print(column_names) for row in reader: bu_code = row[column_names.index('bu_code')] bu_code.replace('\'', '') # remove quotes from bu_code area = Area(id=bu_code, scope="NEIGHBOURHOOD") ce_buurtoptie = row[column_names.index('uitkomst_gecheckt')] # measure = Measure(id=str(uuid.uuid4()),name=ce_buurtoptie) if not ce_buurtoptie == '': measures = Measures(id=str(uuid.uuid4())) # measures.measure.append(ce_buurtoptie) # ce_buurtoptie = row[column_names.index('uitkomst_gecheckt')] # measure = Measure(id=str(uuid.uuid4()),name=ce_buurtoptie) if ce_buurtoptie == 'all-electric': measures.measure.append( MeasureReference(id=str(uuid.uuid4()), reference='S1a_B_LuchtWP')) # measures.measure.append(MeasureReference(id=str(uuid.uuid4()),reference='s1b')) if ce_buurtoptie == 'warmtenet': measures.measure.append( MeasureReference(id=str(uuid.uuid4()), reference='S2a_B_Restwarmte')) # measures.measure.append(MeasureReference(id=str(uuid.uuid4()),reference='s2b')) # measures.measure.append(MeasureReference(id=str(uuid.uuid4()),reference='s3a')) # measures.measure.append(MeasureReference(id=str(uuid.uuid4()),reference='s3b')) # measures.measure.append(MeasureReference(id=str(uuid.uuid4()),reference='s3c')) # measures.measure.append(MeasureReference(id=str(uuid.uuid4()),reference='s3d')) measures.measure.append( MeasureReference(id=str(uuid.uuid4()), reference='S3e_B_TEO')) if ce_buurtoptie == 'groengas': measures.measure.append( MeasureReference(id=str(uuid.uuid4()), reference='S4a_GG_B_hWP')) # measure.append(MeasureReference(id=str(uuid.uuid4()),reference='s4b')) ed_app_sv.profileQuantityAndUnit = MeasureReference( reference=s1a) ed_app_ip.profile.append(ed_app_sv) area.measures = measures es.instance[0].area.area.append(area) # <measures xsi:type="esdl:Measures"> # <measure xsi:type="esdl:Measure" id="S1a_B_LuchtWP" name="S1a_B_LuchtWP"/> # <measure xsi:type="esdl:Measure" id="S3a_B_LT30_30" name="S3a_B_LT30_30"/> # <measure xsi:type="esdl:Measure" id="S0_Referentie" name="S0_Referentie"/> # </measures> if 'save_to_disk' in actions: export_name = "FlipInput/%s.esdl" % (RegioNaam) resource = rset.create_resource(URI(export_name)) resource.append(es) resource.save()
def test_resourceset_canresolve(): rset = ResourceSet() assert rset.can_resolve('http://simple.ecore#//test') is False rset.create_resource(URI('http://simple.ecore')) assert rset.can_resolve('http://simple.ecore#//test') is True
def main(): # create a resourceSet that hold the contents of the esdl.ecore model and the instances we use/create rset = ResourceSet() # register the metamodel (available in the generated files) rset.metamodel_registry[esdl.nsURI] = esdl # Assign files with the .esdl extension to the XMLResource instead of default XMI rset.resource_factory['esdl'] = lambda uri: XMLResource( uri ) # we register the factory for '.esdl' extension and XML serialization # Create a new EnergySystem es = EnergySystem(name="Vesta Resultaten") instance = Instance(name="StartJaar") # AbstractInstanceDate = InstanceDate.date(2020) instance.aggrType = AggrTypeEnum.PER_COMMODITY es.instance.append(instance) es.instance[0].area = Area(name="RESMetropoolregioEindhoven") qau_energy_GJ_yr = QuantityAndUnitType(id=str(uuid.uuid4()), physicalQuantity="ENERGY", unit="JOULE", multiplier="GIGA", perTimeUnit="YEAR") qau_emission_KG = QuantityAndUnitType(id=str(uuid.uuid4()), physicalQuantity="EMISSION", unit="GRAM", multiplier="KILO") with open('data/Strategie1_isolatie_ewp/PerPlanRegio_ESDL.csv', newline='') as csvfile: reader = csv.reader(csvfile, delimiter=';') column_names = next(reader) print(column_names) for row in reader: area = Area(id=row[column_names.index('BU_CODE')], scope="NEIGHBOURHOOD") houses = AggregatedBuilding( id=str(uuid.uuid4()), name="Woningen", numberOfBuildings=int( row[column_names.index('Aantal_woningen')])) area.asset.append(houses) utilities = AggregatedBuilding( id=str(uuid.uuid4()), name="Utiliteiten", numberOfBuildings=int( row[column_names.index('Aantal_utiliteiten')])) area.asset.append(utilities) hd_total = HeatingDemand(id=str(uuid.uuid4()), name="Vraag_Warmte_totaal") hd_total_ip = InPort(id=str(uuid.uuid4()), name="InPort") hd_total_sv = SingleValue( id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_Warmte_totaal')])) hd_total_sv.profileQuantityAndUnit = qau_energy_GJ_yr hd_total_ip.profile = hd_total_sv hd_total.port.append(hd_total_ip) area.asset.append(hd_total) hd_MT = HeatingDemand(id=str(uuid.uuid4()), name="Vraag_MT_Warmte") hd_MT_ip = InPort(id=str(uuid.uuid4()), name="InPort") hd_MT_sv = SingleValue( id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_MT_Warmte')])) hd_MT_sv.profileQuantityAndUnit = qau_energy_GJ_yr hd_MT_ip.profile = hd_MT_sv hd_MT.port.append(hd_MT_ip) area.asset.append(hd_MT) hd_LT = HeatingDemand(id=str(uuid.uuid4()), name="Vraag_LT_Warmte") hd_LT_ip = InPort(id=str(uuid.uuid4()), name="InPort") hd_LT_sv = SingleValue( id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_LT_Warmte')])) hd_LT_sv.profileQuantityAndUnit = qau_energy_GJ_yr hd_LT_ip.profile = hd_LT_sv hd_LT.port.append(hd_LT_ip) area.asset.append(hd_LT) ed = ElectricityDemand(id=str(uuid.uuid4()), name="Vraag_Elektriciteit") ed_ip = InPort(id=str(uuid.uuid4()), name="InPort") ed_sv = SingleValue( id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_Elektriciteit')])) ed_sv.profileQuantityAndUnit = qau_energy_GJ_yr ed_ip.profile = ed_sv ed.port.append(ed_ip) area.asset.append(ed) gd = GasDemand(id=str(uuid.uuid4()), name="Vraag_Aardgas") gd_ip = InPort(id=str(uuid.uuid4()), name="InPort") gd_sv = SingleValue(id=str(uuid.uuid4()), value=float( row[column_names.index('Vraag_Aardgas')])) gd_sv.profileQuantityAndUnit = qau_energy_GJ_yr gd_ip.profile = gd_sv gd.port.append(gd_ip) area.asset.append(gd) co2 = StringKPI(id=str(uuid.uuid4()), name='CO2_uitstoot', value=row[column_names.index('CO2_uitstoot')]) costs = StringKPI( id=str(uuid.uuid4()), name='Maatschappelijke_kosten', value=row[column_names.index('Maatschappelijke_kosten,')]) kpis = KPIs(id=str(uuid.uuid4())) kpis.kpi.append(co2) kpis.kpi.append(costs) area.KPIs = kpis es.instance[0].area.area.append(area) # print("Energy system: {}".format(attr_to_dict(es))) resource = rset.create_resource( URI('vesta_output_warmtekeuze_per_buurt.esdl')) resource.append(es) resource.save()
def MakeESDL(RegioNaam, StrategieNaam): # create a resourceSet that hold the contents of the esdl.ecore model and the instances we use/create rset = ResourceSet() # register the metamodel (available in the generated files) rset.metamodel_registry[esdl.nsURI] = esdl # Assign files with the .esdl extension to the XMLResource instead of default XMI rset.resource_factory['esdl'] = lambda uri: XMLResource(uri) # we register the factory for '.esdl' extension and XML serialization # Create a new EnergySystem es = EnergySystem(name="Vesta Resultaten PerBebouwingsObject") instance = Instance(name="y2030") # AbstractInstanceDate = InstanceDate.date(2020) instance.aggrType = AggrTypeEnum.PER_COMMODITY es.instance.append(instance) es.instance[0].area = Area(name=RegioNaam) qau_energy_GJ_yr = QuantityAndUnitType(id=str(uuid.uuid4()), physicalQuantity="ENERGY", unit="JOULE", multiplier="GIGA", perTimeUnit="YEAR") qau_emission_KG = QuantityAndUnitType(id=str(uuid.uuid4()), physicalQuantity="EMISSION", unit="GRAM", multiplier="KILO") filename = "data/%s/PerBebouwingsObject_ESDL_%s.csv" % (StrategieNaam,RegioNaam) with open(filename, newline='') as csvfile: reader = csv.reader(csvfile, delimiter=';') column_names = next(reader) # print(column_names) for row in reader: area = Area(id=row[column_names.index('BU_CODE')], scope="NEIGHBOURHOOD") hd_total = HeatingDemand(id=str(uuid.uuid4()), name="Vraag_Warmte_totaal") hd_total_ip = InPort(id=str(uuid.uuid4()), name="InPort") hd_total_sv = SingleValue(id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_Warmte_totaal')])) hd_total_sv.profileQuantityAndUnit = qau_energy_GJ_yr hd_total_ip.profile = hd_total_sv hd_total.port.append(hd_total_ip) area.asset.append(hd_total) hd_MT = HeatingDemand(id=str(uuid.uuid4()), name="Vraag_MT_Warmte") hd_MT_ip = InPort(id=str(uuid.uuid4()), name="InPort") hd_MT_sv = SingleValue(id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_MT_Warmte')])) hd_MT_sv.profileQuantityAndUnit = qau_energy_GJ_yr hd_MT_ip.profile = hd_MT_sv hd_MT.port.append(hd_MT_ip) area.asset.append(hd_MT) hd_LT = HeatingDemand(id=str(uuid.uuid4()), name="Vraag_LT_Warmte") hd_LT_ip = InPort(id=str(uuid.uuid4()), name="InPort") hd_LT_sv = SingleValue(id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_LT_Warmte')])) hd_LT_sv.profileQuantityAndUnit = qau_energy_GJ_yr hd_LT_ip.profile = hd_LT_sv hd_LT.port.append(hd_LT_ip) area.asset.append(hd_LT) hd_elek = HeatingDemand(id=str(uuid.uuid4()), name="Vraag_ElektrischeWarmte") hd_elek_ip = InPort(id=str(uuid.uuid4()), name="InPort") hd_elek_sv = SingleValue(id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_ElektrischeWarmte')])) hd_elek_sv.profileQuantityAndUnit = qau_energy_GJ_yr hd_elek_ip.profile = hd_elek_sv hd_elek.port.append(hd_elek_ip) area.asset.append(hd_elek) cd = CoolingDemand(id=str(uuid.uuid4()), name="Vraag_Koude") cd_ip = InPort(id=str(uuid.uuid4()), name="InPort") cd_sv = SingleValue(id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_Koude')])) cd_sv.profileQuantityAndUnit = qau_energy_GJ_yr cd_ip.profile = cd_sv cd.port.append(cd_ip) area.asset.append(cd) ed = ElectricityDemand(id=str(uuid.uuid4()), name="Vraag_Elektriciteit") ed_ip = InPort(id=str(uuid.uuid4()), name="InPort") ed_sv = SingleValue(id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_Elektriciteit')])) ed_sv.profileQuantityAndUnit = qau_energy_GJ_yr ed_ip.profile = ed_sv ed.port.append(ed_ip) area.asset.append(ed) gd = GasDemand(id=str(uuid.uuid4()), name="Vraag_Aardgas") gd_ip = InPort(id=str(uuid.uuid4()), name="InPort") gd_sv = SingleValue(id=str(uuid.uuid4()), value=float(row[column_names.index('Vraag_Aardgas')])) gd_sv.profileQuantityAndUnit = qau_energy_GJ_yr gd_ip.profile = gd_sv gd.port.append(gd_ip) area.asset.append(gd) co2_gas = StringKPI(id=str(uuid.uuid4()),name='CO2_uitstoot_gas', value=row[column_names.index('CO2_uitstoot_gas')]) co2_elek = StringKPI(id=str(uuid.uuid4()),name='CO2_uitstoot_elek', value=row[column_names.index('CO2_uitstoot_elek')]) costs = StringKPI(id=str(uuid.uuid4()),name='Maatschappelijke_kosten', value=row[column_names.index('Maatschappelijke_kosten')]) kpis = KPIs(id=str(uuid.uuid4())) kpis.kpi.append(co2_gas) kpis.kpi.append(co2_elek) kpis.kpi.append(costs) area.KPIs = kpis es.instance[0].area.area.append(area) # print("Energy system: {}".format(attr_to_dict(es))) export_name = "output/%s_%s.esdl" %(StrategieNaam,RegioNaam) resource = rset.create_resource(URI(export_name)) resource.append(es) resource.save() return (RegioNaam, StrategieNaam)
def excel_to_ESDL(fname, sname_woningen, sname_bedrijven): book = open_workbook(fname) sheet = book.sheet_by_name(sname_woningen) top_area_type = str(sheet.cell(0, 3).value) if top_area_type == 'GM': top_area_scope = 'MUNICIPALITY' else: print('Other scopes than municipality not supported yet') # sys.exit(1) top_area_code = top_area_type + str(sheet.cell(0, 4).value) top_area_name = str(sheet.cell(0, 1).value) top_area_year = ci2s(sheet.cell(0, 2)) sub_aggr = str(sheet.cell(0, 5).value) if sub_aggr == 'WK': sub_aggr_id_start = 'WK' + str(sheet.cell(0, 4).value) sub_aggr_scope = 'DISTRICT' sub_area_number_pos = 5 elif sub_aggr[0:2] == 'BU': sub_aggr_scope = 'NEIGHBOURHOOD' sub_aggr_code_column = 3 print('TODO: check buurt codes in excel') column1_name = str(sheet.cell(1, 1).value) column2_name = str(sheet.cell(1, 2).value) if column1_name[0:3] == 'gas': gas_column = 1 if column1_name[0:4] == 'elek': elec_column = 1 if column2_name[0:3] == 'gas': gas_column = 2 if column2_name[0:4] == 'elek': elec_column = 2 es = esdl.EnergySystem(id=str(uuid.uuid4()), name=top_area_name + ' ' + top_area_year) carrs = esdl.Carriers(id=str(uuid.uuid4())) elec_car = esdl.EnergyCarrier(id='ELEC', name='Electricity', emission=180.28, energyContent=1.0, energyCarrierType='FOSSIL') elec_car.emissionUnit = esdl.QuantityAndUnitType( physicalQuantity='EMISSION', multiplier='KILO', unit='GRAM', perMultiplier='GIGA', perUnit='JOULE') elec_car.energyContentUnit = esdl.QuantityAndUnitType( physicalQuantity='ENERGY', multiplier='MEGA', unit='JOULE', perMultiplier='MEGA', perUnit='JOULE') carrs.carrier.append(elec_car) gas_car = esdl.EnergyCarrier(id='GAS', name='Natural Gas', emission=1.788225, energyContent=35.1700000, energyCarrierType='FOSSIL') gas_car.emissionUnit = esdl.QuantityAndUnitType( physicalQuantity='EMISSION', multiplier='KILO', unit='GRAM', perUnit='CUBIC_METRE') gas_car.energyContentUnit = esdl.QuantityAndUnitType( physicalQuantity='ENERGY', multiplier='MEGA', unit='JOULE', perUnit='CUBIC_METRE') carrs.carrier.append(gas_car) heat_comm = esdl.HeatCommodity(id='HEAT', name='Heat') carrs.carrier.append(heat_comm) es.energySystemInformation = esdl.EnergySystemInformation(id=str( uuid.uuid4()), carriers=carrs) srvs = esdl.Services() inst = esdl.Instance(id=str(uuid.uuid4()), name=top_area_name + ' ' + top_area_year) es.instance.append(inst) ar = esdl.Area(id=top_area_code, name=top_area_name, scope=top_area_scope) es.instance[0].area = ar elec_nw_op = esdl.OutPort(id=str(uuid.uuid4()), name='EOut', carrier=elec_car) elec_nw_ip = esdl.InPort(id=str(uuid.uuid4()), name='EIn', carrier=elec_car) elec_nw = esdl.ElectricityNetwork(id=str(uuid.uuid4()), name='ElectricityNetwork', port=[elec_nw_ip, elec_nw_op]) ar.asset.append(elec_nw) gep_mc = esdl.SingleValue(id=str(uuid.uuid4()), name='MarginalCosts', value=elec_prod_mc) gep_ci = esdl.CostInformation(marginalCosts=gep_mc) gep_op = esdl.OutPort(id=str(uuid.uuid4()), name='EOut', connectedTo=[elec_nw_ip], carrier=elec_car) gep = esdl.GenericProducer(id=str(uuid.uuid4()), name='Unlimited Electricity Generation', port=[gep_op], power=gep_power, costInformation=gep_ci, prodType=esdl.RenewableTypeEnum.FOSSIL) ar.asset.append(gep) gec_mc = esdl.SingleValue(id=str(uuid.uuid4()), name='MarginalCosts', value=elec_cons_mc) gec_ci = esdl.CostInformation(marginalCosts=gec_mc) gec_ip = esdl.InPort(id=str(uuid.uuid4()), name='EIn', connectedTo=[elec_nw_op], carrier=elec_car) gec = esdl.GenericConsumer(id=str(uuid.uuid4()), name='Unlimited Electricity Consumption', port=[gec_ip], power=gec_power, costInformation=gec_ci) ar.asset.append(gec) gas_nw_op = esdl.OutPort(id=str(uuid.uuid4()), name='GOut', carrier=gas_car) gas_nw_ip = esdl.InPort(id=str(uuid.uuid4()), name='GIn', carrier=gas_car) gas_nw = esdl.GasNetwork(id=str(uuid.uuid4()), name='GasNetwork', port=[gas_nw_ip, gas_nw_op]) ar.asset.append(gas_nw) ggp_mc = esdl.SingleValue(id=str(uuid.uuid4()), name='MarginalCosts', value=gas_prod_mc) ggp_ci = esdl.CostInformation(marginalCosts=ggp_mc) ggp_op = esdl.OutPort(id=str(uuid.uuid4()), name='GOut', connectedTo=[gas_nw_ip], carrier=gas_car) ggp = esdl.GenericProducer(id=str(uuid.uuid4()), name='Unlimited Gas Generation', port=[ggp_op], power=ggp_power, costInformation=ggp_ci, prodType=esdl.RenewableTypeEnum.FOSSIL) ar.asset.append(ggp) # ggc_mc = esdl.SingleValue(id=str(uuid.uuid4()), name='MarginalCosts', value=gas_cons_mc) # ggc_ci = esdl.CostInformation(marginalCosts=ggc_mc) # ggc_ip = esdl.InPort(id=str(uuid.uuid4()), name='EIn', connectedTo=[gas_nw_op], carrier=elec_car) # ggc = esdl.GenericConsumer(id=str(uuid.uuid4()), name='Unlimited Gas Consumption', port=[ggc_ip], # power=ggc_power, costInformation=ggc_ci) # ar.asset.append(ggc) for row in range(2, sheet.nrows - 3): sub_area_name = str(sheet.cell(row, 0).value) if sub_aggr_scope == 'DISTRICT': sub_area_number = sub_area_name[ sub_area_number_pos:sub_area_number_pos + 2] sub_area_id = str(sub_aggr_id_start + sub_area_number) else: sub_area_id = str(sheet.cell(row, sub_aggr_code_column).value) gas_value = sheet.cell(row, gas_column).value if str(gas_value) != '?' and str(gas_value) != '': heat_value = gas_heater_efficiency * gas_value else: heat_value = None elec_value = sheet.cell(row, elec_column).value if str(elec_value) == '?' and str(elec_value) != '': elec_value = None sub_area = esdl.Area(id=sub_area_id, name=sub_area_name, scope=sub_aggr_scope) aggr_build = esdl.AggregatedBuilding(id=str(uuid.uuid4()), name="building") if heat_value: hdprofqau = esdl.QuantityAndUnitType(physicalQuantity='ENERGY', multiplier='TERRA', unit='JOULE') hdprof = esdl.InfluxDBProfile(id=str(uuid.uuid4()), multiplier=heat_value, host=influx_host, port=influx_port, database=influx_database, filters=influx_filters, measurement=gas_measurement, field=gas_field, profileQuantityAndUnit=hdprofqau, profileType='ENERGY_IN_TJ') hdip = esdl.InPort(id=str(uuid.uuid4()), name='InPort', carrier=heat_comm, profile=hdprof) hd = esdl.HeatingDemand(id=str(uuid.uuid4()), name='HeatingDemand_' + sub_area_id, port=[hdip]) ghip = esdl.InPort(id=str(uuid.uuid4()), name='InPort', connectedTo=[gas_nw_op], carrier=gas_car) ghop = esdl.OutPort(id=str(uuid.uuid4()), name='OutPort', connectedTo=[hdip], carrier=heat_comm) gh = esdl.GasHeater(id=str(uuid.uuid4()), name='GasHeater_' + sub_area_id, efficiency=gas_heater_efficiency, power=gas_heater_power, port=[ghip, ghop]) dbd = esdl.DrivenByDemand(id=str(uuid.uuid4()), name='DBD_GasHeater_' + sub_area_id, energyAsset=gh, outPort=ghop) srvs.service.append(dbd) aggr_build.asset.append(hd) aggr_build.asset.append(gh) if elec_value: edprofqau = esdl.QuantityAndUnitType(physicalQuantity='ENERGY', multiplier='TERRA', unit='JOULE') edprof = esdl.InfluxDBProfile(id=str(uuid.uuid4()), multiplier=elec_value, host=influx_host, port=influx_port, database=influx_database, filters=influx_filters, measurement=elec_measurement, field=elec_field, profileQuantityAndUnit=edprofqau, profileType='ENERGY_IN_TJ') edip = esdl.InPort(id=str(uuid.uuid4()), name='InPort', connectedTo=[elec_nw_op], carrier=elec_car, profile=edprof) ed = esdl.ElectricityDemand(id=str(uuid.uuid4()), name='ElectricityDemand_' + sub_area_id, port=[edip]) aggr_build.asset.append(ed) if heat_value or elec_value: sub_area.asset.append(aggr_build) ar.area.append(sub_area) if sname_bedrijven: sheet = book.sheet_by_name(sname_bedrijven) aggr_build_comp = esdl.AggregatedBuilding(id=str(uuid.uuid4()), name="building-bedrijven") for row in range(2, sheet.nrows - 3): cat = str(sheet.cell(row, 0).value) waarde = sheet.cell(row, 1).value if cat != '' and waarde != 0 and waarde != '?': # filter non relevant data cat = re.sub(' ', '_', cat) print(cat, waarde) if cat.find('m3') != -1: # category contains gasusage gas_tj = waarde * gas_energy_content / mega_to_terra heat_tj = gas_tj * gas_to_heat_efficiency hdbprofqau = esdl.QuantityAndUnitType( physicalQuantity='ENERGY', multiplier='TERRA', unit='JOULE') hdbprof = esdl.InfluxDBProfile( id=str(uuid.uuid4()), multiplier=heat_tj, host=influx_host, port=influx_port, database=influx_database, filters=influx_filters, measurement=gas_measurement, field=gas_field_comp, profileQuantityAndUnit=hdbprofqau, profileType='ENERGY_IN_TJ') hdbip = esdl.InPort(id=str(uuid.uuid4()), name='InPort', carrier=heat_comm, profile=hdbprof) hdb = esdl.HeatingDemand(id=str(uuid.uuid4()), name='HeatingDemand_' + cat, port=[hdbip]) ghbip = esdl.InPort(id=str(uuid.uuid4()), name='InPort', connectedTo=[gas_nw_op], carrier=gas_car) ghbop = esdl.OutPort(id=str(uuid.uuid4()), name='OutPort', connectedTo=[hdbip], carrier=heat_comm) ghb = esdl.GasHeater(id=str(uuid.uuid4()), name='GasHeater_' + cat, efficiency=gas_heater_efficiency, power=gas_heater_power, port=[ghbip, ghbop]) aggr_build_comp.asset.append(hdb) aggr_build_comp.asset.append(ghb) dbd = esdl.DrivenByDemand(id=str(uuid.uuid4()), name='DBD_GasHeater_' + cat, energyAsset=ghb, outPort=ghbop) srvs.service.append(dbd) if cat.find( 'kWh') != -1: # category contains electricity usage elec_tj = waarde * kwh_to_tj edbprofqau = esdl.QuantityAndUnitType( physicalQuantity='ENERGY', multiplier='TERRA', unit='JOULE') edbprof = esdl.InfluxDBProfile( id=str(uuid.uuid4()), multiplier=elec_tj, host=influx_host, port=influx_port, database=influx_database, filters=influx_filters, measurement=elec_measurement, field=elec_field_comp, profileQuantityAndUnit=edbprofqau, profileType='ENERGY_IN_TJ') edbip = esdl.InPort(id=str(uuid.uuid4()), name='InPort', connectedTo=[elec_nw_op], carrier=elec_car, profile=edbprof) edb = esdl.ElectricityDemand(id=str(uuid.uuid4()), name='ElectricityDemand_' + cat, port=[edbip]) aggr_build_comp.asset.append(edb) ar.asset.append(aggr_build_comp) es.services = srvs rset = ResourceSet() rset.resource_factory['esdl'] = lambda uri: XMLResource(uri) rset.metamodel_registry[esdl.nsURI] = esdl resource = rset.create_resource( URI(top_area_name + top_area_year + '.esdl')) resource.append(es) resource.save()
def main(): # create a resourceSet that hold the contents of the esdl.ecore model and the instances we use/create rset = ResourceSet() # register the metamodel (available in the generated files) rset.metamodel_registry[esdl.nsURI] = esdl rset.resource_factory['esdl'] = lambda uri: XMLResource( uri ) # we register the factory for '.esdl' extension and XML serialization # Create a new EnergySystem es = EnergySystem(name="mpoc") instance = Instance(name="test instance") # example of using an Enum instance.aggrType = AggrTypeEnum.PER_COMMODITY es.instance.append(instance) es.instance[0].area = Area(name="Groningen", id="PV20") # create a new PV parc with 10 panels pvparc = PVParc(name="PV parc") pvparc.numberOfPanels = 10 # Use datatime to set dates and times now = datetime.datetime.now() pvparc.commissioningDate = now ed = ElectricityDemand(name="E demand") es.instance[0].area.asset.append(pvparc) es.instance[0].area.asset.append(ed) inPort = InPort(id='InPort1') ed.port.append(inPort) outPort = OutPort(id='OutPort1', connectedTo=[inPort]) pvparc.port.append(outPort) # create a new windturbine turbine = WindTurbine(id=EnergySystemHandler.generate_uuid(), name='WindTurbine 4', power=2E6, fullLoadHours=2000, height=150.0, surfaceArea=100, prodType=RenewableTypeEnum.from_string('RENEWABLE'), type=WindTurbineTypeEnum.from_string('WIND_ON_LAND')) es.instance[0].area.asset.append(turbine) # create new wind search area search_area_wind = SearchAreaWind(id=EnergySystemHandler.generate_uuid(), name="Search Area Wind", fullLoadHours=1920, area=2E8) es.instance[0].area.potential.append(search_area_wind) # create new solar search area search_area_solar = SearchAreaSolar(id=EnergySystemHandler.generate_uuid(), name="Search Area Solar", fullLoadHours=867, area=2E8) es.instance[0].area.potential.append(search_area_solar) # create new KPIs object es.instance[0].area.KPIs = KPIs(description="KPIs") # Create quantity and unit for CO2-emissions co2_unit = QuantityAndUnitType( physicalQuantity="EMISSION", multiplier="MEGA", # unit="GRAM", # perMultiplier="", # perUnit="", description="Mton (CO2-emissions)", # perTimeUnit="", id="mton", ) # Create CO2-emissions KPI kpi_co2 = KPI(name="KPI CO2-emissions", value=None, quantityAndUnit=co2_unit) # Create quantity and unit for total costs costs_unit = QuantityAndUnitType( physicalQuantity="COST", multiplier="MEGA", # unit="GRAM", # perMultiplier="", # perUnit="", description="Mln euros (total costs)", # perTimeUnit="", id="meur", ) # Create costs KPI kpi_costs = KPI(name="KPI Total costs", value=None, quantityAndUnit=costs_unit) # Add CO2-emissions and total costs KPIs to KPIs es.instance[0].area.KPIs.kpi.append(kpi_co2) es.instance[0].area.KPIs.kpi.append(kpi_costs) print("Energy system: {}".format(attr_to_dict(es))) print("OutPort connectedTo: {}".format(outPort.connectedTo)) print("InPort connectedTo: {}".format(inPort.connectedTo)) resource = rset.create_resource(URI('mpoc.esdl')) resource.append(es) resource.save()
def main_model_creator(): rset = ResourceSet() main_list = setup_list() setup = model_setup() a_instance = setup['model'] MyMetamodel = setup['meta-model'] try: #modello già presente resource = rset.get_resource(URI('metamodel.ecore')) mm_root = resource.contents[0] rset.metamodel_registry[mm_root.nsURI] = mm_root resource = rset.get_resource(URI('model.xmi')) model_root = resource.contents[0] for user in model_root.users: # aggiunta utente print(user.name) for repository in user.repositories: # aggiunta repository print(repository.name) ######### inserimento di developers nel modello ########## a_instance = create_developers(main_list, a_instance, MyMetamodel) ########################################################## ######### inserimento delle technologies nel modello ########## tech_instance = create_technology(main_list, a_instance, MyMetamodel) ############################################################### ########## filling model ############ a_instance = insert_from_dict(main_list, MyMetamodel, a_instance, tech_instance) ##################################### ########################################## first_instance = MyMetamodel.User() first_instance.name = model_root.users[0].name a_instance.users.append(first_instance) ########################################## save_resource = rset.create_resource('new_model.xmi') save_resource.append(a_instance) save_resource.save() return 0 except: #modello nuovo ######### inserimento di developers nel modello ########## a_instance = create_developers(main_list, a_instance, MyMetamodel) ########################################################## ######### inserimento delle technologies nel modello ########## tech_instance = create_technology(main_list, a_instance, MyMetamodel) ############################################################### ########## filling model ############ a_instance = insert_from_dict(main_list, MyMetamodel, a_instance, tech_instance) ##################################### save_resource = rset.create_resource('model.xmi') save_resource.append(a_instance) save_resource.save()
class EnergySystemHandler: """Class to handle (load, read, and update) an ESDL Energy System""" # TODO: CAN WE USE THE THING FROM THE VENDOR MODULE? # TODO: extract this to a simple module (NO CLASS) and just import the (self.)esdl # somewhere and define all the lookup there - because the lookup does not need # this whole class right?? just the self.esdl and that has nothing to do with the # actual esdl?? def __init__(self, name=None): # create a resourceSet that hold the contents of the esdl.ecore model and the # instances we use/create self.rset = ResourceSet() # Assign files with the .esdl extension to the XMLResource instead of default XMI self.rset.resource_factory['esdl'] = lambda uri: XMLResource(uri) # Read the esdl.ecore from the tmp folder esdl_model_resource = self.rset.get_resource(URI('vendor/esdl/esdl.ecore')) esdl_model = esdl_model_resource.contents[0] # print('Namespace: {}'.format(esdl_model.nsURI)) self.rset.metamodel_registry[esdl_model.nsURI] = esdl_model # Create a dynamic model from the loaded esdl.ecore model, which we can use to # build Energy Systems self.esdl = DynamicEPackage(esdl_model) # fix python buildin 'from' that is also used in ProfileElement as attribute # use 'start' instead of 'from' when using a ProfileElement alias('start', self.esdl.ProfileElement.findEStructuralFeature('from')) # have a nice __repr__ for some ESDL classes when printing ESDL objects # (includes all Assets and EnergyAssets) # self.esdl.Item.python_class.__repr__ = lambda x: format_repr(x.name, x) self.esdl.Carrier.python_class.__repr__ = lambda x: format_repr(x.name, x) self.esdl.Geometry.python_class.__repr__ = lambda x: format_repr(x.name, x) self.esdl.QuantityAndUnitType.python_class.__repr__ = lambda x: format_repr(x.id, x) self.esdl.QuantityAndUnitReference.python_class.__repr__ = lambda x: format_repr('QuantityAndUnitReference', x) self.esdl.KPI.python_class.__repr__ = lambda x: format_repr(x.name, x) self.esdl.ProfileElement.python_class.__repr__ = lambda x: format_repr('ProfileElement', x) if name: self.name = name self.load_energy_system(name) @staticmethod def generate_uuid(): ''' Creates a uuid: useful for generating unique IDs ''' return str(uuid.uuid4()) def load_energy_system(self, name): ''' Load an ESDL file ''' self.resource = self.rset.get_resource(URI(name)) self.es = self.resource.contents[0] def add_data_source(self, name, description): ''' Adds a data_source to the ESDL containing a name and description''' data_source = self.esdl.DataSource(id='data_source', name=name, description=description) self.es.dataSource = data_source def get_quantity_and_units(self): ''' Returns quantity and units Add energy system information to the energy system if it is not there yet Energy System information can be used to globally define the quantity and units of this system, instead of defining them manually per KPI in each area: this fosters reuse (but is not necessary) ''' if not self.get_by_id('energy_system_information') is None: return self.get_by_id('quantity_and_units') self.__add_energy_system_information() q_and_u = self.esdl.QuantityAndUnits(id='quantity_and_units') self.es.energySystemInformation.quantityAndUnits = q_and_u return q_and_u def __add_energy_system_information(self): '''Add Energy System Information''' esi = self.esdl.EnergySystemInformation(id='energy_system_information') self.es.energySystemInformation = esi def add_measures(self): ''' Add Measures object to Energy System ''' # Create new Measures object measures = self.esdl.Measures(id='measures') self.es.instance[0].area.measures = measures def append_measure(self, measure): ''' Append measure to Measures object ''' self.es.instance[0].area.measures.measure.append(measure) def append_asset_to_measure(self, measure, asset): ''' Append asset measure to Measures object ''' measure.asset.append(asset) self.es.instance[0].area.measures.measure.append(measure) ######## KPIs ######## def add_kpis(self): ''' Add KPIs object to Energy System ''' # create new KPIs object kpis = self.esdl.KPIs(id='kpis', description='KPIs') self.es.instance[0].area.KPIs = kpis def create_kpi(self, kpi_type, kpi_id, name, q_and_u): ''' Create new KPI object ''' return getattr(self.esdl, kpi_type)( id=kpi_id, name=name, quantityAndUnit=q_and_u ) def add_kpi(self, kpi): ''' Add KPI to KPIs object ''' self.es.instance[0].area.KPIs.kpi.append(kpi) def get_kpi_by_id(self, kpi_id): ''' Returns a specific KPI by id, see also get_by_id for a faster method ''' for kpi in self.es.instance[0].area.KPIs.kpi: if kpi.id == kpi_id: return kpi return None def get_kpi_by_name(self, name): ''' Returns a specific KPI by name ''' for kpi in self.es.instance[0].area.KPIs.kpi: if kpi.name == name: return kpi return None ######### LOOKUP ########## def get_by_id(self, object_id): ''' Using this function you can query for objects by ID After loading an ESDL-file, all objects that have an ID defines are stored in resource.uuid_dict automatically Note: If you add things later to the resource, it won't be added automatically to this dictionary though. Use get_by_id_slow() for that ''' if object_id in self.resource.uuid_dict: return self.resource.uuid_dict[object_id] return None def get_by_id_slow(self, object_id): ''' This function iterates over all the contents of the Energy System and is much slower than get_by_id() ''' for child in self.es.eAllContents(): if hasattr(child, 'id') and child.id == object_id: return child return None def get_assets_of_type(self, esdl_type, area=None): '''Get a list of assets of a specific ESDL type in the specified area or asset''' assets = area.asset if not area is None else self.es.instance[0].area.asset esdl_asset = getattr(self.esdl, esdl_type) return [asset for asset in assets if isinstance(asset, esdl_asset)] def has_assets_of_type(self, esdl_type, area=None): ''' Boolean, see get_assets_of_type ''' assets = area.asset if not area is None else self.es.instance[0].area.asset try: next((asset for asset in assets if isinstance(asset, getattr(self.esdl, esdl_type)))) return True except StopIteration: return False def get_assets_of_type_and_attribute_value(self, esdl_type, area, attr, val): ''' Returns a list of assets of a specific ESDL type in the specified area or asset filtered by a specified attribute-value combination Params: esdl_type (str): The type of asset area (esdl.Area): The area that contains the assets to be filtered attr (str): The attribute that should be evaluated val (str): The value that the attribute should have Returns: list[esdl.Asset] ''' esdl_asset = getattr(self.esdl, esdl_type) return [asset for asset in area.asset if isinstance(asset, esdl_asset) and str(getattr(asset, attr)) == val] def has_assets_of_type_and_attribute_value(self, esdl_type, area, attr, val): ''' Works like get_of_type_and_attribute_value, but only checks if the first item can be generated Params: esdl_type (str): The type of asset area (esdl.Area): The area that contains the assets to be filtered attr (str): The attribute that should be evaluated val (str): The value that the attribute should have Returns: bool ''' try: next((asset for asset in area.asset if isinstance(asset, getattr(self.esdl, esdl_type)) and str(getattr(asset, attr)) == val)) return True except StopIteration: return False def get_potentials_of_type(self, esdl_type): ''' Get a list of potentials of a specific ESDL type in the main instance's area ''' potentials = [] for current_potential in self.es.instance[0].area.potential: if isinstance(current_potential, esdl_type): potentials.append(current_potential) return potentials def get_all_instances_of_type(self, esdl_type): ''' Returns a generator of all assets or potentials of a specific type. Not only the ones defined in the main Instance's Area e.g. QuantityAndUnits can be defined in the KPI of an Area or in the EnergySystemInformation object this function returns all of them at once. Params: esdl_type (str): The type of asset Returns: generator of assets or potentials ''' yield from getattr(self.esdl, esdl_type).allInstances(resources=(self.resource,)) def get_all_instances_of_type_and_attribute_value(self, esdl_type, attr, val): ''' Returns a generator of all assets or potentials of a specific type. Not only the ones defined in the main Instance's Area e.g. QuantityAndUnits can be defined in the KPI of an Area or in the EnergySystemInformation object this function returns all of them at once. The assets are then filtered for a specific attribute-value combination Params: esdl_type (str): The type of asset attr (str): The attribute that should be evaluated val (str): The value that the attribute should have Returns: generator of assets or potentials ''' yield from (inst for inst in self.get_all_instances_of_type(esdl_type) if str(getattr(inst, attr)) == val) def get_all_instances_of_type_and_sector(self, esdl_type, sector_id): ''' Returns a generator of all assets or potentials of a specific type. Not only the ones defined in the main Instance's Area e.g. QuantityAndUnits can be defined in the KPI of an Area or in the EnergySystemInformation object this function returns all of them at once. The assets are then filtered for a specific combination on an attribute and it's ID. Params: esdl_type (str): The type of asset sector_id (str | list[str]): The value of the sectors id, e.g. REF for Refineries Returns: generator of assets or potentials ''' yield from (inst for inst in self.get_all_instances_of_type(esdl_type) if self.in_sector(inst, sector_id)) def get_all_instances_of_type_and_carrier(self, esdl_type, carrier_id): ''' Returns a generator of all assets or potentials of a specific type. Not only the ones defined in the main Instance's Area e.g. QuantityAndUnits can be defined in the KPI of an Area or in the EnergySystemInformation object this function returns all of them at once. The assets are then filtered for having the specified carrier as input. Params: esdl_type (str): The type of asset carrier_id (str | list[str]): The value of the carriers id, e.g. HTLH for network gas Returns: generator of assets or potentials ''' yield from (inst for inst in self.get_all_instances_of_type(esdl_type) if self.has_carrier(inst, carrier_id)) def get_all_instances_of_type_carrier_and_sector(self, esdl_type, sector_id, carrier_id): ''' Returns a generator of all assets or potentials of a specific type. Not only the ones defined in the main Instance's Area e.g. QuantityAndUnits can be defined in the KPI of an Area or in the EnergySystemInformation object this function returns all of them at once. The assets are then filtered for given sectors and carriers. Params: esdl_type (str): The type of asset sector_id (str | list[str]): The value of the sectors id, e.g. REF for Refineries carrier_id (str | list[str]): The value of the carriers id, e.g. HTLH for network gas Returns: generator of assets or potentials ''' yield from (inst for inst in self.get_all_instances_of_type(esdl_type) if self.in_sector(inst, sector_id) and self.has_carrier(inst, carrier_id)) def has_carrier(self, asset, carrier_id): '''Carrier id may also be a list''' for port in asset.port: if not isinstance(port, self.esdl.InPort): continue if port.carrier.id == carrier_id: return True if isinstance(carrier_id, list) and port.carrier.id in carrier_id: return True return False def in_sector(self, asset, sector_id): ''' Returns Boolean depending on if the asset is in the sector or not. Also checks if the assets parents have a sector set, if 'sector' is not an attribute of the asset directly. Params: asset (pyecore.ecore.Object): The asset that is to be checked. sector_id (str | list[str]): The id of the sector, e.g. REF for Refineries. Returns: bool ''' if asset.sector and equal_or_in(asset.sector.id, sector_id): return True for port in asset.port: if not isinstance(port, self.esdl.OutPort): continue for connection in port.connectedTo: if not getattr(connection.energyasset, 'sector', None): continue if equal_or_in(connection.energyasset.sector.id, sector_id): return True return False def get_asset_attribute(self, esdl_type, attr, area=None): ''' Create a readable list of the attributes of an ESDL class Scoped to a specific area, if one is given Returns: list[dict] with formatted assets ''' assets = area.asset if not area is None else self.es.instance[0].area.asset return [self.__format_asset(ass, attr) for ass in assets if isinstance(ass, esdl_type)] def __format_asset(self, current_asset, attribute): return { 'name': current_asset.name, # name 'attribute': { 'key': attribute, 'value': getattr(current_asset, attribute) } } ######### LOAD & SAVE ########## def save(self, filename): ''' Saves the energy system to a file ''' uri = URI(filename) fileresource = self.rset.create_resource(uri) # add the current energy system fileresource.append(self.es) # save the resource fileresource.save() # return the resource return fileresource def get_as_string(self): ''' Returns the current energy system as an XML string Note: does not change the 'active' resource so save() will still save as a file ''' # to use strings as resources, we simulate a string as being a file uri = StringURI('tmp/anyname.esdl') # create the string resource stringresource = self.rset.create_resource(uri) # add the current energy system stringresource.append(self.es) # save the resource stringresource.save() # remove the temporary resource in the resource set self.rset.remove_resource(stringresource) # return the string return uri.getvalue() def get_as_stream(self): ''' Returns the current energy system as a BytesIO stream ''' # to use strings as resources, we simulate a string as being a file uri = StringURI('tmp/anyname.esdl') # create the string resource stringresource = self.rset.create_resource(uri) # add the current energy system stringresource.append(self.es) # save the resource stringresource.save() # remove the temporary resource in the resource set self.rset.remove_resource(stringresource) # return the string return uri.get_stream() @classmethod def from_string(cls, esdl_string): ''' Create a new EnergySystemHandler based on an EnergySystem esdl_string (using UTF-8 encoding) ''' try: handler = EnergySystemHandler() handler.resource = handler.rset.create_resource( StringURI('loadfromstring', esdl_string) ) handler.resource.load() handler.es = handler.resource.contents[0] return handler except Exception as exception: raise EnergysystemParseError('ESDL could not be parsed') from exception
def saveModel(metamodel, model, output): rset = ResourceSet() rset.metamodel_registry[metamodel.nsURI] = metamodel model_resource = rset.create_resource(URI(output)) model_resource.append(model) return model_resource.save()
def save_model(model_root, filename='model.xmi'): """Save model to file.""" rset = ResourceSet() resource = rset.create_resource(URI(filename)) resource.append(model_root) resource.save()
@when(lambda self, parent: self.name) @mapping def createEClass(self: Ecore.EClass, parent: Ecore.EPackage) -> Ecore.EClass: result.name = self.name + 'Copy' result.abstract = self.abstract for attribute in self.eAttributes: result.eStructuralFeatures.append(copyEAttribute(attribute)) parent.eClassifiers.append(self) @mapping def copyEAttribute(self: Ecore.EAttribute) -> Ecore.EAttribute: result.name = self.name + 'Copy' result.lowerBound = self.lowerBound result.upperBound = self.upperBound result.eType = self.eType root = Ecore.EPackage('test') A1 = Ecore.EClass('A1') root.eClassifiers.append(A1) A1.eStructuralFeatures.append(Ecore.EAttribute('name', eType=Ecore.EString)) inPackage = root result = createEPackage(inPackage) rset = ResourceSet() outresource = rset.create_resource(URI('testt.xmi')) outresource.append(result) outresource.save()
class EnergySystemHandler: """Class to handle (load, read, and update) an ESDL Energy System""" def __init__(self, name=None): # create a resourceSet that hold the contents of the esdl.ecore model and the instances we use/create self.rset = ResourceSet() # Assign files with the .esdl extension to the XMLResource instead of default XMI self.rset.resource_factory['esdl'] = lambda uri: XMLResource(uri) # Read the esdl.ecore from the tmp folder esdl_model_resource = self.rset.get_resource( URI('tmp/esdl/esdl.ecore')) esdl_model = esdl_model_resource.contents[0] # print('Namespace: {}'.format(esdl_model.nsURI)) self.rset.metamodel_registry[esdl_model.nsURI] = esdl_model # Create a dynamic model from the loaded esdl.ecore model, which we can use to build Energy Systems self.esdl = DynamicEPackage(esdl_model) # fix python buildin 'from' that is also used in ProfileElement as attribute # use 'start' instead of 'from' when using a ProfileElement alias('start', self.esdl.ProfileElement.findEStructuralFeature('from')) # have a nice __repr__ for some ESDL classes when printing ESDL objects (includes all Assets and EnergyAssets) self.esdl.Item.python_class.__repr__ = lambda x: '{}: ({})'.format( x.name, EnergySystemHandler.attr_to_dict(x)) self.esdl.Carrier.python_class.__repr__ = lambda x: '{}: ({})'.format( x.name, EnergySystemHandler.attr_to_dict(x)) self.esdl.Geometry.python_class.__repr__ = lambda x: '{}: ({})'.format( x.name, EnergySystemHandler.attr_to_dict(x)) self.esdl.QuantityAndUnitType.python_class.__repr__ = lambda x: '{}: ({})'.format( x.id, EnergySystemHandler.attr_to_dict(x)) self.esdl.QuantityAndUnitReference.python_class.__repr__ = lambda x: '{}: ({})'.format( 'QuantityAndUnitReference', EnergySystemHandler.attr_to_dict(x)) self.esdl.KPI.python_class.__repr__ = lambda x: '{}: ({})'.format( x.name, EnergySystemHandler.attr_to_dict(x)) self.esdl.ProfileElement.python_class.__repr__ = lambda x: 'ProfileElement ({})'.format( EnergySystemHandler.attr_to_dict(x)) if name: self.name = name self.load_energy_system(name) # Creates a dict of all the attributes of an ESDL object @staticmethod def attr_to_dict(esdl_object): d = dict() d['esdlType'] = esdl_object.eClass.name for attr in dir(esdl_object): attr_value = esdl_object.eGet(attr) if attr_value is not None: d[attr] = attr_value return d # Creates a uuid: useful for generating unique IDs @staticmethod def generate_uuid(): return str(uuid.uuid4()) def load_energy_system(self, name): # load the ESDL file self.resource = self.rset.get_resource(URI(name)) self.es = self.resource.contents[0] # Add Energy System Information def add_energy_system_information(self): esi = self.esdl.EnergySystemInformation(id='energy_system_information') self.es.energySystemInformation = esi def add_data_source(self, name, description): data_source = self.esdl.DataSource(id='data_source', name=name, description=description) self.es.dataSource = data_source # Add energy system information to the energy system if it is not there yet # Energy System information can be used to globally define the quantity and units of this system, # instead of defining them manually per KPI in each area: this fosters reuse (but is not necessary) def get_quantity_and_units(self): q_and_u = None if self.get_by_id('energy_system_information') is None: self.add_energy_system_information() q_and_u = self.esdl.QuantityAndUnits(id='quantity_and_units') self.es.energySystemInformation.quantityAndUnits = q_and_u else: q_and_u = self.get_by_id('quantity_and_units') return q_and_u # Add Measures object to Energy System def add_measures(self): # Create new Measures object measures = self.esdl.Measures(id='measures') self.es.instance[0].area.measures = measures # Append measure to Measures object def append_measure(self, measure): self.es.instance[0].area.measures.measure.append(measure) # Append asset measure to Measures object def append_asset_to_measure(self, measure, asset): measure.asset.append(asset) self.es.instance[0].area.measures.measure.append(measure) # Add KPIs object to Energy System def add_kpis(self): # create new KPIs object kpis = self.esdl.KPIs(id='kpis', description='KPIs') self.es.instance[0].area.KPIs = kpis # Create new KPI object def create_kpi(self, kpi_type, kpi_id, name, q_and_u): return getattr(self.esdl, kpi_type)(id=kpi_id, name=name, quantityAndUnit=q_and_u) # Add KPI to KPIs object def add_kpi(self, kpi): self.es.instance[0].area.KPIs.kpi.append(kpi) # Get a list of assets of a specific ESDL type in the main instance's area # def get_assets_of_type(self, esdl_type): # assets = [] # # for current_asset in self.es.instance[0].area.asset: # if isinstance(current_asset, esdl_type): # assets.append(current_asset) # return assets # Get a list of assets of a specific ESDL type in the specified area or asset def get_assets_of_type(self, area, esdl_type): assets = [] for current_asset in area.asset: if isinstance(current_asset, esdl_type): assets.append(current_asset) return assets # Get a list of assets of a specific ESDL type in the specified area or asset # filtered by a specified attribute-value combination def get_assets_of_type_and_attribute_value(self, area, esdl_type, attribute, value): assets = [] for current_asset in area.asset: if isinstance(current_asset, esdl_type): if str(getattr(current_asset, attribute)) == value: assets.append(current_asset) return assets # Get a list of potentials of a specific ESDL type in the main instance's area def get_potentials_of_type(self, esdl_type): potentials = [] for current_potential in self.es.instance[0].area.potential: if isinstance(current_potential, esdl_type): potentials.append(current_potential) return potentials # returns a generator of all assets or potentials of a specific type. Not only the ones defined in the main Instance's Area # e.g. QuantityAndUnits can be defined in the KPI of an Area or in the EnergySystemInformation object # this function returns all of them at once def get_all_instances_of_type(self, esdl_type): return esdl_type.allInstances() # Using this function you can query for objects by ID # After loading an ESDL-file, all objects that have an ID defines are stored in resource.uuid_dict automatically # Note: If you add things later to the resource, it won't be added automatically to this dictionary though. # Use get_by_id_slow() for that def get_by_id(self, id): if id in self.resource.uuid_dict: return self.resource.uuid_dict[id] else: return None # This function iterates over all the contents of the Energy System and is much slower than get_by_id() def get_by_id_slow(self, id): for child in self.es.eAllContents(): if hasattr(child, 'id'): if child.id == id: return child # create a readable list of the attributes of an ESDL class def get_asset_attribute(self, esdl_type, attribute): asset_data = [] for current_asset in self.es.instance[0].area.asset: if isinstance(current_asset, esdl_type): asset_data.append({ 'name': current_asset.name, # name 'attribute': { 'key': attribute, 'value': getattr(current_asset, attribute) } }) return asset_data # create a readable list of the attributes of an ESDL class # (scoped to a specific area) def get_asset_attribute(self, area, esdl_type, attribute): asset_data = [] for current_asset in area.asset: if isinstance(current_asset, esdl_type): asset_data.append({ 'name': current_asset.name, # name 'attribute': { 'key': attribute, 'value': getattr(current_asset, attribute) } }) return asset_data # returns a specific KPI by id, see also get_by_id for a faster method def get_kpi_by_id(self, id): for kpi in self.es.instance[0].area.KPIs.kpi: if kpi.id == id: return kpi # returns a specific KPI by name def get_kpi_by_name(self, name): for kpi in self.es.instance[0].area.KPIs.kpi: if kpi.name == name: return kpi # save the resource def save(self, filename): uri = URI(filename) fileresource = self.rset.create_resource(uri) # add the current energy system fileresource.append(self.es) # save the resource fileresource.save() # return the resource return fileresource # get the energy system as a XML String # does not change the 'active' resource # so save() will still save as a file def get_as_string(self): # to use strings as resources, we simulate a string as being a file uri = StringURI('tmp/anyname.esdl') # create the string resource stringresource = self.rset.create_resource(uri) # add the current energy system stringresource.append(self.es) # save the resource stringresource.save() # remove the temporary resource in the resource set self.rset.remove_resource(stringresource) # return the string return uri.getvalue() def get_as_stream(self): # to use strings as resources, we simulate a string as being a file uri = StringURI('tmp/anyname.esdl') # create the string resource stringresource = self.rset.create_resource(uri) # add the current energy system stringresource.append(self.es) # save the resource stringresource.save() # remove the temporary resource in the resource set self.rset.remove_resource(stringresource) # return the string return uri.get_stream() # load an EnergySystem from a string (using UTF-8 encoding) def load_from_string(self, string): uri = StringURI('loadfromstring', string) # this overrides the current loaded resource self.resource = self.rset.create_resource(uri) self.resource.load() self.es = self.resource.contents[0] return self.es
class EnergySystemHandler: def __init__(self, energy_system=None): if energy_system is not None: self.energy_system = energy_system self.resource = None self.rset = ResourceSet() self.esid_uri_dict = {} self._set_resource_factories() # fix python builtin 'from' that is also used in ProfileElement as attribute # use 'start' instead of 'from' when using a ProfileElement # alias('start', esdl.ProfileElement.findEStructuralFeature('from')) esdl.ProfileElement.from_.name = 'from' setattr(esdl.ProfileElement, 'from', esdl.ProfileElement.from_) alias('start', esdl.ProfileElement.from_) esdl.FromToIntItem.from_.name = 'from' setattr(esdl.FromToIntItem, 'from', esdl.FromToIntItem.from_) alias('start', esdl.FromToIntItem.from_) esdl.FromToDoubleItem.from_.name = 'from' setattr(esdl.FromToDoubleItem, 'from', esdl.FromToDoubleItem.from_) alias('start', esdl.FromToDoubleItem.from_) # add support for shallow copying or cloning an object # it copies the object's attributes (e.g. clone an object), does only shallow copying def clone(self): """ Shallow copying or cloning an object It only copies the object's attributes (e.g. clone an object) Usage object.clone() or copy.copy(object) (as _copy__() is also implemented) :param self: :return: A clone of the object """ newone = type(self)() eclass = self.eClass for x in eclass.eAllStructuralFeatures(): if isinstance(x, EAttribute): #logger.trace("clone: processing attribute {}".format(x.name)) if x.many: eOrderedSet = newone.eGet(x.name) for v in self.eGet(x.name): eOrderedSet.append(v) else: newone.eSet(x.name, self.eGet(x.name)) return newone setattr(EObject, '__copy__', clone) setattr(EObject, 'clone', clone) """ Deep copying an EObject. Does not work yet for copying references from other resources than this one. """ def deepcopy(self, memo=None): logger.debug("deepcopy: processing {}".format(self)) first_call = False if memo is None: memo = dict() first_call = True if self in memo: return memo[self] copy: EObject = self.clone() logger.debug("Shallow copy: {}".format(copy)) eclass: EClass = self.eClass for x in eclass.eAllStructuralFeatures(): if isinstance(x, EReference): #logger.debug("deepcopy: processing reference {}".format(x.name)) ref: EReference = x value: EStructuralFeature = self.eGet(ref) if value is None: continue if ref.containment: if ref.many and isinstance(value, EAbstractSet): #clone all containment elements eAbstractSet = copy.eGet(ref.name) for ref_value in value: duplicate = ref_value.__deepcopy__(memo) eAbstractSet.append(duplicate) else: copy.eSet(ref.name, value.__deepcopy__(memo)) #else: # # no containment relation, but a reference # # this can only be done after a full copy # pass # now copy should a full copy, but without cross references memo[self] = copy if first_call: logger.debug("copying references") for k, v in memo.items(): eclass: EClass = k.eClass for x in eclass.eAllStructuralFeatures(): if isinstance(x, EReference): #logger.debug("deepcopy: processing x-reference {}".format(x.name)) ref: EReference = x orig_value: EStructuralFeature = k.eGet(ref) if orig_value is None: continue if not ref.containment: opposite = ref.eOpposite if opposite and opposite.containment: # do not handle eOpposite relations, they are handled automatically in pyEcore continue if x.many: eAbstractSet = v.eGet(ref.name) for orig_ref_value in orig_value: try: copy_ref_value = memo[ orig_ref_value] except KeyError: logger.warning( f'Cannot find reference of type {orig_ref_value.eClass.Name} \ for reference {k.eClass.name}.{ref.name} in deepcopy memo, using original' ) copy_ref_value = orig_ref_value eAbstractSet.append(copy_ref_value) else: try: copy_value = memo[orig_value] except KeyError: logger.warning( f'Cannot find reference of type {orig_value.eClass.name} of \ reference {k.eClass.name}.{ref.name} in deepcopy memo, using original' ) copy_value = orig_value v.eSet(ref.name, copy_value) return copy setattr(EObject, '__deepcopy__', deepcopy) setattr(EObject, 'deepcopy', deepcopy) # show deleted object from memory # setattr(EObject, '__del__', lambda x: print('Deleted {}'.format(x.eClass.name))) # def update_id(n: Notification): # if isinstance(n.feature, EAttribute): # #print(n) # if n.feature.name == 'id': # resource = n.notifier.eResource # if resource is not None and (n.kind != Kind.UNSET and n.kind != Kind.REMOVE): # print('ADDING to UUID dict {}#{}, notification type {}'.format(n.notifier.eClass.name, n.feature.name, n.kind.name)) # resource.uuid_dict[n.new] = n.notifier # if n.old is not None and n.old is not '': # del resource.uuid_dict[n.old] # observer = EObserver() # observer.notifyChanged = update_id # # old_init = EObject.__init__ # def new_init(self, **kwargs): # observer.observe(self) # old_init(self, **kwargs) # # setattr(EObject, '__init__', new_init) # Methods to automatically update the uuid_dict. # Currently disabled, because it does not work in all circumstances # This only works when the object which id is to be added to the dict is already part # of the energysystem xml tree, otherwise there is no way of knowing to which uuid_dict it should be added. # E.g. # > asset = esdl.Asset(id='uuid) # > asset.port.append(esdl.InPort(id='uuid)) # this does not work because asset is not part of the energy system yet # > area.asset.append(asset) #works for asset, but not for port. In order to have port working too, this statement # should be executed bofore adding the port... # old_set = EObject.__setattr__ # def updated_set(self, feature, value): # old_set(self, feature, value) # #if feature == 'id': # #print('Feature :{}#{}, value={}, resource={}'.format(self.eClass.name, feature, value, '?')) # #if isinstance(feature, EReference): # if hasattr(value, 'id') and feature[0] != '_': # print('*****Update uuid_dict {}#{} for {}#id'.format(self.eClass.name, feature, value.eClass.name)) # self.eResource.uuid_dict[value.id] = value # setattr(EObject, '__setattr__', updated_set) # # # # old_append = EAbstractSet.append # def updated_append(self, value, update_opposite=True): # old_append(self, value, update_opposite) # #print('EAbstractSet :{}, value={}, resource={}, featureEr={}'.format(self, value, value.eResource, self.feature.eResource)) # if hasattr(value, 'id'): # if self.feature.eResource: # print('****Update uuid_dict AbstractSet-{}#id'.format(value.eClass.name)) # self.feature.eResource.uuid_dict[value.id] = value # elif value.eResource: # print('****Update uuid_dict AbstractSet-{}#id'.format(value.eClass.name)) # value.eResource.uuid_dict[value.id] = value # # setattr(EAbstractSet, 'append', updated_append) # def toJSON(self): # return json.dumps(self, default=lambda o: list(o), # sort_keys=True, indent=4) # setattr(EOrderedSet, 'toJSON', toJSON) # have a nice __repr__ for some ESDL classes when printing ESDL objects (includes all Assets and EnergyAssets) esdl.EnergySystem.__repr__ = \ lambda x: '{}: ({})'.format(x.name, EnergySystemHandler.attr_to_dict(x)) def _new_resource_set(self): """Resets the resourceset (e.g. when loading a new file)""" self.rset = ResourceSet() self.resource = None self._set_resource_factories() def _set_resource_factories(self): # Assign files with the .esdl extension to the XMLResource instead of default XMI self.rset.resource_factory['esdl'] = XMLResource self.rset.resource_factory['*'] = XMLResource def load_file(self, uri_or_filename): """Loads a EnergySystem file or URI into a new resourceSet :returns EnergySystem the first item in the resourceSet""" if isinstance(uri_or_filename, str): if uri_or_filename[:4] == 'http': uri = HttpURI(uri_or_filename) else: uri = URI(uri_or_filename) else: uri = uri_or_filename return self.load_uri(uri) def import_file(self, uri_or_filename): if isinstance(uri_or_filename, str): if uri_or_filename[:4] == 'http': uri = HttpURI(uri_or_filename) else: uri = URI(uri_or_filename) else: uri = uri_or_filename return self.add_uri(uri) def load_uri(self, uri): """Loads a new resource in a new resourceSet""" self._new_resource_set() self.resource = self.rset.get_resource(uri) # At this point, the model instance is loaded! self.energy_system = self.resource.contents[0] if isinstance(uri, str): self.esid_uri_dict[self.energy_system.id] = uri else: self.esid_uri_dict[self.energy_system.id] = uri.normalize() self.add_object_to_dict(self.energy_system.id, self.energy_system, True) return self.energy_system def add_uri(self, uri): """Adds the specified URI to the resource set, i.e. load extra resources that the resource can refer to.""" tmp_resource = self.rset.get_resource(uri) # At this point, the model instance is loaded! # self.energy_system = self.resource.contents[0] self.validate(es=tmp_resource.contents[0]) if isinstance(uri, str): self.esid_uri_dict[tmp_resource.contents[0].id] = uri else: self.esid_uri_dict[tmp_resource.contents[0].id] = uri.normalize() # Edwin: recursive moet hier toch False zijn?? immers elke resource heeft zijn eigen uuid_dict self.add_object_to_dict(tmp_resource.contents[0].id, tmp_resource.contents[0], True) return tmp_resource.contents[0] def load_from_string(self, esdl_string, name='from_string'): """Loads an energy system from a string and adds it to a *new* resourceSet :returns the loaded EnergySystem """ uri = StringURI(name + '.esdl', esdl_string) self._new_resource_set() self.resource = self.rset.create_resource(uri) try: self.resource.load() self.energy_system = self.resource.contents[0] self.validate() self.esid_uri_dict[self.energy_system.id] = uri.normalize() # Edwin: recursive moet hier toch False zijn?? immers elke resource heeft zijn eigen uuid_dict self.add_object_to_dict(self.energy_system.id, self.energy_system, True) return self.energy_system except Exception as e: logger.error("Exception when loading resource: {}: {}".format( name, e)) raise def load_external_string(self, esdl_string, name='from_string'): """Loads an energy system from a string but does NOT add it to the resourceSet (e.g. as a separate resource) It returns an Energy System, but it is not part of a resource in the ResourceSet """ uri = StringURI(name + '.esdl', esdl_string) external_rset = ResourceSet() external_resource = external_rset.create_resource(uri) external_resource.load() external_energy_system = external_resource.contents[0] self.validate(es=external_energy_system) return external_energy_system def add_from_string(self, name, esdl_string): """Loads an energy system from a string and adds it to the *existing* resourceSet""" uri = StringURI(name + '.esdl', esdl_string) # self.add_uri(uri) tmp_resource = self.rset.get_resource(uri) tmp_es = tmp_resource.contents[0] try: self.validate(es=tmp_es) self.esid_uri_dict[tmp_es.id] = uri.normalize() self.add_object_to_dict(tmp_es.id, tmp_es, True) return tmp_resource.contents[0] except Exception as e: logger.error("Exception when loading resource: {}: {}".format( name, e)) raise def to_string(self, es_id=None): # to use strings as resources, we simulate a string as being a URI uri = StringURI('to_string_' + str(uuid4()) + '.esdl') if es_id is None: self.resource.save(uri) else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] resource = self.rset.resources[my_uri] resource.save(uri) else: # TODO: what to do? original behaviour self.resource.save(uri) # return the string return uri.getvalue() def to_bytesio(self): """Returns a BytesIO stream for the energy system""" uri = StringURI('bytes_io_to_string.esdl') self.resource.save(uri) return uri.get_stream() def save(self, es_id=None, filename=None): """Add the resource to the resourceSet when saving""" if filename is None: if es_id is None: self.resource.save() else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] resource = self.rset.resources[my_uri] resource.save() else: # TODO: what to do? original behaviour self.resource.save() else: uri = URI(filename) fileresource = self.rset.create_resource(uri) if es_id is None: # add the current energy system fileresource.append(self.energy_system) else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] es = self.rset.resources[my_uri].contents[0] fileresource.append(es) else: # TODO: what to do? original behaviour # add the current energy system fileresource.append(self.energy_system) # save the resource fileresource.save() self.rset.remove_resource(fileresource) def save_as(self, filename): """Saves the resource under a different filename""" self.resource.save(output=filename) def save_resourceSet(self): """Saves the complete resourceSet, including additional loaded resources encountered during loading of the initial resource""" for uri, resource in self.rset.resources.items(): logger.info('Saving {}'.format(uri)) resource.save( ) # raises an Error for HTTP URI, but not for CDOHttpURI def get_resource(self, es_id=None): if es_id is None: return self.resource else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] res = self.rset.resources[my_uri] return res else: return None def get_energy_system(self, es_id=None): if es_id is None: return self.energy_system else: if es_id in self.esid_uri_dict: my_uri = self.esid_uri_dict[es_id] es = self.rset.resources[my_uri].contents[0] return es else: return None def remove_energy_system(self, es_id=None): if es_id is None: return else: my_uri = self.esid_uri_dict[es_id] del self.rset.resources[my_uri] del self.esid_uri_dict[es_id] def get_energy_systems(self): es_list = [] # for esid in self.esid_uri_dict: # uri = self.esid_uri_dict[esid] # es_list.append(self.rset.resources[uri]) for key in self.rset.resources.keys(): es_list.append(self.rset.resources[key].contents[0]) return es_list def validate(self, es=None): if es is None and self.energy_system is not None: es = self.energy_system if es is not None: if es.id is None: es.id = str(uuid4()) logger.warning( "Energysystem has no id, generating one: {}".format(es)) else: logger.warning("Can't validate EnergySystem {}".format(es)) # Using this function you can query for objects by ID # After loading an ESDL-file, all objects that have an ID defines are stored in resource.uuid_dict automatically # Note: If you add things later to the resource, it won't be added automatically to this dictionary though. # Use get_by_id_slow() for that def get_by_id(self, es_id, object_id): if object_id in self.get_resource(es_id).uuid_dict: return self.get_resource(es_id).uuid_dict[object_id] else: print('Can\'t find asset for id={} in uuid_dict of the ESDL model'. format(object_id)) print(self.get_resource(es_id).uuid_dict) raise KeyError( 'Can\'t find asset for id={} in uuid_dict of the ESDL model'. format(object_id)) return None def add_object_to_dict(self, es_id: str, esdl_object: EObject, recursive=False): if recursive: for obj in esdl_object.eAllContents(): self.add_object_to_dict(es_id, obj) if hasattr(esdl_object, 'id'): if esdl_object.id is not None: self.get_resource(es_id).uuid_dict[ esdl_object.id] = esdl_object else: print('Id has not been set for object {}({})', esdl_object.eClass.name, esdl_object) def remove_object_from_dict(self, es_id, esdl_object): if hasattr(esdl_object, 'id'): if esdl_object.id is not None: del self.get_resource(es_id).uuid_dict[esdl_object.id] def remove_object_from_dict_by_id(self, es_id, object_id): del self.get_resource(es_id).uuid_dict[object_id] # returns a generator of all assets of a specific type. Not only the ones defined in the main Instance's Area # e.g. QuantityAndUnits can be defined in the KPI of an Area or in the EnergySystemInformation object # this function returns all of them at once # @staticmethod def get_all_instances_of_type(self, esdl_type, es_id): all_instances = list() for esdl_element in self.get_energy_system(es_id=es_id).eAllContents(): if isinstance(esdl_element, esdl_type): all_instances.append(esdl_element) return all_instances #return esdl_type.allInstances() # Creates a dict of all the attributes of an ESDL object, useful for printing/debugging @staticmethod def attr_to_dict(esdl_object): d = dict() d['esdlType'] = esdl_object.eClass.name for attr in dir(esdl_object): attr_value = esdl_object.eGet(attr) if attr_value is not None: d[attr] = attr_value return d # Creates a uuid: useful for generating unique IDs @staticmethod def generate_uuid(): return str(uuid4()) def create_empty_energy_system(self, name, es_description, inst_title, area_title): es_id = str(uuid4()) self.energy_system = esdl.EnergySystem(id=es_id, name=name, description=es_description) uri = StringURI('empty_energysystem.esdl') self.resource = self.rset.create_resource(uri) # add the current energy system self.resource.append(self.energy_system) self.esid_uri_dict[self.energy_system.id] = uri.normalize() instance = esdl.Instance(id=str(uuid4()), name=inst_title) self.energy_system.instance.append(instance) # TODO: check if this (adding scope) solves error???? area = esdl.Area(id=str(uuid4()), name=area_title, scope=esdl.AreaScopeEnum.from_string('UNDEFINED')) instance.area = area # add generated id's to uuid dict self.add_object_to_dict(es_id, self.energy_system) self.add_object_to_dict(es_id, instance) self.add_object_to_dict(es_id, area) return self.energy_system # Support for Pickling when serializing the energy system in a session # The pyEcore classes by default do not allow for simple serialization for Session management in Flask. # Internally Flask Sessions use Pickle to serialize a data structure by means of its __dict__. This does not work. # Furthermore, ESDL can contain cyclic relations. Therefore we serialize to XMI and back if necessary. def __getstate__(self): state = dict() #print('Serialize rset {}'.format(self.rset.resources)) print('Serializing EnergySystem...', end="") state['energySystem'] = self.to_string() print('done') return state def __setstate__(self, state): self.__init__() #print('Deserialize rset {}'.format(self.rset.resources)) print('Deserializing EnergySystem...', end="") self.load_from_string(state['energySystem']) print('done')