import json import uuid import os from helix.constants.anchor_type import AnchorType from helix.constants.module_type import ModuleType from helix.constants.system_type import SystemType from helix.models.sql.inverter_brands import InverterBrand from helix.models.sql.inverters import Inverter from helix.models.sql.power_monitors import PowerMonitor from helix.models.sql.inverter_brands import InverterBrand from helix.models.sql.power_stations import PowerStation from helix.models.sql.sites import Site from helix.models.sql.standalone_inverters import StandaloneInverter from helix.models.sql.users import User from helix.store import Store from helix.user_values import UserValues class SessionManager(object): def __init__(self, session, raw_redis_store, db_session): self.session = session if 'id' not in session: session['id'] = uuid.uuid4().hex self.db_session = db_session self.user = self.db_session.query(User).filter_by(username=session['id']).first() if not self.user: self.user = User(username=session['id'], password_hash='blah') self.db_session.add(self.user) self.db_session.commit() self.site = None else: self.site = self.db_session.query(Site).filter_by(user_id=self.user.id).first() self.store = Store(raw_redis_store, session['id']) def context(self): if self.site: inverter_brands = [inverter_brands.to_json() for inverter_brands in self.db_session.query(InverterBrand).filter_by(site_id=self.site.id).order_by(InverterBrand.id).all()] power_stations = [power_station.to_json() for power_station in self.db_session.query(PowerStation).filter_by(site_id=self.site.id).order_by(PowerStation.id).all()] standalone_inverters = [standalone_inverter.to_json() for standalone_inverter in self.db_session.query(StandaloneInverter).filter_by(site_id=self.site.id).order_by(StandaloneInverter.id).all()] monitors = [monitor.to_json() for monitor in self.db_session.query(PowerMonitor).filter_by(site_id=self.site.id).order_by(PowerMonitor.id).all()] else: inverter_brands = [] power_stations = [] standalone_inverters = [] monitors = [] site_data_available = self.site is not None csv_available = self.site.cad_file is not None if self.site else False return { 'id': self.session['id'], 'google_analytics_token': os.getenv('GOOGLE_ANALYTICS', ''), 'csv_available': csv_available, 'site_data_available': site_data_available, 'inverter_brands': inverter_brands, 'power_stations': power_stations, 'standalone_inverters': standalone_inverters, 'power_monitors': monitors, 'system_type': SystemType(self.site.system_type) if self.site else SystemType.dualTilt, 'steps': [ (1, 'Site Characterization', '/site_characterization/', site_data_available), (2, 'Site Summary', '/summary/', site_data_available), (3, 'Array Summary', '/array_summary/', csv_available), (4, 'Power Station Configuration', '/power_station_configuration/', True if power_stations or standalone_inverters else False), (5, 'Download', '/download/', None) ] } def user_values(self): return UserValues(self.store, self.site) def save_form_submission(self, form_data): if not self.site: self.site = Site( user_id=self.user.id, project_name=form_data.get('project_name', ''), building_height=form_data.get('building_height', 0), building_width=form_data.get('building_width', 0), building_length=form_data.get('building_length', 0), parapet_height=form_data.get('building_parapet_height', 0), wind_speed=form_data.get('wind_speed', 0), exposure_category=form_data.get('exposure_category', 'C'), exposure_transition_distance=form_data.get('exposure_category_transition_distance', 0), ballast_block_weight=form_data.get('ballast_block_weight', 0), max_psf=form_data.get('max_system_pressure', 0), system_type=form_data.get('system_type', SystemType.dualTilt.value), module_type=form_data.get('module_type', ModuleType.Cell96.value), anchor_type=form_data.get('anchor_type', AnchorType.OMG_PowerGrip_Plus.value), spectral_response=form_data.get('design_spectral_response', 1), seismic_importance_factor=form_data.get('importance_factor', 1) ) self.db_session.add(self.site) self.db_session.commit() else: old_system_type = self.site.system_type old_module_type = self.site.module_type self.site.project_name = form_data.get('project_name', self.site.project_name) self.site.building_height = form_data.get('building_height', self.site.building_height) self.site.building_width = form_data.get('building_width', self.site.building_width) self.site.building_length = form_data.get('building_length', self.site.building_length) self.site.parapet_height = form_data.get('building_parapet_height', self.site.parapet_height) self.site.wind_speed = form_data.get('wind_speed', self.site.wind_speed) self.site.exposure_category = form_data.get('exposure_category', self.site.exposure_category) self.site.exposure_transition_distance = form_data.get('exposure_category_transition_distance', self.site.exposure_transition_distance) self.site.ballast_block_weight = form_data.get('ballast_block_weight', self.site.ballast_block_weight) self.site.max_psf = form_data.get('max_system_pressure', self.site.max_psf) self.site.system_type = form_data.get('system_type', self.site.system_type) self.site.module_type = form_data.get('module_type', self.site.module_type) self.site.anchor_type = form_data.get('anchor_type', self.site.anchor_type) self.site.spectral_response = form_data.get('design_spectral_response', self.site.spectral_response) self.site.seismic_importance_factor = form_data.get('importance_factor', self.site.seismic_importance_factor) if old_system_type != self.site.system_type or old_module_type != self.site.module_type: self.site.cad_file = None self.site.cad_file_name = None self.site.dxf_file = None self.site.dxf_file_name = None self.db_session.commit() def save_or_update_power_station(self, form_data): power_station = None if form_data['power_station_id']: power_station = self.db_session.query(PowerStation).get(int(form_data['power_station_id'])) if not power_station: power_station = PowerStation( site_id=self.site.id, quantity=int(form_data.get('power_station_quantity', 0)), ac_run_length=int(form_data.get('ac_run_length', 0)), description=form_data.get('power_station_description', ''), ) self.db_session.add(power_station) else: power_station.quantity = int(form_data.get('power_station_quantity', power_station.quantity)) power_station.ac_run_length = int(form_data.get('ac_run_length', power_station.ac_run_length)) power_station.description = form_data.get('power_station_description', power_station.description) # Delete all inverters for now in order to create new ones on update for inverter in power_station.inverters: self.db_session.delete(inverter) self.db_session.commit() inverter_quantity = int(form_data['inverter_quantity']) if inverter_quantity == 0: return for index in range(inverter_quantity): prefix = 'inverter_' + str(index + 1) inverter = Inverter( model=str(form_data[prefix + '-model']), strings_per_inverter=int(form_data[prefix + '-strings_per_inverter']), sunshade=bool(form_data.get(prefix + '-sunshade', False)), dc_switch=bool(form_data.get(prefix + '-dc_switch', False)), power_station_id=power_station.id, standalone_inverter_id=None, ) self.db_session.add(inverter) self.db_session.commit() def delete_power_station(self, power_station_id): power_station = self.db_session.query(PowerStation).get(power_station_id) if power_station: attached_standalone_inverters = self.db_session.query(StandaloneInverter).filter(StandaloneInverter.attachment_point_id==power_station.id).all() for standalone_inverter in attached_standalone_inverters: standalone_inverter.attachment_point_id = None attached_power_monitors = self.db_session.query(PowerMonitor).filter(PowerMonitor.power_station_id==power_station.id).all() for power_monitor in attached_power_monitors: power_monitor.power_station_id = None self.db_session.delete(power_station) self.db_session.commit() def delete_power_station_config_data(self): site_id = self.site.id power_stations = self.db_session.query(PowerStation).filter(PowerStation.site_id==site_id).all() for power_station in power_stations: self.db_session\ .query(StandaloneInverter)\ .filter(StandaloneInverter.attachment_point_id==power_station.id)\ .delete() self.db_session\ .query(PowerMonitor)\ .filter(PowerMonitor.power_station_id==power_station.id)\ .delete() self.db_session.delete(power_station) self.db_session.query(StandaloneInverter).filter(StandaloneInverter.site_id==site_id).delete() self.db_session.query(PowerMonitor).filter(PowerMonitor.site_id==site_id).delete() self.db_session.commit() def save_or_update_inverter_brands(self, form_data): inverter_brand = None if form_data.get('inverter_brand_id'): inverter_brand = self.db_session.query(InverterBrand).filter_by( site_id=self.site.id ).first() if not inverter_brand: inverter_brand = InverterBrand( id=int(form_data.get('inverter_brand_id')), site_id=self.site.id, ) self.db_session.add(inverter_brand) self.db_session.commit() else: inverter_brand.id = int(form_data.get('inverter_brand_id', inverter_brand.id)) self.db_session.commit() def save_or_update_standalone_inverter(self, form_data): standalone_inverter = None prefix = 'inverter-' if form_data.get('standalone_inverter_id'): standalone_inverter = self.db_session.query(StandaloneInverter).get(int(form_data.get('standalone_inverter_id'))) if not standalone_inverter: quantity = int(form_data[prefix + 'quantity']) for n in range(quantity): standalone_inverter = StandaloneInverter( site_id=self.site.id, attachment_point_id=form_data.get('attachment_point') if form_data.get('attachment_point') != 'switch_gear' else None, ac_run_length=int(form_data.get('standalone_ac_run_length', 0)) ) self.db_session.add(standalone_inverter) self.db_session.commit() inverter = Inverter( model=str(form_data[prefix + 'model']), strings_per_inverter=int(form_data[prefix + 'strings_per_inverter']), sunshade=bool(form_data.get(prefix + 'sunshade', False)), dc_switch=bool(form_data.get(prefix + 'dc_switch', False)), splice_box=bool(form_data.get(prefix + 'splice_box', False)), power_station_id=None, standalone_inverter_id=standalone_inverter.id, ) self.db_session.add(inverter) self.db_session.commit() else: standalone_inverter.ac_run_length = int(form_data.get('standalone_ac_run_length', standalone_inverter.ac_run_length)) standalone_inverter.attachment_point_id = form_data.get('attachment_point') if form_data.get('attachment_point', standalone_inverter.attachment_point_id) != 'switch_gear' else None standalone_inverter.inverter[0].model = str(form_data[prefix + 'model']) standalone_inverter.inverter[0].strings_per_inverter = int(form_data[prefix + 'strings_per_inverter']) standalone_inverter.inverter[0].sunshade = bool(form_data.get(prefix + 'sunshade', False)) standalone_inverter.inverter[0].dc_switch = bool(form_data.get(prefix + 'dc_switch', False)) standalone_inverter.inverter[0].splice_box = bool(form_data.get(prefix + 'splice_box', False)) self.db_session.commit() def delete_standalone_inverter(self, inverter_id): standalone_inverter = self.db_session.query(StandaloneInverter).get(inverter_id) if standalone_inverter: self.db_session.delete(standalone_inverter) self.db_session.commit() def save_or_update_supervisor_monitor(self, form_data): monitor_id = form_data.get('monitor_id') if monitor_id: monitor = self.db_session.query(PowerMonitor).get(monitor_id) monitor.power_station_id = self.interpret_power_source(form_data.get('power_source')) else: monitor = PowerMonitor( site_id=self.site.id, power_station_id=self.interpret_power_source(form_data['power_source']) ) self.db_session.add(monitor) self.db_session.commit() def delete_supervisor_monitor(self, monitor_id): monitor = self.db_session.query(PowerMonitor).get(monitor_id) if monitor: self.db_session.delete(monitor) self.db_session.commit() def save_uploaded_file(self, contents, cad_file_name=None, dxf_file_name=None): self.site.cad_file = contents self.site.cad_file_name = cad_file_name self.site.dxf_file_name = dxf_file_name self.store.delete('user_override_seismic_anchors') self.db_session.commit() def fill_saved_values_in_form(self, form): if self.site: form.project_name.data = self.site.project_name form.building_height.data = self.site.building_height form.building_width.data = self.site.building_width form.building_length.data = self.site.building_length form.building_parapet_height.data = self.site.parapet_height form.wind_speed.data = self.site.wind_speed form.exposure_category.data = self.site.exposure_category form.exposure_category_transition_distance.data = self.site.exposure_transition_distance form.ballast_block_weight.data = self.site.ballast_block_weight form.max_system_pressure.data = self.site.max_psf form.system_type.data = self.site.system_type form.module_type.data = self.site.module_type form.anchor_type.data = self.site.anchor_type form.design_spectral_response.data = self.site.spectral_response form.importance_factor.data = str(self.site.seismic_importance_factor) def save_user_provided_seismic_anchors(self, seismic_anchor_json): self.store.set("user_override_seismic_anchors", json.dumps(seismic_anchor_json)) def save_buildings_polygons(self, buildings): # buildings is a # list of lists of points presented by list of two numbers # [ [ [123.1, 111.1] , [ 222.1, 223.2 ] , [ 212.1, -225.2 ] ] ] polygons_primitive = list(map(lambda x: x.points, buildings)) self.store.set("buildings_polygons", json.dumps(polygons_primitive)) def save_is_drawing_inaccurate(self, is_drawing_inaccurate): self.store.set("is_drawing_inaccurate", json.dumps(is_drawing_inaccurate)) def get_map_index(self, list_id, identifier_key, identifier): maps = self.store.get_list_of_maps(list_id) for idx, val in enumerate(maps): if val[identifier_key] == identifier: return idx def interpret_power_source(self, power_source): if power_source != 'switch_gear': power_station = self.db_session.query(PowerStation).get(power_source) if power_station: return power_station.id return None