Ejemplo n.º 1
0
    def add_objective(self, building):
        """Creates and adds the meter needed by this objective to the building.

        :param building: the building to modify
        :return: None
        """
        try:
            self.get_objective(building)
        except ValueError:
            pass  # the objective is not present
        else:
            raise ValueError(f'Objective for {repr(self)} already exists')

        mode = ef.get_mode(building)
        new_object_dict = {
            ef.convert_format(field, 'field', mode): getattr(self, attr)
            for attr, field in self.field_pairs if getattr(self, attr)
        }
        if self.frequency is None:
            new_object_dict[ef.convert_format('Reporting_Frequency', 'field',
                                              mode)] = 'Hourly'
        if mode == 'idf':
            building.newidfobject(key=ef.convert_format(
                self.class_name, 'class', mode),
                                  **new_object_dict)
        elif mode == 'json':
            # this is equivalent to appending, but e+ uses a dictionary instead of a list
            objectives = building[self.class_name]
            num = len(objectives)
            new_key = f'{self.class_name} {num}'
            assert new_key not in building, f'The building has incorrectly numbered {self.class_name} entries'
            objectives[new_key] = new_object_dict
Ejemplo n.º 2
0
 def get_objective(self, building):
     mode = ef.get_mode(building)
     if mode == 'idf':
         objectives = building.idfobjects[ef.convert_format(
             self.class_name, 'class', mode)]
     elif mode == 'json':
         objectives = building[ef.convert_format(self.class_name, 'class',
                                                 mode)].values()
     else:
         raise ModeError(mode)
     for objective in objectives:
         if self.check_all(objective, mode):
             return objective
     raise ValueError(f'Cannot find the objective for {repr(self)}')
Ejemplo n.º 3
0
    def get(self, building) -> List:
        """Gets the current values of this field from a building

        :param building: the building to retrieve values from
        :return: a list containing the current values of this selector's fields
        """
        mode = ef.get_mode(building)
        objects = self.get_objects(building)
        field_name = ef.convert_format(self.field_name, 'field', mode)
        if mode == 'idf':
            return [getattr(o, field_name) for o in objects]
        if mode == 'json':
            return [o[field_name] for o in objects]
Ejemplo n.º 4
0
    def set(self, building, value) -> None:
        """Sets this field in the building to the provided value

        :param building: the building to modify
        :param value: the value to set this field to
        :return:
        """
        mode = ef.get_mode(building)
        objects = self.get_objects(building)
        field_name = ef.convert_format(self.field_name, 'field', mode)
        if mode == 'idf':
            for o in objects:
                setattr(o, field_name, value)
        if mode == 'json':
            for o in objects:
                assert field_name in o, f'{field_name} not in {repr(o)}'
                o[field_name] = value
Ejemplo n.º 5
0
    def check_all(self, objective, mode):
        if mode == 'idf':

            def get(attribute):
                return getattr(objective, attribute)
        elif mode == 'json':

            def get(attribute):
                return objective[attribute]
        else:
            raise ModeError(mode)
        for self_attr, objective_attr in self.field_pairs:
            self_value = getattr(self, self_attr)
            objective_value = get(
                ef.convert_format(objective_attr, 'field', mode))
            if self_value is not None and objective_value != self_value:
                return False
        return True
Ejemplo n.º 6
0
 def find(prefix):
     return {
         x
         for x in building_items
         if x.startswith(ef.convert_format(prefix, 'class', mode))
     }
Ejemplo n.º 7
0
    def get_objects(self, building) -> List:
        """Retrieves the objects that this selector will affect from the building.

        :param building: the building to search
        :return: a list of the objects found
        """
        mode = ef.get_mode(building)
        if mode == 'idf':
            if self.class_name is not None:
                class_name = ef.convert_format(self.class_name, 'class', 'idf')
            else:
                class_name = None
            if self.object_name == '*':
                if class_name is None:
                    raise TypeError(
                        "When object_name='*', class_name must be specified.")
                return building.idfobjects[class_name]
            if self.object_name and class_name:
                # this is probably the most reliable way to select an idfObject.
                return [
                    building.getobject(key=class_name, name=self.object_name)
                ]
            if self.object_name:
                # There should only one object matching the name, assuming the idf is valid
                return [
                    eppySupport.get_idfobject_from_name(
                        building, self.object_name)
                ]
            if class_name is not None:
                # assume that we want the first object matching the key
                # TODO: is this specific enough, or should we remove it? our JSON code does not support this
                return [building.idfobjects[class_name][0]]
            else:  # we have neither object_name nor class_name
                raise TypeError(
                    'Either class_name or object_name must be specified.')
        elif mode == 'json':
            if self.object_name == '*':
                if not self.class_name:
                    raise TypeError(
                        "When object_name='*', class_name must be specified.")
                return list(building[self.class_name].values())
            if self.object_name and self.class_name:
                # this is probably the most reliable way to select an idfObject.
                return [building[self.class_name][self.object_name]]
            if self.object_name:
                # There should only one object matching the name, assuming the building is valid
                result = [
                    obj for objs in building.values()
                    for name, obj in objs.items() if name == self.object_name
                ]
                if len(result) != 1:
                    warnings.warn(
                        f'found {len(result)} objects with object_name: {self.object_name}, expected 1'
                    )
                return result
            if self.class_name:
                result = list(building[self.class_name].items())
                if len(result) == 1:
                    return result
                raise ValueError(
                    f'multiple objects with class_name {self.class_name}.'
                    f'Cannot guarantee a reliable ordering')
            else:  # we have neither object_name nor class_name
                raise TypeError(
                    'Either class_name or object_name must be specified.')
        raise ModeError(mode)