Esempio n. 1
0
def export_fmu(model_path, file_name):
    '''Parse signal exchange blocks and export boptest fmu and kpi json.

    Parameters
    ----------
    model_path : str
        Path to orginal modelica model
    file_name : list
        Path(s) to modelica file and required libraries not on MODELICAPATH.
        Passed to file_name parameter of pymodelica.compile_fmu() in JModelica.

    Returns
    -------
    fmu_path : str
        Path to the wrapped modelica model fmu
    kpi_path : str
        Path to kpi json

    '''

    # Get signal exchange instances and kpi signals
    instances, signals = parse_instances(model_path, file_name)
    # Write wrapper and export as fmu
    fmu_path, _ = write_wrapper(model_path, file_name, instances)
    # Write kpi json
    kpi_path = os.path.join(os.getcwd(), 'kpis.json')
    with open(kpi_path, 'w') as f:
        json.dump(signals, f)
    # Generate test case data
    man = Data_Manager()
    man.save_data_and_kpisjson(fmu_path=fmu_path)

    return fmu_path, kpi_path
Esempio n. 2
0
    def __init__(self):
        '''Constructor.

        '''

        # Get configuration information
        con = config.get_config()
        # Define name
        self.name = con['name']
        # Define simulation model
        self.fmupath = con['fmupath']
        # Load fmu
        self.fmu = load_fmu(self.fmupath)
        self.fmu.set_log_level(7)
        # Get version and check is 2.0
        self.fmu_version = self.fmu.get_version()
        if self.fmu_version != '2.0':
            raise ValueError('FMU must be version 2.0.')
        # Instantiate a data manager for this test case
        self.data_manager = Data_Manager(testcase=self)
        # Load data and the kpis_json for the test case
        self.data_manager.load_data_and_jsons()
        # Instantiate a forecaster for this test case
        self.forecaster = Forecaster(testcase=self)
        # Get available control inputs and outputs
        self.input_names = self.fmu.get_model_variables(causality=2).keys()
        self.output_names = self.fmu.get_model_variables(causality=3).keys()
        # Get input and output meta-data
        self.inputs_metadata = self._get_var_metadata(self.fmu,
                                                      self.input_names,
                                                      inputs=True)
        self.outputs_metadata = self._get_var_metadata(self.fmu,
                                                       self.output_names)
        # Set default communication step
        self.set_step(con['step'])
        # Set default forecast parameters
        self.set_forecast_parameters(con['horizon'], con['interval'])
        # Initialize simulation data arrays
        self.__initilize_data()
        # Set default fmu simulation options
        self.options = self.fmu.simulate_options()
        self.options['CVode_options']['rtol'] = 1e-6
        self.options['CVode_options']['store_event_points'] = False
        # Results filtering for pyfmi
        self.options['filter'] = self.output_names + self.input_names
        # Assign initial testing time
        self.initial_time = 0
        # Set initial fmu simulation start
        self.start_time = 0
        self.initialize_fmu = True
        self.options['initialize'] = self.initialize_fmu
        self.elapsed_control_time = []
        # Instantiate a KPI calculator for the test case
        self.cal = KPI_Calculator(testcase=self)
        # Set default scenario
        self.set_scenario(con['scenario'])
Esempio n. 3
0
 def __init__(self):
     '''Constructor.
     
     '''
     
     # Get configuration information
     con = config.get_config()
     # Define simulation model
     self.fmupath = con['fmupath']
     # Load fmu
     self.fmu = load_fmu(self.fmupath, enable_logging=True)
     # Get version and check is 2.0
     self.fmu_version = self.fmu.get_version()
     if self.fmu_version != '2.0':
         raise ValueError('FMU must be version 2.0.')
     # Instantiate a data manager for this test case
     self.data_manager = Data_Manager(testcase=self)
     # Load data and the kpis_json for the test case
     self.data_manager.load_data_and_kpisjson()
     # Instantiate a forecaster for this test case
     self.forecaster = Forecaster(testcase=self)
     # Instantiate a KPI calculator for the test case
     self.cal = KPI_Calculator(testcase=self)
     # Get available control inputs and outputs
     input_names = self.fmu.get_model_variables(causality = 2).keys()
     output_names = self.fmu.get_model_variables(causality = 3).keys()
     # Get input and output meta-data
     self.inputs_metadata = self._get_var_metadata(self.fmu, input_names, inputs=True)
     self.outputs_metadata = self._get_var_metadata(self.fmu, output_names)
     # Define outputs data
     self.y = {'time':[]}
     for key in output_names:
         self.y[key] = []
     self.y_store = copy.deepcopy(self.y)
     # Define inputs data
     self.u = {'time':[]}
     for key in input_names:
         self.u[key] = []
     self.u_store = copy.deepcopy(self.u)
     # Set default options
     self.options = self.fmu.simulate_options()
     self.options['CVode_options']['rtol'] = 1e-6 
     # Set default communication step
     self.set_step(con['step'])
     # Set default forecast parameters
     self.set_forecast_parameters(con['horizon'], con['interval'])
     # Set initial simulation start
     self.start_time = 0
     self.initialize = True
     self.options['initialize'] = self.initialize
     self.elapsed_control_time = []
Esempio n. 4
0
def lambda_handler(event, context):
    data = Data_Manager()
    message = data.load_random_message()
    print(str(today))

    # Get holiday message. Returns None if it is not a holiday
    if (holiday_message := data.get_holiday_msg()) is not None:
        print("It's a holiday week.")
        if today is trashday:
            print("It's Thursday: sending message that it is not trashday")
            notify_recipients(data.recipients, Template(holiday_message))
        elif today is trashday_holiday:
            print("It's Friday: sending message it is trashday (holiday)")
            notify_recipients(data.recipients, Template(message), data.joke)
Esempio n. 5
0
class TestCase(object):
    '''Class that implements the test case.
    
    '''
    
    def __init__(self):
        '''Constructor.
        
        '''
        
        # Get configuration information
        con = config.get_config()
        # Define simulation model
        self.fmupath = con['fmupath']
        # Load fmu
        self.fmu = load_fmu(self.fmupath, enable_logging=True)
        # Get version and check is 2.0
        self.fmu_version = self.fmu.get_version()
        if self.fmu_version != '2.0':
            raise ValueError('FMU must be version 2.0.')
        # Instantiate a data manager for this test case
        self.data_manager = Data_Manager(testcase=self)
        # Load data and the kpis_json for the test case
        self.data_manager.load_data_and_kpisjson()
        # Instantiate a forecaster for this test case
        self.forecaster = Forecaster(testcase=self)
        # Instantiate a KPI calculator for the test case
        self.cal = KPI_Calculator(testcase=self)
        # Get available control inputs and outputs
        input_names = self.fmu.get_model_variables(causality = 2).keys()
        output_names = self.fmu.get_model_variables(causality = 3).keys()
        # Get input and output meta-data
        self.inputs_metadata = self._get_var_metadata(self.fmu, input_names, inputs=True)
        self.outputs_metadata = self._get_var_metadata(self.fmu, output_names)
        # Define outputs data
        self.y = {'time':[]}
        for key in output_names:
            self.y[key] = []
        self.y_store = copy.deepcopy(self.y)
        # Define inputs data
        self.u = {'time':[]}
        for key in input_names:
            self.u[key] = []
        self.u_store = copy.deepcopy(self.u)
        # Set default options
        self.options = self.fmu.simulate_options()
        self.options['CVode_options']['rtol'] = 1e-6 
        # Set default communication step
        self.set_step(con['step'])
        # Set default forecast parameters
        self.set_forecast_parameters(con['horizon'], con['interval'])
        # Set initial simulation start
        self.start_time = 0
        self.initialize = True
        self.options['initialize'] = self.initialize
        self.elapsed_control_time = []
        
    def advance(self,u):
        '''Advances the test case model simulation forward one step.
        
        Parameters
        ----------
        u : dict
            Defines the control input data to be used for the step.
            {<input_name> : <input_value>}
            
        Returns
        -------
        y : dict
            Contains the measurement data at the end of the step.
            {<measurement_name> : <measurement_value>}
            
        '''
        
        # Calculate and store the elapsed time 
        if hasattr(self, 'tic_time'):
            self.tac_time = time.time()
            self.elapsed_control_time.append(self.tac_time-self.tic_time)
            
        # Set final time
        self.final_time = self.start_time + self.step
        # Set control inputs if they exist and are written
        # Check if possible to overwrite
        if u.keys():
            # If there are overwriting keys available
            # Check that any are overwritten
            written = False
            for key in u.keys():
                if u[key]:
                    written = True
                    break
            # If there are, create input object
            if written:
                u_list = []
                u_trajectory = self.start_time
                for key in u.keys():
                    if key != 'time' and u[key]:
                        value = float(u[key])
                        # Check min/max if not activation input
                        if '_activate' not in key:
                            checked_value = self._check_value_min_max(key, value)
                        else:
                            checked_value = value
                        u_list.append(key)
                        u_trajectory = np.vstack((u_trajectory, checked_value))
                input_object = (u_list, np.transpose(u_trajectory))
            # Otherwise, input object is None
            else:
                input_object = None    
        # Otherwise, input object is None
        else:
            input_object = None
        # Simulate
        self.options['initialize'] = self.initialize
        res = self.fmu.simulate(start_time=self.start_time, 
                                final_time=self.final_time, 
                                options=self.options, 
                                input=input_object)
        # Get result and store measurement
        for key in self.y.keys():
            self.y[key] = res[key][-1]
            self.y_store[key] = self.y_store[key] + res[key].tolist()[1:]
        # Store control inputs
        for key in self.u.keys():
            self.u_store[key] = self.u_store[key] + res[key].tolist()[1:] 
        # Advance start time
        self.start_time = self.final_time
        # Prevent inialize
        self.initialize = False
        # Raise the flag to compute time lapse
        self.tic_time = time.time()
        
        return self.y

    def reset(self):
        '''Reset the test.
        
        '''
        
        self.__init__()

    def get_step(self):
        '''Returns the current simulation step in seconds.'''

        return self.step

    def set_step(self,step):
        '''Sets the simulation step in seconds.
        
        Parameters
        ----------
        step : int
            Simulation step in seconds.
            
        Returns
        -------
        None
        
        '''
        
        self.step = float(step)
        
        return None
        
    def get_inputs(self):
        '''Returns a dictionary of control inputs and their meta-data.
        
        Parameters
        ----------
        None
        
        Returns
        -------
        inputs : dict
            Dictionary of control inputs and their meta-data.
            
        '''

        inputs = self.inputs_metadata
        
        return inputs
        
    def get_measurements(self):
        '''Returns a dictionary of measurements and their meta-data.
        
        Parameters
        ----------
        None
        
        Returns
        -------
        measurements : dict
            Dictionary of measurements and their meta-data.
            
        '''

        measurements = self.outputs_metadata
        
        return measurements
        
    def get_results(self):
        '''Returns measurement and control input trajectories.
        
        Parameters
        ----------
        None
        
        Returns
        -------
        Y : dict
            Dictionary of measurement and control input names and their 
            trajectories as lists.
            {'y':{<measurement_name>:<measurement_trajectory>},
             'u':{<input_name>:<input_trajectory>}
            }
        
        '''
        
        Y = {'y':self.y_store, 'u':self.u_store}
        
        return Y
        
    def get_kpis(self):
        '''Returns KPI data.
        
        Requires standard sensor signals.
        
        Parameters
        ----------
        None
        
        Returns
        -------
        kpis : dict
            Dictionary containing KPI names and values.
            {<kpi_name>:<kpi_value>}
        
        '''
        
        # Calculate the core kpis 

        kpis = self.cal.get_core_kpis()

        return kpis

    def set_forecast_parameters(self,horizon,interval):
        '''Sets the forecast horizon and interval, both in seconds.
        
        Parameters
        ----------
        horizon : int
            Forecast horizon in seconds.
        interval : int
            Forecast interval in seconds.
            
        Returns
        -------
        None
        
        '''
        
        self.horizon = float(horizon)
        self.interval = float(interval)
        
        return None
    
    def get_forecast_parameters(self):
        '''Returns the current forecast horizon and interval parameters.'''
        
        forecast_parameters = dict()
        forecast_parameters['horizon'] = self.horizon
        forecast_parameters['interval'] = self.interval
        
        return forecast_parameters

    def get_forecast(self):
        '''Returns the test case data forecast
        
        Parameters
        ----------
        None
        
        Returns
        -------
        forecast : dict 
            Dictionary with the requested forecast data
            {<variable_name>:<variable_forecast_trajectory>}
            where <variable_name> is a string with the variable
            key and <variable_forecast_trajectory> is a list with
            the forecasted values. 'time' is included as a variable
        
        '''
        
        # Get the forecast
        forecast = self.forecaster.get_forecast(horizon=self.horizon,
                                                interval=self.interval)
        
        return forecast
        
    def get_name(self):
        '''Returns the name of the test case fmu.
        
        Parameters
        ----------
        None
        
        Returns
        -------
        name : str
            Name of test case fmu.
            
        '''
        
        name = self.fmupath[7:-4]
        
        return name
        
    def get_elapsed_control_time(self):
        '''Returns the elapsed control time vector for the case.
        
        Parameters
        ----------
        None
        
        Returns
        -------
        elapsed_control_time : list of floats
            elapsed_control_time for each control step.
            
        '''
        
        elapsed_control_time = self.elapsed_control_time
        
        return elapsed_control_time
        
    def _get_var_metadata(self, fmu, var_list, inputs=False):
        '''Build a dictionary of variables and their metadata.
        
        Parameters
        ----------
        fmu : pyfmi fmu object
            FMU from which to get variable metadata
        var_list : list of str
            List of variable names
            
        Returns
        -------
        var_metadata : dict
            Dictionary of variable names as keys and metadata as fields.
            {<var_name_str> :
                "Unit" : str,
                "Description" : str,
                "Minimum" : float,
                "Maximum" : float
            }
            
        '''
        
        # Inititalize
        var_metadata = dict()
        # Get metadata        
        for var in var_list:
            # Units
            if var == 'time':
                unit = 's'
                description = 'Time of simulation'
                mini = None
                maxi = None
            elif '_activate' in var:
                unit = None
                description = fmu.get_variable_description(var)
                mini = None
                maxi = None
            else:
                unit = fmu.get_variable_unit(var)
                description = fmu.get_variable_description(var)
                if inputs:
                    mini = fmu.get_variable_min(var)
                    maxi = fmu.get_variable_max(var)
                else:
                    mini = None
                    maxi = None
            var_metadata[var] = {'Unit':unit,
                                 'Description':description,
                                 'Minimum':mini,
                                 'Maximum':maxi}

        return var_metadata
        
    def _check_value_min_max(self, var, value):
        '''Check that the input value does not violate the min or max.
        
        Note that if it does, the value is truncated to the minimum or maximum.
        
        Parameters
        ----------
        var : str
            Name of variable
        value : numeric
            Specified value of variable
            
        Return
        ------
        checked_value : float
            Value of variable truncated by min and max.
            
        '''
        
        # Get minimum and maximum for variable
        mini = self.inputs_metadata[var]['Minimum']
        maxi = self.inputs_metadata[var]['Maximum']
        # Check the value and truncate if necessary
        if value > maxi:
            checked_value = maxi
            print('WARNING: Value of {0} for {1} is above maximum of {2}.  Using {2}.'.format(value, var, maxi))
        elif value < mini:
            checked_value = mini
            print('WARNING: Value of {0} for {1} is below minimum of {2}.  Using {2}.'.format(value, var, mini))
        else:
            checked_value = value

        return checked_value
            
Esempio n. 6
0
class TestCase(object):
    '''Class that implements the test case.

    '''
    def __init__(self):
        '''Constructor.

        '''

        # Get configuration information
        con = config.get_config()
        # Define name
        self.name = con['name']
        # Define simulation model
        self.fmupath = con['fmupath']
        # Load fmu
        self.fmu = load_fmu(self.fmupath)
        self.fmu.set_log_level(7)
        # Get version and check is 2.0
        self.fmu_version = self.fmu.get_version()
        if self.fmu_version != '2.0':
            raise ValueError('FMU must be version 2.0.')
        # Instantiate a data manager for this test case
        self.data_manager = Data_Manager(testcase=self)
        # Load data and the kpis_json for the test case
        self.data_manager.load_data_and_jsons()
        # Instantiate a forecaster for this test case
        self.forecaster = Forecaster(testcase=self)
        # Get available control inputs and outputs
        self.input_names = self.fmu.get_model_variables(causality=2).keys()
        self.output_names = self.fmu.get_model_variables(causality=3).keys()
        # Get input and output meta-data
        self.inputs_metadata = self._get_var_metadata(self.fmu,
                                                      self.input_names,
                                                      inputs=True)
        self.outputs_metadata = self._get_var_metadata(self.fmu,
                                                       self.output_names)
        # Set default communication step
        self.set_step(con['step'])
        # Set default forecast parameters
        self.set_forecast_parameters(con['horizon'], con['interval'])
        # Initialize simulation data arrays
        self.__initilize_data()
        # Set default fmu simulation options
        self.options = self.fmu.simulate_options()
        self.options['CVode_options']['rtol'] = 1e-6
        self.options['CVode_options']['store_event_points'] = False
        # Results filtering for pyfmi
        self.options['filter'] = self.output_names + self.input_names
        # Assign initial testing time
        self.initial_time = 0
        # Set initial fmu simulation start
        self.start_time = 0
        self.initialize_fmu = True
        self.options['initialize'] = self.initialize_fmu
        self.elapsed_control_time = []
        # Instantiate a KPI calculator for the test case
        self.cal = KPI_Calculator(testcase=self)
        # Set default scenario
        self.set_scenario(con['scenario'])

    def __initilize_data(self):
        '''Initializes objects for simulation data storage.

        Uses self.output_names and self.input_names to create
        self.y, self.y_store, self.u, and self.u_store.

        Parameters
        ----------
        None

        Returns
        -------
        None

        '''

        # Outputs data
        self.y = {'time': np.array([])}
        for key in self.output_names:
            self.y[key] = np.array([])
        self.y_store = copy.deepcopy(self.y)
        # Inputs data
        self.u = {'time': np.array([])}
        for key in self.input_names:
            self.u[key] = np.array([])
        self.u_store = copy.deepcopy(self.u)

    def __simulation(self, start_time, end_time, input_object=None):
        '''Simulates the FMU using the pyfmi fmu.simulate function.

        Parameters
        ----------
        start_time: int
            Start time of simulation in seconds.
        final_time: int
            Final time of simulation in seconds.
        input_object: pyfmi input_object, optional
            Input object for simulation
            Default is None

        Returns
        -------
        res: pyfmi results object
            Results of the fmu simulation.

        '''

        # Set fmu initialization option
        self.options['initialize'] = self.initialize_fmu
        # Set sample rate
        self.options['ncp'] = int((end_time - start_time) / 30)
        # Simulate fmu
        try:
            res = self.fmu.simulate(start_time=start_time,
                                    final_time=end_time,
                                    options=self.options,
                                    input=input_object)
        except Exception as e:
            return None
        # Set internal fmu initialization
        self.initialize_fmu = False

        return res

    def __get_results(self, res, store=True, store_initial=False):
        '''Get results at the end of a simulation and throughout the
        simulation period for storage. This method assigns these results
        to `self.y` and, if `store=True`, also to `self.y_store` and
        to `self.u_store`.
        This method is used by `initialize()` and `advance()` to retrieve
        results. `initialize()` does not store results whereas `advance()`
        does.

        Parameters
        ----------
        res: pyfmi results object
            Results of the fmu simulation.
        store: boolean
            Set to true if desired to store results in `self.y_store` and
            `self.u_store`
        store_initial: boolean
            Set to true if desired to store initial point.

        '''

        # Determine if store initial point
        if store_initial:
            i = 0
        else:
            i = 1
        # Get result and store measurement
        for key in self.y.keys():
            self.y[key] = res[key][-1]
            if store:
                self.y_store[key] = np.append(self.y_store[key], res[key][i:])

        # Store control inputs
        if store:
            for key in self.u.keys():
                self.u_store[key] = np.append(self.u_store[key], res[key][i:])

    def advance(self, u):
        '''Advances the test case model simulation forward one step.

        Parameters
        ----------
        u : dict
            Defines the control input data to be used for the step.
            {<input_name> : <input_value>}

        Returns
        -------
        y : dict
            Contains the measurement data at the end of the step.
            {<measurement_name> : <measurement_value>}
            If empty, simulation end time has been reached.

        '''

        # Calculate and store the elapsed time
        if hasattr(self, 'tic_time'):
            self.tac_time = time.time()
            self.elapsed_control_time.append(self.tac_time - self.tic_time)

        # Set final time
        self.final_time = self.start_time + self.step
        # Set control inputs if they exist and are written
        # Check if possible to overwrite
        if u.keys():
            # If there are overwriting keys available
            # Check that any are overwritten
            written = False
            for key in u.keys():
                if u[key]:
                    written = True
                    break
            # If there are, create input object
            if written:
                u_list = []
                u_trajectory = self.start_time
                for key in u.keys():
                    if key != 'time' and u[key]:
                        value = float(u[key])
                        # Check min/max if not activation input
                        if '_activate' not in key:
                            checked_value = self._check_value_min_max(
                                key, value)
                        else:
                            checked_value = value
                        u_list.append(key)
                        u_trajectory = np.vstack((u_trajectory, checked_value))
                input_object = (u_list, np.transpose(u_trajectory))
            # Otherwise, input object is None
            else:
                input_object = None
        # Otherwise, input object is None
        else:
            input_object = None
        # Simulate if not end of test
        if self.start_time < self.end_time:
            # Make sure stop at end of test
            if self.final_time > self.end_time:
                self.final_time = self.end_time
            res = self.__simulation(self.start_time, self.final_time,
                                    input_object)
            # Process results
            if res is not None:
                # Get result and store measurement and control inputs
                self.__get_results(res, store=True, store_initial=False)
                # Advance start time
                self.start_time = self.final_time
                # Raise the flag to compute time lapse
                self.tic_time = time.time()

                return self.y

            else:
                # Error in simulation
                return None
        else:
            # Simulation at end time
            return dict()

    def initialize(self, start_time, warmup_period, end_time=np.inf):
        '''Initialize the test simulation.

        Parameters
        ----------
        start_time: int
            Start time of simulation to initialize to in seconds.
        warmup_period: int
            Length of time before start_time to simulate for warmup in seconds.
        end_time: int, optional
            Specifies a finite end time to allow simulation to continue
            Default value is infinite.

        Returns
        -------
        y : dict
            Contains the measurement data at the end of the initialization.
            {<measurement_name> : <measurement_value>}

        '''

        # Reset fmu
        self.fmu.reset()
        # Reset simulation data storage
        self.__initilize_data()
        self.elapsed_control_time = []
        # Record initial testing time
        self.initial_time = start_time
        # Record end testing time
        self.end_time = end_time
        # Set fmu intitialization
        self.initialize_fmu = True
        # Simulate fmu for warmup period.
        # Do not allow negative starting time to avoid confusions
        res = self.__simulation(max(start_time - warmup_period, 0), start_time)
        # Process result
        if res is not None:
            # Get result
            self.__get_results(res, store=True, store_initial=True)
            # Set internal start time to start_time
            self.start_time = start_time
            # Initialize KPI Calculator
            self.cal.initialize()
            return self.y

        else:

            return None

    def get_step(self):
        '''Returns the current simulation step in seconds.'''

        return self.step

    def set_step(self, step):
        '''Sets the simulation step in seconds.

        Parameters
        ----------
        step : int
            Simulation step in seconds.

        Returns
        -------
        None

        '''

        self.step = float(step)

        return None

    def get_inputs(self):
        '''Returns a dictionary of control inputs and their meta-data.

        Parameters
        ----------
        None

        Returns
        -------
        inputs : dict
            Dictionary of control inputs and their meta-data.

        '''

        inputs = self.inputs_metadata

        return inputs

    def get_measurements(self):
        '''Returns a dictionary of measurements and their meta-data.

        Parameters
        ----------
        None

        Returns
        -------
        measurements : dict
            Dictionary of measurements and their meta-data.

        '''

        measurements = self.outputs_metadata

        return measurements

    def get_results(self, var, start_time, final_time):
        '''Returns measurement and control input trajectories.

        Parameters
        ----------
        var : str
            Name of variable.
        start_time : float
            Start time of data to return in seconds.
        final_time : float
            Start time of data to return in seconds.

        Returns
        -------
        Y : dict or None
            Dictionary of variable trajectories with time as lists.
            {'time':[<time_data>],
             'var':[<var_data>]
            }
            Returns None if no variable can be found

        '''

        # Get correct point
        if var in self.y_store.keys():
            Y = {'time': self.y_store['time'], var: self.y_store[var]}
        elif var in self.u_store.keys():
            Y = {'time': self.u_store['time'], var: self.u_store[var]}
        else:
            Y = None
            return Y

        # Get correct time
        time1 = Y['time']
        for key in [var, 'time']:
            Y[key] = Y[key][time1 >= start_time]
            time2 = time1[time1 >= start_time]
            Y[key] = Y[key][time2 <= final_time]

        return Y

    def get_kpis(self):
        '''Returns KPI data.

        Requires standard sensor signals.

        Parameters
        ----------
        None

        Returns
        -------
        kpis : dict
            Dictionary containing KPI names and values.
            {<kpi_name>:<kpi_value>}

        '''

        # Set correct price scenario for cost
        if self.scenario['electricity_price'] == 'constant':
            price_scenario = 'Constant'
        elif self.scenario['electricity_price'] == 'dynamic':
            price_scenario = 'Dynamic'
        elif self.scenario['electricity_price'] == 'highly_dynamic':
            price_scenario = 'HighlyDynamic'
        # Calculate the core kpis
        kpis = self.cal.get_core_kpis(price_scenario=price_scenario)

        return kpis

    def set_forecast_parameters(self, horizon, interval):
        '''Sets the forecast horizon and interval, both in seconds.

        Parameters
        ----------
        horizon : int
            Forecast horizon in seconds.
        interval : int
            Forecast interval in seconds.

        Returns
        -------
        None

        '''

        self.horizon = float(horizon)
        self.interval = float(interval)

        return None

    def get_forecast_parameters(self):
        '''Returns the current forecast horizon and interval parameters.'''

        forecast_parameters = dict()
        forecast_parameters['horizon'] = self.horizon
        forecast_parameters['interval'] = self.interval

        return forecast_parameters

    def get_forecast(self):
        '''Returns the test case data forecast

        Parameters
        ----------
        None

        Returns
        -------
        forecast : dict
            Dictionary with the requested forecast data
            {<variable_name>:<variable_forecast_trajectory>}
            where <variable_name> is a string with the variable
            key and <variable_forecast_trajectory> is a list with
            the forecasted values. 'time' is included as a variable

        '''

        # Get the forecast
        forecast = self.forecaster.get_forecast(horizon=self.horizon,
                                                interval=self.interval)

        return forecast

    def set_scenario(self, scenario):
        '''Sets the case scenario.

        Parameters
        ----------
        scenario : dict
            {'electricity_price': <'constant' or 'dynamic' or 'highly_dynamic'>,
             'time_period': see available keys for test case
             }
            If any value is None, it will not change existing.

        Returns
        -------
        result : dict
            {'electricity_price': if succeeded in changing then True, else None,
             'time_period': if succeeded then initial measurements, else None
             }
        '''

        result = {'electricity_price': None, 'time_period': None}

        if not hasattr(self, 'scenario'):
            self.scenario = {}
        # Handle electricity price
        if scenario['electricity_price']:
            try:
                self.scenario['electricity_price'] = scenario[
                    'electricity_price']
                result['electricity_price'] = True
            except Exception as e:
                pass
        # Handle timeperiod
        if scenario['time_period']:
            try:
                self.scenario['time_period'] = scenario['time_period']
                warmup_period = 7 * 24 * 3600
                key = self.scenario['time_period']
                start_time = self.days_json[key] * 24 * 3600 - 7 * 24 * 3600
                end_time = start_time + 14 * 24 * 3600
                result['time_period'] = self.initialize(start_time,
                                                        warmup_period,
                                                        end_time=end_time)
            except Exception as e:
                pass

        # It's needed to reset KPI Calculator when scenario is changed
        self.cal.initialize()

        return result

    def get_scenario(self):
        '''Returns the current case scenario.'''

        scenario = self.scenario

        return scenario

    def get_name(self):
        '''Returns the name of the test case fmu.

        Parameters
        ----------
        None

        Returns
        -------
        name : dict
            Name of test case as {'name': <str>}

        '''

        name = {'name': self.name}

        return name

    def get_elapsed_control_time(self):
        '''Returns the elapsed control time vector for the case.

        Parameters
        ----------
        None

        Returns
        -------
        elapsed_control_time : list of floats
            elapsed_control_time for each control step.

        '''

        elapsed_control_time = self.elapsed_control_time

        return elapsed_control_time

    def _get_var_metadata(self, fmu, var_list, inputs=False):
        '''Build a dictionary of variables and their metadata.

        Parameters
        ----------
        fmu : pyfmi fmu object
            FMU from which to get variable metadata
        var_list : list of str
            List of variable names

        Returns
        -------
        var_metadata : dict
            Dictionary of variable names as keys and metadata as fields.
            {<var_name_str> :
                "Unit" : str,
                "Description" : str,
                "Minimum" : float,
                "Maximum" : float
            }

        '''

        # Inititalize
        var_metadata = dict()
        # Get metadata
        for var in var_list:
            # Units
            if var == 'time':
                unit = 's'
                description = 'Time of simulation'
                mini = None
                maxi = None
            elif '_activate' in var:
                unit = None
                description = fmu.get_variable_description(var)
                mini = None
                maxi = None
            else:
                unit = fmu.get_variable_unit(var)
                description = fmu.get_variable_description(var)
                if inputs:
                    mini = fmu.get_variable_min(var)
                    maxi = fmu.get_variable_max(var)
                else:
                    mini = None
                    maxi = None
            var_metadata[var] = {
                'Unit': unit,
                'Description': description,
                'Minimum': mini,
                'Maximum': maxi
            }

        return var_metadata

    def _check_value_min_max(self, var, value):
        '''Check that the input value does not violate the min or max.

        Note that if it does, the value is truncated to the minimum or maximum.

        Parameters
        ----------
        var : str
            Name of variable
        value : numeric
            Specified value of variable

        Return
        ------
        checked_value : float
            Value of variable truncated by min and max.

        '''

        # Get minimum and maximum for variable
        mini = self.inputs_metadata[var]['Minimum']
        maxi = self.inputs_metadata[var]['Maximum']
        # Check the value and truncate if necessary
        if value > maxi:
            checked_value = maxi
            print(
                'WARNING: Value of {0} for {1} is above maximum of {2}.  Using {2}.'
                .format(value, var, maxi))
        elif value < mini:
            checked_value = mini
            print(
                'WARNING: Value of {0} for {1} is below minimum of {2}.  Using {2}.'
                .format(value, var, mini))
        else:
            checked_value = value

        return checked_value
Esempio n. 7
0
    def __init__(self, fmupath='models/wrapped.fmu'):
        '''Constructor.

        Parameters
        ----------
        fmupath : str, optional
            Path to the test case fmu.
            Default is assuming a particular directory structure.

        '''

        # Set BOPTEST version number
        with open('version.txt', 'r') as f:
            self.version = f.read()
        # Set test case fmu path
        self.fmupath = fmupath
        # Instantiate a data manager for this test case
        self.data_manager = Data_Manager(testcase=self)
        # Load data and the kpis_json for the test case
        self.data_manager.load_data_and_jsons()
        # Instantiate a forecaster for this test case
        self.forecaster = Forecaster(testcase=self)
        # Define name
        self.name = self.config_json['name']
        # Load fmu
        self.fmu = load_fmu(self.fmupath)
        self.fmu.set_log_level(7)
        # Get version and check is 2.0
        self.fmu_version = self.fmu.get_version()
        if self.fmu_version != '2.0':
            raise ValueError('FMU must be version 2.0.')
        # Get building area
        self.area = self.config_json['area']
        # Get available control inputs and outputs
        self.input_names = self.fmu.get_model_variables(causality=2).keys()
        self.output_names = self.fmu.get_model_variables(causality=3).keys()
        # Get input and output meta-data
        self.inputs_metadata = self._get_var_metadata(self.fmu,
                                                      self.input_names,
                                                      inputs=True)
        self.outputs_metadata = self._get_var_metadata(self.fmu,
                                                       self.output_names)
        # Set default communication step
        self.set_step(self.config_json['step'])
        # Set default forecast parameters
        self.set_forecast_parameters(self.config_json['horizon'],
                                     self.config_json['interval'])
        # Initialize simulation data arrays
        self.__initilize_data()
        # Set default fmu simulation options
        self.options = self.fmu.simulate_options()
        self.options['CVode_options']['rtol'] = 1e-6
        self.options['CVode_options']['store_event_points'] = False
        self.options['filter'] = self.output_names + self.input_names
        # Instantiate a KPI calculator for the test case
        self.cal = KPI_Calculator(testcase=self)
        # Initialize test case
        self.initialize(self.config_json['start_time'],
                        self.config_json['warmup_period'])
        # Set default scenario
        self.set_scenario(self.config_json['scenario'])