def forecast_climate(self, entities): answer = [] # Entities were found #if (len(entities) > 0): # Get the localities geographic = self.catalog.get_Geographic() if geographic is None: answer.append(NER(Error.ERROR_ACLIMATE)) else: ws_data = pd.DataFrame() # Try to search if locality was reconigzed if "locality" in entities.keys(): # This loop figure out all localtities through: states, municipalities and ws, which are into the message l = entities["locality"] ws_data = self.get_ws(l, geographic) # Check if the ws were found if(ws_data.shape[0] > 0): ws_id = ws_data["ws_id"].unique() ws = ','.join(ws_id) # Ask for the forecast data forecast = self.forecast.get_Climate(ws) if forecast is None: answer.append(NER(type = Error.ERROR_ACLIMATE_FORECAST_CLIMATE, tag = l)) else: df = pd.merge(forecast, geographic, on='ws_id', how='inner') answer.append(NER(Forecast.CLIMATE, df)) else: answer.append(NER(Error.LOCALITY_NOT_FOUND,tag=l)) else: answer.append(NER(Error.MISSING_GEOGRAPHIC)) #else: #answer.append(NER(Error.MISSING_ENTITIES)) return answer
class PolicyManagement: def __init__(self, url): self.url_base = url self.headers = {'Content-Type': 'application/json'} self.catalog = Catalog(url, self.headers) self.forecast = ForecastData(url, self.headers) self.historical_data = HistoricalData(url, self.headers) # Method that search geographic places # (dataframe) entities: List of entities found in the message user def geographic(self, entities): answer = [] data = self.catalog.get_Geographic() # Check if could connect with aclimate if data is None: answer.append(NER(Error.ERROR_ACLIMATE)) else: # Entities weren't found if (len(entities) == 0): answer.append(NER(Geographic.STATE, data.loc[:,"state_name"].unique())) else: # This section adds the list of localities l = entities["locality"] e_data = data.loc[data["state_name"].str.contains(l.lower(), case = False), :] # Check if the message has state name in order to send the municipalities if(e_data.shape[0] > 0): answer.append(NER(Geographic.MUNICIPALITIES_STATE, e_data.loc[:,"municipality_name"].unique(), l)) else: e_data = data.loc[data["municipality_name"].str.contains(l.lower(), case = False),: ] # Check if message has municipality name in order to send weather stations if(e_data.shape[0] > 0): answer.append(NER(Geographic.WS_MUNICIPALITY, e_data.loc[:,"ws_name"].unique(),l)) else: e_data = data.loc[data["ws_name"].str.contains(l.lower(), case = False),: ]
def historical_climatology(self, entities): answer = [] # Entities were found #if (len(entities) > 0): # Get the localities geographic = self.catalog.get_Geographic() if geographic is None: answer.append(NER(Error.ERROR_ACLIMATE)) else: ws_data = pd.DataFrame() # Try to search if locality was reconigzed if "locality" in entities.keys(): # This loop figure out all localtities through: states, municipalities and ws, which are into the message l = entities["locality"] ws_data = self.get_ws(l, geographic) # Check if the ws were found if ws_data.shape[0] > 0: ws_id = ws_data["ws_id"].unique() ws = ','.join(ws_id) # Ask for the historical data climatology = self.historical_data.get_Climatology(ws) if climatology is None: answer.append(NER(type = Error.ERROR_ACLIMATE_CLIMATOLOGY, tag = l)) else: df = pd.merge(climatology, geographic, on='ws_id', how='inner') # Filter by measure if "measure" in entities.keys(): dft = pd.DataFrame() dft = dft.append(df.loc[df["measure"] == self.get_measure_from_entities(entities["measure"]),:], ignore_index=True) if(dft.shape[0] > 0): df = dft # Filter by months if "date" in entities. keys(): m_n = self.get_month_from_entities(entities["date"]) if(len(m_n) >= 0): m_n = m_n + 1 df = df.loc[df["month"].isin(m_n),:] # Add all answers answer.append(NER(Historical.CLIMATOLOGY, df, l)) else: answer.append(NER(Error.LOCALITY_NOT_FOUND,tag = l)) else: answer.append(NER(Error.MISSING_GEOGRAPHIC)) #else: #answer.append(NER(Error.MISSING_ENTITIES)) return answer
def cultivars(self, entities): answer = [] data = self.catalog.get_Cultivars() if data is None: answer.append(NER(Error.ERROR_ACLIMATE)) else: # Entities weren't found if (len(entities) == 0): answer.append(NER(Cultivars.CROP_MULTIPLE, data.loc[:,"cp_name"].unique())) # Entities were found else: # This section adds the list of cultivars for each crop required if "crop" in entities.keys(): c = entities["crop"] e_data = data.loc[data["cp_name"].str.contains(c.lower(), case=False), :] answer.append(NER(Cultivars.CROP_CULTIVAR, e_data.loc[:,"cu_name"].unique(), c)) else:
def geographic(self, entities): answer = [] data = self.catalog.get_Geographic() # Check if could connect with aclimate if data is None: answer.append(NER(Error.ERROR_ACLIMATE)) else: # Entities weren't found if (len(entities) == 0): answer.append(NER(Geographic.STATE, data.loc[:,"state_name"].unique())) else: # This section adds the list of localities l = entities["locality"] e_data = data.loc[data["state_name"].str.contains(l.lower(), case = False), :] # Check if the message has state name in order to send the municipalities if(e_data.shape[0] > 0): answer.append(NER(Geographic.MUNICIPALITIES_STATE, e_data.loc[:,"municipality_name"].unique(), l)) else: e_data = data.loc[data["municipality_name"].str.contains(l.lower(), case = False),: ] # Check if message has municipality name in order to send weather stations if(e_data.shape[0] > 0):
def forecast_yield(self, entities, best_date = False): answer = [] # Entities were found #if (len(entities) > 0): # Get the localities geographic = self.catalog.get_Geographic() cultivars = self.catalog.get_Cultivars() soils = self.catalog.get_Soils() if geographic is None or cultivars is None or soils is None: answer.append(NER(Error.ERROR_ACLIMATE)) else: ws_data = pd.DataFrame() # Try to search if locality was reconigzed if "locality" in entities.keys(): # This loop figure out all localtities through: states, municipalities and ws, which are into the message l = entities["locality"] ws_data = self.get_ws(l, geographic) # Check if the ws were found if(ws_data.shape[0] > 0): ws_id = ws_data["ws_id"].unique() ws = ','.join(ws_id) # Ask for the forecast data forecast = self.forecast.get_Yield(ws) if forecast is None: answer.append(NER(type = Error.ERROR_ACLIMATE_FORECAST_YIELD, tag = l)) else: df = pd.merge(forecast, geographic, on='ws_id', how='inner') df = pd.merge(df, cultivars, on='cu_id', how='inner') df = pd.merge(df, soils, on='so_id', how='inner') # Filtering by cultivar filter_cultivar = False if "cultivar" in entities.keys(): cu = entities["cultivar"] dft = df.loc[df["cu_name"].str.contains(cu.lower(), case = False) ,:] if(dft.shape[0] > 0): df = dft filter_cultivar = True # Filter by crop if couldn't filter by cultivar if(filter_cultivar == False and "crop" in entities.keys()): cp = entities["crop"] dft = df.loc[df["cp_name"].str.contains(cp.lower(), case = False) ,:] if(dft.shape[0] > 0): df = dft # Filter by measure df = df.loc[df["measure"].isin(["yield_14", "yield_0"]),:] # Top five by crop crops = df["cp_name"].unique().tolist() for c in crops: amount = 5 type_answer = Forecast.YIELD_PERFORMANCE dft = pd.DataFrame() if best_date: amount = 1 type_answer = Forecast.YIELD_DATE stations = df["ws_id"].unique().tolist() for s in stations: d_local = df.loc[df["cp_name"] == str(c) ,:] d_local = d_local.loc[ d_local["ws_id"] == str(s),:] dft = dft.append(d_local.nlargest(amount,"avg"), ignore_index = True) else: dft = df.loc[df["cp_name"] == c,:].nlargest(amount,"avg") answer.append(NER(type_answer, dft))
# This section adds the list of localities l = entities["locality"] e_data = data.loc[data["state_name"].str.contains(l.lower(), case = False), :] # Check if the message has state name in order to send the municipalities if(e_data.shape[0] > 0): answer.append(NER(Geographic.MUNICIPALITIES_STATE, e_data.loc[:,"municipality_name"].unique(), l)) else: e_data = data.loc[data["municipality_name"].str.contains(l.lower(), case = False),: ] # Check if message has municipality name in order to send weather stations if(e_data.shape[0] > 0): answer.append(NER(Geographic.WS_MUNICIPALITY, e_data.loc[:,"ws_name"].unique(),l)) else: e_data = data.loc[data["ws_name"].str.contains(l.lower(), case = False),: ] # Check if message has weather station name in order to send the ws found if(e_data.shape[0] > 0): answer.append(NER(Geographic.WEATHER_STATION, e_data.loc[:,"ws_name"].unique(),l)) return answer # Method that search cultivars available # (dataframe) entities: List of entities found in the message user def cultivars(self, entities): answer = [] data = self.catalog.get_Cultivars() if data is None: answer.append(NER(Error.ERROR_ACLIMATE)) else: # Entities weren't found if (len(entities) == 0): answer.append(NER(Cultivars.CROP_MULTIPLE, data.loc[:,"cp_name"].unique())) # Entities were found else:
def api_query(): # Validate autentication of melisa if not Melisa.objects(name=request.args.get("melisa")): return "ERROR 1" else: melisa = Melisa.objects.get(name=request.args.get("melisa")) if(melisa.token == request.args.get("token")): policy = PolicyManagement(aclimate) user = None user_id = request.args.get("user") message = request.args.get("message") chat_id = "" if request.args.get("chat_id"): chat_id = request.args.get("chat_id") # Check if user exists, otherwise it will create if not User.objects(user_id=user_id): user = User(melisa = melisa, user_id = user_id) user.save() request_body = {"user_id": user_id, "token": melisa.token, "chat_id":chat_id, "text": ["Hola, soy Melisa, un bot que provee información agroclimática."]} response = requests.post(melisa.url_post,json=request_body) else: user = User.objects.get(user_id=user_id) # Create chat chat = Chat(user = user, text = message, date = datetime.datetime.now(), ext_id = chat_id) chat.save() # message message = message.replace("_"," ") print(message) answer = [] # Check some especial words if message.startswith(("hola", "hi", "Hola", "HOLA")) : answer.append(NER(Commands.HI)) chat.intent_id = 6 chat.intent_name = "hi" chat.slots = {} chat.save() elif message.startswith(("bye", "adios", "Bye", "BYE", "ADIOS")): answer.append(NER(Commands.BYE)) chat.intent_id = 7 chat.intent_name = "bye" chat.slots = {} chat.save() elif message.startswith(("help","ayuda","Help", "HELP", "Ayuda", "Ayuda")): answer.append(NER(Commands.HELP)) chat.intent_id = 8 chat.intent_name = "help" chat.slots = {} chat.save() elif "thanks" in message or "gracias" in message: answer.append(NER(Commands.THANKS)) chat.intent_id = 9 chat.intent_name = "thanks" chat.slots = {} chat.save() else: # Temporal message rb_tmp = {"user_id": user_id, "token": melisa.token, "chat_id":chat_id, "text": ["Estoy procesando tu pregunta"]} response = requests.post(melisa.url_post,json=rb_tmp) # Decoded message utterance = nlu_o.nlu(message) print(utterance) # Update chat chat.intent_id = utterance["intent"] chat.intent_name = utterance["name"] chat.slots = utterance["slots"] chat.save() intent = Intent(utterance["intent"]) entities = utterance["slots"] if(intent == Intent.PLACES): answer = policy.geographic(entities) elif(intent == Intent.CULTIVARS): answer = policy.cultivars(entities) elif(intent == Intent.CLIMATOLOGY): answer = policy.historical_climatology(entities) elif(intent == Intent.FORECAST_PRECIPITATION): answer = policy.forecast_climate(entities) elif(intent == Intent.FORECAST_YIELD): answer = policy.forecast_yield(entities) elif(intent == Intent.FORECAST_DATE): answer = policy.forecast_yield(entities, best_date=True) answers = Generator.print(answer) answers += ["En estos momentos estoy aprendiendo a responder a tus preguntas, por favor ayúdame a mejorar con esta encuesta: https://demeter.paperform.co/?4ctj8=" + str(chat.pk)] request_body = {"user_id": user_id, "token": melisa.token, "chat_id":chat_id, "text": answers} response = requests.post(melisa.url_post,json=request_body) return 'ok' else: return "ERROR 2"