def update_system(self, entity, time): logger.info( f"{entity._name} ({entity.__class__.__name__}) with dt of {time}") original_port_values = {t: t.value for t in get_all_ports(entity)} original_states = { e: (e.current if hasattr(e, "current") else None) for e in get_all_entities(entity) } # backup subentity-inputs' and outputs' pre values for sub in get_entities(entity): for _in in get_inputs(sub): _in.pre = _in.value for _out in get_outputs(sub): _out.pre = _out.value # and local pre values for local in get_locals(entity): local.pre = local.value self._update_fp(entity, time, original_states, original_port_values, first=True) # we return whether the entity's outputs changed so we know whether the parent has to re-calculate the updates output_changed = [ original_port_values[p] != p.value for p in get_outputs(entity) ] logger.info( f"finished {entity._name} ({entity.__class__.__name__}) with dt of {time}" ) return any(output_changed)
def check_current_states(self): """Assert that each entity has a current state that is one of the states of the entity.""" for entity in crest.get_all_entities(self.model): if len(crest.get_states(entity)) > 0: assert entity.current is not None, f"Entity {entity._name} has no current state" assert isinstance(entity.current, crest.State), f"Entity's current state '{entity._name}' is not a crest.State" assert entity.current in crest.get_states(entity)
def reset_subentity(self, entity, state_map, port_value_map): logger.debug( f"Resetting entity {entity._name} ({entity.__class__.__name__})") for ent in get_all_entities(entity): if ent in state_map and state_map[ent] is not None: ent.current = state_map[ent] for port in get_all_ports(entity): if port not in get_inputs(entity): # don't reset the input values port.value = port_value_map[port]
def save_entity(self, root_entity, timestamp): data = {"timestamp": timestamp} data.update({ entity: entity.current for entity in get_all_entities(root_entity) }) data.update({port: port.value for port in get_all_ports(root_entity)}) # print(self.data.shape) # try: self._data.append(data)
def test_entity_hierarchy(self): """ Assert that - each entity has only appears once in the children of another entity - there is exactly one entity - the root - that has no parent """ all_entities = crest.get_all_entities(self.model) for entity in all_entities: is_child_of = [(entity in api.get_children(ent)) for ent in all_entities] assert is_child_of.count(True) <= 1, f"Entity {entity._name} is child of multiple entities" has_parent = [entity._parent is None for entity in all_entities] assert has_parent.count(True) == 1, "There is more than one entity with no parent (i.e. more than one root)"
def calculate_system(self, entity=None, include_subentities=True): logger.debug("Calculating for all entities") if not entity: entity = self.entity entities_to_calculate = get_all_entities( entity) if include_subentities else [entity] all_entities_values = [] for e in entities_to_calculate: all_entities_values.extend(self.calculate_individual_entity( e)) # expect to get a flat list... return all_entities_values
def save(self): """Creates two maps, one with <entity: current>, the other one with <port, value>""" current_states = { entity: entity.current for entity in model.get_all_entities(self.system) } self.states.update(current_states) port_values = { port: port.value for port in model.get_all_ports(self.system) } self.ports.update(port_values) pre_values = { port: port.pre for port in model.get_all_ports(self.system) if hasattr(port, "pre") } self.pre.update(pre_values) return self # to be able to do state = CrestState(system).save()