def receive_monitoring_data(self, message): # extract actual_time and trigger prediction_and_control once the thresold has been reached #print(message, type(message)) wyn1 = str(message.payload.decode("utf-8")).split("|") #print("received message =", str(message.payload.decode("utf-8"))) print(wyn1[94], wyn1[95]) #actual_time = utils.extract_time_stamp_from_string(wyn1[1]) actual_time = datetime.fromtimestamp(float(wyn1[95])) # define start_datetime as soon as possible if(self.first): self.first = False self.start_datetime = actual_time self.ini_time_in_h = utils.convert_time_to_hours(actual_time) self.next_prediction_timestamp = actual_time #print(actual_time, self.next_prediction_timestamp) # check whether time elapsed for prediction if(self.time_condition_for_prediction(actual_time, self.pred)): self.fnr = self.fnr + 1 self.next_prediction_timestamp = actual_time + timedelta(seconds=self.prediction_time_step_in_s) weather_pred = self.pred.get_weather_prediction(actual_time, self.simulation, self.wetter_file, self.start_datetime, self.start_sim_inh, self.end_sim_inh, self.fnr) arch_option_1 = False act_time_in_h = utils.convert_time_to_hours(actual_time)-self.ini_time_in_h self.pred.update_heat_consumption_from_crate(actual_time, self.time_step_in_s, arch_option_1, self.fnr) last_t_profile = [float(wyn1[3]),float(wyn1[5]),float(wyn1[7]),float(wyn1[9]),float(wyn1[11]),float(wyn1[13]),float(wyn1[15]),float(wyn1[17]),float(wyn1[19]),float(wyn1[21]),float(wyn1[23]),float(wyn1[25]),float(wyn1[27]),float(wyn1[29]),float(wyn1[31]),float(wyn1[33]),float(wyn1[35]),float(wyn1[37]),float(wyn1[39]),float(wyn1[41])] energy_vector = self.pred.predict_energy_vector(weather_pred, act_time_in_h, actual_time, self.start_datetime, self.start_sim_inh, self.end_sim_inh, self.output_horizon_in_h, self.output_resolution_in_s, last_t_profile, self.fnr) config_file = './config.json' current_sched = platformcontroller.cloud_schedule_gen(actual_time, energy_vector, self.start_datetime, config_file) print('\n\ngot schedule {}\n\n\n\n'.format(current_sched)) platformcontroller.send_schedule_to_rvk(current_sched, self.mqtt_client, self.mqtt_api_key, self.mqtt_sensor_name, self.mqtt_commands, self.fnr)
def process_gw_on_platform(self, act_gw, actual_time): # trigger energy vector and schedule generation if time elapses for the gateway if (actual_time >= act_gw['next_prediction_timestamp']): # config_file = act_gw['config'] self.fnr = self.fnr + 1 prediction_time_step_in_s = config_file['prediction'][ 'prediction_time_step_in_s'] next_prediction_timestamp = actual_time + timedelta( seconds=prediction_time_step_in_s) act_gw['next_prediction_timestamp'] = next_prediction_timestamp weather_pred = self.pred.get_weather_prediction( actual_time, self.simulation, self.wetter_file, self.start_datetime, self.start_sim_inh, self.end_sim_inh, self.fnr) arch_option_1 = False act_time_in_h = utils.convert_time_to_hours( actual_time) - self.ini_time_in_h self.pred.update_heat_consumption_from_crate( actual_time, self.time_step_in_s, arch_option_1, device_id, self.fnr) last_t_profile = self.pred.get_last_storage_temp_profile_from_crate( actual_time, 2.0 * self.time_step_in_s, device_id) energy_vector = self.pred.predict_energy_vector( weather_pred, act_time_in_h, actual_time, self.start_datetime, self.start_sim_inh, self.end_sim_inh, self.output_horizon_in_h, self.output_resolution_in_s, last_t_profile, self.fnr) current_sched = platformcontroller.cloud_schedule_gen( actual_time, energy_vector, self.start_datetime, config_file) if (self.dbg == 2): print('\n\ngot schedule {}\n\n\n\n'.format(current_sched)) platformcontroller.send_schedule_to_rvk( current_sched, self.mqtt_client, self.mqtt_api_key, self.mqtt_sensor_name, self.mqtt_commands, self.fnr)
def receive_monitoring_data(self, message): # extract actual_time and trigger prediction_and_control once the thresold has been reached #print(message, type(message)) # read the input file - here wetter_file - anew in every timestep, as it is changed externally by Stephan wet_file = utils.check_and_open_file( self.conf_file['calculation']['demonstrator_mode'] ['load_profile_file']) # list of strings if (isinstance(wet_file, list) ): # use the wetter file only when reaing it was successfull self.wetter_file = wet_file # list of strings wyn1 = str(message.payload.decode("utf-8")).split("|") #print('DEMO {} {}'.format(wyn1[94], wyn1[95])) #actual_time = utils.extract_time_stamp_from_string(wyn1[1]) actual_time = datetime.fromtimestamp(float(wyn1[95])) #print('DEMO actual_time = {}'.format(actual_time)) # define start_datetime as soon as possible if (self.first): self.first = False self.start_datetime = actual_time self.ini_time_in_h = utils.convert_time_to_hours(actual_time) self.next_prediction_timestamp = actual_time # whenever new time is received from rvk do the following act_time_in_h = utils.convert_time_to_hours( actual_time) - self.ini_time_in_h #print('act_time_in_h = {}'.format(act_time_in_h)) # get heat load in kW from wetter_file q_in_kW = utils.get_jth_column_val(self.simulation, self.wetter_file, actual_time, self.start_datetime, self.start_sim_inh, self.end_sim_inh, 24, 1, 3) # send the heat load in kW to the rvk print( 'DEMO act_time = {}; q in kW from demo= {}, q in kW after scaling = {}' .format(actual_time, q_in_kW, q_in_kW * self.scaling_factor + self.scaling_offset)) self.send_heat_load_to_rvk( actual_time, q_in_kW * self.scaling_factor + self.scaling_offset)
def process_gw_on_platform(self, gw_nr, urn, config_file, actual_time): # check whether the urn is already registered add_gw = True for gw in self.gw_list: if(urn == gw['urn']): add_gw = False # add gw to self.gw_list if it is not yet there if(add_gw): if(len(self.gw_list) == 0): # first gateway uses the predefined data, # that meand that config file of first gateway has to contain the same system data as config file of the platform pred = self.pred else: pred = self.initialize_thermal_prediction(config_file) crdb_endpoint = config_file['calculation']['platform_mode']['crdb_endpoint'] crdb_endpoint_add = config_file['calculation']['platform_mode']['crdb_endpoint_add'] crdb_username = config_file['calculation']['platform_mode']['crdb_username'] crdb_direct_com = config_file['calculation']['platform_mode']['crdb_direct_com'] pred.initialize_crate_db_connection(crdb_endpoint, crdb_endpoint_add, crdb_username, crdb_direct_com) next_prediction_timestamp = self.get_next_prediction_timestamp(actual_time, config_file, pred) # ~ new_gw = {'nr': gw_nr, 'urn': urn, 'config': config_file, 'next_prediction_timestamp': next_prediction_timestamp, 'pred': pred} gw_list.append(new_gw) # find gw in self.gw_list for gw in self.gw_list: if(urn == gw['urn']): act_gw = gw # trigger energy vector and schedule generation if time elapses for the gateway if(actual_time >= act_gw['next_prediction_timestamp']): # config_file = act_gw['config'] self.fnr = self.fnr + 1 prediction_time_step_in_s = config_file['prediction']['prediction_time_step_in_s'] next_prediction_timestamp = actual_time + timedelta(seconds=prediction_time_step_in_s) act_gw['next_prediction_timestamp'] = next_prediction_timestamp #start_datetime = # !!! still TODO weather_pred = self.pred.get_weather_prediction(actual_time, self.simulation, self.wetter_file, self.start_datetime, self.start_sim_inh, self.end_sim_inh, self.fnr) ini_time_in_h = 1 arch_option_1 = False act_time_in_h = utils.convert_time_to_hours(actual_time)-self.ini_time_in_h self.pred.update_heat_consumption_from_crate(actual_time, self.time_step_in_s, arch_option_1, self.fnr) last_t_profile = [float(wyn1[3]),float(wyn1[5]),float(wyn1[7]),float(wyn1[9]),float(wyn1[11]),float(wyn1[13]),float(wyn1[15]),float(wyn1[17]),float(wyn1[19]),float(wyn1[21]),float(wyn1[23]),float(wyn1[25]),float(wyn1[27]),float(wyn1[29]),float(wyn1[31]),float(wyn1[33]),float(wyn1[35]),float(wyn1[37]),float(wyn1[39]),float(wyn1[41])] energy_vector = self.pred.predict_energy_vector(weather_pred, act_time_in_h, actual_time, self.start_datetime, self.start_sim_inh, self.end_sim_inh, self.output_horizon_in_h, self.output_resolution_in_s, last_t_profile, self.fnr) current_sched = platformcontroller.cloud_schedule_gen(actual_time, energy_vector, self.start_datetime, config_file) print('\n\ngot schedule {}\n\n\n\n'.format(current_sched)) platformcontroller.send_schedule_to_rvk(current_sched, self.mqtt_client, self.mqtt_api_key, self.mqtt_sensor_name, self.mqtt_commands, self.fnr)
def main(self): # initialize: pred, mqtt (record_step_in_s, mqtt_attributes, multiple_gateways, mg_path, mg_croot) = self.initialize_components(self.config_file) if(multiple_gateways): # initialize multi-gateway mode; gateways have to be in sensor mode to (actual_time) = self.initialize_multiple_gws(self.config_file) self.ini_time_in_h = utils.convert_time_to_hours(actual_time) self.start_datetime = actual_time end_sim_inh = self.end_sim_inh start_sim_inh = self.start_sim_inh end_datetime = actual_time + timedelta(hours=(end_sim_inh - start_sim_inh)) while self.loop_condition(self.simulation, actual_time, end_datetime): # try: # get list of gateways - now from file system, later from Orion gateways = os.listdir(mg_path) # list of strings urn_base = self.mqtt_sensor_name[:-len(mg_croot)] # for each gateway keep track of it for gw in gateways: # get its number #gw_nr = mqtt_sensor_name[-3:] gw_nr = int(gw[len(mg_croot):]) # get its urn = mqtt_sensor_name from config file myurn = '{}{}'.format(urn_base, gw[len(mg_croot):]) config_file_path = print('{}\\{}{}'.format(mg_path, mg_croot, gw)) print('config_file_path = {}'.format(config_file_path)) config_file = utils.check_and_open_json_file(config_file_path) self.process_gw_on_platform(gw_nr, myurn, config_file, actual_time) except: print('exception in platform') else: # only one gateway # listen to rvk - initialize mqtt subscription - read times of every data set self.mqtt_client = self.create_mqtt_client(self.mqtt_broker, self.mqtt_port_nr, self.mqtt_client_name) self.subscribe_to_monitoring_data(self.mqtt_client, self.mqtt_api_key, self.mqtt_sensor_name, mqtt_attributes) self.mqtt_client.loop_forever()
def main(self): #print('internal main proc') config_file = utils.check_and_open_json_file('./config.json') #print('in main - type of config is {}'.format(type(config_file))) (simulation, time_step_in_s, record_step_in_s, start_sim_inh, end_sim_inh, wetter_file, dhw_load_file, el_load_file, actual_time, F, tsm, tank, chp, kessel, cvalve, heizkurve, pred) = self.initialize_components(config_file) ini_time_in_h = utils.convert_time_to_hours(actual_time) last_record_time = actual_time # time in datetime format print_time_in_h = 0 start_datetime = actual_time end_datetime = actual_time + timedelta(hours=(end_sim_inh - start_sim_inh)) #end_datetime = actual_time + timedelta(hours=end_sim_inh) print('actual_time = {} (in hours = {})'.format(actual_time,utils.convert_time_to_hours(actual_time))) print('start_datetime = {} (in hours = {})'.format(start_datetime,utils.convert_time_to_hours(start_datetime))) print('end_datetime = {} (in hours = {})'.format(end_datetime,utils.convert_time_to_hours(end_datetime))) self.write_header_output_file(F) #act_time_in_h = utils.convert_time_to_hours(actual_time)-ini_time_in_h #ambient_temp = self.get_ambient_temperature(simulation, wetter_file, actual_time, start_datetime, start_sim_inh, end_sim_inh) #self.write_output_into_file(F, actual_time,act_time_in_h,ambient_temp,chp,kessel,cvalve) # first step print('modules initialized') # Martin's code predict_thermal.file_name=open("./pred.txt","a") timestart = datetime.now() H = open("./logrvk1.dat","w") G = open("./mylog.dat","w") G.write(' time load temp \n') while self.loop_condition(simulation, actual_time, end_datetime): # t_a ambient_temp = self.get_ambient_temperature(simulation, wetter_file, actual_time, start_datetime, start_sim_inh, end_sim_inh) self.t30 = ambient_temp # dhw consumption self.V_1 = self.get_dhw_minute_consumption(simulation, dhw_load_file, actual_time, start_datetime, start_sim_inh, end_sim_inh) # cold water temperature self.t22 = 10.0 # electrical rod heater el_heat_status = self.get_heater_rod_status(simulation, el_load_file, actual_time, start_datetime, start_sim_inh, end_sim_inh) el_heat_status = 0.0 # time management act_time_in_h = utils.convert_time_to_hours(actual_time)-ini_time_in_h next_time_step = self.update_time(simulation, actual_time, tsm) real_dt_in_s = (next_time_step - actual_time).seconds tank.update_act_time(act_time_in_h) # calculation self.one_iteration_step(tsm, tank, chp, kessel, cvalve, heizkurve, ambient_temp, el_heat_status, actual_time, H) # output control last_record_time = self.write_output_into_file(F, record_step_in_s, last_record_time, actual_time ,act_time_in_h ,ambient_temp ,chp ,kessel ,cvalve ,tank, tsm) # at the end of the timestep # proceed to the next timestep actual_time = next_time_step flag_big_time_step = tsm.has_timestep_ended(actual_time) # redundant ? # show progress at prompt if((act_time_in_h-print_time_in_h) > 0.05 * (end_sim_inh - start_sim_inh)): print_time_in_h = act_time_in_h print('.', end = '') #print('time = {} (in hours = {}; {})'.format(actual_time, act_time_in_h, utils.convert_time_to_hours(actual_time))) #print('time = {}; act_time_in_h = {}; kessel = {}; mstr = {}; tinp = {}; tout = {}; Qhk = {}'.format(actual_time, act_time_in_h, kessel.get_status(), kessel.get_volume_flow_at_output(), kessel.get_inp_temp(), kessel.get_out_temp(), kessel.get_heat_output())) # saving data for prediction algorithms #print('main time = {} ; {}'.format(actual_time, act_time_in_h)) self.save_data_for_prediction(pred, act_time_in_h, ambient_temp, G) if(self.time_condition_for_prediction(actual_time, pred)): #G.write(' weather prediction') #G.flush() weather_pred = self.get_weather_prediction(actual_time, simulation, wetter_file, start_datetime, start_sim_inh, end_sim_inh) #G.write(' --> energy vector') #G.flush() energy_vector = pred.predict_energy_vector(weather_pred, act_time_in_h, actual_time, start_datetime, start_sim_inh, end_sim_inh, self.output_horizont_in_h, self.output_resolution_in_s) #G.write('--> send or save') #G.flush() self.send_or_save_energy_vector(actual_time, energy_vector, start_datetime) #G.write('--> end\n') #G.flush() #self.control_execute_schedule(self.current_schedule, actual_time) # output to the file - end F.close() G.close() H.close() # duration of the calculation timeend = datetime.now() print('\ncalculation took = {} seconds'.format(timeend - timestart))
def main(self): # main procedure # initialize: pred, mqtt (record_step_in_s, mqtt_attributes, multiple_gateways, mg_path, mg_croot) = self.initialize_components(self.config_file) if (multiple_gateways): # create one mqtt broker for all communications coming into and out of the platform self.mqtt_client = self.create_mqtt_client( self.mqtt_broker, self.mqtt_port_nr, self.mqtt_client_name, self.authentication, self.mqtt_username, self.mqtt_password, self.tls_connection) self.mqtt_client.loop_start() # initialize multi-gateway mode; gateways have to be in sensor mode to do so # platform will enforce its time on the gateways as long as 'calculation' -> 'platform_mode' -> 'real_time_send' is false (actual_time, real_time_send, provisioning_endpoint, sleep_time_in_s, time_step_in_s) = self.initialize_multiple_gws(self.config_file) if (self.dbg == 1): print('real_time_send = {}'.format(real_time_send)) self.ini_time_in_h = utils.convert_time_to_hours(actual_time) self.start_datetime = actual_time end_sim_inh = self.end_sim_inh start_sim_inh = self.start_sim_inh end_datetime = actual_time + timedelta(hours=(end_sim_inh - start_sim_inh)) while self.loop_condition(self.simulation, actual_time, end_datetime): # try: # get list of gateways from Orion prov_iot_devs = utils.list_registered_iot_devices_in_platform( provisioning_endpoint) # dictionary gateways = prov_iot_devs['devices'] # list of dicts if (self.dbg == 1): print('# of devices = {}; '.format( prov_iot_devs['count'])) # for each gateway that is provisioned with the platform - process it for gw in gateways: # data from Orion gw_urn = gw[ 'entity_name'] # urn registered with platform by provisioning gw_id = gw[ 'device_id'] # id registered with platform by provisioning gw_tag = utils.get_last_substring_of_urn( gw_urn, ':' ) # string with the number at the end of urn 001 or 0001 or 00001 etc. urn_base = self.mqtt_sensor_name[:-len( gw_tag )] # string without end number = urn - gw_tag # match data from Orion to the data in file structure # list of directories in directory defined by 'calculation' -> 'platform_mode' -> 'multiple_gateways_directory' rvpps = os.listdir(mg_path) # list of strings: match = False for rvk in rvpps: # test all directories in the data structure rvk_urn = '{}{}'.format(urn_base, rvk[len(mg_croot):]) rvk_id = rvk_urn rvk_tag = rvk[len(mg_croot):] if ((gw_urn == rvk_urn) and (gw_id == rvk_id)): match = True # when number at the end of urn is equal to the number at the end of directory name wyn_urn = rvk_urn wyn_id = rvk_id wyn_tag = rvk_tag #if((gw_tag == rvk_tag) or (int(gw_tag) == int(rvk_tag))): # nickel = True #else: # nickel = False # end for rvk in rvpps: if (match): # the urn provisioned with platform has been found in the file structure if (self.dbg == 1): print('urn = {} '.format(gw_urn)) #print('the urn {} provisioned with platform has been found in the directory {}/{}{} of the file structure'.format(gw_urn, # mg_path, mg_croot, wyn_tag)) # get config file of the registered gateway from the matching directory config_file_path = '{}/{}{}/config.json'.format( mg_path, mg_croot, wyn_tag) config_file = utils.check_and_open_json_file( config_file_path) # check whether gateway has already been initialized in the platform add_gw = True for gwi in self.gw_list: # look for the urn in the internal data structure of the platform if (gw_urn == gwi['urn']): add_gw = False # gateway with such urn is already in the self.gw_list act_gw = gwi # add gw to self.gw_list if it is not yet there == initialize data structure in the platform that works with if (add_gw): # create topics for mqtt communication with this gateway only (mqtt_topic_cmd, mqtt_topic_attr ) = self.configure_mqtt_client_from_config( config_file) ## send initial data set consisting of actual_time and number 10.0 to the platform ## only this makes the crate db create the needed tables - which in turn makes its query possible ## db queries are needed for the rest of initialization ## (self.get_next_prediction_timestamp and self.pred.update_heat_consumption_from_crate in self.process_gw_on_platform) #utils.send_ini_data_to_platform(mqtt_topic_attr, 10.0, actual_time, mqtt_client) # create prediction object (predict_thermal.predict_Q) if it does not exist yet if (len(self.gw_list) == 0): # first gateway uses the predefined data, # that means that config file of first gateway has to contain the same system data as config file of the platform # thanks to this, the provisioning of the first gateway can be left in place, so that other modes of operation are still able to run pred = self.pred else: # it is not the very first gateway, so initialize its prediction module, and communication endpoint pred = self.initialize_thermal_prediction( config_file) crdb_endpoint = config_file['calculation'][ 'platform_mode']['crdb_endpoint'] crdb_endpoint_add = config_file[ 'calculation']['platform_mode'][ 'crdb_endpoint_add'] crdb_username = config_file['calculation'][ 'platform_mode']['crdb_username'] crdb_direct_com = config_file[ 'calculation']['platform_mode'][ 'crdb_direct_com'] pred.initialize_crate_db_connection( crdb_endpoint, crdb_endpoint_add, crdb_username, crdb_direct_com) # determine the time stamp at which the update of the schedule in the new gateway has to take place next_prediction_timestamp = self.get_next_prediction_timestamp( actual_time, config_file, pred, gw_urn) # # create new gateway structure new_gw = { 'nr': gw_tag, 'urn': gw_urn, 'config': config_file, 'next_prediction_timestamp': next_prediction_timestamp, 'pred': pred, 'mqtt_client': self.mqtt_client, 'mqtt_topic_attr': mqtt_topic_attr, 'mqtt_topic_cmd': mqtt_topic_cmd } # add the new gateway to the data structure self.gw_list.append(new_gw) # if the 'calculation' -> 'platform_mode' -> 'real_time_send' is false # the time of gateway has to be synchronized with the time of the platform # If it is true, every gateway can use its own clock as the differences # are expected to be neither significant nor crucial for the operation if (not real_time_send): self.time_sync_gw_with_platform( new_gw, actual_time, start_sim_inh, end_sim_inh) # for the first gateway, that is already provisioned with the platform act_gw = new_gw # end if(add_gw) # if the gateway has match in files and in data structure - it has to be processed: self.process_gw_on_platform(act_gw, actual_time) # end if(match): else: # the urn provisioned with platform cannot be found in the file structure print( 'the urn {} provisioned with platform cannot be found in the file structure' .format(gw_urn)) # end if(match): else: # end for gw in gateways: # keep internal list consistent with the list in the platform for idx, my_gw in enumerate(self.gw_list): my_urn = my_gw['urn'] # check whether urn is in the list is_in = False for gw in gateways: gw_urn = gw['entity_name'] if (gw_urn == my_urn): is_in = True if (not is_in): self.gw_list.pop(idx) # end for idx, my_gw in enumerate(self.gw_list): # end try except: print('exception in platform') # end try: except: # determine the next timestep next_time_step = self.update_time(self.simulation, self.platform, actual_time, real_time_send, sleep_time_in_s, time_step_in_s) # proceed to the next timestep actual_time = next_time_step # end while self.loop_condition # end if(multiple_gateways): else: # only one gateway # listen to rvk - initialize mqtt subscription - read times of every data set self.mqtt_client = self.create_mqtt_client( self.mqtt_broker, self.mqtt_port_nr, self.mqtt_client_name, self.authentication, self.mqtt_username, self.mqtt_password, self.tls_connection) self.subscribe_to_monitoring_data(self.mqtt_client, self.mqtt_api_key, self.mqtt_sensor_name, mqtt_attributes) self.mqtt_client.loop_forever()