Source code for dragonfly_energy.opendss.result

"""Module for parsing OpenDSS results to data collections."""
import os
import datetime

from ladybug.datacollection import HourlyContinuousCollection
from ladybug.header import Header
from ladybug.analysisperiod import AnalysisPeriod
from ladybug.datatype.generic import GenericType
from ladybug.datatype.fraction import Fraction
from ladybug.futil import csv_to_matrix


[docs]class OpenDSSResult(object): """Object for parsing OpenDSS CSV result files into Ladybug DataCollections. Args: file_paths: A list of file paths to CSV files that were generated by OpenDSS. Properties: * file_paths * factor_data * condition_data * peak_factors * average_factors """ # data types for the various outputs from OpenDSS IS_OVERLOADED = GenericType( 'Is Overloaded', 'condition', unit_descr={1: 'Overloaded', 0: 'Normal'}) VOLTAGE_CONDITION = GenericType( 'Voltage Condition', 'condition', unit_descr={-1: 'Undervoltage', 0: 'Normal', 1: 'Overvoltage'}) def __init__(self, file_paths): """Initialize OpenDSSResult""" # check the file paths for fp in file_paths: assert os.path.isfile(fp), 'No file was found at {}'.format(fp) assert fp.endswith('.csv'), \ '{} is not an SQL file ending in .sql or .db.'.format(fp) self._file_paths = tuple(file_paths) # parse the csv data factors, condition = [], [] for result_file in self._file_paths: # parse the data and figure out the time series properties data = csv_to_matrix(result_file) data.pop(0) # remove the header from the CSV column a_period = self._extract_analysis_period(data) # figure out the type of object to write into the metadata obj_name = os.path.basename(result_file).replace('.csv', '') if obj_name.startswith('Line.'): obj_name = obj_name.replace('Line.', '') obj_type = 'Electrical Connector Loading' elif obj_name.startswith('Transformer.'): obj_name = obj_name.replace('Transformer.', '') obj_type = 'Transformer Loading' else: obj_type = 'Building Voltage' metadata = {'type': obj_type, 'name': obj_name} # output the data collection of factors result_vals = [float(data[i][1]) for i in range(len(data))] header = Header(Fraction('Loading Factor'), 'fraction', a_period, metadata) factors.append(HourlyContinuousCollection(header, result_vals)) # output the data collection of conditions if len(data[0]) == 4: # building voltage results cond_vals = [] for row in data: cond = 0 if row[2] == 'False' else 1 if cond != 1 and row[3] == 'True\n': cond = -1 cond_vals.append(cond) header = Header( self.VOLTAGE_CONDITION, self.VOLTAGE_CONDITION.units[0], a_period, metadata) condition.append(HourlyContinuousCollection(header, cond_vals)) else: # transformer or connector load cond_vals = [] for row in data: cond = 0 if row[2] == 'False\n' else 1 cond_vals.append(cond) header = Header( self.IS_OVERLOADED, self.IS_OVERLOADED.units[0], a_period, metadata) condition.append(HourlyContinuousCollection(header, cond_vals)) self._factor_data = tuple(factors) self._condition_data = tuple(condition) @property def file_paths(self): """Get a tuple of file paths to CSV files.""" return self._file_paths @property def factor_data(self): """Get a tuple of loading factors associated with the input file paths.""" return self._factor_data @property def condition_data(self): """Get a tuple of conditions associated with the input file paths.""" return self._condition_data @property def peak_factors(self): """Get a list of numbers for the peak factors across the data.""" return [dat.max for dat in self._factor_data] @property def average_factors(self): """Get a list of numbers for the average factors across the data.""" return [dat.average for dat in self._factor_data] @staticmethod def _date_str_to_datetime(date_str): """Get a datetime object from a string.""" return datetime.datetime.strptime(date_str, '%Y/%m/%d %H:%M:%S') @staticmethod def _extract_analysis_period(data): """Extract an AnalysisPeriod from CSV data.""" dts = [OpenDSSResult._date_str_to_datetime(data[i][0]) for i in (0, 1, -2)] timestep = int(3600 / (dts[1] - dts[0]).total_seconds()) leap_year = True if dts[0].year % 4 == 0 else False a_period = AnalysisPeriod( dts[0].month, dts[0].day, 0, dts[-1].month, dts[-1].day, 23, timestep=timestep, is_leap_year=leap_year) return a_period
[docs] def ToString(self): """Overwrite .NET ToString.""" return self.__repr__()
def __repr__(self): return 'OpenDSS Result [{} files]'.format(len(self.file_paths))