[docs]classAdapter(network_gym_client.adapter.Adapter):"""qos_steer environment adapter. Args: Adapter (network_gym_client.adapter.Adapter): base class. """def__init__(self,config_json):"""Initialize the adapter. Args: config_json (json): the configuration file """super().__init__(config_json)self.env=Path(__file__).resolve().parent.nameself.num_features=3self.size_per_feature=int(self.config_json['env_config']['num_users'])num_users=0foriteminself.config_json['env_config']['per_slice_config']['num_users']:num_users+=itemself.config_json['env_config']['num_users']=num_usersifconfig_json['env_config']['env']!=self.env:sys.exit("[ERROR] wrong environment Adapter. Configured environment: "+str(config_json['env_config']['env'])+" != Launched environment: "+str(self.env))defget_action_space(self):"""Get action space for qos_steer env. Returns: spaces: action spaces """myarray=np.empty([self.size_per_feature,],dtype=int)myarray.fill(3)#print(myarray)returnspaces.MultiDiscrete(myarray)#consistent with the get_observation function.defget_observation_space(self):"""Get observation space for qos_steer env. Returns: spaces: observation spaces """returnspaces.Box(low=0,high=1000,shape=(self.num_features,self.size_per_feature),dtype=np.float32)defget_observation(self,df):"""Prepare observation for qos_steer env. This function should return the same number of features defined in the :meth:`get_observation_space`. Args: df (pd.DataFrame): network stats measurement Returns: spaces: observation spaces """#print (df.sort_values('name').to_string())#data_recv_flat = df.explode(column=['user', 'value'])#print(data_recv_flat)df_rate=Nonedf_wifi_traffic_ratio=Nonedf_x_loc=Nonedf_y_loc=Nonedf_phy_wifi_max_rate=Nonedf_phy_lte_max_rate=Nonerate_value=np.empty(self.size_per_feature,dtype=object)wifi_max_rate_value=np.empty(self.size_per_feature,dtype=object)lte_max_rate_value=np.empty(self.size_per_feature,dtype=object)forindex,rowindf.iterrows():ifrow['source']=='gma':ifrow['name']=='dl::rate':df_rate=rowrate_value=row['value']self.action_data_format=rowelifrow['name']=='wifi::dl::traffic_ratio':df_wifi_traffic_ratio=rowelifrow['name']=='x_loc':df_x_loc=rowelifrow['name']=='y_loc':df_y_loc=rowelifrow['source']=='wifi':ifrow['name']=='dl::max_rate':df_phy_wifi_max_rate=rowwifi_max_rate_value=row['value']elifrow['source']=='lte':ifrow['name']=='dl::max_rate':df_phy_lte_max_rate=rowlte_max_rate_value=row['value']#print(df_rate)#print(df_phy_lte_max_rate)#print(df_phy_wifi_max_rate)#print(df_wifi_split_ratio)#print(df_x_loc)#Print(df_y_loc)# if not empty and send to wanDB databaseself.wandb_log_buffer_append(self.df_to_dict(df_phy_wifi_max_rate))self.wandb_log_buffer_append(self.df_to_dict(df_phy_lte_max_rate))dict_rate=self.df_to_dict(df_rate)ifdf_rateisnotNone:dict_rate["sum_rate"]=sum(df_rate["value"])self.wandb_log_buffer_append(dict_rate)self.wandb_log_buffer_append(self.df_to_dict(df_wifi_traffic_ratio))self.wandb_log_buffer_append(self.df_to_dict(df_x_loc))self.wandb_log_buffer_append(self.df_to_dict(df_y_loc))observation=np.vstack([lte_max_rate_value,wifi_max_rate_value,rate_value])# print('Observation --> ' + str(observation))returnobservationdefget_policy(self,action):"""Prepare network policy for qos_steer env. Args: action (spaces): action from RL agent Returns: json: network policy """# you may also check other constraints for action... e.g., min, max.policy1=json.loads(self.action_data_format.to_json())policy1["name"]="dl::split_weight"#policy1["value"] = action.tolist()newAction=[]foriteminaction:ifitem==0:newAction.append([1,0,0])elifitem==1:newAction.append([0,1,0])elifitem==2:newAction.append([0,0,1])policy1["value"]=newAction# print('Action --> ' + str(policy1))returnpolicy1defget_reward(self,df):"""Prepare reward for qos_steer env. Args: df (pd.DataFrame]): network stats measurement Returns: spaces: reward space """df_wifi_qos_rate=Noneforindex,rowindf.iterrows():ifrow['source']=='gma':ifrow['name']=='wifi::dl::qos_rate':df_wifi_qos_rate=row#print (df_wifi_qos_rate)reward=0ifself.config_json["rl_config"]["reward_type"]=="wifi_qos_user_num":reward=self.calculate_wifi_qos_user_num(df_wifi_qos_rate[:]["value"])else:sys.exit("[ERROR] reward type not supported yet")self.wandb_log_buffer_append(self.df_to_dict(df_wifi_qos_rate,"wifi-qos-rate"))self.wandb_log_buffer_append({"reward":reward})returnrewarddefcalculate_wifi_qos_user_num(self,qos_rate):"""Calculate the number of QoS users over Wi-Fi. Default reward function. Args: qos_rate (pandas.DataFrame): qos data rate per user Returns: double: reward """#print(qos_rate)reward=0forrinqos_rate:ifr>0.1:#we assume the min qos rate is 0.1 mbpsreward=reward+1returnreward