Example #1
0
 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)
Example #2
0
    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)
Example #4
0
    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)
Example #5
0
 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))
Example #7
0
    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()