def initialize_thermal_prediction(self, config_file): """ copyright by Martin Knorr """ conf_pred = config_file['prediction']['heat'] conf_powr = config_file['prediction']['power'] # conf_pred n_day = conf_pred['n_day'] n_values = conf_pred['n_values_per_day'] precision_in_h = conf_pred['precision_in_h'] use_predef_loads = conf_pred['use_predef_loads'] predef_loads_file_path = conf_pred['path_loads'] # heating curve conf_hk = config_file['components']['heating_curve'] hk_ta = conf_hk['design_ambient_temperature_oC'] hk_ti = conf_hk['design_indoor_temperature_oC'] hk_tv = conf_hk['design_supply_temperature_oC'] hk_tr = conf_hk['design_return_temperature_oC'] hk_n = conf_hk['radiator_coefficient_n'] hk_m = conf_hk['radiator_coefficient_m'] hk_qn = conf_hk['design_heat_load_in_kW'] # chp unit patm = utils.get_pressure_in_MPa() calcopt = utils.get_calc_option() eps_el_chp = config_file['components']['chp_unit']['electrical_efficiency'] eps_th_chp = config_file['components']['chp_unit']['thermal_efficiency'] qel_n_chp = config_file['components']['chp_unit']['max_electric_power_in_kW'] chp_tinp = config_file['components']['chp_unit']['design_input_temperature_oC'] chp_tmax = config_file['components']['chp_unit']['design_output_temperature_oC'] qth_n_chp = eps_th_chp * qel_n_chp / eps_el_chp # in kW mstr_chp = qth_n_chp / (utils.cp_fluid_water(0.5 * (chp_tmax + chp_tinp), patm, calcopt) * (chp_tmax - chp_tinp)) # in kg/s = kW / (kJ/kg/K * K) # gas boiler qth_n_gb = config_file['components']['gas_boiler']['max_thermal_power_in_kW'] gb_tinp = config_file['components']['gas_boiler']['design_input_temperature_oC'] gb_tmax = config_file['components']['gas_boiler']['design_output_temperature_oC'] mstr_gb = qth_n_gb / (utils.cp_fluid_water(0.5 * (gb_tinp + gb_tmax), patm, calcopt) * (gb_tmax - gb_tinp)) # in kg/s = kW / (kJ/kg/K * K) # in kg/s = kW / (kJ/kg/K * K) # storage tank effective_height = config_file['components']['storage_tank']['effective_heigth_in_m'] inner_radius = config_file['components']['storage_tank']['inner_radius_tank_in_m'] effective_pipe_volume = config_file['components']['storage_tank']['effective_coil_volume_in_m3'] # in m3 - water volume of the pipes of inner heat exchanger effective_volume = config_file['components']['storage_tank']['effective_volume_in_m3'] if (effective_volume <= 0.0): effective_volume = math.pi * inner_radius * inner_radius * effective_height - effective_pipe_volume # in m3 nr_calc = 20 slice_volume = effective_volume / nr_calc # in m3 qmax_rod_el = config_file['components']['storage_tank']['power_heating_rod_in_kW'] open_weather_map_active = config_file['calculation']['platform_mode']['open_weather_map_active'] # conf_powr #print('\n initialize_thermal_prediction') #print('use_predef_loads = {}; {}'.format(use_predef_loads,type(use_predef_loads))) #print('predef_loads_file_path = {}; {}'.format(predef_loads_file_path,type(predef_loads_file_path))) return predict_thermal.predict_Q(n_day, n_values, precision_in_h, predef_loads_file_path, use_predef_loads, self.output_horizon_in_h, self.output_resolution_in_s, conf_powr, hk_tv, hk_tr, hk_ti, hk_ta, hk_qn, hk_n, hk_m, chp_tmax, gb_tmax, slice_volume, mstr_chp, mstr_gb, qmax_rod_el, eps_th_chp, eps_el_chp, open_weather_map_active)
def get_heat_output(self): if (self.status == 1): return self.design_mass_flow * utils.cp_fluid_water( self.input_temperature, self.p_atm, 1) * ( self.output_temperature - self.input_temperature) # in kW else: return 0.0 # in kW
def cpcalc(self, temp): """ returns the specific heat capacity in J/kg/K """ if(self.extcp): patm = 0.1 * 1.01325 # in MPa return utils.cp_fluid_water(temp, patm, 1) * 1000.0 else: return self.flcp
def get_mass_flow(self): # in kg/s = kW / (kJ/kg/K * K) if((self.output_temperature - self.input_temperature) != 0.0): self.mass_flow = self.get_heat_output() / ( utils.cp_fluid_water(self.input_temperature, self.p_atm, 1) * (self.output_temperature - self.input_temperature)) else: self.mass_flow = 0.0 return self.mass_flow
def set_design_mass_flow(self): # return self.get_volumen_flow() * utils.rho_fluid_water(self.get_inp_temp(), p_atm, 1) # # m1 = self.get_heat_output() / (0.001 * cp_fluid_water(self.get_inp_temp(), p_atm, 1) * (self.get_out_temp() - self.get_inp_temp())) # in kg/s return self.get_design_heat_output() / ( utils.cp_fluid_water( 0.5 * (self.design_output_temperature + self.design_input_temperature), self.p_atm, 1) * (self.design_output_temperature - self.design_input_temperature) ) # in kg/s = kW / (kJ/kg/K * K)
def get_heat_consumption_from_crate(cursor, start_time, horizont_in_h, pred, time_step_in_s): """ # gets data from crate db # calculates from it the heat flows needed by Martin's function # and passes them as result """ # q_th_dhw = 0.0 q_th_hk = 0.0 t_a_avg = 0.0 n_avg = 0 p_in_MPa = utils.get_pressure_in_MPa() calc_opt = utils.get_calc_option() # cursor.execute("SELECT time_index,t30_ambientairtemperature,t21_domestichotwater,t22_domesticcoldwater,v01_colddrinkingwater,t25_supply_heatingcircuit,t24_return_heatingcircuit,v02_heatingcircuit FROM mtopeniot.etrvk") result = cursor.fetchone() while result != None: timestamp = datetime.utcfromtimestamp(float(result[0]*0.001)) actual_time = start_time if((timestamp >= start_time) and (timestamp < (start_time + timedelta(hours=horizont_in_h)))): # ambient ar temperature t30_ambientairtemperature = result[1] # heat consumption for domestic hot water - get the data t21_domestichotwater = result[2] t22_domesticcoldwater = result[3] v01_colddrinkingwater = result[4] cp_dhw = utils.cp_fluid_water(0.5 * (t22_domesticcoldwater + t21_domestichotwater), p_in_MPa, calc_opt) rho_dhw = utils.rho_fluid_water(t22_domesticcoldwater, p_in_MPa, 1) # kg/m3 * m3/s * J/kg/K * K * s = J q_dhw = rho_dhw * v01_colddrinkingwater * cp_dhw * (t21_domestichotwater - t22_domesticcoldwater) * time_step_in_s # heat consumption for heating system - get the data t25_supply_heatingcircuit = result[5] t24_return_heatingcircuit = result[6] v02_heatingcircuit = result[7] cp_hk = utils.cp_fluid_water(0.5 * (t24_return_heatingcircuit + t25_supply_heatingcircuit), p_in_MPa, calc_opt) rho_hk = utils.rho_fluid_water(t24_return_heatingcircuit, p_in_MPa, 1) # kg/m3 * m3/s * J/kg/K * K * s = J q_hk = rho_hk * v02_heatingcircuit * cp_hk * (t25_supply_heatingcircuit - t24_return_heatingcircuit) * time_step_in_s # aggregate the data in the needed resolution t_act = actual_time.hour # t_act - actual time in hours q_act = (q_dhw + q_hk)/time_step_in_s # q_act - actual heat load of the system in W t_e_act = t30_ambientairtemperature # t_e_act - ambient air temperature in grad Celcius # add aggregated data to the data structure for predict_thermal.py pred.run_to_save_data(t_act,q_act,t_e_act)
def get_design_mass_flow(self): # in kg/s = kW / (kJ/kg/K * K) #print('heat_load = {}'.format(self.heat_load(self.design_ambient_temp))) #print('cp = {}'.format(cp_fluid_water(self.get_avg_hk_temperature(self.design_ambient_temp), self.p_atm, 1))) #print('Dt = {}'.format(self.design_supply_temp - self.design_return_temp)) # in kg/s = kW / (kJ/kg/K * K) return self.heat_load(self.design_ambient_temp) / ( utils.cp_fluid_water( self.get_avg_hk_temperature(self.design_ambient_temp), self.p_atm, 1) * (self.design_supply_temp - self.design_return_temp) ) # kg/s = kW / (kJ/kg/K * K)
def control_internal_1(self, heizkurve, kessel, chp, cvalve, t_a, actual_time, m4, H): if(t_a<=15.0): # heating period heizkurve.turn_on(t_a) else: heizkurve.turn_off() self.V_2 = heizkurve.get_volume_flow() # .............................................................. # mass flow m25 = utils.rho_fluid_water(self.t24, self.p_atm, 1) * self.V_2 # mass flow in heating circuit in kg/s #print('time = {}; type t23 = {}; type t25 = {}'.format(actual_time, type(self.t23), type(self.t25))) if(t_a<=15.0): # heating period #self.t25 = heizkurve.get2_supply_temperature(t_a) if self.t23 < self.t25: # temp in storage is too low to heat the building´ self.too_cold = 1 self.t24 = max(self.t24 - (self.t25 - self.t23),self.t22) # return temperature from the heating system self.t25 = self.t23 # supply temperature to the heating system is too low if chp.get_status() == 1 and self.t15 < self.t25: # storage is almost empty even though the chp is already running wyn = kessel.turn_on(actual_time) # turn the gas boiler on if (wyn[0] == False): H.write('Could not turn gas boiler on at time = {}. Time left to the next turn on = {} s. t23 < t25\n'.format(actual_time,wyn[4].seconds)) #print('Could not turn gas boiler on at time = {}. Time left to the next turn on = {} s. t23 < t25'.format(actual_time,wyn[4].seconds)) #print('t28 = {}; wyn[2] = {}'.format(self.t28,wyn[2])) self.t28 = wyn[2] #self.t29 = wyn[1] kessel.set_inp_temp(self.t29) m4 = wyn[3] if(wyn[0] == False): print('ERROR 2 at time = {}'.format(actual_time)) self.V_4 = m4 / utils.rho_fluid_water(self.t29, self.p_atm, 1) # in m3/s = kg/s / kg/m3 else: wyn = chp.turn_on(actual_time) # turn the chp unit on if (wyn[0] == False): H.write('Could not turn CHP unit on at time = {}. Time left to the next turn on = {} s. t23 < t25\n'.format(actual_time,wyn[4].seconds)) #print('Could not turn CHP unit on at time = {}. Time left to the next turn on = {} s. t23 < t25'.format(actual_time,wyn[4].seconds)) #print('TOO COLD, chp is off, t26 = {}; wyn[2] = {}; stat chp = {}; stat boiler = {}'.format(self.t26,wyn[2],chp.get_status(),kessel.get_status())) self.t26 = wyn[2] #self.t27 = wyn[1] chp.set_inp_temp(self.t27) # temperature incoming from tank to chp m3 = wyn[3] if (wyn[0] == False): print('ERROR 1 at time = {}'.format(actual_time)) self.V_3 = m3 / utils.rho_fluid_water(self.t26, self.p_atm, 1) # in m3/s = kg/s / kg/m3 #print('t23<t25, turn ON, chp = {}, kessel = {}'.format(chp.get_status(),kessel.get_status())) m23 = m25 cvalve.set_hub(1.0) else: self.too_cold = 0 cp25 = utils.cp_fluid_water(self.t25, self.p_atm, 1) cp24 = utils.cp_fluid_water(self.t24, self.p_atm, 1) cp23 = utils.cp_fluid_water(self.t23, self.p_atm, 1) # m23 + m_bypass = m25 ==> m_bypass = m25 - m23 # t23 * cp23 * m23 + t24 * cp24 * m_bypass = t25 * cp25 * m25 # t23 * cp23 * m23 + t24 * cp24 * (m25 - m23) = t25 * cp25 * m25 # m23 * (t23 * cp23 - t24 * cp24) = m25 * (t25 * cp25 - t24 * cp24) m23 = m25 * (self.t25 * cp25 - self.t24 * cp24) / (self.t23 * cp23 - self.t24 * cp24) # m_bypass = m25 * (1.0 - cvalve.get_hub) # mass flow in bypass in kg/s if(m25!=0.0): cvalve.set_hub(m23 / m25) # t25 = (t23 * cp23 + m_bypass * cp24) / (m25 * cp24) else: # no heating needed self.too_cold = 0 m23 = 0.0 m25 = 0.0 self.V_2 = 0.0 return (m23, m25, m4)
def get_heat_output(self): # in kW = kg/s * kJ/kg/K * K return self.mass_flow * utils.cp_fluid_water(self.get_inp_temp(), self.p_atm, 1) * ( self.get_out_temp() - self.get_inp_temp())
def calc_mass_flow(self): return self.max_th_power / (utils.cp_fluid_water(self.design_avg_temp(), self.p_atm, 1) * (self.design_output_temperature - self.design_input_temperature)) # in kg/s = kW / (kJ/kg/K * K) # in kg/s = kW / (kJ/kg/K * K)